阅读:1685回复:0
ZT---关于PE可执行文件的修改(2)
关于PE可执行文件的修改(2)
[ 作者: ilsy 添加时间: 2001-9-24 9:25:08 ] PE文件头后是节表,在winnt.h下如下定义 typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//节表名称,如“.text” union { DWORD PhysicalAddress; //物理地址 DWORD VirtualSize; //真实长度 } Misc; DWORD VirtualAddress; //RVA DWORD SizeOfRawData; //物理长度 DWORD PointerToRawData; //节基于文件的偏移量 DWORD PointerToRelocations; //重定位的偏移 DWORD PointerToLinenumbers; //行号表的偏移 WORD NumberOfRelocations; //重定位项数目 WORD NumberOfLinenumbers; //行号表的数目 DWORD Characteristics; //节属性 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 以上结构就是在winnt.h中关于PE文件头的定义,如何我们用C/C++来进行PE可执行文件操作,就要用到上面的所有结构,它详细的描述了PE文件头的结构。 3、修改PE可执行文件 现在让我们把一段代码写入任何一个PE格式的可执行文件,代码如下: -- test.asm -- .386p .model flat, stdcall option casemap:none include \\masm32\\include\\windows.inc include \\masm32\\include\\user32.inc includelib \\masm32\\lib\\user32.lib .code start: INVOKE MessageBoxA,0,0,0,MB_ICONINFORMATION or MB_OK ret end start 以上代码只显示一个MessageBox框,编译后得到二进制代码如下: unsigned char writeline[18]={ 0x6a,0x40,0x6a,0x0,0x6a,0x0,0x6a,0x0,0xe8,0x01,0x0,0x0,0x0,0xe9,0x0,0x0,0x0,0x0 }; 好,现在让我们看看该把这些代码写到那。现在用Tdump.exe显示一个PE格式得可执行文件信息,可以发现如下描述: Object table: # Name VirtSize RVA PhysSize Phys off Flags -- -------- -------- -------- -------- -------- -------- 01 .text 0000CCC0 00001000 0000CE00 00000600 60000020 [CER] 02 .data 00004628 0000E000 00002C00 0000D400 C0000040 [IRW] 03 .rsrc 000003C8 00013000 00000400 00010000 40000040 [IR] Key to section flags: C - contains code E - executable I - contains initialized data R - readable W - writeable 上面描述此文件中存在3个段及每个段得信息,实际上我们的代码可以写入任何一个段,这里我选择“.text”段。 用如下代码得到一个PE格式可执行文件的头信息: //writePE.cpp #include <windows.h> #include <stdio.h> #include <io.h> #include <fcntl.h> #include <time.h> #include <SYS\\STAT.H> unsigned char writeline[18]={ 0x6a,0x40,0x6a,0x0,0x6a,0x0,0x6a,0x0,0xe8,0x01,0x0,0x0,0x0,0xe9,0x0,0x0,0x0,0x0 }; DWORD space; DWORD entryaddress; DWORD entrywrite; DWORD progRAV; DWORD oldentryaddress; DWORD newentryaddress; DWORD codeoffset; DWORD peaddress; DWORD flagaddress; DWORD flags; DWORD virtsize; DWORD physaddress; DWORD physsize; DWORD MessageBoxAadaddress; int main(int argc,char * * argv) { HANDLE hFile, hMapping; void *basepointer; FILETIME * Createtime; FILETIME * Accesstime; FILETIME * Writetime; Createtime = new FILETIME; Accesstime = new FILETIME; Writetime = new FILETIME; if ((hFile = CreateFile(argv[1], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) == INVALID_HANDLE_VALUE)//打开要修改的文件 { puts(\"(could not open)\"); return EXIT_FAILURE; } if(!GetFileTime(hFile,Createtime,Accesstime,Writetime)) { printf(\"\\nerror getfiletime: %d\\n\",GetLastError()); } //得到要修改文件的创建、修改等时间 if (!(hMapping = CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0))) { puts(\"(mapping failed)\"); CloseHandle(hFile); return EXIT_FAILURE; } if (!(basepointer = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0))) { puts(\"(view failed)\"); CloseHandle(hMapping); CloseHandle(hFile); return EXIT_FAILURE; } //把文件头映象存入baseointer CloseHandle(hMapping); CloseHandle(hFile); map_exe(basepointer);//得到相关地址 UnmapViewOfFile(basepointer); printaddress(); printf(\"\\n\\n\"); if(space<50) { printf(\"\\n空隙太小,数据不能写入.\\n\"); } else { writefile();//写文件 } if ((hFile = CreateFile(argv[1], GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) == INVALID_HANDLE_VALUE) { puts(\"(could not open)\"); return EXIT_FAILURE; } if(!SetFileTime(hFile,Createtime,Accesstime,Writetime)) { printf(\"error settime : %d\\n\",GetLastError()); } //恢复修改后文件的建立时间等 |
|
最新喜欢:why_wh...
|