学破解 一 PE格式之MS-DOS MZ header
from:http://www.2cto.com/Article/201203/123125.html
PE的意思就是這個the Protable Executable (PE) file format 微軟搞得那么一套東西,字面意思是可移植的,但是現實使用中沒見他多么的可移植,PE格式借鑒了UNIX系統中的COFF (Common Object File Format) 格式。而且PE對MS-Dos的兼容,保留了MS-Dos頭,在dos下打開會提示 “這是win32程序在dos下不能跑” 向下兼容,非常的友好。
MS-DOS MZ header 的結構是這樣的
其中比較關鍵的成員是這個e_lfanew 它指向了PE文件頭在PE文件中的相對虛擬地址RAV(Relative Virtual Addresses),e_magic的值應該等于0x5A4D 是MS-DOS MZ header的標志MZ好像是個程序員名字的縮寫 其他成員基本沒啥大用,一些加殼軟件會修改它的成員為自己的節騰出空間,或者在添加節形式感染時節表尾部的空隙不夠寫入一個新的解表結構的時候把IMAGE_DOS_HEADE 和IMAGE_NT_HEADER 融合。
可以自己寫一個小程序來輸出一下IMAGE_DOS_HEADE
IMAGE_DOS_HEADE這個結構體定義在windows.h中
系統加載PE格式的文件時,會先加載IMAGE_DOS_HEADE這個結構體,再根據結構體里的e_lfanew提供的相對偏移找到PE文件頭。
?
用c語言可以直接讀出IMAGE_DOS_HEADE這個結構體,下面開始寫。
從文件的開始位置讀取IMAGE_DOS_HEADE結構體
[cpp] view plaincopy
fread(&mydosheader,sizeof(mydosheader),1,p);?
吧文件指針移動到e_lfanew所指的相對偏移,即PE文件頭
[cpp] view plaincopy
fseek(p,mydosheader.e_lfanew,SEEK_SET);?
讀取PE文件標志,這個PE Signature是PE\0\0 這樣一個值,證明它是PE格式的身份。
[cpp] view plaincopy
fread(&sig,4,1,p);?
這個判斷中大寫的變量都是,windows.h中的常數
IMAGE_NT_SIGNATURE 的值是PE\0\0
IMAGE_DOS_SIGNATURE 的值是MZ
具體的定義可以自己去windows.h中看
if((mydosheader.e_magic ==IMAGE_DOS_SIGNATURE) &&?
(sig == IMAGE_NT_SIGNATURE))?
printf("有效的PE文件/n");?
else?
printf("無效的PE文件/n");?
return 0;?
下面是完整的程序
#include "windows.h" #include "stdio.h" int main(int argc, char* argv[]) { FILE *p; IMAGE_DOS_HEADER mydosheader; unsigned long sig; p = fopen("test1.exe","r+b"); if(p == NULL)return -1; fread(&mydosheader,sizeof(mydosheader),1,p); fseek(p,mydosheader.e_lfanew,SEEK_SET); fread(&sig,4,1,p); fclose(p); printf("IMAGE_DOS_HEADER dump:/n"); printf("e_magic : %04x/n",mydosheader.e_magic); printf("e_cblp : %04x/n",mydosheader.e_cblp); printf("e_cp : %04x/n",mydosheader.e_cp); printf("e_crlc : %04x/n",mydosheader.e_crlc); printf("e_cparhdr : %04x/n",mydosheader.e_cparhdr); printf("e_minalloc: %04x/n",mydosheader.e_minalloc); printf("e_maxalloc: %04x/n",mydosheader.e_maxalloc); printf("e_ss : %04x/n",mydosheader.e_ss); printf("e_sp : %04x/n",mydosheader.e_sp); printf("e_csum : %04x/n",mydosheader.e_csum); printf("e_ip : %04x/n",mydosheader.e_ip); printf("e_cs : %04x/n",mydosheader.e_cs); printf("e_lfarlc : %04x/n",mydosheader.e_lfarlc); printf("e_ovno : %04x/n",mydosheader.e_ovno); printf("e_res[0] : %04x/n",mydosheader.e_res[0]); printf("e_oemid : %04x/n",mydosheader.e_oemid); printf("e_oeminfo : %04x/n",mydosheader.e_oeminfo); printf("res2[0] : %04x/n",mydosheader.e_res2[0]); printf("lfanew : %08x/n",mydosheader.e_lfanew); if((mydosheader.e_magic ==IMAGE_DOS_SIGNATURE) && (sig == IMAGE_NT_SIGNATURE)) printf("有效的PE文件/n"); else printf("無效的PE文件/n"); return 0; }?
?
轉載于:https://www.cnblogs.com/tk091/archive/2012/04/18/2456172.html
總結
以上是生活随笔為你收集整理的学破解 一 PE格式之MS-DOS MZ header的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分享9个最棒的代码片段资源网站
- 下一篇: 引入extThree20JSON之后,怎