-
-
[原创]一款简易的PE-editor
-
发表于: 2013-12-2 22:08 7149
-
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage; PIMAGE_NT_HEADERS32 pNT32 = (PIMAGE_NT_HEADERS32)((LONG)lpImage+pDos->e_lfanew); PIMAGE_OPTIONAL_HEADER32 pOptional = &(pNT32->OptionalHeader); PIMAGE_DATA_DIRECTORY pDirec = (PIMAGE_DATA_DIRECTORY)pOptional->DataDirectory; // 导出表的FOA PIMAGE_EXPORT_DIRECTORY pExp = (PIMAGE_EXPORT_DIRECTORY)((LONG)lpImage+RVA2FOA(lpImage, pDirec->VirtualAddress)); DWORD dwNum = RVA2FOA(lpImage,pExp->AddressOfNameOrdinals); PWORD pNum = (PWORD)(dwNum+(DWORD)lpImage); DWORD pfn = RVA2FOA(lpImage,pExp->AddressOfFunctions); PDWORD pGet = PDWORD(pfn+(DWORD)lpImage); DWORD dwPNames = RVA2FOA(lpImage,pExp->AddressOfNames); PDWORD pdwNames = PDWORD(dwPNames+(DWORD)lpImage); DWORD dwNames = RVA2FOA(lpImage,(DWORD)(*pdwNames)); dwNames = (dwNames)+(DWORD)lpImage; vecDllNum.clear(); vecNames.clear(); vecAdd.clear(); for( DWORD i=0; i<pExp->NumberOfFunctions; i++ ) { if( !(*pGet) ) { pGet++; continue; } int count=0; BOOL bflag = FALSE; for( ; count<pExp->NumberOfNames; count++ ) { if( i==pNum[count] ) { bflag = TRUE; break; } } CString csTempNum; csTempNum.Format(_T("0x%p"),i+pExp->Base); vecDllNum.push_back(csTempNum); csTempNum.Format(_T("0x%p"),*pGet); vecAdd.push_back(csTempNum); CHAR Temp[100]; if( !bflag ) { csTempNum = _T("--"); } else { sprintf_s(Temp,"%s",dwNames); csTempNum = Temp; pdwNames++; dwNames = RVA2FOA(lpImage,(DWORD)(*pdwNames)); dwNames = (dwNames)+(DWORD)lpImage; } vecNames.push_back(csTempNum); pGet++; }
typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; // 0 for terminating null import descriptor DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) } DUMMYUNIONNAME; DWORD TimeDateStamp; // 0 if not bound, // -1 if bound, and real date\time stamp // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) // O.W. date/time stamp of DLL bound to (Old BIND) DWORD ForwarderChain; // -1 if no forwarders DWORD Name; DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) } IMAGE_IMPORT_DESCRIPTOR; typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_THUNK_DATA32 { union { DWORD ForwarderString; // PBYTE DWORD Function; // PDWORD DWORD Ordinal; // 被导入函数的序号 DWORD AddressOfData; // PIMAGE_IMPORT_BY_NAME } u1; } IMAGE_THUNK_DATA32; typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
// 2. 循环遍历导入表 while ( pImport->Name ) { IMPORT_DLL_INFO stcImportInfo; // 2.1 获取导入项DLL名称 PCHAR pszDllName = (PCHAR)((DWORD)lpImage+RVA2FOA(lpImage,pImport->Name)); // 2.2 获取INT PIMAGE_THUNK_DATA32 pINT = (PIMAGE_THUNK_DATA32)((DWORD)lpImage+RVA2FOA(lpImage,(DWORD)pImport->OriginalFirstThunk)); // 2.3 导入项头部信息 dwThunkValue = *pdwThunkValue; stcImportInfo.ThunkOffset.push_back(dwTempThunkOffset); stcImportInfo.ThunkRVA.push_back(dwTempThunkRVA); stcImportInfo.ThunkValue.push_back(dwThunkValue); lvItem.iItem = dwIndex++; CString csDllName; csDllName = pszDllName; lvItem.pszText = (LPWSTR)(LPCWSTR)csDllName; ListView_InsertItem(hListWnd, &lvItem); stcImportInfo.DllName = csDllName; csDllName.Format(_T("0x%p"),pImport->OriginalFirstThunk); ListView_SetItemText(hListWnd,lvItem.iItem,1,(LPWSTR)(LPCWSTR)csDllName); csDllName.Format(_T("0x%p"),pImport->TimeDateStamp); ListView_SetItemText(hListWnd,lvItem.iItem,2,(LPWSTR)(LPCWSTR)csDllName); csDllName.Format(_T("0x%p"),pImport->ForwarderChain); ListView_SetItemText(hListWnd,lvItem.iItem,3,(LPWSTR)(LPCWSTR)csDllName); csDllName.Format(_T("0x%p"),pImport->Name); ListView_SetItemText(hListWnd,lvItem.iItem,4,(LPWSTR)(LPCWSTR)csDllName); csDllName.Format(_T("0x%p"),pImport->FirstThunk); ListView_SetItemText(hListWnd,lvItem.iItem,5,(LPWSTR)(LPCWSTR)csDllName); // 2.4 循环INT的内容 while ( pINT->u1.Ordinal ) { // 2.4.1 判断最高位是否不为1,是的话则打印其AddressOfData的内容 if ( !IMAGE_SNAP_BY_ORDINAL32(pINT->u1.Ordinal) ) { PIMAGE_IMPORT_BY_NAME pByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)lpImage+RVA2FOA(lpImage,pINT->u1.AddressOfData)); //printf( "%04X %s\r\n", pByName->Hint, pByName->Name ); CString csTemp; csTemp.Format(_T("%04x"),pByName->Hint); stcImportInfo.vecHint.push_back(csTemp); csTemp = pByName->Name; stcImportInfo.vecName.push_back(csTemp); dwTempThunkOffset += 4; dwTempThunkRVA += 4; pdwThunkValue++; dwThunkValue = *pdwThunkValue; stcImportInfo.ThunkOffset.push_back(dwTempThunkOffset); stcImportInfo.ThunkRVA.push_back(dwTempThunkRVA); stcImportInfo.ThunkValue.push_back(dwThunkValue); pINT++; continue; } // 2.4.2 如果最高位为1,则直接打印Ordinal部分 CString csTemp; csTemp.Format(_T("--")); stcImportInfo.vecHint.push_back(csTemp); csTemp.Format(_T("%d"),pINT->u1.Ordinal&0x7FFF); stcImportInfo.vecName.push_back(csTemp); dwTempThunkOffset += 4; dwTempThunkRVA += 4; pdwThunkValue++; dwThunkValue = *pdwThunkValue; stcImportInfo.ThunkOffset.push_back(dwTempThunkOffset); stcImportInfo.ThunkRVA.push_back(dwTempThunkRVA); stcImportInfo.ThunkValue.push_back(dwThunkValue); pINT++; continue; // printf( "%04X %s\r\n", pINT->u1.Ordinal&0x0000FFFF, "(Null)" ); // pINT++; } // // 2.5 打印导入项的尾部信息,并将指针加1,使其指向下一项导入表结构 // printf( "====================================\r\n\r\n" ); vecDllInfo.push_back(stcImportInfo); dwTempThunkOffset += 4; dwTempThunkRVA += 4; pdwThunkValue++; dwThunkValue = *pdwThunkValue; pImport++; }
typedef struct _IMAGE_RESOURCE_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; WORD NumberOfNamedEntries; WORD NumberOfIdEntries; // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; } IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { union { struct { DWORD NameOffset:31; DWORD NameIsString:1; } DUMMYSTRUCTNAME; DWORD Name; WORD Id; } DUMMYUNIONNAME; union { DWORD OffsetToData; struct { DWORD OffsetToDirectory:31; DWORD DataIsDirectory:1; } DUMMYSTRUCTNAME2; } DUMMYUNIONNAME2; } IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
// 2. 循环遍历资源表 // 2.1 第一层目录遍历 DWORD dwCount1 = pResource1->NumberOfIdEntries+pResource1->NumberOfNamedEntries; for ( DWORD i=0; i<dwCount1; i++ ) { SRC_1ST stc1st; PIMAGE_RESOURCE_DIRECTORY_ENTRY pDirEntry1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResource1+sizeof(IMAGE_RESOURCE_DIRECTORY)); if ( pDirEntry1[i].NameIsString ) { PIMAGE_RESOURCE_DIR_STRING_U pString = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResource1+pDirEntry1[i].NameOffset); stc1st.csType = pString->NameString; //printf( "Type: %ls", pString->NameString ); //printf("\r\n"); } else { if ( pDirEntry1[i].Name>0x10 ) stc1st.csType.Format(_T("%d"),pDirEntry1[i].Name); //printf( "Type:%04X\r\n", pDirEntry1[i].Name ); else stc1st.csType = szResourceType[pDirEntry1[i].Name]; //printf( "Type:%s\r\n", szResourceType[pDirEntry1[i].Name] ); } if ( pDirEntry1[i].DataIsDirectory ) { SRC_2ND stc2nd; // 2.2 第二层目录的遍历 PIMAGE_RESOURCE_DIRECTORY pResource2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource1+pDirEntry1[i].OffsetToDirectory); DWORD dwCount2 = pResource2->NumberOfIdEntries+pResource2->NumberOfNamedEntries; for ( DWORD j=0; j<dwCount2; j++ ) { PIMAGE_RESOURCE_DIRECTORY_ENTRY pDirEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResource2+sizeof(IMAGE_RESOURCE_DIRECTORY)); if ( pDirEntry2[j].NameIsString ) { PIMAGE_RESOURCE_DIR_STRING_U pString = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResource2+pDirEntry2[j].NameOffset); stc2nd.csID = pString->NameString; //printf( "\tID: %ls", pString->NameString ); //printf("\r\n"); } else { stc2nd.csID.Format(_T("%d"),pDirEntry2[j].Name); //printf( "\tID:%04X\r\n", pDirEntry2[j].Name ); } if ( pDirEntry2[j].DataIsDirectory ) { // 2.3 第三层目录的遍历 PIMAGE_RESOURCE_DIRECTORY pResource3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource1+pDirEntry2[j].OffsetToDirectory); stc2nd.vec3rd.push_back(pResource3); DWORD dwCount3 = pResource3->NumberOfIdEntries+pResource3->NumberOfNamedEntries; for ( DWORD k=0; k< dwCount3; k++ ) { PIMAGE_RESOURCE_DIRECTORY_ENTRY pDirEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResource3+sizeof(IMAGE_RESOURCE_DIRECTORY)); //printf( "\t\tLng:%04X\r\n", pDirEntry3[k].Name ); PIMAGE_RESOURCE_DATA_ENTRY pData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pResource1+pDirEntry3[k].OffsetToData); printf( "\t\tRVA:0x%p Size:%04d Page:0x%p\r\n", pData->OffsetToData, pData->Size, pData->CodePage ); } } else { // .... } stc1st.vec2nd.push_back(stc2nd); } }
// 2. 遍历并执行虚拟重定位操作,并打印结果 while ( pReloc->VirtualAddress ) { dwIndex++; stcReloc.dwIndex = dwIndex; DWORD dwImageBase = pNT32->OptionalHeader.ImageBase; DWORD dwRelocBlockBase = pReloc->VirtualAddress; DWORD dwCount = (pReloc->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/sizeof(WORD); PTYPE_OFFSET pTypeOffset = (PTYPE_OFFSET)((DWORD)pReloc+sizeof(IMAGE_BASE_RELOCATION)); stcReloc.dwRVA = dwRelocBlockBase; stcReloc.dwCount = dwCount; for ( DWORD i=0; i<pNT32->FileHeader.NumberOfSections; i++ ) { if ( dwRelocBlockBase>=pSection[i].VirtualAddress && dwRelocBlockBase<pSection[i].VirtualAddress+pSection[i].Misc.VirtualSize ) { stcReloc.csSection = pSection[i].Name; break; } } vecReloc.push_back(stcReloc); stcRelocDetail.dwFlag = dwIndex; for ( DWORD i=0; i<dwCount; i++ ) { stcRelocDetail.stcTypeOffset.Type = pTypeOffset->Type; stcRelocDetail.stcTypeOffset.Offset = ((pTypeOffset+i)->Offset + dwRelocBlockBase); vecRelocDetail.push_back(stcRelocDetail); } // 指向下一个重定位表的起始地址 pReloc = (PIMAGE_BASE_RELOCATION)((DWORD)pReloc+pReloc->SizeOfBlock); }
- Typedef struct _IMAGE_DOS_HEADER{
- WORD e_magic; // 魔术数字
- WORD e_cblp; // 文件最后页的字节数
- WORD e_cp; // 文件页数
- WORD e_crlc; // 重定义元素个数
- WORD e_cparhdr; // 头部尺寸,以段落为单位
- WORD e_minalloc; // 所需的最小附加段
- WORD e_maxalloc; // 所需的最大附加段
- WORD e_ss; // 初始的SS值(相对偏移量)
- WORD e_sp; // 初始的SP值
- WORD e_csum; // 校验和
- WORD e_ip; // 初始的IP值
- WORD e_cs; // 初始的CS值(相对偏移量)
- WORD e_lfarlc; // 重分配表文件地址
- WORD e_ovno; // 覆盖号
- WORD e_res[4]; // 保留字
- WORD e_oemid; // OEM标识符(相对e_oeminfo)
- WORD e_oeminfo; // OEM信息
- WORD e_res2[10]; // 保留字
- LONG e_lfanew; // 新exe头部的文件地址
- } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
- typedef struct _IMAGE_NT_HEADERS {
- DWORD Signature; //[0x00] PE文件标识
- IMAGE_FILE_HEADER FileHeader; //[0x04]文件头
- IMAGE_OPTIONAL_HEADER32 OptionalHeader; //[0x18]扩展头
- } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
- typedef struct _IMAGE_FILE_HEADER {
- WORD Machine;
- WORD NumberOfSections;
- DWORD TimeDateStamp;
- DWORD PointerToSymbolTable;
- DWORD NumberOfSymbols;
- WORD SizeOfOptionalHeader;
- WORD Characteristics;
- } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
- typedef struct _IMAGE_OPTIONAL_HEADER {
- //
- // Standard fields.
- //
- WORD Magic;
- BYTE MajorLinkerVersion;
- BYTE MinorLinkerVersion;
- DWORD SizeOfCode;
- DWORD SizeOfInitializedData;
- DWORD SizeOfUninitializedData;
- DWORD AddressOfEntryPoint;
- DWORD BaseOfCode;
- DWORD BaseOfData;
- //
- // NT additional fields.
- //
- DWORD ImageBase;
- DWORD SectionAlignment;
- DWORD FileAlignment;
- WORD MajorOperatingSystemVersion;
- WORD MinorOperatingSystemVersion;
- WORD MajorImageVersion;
- WORD MinorImageVersion;
- WORD MajorSubsystemVersion;
- WORD MinorSubsystemVersion;
- DWORD Win32VersionValue;
- DWORD SizeOfImage;
- DWORD SizeOfHeaders;
- DWORD CheckSum;
- WORD Subsystem;
- WORD DllCharacteristics;
- DWORD SizeOfStackReserve;
- DWORD SizeOfStackCommit;
- DWORD SizeOfHeapReserve;
- DWORD SizeOfHeapCommit;
- DWORD LoaderFlags;
- DWORD NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
- } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
- typedef struct _IAMGE_DATA_DIRECTORY
- {
- DWORD VirtualAddress; // 数据块的起始地址
- DWORD Size; // 数据块的长度
- }IAMGE_DATA_DIRECTORY, PIAMGE_DATA_DIRECTORY;
- PIMAGE_SECTION_HEADER pSection1 = IMAGE_FIRST_SECTION(pNT32);
- for( DWORD i=0; i<pImageHeader->NumberOfSections; i++ )
- {
- pSection.push_back(pSection1[i]);
- }
- typedef struct _IMAGE_SECTION_HEADER {
- BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
- union {
- DWORD PhysicalAddress;
- DWORD VirtualSize;
- } Misc;
- DWORD VirtualAddress;
- DWORD SizeOfRawData;
- DWORD PointerToRawData;
- DWORD PointerToRelocations;
- DWORD PointerToLinenumbers;
- WORD NumberOfRelocations;
- WORD NumberOfLinenumbers;
- DWORD Characteristics;
- } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
- 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;
- OriginalFirstThunk : 包含指向INT的RVA,INT是一个IMAGE_THUNK_DATA结构的数组,大多情况下,数组中的每个IMAGE_THUNK_DATA结构会再指向IMAGE_IMPORT_BY_NAME结构,结尾处以全0x00的IMAGE_THUNK_DATA结构结束.
- TimeDateStamp : 一个32位的时间标识,与下一个转发链字段合并工作,否则可以为空。
- ForwarderChain : 转发链,如果不转发则此值为0
- Name : 指向导入文件的名字
- FirstThunk : 指向导入地址表的RVA
- ForwarderString : 负责与导入转发表forwarders协同工作的一个字段。当导入表的ForwarderChain不为0时,此值有效,并指向包含有转发函数与导出这个函数的映像文件名的字符串RVA。
- Function : 导入表导入函数的实际内存地址,此字段仅在此映像被加载,且此结构为IAT的前提下有效。
- Ordinal : 被导入函数的序号
- AddressOfData : 指向IMAGE_IMPORT_BY_NAME结构,当以上3个值都未生效时,此值有效。
- typedef struct _IMAGE_IMPORT_BY_NAME
- {
- WORD Hint; // 需导入的函数序号
- BYTE Name[1]; // 需导入的函数名称
- }IMAGE_IMPORT_BY_NAME, PIMAGE_IMPORT_BY_NAME;
赞赏记录
参与人
雪币
留言
时间
心游尘世外
为你点赞~
2024-5-31 07:02
QinBeast
为你点赞~
2024-5-31 06:53
飘零丶
为你点赞~
2024-5-31 01:24
shinratensei
为你点赞~
2024-5-31 01:06
一笑人间万事
为你点赞~
2023-3-5 04:16
赞赏
他的文章
- [讨论]《0day2》小疑问 12294
- [求助]《0day2》ActiveX绕过SafeSEH实验的问题 14680
- [已解决]《0day2》书中DWORD SHOOT实验的疑问 13554
- 题目为breakpoint的elf逆向问题 6597
- [讨论]fscanf函数的一个问题? 5052
谁下载
谁下载
谁下载
谁下载
看原图
赞赏
雪币:
留言: