讀取文件的OEP的方法

讀取一個文件的OEP值一般有兩種方法:一.數據流方式:直接用fopen打開一個文件,通過字節流的方式來讀取文件中的值,即首先需要知道目標數據的文件偏移才行,可以直接fread讀取。

二.內存映射方式:使用CreateFile打開一個文件,使用CreateFileMapping和MapViewOfFile來映射文件到當前進程空間,然後根據MapViewOfFile返回的指針進行結構體的讀取操作即可。完整代碼如下:

#include <stdio.h>
#include <windows.h>
#include <WINNT.h>
int main()
{
PIMAGE_DOS_HEADER pDos;
PIMAGE_NT_HEADERS32 pFile;
int i=0;
FILE *f;
HANDLE h,h1;
BYTE * pbFile;
WORD buf[100];
unsigned long address;
/*使用數據流的方式讀取OEP*/
f=fopen("Test.exe","r");
if(f==NULL)
{
printf("Error!\n");
return 0;
}
fread(buf,sizeof(WORD),30,f);
for(i=0;i<30;i++)
printf("%x ",buf[i]);
fread(&address,sizeof(unsigned long),1,f);
printf("0x%x\n",address);
fseek(f,address+40,SEEK_SET);
fread(&address,sizeof(unsigned long),1,f);
printf("數據流方式讀取的OEP:0x%x\n",address);
fclose(f);
/*使用內存映射的方式讀取OEP*/
h=CreateFile("Test.exe",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(h==NULL)
return 0;
h1=CreateFileMapping(h,NULL,PAGE_READWRITE,0,0x4000000,0);
CloseHandle(h);
if(h1==NULL)
{
printf("CreateFileMapping Error!\n");
return 0;
}
pbFile=(BYTE *)MapViewOfFile(h1,FILE_MAP_ALL_ACCESS,0,0,0);
if(pbFile==NULL)
{
printf("MapView Error!\n");
return 0;
}
printf("Map Successful!\n");
pDos=(PIMAGE_DOS_HEADER)pbFile;
address=(unsigned long)pDos->e_lfanew;
pFile=(PIMAGE_NT_HEADERS32)(pbFile+address);
printf("內存映射的方式讀取的OEP:0x%x\n",pFile->OptionalHeader.AddressOfEntryPoint);
UnmapViewOfFile(pbFile);
return 0;
}

下面說明編程中遇到的幾個問題:

1.IMAGE_DOS_HEADER中的e_lfanew位於60字節處,所以首先使文件指針指向60偏移處,這裏我是用的fread來做的,也可以使用fseek來移動,效果一樣。當然注意fseek中最後一個參數的含義,SEEK_SET是從文件開頭來算偏移的,從文件開頭移動第二個參數那麼遠的位置。OEP位於PE HEADER的40偏移處。

2.在CreateFile中的倒數第三個參數是OPEN_EXISTING,表示打開一個存在的文件,如果文件不存在則失敗返回,我們這裏只是讀取它的數據。並且如果是打開一個設備文件的話,那麼只能使用OPEN_EXITING。如果使用CREATE_ALWAYS,則存在的文件內容被清空,讀取會失敗。

3.在使用CreateFileMapping後記得關閉使用的文件句柄。

4.pDos->e_lfanew的值只是相對於文件開頭或者加載點的相對偏移,所以如果在程序中要求出它的位移指針,必須加上進程爲此文件映射的基地址,否則訪問的地址將是相對於地址0的偏移,會出現訪問內存出錯問題,所以上例中pFile的計算時要加上pbFile才行,否則會出錯,切記切記。


關於文件映射函數的詳細介紹請參考此文:http://hi.baidu.com/anglecloudy/blog/item/639be973f9d60a198701b01b.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章