8void ExportsMapper::print_va_to_func(std::stringstream &stream)
const
10 std::map<ULONGLONG, std::set<ExportedFunc>>::const_iterator itr;
14 stream << std::hex << itr->first <<
" :\n";
16 std::set<ExportedFunc>::const_iterator itr2;
17 const std::set<ExportedFunc> &funcs = itr->second;
19 for (itr2 = funcs.begin(); itr2 != funcs.end(); ++itr2) {
20 stream <<
"\t" << itr2->toString() <<
"\n";
27 std::map<ExportedFunc, ULONGLONG>::const_iterator itr;
29 stream << itr->first.toString() <<
" : "
30 << std::hex << itr->second <<
"\n";
34ULONGLONG
rebase_va(ULONGLONG va, ULONGLONG currBase, ULONGLONG targetBase)
36 if (currBase == targetBase) {
39 ULONGLONG rva = va - (ULONGLONG) currBase;
40 return rva + targetBase;
43size_t ExportsMapper::make_ord_lookup_tables(
46 std::map<PDWORD, DWORD> &va_to_ord
50 if (exp == NULL)
return 0;
52 SIZE_T functCount = exp->NumberOfFunctions;
53 DWORD funcsListRVA = exp->AddressOfFunctions;
54 DWORD ordBase = exp->Base;
57 for (DWORD i = 0; i < functCount; i++) {
58 DWORD* recordRVA = (DWORD*)(funcsListRVA + (BYTE*) modulePtr + i *
sizeof(DWORD));
59 if (*recordRVA == 0) {
61 std::cout <<
">>> Skipping 0 function address at RVA:" << std::hex << (BYTE*)recordRVA - (BYTE*)modulePtr<<
"(ord)\n";
69 DWORD ordinal = ordBase + i;
70 va_to_ord[recordRVA] = ordinal;
75size_t ExportsMapper::resolve_forwarders(
const ULONGLONG va,
ExportedFunc &currFunc)
79 std::map<ExportedFunc, std::set<ExportedFunc>>::iterator fItr =
forwarders_lookup.find(currFunc);
82 std::set<ExportedFunc>::iterator sItr;
83 for (sItr = fItr->second.begin(); sItr != fItr->second.end(); ++sItr) {
92bool ExportsMapper::add_forwarded(
ExportedFunc &currFunc, DWORD callRVA, PBYTE modulePtr,
size_t moduleSize)
94 PBYTE fPtr = modulePtr + callRVA;
102 if (forwardedFunc.length() == 0) {
107 if (!forwarder.isValid()) {
109 std::cerr <<
"Skipped invalid forwarder" << std::endl;
122DWORD
get_ordinal(PDWORD recordPtr, std::map<PDWORD, DWORD> &va_to_ord)
124 std::map<PDWORD, DWORD>::iterator ord_itr = va_to_ord.find(recordPtr);
125 if (ord_itr == va_to_ord.end()) {
129 DWORD ordinal = ord_itr->second;
130 va_to_ord.erase(ord_itr);
134bool ExportsMapper::add_to_maps(ULONGLONG va,
ExportedFunc &currFunc)
137 resolve_forwarders(va, currFunc);
143 if (exp ==
nullptr)
return false;
145 const SIZE_T namesCount = exp->NumberOfNames;
146 const SIZE_T funcCount = exp->NumberOfFunctions;
148 const DWORD funcsListRVA = exp->AddressOfFunctions;
149 const DWORD funcNamesListRVA = exp->AddressOfNames;
150 const DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals;
152 for (DWORD i = 0; i < funcCount; i++) {
153 DWORD* recordRVA = (DWORD*)(funcsListRVA + (BYTE*)modulePtr + i *
sizeof(DWORD));
159 for (SIZE_T i = 0; i < namesCount; i++) {
160 DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*)modulePtr + i *
sizeof(DWORD));
161 WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*)modulePtr + i *
sizeof(WORD));
167 DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*)modulePtr + (*nameIndex) *
sizeof(DWORD));
176ExportsMapper::ADD_FUNC_RES ExportsMapper::add_function_to_lookup(HMODULE modulePtr, ULONGLONG moduleBase,
size_t moduleSize,
ExportedFunc &currFunc, DWORD callRVA)
178 if (add_forwarded(currFunc, callRVA, (BYTE*)modulePtr, moduleSize)) {
180 char* fPtr = (
char*)modulePtr + callRVA;
181 std::cout <<
"FWD " << currFunc.
toString() <<
" -> " << fPtr <<
"\n";
183 return ExportsMapper::RES_FORWARDED;
186 ULONGLONG callVa = callRVA + moduleBase;
190 std::cout <<
"Validation failed: " << currFunc.
toString() <<
"\n";
192 return ExportsMapper::RES_INVALID;
195 add_to_maps(callVa, currFunc);
196 return ExportsMapper::RES_MAPPED;
212 std::map<PDWORD, DWORD> va_to_ord;
213 size_t functCount = make_ord_lookup_tables(modulePtr, module_size, va_to_ord);
217 size_t forwarded_ctr = 0;
218 SIZE_T namesCount = exp->NumberOfNames;
220 DWORD funcsListRVA = exp->AddressOfFunctions;
221 DWORD funcNamesListRVA = exp->AddressOfNames;
222 DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals;
224 size_t mapped_ctr = 0;
226 for (SIZE_T i = 0; i < namesCount; i++) {
227 DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*) modulePtr + i *
sizeof(DWORD));
228 WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*) modulePtr + i *
sizeof(WORD));
229 DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*) modulePtr + (*nameIndex) *
sizeof(DWORD));
232 std::cout <<
">>> Skipping 0 function address at RVA:" << std::hex << (BYTE*)funcRVA - (BYTE*)modulePtr <<
"(name)\n";
238 LPSTR name = (LPSTR)(*nameRVA + (BYTE*) modulePtr);
242 DWORD callRVA = *funcRVA;
245 int res = add_function_to_lookup(modulePtr, moduleBase, module_size, currFunc, callRVA);
246 if (res == ExportsMapper::RES_FORWARDED) forwarded_ctr++;
247 if (res == ExportsMapper::RES_MAPPED) mapped_ctr++;
250 std::map<PDWORD, DWORD>::iterator ord_itr = va_to_ord.begin();
251 for (;ord_itr != va_to_ord.end(); ++ord_itr) {
253 DWORD* funcRVA = ord_itr->first;
254 DWORD callRVA = *funcRVA;
257 int res = add_function_to_lookup(modulePtr, moduleBase, module_size, currFunc, callRVA);
258 if (res == ExportsMapper::RES_FORWARDED) forwarded_ctr++;
259 if (res == ExportsMapper::RES_MAPPED) mapped_ctr++;
262 std::cout <<
"Finished exports parsing, mapped: "<< mapped_ctr <<
" forwarded: " << forwarded_ctr << std::endl;
std::string toString() const
std::map< std::string, std::string > dll_shortname_to_path
size_t add_to_lookup(std::string moduleName, HMODULE modulePtr, ULONGLONG moduleBase)
void associateVaAndFunc(ULONGLONG va, const ExportedFunc &func)
std::map< ExportedFunc, ULONGLONG > func_to_va
void print_func_to_va(std::stringstream &stream) const
std::map< ExportedFunc, std::set< ExportedFunc > > forwarders_lookup
std::map< ULONGLONG, std::set< ExportedFunc > > va_to_func
ULONGLONG rebase_va(ULONGLONG va, ULONGLONG currBase, ULONGLONG targetBase)
bool is_valid_export_table(IMAGE_EXPORT_DIRECTORY *exp, HMODULE modulePtr, const size_t module_size)
DWORD get_ordinal(PDWORD recordPtr, std::map< PDWORD, DWORD > &va_to_ord)
A definition of ExportsMapper class. Creates a lookup of all the exported functions from the supplied...
bool validate_ptr(IN const void *buffer_bgn, IN SIZE_T buffer_size, IN const void *field_bgn, IN SIZE_T field_size)
size_t forwarder_name_len(BYTE *fPtr)
DWORD get_image_size(IN const BYTE *payload)
std::string format_dll_func(const std::string &str)
IMAGE_EXPORT_DIRECTORY * get_export_directory(IN HMODULE modulePtr)
std::string get_dll_shortname(const std::string &str)