首页
社区
课程
招聘
[旧帖] [求助]关于PE文件捆绑的问题 0.00雪花
发表于: 2010-3-5 23:58 1140

[旧帖] [求助]关于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。 

我的代码如下:
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直播授课

收藏
免费
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册