224 lines
10 KiB
C++
224 lines
10 KiB
C++
// process_util.h : include utilities for manage folders
|
|
//
|
|
// Author: Gongbing
|
|
//
|
|
// Date: 2016-09-25
|
|
|
|
#pragma once
|
|
#include <string>
|
|
#include <vector>
|
|
#ifndef _INCLUDED_REF_
|
|
#define _INCLUDED_REF_
|
|
#include "../ref/ref.h"
|
|
#endif
|
|
|
|
|
|
|
|
// hook utils
|
|
namespace pe_util
|
|
{
|
|
__declspec(novtable) struct IObscurityCall : public ref_util::IRef
|
|
{
|
|
// params must not be NULL but the API was no parameter
|
|
COM_API_DECLARE(long, invoke(void** params, int* ret_val = NULL)); // return error code
|
|
};
|
|
#pragma pack(push)
|
|
#pragma pack(1)
|
|
typedef struct _hook_instruction_info
|
|
{
|
|
// e.g. in instruction 'E912345678', then bytes = 5, rel_addr_off = 1, rel_addr_size = 4
|
|
unsigned long bytes : 6; // all bytes in this instruction
|
|
unsigned long far_bytes : 3; // the far jumping instruction bytes if this was a near jumping instruction
|
|
unsigned long rel_addr_off : 3; // relative address offset to instruction in this
|
|
unsigned long rel_addr_size : 3; // relative address size of this instruction, ZERO is none
|
|
unsigned char far_instruction[8]; // far jumping instruction, relative address size always be 4 bytes (int)
|
|
unsigned long far_adden; // the jumping offset should added this value for converting near jumping to far jumping
|
|
}HOOKII, *LPHOOKII;
|
|
|
|
typedef struct _group_icon_entry
|
|
{
|
|
unsigned char width;
|
|
unsigned char height;
|
|
unsigned char color_count;
|
|
unsigned char reserved;
|
|
unsigned short planes;
|
|
unsigned short bits_per_pixel;
|
|
unsigned long bytes;
|
|
unsigned short id;
|
|
}GROUPICONENTRY, *LPGROUPICONENTRY;
|
|
typedef struct _group_icon // for RT_GROUP_ICON
|
|
{
|
|
unsigned short reserved;
|
|
unsigned short res_type; // 1 for icon
|
|
unsigned short entries;
|
|
GROUPICONENTRY entry[1];
|
|
}GROUPICON, *LPGROUPICON;
|
|
#pragma pack(pop)
|
|
|
|
PORT_API(LPVOID) allocate_code_buffer(size_t size);
|
|
PORT_API(void) free_code_buffer(LPVOID code_buf);
|
|
PORT_API(int) get_min_code_buffer_bytes(void);
|
|
|
|
// function: calculate hooking info at hook_addr
|
|
// hook_addr: the address will be hooked
|
|
// lphii: the hooking instruction info, at least 6 elements
|
|
// size: [in] - count of lphii, [out] - valid elements in lphii
|
|
// bytes: to receive the minimum bytes to be moved for hooking
|
|
// return: error code
|
|
PORT_API(int) calculate_hook_bytes(const BYTE* hook_addr, LPHOOKII lphii, int* size, int* bytes);
|
|
PORT_API(LPVOID) move_src_code_for_hook(LPVOID src_code, LPHOOKII lphii, int count, LPVOID given_buf = NULL, int bytes = 0);
|
|
|
|
// hook_addr: the instruction address which you should hooking at
|
|
// new_addr: your hooking codes which would jump from hood_addr
|
|
// origin_code: to receive origin codes at hook_addr. or the given address for hook junk if was not NULL, then the moved_bytes contains the size of the buffer when in
|
|
// moved_bytes: to receive copied bytes from hook_addr. it can contains the origin_code buffer bytes if origin_code is not NULL
|
|
PORT_API(int) hook_at(DWORD_PTR hook_addr, FARPROC new_addr, DWORD_PTR *origin_code, int *moved_bytes);
|
|
PORT_API(int) hook_at(const char* module_name, const char* api, FARPROC new_addr, DWORD_PTR *origin_code, int *moved_bytes, int api_offset = 0);
|
|
PORT_API(int) hook_with_shellcode(DWORD_PTR hook_addr, unsigned char* shellcodes, size_t shell_codes_bytes); // // RVA in shellcodes will not be handled !!!
|
|
PORT_API(int) unhook_at(DWORD_PTR unhook_addr, DWORD_PTR* origin_code, int bytes_moved);
|
|
PORT_API(int) unhook_at(const char* module_name, const char* api, DWORD_PTR *origin_code, int bytes_moved, int api_offset = 0);
|
|
|
|
// hook_bef: call method must be '__stdcall', and the parameters are pointers that points to the parameter of the origin api
|
|
// hook_after: call method must be '__stdcall', and the first parameter is the return value of origin api whenever the origin api return value or not
|
|
// and following the parameters is the same as origin api
|
|
//
|
|
// e.g. system api: HANDLE WINAPI CreateFileW(_In_ LPCWSTR lpFileName,
|
|
// _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode,
|
|
// _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
// _In_ DWORD dwCreationDisposition, _In_ DWORD dwFlagsAndAttributes,
|
|
// _In_opt_ HANDLE hTemplateFile);
|
|
// hook_bef: void __stdcall hook_bef(LPCWSTR* lpFileName,
|
|
// DWORD* dwDesiredAccess, DWORD* dwShareMode,
|
|
// LPSECURITY_ATTRIBUTES* lpSecurityAttributes,
|
|
// DWORD* dwCreationDisposition, DWORD* dwFlagsAndAttributes,
|
|
// HANDLE* hTemplateFile
|
|
// void* user_data);
|
|
// or can be void __stdcall hook_bef(void* user_data) if no_param_for_hook_before was true;
|
|
//
|
|
// hook_after: void __stdcall hook_after(HANDLE* ret, LPCWSTR lpFileName,
|
|
// DWORD dwDesiredAccess, DWORD dwShareMode,
|
|
// LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
// DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
|
|
// HANDLE hTemplateFile
|
|
// void* user_data);
|
|
//
|
|
//
|
|
PORT_API(void*) any_hook_at(FARPROC api, size_t param_count, bool stdcall, FARPROC hook_bef = NULL, bool hook_bef_without_param = false, FARPROC hook_after = NULL, void* user_data = NULL);
|
|
PORT_API(void) free_any_hook(void* any_hook);
|
|
|
|
PORT_API(IObscurityCall*) create_obscurity_caller(const wchar_t* module, const char* api, int api_params, bool stdcall);
|
|
PORT_API(IObscurityCall*) create_obscurity_caller(HMODULE module, const char* api, int api_params, bool stdcall);
|
|
|
|
// pe parsing ...
|
|
enum pe_address_type
|
|
{
|
|
PE_ADDR_RELATIVE_TO_FILE = 0,
|
|
PE_ADDR_RELATIVE_TO_MEM,
|
|
PE_ADDR_ABSOLUTE_ON_DEFAULT_BASE,
|
|
};
|
|
__declspec(novtable) struct IPe : public ref_util::IRef
|
|
{
|
|
// params must not be NULL but the API was no parameter
|
|
COM_API_DECLARE(long, load_pe(const wchar_t* path_pe)); // return error code
|
|
COM_API_DECLARE(long, close(void)); // return error code, owner MUST call this before 'release' when you never use this !!!
|
|
COM_API_DECLARE(long, attach(unsigned char* buf, UINT64 bytes)); // return error code
|
|
COM_API_DECLARE(long, detach(unsigned char** buf)); // return error code
|
|
|
|
// cb: data - (const char*)dll_name if flag was DATA_FLAG_FINAL or (const char*)err_msg if flag was DATA_FLAG_ERROR
|
|
// or "IAT" if flag was DATA_FLAG_INSTAR
|
|
// len - (const char*)api_name
|
|
// or IAT sector info(void*[2]) if flag was DATA_FLAG_INSTAR: [0] - (char*)section name, [1] - (UINT64) offset to file
|
|
// total - UINT64[2]: [0] - hint, [2] - offset in file(EAT only), [1] - offset in mem set to be '0' if 'only_dll' was true if flag was DATA_FLAG_FINAL or unused if flag was DATA_FLAG_ERROR
|
|
// or IAT table info(UINT64[3]) if flag was DATA_FLAG_INSTAR: [0] - offset to file, [1] - offset in memory, [2] - table bytes
|
|
// flag - DATA_FLAG_FINAL or DATA_FLAG_INSTAR or DATA_FLAG_ERROR
|
|
//
|
|
// param - same as the paramenter you passed 'param'
|
|
//
|
|
// return non 'SET_RESULT_CONTINUE' to stop working
|
|
COM_API_DECLARE(long, dump_iat(INTER_MODULE_CALLBACK_VAR(cb), void* param, bool only_dll = false));
|
|
COM_API_DECLARE(long, dump_eat(INTER_MODULE_CALLBACK_VAR(cb), void* param));
|
|
|
|
// cb: data - (const char*)section name
|
|
//
|
|
// len - bytes of section name
|
|
//
|
|
// total - UINT64 pos[3]: pos[0] - offset in file, pos[1] - offset in memory, pos[2] - section size in bytes
|
|
//
|
|
// flag - DATA_FLAG_FINAL
|
|
//
|
|
// param - same as the paramenter you passed 'param'
|
|
COM_API_DECLARE(long, dump_sections(INTER_MODULE_CALLBACK_VAR(cb), void* param));
|
|
|
|
// cb: data - (const char*)resource name
|
|
//
|
|
// len - UINT64[2]: [0] - bytes of resource; [1] - (void*)resource_data
|
|
//
|
|
// total - UINT64[4]: [0] - id; [1] - memory offset; [2] - file offset, [3] - codepage
|
|
//
|
|
// flag - DATA_FLAG_FINAL
|
|
//
|
|
// param - same as the paramenter you passed 'param'
|
|
COM_API_DECLARE(long, dump_resources(INTER_MODULE_CALLBACK_VAR(cb), void* param));
|
|
|
|
// function: convert RVA between memory offset and file offset
|
|
//
|
|
// parameter: from - source address;
|
|
//
|
|
// to - to receive the target address
|
|
//
|
|
// off2rva - true: file offset to memory offset; false: memory offset to file offset
|
|
COM_API_DECLARE(long, rva(UINT64 from, UINT64* to, bool off2rva));
|
|
|
|
// cb: data - (const char*)assembly
|
|
//
|
|
// len - bytes of assembly
|
|
//
|
|
// total - UINT[2]: 0 - offset in file of the code, 1 - offset in memory of the assembly
|
|
//
|
|
// flag - DATA_FLAG_FINAL
|
|
//
|
|
// param - same as the paramenter you passed 'param'
|
|
COM_API_DECLARE(long, find_address_ref(UINT64 addr, INTER_MODULE_CALLBACK_VAR(cb), void* param, short addr_bytes = 4));
|
|
COM_API_DECLARE(long, find_iat_ref(const char* dll_name, const char* api_name/*consider as hint if less than 0x10000*/, INTER_MODULE_CALLBACK_VAR(cb), void* param));
|
|
COM_API_DECLARE(long, find_string_ref(const char* str, INTER_MODULE_CALLBACK_VAR(cb), void* param));
|
|
COM_API_DECLARE(long, find_string_ref(const wchar_t* str, INTER_MODULE_CALLBACK_VAR(cb), void* param));
|
|
|
|
// function: un-assembly given function begin from 'addr' and ENDING at instruction 'ret' or 'cb' return SET_RESULT_STOP
|
|
//
|
|
// parameter: addr - given address
|
|
//
|
|
// addr_type - how to use the address 'addr'
|
|
//
|
|
// cb - data: (const char*) assembly
|
|
// len: bytes of data
|
|
// total: UINT64[4]: 0 - file offset; 1 - instruction absolute address; 2 - bytes; [3] - (unsigned char*) codes
|
|
// flag: DATA_FLAG_FINAL
|
|
// param: same as the paramenter you passed 'param'
|
|
// return SET_RESULT_CONTINUE to work until 'ret', or SET_RESULT_STOP to stop immediately
|
|
//
|
|
// param - parameter for 'cb'
|
|
//
|
|
// img_base - specify the image base. use default base if it was '0'
|
|
COM_API_DECLARE(long, un_assembly(UINT64 addr, enum pe_address_type addr_type, INTER_MODULE_CALLBACK_VAR(cb), void* param, UINT64 img_base = 0));
|
|
COM_API_DECLARE(long, un_assembly(const char* export_api_name, INTER_MODULE_CALLBACK_VAR(cb), void* param));
|
|
|
|
// function: to change content at given file offset
|
|
//
|
|
// cb - data: (const wchar_t*) target file after changed
|
|
// len: bytes of data
|
|
// total: unused
|
|
// flag: DATA_FLAG_FINAL
|
|
// param: same as the parameter you passed 'param'
|
|
// return: omitted
|
|
COM_API_DECLARE(long, change(UINT64 file_off, const unsigned char* data, size_t bytes, INTER_MODULE_CALLBACK_VAR(cb), void* param));
|
|
|
|
COM_API_DECLARE(bool, is_pe_64(void)); // whether the PE is a 64-bits module
|
|
COM_API_DECLARE(long, get_entry_point(UINT64* off)); // get offset of entry-point in memory
|
|
COM_API_DECLARE(long, get_image_base_addr(UINT64* addr)); // get offset of entry-point in memory
|
|
COM_API_DECLARE(long, get_file_time(UINT64* file_time)); // get file compiled time
|
|
};
|
|
|
|
PORT_API(IPe*) create_pe_parser(void);
|
|
};
|
|
|