Skip to content

Instantly share code, notes, and snippets.

@hasherezade
Created April 7, 2017 18:18
Show Gist options
  • Select an option

  • Save hasherezade/5bfbbc52d9335635d03450ce7a44dda4 to your computer and use it in GitHub Desktop.

Select an option

Save hasherezade/5bfbbc52d9335635d03450ce7a44dda4 to your computer and use it in GitHub Desktop.
Find imported function by address
#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