这是一个非常简单的驱动程序:
/****************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
//ddk的一个核心编译头文件
#include<ntddk.h>
#ifdef __cplusplus
}
#endif
void Func();
//非分页内存数据
#pragma data_seg()
//long P_Func=(long)Func;
long P_Func=(long)Func^0x10101010;
//非分页内存代码
#pragma code_seg()
void Func()
{
}
//分页内存
#pragma code_seg("INIT")
//驱动入口函数
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject//系统传给驱动程序入口函数的驱动对象
,IN PUNICODE_STRING pRegistryPath//这是注册表路径:
//L"\\Registry\\Machine\\System\\[驱动服务键名]
)
{
Func();
return 0;
}
/****************************************************************/
大牛们,请耐心往下看我这个小菜的问题。
我用vc++6.0配置ddk把这段代码编译成驱动程序后,拖进IDA反汇编。我用的是abcd版的IDA所以F5一下是可以把反汇编程序又还原到等价的c程
序,但是有这样一个问题:我原来的c程序明明就是只有DriverEntry和Func两个函数,IDA反汇编却除了DriverEntry和Func函数外还有一个函
数:$E1,这个$E1函数是怎么来的!它对整个驱动程序起到什么作用?有人对类似$E1多出来的函数进行分析过吗?
所以就来看看$E1函数的反汇编程序,很简单:
.text:00101000 ; void __stdcall Func()
..............
.text:00101010 $E1 proc near ; DATA XREF: .CRT:$S2o
.text:00101010 55 push ebp
.text:00101011 8B EC mov ebp, esp
.text:00101013 83 EC 40 sub esp, 40h
.text:00101016 53 push ebx
.text:00101017 56 push esi
.text:00101018 57 push edi
.text:00101019 B8 00 10 10 00 mov eax, offset ?Func@@YGXXZ ; Func(void)
.text:0010101E 35 10 10 10 10 xor eax, 10101010h
.text:00101023 A3 00 30 10 00 mov ?P_Func@@3JA, eax ; long P_Func
.text:00101028 5F pop edi
.text:00101029 5E pop esi
.text:0010102A 5B pop ebx
.text:0010102B 8B E5 mov esp, ebp
.text:0010102D 5D pop ebp
.text:0010102E C3 retn
.text:0010102E $E1 endp
干脆直接F5结果来得直观一点:
unsigned int __cdecl _E1()
{
unsigned int result; // eax@1、
result = (unsigned int)Func ^ 0x10101010;
P_Func = (unsigned int)Func ^ 0x10101010;
return result;
}
原来啊!这个函数就是:long P_Func=(long)Func^0x10101010;它说明了P_Func值的来历。但是这个函数自始至终没有被运行过,虽然不会被运行,但是函数的代码却在驱动程序加载过程中有2处需要被加载器重定位,分别是0010101A和00101024,并且$E1函数的代码是被加载到了非分页内存。有这样一个事实:在驱动入口函数被运行的时候:P_Func的值是:Func函数的编译地址(0x101000)与0x10101010按位求异的值,并不是等于:Func函数载入内存运行时的内存地址与0x10101010按位求异的值。并且P_Func的值并没有被重定位!因此除了vc++6.0的作者,还有谁可以帮我在编译这类程序时免去$E1函数的无用的占用代码?假设:我的c程序long P_Func=(long)Func^0x10101010;不变的情况下?
我试过了,如果把long P_Func=(long)Func^0x10101010;换成long P_Func=(long)Func;就不会有$E1函数了!但是P_Func被加载器重定位了,所以在驱动入口函数被运行的时候,P_Func的值是:Func函数的运行地址而不是Func函数的编译地址(0x101000)!这也是一个事实,在这种情况下要怎样才能设置vc++6.0编译器不对P_Func进行加载重定位?
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)