首页
社区
课程
招聘
[求助]请教磁盘文件导出表钩子的函数偏移问题
发表于: 2011-5-7 17:48 9607

[求助]请教磁盘文件导出表钩子的函数偏移问题

2011-5-7 17:48
9607
关于静态磁盘文件PE各字段的修改.其中导出表钩子.该怎么计算内存镜像和文件镜像的转换呢?

翻阅了<<加密解密3>> <<win32汇编程序设计>>中对PE格式的讲解。也没有搞明白。又经过

大量搜索也没得到答案。在此求助看雪前辈

PVOID OperateExportTable(LPCSTR FileName,CString FunctionsName,PVOID Replace,PVOID Original)
{
	HANDLE File=NULL;
	HANDLE Mapping=NULL;
	PVOID View=NULL;
	PVOID Value=NULL;
	PIMAGE_DOS_HEADER DosHeader=NULL;
	PIMAGE_NT_HEADERS NTHeader=NULL;
	PIMAGE_OPTIONAL_HEADER OptionalHeader=NULL; 
	PIMAGE_EXPORT_DIRECTORY ExportDirectory=NULL; 
	PWORD Ordinals=NULL;
	PDWORD Functions=NULL;
	PDWORD Names=NULL;
	SIZE_T Size=0;
	DWORD Index=0;
//映射磁盘文件入内存供操作
	File=CreateFile(FileName,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
	if (File==INVALID_HANDLE_VALUE)
	{
		AfxMessageBox(_T("创建文件失败..."));
		goto Exit;
	}
	Mapping=CreateFileMapping(File,NULL,PAGE_READWRITE|SEC_COMMIT,0,Size,NULL); 
	if (Mapping==NULL)
	{
		AfxMessageBox(_T("创建文件映射失败..."));
		goto Exit;
	}
	View=MapViewOfFile(Mapping,FILE_MAP_ALL_ACCESS,0,0,Size);
	if (View==NULL)
	{
		AfxMessageBox(_T("创建映射视图失败..."));
		goto Exit;
	}
//验证文件是否为有效的PE格式
	DosHeader=(PIMAGE_DOS_HEADER)View;
	if (DosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
	{
		AfxMessageBox(_T("此文件非PE格式..."));
		goto Exit;
	}
	NTHeader=(PIMAGE_NT_HEADERS)((DWORD)DosHeader+DosHeader->e_lfanew);
	if (NTHeader->Signature!=IMAGE_NT_SIGNATURE)
	{
		AfxMessageBox(_T("此文件非PE格式..."));
		goto Exit;
	}
//读出文件导出表和相关RVA
	ExportDirectory=(PIMAGE_EXPORT_DIRECTORY)((DWORD)DosHeader+(NTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)-0xc00);
	Ordinals=(PWORD)((DWORD)DosHeader+ExportDirectory->AddressOfNameOrdinals-0xc00);
	Functions=(PDWORD)((DWORD)DosHeader+ExportDirectory->AddressOfFunctions-0xc00);
	Names=(PDWORD)((DWORD)DosHeader+ExportDirectory->AddressOfNames-0xc00);
//替换导出表原函数的位置
	for (Index;Index<ExportDirectory->NumberOfFunctions;Index++)
	{

		if (FunctionsName.Compare((LPCSTR)((DWORD)DosHeader+Names[Index]-0xc00))==0)
		{
			//此处希望大牛指教。自己的函数地址。通过怎么样的计算可以替换文件导出表中。原函数的RVA呢?
			//这样的EAT HOOK该怎么做?
		}
	}

Exit:
	if (View!=NULL)
	{
		UnmapViewOfFile(View);
	}
	if (Mapping!=NULL)
	{
		CloseHandle(Mapping);
	}
	if (File==NULL)
	{
		CloseHandle(File);
	}
	return Value;
}


很疑惑呀...

如今看雪<<今年22岁想学编程,不过没基础,也不会英文...能行么?>>这类帖子为什么会如此之火呢???   浏览量全部过万级...回复都成百上千计...  而相反技术类 无论是求助类

还是原创类.真是门庭冷清呀.   这是怎么啦???  看雪难道要转型成为天涯?MOP?啦?

说实话发这种帖子的人都很无聊... 这次是22岁.之前还有几个37岁 40岁之类..基本每个星期.都有这种人跳出来发这种贴... 我就纳闷啦.22岁可能说年轻阅历低.心智还不成熟.迷惑会多

一些..难免做出一些幼稚的事情...  可这些37-40岁的人...你这么多年都白活了嘛???  这么简单的问题  需要发帖来问大家的意见嘛???

更离谱的是...居然还有这么多人捧场...乐此不疲...

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (17)
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2


没人帮助嘛?
2011-5-8 19:00
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3

没人帮助嘛?
2011-5-9 18:14
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4


没人帮助嘛?
2011-5-9 22:03
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5


没人帮助嘛?
2011-5-10 08:26
0
雪    币: 107
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
其实那些资料已经很详细了  不过消化吸收要时间
2011-5-10 08:40
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
那你会嘛? 你消化吸收了嘛?
2011-5-10 09:02
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8


没人帮助嘛?
2011-5-10 21:28
0
雪    币: 596
活跃值: (449)
能力值: ( LV12,RANK:320 )
在线值:
发帖
回帖
粉丝
9
用某域的RVA与各节表所描述节的RVA范围比较,确定此域所在节. 最后用此域RVA减去 这个节的RVA得到的偏移加上此节的文件偏移即得到你要计算的域在PE中的文件偏移.

可以参考下面的代码:

DWORD RvaToFileOffset(DWORD dwRva,DWORD dwSecNum,PIMAGE_SECTION_HEADER pSec)
{
    if (dwSecNum==0 || pSec==NULL)
    {
        return 0;
    }
   
    for (DWORD i=0;i<dwSecNum;i++)
    {
        if (dwRva>=pSec[i].VirtualAddress&&dwRva<pSec[i].VirtualAddress+pSec[i].SizeOfRawData)
        {

             return dwRva-pSec[i].VirtualAddress+pSec[i].PointerToRawData;
            
        }
    }
    return 0;
   
}
2011-5-10 21:37
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
哥哥.你好像误会了我的意思...我不是想问镜像偏移和文件偏移的换算...

我想知道我的钩子函数地址...怎么去替换导出表的函数地址...在R3层...
2011-5-10 22:11
0
雪    币: 596
活跃值: (449)
能力值: ( LV12,RANK:320 )
在线值:
发帖
回帖
粉丝
11
呵呵那个很简单,首先得到你要HOOK函数的RVA即AddressOfFunctions[i],也就是得到该函数在地址表的索引,然后重写即可.即AddressOfFunctions[i]=你的函数地址-该DLL加载的基地址
2011-5-10 22:30
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
[QUOTE=evilkis;957167]呵呵那个很简单,首先得到你要HOOK函数的RVA即AddressOfFunctions[i],也就是得到该函数在地址表的索引,然后重写即可.即AddressOfFunctions[i]=你的函数地址-该DLL加载的基地址[/QUOTE]

正常是这样的...但是随便打个比方...你钩USER32.DLL的某个函数...

静态加载入你自己进程中其基址大概0x70000000以上...

而你自己进程中某个函数要想替换他导出的函数...

基本上自己钩子函数地址=0x410050-USER32.DLL的基址0x70000000=负数RVA

如果有其他进程调用USER32.DLL的函数.会跳到这个0x410050嘛?
2011-5-10 22:41
0
雪    币: 596
活跃值: (449)
能力值: ( LV12,RANK:320 )
在线值:
发帖
回帖
粉丝
13
这不是ring0的EAThook,ring3下你的函数地址必须在你要hook的进程地址空间中.你只能hook某一个进程对某一DLL导出函数的调用. 其实,ring3下的EAT hook很鸡肋,在进程运行时,你在修改EAT已经一点用没有了,因为那时程序对函数的调用是通过IAT. 当然使用LoadLibrary
和GetProcAddress,这样对函数的调用,或许RING3的EAThook会有用. 当然你也可以在进程运行前,直接把DLL改写了,这样以后所有要运行的进程,只要调用此DLL的导出函数,都会被你HOOK(前提是你的函数要首先进入目标进程地址空间).
2011-5-10 23:01
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
对..就是这么回事..确实很尴尬..

不过我还有一个想法..目前还不太成熟.. 我想劫持一个系统DLL..在此DLL里导出一个我的钩子函数

比如.我要钩USER32.DLL里的函数.它在我的进程里的镜像是0x70000000.在其他进程也是一样

的..而我的钩子在USP10.DLL里..它的镜像大概是0x4B000000..在其他进程里也是一样.

这样.我好像就可以不用进入其他进程.就可以直接替换啦.
2011-5-11 08:23
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15

没人帮助嘛?
2011-5-11 19:54
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
16

没人帮助嘛?
2011-5-13 07:58
0
雪    币: 72
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17


元 亨 利 贞

初九

潜龙 勿用
2011-5-15 08:42
0
雪    币: 132
活跃值: (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18


没人帮助嘛?
2011-5-15 11:44
0
游客
登录 | 注册 方可回帖
返回
//