PE简单解析
代码
1
2 typedef struct peinfo
3 {
4 IMAGE_DOS_HEADER dosHeader;
5 IMAGE_NT_HEADERS ntHeader;
6
7 DWORD curPos;
8 DWORD dwRvaOep;
9 } peinfo;
10
11 peinfo pefile;
12
13 DWORD dwReadSize;
14
15 //读取DOS头,并判断是否是一个PE文件
16 //如果不是个合法的PE文件,则失败
17 //如果是,则将f定位到NtHeader
18 BOOL GetDosHeader(FILE *f,peinfo *p)
19 {
20 IMAGE_DOS_HEADER *dh;
21 char mz[2] = {0};
22 dh = &p->dosHeader;
23 if (!fread(mz,2,1,f))
24 {
25 printf("read mz error");
26 return FALSE;
27 }
28
29 ungetc(mz[1],f);
30 ungetc(mz[0],f);
31
32 if (!fread(dh,sizeof(*dh),1,f))
33 {
34 printf("read dos header error");
35 return FALSE;
36 }
37
38 fseek(f,dh->e_lfanew,SEEK_SET);
39 return TRUE;
40 }
41
42 BOOL GetNtHeader(FILE *f,peinfo *pf)
43 {
44 IMAGE_NT_HEADERS *nh = &pf->ntHeader;
45 if(!fread(nh,sizeof(*nh),1,f))
46 {
47 printf("read nt header error\n");
48 return FALSE;
49 }
50 return TRUE;
51 }
52
53 BOOL GetOEPOfFile(FILE *f,peinfo *pe)
54 {
55 IMAGE_SECTION_HEADER sh;
56 DWORD oepRva = 0;
57 fpos_t pos;
58
59 DWORD dwLen = 0;
60
61
62 assert(f);
63 pos = pe->dosHeader.e_lfanew + sizeof(IMAGE_NT_HEADERS);
64 oepRva = pe->ntHeader.OptionalHeader.AddressOfEntryPoint;
65
66 if (fseek(f,pos,SEEK_SET) != 0)
67 {
68 printf("seek position error\n");
69 return FALSE;
70 }
71
72 //dwLen = sizeof(sh);
73 //dwLen = fread(&sh,1,sizeof(IMAGE_SECTION_HEADER),f);
74
75
76 //当前位置指向的是节表
77 while (fread(&sh,1,sizeof(sh),f) == sizeof(sh))
78 {
79 if ((oepRva >= sh.VirtualAddress) && (oepRva < (sh.VirtualAddress + sh.SizeOfRawData)))
80 {
81 oepRva = oepRva - sh.VirtualAddress + sh.PointerToRawData;
82 pe->dwRvaOep = oepRva;
83 return TRUE;
84 }
85
86 }
87
88 printf("read section table error\n");
89 return FALSE;
90
91 //设置恢复原来的位置
92 fsetpos(f,(fpos_t*)&pe->curPos);
93
94 return FALSE;
95 }
96
97 int main()
98 {
99 //# bak
100 FILE *f;
101 f = fopen("D:\\soft\\deepinms.exe","rb");
102
103 if(f == NULL)
104 {
105 printf("open error \n");
106 #ifdef __DEBUG__
107 DebugBreak();
108 #endif
109 return -1;
110 }
111
112 if(!GetDosHeader(f,&pefile))
113 {
114 printf("read dos error \n");
115 goto END;
116 }
117 if(!GetNtHeader(f,&pefile))
118 {
119 printf("read nt header error\n");
120 goto END;
121 }
122
123 printf((char *)&pefile.ntHeader.Signature);
124 //__asm int 3;
125
126 GetOEPOfFile(f,&pefile);
127
128 printf("rvatooffset = %p\n",pefile.dwRvaOep);
129
130 END:
131 fclose(f);
132 getchar();
133
134 return 0;
135 }
136
RT,这玩意一搜一大把,这个也没啥亮点,主要是实现了RVA和文件偏移的转换,加个反汇编引擎就能DISASM了