14 BYTE* dimps_table = (BYTE*)((ULONGLONG) modulePtr + d_imps_dir->VirtualAddress);
16 if (d_imps_dir->Size < min_size) {
22 dir_size = d_imps_dir->Size;
26template <
typename T_FIELD,
typename T_IMAGE_THUNK_DATA>
28 BYTE* modulePtr,
const size_t moduleSize,
29 const ULONGLONG img_base,
31 const T_FIELD ordinal_flag,
34 const std::unordered_set<ULONGLONG> &reloc_values
38 LOG_ERROR(
"Invalid IMAGE_DELAYLOAD_DESCRIPTOR");
43 auto convert_va_to_rva = [&](ULONGLONG& addr) ->
bool
45 if (reloc_values.find(addr) != reloc_values.end()) {
46 if (addr < img_base) {
47 LOG_ERROR(
"Invalid VA: 0x%llx cannot convert safely", addr);
58 if (!convert_va_to_rva(iat_addr) || !convert_va_to_rva(thunk_addr)) {
62 if (iat_addr > moduleSize || thunk_addr > moduleSize) {
66 LOG_INFO(
"iat_addr: 0x%llx, thunk_addr: 0x%llx", iat_addr, thunk_addr);
68 T_FIELD* record_va = (T_FIELD*)((ULONGLONG)modulePtr + iat_addr);
69 T_IMAGE_THUNK_DATA* thunk_va = (T_IMAGE_THUNK_DATA*)((ULONGLONG)modulePtr + thunk_addr);
71 for (; ; record_va++, thunk_va++) {
77 if (*record_va == 0)
break;
79 ULONGLONG iat_rva =
static_cast<ULONGLONG
>(*record_va);
80 if (!convert_va_to_rva(iat_rva))
return false;
82 LOG_DEBUG(
"IAT VA: 0x%llx RVA: 0x%llx",
static_cast<unsigned long long>(*record_va),
static_cast<unsigned long long>(iat_rva));
84 const T_FIELD* iat_record_ptr = (T_FIELD*)((ULONGLONG)modulePtr + iat_rva);
89 FARPROC hProc =
nullptr;
90 if (thunk_va->u1.Ordinal & ordinal_flag) {
91 T_FIELD raw_ordinal = thunk_va->u1.Ordinal & (~ordinal_flag);
92 LOG_DEBUG(
"ord: 0x%llx",
static_cast<unsigned long long>(raw_ordinal));
94 hProc = func_resolver->
resolve_func(lib_name, MAKEINTRESOURCEA(raw_ordinal));
98 ULONGLONG name_rva = thunk_va->u1.AddressOfData;
99 if (!convert_va_to_rva(name_rva))
return false;
101 PIMAGE_IMPORT_BY_NAME by_name = (PIMAGE_IMPORT_BY_NAME)((ULONGLONG)modulePtr + name_rva);
103 LOG_ERROR(
"Invalid pointer to IMAGE_IMPORT_BY_NAME");
107 LPSTR func_name =
reinterpret_cast<LPSTR
>(by_name->Name);
114 hProc = func_resolver->
resolve_func(lib_name, func_name);
120 *record_va = (T_FIELD) hProc;
121 LOG_DEBUG(
"Delayload Function resolved");
124 LOG_DEBUG(
"Delayload Function not resolved");
137 bool is_loader64 =
false;
141 if (is_64bit != is_loader64) {
142 LOG_ERROR(
"Loader/Payload bitness mismatch.");
148 if (!func_resolver) {
149 func_resolver = &default_res;
151 size_t table_size = 0;
158 std::unordered_set<ULONGLONG> reloc_values;
163 auto convert_va_to_rva = [&](ULONGLONG& addr) ->
bool
165 if (reloc_values.find(addr) != reloc_values.end()) {
166 if (addr < moduleBase) {
167 LOG_ERROR(
"Invalid VA: 0x%llx cannot convert safely", addr);
175 LOG_DEBUG(
"Delay-import table found, table_size = %zu bytes.", table_size);
178 for (
size_t i = 0; i < max_count; i++) {
185 if (!convert_va_to_rva(dll_name_rva)) {
189 char* dll_name = (
char*)((ULONGLONG) modulePtr + dll_name_rva);
191 LOG_DEBUG(
"Processing delayed imports for: %s", dll_name);
194 is_ok &= parse_delayed_desc<ULONGLONG,IMAGE_THUNK_DATA64>(modulePtr, module_size, moduleBase, dll_name, IMAGE_ORDINAL_FLAG64, desc, func_resolver, reloc_values);
201 is_ok &= parse_delayed_desc<DWORD, IMAGE_THUNK_DATA32>(modulePtr, module_size, moduleBase, dll_name, IMAGE_ORDINAL_FLAG32, desc, func_resolver, reloc_values);
virtual FARPROC resolve_func(LPCSTR lib_name, LPCSTR func_name)=0
bool parse_delayed_desc(BYTE *modulePtr, const size_t moduleSize, const ULONGLONG img_base, LPSTR lib_name, const T_FIELD ordinal_flag, IMAGE_DELAYLOAD_DESCRIPTOR *desc, peconv::t_function_resolver *func_resolver, const std::unordered_set< ULONGLONG > &reloc_values)
Parsing and filling the Delayload Import Table.
struct _IMAGE_DELAYLOAD_DESCRIPTOR IMAGE_DELAYLOAD_DESCRIPTOR
Parsing and filling the Import Table.
Compile-time configurable logging macros for peconv.
#define LOG_DEBUG(fmt,...)
#define LOG_INFO(fmt,...)
#define LOG_ERROR(fmt,...)
bool load_delayed_imports(BYTE *modulePtr, const ULONGLONG moduleBase, t_function_resolver *func_resolver=nullptr)
bool is_valid_string(LPVOID modulePtr, const size_t moduleSize, const CHAR_T *name_ptr, const size_t max_len=260)
bool validate_ptr(IN const void *buffer_bgn, IN size_t buffer_size, IN const void *field_bgn, IN size_t field_size)
DWORD get_image_size(IN const BYTE *payload)
bool process_relocation_table(IN PVOID modulePtr, IN SIZE_T moduleSize, IN RelocBlockCallback *callback)
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)
IMAGE_DELAYLOAD_DESCRIPTOR * get_delayed_imps(IN const BYTE *modulePtr, IN const size_t moduleSize, OUT size_t &dir_size)
Operating on PE file's relocations table.
DWORD ImportAddressTableRVA
Miscellaneous utility functions.