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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
| #include <stdio.h> #include <string.h> #include <windows.h>
IMAGE_DOS_HEADER dosheader; IMAGE_FILE_HEADER fileheader; IMAGE_SECTION_HEADER SectionHeader; IMAGE_OPTIONAL_HEADER32 optionalheader; IMAGE_IMPORT_DESCRIPTOR iid; DWORD PointerToPeHeader = 0; DWORD Size_Of_File = 0; DWORD Pe_Signature = 0; WORD Size_Of_Opt_Header = 0; WORD subsys = 0; DWORD Addr_of_EP = 0; DWORD PtrIdata = 0; DWORD ImageBase = 0; DWORD ImportsVA = 0; DWORD ImportsSize = 0; DWORD ImportDirAddr = 0; int NrOfSections = 0;
struct SectionInfo { char name[10]; int VA; int VirtualSize; int SizeOfRAW; int Ptr2RAW; };
void print_section(struct SectionInfo *section_info) { printf("%s节区:\n", section_info->name); printf("\t装如内存虚拟空间后的地址(RVA) : 0x%x\n", section_info->VA); printf("\t该节区装入内存后的总大小: %d byte\n", section_info->VirtualSize); printf("\t该节区在硬盘文件中的地址(FOA) : 0x%x\n", section_info->Ptr2RAW); printf("\t该节区在硬盘上初始化数据的大小 : %d byte\n", section_info->SizeOfRAW); }
int main() { char name[] = "ty.exe"; printf("请将测试文件与本程序放在同一目录下\n"); printf("请输入文件名:"); scanf("%s",name); printf("测试文件%s\n",name); printf("-----------文件信息-----------\n");
FILE* fp;
fp=fopen(name , "rb"); if(fp == NULL) { printf("文件打开失败\n"); return 0; }
fseek(fp,0,SEEK_SET); fread(&dosheader , 1 , sizeof(dosheader) , fp); WORD MZ=dosheader.e_magic; if(MZ != 0x5a4d) { printf("这不是PE文件,或者你把DOS头删了\nfuck you\n"); fclose(fp); return 0; } printf("PE文件的Dos头是:%x\n",MZ); printf("DOS结构体里面有两个重要成员:e_magic(MZ) e_lfanew\n"); WORD NToffset=dosheader.e_lfanew; printf("NT头的偏移 = 0x%x\n",NToffset);
fseek(fp,NToffset,SEEK_SET); fread(&Pe_Signature,1,sizeof(Pe_Signature),fp); WORD signature=Pe_Signature; printf("PE签名是:%x\n",signature); if(signature != 0x4550) { printf("你PE头呢?\nFuck you"); fclose(fp); return 0; }
fread(&fileheader,1,sizeof(fileheader),fp); WORD m_code=fileheader.Machine; if (m_code==0x014c) { printf("该CPU是intel-386(X32)\n"); } else if(m_code==0x8664) { printf("该CPU是(X64)\n"); } else { printf("谁知道你这是么cpu,自己百度去\n"); }
if (fileheader.NumberOfSections==0) { printf("不可能有0个节区\n"); fclose(fp); return 0; } WORD section_num=fileheader.NumberOfSections; printf("文件一共有%x个节区\n",fileheader.NumberOfSections);
WORD optional_header_size=fileheader.SizeOfOptionalHeader; int xbit=0; if (optional_header_size==0xE0) { xbit=32; } else { xbit=64; } printf("可选头结构体的大小是:0x%x\n这是一个X%d程序\n",optional_header_size,xbit);
fread(&optionalheader,1,optional_header_size,fp); subsys=optionalheader.Subsystem; if (subsys==2) { printf("这是一个Windows GUI 子系统\n"); } else if(subsys==3) { printf("这是一个Windows 控制台子系统\n"); } else { printf("俺也不知道了,恁自己查吧\n"); } DWORD iid_addr=optionalheader.DataDirectory[1].VirtualAddress; DWORD iid_size=optionalheader.DataDirectory[1].Size;
DWORD ope_addr=optionalheader.AddressOfEntryPoint; printf("程序最先执行的代码的地址(RVA)是:0x%x",ope_addr); printf("如果想要在一个可执行文件中附加了一段代码并且要让这段代码首先被执行,就可以通过更改入口地址到目标代码上,然后再跳转回原有的入口地址。\n"); printf("就像upx压缩那样\n"); printf("代码节的起始地址:0x%x, ",optionalheader.BaseOfCode); printf("数据节的起始地址:0x%x\n",optionalheader.BaseOfData);
struct SectionInfo section_info[section_num]; for(int i=0;i<section_num;i++) { fread(&SectionHeader,1,sizeof(SectionHeader),fp); memcpy(section_info[i].name,SectionHeader.Name,10); section_info[i].VA=SectionHeader.VirtualAddress; section_info[i].VirtualSize=SectionHeader.Misc.VirtualSize; section_info[i].Ptr2RAW=SectionHeader.PointerToRawData; print_section(§ion_info[i]); }
int RVA2RAW(int rva) { int i,raw; for(i=0;i<section_num;i++) { if ((rva>=section_info[i].VA) && (rva<=(section_info[i].VA + section_info[i].VirtualSize))) { raw = rva - section_info[i].VA + section_info[i].VirtualSize; return raw; } } return -1; }
printf("IID结构体的大小:%d\n",iid_size); int IID_addr=RVA2RAW(iid_addr); fseek(fp,IID_addr,SEEK_SET); fread(&iid,1,20,fp); int count = 1;
while(iid.Name!=0) { fread(&iid,1,20,fp); count++; }
IMAGE_IMPORT_DESCRIPTOR Imported[count-1]; fseek(fp, iid_addr, SEEK_SET);
for(int i=0;i<(count-1);i++) { fread(&Imported[i],1,20,fp); printf("[%d] DLL文件的名称在地址 0x%lx 处。\n", i, Imported[i].Name); }
printf("文件用到的DLL:\n");
fclose(fp); return 0; }
|