10 ListImportNames(BYTE* _modulePtr,
size_t _moduleSize, std::map<std::string, DWORD> &name_to_addr)
15 virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr, ULONG_PTR firstThunkPtr)
18 IMAGE_THUNK_DATA64* desc =
reinterpret_cast<IMAGE_THUNK_DATA64*
>(origFirstThunkPtr);
19 ULONGLONG* call_via =
reinterpret_cast<ULONGLONG*
>(firstThunkPtr);
22 IMAGE_THUNK_DATA32* desc =
reinterpret_cast<IMAGE_THUNK_DATA32*
>(origFirstThunkPtr);
23 DWORD* call_via =
reinterpret_cast<DWORD*
>(firstThunkPtr);
28 template <
typename T_FIELD,
typename T_IMAGE_THUNK_DATA>
29 bool processThunks_tpl(LPSTR lib_name, T_IMAGE_THUNK_DATA* desc, T_FIELD* call_via, T_FIELD ordinal_flag)
31 DWORD call_via_rva =
static_cast<DWORD
>((ULONG_PTR)call_via - (ULONG_PTR)this->
modulePtr);
33 std::cout <<
"via RVA: " << std::hex << call_via_rva <<
" : ";
35 bool is_by_ord = (desc->u1.Ordinal & ordinal_flag) != 0;
37 PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)((ULONGLONG)
modulePtr + desc->u1.AddressOfData);
38 LPSTR func_name =
reinterpret_cast<LPSTR
>(by_name->Name);
40 std::cout <<
"name: " << func_name << std::endl;
52 std::map<std::string, DWORD> name_to_addr;
56 std::map<std::string, DWORD>::iterator found = name_to_addr.find(
"_CorExeMain");
57 if (found != name_to_addr.end())
return found->second;
59 found = name_to_addr.find(
"_CorDllMain");
60 if (found != name_to_addr.end())
return found->second;
65BYTE*
search_jump(BYTE *buf,
size_t buf_size,
const DWORD cor_exe_main_thunk,
const ULONGLONG img_base)
69 const size_t jmp_size = 2;
70 const BYTE jmp_pattern[jmp_size] = { 0xFF, 0x25 };
72 const size_t arg_size =
sizeof(DWORD);
73 if ((jmp_size + arg_size) > buf_size) {
76 const size_t end_offset = buf_size - (jmp_size + arg_size);
78 for (
size_t i = end_offset;
82 if (buf[i] == jmp_pattern[0] && buf[i + 1] == jmp_pattern[1]) {
83 DWORD* addr = (DWORD*)(&buf[i + jmp_size]);
84 DWORD rva =
static_cast<DWORD
>((*addr) - img_base);
85 if (rva == cor_exe_main_thunk) {
87 std::cout <<
"Found call to _CorExeMain\n";
92 std::cerr <<
"[!] Mismatch: " << std::hex << rva <<
" vs _CorExeMain: " << cor_exe_main_thunk << std::endl;
101 if (!pe_buffer)
return false;
111 std::cout <<
"[*] This is a .NET payload and may require Enty Point correction. Current EP: " << std::hex << ep_rva <<
"\n";
117 BYTE* sec_ptr = (BYTE*)((ULONG_PTR)pe_buffer + sec_hdr->VirtualAddress);
123 if (!cor_exe_main_thunk) {
126 BYTE* jump_ptr =
search_jump(sec_ptr, sec_hdr->SizeOfRawData, cor_exe_main_thunk, img_base);
130 size_t offset = (ULONG_PTR)jump_ptr - (ULONG_PTR)pe_buffer;
133 std::cout <<
"[*] Found possible Entry Point: " << std::hex << offset << std::endl;
virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr, ULONG_PTR firstThunkPtr)
bool processThunks_tpl(LPSTR lib_name, T_IMAGE_THUNK_DATA *desc, T_FIELD *call_via, T_FIELD ordinal_flag)
ListImportNames(BYTE *_modulePtr, size_t _moduleSize, std::map< std::string, DWORD > &name_to_addr)
std::map< std::string, DWORD > & nameToAddr
ImportThunksCallback(BYTE *_modulePtr, size_t _moduleSize)
bool fix_dot_net_ep(BYTE *pe_buffer, size_t pe_buffer_size)
BYTE * search_jump(BYTE *buf, size_t buf_size, const DWORD cor_exe_main_thunk, const ULONGLONG img_base)
DWORD find_corexemain(BYTE *buf, size_t buf_size)
bool update_entry_point_rva(IN OUT BYTE *pe_buffer, IN DWORD ep)
DWORD get_entry_point_rva(IN const BYTE *pe_buffer)
ULONGLONG get_image_base(IN const BYTE *pe_buffer)
bool process_import_table(IN BYTE *modulePtr, IN SIZE_T moduleSize, IN ImportThunksCallback *callback)
bool validate_ptr(IN const void *buffer_bgn, IN size_t buffer_size, IN const void *field_bgn, IN size_t field_size)
PIMAGE_SECTION_HEADER get_section_hdr(IN const BYTE *pe_buffer, IN const size_t buffer_size, IN size_t section_num)
bool is64bit(IN const BYTE *pe_buffer)
Master include file, including everything else.