How to read C import directory table

I am trying to create a PE viewer in C ++ and it seems to crash if I try to display the library names in the Import Directory table. It seems that I am not getting the correct DLL pointers that are used by the program.

HANDLE handle = CreateFile("messagebox.exe",GENERIC_READ,0,0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0); DWORD size = GetFileSize(handle,NULL); PVOID virtualpointer = VirtualAlloc(NULL,size,MEM_COMMIT,PAGE_READWRITE); state = ReadFile(handle,virtualpointer,size,&byteread,NULL); CloseHandle(handle); PIMAGE_NT_HEADERS ntheaders = PIMAGE_NT_HEADERS(PCHAR(vpointer) + PIMAGE_DOS_HEADER(vpointer)->e_lfanew); handle = GetCurrentProcess(); DWORD EntryAddr = ntheaders->OptionalHeader.ImageBase + ntheaders->OptionalHeader.AddressOfEntryPoint; DWORD importdir = (DWORD) &(ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]); DWORD va = (DWORD)(ntheaders->OptionalHeader.ImageBase) + ((PIMAGE_DATA_DIRECTORY)dwValueB)->VirtualAddress; LPSTR libname[128]; int i =0; while(((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name) { // get DLL name libname[i] = (LPSTR)(nt->OptionalHeader.ImageBase + ((PIMAGE_IMPORT_DESCRIPTOR)dwValueC)->Name); i++; } 
+6
source share
1 answer

To read the library names in the Import Directory table, you can do the following:

  • Get the base address with memory mapping.
  • Get a pointer to an IMAGE_NT_HEADERS structure.
  • Get a pointer to an IMAGE_SECTION_HEADER structure.

  • DataDirectory is the final 128 bytes of OptionalHeader, which in turn is the final member of the PE IMAGE_NT_HEADERS header. The structure has 2 members that contain the location and size of the data structure.
    If you want to find information about dll names, first find the RVA (Relative Virtual Address) of the Import Directory from the Data Directory , find this address in the data of the source section, and now you have the IMAGE_IMPORT_DESCRIPTOR array. Get the member of this array, which refers to the displayed image, by checking the lines pointed to by the Name fields.

I will not describe the structure of Portable Executable File Format, but you can see the following links:
Microsoft Systems Magazine

Some variables in your code are not declared, and this is confusing, but, adhering to your skeleton code, I wrote it so that it matches your question.

 DWORD Rva2Offset(DWORD rva,PIMAGE_SECTION_HEADER psh,PIMAGE_NT_HEADERS pnt); int _tmain(int argc, _TCHAR* argv[]) { LPCWSTR fNmae=L"C:\\Windows\\system32\\notepad.exe"; HANDLE handle=CreateFile(fNmae/*"messagebox.exe"*/, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); DWORD byteread,size=GetFileSize(handle, NULL); PVOID virtualpointer=VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); ReadFile(handle, virtualpointer, size, &byteread, NULL); CloseHandle(handle); // Get pointer to NT header PIMAGE_NT_HEADERS ntheaders=(PIMAGE_NT_HEADERS)(PCHAR(virtualpointer) + PIMAGE_DOS_HEADER(virtualpointer)-> e_lfanew); PIMAGE_SECTION_HEADER pSech=IMAGE_FIRST_SECTION(ntheaders);//Pointer to first section header PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor; //Pointer to import descriptor __try { if(ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size != 0)/*if size of the table is 0 - Import Table does not exist */ { pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)virtualpointer +\ Rva2Offset(ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,pSech,ntheaders)); LPSTR libname[256]; size_t i=0; // Walk until you reached an empty IMAGE_IMPORT_DESCRIPTOR while(pImportDescriptor->Name != NULL) { printf("Library Name :"); //Get the name of each DLL libname[i]=(PCHAR)((DWORD_PTR)virtualpointer + Rva2Offset(pImportDescriptor->Name,pSech,ntheaders)); printf("%s\n", libname[i]); pImportDescriptor++; //advance to next IMAGE_IMPORT_DESCRIPTOR i++; } } else { printf("No Import Table!\n"); return 1; } } __except(EXCEPTION_EXECUTE_HANDLER) { if(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode()) { printf("Exception: EXCEPTION_ACCESS_VIOLATION\n"); return 1; } } if(virtualpointer) VirtualFree(virtualpointer, size, MEM_DECOMMIT); return 0; } /*Convert Virtual Address to File Offset */ DWORD Rva2Offset(DWORD rva,PIMAGE_SECTION_HEADER psh,PIMAGE_NT_HEADERS pnt) { size_t i = 0; PIMAGE_SECTION_HEADER pSeh; if(rva == 0) { return (rva); } pSeh = psh; for(i = 0; i < pnt->FileHeader.NumberOfSections; i++) { if(rva >= pSeh->VirtualAddress && rva < pSeh->VirtualAddress + pSeh->Misc.VirtualSize) { break; } pSeh++; } return (rva - pSeh->VirtualAddress + pSeh->PointerToRawData); } 
+10
source

All Articles