Created
April 7, 2017 18:18
-
-
Save hasherezade/5bfbbc52d9335635d03450ce7a44dda4 to your computer and use it in GitHub Desktop.
Find imported function by address
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <Windows.h> | |
| #include <TlHelp32.h> | |
| #include <map> | |
| #include <iostream> | |
| #include "peloader/pe_hdrs_helper.h" | |
| /* | |
| class PeModule { | |
| public: | |
| BYTE *start; | |
| size_t size; | |
| std::string moduleName; | |
| PeModule(BYTE *start, size_t size, std::string moduleName) | |
| { | |
| this->start = start; | |
| this->size = size; | |
| this->moduleName = moduleName; | |
| } | |
| }; | |
| */ | |
| size_t enum_modules_in_process(DWORD process_id, std::map<ULONGLONG, MODULEENTRY32> &modulesMap) | |
| { | |
| HANDLE hProcessSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, process_id); | |
| MODULEENTRY32 module_entry = { 0 }; | |
| module_entry.dwSize = sizeof(module_entry); | |
| if (!Module32First(hProcessSnapShot, &module_entry)) { | |
| printf("[ERROR] Fetching modules failed!\n"); | |
| return 0; | |
| } | |
| size_t modules = 1; | |
| modulesMap[(ULONGLONG) module_entry.modBaseAddr] = module_entry; | |
| while (Module32Next(hProcessSnapShot, &module_entry)) { | |
| modulesMap[(ULONGLONG) module_entry.modBaseAddr] = module_entry; | |
| modules++; | |
| } | |
| // Close the handle | |
| CloseHandle(hProcessSnapShot); | |
| return modules; | |
| } | |
| char* get_exported_func(PVOID modulePtr, ULONGLONG searchedRVA) | |
| { | |
| IMAGE_DATA_DIRECTORY *exportsDir = get_pe_directory(modulePtr, IMAGE_DIRECTORY_ENTRY_EXPORT); | |
| if (exportsDir == NULL) return NULL; | |
| DWORD expAddr = exportsDir->VirtualAddress; | |
| if (expAddr == 0) return NULL; | |
| IMAGE_EXPORT_DIRECTORY* exp = (IMAGE_EXPORT_DIRECTORY*)(expAddr + (ULONG_PTR) modulePtr); | |
| SIZE_T namesCount = exp->NumberOfNames; | |
| DWORD funcsListRVA = exp->AddressOfFunctions; | |
| DWORD funcNamesListRVA = exp->AddressOfNames; | |
| DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals; | |
| //go through names: | |
| for (SIZE_T i = 0; i < namesCount; i++) { | |
| DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*) modulePtr + i * sizeof(DWORD)); | |
| WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*) modulePtr + i * sizeof(WORD)); | |
| DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*) modulePtr + (*nameIndex) * sizeof(DWORD)); | |
| LPSTR name = (LPSTR)(*nameRVA + (BYTE*) modulePtr); | |
| if (searchedRVA == (*funcRVA)) { | |
| printf("Found function!\n"); | |
| printf("Name: %s\n", name); | |
| return name; | |
| } | |
| } | |
| //function not found | |
| return NULL; | |
| } | |
| int main(int argc, char *argv[]) | |
| { | |
| ULONGLONG loadBase = 0; | |
| if (argc < 3) { | |
| printf("Required args: <PID> <searched_addr>\n"); | |
| system("pause"); | |
| return -1; | |
| } | |
| DWORD pid = atoi(argv[1]); | |
| if (pid == 0) pid = GetCurrentProcessId(); | |
| printf("PID: %d\n", pid); | |
| ULONGLONG searchedAddr = 0; | |
| if (sscanf(argv[2],"%llX", &searchedAddr) == 0) { | |
| sscanf(argv[2],"%#llX", &searchedAddr); | |
| } | |
| std::map<ULONGLONG, MODULEENTRY32> modulesMap; | |
| int num = enum_modules_in_process(pid, modulesMap); | |
| printf("Counted modules: %d\n", num); | |
| printf("Map size: %d\n", modulesMap.size()); | |
| std::map<ULONGLONG, MODULEENTRY32>::iterator lastEl = modulesMap.lower_bound(searchedAddr); | |
| std::map<ULONGLONG, MODULEENTRY32>::iterator itr1; | |
| HMODULE foundMod = NULL; | |
| for (itr1 = modulesMap.begin(); itr1 != lastEl; itr1++) { | |
| ULONGLONG begin = itr1->first; | |
| ULONGLONG end = itr1->second.modBaseSize + begin; | |
| if (searchedAddr >= begin && searchedAddr < end) { | |
| ULONGLONG searchedRVA = searchedAddr - begin; | |
| printf("Found address in the module: %s\n", itr1->second.szExePath); | |
| printf("Function RVA: %llX\n", searchedRVA); | |
| foundMod = LoadLibraryA(itr1->second.szExePath); | |
| if (foundMod == NULL) { | |
| printf("Loading module failed!\n"); | |
| break; | |
| } | |
| get_exported_func(foundMod, searchedRVA); | |
| break; | |
| } | |
| } | |
| system("pause"); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment