首页
社区
课程
招聘
[求助][求助]ntoskrnl.exe导出函数用MmGetSystemRoutineAddress获取地址
发表于: 2009-8-13 11:43 18292

[求助][求助]ntoskrnl.exe导出函数用MmGetSystemRoutineAddress获取地址

2009-8-13 11:43
18292
ntoskrnl.exe导出函数,既然是导出函数,不就可以直接(ULONG)函数名获取地址
但是请看下面:
KdPrint(("KeInsertQueueApc--0x%x",(ULONG)KeInsertQueueApc));
KdPrint(("ObReferenceObjectByHandle--0x%x",(ULONG)ObReferenceObjectByHandle));
KdPrint(("ZwOpenFile---0x%x",(ULONG)ZwOpenFile));
结果:
0003        0.00021707        KeInsertQueueApc--0xf9cb65d4                 地址错误       
00000004        0.00023411        ObReferenceObjectByHandle--0x805b0574   地址正确       
00000005        0.00024975        ZwOpenFile---0x804feb84                         地址正确

windbg:
lkd> u KeInsertQueueApc
nt!KeInsertQueueApc:
804fb704 8bff            mov     edi,edi
804fb706 55              push    ebp
804fb707 8bec            mov     ebp,esp
804fb709 83ec0c          sub     esp,0Ch
804fb70c 53              push    ebx
804fb70d 56              push    esi

lkd> u nt!zwopenfile
nt!ZwOpenFile:
804feb84 b874000000      mov     eax,74h
804feb89 8d542404        lea     edx,[esp+4]
804feb8d 9c              pushfd
804feb8e 6a08            push    8
804feb90 e8bcea0300      call    nt!KiSystemService (8053d651)
804feb95 c21800          ret     18h

lkd> u ObReferenceObjectByHandle
nt!ObReferenceObjectByHandle:
805b0574 8bff            mov     edi,edi
805b0576 55              push    ebp
805b0577 8bec            mov     ebp,esp
805b0579 51              push    ecx
805b057a 51              push    ecx
805b057b 53              push    ebx
805b057c 56              push    esi
805b057d 57              push    edi
而利用MmGetSystemRoutineAddress获取的KeInsertQueueApc地址才正确

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

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
2
我一直这么认为:只要是内核导出函数,就可以用函数名做变量,(ULONG)导出函数==地址
但是KeInsertQueueApc却不正确呢?到底什么导出函数才可以直接用函数名得到地址?
2009-8-13 11:45
0
雪    币: 229
活跃值: (508)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
3
ntddk.h好像没有声名KeInsertQueueApc这个函数吧..
我在当前文件里声明了下.打印出来的地址KdPrint(("%0x",(ULONG)KeInsertQueueApc));
和windbg中反汇编的地址一样的..
lz再试下...
2009-8-13 12:06
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
4
我声明了:
BOOLEAN KeInsertQueueApc(PKAPC Apc,PVOID SystemArg1,PVOID SystemArg2,KPRIORITY Increment);
2009-8-13 12:18
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
5
还是一样的结果
2009-8-13 12:22
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
BOOLEAN KeInsertQueueApc(PKAPC Apc,PVOID SystemArg1,PVOID SystemArg2,KPRIORITY Increment);

NTKERNELAPI NTSTATUS ObReferenceObjectByHandle(
                                                                                          
                                                                                           IN HANDLE  Handle,
                                                                                           IN ACCESS_MASK  DesiredAccess,
                                                                                           IN POBJECT_TYPE  ObjectType  OPTIONAL,
                                                                                           IN KPROCESSOR_MODE  AccessMode,
                                                                                           OUT PVOID  *Object,
                                                                                           OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL
                                                                                          
                                                                                           );

KdPrint(("KeInsertQueueApc--0x%x",(ULONG)KeInsertQueueApc));
KdPrint(("ObReferenceObjectByHandle--0x%x",(ULONG)ObReferenceObjectByHandle));
KdPrint(("ZwOpenFile---0x%x",(ULONG)ZwOpenFile));
2009-8-13 12:29
0
雪    币: 229
活跃值: (508)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
7
NTKERNELAPI
BOOLEAN
KeInsertQueueApc (
                                  IN PKAPC        Apc,
                                  IN PVOID        SystemArgument1,
                                  IN PVOID        SystemArgument2,
                                  IN KPRIORITY    Increment
);

你前面掉了NTKERNELAPI,引入的意思..
否则编译器认为KeInsertQueueApc 是你自己定义的函数..打印出来的地址跟定不是系统的那个KeInsertQueueApc 的地址咯
2009-8-13 12:45
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
8
楼上正解~~
2009-8-13 12:55
0
雪    币: 636
活跃值: (174)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
9
如果直接打印 KeInsertQueueApc 地址会得到你自己的程序里的一个地址,因为这是你自己声明的函数。其实你的程序会被编译成这样:

山寨_KeInsertQueueApc(){
   jmp [导入表中KeInsertQueueApc的位置]
}

而直接打印 KeInsertQueueApc 将得到 山寨_KeInsertQueueApc 的地址。

可以做如下实验:

lkd> u f8bdf49c   //山寨_KeInsertQueueApc
f8bdf49c ff2508f5bdf8    jmp     dword ptr ds:[0F8BDF508h]
f8bdf4a2 cc              int     3
f8bdf4a3 cc              int     3
f8bdf4a4 cc              int     3
f8bdf4a5 cc              int     3
f8bdf4a6 cc              int     3
f8bdf4a7 cc              int     3
f8bdf4a8 cc              int     3

lkd> d f8bdf508
f8bdf508  804e6ccf 8055b000 805bc0b0 00000000
f8bdf518  00000000 00000000 00000000 4a83a094
f8bdf528  00000000 00000002 00000045 0000053c
f8bdf538  0000053c 53445352 51e405bb 41a61c50
f8bdf548  cad3efb9 6271f912 00000001 745c3a63
f8bdf558  64747365 5c327672 636a626f 775f6b68
f8bdf568  785f7078 695c3638 5c363833 74736574
f8bdf578  32767264 6264702e 00000000 00000000

804e6ccf为真实地址
2009-8-13 13:21
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
10
明白了 谢了
2009-8-13 13:37
0
雪    币: 152
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
[QUOTE=Fypher;670531]如果直接打印 KeInsertQueueApc 地址会得到你自己的程序里的一个地址,因为这是你自己声明的函数。其实你的程序会被编译成这样:

山寨_KeInsertQueueApc(){
   jmp [导入表中KeInsertQueueApc的位置]
}

而直接打印 KeInsert...[/QUOTE]


快上Q
2009-8-13 13:37
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
12
那Mm函数不就没有什么意思
2009-8-13 13:41
0
雪    币: 636
活跃值: (174)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
13
MmXXX是找函数指针。你在导入函数的声明前面加个NTKERNELAPI,说明是导入的,就可以啦。否则编译器一开始不知道是导入的,会建个函数框架,之后发现是导入的,再加个jmp到函数体中。MmXXX就误找到这个山寨的函数了。
2009-8-13 13:51
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
14
MmXXX是找函数指针怎么是找函数指针?
Mm得到的函数地址跟 直接用(ULONG)KeInsertQueueApc是一样的,那么Mm就失业了
2009-8-13 15:49
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
15
你们理解有误.Mm的作用是在ntos*的EAT中找到函数地址, 和自己在EAT中没什么区别, 唯一不同的是它是用二分查找法找的.

再者, 若直接调用导出函数,比如KeInsertQueueApc,是直接从你写的驱动的IAT中调用,而此时你的IAT可能被某些程序修改过,比如微点主动防御软件. 此时你的地址便是微点的fake_KeInsertQueueApc的地址; 而用MmGet*得到的函数地址是ntos*导出的地址, 若安全软件没有对ntos*进行EAT HOOK,那么取得的地址是正确的.

这就是区别,所以不能说 Mm无用,失业..
2009-8-13 16:00
0
雪    币: 107
活跃值: (1693)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
16
微点会修改EXE的IAT函数地址,是他加载的时候就修改了吧,他HOOKEXEIAT做啥?请楼上指点
2009-8-13 16:05
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
和r3的getprocaddr函数一样
过导入表hook 过不了导出表hook
自己分析原始pe获取函数指针可以过上面的
2009-8-14 17:35
0
游客
登录 | 注册 方可回帖
返回
//