-
-
[旧帖] [求助]关于PE文件捆绑的问题 0.00雪花
-
发表于: 2010-3-5 23:58 1140
-
在《Windows应用程序捆绑核心编程》一书的11章,讲的是可执行文件捆绑,其中提到了可运行式捆绑。原文如下:
(1)可运行式捆绑
这类捆绑方式是指Attach可以运行,也可以用加载的方式进行捆绑。
对PE文件捆绑的过程为,先把Target.exe的入口地址取出,把他保存到Attach出口,再把Attach捆绑后的起始点地址写到Target.exe的入口。这样当Target.exe运行时,Attach首先获得运行权,当Attach完成所有操作后再把运行权交还给Target.exe。
我的代码如下:
这样做不对,但新的节表已经插入。求大牛给改改。我在CSDN上也发帖问过,好像没人会。
郁闷好几天了。(备注:上面的代码页出自本论坛,我只是改了下)
(1)可运行式捆绑
这类捆绑方式是指Attach可以运行,也可以用加载的方式进行捆绑。
对PE文件捆绑的过程为,先把Target.exe的入口地址取出,把他保存到Attach出口,再把Attach捆绑后的起始点地址写到Target.exe的入口。这样当Target.exe运行时,Attach首先获得运行权,当Attach完成所有操作后再把运行权交还给Target.exe。
我的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #include <windows.h> #include <stdio.h> #include <iostream.h> #include <winnt.h> // 判断文件是否为合法PE文件 BOOL CheckPe(FILE* pFile) { fseek(pFile,0,SEEK_SET); BOOL bFlags=FALSE; WORD IsMZ; DWORD IsPE,pNT; fread(&IsMZ,sizeof(WORD),1,pFile); if (IsMZ==0x5A4D) { fseek(pFile,0x3c,SEEK_SET); fread(&pNT,sizeof(DWORD),1,pFile); fseek(pFile,pNT,SEEK_SET); fread(&IsPE,sizeof(DWORD),1,pFile); if (IsPE==0X00004550) bFlags=TRUE; else bFlags=FALSE; } else bFlags=FALSE; fseek(pFile,0,SEEK_SET); return bFlags; } // 用来计算对齐数据后的大小 int alig(int size,unsigned int align) { if (size%align!=0) return (size /align +1)*align; else return size; } int main() { FILE *rwFile,*fp_read; char buff[1024]={0}; char szPath[] = ".\\calc.exe" ; int nread = 0 , sum = 0; if ((rwFile=fopen(szPath, "rb " ))==NULL) // 打开文件失败则退出 { printf ( "Open file faild\n " ); fclose(rwFile); return 0; } if (!CheckPe(rwFile)) { printf ( "invalid pe......!\n " ); fclose(rwFile); return 0; } char szNewFile[10]= "_New.exe " ; if (!CopyFile(szPath,szNewFile,0)) // 若备份文件出错则退出 { printf ( "bak faild\n " ); fclose(rwFile); return 0; } IMAGE_NT_HEADERS NThea; fseek(rwFile,0x3c,0); DWORD pNT; //pNT 中存放IMAGE_NT_HEADERS结构的地址 fread(&pNT,sizeof(DWORD),1,rwFile); fseek(rwFile,pNT,0); fread(&NThea,sizeof(IMAGE_NT_HEADERS),1,rwFile); // 读取原文件的IMAGE_NT_HEADERS结构 // 保存原文件区块数量与OEP int nOldSectionNo=NThea.FileHeader.NumberOfSections; int OEP=NThea.OptionalHeader.AddressOfEntryPoint; // 保存文件对齐值与区块对齐值 int SECTION_ALIG=NThea.OptionalHeader.SectionAlignment; int FILE_ALIG=NThea.OptionalHeader.FileAlignment; // 定义要添加的区块 IMAGE_SECTION_HEADER NewSection; // 将该结构全部清零 memset(&NewSection, 0, sizeof(IMAGE_SECTION_HEADER)); // 再定义一个区块,来存放原文件最后一个区块的信息 IMAGE_SECTION_HEADER SEChea; // 读原文件最后一个区块的信息 fseek(rwFile,pNT+248,0); for (int i=0;i <nOldSectionNo;i++) fread(&SEChea,sizeof(IMAGE_SECTION_HEADER),1,rwFile); FILE *newfile=fopen(szNewFile, "rb+ " ); if (newfile==NULL) { printf ( "Open bak file faild\n " ); fclose(rwFile); return 0; } fseek(newfile,SEChea.PointerToRawData+SEChea.SizeOfRawData,SEEK_SET); // 写入文件 if ((fp_read=fopen( ".\\notepad.exe" , "rb" ))==NULL) { printf ( "Cann't open notepad.exe !" ); return 0; } while ((nread=fread(buff,sizeof(char),1024,fp_read))>0) { fwrite(buff,sizeof(char),nread,newfile); sum = sum +nread; } NewSection.VirtualAddress=SEChea.VirtualAddress+alig(SEChea.Misc.VirtualSize,SECTION_ALIG); BYTE jmp = 0xE9; OEP=OEP-(NewSection.VirtualAddress+ sum )-5; // 计算相对偏移 fwrite(&jmp, sizeof(jmp), 1, newfile); fwrite(&OEP, sizeof(OEP), 1, newfile); // 将最后增加的数据用0填充至按文件中对齐的大小 for (i=0;i <alig( sum ,FILE_ALIG)- sum -5;i++) fputc( '\0 ' ,newfile); // 新区块中的数据 strcpy((char*)NewSection.Name, ".llydd " ); NewSection.PointerToRawData=SEChea.PointerToRawData+SEChea.SizeOfRawData; NewSection.Misc.VirtualSize= sum ; NewSection.SizeOfRawData=alig( sum ,FILE_ALIG); NewSection.Characteristics=0xE0000020; // 新区块可读可写可执行 fseek(newfile,pNT+248+sizeof(IMAGE_SECTION_HEADER)*nOldSectionNo,0); // 写入新的块表 fwrite(&NewSection,sizeof(IMAGE_SECTION_HEADER),1,newfile); int nNewImageSize=NThea.OptionalHeader.SizeOfImage+alig( sum ,SECTION_ALIG); int nNewSizeofCode=NThea.OptionalHeader.SizeOfCode+alig( sum ,FILE_ALIG); fseek(newfile,pNT,0); NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress=0; NThea.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size=0; NThea.OptionalHeader.SizeOfCode=nNewSizeofCode; NThea.OptionalHeader.SizeOfImage=nNewImageSize; NThea.FileHeader.NumberOfSections=nOldSectionNo+1; NThea.OptionalHeader.AddressOfEntryPoint=NewSection.VirtualAddress; // 写入更新后的PE头结构 fwrite(&NThea,sizeof(IMAGE_NT_HEADERS),1,newfile); printf ( "ok.........!\n " ); fclose(fp_read); fclose(newfile); fclose(rwFile); return 1; } |
这样做不对,但新的节表已经插入。求大牛给改改。我在CSDN上也发帖问过,好像没人会。
郁闷好几天了。(备注:上面的代码页出自本论坛,我只是改了下)
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
赞赏
雪币:
留言: