Last active
August 25, 2016 18:02
-
-
Save hasherezade/d54e0218962555d1b7287c8583ec0c10 to your computer and use it in GitHub Desktop.
Search function in exports
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
| #pragma once | |
| #include <Windows.h> | |
| //WARNIG: we don't want to use any imported functions in here! | |
| #include "pe_hdrs_helper.h" | |
| /* | |
| typedef struct _IMAGE_EXPORT_DIRECTORY { | |
| DWORD Characteristics; | |
| DWORD TimeDateStamp; | |
| WORD MajorVersion; | |
| WORD MinorVersion; | |
| DWORD Name; | |
| DWORD Base; | |
| DWORD NumberOfFunctions; | |
| DWORD NumberOfNames; | |
| DWORD AddressOfFunctions; // RVA from base of image | |
| DWORD AddressOfNames; // RVA from base of image | |
| DWORD AddressOfNameOrdinals; // RVA from base of image | |
| } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; | |
| */ | |
| #ifndef TO_LOWERCASE | |
| #define TO_LOWERCASE(c1) c1 = (c1 <= 'Z' && c1 >= 'A') ? c1 = (c1 - 'A') + 'a': c1; | |
| #endif | |
| bool is_wanted(LPSTR curr_name, LPSTR wanted_name) | |
| { | |
| if (curr_name == NULL || wanted_name == NULL) return false; | |
| SIZE_T wanted_name_len = strlen(wanted_name); | |
| SIZE_T curr_name_len = strlen(curr_name); | |
| if (curr_name_len < wanted_name_len) return false; | |
| for (size_t i = 0; i < wanted_name_len && i < curr_name_len; i++) { | |
| char c1 = curr_name[i]; | |
| char c2 = wanted_name[i]; | |
| //tolower: | |
| TO_LOWERCASE(c1); | |
| TO_LOWERCASE(c2); | |
| if (c1 != c2) return false; | |
| } | |
| return true; | |
| } | |
| LPSTR get_func_name(PVOID modulePtr, DWORD funcNamesAddr, DWORD namesOrdsAddr, DWORD myOrdinal, DWORD nameOrdinal ) | |
| { | |
| DWORD offset = sizeof(DWORD) * (nameOrdinal - 1); | |
| DWORD* funcNameRVA = (DWORD*)(funcNamesAddr + (BYTE*) modulePtr + offset); | |
| DWORD nameRVA = *funcNameRVA; | |
| if (nameRVA == NULL) return NULL; | |
| LPSTR name = (LPSTR)(nameRVA + (BYTE*) modulePtr); | |
| //printf("Got name: %s | %d\n", name, nameOrdinal); | |
| return name; | |
| } | |
| SIZE_T ord_lookup(PVOID modulePtr, SIZE_T funcCount, DWORD namesOrdsAddr, DWORD myOrd) | |
| { | |
| for (SIZE_T i = 0; i < funcCount; i++) { | |
| WORD* funcOrdRVA = (WORD*)(namesOrdsAddr + (BYTE*) modulePtr + i * sizeof(WORD)); | |
| if (*funcOrdRVA == myOrd) return i; | |
| } | |
| return -1; | |
| } | |
| PVOID get_exported_func(PVOID modulePtr, LPSTR wanted_name) | |
| { | |
| IMAGE_DATA_DIRECTORY *exportsDir = get_pe_directory(modulePtr, IMAGE_DIRECTORY_ENTRY_EXPORT); | |
| if (exportsDir == NULL) return NULL; | |
| DWORD maxSize = exportsDir->Size; | |
| DWORD parsedSize = 0; | |
| DWORD expAddr = exportsDir->VirtualAddress; | |
| if (expAddr == 0) return NULL; | |
| IMAGE_EXPORT_DIRECTORY* exp = (IMAGE_EXPORT_DIRECTORY*)(expAddr + (ULONG_PTR) modulePtr); | |
| SIZE_T funcCount = exp->NumberOfFunctions; | |
| DWORD funcsAddr = exp->AddressOfFunctions; | |
| DWORD funcNamesAddr = exp->AddressOfNames; | |
| DWORD namesOrdsAddr = exp->AddressOfNameOrdinals; | |
| //printf("---EXP---\n"); | |
| DWORD offset = 0; | |
| for (SIZE_T i = 0; i < funcCount; i++, offset+=sizeof(DWORD)) { | |
| DWORD* funcRVA = (DWORD*)(funcsAddr + (BYTE*) modulePtr + offset); | |
| DWORD* funcNameRVA = (DWORD*)(funcNamesAddr + (BYTE*) modulePtr + offset); | |
| WORD* funcOrdRVA = (WORD*)(namesOrdsAddr + (BYTE*) modulePtr + i*sizeof(WORD)); | |
| if (*funcRVA == NULL || *funcNameRVA == NULL) return NULL; | |
| DWORD nameRVA = *funcNameRVA; | |
| DWORD func = (*funcRVA); | |
| WORD ordinal = (*funcOrdRVA); | |
| if (ordinal == 0) { | |
| continue; | |
| } | |
| DWORD myOrdinal = i + exp->Base; | |
| SIZE_T foundPos = ord_lookup( modulePtr, funcCount, namesOrdsAddr, myOrdinal); | |
| if (foundPos == -1) return NULL; | |
| //printf("Found Pos: %d\n", foundPos); | |
| DWORD nameOrdinal = ordinal; | |
| LPSTR name = get_func_name(modulePtr, funcNamesAddr, namesOrdsAddr, myOrdinal, foundPos); | |
| if (is_wanted(name, wanted_name)) { | |
| //printf("Exported %d ord:%d | name: %s | func: %x\n", myOrdinal, ordinal, name, func); | |
| return (BYTE*) modulePtr + func; | |
| } | |
| } | |
| //printf("Func not found!\n"); | |
| //printf("---------\n"); | |
| return NULL; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment