godot/tools/pe_bliss/pe_imports.h
2015-11-09 02:24:41 +03:30

209 lines
8.8 KiB
C++

/*************************************************************************/
/* Copyright (c) 2015 dx, http://kaimi.ru */
/* */
/* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following conditions: */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#pragma once
#include <vector>
#include <string>
#include "pe_structures.h"
#include "pe_directory.h"
#include "pe_base.h"
namespace pe_bliss
{
//Class representing imported function
class imported_function
{
public:
//Default constructor
imported_function();
//Returns true if imported function has name (and hint)
bool has_name() const;
//Returns name of function
const std::string& get_name() const;
//Returns hint
uint16_t get_hint() const;
//Returns ordinal of function
uint16_t get_ordinal() const;
//Returns IAT entry VA (usable if image has both IAT and original IAT and is bound)
uint64_t get_iat_va() const;
public: //Setters do not change everything inside image, they are used by PE class
//You also can use them to rebuild image imports
//Sets name of function
void set_name(const std::string& name);
//Sets hint
void set_hint(uint16_t hint);
//Sets ordinal
void set_ordinal(uint16_t ordinal);
//Sets IAT entry VA (usable if image has both IAT and original IAT and is bound)
void set_iat_va(uint64_t rva);
private:
std::string name_; //Function name
uint16_t hint_; //Hint
uint16_t ordinal_; //Ordinal
uint64_t iat_va_;
};
//Class representing imported library information
class import_library
{
public:
typedef std::vector<imported_function> imported_list;
public:
//Default constructor
import_library();
//Returns name of library
const std::string& get_name() const;
//Returns RVA to Import Address Table (IAT)
uint32_t get_rva_to_iat() const;
//Returns RVA to Original Import Address Table (Original IAT)
uint32_t get_rva_to_original_iat() const;
//Returns timestamp
uint32_t get_timestamp() const;
//Returns imported functions list
const imported_list& get_imported_functions() const;
public: //Setters do not change everything inside image, they are used by PE class
//You also can use them to rebuild image imports
//Sets name of library
void set_name(const std::string& name);
//Sets RVA to Import Address Table (IAT)
void set_rva_to_iat(uint32_t rva_to_iat);
//Sets RVA to Original Import Address Table (Original IAT)
void set_rva_to_original_iat(uint32_t rva_to_original_iat);
//Sets timestamp
void set_timestamp(uint32_t timestamp);
//Adds imported function
void add_import(const imported_function& func);
//Clears imported functions list
void clear_imports();
private:
std::string name_; //Library name
uint32_t rva_to_iat_; //RVA to IAT
uint32_t rva_to_original_iat_; //RVA to original IAT
uint32_t timestamp_; //DLL TimeStamp
imported_list imports_;
};
//Simple import directory rebuilder
//Class representing import rebuilder advanced settings
class import_rebuilder_settings
{
public:
//Default constructor
//Default constructor
//If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset
//to new value after import rebuilding
//If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero
//IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable
//to be able to modify IAT thunks
explicit import_rebuilder_settings(bool set_to_pe_headers = true, bool auto_zero_directory_entry_iat = false);
//Returns offset from section start where import directory data will be placed
uint32_t get_offset_from_section_start() const;
//Returns true if Original import address table (IAT) will be rebuilt
bool build_original_iat() const;
//Returns true if Original import address and import address tables will not be rebuilt,
//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
bool save_iat_and_original_iat_rvas() const;
//Returns true if Original import address and import address tables contents will be rewritten
//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
//and save_iat_and_original_iat_rvas is true
bool rewrite_iat_and_original_iat_contents() const;
//Returns true if original missing IATs will be rebuilt
//(only if IATs are saved)
bool fill_missing_original_iats() const;
//Returns true if PE headers should be updated automatically after rebuilding of imports
bool auto_set_to_pe_headers() const;
//Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
bool zero_directory_entry_iat() const;
//Returns true if the last section should be stripped automatically, if imports are inside it
bool auto_strip_last_section_enabled() const;
public: //Setters
//Sets offset from section start where import directory data will be placed
void set_offset_from_section_start(uint32_t offset);
//Sets if Original import address table (IAT) will be rebuilt
void build_original_iat(bool enable);
//Sets if Original import address and import address tables will not be rebuilt,
//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
//enable_rewrite_iat_and_original_iat_contents sets if Original import address and import address tables contents will be rewritten
//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
//and save_iat_and_original_iat_rvas is true
void save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents = false);
//Sets if original missing IATs will be rebuilt
//(only if IATs are saved)
void fill_missing_original_iats(bool enable);
//Sets if PE headers should be updated automatically after rebuilding of imports
void auto_set_to_pe_headers(bool enable);
//Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
void zero_directory_entry_iat(bool enable);
//Sets if the last section should be stripped automatically, if imports are inside it, default true
void enable_auto_strip_last_section(bool enable);
private:
uint32_t offset_from_section_start_;
bool build_original_iat_;
bool save_iat_and_original_iat_rvas_;
bool fill_missing_original_iats_;
bool set_to_pe_headers_;
bool zero_directory_entry_iat_;
bool rewrite_iat_and_original_iat_contents_;
bool auto_strip_last_section_;
};
typedef std::vector<import_library> imported_functions_list;
//Returns imported functions list with related libraries info
const imported_functions_list get_imported_functions(const pe_base& pe);
template<typename PEClassType>
const imported_functions_list get_imported_functions_base(const pe_base& pe);
//You can get all image imports with get_imported_functions() function
//You can use returned value to, for example, add new imported library with some functions
//to the end of list of imported libraries
//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default)
//Don't add new imported functions to existing imported library entries, because this can cause
//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader
//The safest way is just adding import libraries with functions to the end of imported_functions_list array
const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());
template<typename PEClassType>
const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());
}