Код | #include <tchar.h> #include <windows.h> #include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")
void Parse(const TCHAR *pszFile) { HANDLE hFile = INVALID_HANDLE_VALUE;
if(!pszFile) return;
hFile = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(hFile != INVALID_HANDLE_VALUE) { IMAGE_DOS_HEADER *pDosHdr = NULL; IMAGE_NT_HEADERS *pNtHdr = NULL; IMAGE_IMPORT_DESCRIPTOR *pImport = NULL; IMAGE_EXPORT_DIRECTORY *pExport = NULL;
DWORD size = GetFileSize(hFile, NULL); DWORD dwBytes = 0; DWORD expSize = 0; DWORD expPtr = 0; DWORD impPtr = 0; BYTE* pData = (BYTE*)malloc(size);
if(!pData) { CloseHandle(hFile); return; }
if(!ReadFile(hFile, pData, size, &dwBytes, NULL) || dwBytes != size) goto clean;
pDosHdr = (IMAGE_DOS_HEADER*)pData; if(pDosHdr->e_magic != IMAGE_DOS_SIGNATURE) goto clean;
pNtHdr = (IMAGE_NT_HEADERS*)(pData + pDosHdr->e_lfanew); if(pNtHdr->Signature != IMAGE_NT_SIGNATURE) goto clean;
// // Import // impPtr = pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if(impPtr != 0) { pImport = (IMAGE_IMPORT_DESCRIPTOR*)ImageRvaToVa(pNtHdr, pData, impPtr, NULL);
for (; pImport->Name; ++pImport) { IMAGE_THUNK_DATA *pRVA = NULL;
// Name of import DLL char *pDllName = (char*)ImageRvaToVa(pNtHdr, pData, (ULONG)pImport->Name, NULL);
// Choose appropriate thunk if (pImport->OriginalFirstThunk) pRVA = (IMAGE_THUNK_DATA*)ImageRvaToVa(pNtHdr, pData, (ULONG)pImport->OriginalFirstThunk, NULL); else pRVA = (IMAGE_THUNK_DATA*)ImageRvaToVa(pNtHdr, pData, (ULONG)pImport->FirstThunk, NULL);
while (pRVA->u1.AddressOfData) { void* addr = 0; // Function address IMAGE_IMPORT_BY_NAME* pAddressTable = (IMAGE_IMPORT_BY_NAME*)ImageRvaToVa(pNtHdr, pData, (ULONG)pRVA->u1.AddressOfData, NULL); HMODULE hMod = GetModuleHandleA(pDllName);
if(!hMod) hMod = LoadLibraryA(pDllName);
// Import by name (most significant bit is 0) if ((size_t)pAddressTable < ((size_t)1 << (sizeof(size_t) * 8 - 1)) && pAddressTable->Name[0]) { addr = GetProcAddress(hMod, pAddressTable->Name); } // Import by ordinal else { addr = GetProcAddress(hMod, (char*)((USHORT)pAddressTable & 0xFFFF)); }
pRVA++; } } }
// // Export // expPtr = pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
if(expPtr != 0) { WORD *pAddressOfOrds = NULL; DWORD *pAddressOfNames = NULL; DWORD *pAddressOfFuncs = NULL; DWORD i;
pExport = (IMAGE_EXPORT_DIRECTORY*)ImageRvaToVa(pNtHdr, pData, expPtr, NULL); expSize = pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
pAddressOfOrds = (WORD*) ImageRvaToVa(pNtHdr, pData, pExport->AddressOfNameOrdinals, NULL); pAddressOfNames = (DWORD*)ImageRvaToVa(pNtHdr, pData, pExport->AddressOfNames, NULL); pAddressOfFuncs = (DWORD*)ImageRvaToVa(pNtHdr, pData, pExport->AddressOfFunctions, NULL);
for( i = 0; i < pExport->NumberOfFunctions; ++i ) { WORD OrdIndex = 0xFFFF; char *pName = NULL; size_t pFunc = 0;
// Export by name if(i < pExport->NumberOfNames) { pName = (char*)(pAddressOfNames[i]); OrdIndex = (WORD)pAddressOfOrds[i]; } // Export by index else { OrdIndex = (WORD)i; }
// Function rva pFunc = pAddressOfFuncs[OrdIndex];
// Invalid function pointer if(pFunc == 0) continue;
// Check chained export(function address belongs to export directory address range) if(pFunc >= expPtr && pFunc <= expPtr + expSize) { HMODULE hChainMod = NULL;
char* chainExp = (char*)ImageRvaToVa(pNtHdr, pData, (ULONG)pFunc, NULL); char *strDll = 0; char *strName = 0;
strDll = strtok_s(chainExp, ".", &strName);
// Load target dll hChainMod = (HMODULE)GetModuleHandleA(strDll); if(hChainMod == NULL) hChainMod = LoadLibraryA(strDll);
pFunc = (size_t)GetProcAddress(hChainMod, strName); } else pFunc = (size_t)ImageRvaToVa(pNtHdr, pData, (ULONG)pFunc, NULL); } }
clean: free(pData); CloseHandle(hFile); } }
|
|