Tricker Posted September 8, 2012 Posted September 8, 2012 (edited) Summary:Read 32- and 64-bit PE files (PE, PE+) for Windows, work similar with both formatsRebuild 32- and 64-bit PE filesWork with directories and headersConvert addressesRead and write PE sectionsRead and write importsRead and write exportsRead and write relocationsRead and write resourcesRead and write TLSRead and write image configRead and write basic .NET informationRead bound importsRead exception directory (PE+ only)Read debug directory and extended debug informationCalculate entropyChange file alignmentChange base addressWork with DOS Stub and Rich overlayHigh-level resource reading: bitmaps, icons, cursors, version info, string and message tablesHigh-level resource editing: bitmaps, icons, cursors, version infoLibrary code is commented in English well. 25 samples included (with Russian comments) showing how to use different functions of library. MSVC++ 2008 and 2010 solutions included. There's no documentation, probably it will be written in the future.Library doesn't use WinAPI and other libraries except STL. Crossplatform version can be released in the future, but it's not so easy at this time because of wchar_t type size differences on Windows and Linux (PE files have lots of UTF-16 strings) and some other problems.Library code can be built for Windows x86 and x64, but x64 build is not necessary if you want to work with PE+, x86 is enough. Library doesn't use WinAPI and doesn't execute PE files, so it's safe to use it with suspicious binaries.Repo and source download: http://code.google.c...utable-library/Project page: https://kaimi.ru/201...utable-library/Author's blog: https://kaimi.ru/Usage example:#include <iostream>#include <fstream>#include <pe_factory.h>#include <pe_resource_manager.h>#include "resource.h"#include "lib.h"//Sample showing how to edit PE resources//Learn resource_viewer example first//Example is compatible with x86 and x64 and will work in both variantsint main(int argc, char* argv[]){ //Open file (ourselves) std::ifstream pe_file(argv[0], std::ios::in | std::ios::binary); if(!pe_file) { std::cout << "Cannot open " << argv[0] << std::endl; return -1; } try { //Create PE or PE+ class object with the help of factory std::auto_ptr<pe_base> image = pe_factory::create_pe(pe_file); //The aim of this sample: //This example binary file has an icon inside "CUSTOM" resource directory //This icon has three different resolution bitmaps //We will read this icon from CUSTOM directory and set is as main executable icon //Then we will delete CUSTOM directory //Finally, we will generate some version information for this binary //Check if we have resource directory if(!image->has_resources()) { std::cout << "Image has no resources" << std::endl; return 0; } //Get resource root directory std::cout << "Reading PE resources..." << std::hex << std::showbase << std::endl << std::endl; pe_base::resource_directory root = image->get_resources(); //To simplify reading and editing of resources there are some helper classes //This class allows to edit and read any resources from root resource directory //and has some high-level functions to read icons, cursors, bitmaps, string and message tables and version information //and to write icons, cursors, bitmaps, string and message tables pe_resource_manager res(root); //Check CUSTOM directory existence if(!res.resource_exists(L"CUSTOM")) { std::cout << "\"CUSTOM\" resource directory does not exist" << std::endl; return -1; } //Get the icon from this directory: we know its ID=100 and it is the only one in this directory //Get it by zero index (it is also possible to get it by language, but it is the only one, so no need for this) const pe_resource_viewer::resource_data_info data = res.get_resource_data_by_id(L"CUSTOM", IDR_CUSTOM1); //Now we add it as main executable icon //Main icon is icon from the very first icon group //Remember that named resources come first, and resources with ID next, and everything is sorted //Create MAIN_ICON icon group res.add_icon(data.get_data(), //Icon file data L"MAIN_ICON", //Icon group name (all three icon bitmaps will be placed inside this group) 0, //Language - does not matter pe_resource_manager::icon_place_after_max_icon_id, //Icon placement method - does not matter, because we are creating the new icon group data.get_codepage(), //Keep Codepage 0 //Timestamp - does not matter ); //Remove CUSTOM directory, we do not need it anymore res.remove_resource(L"CUSTOM"); //Now create version info pe_resource_viewer::file_version_info file_info; //Basic file info file_info.set_special_build(true); //Let this build be special file_info.set_file_os(pe_resource_viewer::file_version_info::file_os_nt_win32); //OS file_info.set_file_version_ms(0x00010002); //File version: 1.2.3.4 file_info.set_file_version_ls(0x00030004); //Now create version strings and translations pe_resource_viewer::lang_string_values_map strings; pe_resource_viewer::translation_values_map translations; //There is also helper class to work with this stuff version_info_editor version(strings, translations); //Add translation - default process language, UNICODE //We also can specify language and codepage version.add_translation(version_info_editor::default_language_translation); //Strings will be added to default translation (default_language_translation) //If there is no default one, then to the first existent //If there is no translations, the default one will be added automatically (default_language_translation) //So, add_translation call can be skipped here //We can specify any version info strings like that: version.set_company_name(L"Kaimi.ru DX"); version.set_file_description(L"Generated file version info"); version.set_internal_name(L"Tralala.exe"); version.set_legal_copyright(L"(C) DX Portable Executable Library"); version.set_original_filename(L"resource_editor.exe"); version.set_product_name(L"PE Resource Editor Example"); version.set_product_version(L"x.y.z"); //We can also add our very own string: it will be saved to version information //but Windows Explorer will not show it version.set_property(L"MyLittleProperty", L"Secret Value"); //Set version information res.set_version_info(file_info, strings, translations, 1033); //1033 - Russian language //Now we are renaming old resource section //(.rsrc) //It is necessary to allow Windows Explorer read our icon from the new resource directory and section image->section_from_directory(IMAGE_DIRECTORY_ENTRY_RESOURCE).set_name("oldres"); //Rebuild resources //They will be bigger than used to be //so we will create a new section for them //(we cannot enlarge existing sections, apart from the very last section in PE file) pe_base::section new_resources; new_resources.get_raw_data().resize(1); //We cannot add empty sections, so let it have raw size 1 new_resources.set_name(".rsrc"); //Section name new_resources.readable(true); //Readable only pe_base::section& attached_section = image->add_section(new_resources); //Add section and get added and recalculated section //Rebuild resources, put it in the beginning of our new section, fix PE header image->rebuild_resources(root, attached_section); //Create new PE file std::string base_file_name(argv[0]); std::string::size_type slash_pos; if((slash_pos = base_file_name.find_last_of("/\\")) != std::string::npos) base_file_name = base_file_name.substr(slash_pos + 1); base_file_name = "new_" + base_file_name; std::ofstream new_pe_file(base_file_name.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); if(!new_pe_file) { std::cout << "Cannot create " << base_file_name << std::endl; return -1; } //Rebuild PE file image->rebuild_pe(new_pe_file); std::cout << "PE was rebuilt and saved to " << base_file_name << std::endl; } catch(const pe_exception& e) { //On error std::cout << "Error: " << e.what() << std::endl; return -1; } return 0;} Edited September 8, 2012 by Tricker
deepzero Posted September 8, 2012 Posted September 8, 2012 * Copyright © 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)* All rights reserved.looks very much like pelib to me./>http://www.pelib.com/index.php
Tricker Posted September 12, 2012 Author Posted September 12, 2012 Is this some kind of knock off?Download source code and compare it to pelib. This implementation is original and much better.
mudlord Posted September 13, 2012 Posted September 13, 2012 pelib official git: https://github.com/sporst/PeLib
mudlord Posted September 13, 2012 Posted September 13, 2012 Download source code and compare it to pelib. This implementation is original and much better.How is it better?
Tricker Posted September 13, 2012 Author Posted September 13, 2012 How is it better?I love such questions. So, I need to provide comparison table cause it's easier to ask than to spent 10-15 mins to overlook available methods. OK, will be done...
deepzero Posted September 13, 2012 Posted September 13, 2012 yes. it`s common practice that if you improve existing code you state what you improved, a simple "it`s better, believe me" wont do. Also, no one will spent 15+ min going through two sources he doesn't even know to try to tell which one`s better. that`s just the way it is.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now