15 virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr, ULONG_PTR firstThunkPtr)
19 IMAGE_THUNK_DATA64* desc =
reinterpret_cast<IMAGE_THUNK_DATA64*
>(origFirstThunkPtr);
20 ULONGLONG* call_via =
reinterpret_cast<ULONGLONG*
>(firstThunkPtr);
21 return processThunks_tpl<ULONGLONG, IMAGE_THUNK_DATA64>(lib_name, desc, call_via, IMAGE_ORDINAL_FLAG64);
23 std::cerr <<
"[!] Cannot fill imports into 64 bit PE via 32 bit loader!\n";
29 IMAGE_THUNK_DATA32* desc =
reinterpret_cast<IMAGE_THUNK_DATA32*
>(origFirstThunkPtr);
30 DWORD* call_via =
reinterpret_cast<DWORD*
>(firstThunkPtr);
31 return processThunks_tpl<DWORD, IMAGE_THUNK_DATA32>(lib_name, desc, call_via, IMAGE_ORDINAL_FLAG32);
33 std::cerr <<
"[!] Cannot fill imports into 32 bit PE via 64 bit loader!\n";
40 template <
typename T_FIELD,
typename T_IMAGE_THUNK_DATA>
41 bool processThunks_tpl(LPSTR lib_name, T_IMAGE_THUNK_DATA* desc, T_FIELD* call_via, T_FIELD ordinal_flag)
47 bool is_by_ord = (desc->u1.Ordinal & ordinal_flag) != 0;
49 FARPROC hProc =
nullptr;
51 T_FIELD raw_ordinal = desc->u1.Ordinal & (~ordinal_flag);
53 std::cout <<
"raw ordinal: " << std::hex << raw_ordinal << std::endl;
59 PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)((ULONGLONG)
modulePtr + desc->u1.AddressOfData);
60 LPSTR func_name =
reinterpret_cast<LPSTR
>(by_name->Name);
62 std::cout <<
"name: " << func_name << std::endl;
68 std::cerr <<
"Could not resolve the function!" << std::endl;
72 (*call_via) =
reinterpret_cast<T_FIELD
>(hProc);
81template <
typename T_FIELD,
typename T_IMAGE_THUNK_DATA>
86 T_FIELD *thunks = (T_FIELD*)((ULONGLONG)modulePtr + thunk_addr);
87 T_FIELD *callers = (T_FIELD*)((ULONGLONG)modulePtr + call_via);
89 for (
size_t index = 0;
true; index++) {
90 if (!
validate_ptr(modulePtr, module_size, &callers[index],
sizeof(T_FIELD))) {
93 if (!
validate_ptr(modulePtr, module_size, &thunks[index],
sizeof(T_FIELD))) {
96 if (callers[index] == 0) {
100 LPVOID thunk_ptr = &thunks[index];
101 T_IMAGE_THUNK_DATA* desc =
reinterpret_cast<T_IMAGE_THUNK_DATA*
>(thunk_ptr);
102 if (!
validate_ptr(modulePtr, module_size, desc,
sizeof(T_IMAGE_THUNK_DATA))) {
105 if (desc->u1.Function == NULL) {
108 T_FIELD ordinal_flag = (
sizeof(T_FIELD) ==
sizeof(ULONGLONG)) ? IMAGE_ORDINAL_FLAG64 : IMAGE_ORDINAL_FLAG32;
109 bool is_by_ord = (desc->u1.Ordinal & ordinal_flag) != 0;
111 PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)((ULONGLONG)modulePtr + desc->u1.AddressOfData);
112 if (!
validate_ptr(modulePtr, module_size, by_name,
sizeof(IMAGE_IMPORT_BY_NAME))) {
117 if (!callback->processThunks(lib_name, (ULONG_PTR)&thunks[index], (ULONG_PTR)&callers[index])) {
127 bool isAllFilled =
true;
129 std::cout <<
"---IMP---" << std::endl;
131 const bool is64 =
is64bit((BYTE*)modulePtr);
132 IMAGE_IMPORT_DESCRIPTOR* lib_desc =
nullptr;
134 for (
size_t i = 0;
true; i++) {
135 lib_desc = &first_desc[i];
136 if (!
validate_ptr(modulePtr, module_size, lib_desc,
sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
139 if (lib_desc->OriginalFirstThunk == NULL && lib_desc->FirstThunk == NULL) {
142 LPSTR lib_name = (LPSTR)((ULONGLONG)modulePtr + lib_desc->Name);
147 DWORD call_via = lib_desc->FirstThunk;
148 DWORD thunk_addr = lib_desc->OriginalFirstThunk;
149 if (thunk_addr == NULL) {
150 thunk_addr = lib_desc->FirstThunk;
153 std::cout <<
"Imported Lib: " << std::hex << lib_desc->FirstThunk <<
" : " << std::hex << lib_desc->OriginalFirstThunk <<
" : " << lib_desc->Name << std::endl;
155 size_t all_solved =
false;
157 all_solved = process_imp_functions_tpl<ULONGLONG, IMAGE_THUNK_DATA64>(modulePtr, module_size, lib_name, call_via, thunk_addr, callback);
160 all_solved = process_imp_functions_tpl<DWORD, IMAGE_THUNK_DATA32>(modulePtr, module_size, lib_name, call_via, thunk_addr, callback);
167 printf(
"---------\n");
174 if (moduleSize == 0) {
177 if (moduleSize == 0)
return false;
179 IMAGE_DATA_DIRECTORY *importsDir =
get_directory_entry((BYTE*)modulePtr, IMAGE_DIRECTORY_ENTRY_IMPORT);
183 const DWORD impAddr = importsDir->VirtualAddress;
184 IMAGE_IMPORT_DESCRIPTOR *first_desc = (IMAGE_IMPORT_DESCRIPTOR*)(impAddr + (ULONG_PTR)modulePtr);
185 if (!
peconv::validate_ptr(modulePtr, moduleSize, first_desc,
sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
188 return process_dlls(modulePtr, moduleSize, first_desc, callback);
194 if (moduleSize == 0)
return false;
196 bool is64 =
is64bit((BYTE*)modulePtr);
197 bool is_loader64 =
false;
201 if (is64 != is_loader64) {
202 std::cerr <<
"[ERROR] Loader/Payload bitness mismatch.\n";
207 if (!func_resolver) {
222 char next_char = *lib_name;
223 if (next_char ==
'\0')
break;
225 if (next_char <= 0x20 || next_char >= 0x7E) {
235 IMAGE_DATA_DIRECTORY *importsDir =
get_directory_entry((BYTE*)modulePtr, IMAGE_DIRECTORY_ENTRY_IMPORT);
236 if (importsDir == NULL)
return false;
238 const DWORD impAddr = importsDir->VirtualAddress;
240 IMAGE_IMPORT_DESCRIPTOR* lib_desc = NULL;
241 DWORD parsedSize = 0;
242 size_t valid_records = 0;
245 lib_desc = (IMAGE_IMPORT_DESCRIPTOR*)(impAddr + parsedSize + (ULONG_PTR)modulePtr);
249 parsedSize +=
sizeof(IMAGE_IMPORT_DESCRIPTOR);
251 if (lib_desc->OriginalFirstThunk == NULL && lib_desc->FirstThunk == NULL) {
254 LPSTR lib_name = (LPSTR)((ULONGLONG)modulePtr + lib_desc->Name);
257 DWORD call_via = lib_desc->FirstThunk;
258 DWORD thunk_addr = lib_desc->OriginalFirstThunk;
259 if (thunk_addr == NULL) thunk_addr = lib_desc->FirstThunk;
261 DWORD *thunks = (DWORD*)((ULONGLONG)modulePtr + thunk_addr);
264 DWORD *callers = (DWORD*)((ULONGLONG)modulePtr + call_via);
270 return (valid_records > 0);
FillImportThunks(BYTE *_modulePtr, size_t _moduleSize, t_function_resolver *func_resolver)
bool processThunks_tpl(LPSTR lib_name, T_IMAGE_THUNK_DATA *desc, T_FIELD *call_via, T_FIELD ordinal_flag)
virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr, ULONG_PTR firstThunkPtr)
t_function_resolver * funcResolver
virtual FARPROC resolve_func(LPSTR lib_name, LPSTR func_name)=0
bool process_dlls(BYTE *modulePtr, size_t module_size, IMAGE_IMPORT_DESCRIPTOR *first_desc, IN ImportThunksCallback *callback)
bool process_imp_functions_tpl(BYTE *modulePtr, size_t module_size, LPSTR lib_name, DWORD call_via, DWORD thunk_addr, IN ImportThunksCallback *callback)
Parsing and filling the Import Table.
bool validate_ptr(IN const void *buffer_bgn, IN SIZE_T buffer_size, IN const void *field_bgn, IN SIZE_T field_size)
bool has_valid_import_table(const PBYTE modulePtr, size_t moduleSize)
bool process_import_table(IN BYTE *modulePtr, IN SIZE_T moduleSize, IN ImportThunksCallback *callback)
DWORD get_image_size(IN const BYTE *payload)
bool is64bit(IN const BYTE *pe_buffer)
bool is_valid_import_name(const PBYTE modulePtr, const size_t moduleSize, LPSTR lib_name)
IMAGE_DATA_DIRECTORY * get_directory_entry(IN const BYTE *pe_buffer, IN DWORD dir_id, IN bool allow_empty=false)
bool load_imports(BYTE *modulePtr, t_function_resolver *func_resolver=nullptr)