10 template <
typename FIELD_T>
11 size_t fetch_callbacks_list(IN PVOID modulePtr, IN
size_t moduleSize, IN DWORD callbacks_rva, OUT std::vector<ULONGLONG> &tls_callbacks)
13 FIELD_T* callbacks_list_ptr = (FIELD_T*)(callbacks_rva + (BYTE*)modulePtr);
14 if (!
validate_ptr(modulePtr, moduleSize, callbacks_list_ptr,
sizeof(FIELD_T))) {
18 for (FIELD_T *next_callback = callbacks_list_ptr;
19 validate_ptr(modulePtr, moduleSize, next_callback,
sizeof(FIELD_T));
22 FIELD_T value = *next_callback;
23 if (value == 0)
break;
25 tls_callbacks.push_back(value);
32size_t peconv::list_tls_callbacks(IN PBYTE modulePtr, IN
size_t moduleSize, OUT std::vector<ULONGLONG> &tls_callbacks, IN std::unordered_set<ULONGLONG>* _relocs)
34 const ULONGLONG img_base = (ULONGLONG)modulePtr;
36 if (!img_size)
return 0;
38 if (moduleSize == 0) {
39 moduleSize = img_size;
41 IMAGE_TLS_DIRECTORY* tls_dir = peconv::get_type_directory<IMAGE_TLS_DIRECTORY>((HMODULE)modulePtr, IMAGE_DIRECTORY_ENTRY_TLS);
42 if (!tls_dir)
return 0;
44 ULONGLONG callbacks_addr = tls_dir->AddressOfCallBacks;
45 if (!callbacks_addr)
return 0;
46 LOG_DEBUG(
"TLS Callbacks Table: 0x%llx.", (
unsigned long long)callbacks_addr);
47 DWORD callbacks_rva = 0;
48 if (!
virtual_addr_to_rva((PBYTE)modulePtr, img_size, callbacks_addr, callbacks_rva, _relocs))
return 0;
49 LOG_DEBUG(
"TLS Callbacks RVA: 0x%llx.", (
unsigned long long)callbacks_rva);
52 counter = fetch_callbacks_list<ULONGLONG>(modulePtr, moduleSize, callbacks_rva, tls_callbacks);
55 counter = fetch_callbacks_list<DWORD>(modulePtr, moduleSize, callbacks_rva, tls_callbacks);
63 if (moduleSize == 0) {
64 moduleSize = img_size;
67 std::unordered_set<ULONGLONG> reloc_values;
71 std::vector<ULONGLONG> tls_callbacks;
76 std::vector<ULONGLONG>::iterator itr;
78 for (itr = tls_callbacks.begin(); itr != tls_callbacks.end(); ++itr, i++) {
79 ULONGLONG callback_addr = *itr;
86 LOG_DEBUG(
"TLS RVA: 0x%llx.", (
unsigned long long)rva);
87 ULONG_PTR callback_va = rva + (ULONG_PTR)modulePtr;
88 if (!
validate_ptr(modulePtr, moduleSize, (BYTE*)callback_va,
sizeof(BYTE))) {
92 void(NTAPI *callback_func)(PVOID DllHandle, DWORD dwReason, PVOID) = (
void(NTAPI *)(PVOID, DWORD, PVOID)) (callback_va);
93 LOG_INFO(
"Calling TLS callback[%zu].", i);
94 callback_func(modulePtr, dwReason, NULL);
Compile-time configurable logging macros for peconv.
#define LOG_DEBUG(fmt,...)
#define LOG_INFO(fmt,...)
bool virtual_addr_to_rva(IN const PBYTE imgBase, IN const size_t imgSize, IN ULONGLONG virtualAddr, OUT DWORD &outRVA, IN std::unordered_set< ULONGLONG > *relocs=nullptr)
size_t list_tls_callbacks(IN PBYTE modulePtr, IN size_t moduleSize, OUT std::vector< ULONGLONG > &tls_callbacks, IN std::unordered_set< ULONGLONG > *relocs)
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)
size_t fetch_callbacks_list(IN PVOID modulePtr, IN size_t moduleSize, IN DWORD callbacks_rva, OUT std::vector< ULONGLONG > &tls_callbacks)
bool is64bit(IN const BYTE *pe_buffer)
size_t run_tls_callbacks(IN PBYTE modulePtr, IN size_t moduleSize=0, IN DWORD dwReason=DLL_PROCESS_ATTACH)
Wrappers over various fields in the PE header. Read, write, parse PE headers.
Operating on PE file's relocations table.
Functions related to TLS Callbacks.