首页
社区
课程
招聘
[求助]这是一个非常简单的驱动程序,熟悉vc++6.0的、会逆向的师傅来帮忙
发表于: 2012-6-20 14:03 2874

[求助]这是一个非常简单的驱动程序,熟悉vc++6.0的、会逆向的师傅来帮忙

2012-6-20 14:03
2874
这是一个非常简单的驱动程序:
/****************************************************************/
#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;的编译结果为P_Func被一个立即数(常量)初始化,就是与Func函数地址没有关系的编译?

我试过了,如果把long P_Func=(long)Func^0x10101010;换成long P_Func=(long)Func;就不会有$E1函数了!但是P_Func被加载器重定位了,所以在驱动入口函数被运行的时候,P_Func的值是:Func函数的运行地址而不是Func函数的编译地址(0x101000)!这也是一个事实,在这种情况下要怎样才能设置vc++6.0编译器不对P_Func进行加载重定位?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//