导入表有些复杂,文件与内存中的格式不太一样
理解导入表的结构是关键
void TestPrintImportDirectory(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew); pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4); pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader); pDataDirectory = pOptionHeader->DataDirectory; //IMAGE_DIRECTORY_ENTRY_IMPORT /* #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory */ //确定导入表 //pImportDirectory = NULL; IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress; DWORD ImportFoa = RVAToFileOffset(pFileBuffer,ImportVirtualAddress); printf("ImportVirtualAddress: %x \n",ImportVirtualAddress); printf("Size: %x \n",pImportDirectory.Size); printf("ImportFoa: %x \n",ImportFoa); //输出所有的导入表 //PIMAGE_THUNK_DATA32 pThunkData = NULL; //第一个导入表 PIMAGE_IMPORT_DESCRIPTOR pImportDes = NULL; pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + ImportFoa); while(pImportDes->OriginalFirstThunk != 0x0 && pImportDes->FirstThunk != 0x0 ) { //输出所有的dll printf("OriginalFirstThunk: %x\n",pImportDes->OriginalFirstThunk); DWORD pNameAddress = RVAToFileOffset(pFileBuffer,pImportDes->Name); PSTR pDllName = (PSTR)((DWORD)pFileBuffer + pNameAddress); printf("name: %s \n",pDllName); printf("------------------------------------------\n"); //输出OriginalFirstThunk的信息 DWORD Thunk_Address = RVAToFileOffset(pFileBuffer,pImportDes->OriginalFirstThunk); PIMAGE_THUNK_DATA32 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + Thunk_Address); //根据pThunkData 的最高为来判断 DWORD ImportOrdinal = pThunkData->u1.Ordinal; while(ImportOrdinal) { //输出所有所有的信息 //#define IMAGE_ORDINAL_FLAG32 0x80000000 if(ImportOrdinal & IMAGE_ORDINAL_FLAG32) { printf("按序号导入:%x\n",ImportOrdinal&0x0FFF); }else { DWORD ImageNameAddress = RVAToFileOffset(pFileBuffer,ImportOrdinal); PIMAGE_IMPORT_BY_NAME pImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+ImageNameAddress); printf("按名字导入:%x - %s \n",pImageName->Hint,pImageName->Name); } //向下移动 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pThunkData + 4); ImportOrdinal = pThunkData->u1.Ordinal; } printf("------------------------------------------\n"); //printf("FirstThunk:%x \n",pImportDes->FirstThunk); DWORD pFirstThunk = (DWORD)pImportDes->FirstThunk; printf("FirstThunk:%x \n",pImportDes->FirstThunk); printf("------------------------------------------\n"); DWORD FirstThunk_Address = RVAToFileOffset(pFileBuffer,pFirstThunk); PIMAGE_THUNK_DATA32 pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + FirstThunk_Address); DWORD newImportOrdinal = pNewThunkData->u1.Ordinal; while(newImportOrdinal) { //输出所有所有的信息 //#define IMAGE_ORDINAL_FLAG32 0x80000000 if(newImportOrdinal & IMAGE_ORDINAL_FLAG32) { printf("按序号导入:%x\n",newImportOrdinal&0x0FFF); }else { DWORD newImageNameAddress = RVAToFileOffset(pFileBuffer,newImportOrdinal); PIMAGE_IMPORT_BY_NAME pNewImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+newImageNameAddress); printf("按名字导入:%x - %s \n",pNewImageName->Hint,pNewImageName->Name); } //向下移动 pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pNewThunkData + 4); newImportOrdinal = pNewThunkData->u1.Ordinal; } printf("------------------------------------------\n"); pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDes + 20); getchar(); } }
0则评论给“打印PE导入表信息”