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

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

2012-6-20 13:55
9463
这是一个非常简单的驱动程序:
/****************************************************************/
#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期)

收藏
免费 0
支持
分享
最新回复 (21)
雪    币: 125
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我只知道,编译器会对程序源码进行优化。
2012-6-20 14:59
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
3
一般的我都是编译调试版的,我没有设置编译过优化版的,因为我以前好像见过有资料说是会编译出错(就是优化编译的汇编程序函数功能与原来的c 函数功能不同),这是在内核,一下子就会蓝屏,所以我一直用调试版编译。
2012-6-20 15:54
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
坐等高手解答
2012-6-21 19:29
0
雪    币: 224
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不是特别清楚LZ的问题,C++中的环境会存在一些初始化或者反初始化的函数, 例如定义了SomeCalss oneInstance; C++环境会在调用入口前作初始化,调用后在释放掉,这个问题和调试版无关。
2012-6-21 19:52
0
雪    币: 224
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
LZ要是不喜欢这样的处理, 那就把P_Func自己初始化复值就行了,P_Func=(long)Func^0x10101010;放到DriverEntry中
2012-6-21 19:56
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
7
猜测:如果LZ在DriverEntry中放上一条对F_Func的引用语句,则在执行DriverEntry前C库初始化过程中会调用函数$E1,使得F_Func成为Func重定位后的值和0x10101010相异或的结果。
2012-6-21 20:40
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
long P_Func=(long)Func^0x10101010;

被当成一个函数来编译了。
2012-6-21 23:30
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
把它改成 内联汇编,肯定不被优化,当然你也可以改 项目 的优化设置。
2012-6-21 23:33
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
10
把P_Func=(long)Func^0x10101010;放到DriverEntry中,那P_Func=(long)Func^0x10101010;这个表达式编译的机器码是要被重定位的,如果我要免去重定位怎么办?并且DriverEntry中的P_Func=(long)Func^0x10101010;运行结果是:P_Func的值是Func函数的运行地址与0x10101010按位求异的值,并不是Func函数的编译地址(0x101000)与0x10101010按位求异的值。我要的是后者。
2012-6-22 12:19
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
11
依据的的目的,怎么设置优化?

你的意思是:在DriverEntry中用汇编
_asm
{
push eax;
mov eax,Func;//你的意思是:这个Func在编译后不会被重定位吗?
xor eax,0x0x10101010;
mov P_Func,eax;
pop eax;
}
2012-6-22 12:25
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
12
我查看了.cab的编译汇编代码,里面好像是提示:把long P_Func=(long)Func^0x10101010;
当成一个函数来编译了是编译函数默认的,要怎么设置vc++6.0 取消这种默认编译?
2012-6-22 12:31
0
雪    币: 224
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
还简单呢, 要求越来越天马行空,慢慢琢磨吧
2012-6-22 18:04
0
雪    币: 224
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
不是不能做,搞不清楚你到底想干么,有要求就肯定有办法实现, 没有必要的东西讨论来讨论去也没多大意思。
2012-6-22 18:08
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
VC6.0,菜单:项目->设置 里有个 c/c++ ,project options ,那里面有个/O2,改成/O
2012-6-23 08:41
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
具体为什么,百度搜吧。
2012-6-23 08:42
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
17
就拿我的这个Func函数来说,我在DriverEntry里要初始化全局变量P_Func的值,要求的值是Func函数的编译地址,我这里的编译地址指的是:Func函数在编译时所用的地址值:0x101000;
2012-6-23 12:14
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
18
把P_Func=(long)Func^0x10101010;放到DriverEntry中那表达式:(long)Func的值是被重定位了,这个值不可能再是Func函数的编译地址值:0x101010了。
2012-6-23 12:19
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
19
要怎样才能不让:long P_Func=(long)Func^0x10101010;不被当成一个函数来编译?而是被当成立即数来编译?
2012-6-23 12:21
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
20
long P_Func=(long)Func^0x10101010;
如果改动程序的话,很难保证下次编译在同一位置上。
2012-6-24 09:19
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
21
Func的值,程序不同,位置也有可能不同,怎么换成立即数?
2012-6-24 09:20
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
22
我的意思是:让编译器编译成立即数。就如:long P_Func=(long)Func^0x10101010;这样编译器已经把P_Func编译成赋值立即数了,只是编译器又把P_Func的值是怎么算来的,用一个$E1函数来给反编译者留下痕迹!?是吧?我现在是想问怎么设置编译器不把$E1函数的机器码编译进驱动文件内?
2012-6-24 13:12
0
游客
登录 | 注册 方可回帖
返回
//