Advanced Debugging
About AdvDbg Consult Train Services Products Tools Community Contact  
欢迎光临 高端调试 登录 | 注册 | FAQ
 
  ACPI调试
Linux内核调试
Windows内核调试
 
  调试战役
调试原理
新工具观察
 
  Linux
Windows Vista
Windows
 
  Linux驱动
WDF
WDM
 
  PCI Express
PCI/PCI-X
USB
无线通信协议
 
  64位CPU
ARM
IA-32
  CPU Info Center
 
  ACPI标准
系统认证
Desktop
服务器
 
  Embedded Linux
嵌入式开发工具
VxWorks
WinCE
嵌入式Windows
 
  格蠹调试套件(GDK)
  格蠹学院
  小朱书店
  老雷的微博
  《软件调试》
  《格蠹汇编》
  《软件调试(第二版)》
沪ICP备11027180号-1

Windows内核调试

帖子发起人: holly   发起时间: 2008-12-02 12:58 下午   回复: 9

Print Search
帖子排序:    
   2008-12-02, 12:58 下午
hollyhunter 离线,最后访问时间: 2009/10/10 9:42:36 holly

发帖数前50位
注册: 2008-07-14
发 贴: 22
Whisper [:-*] 求教:如何调用内核未引出的函数!
Reply Quote

如题,我想调用内核的函数KeSuspendThread这样的函数,但是这个函数DDK是没有支持的,不能通过简单的编写原型Link的方式。

我怎样才能调用像这种类型的内核函数啊,只是一个方法问题。

 


IP 地址: 已记录   报告
   2008-12-02, 14:28 下午
MJ0011 离线,最后访问时间: 2009/12/24 22:33:41 MJ0011

发帖数前10位
注册: 2008-04-24
发 贴: 112
Re: 求教:如何调用内核未引出的函数!
Reply Quote
下载PDB解析之
IP 地址: 已记录   报告
   2008-12-02, 14:44 下午
WANGyu 离线,最后访问时间: 2012/9/10 3:34:00 王宇

发帖数前10位
男
注册: 2007-05-08
发 贴: 306
Re: 求教:如何调用内核未引出的函数!
Reply Quote

ULONG
KeSuspendThread (
    __inout PKTHREAD Thread
    )

/*++

Routine Description:

    This function suspends the execution of a thread. If the suspend count
    overflows the maximum suspend count, then a condition is raised.

Arguments:

    Thread  - Supplies a pointer to a dispatcher object of type thread.

Return Value:

    The previous suspend count.

--*/


NTSTATUS
PsSuspendThread (
    IN PETHREAD Thread,
    OUT PULONG PreviousSuspendCount OPTIONAL
    )

/*++

Routine Description:

    This function suspends the target thread, and optionally
    returns the previous suspend count.

Arguments:

    ThreadHandle - Supplies a handle to the thread object to suspend.

    PreviousSuspendCount - An optional parameter, that if specified
        points to a variable that receives the thread's previous suspend
        count.

Return Value:

    NTSTATUS - Status of call

--*/

利用结合反汇编的暴力搜索定位,比如:

0: kd> u nt!NtSuspendThread
nt!NtSuspendThread:
805d58b0 6a20            push    20h
805d58b2 68f8b94d80      push    offset nt!ObWatchHandles+0x79c (804db9f8)
805d58b7 e8c472f6ff      call    nt!_SEH_prolog (8053cb80)
805d58bc 33db            xor     ebx,ebx
805d58be 895dfc          mov     dword ptr [ebp-4],ebx
805d58c1 64a124010000    mov     eax,dword ptr fs:[00000124h]
805d58c7 8945d0          mov     dword ptr [ebp-30h],eax
805d58ca 8a8040010000    mov     al,byte ptr [eax+140h]
805d58d0 8845e0          mov     byte ptr [ebp-20h],al
805d58d3 8b750c          mov     esi,dword ptr [ebp+0Ch]
805d58d6 3ac3            cmp     al,bl
805d58d8 7413            je      nt!NtSuspendThread+0x3d (805d58ed)
805d58da 3bf3            cmp     esi,ebx
805d58dc 740f            je      nt!NtSuspendThread+0x3d (805d58ed)
805d58de a134315680      mov     eax,dword ptr [nt!MmUserProbeAddress (80563134)]
805d58e3 3bf0            cmp     esi,eax
805d58e5 7202            jb      nt!NtSuspendThread+0x39 (805d58e9)
805d58e7 8918            mov     dword ptr [eax],ebx
805d58e9 8b06            mov     eax,dword ptr [esi]
805d58eb 8906            mov     dword ptr [esi],eax
805d58ed 834dfcff        or      dword ptr [ebp-4],0FFFFFFFFh
805d58f1 53              push    ebx
805d58f2 8d45e4          lea     eax,[ebp-1Ch]
805d58f5 50              push    eax
805d58f6 ff75e0          push    dword ptr [ebp-20h]
805d58f9 ff35bc495680    push    dword ptr [nt!PsThreadType (805649bc)]
805d58ff 6a02            push    2
805d5901 ff7508          push    dword ptr [ebp+8]
805d5904 e8896bfeff      call    nt!ObReferenceObjectByHandle (805bc492)
805d5909 3bc3            cmp     eax,ebx
805d590b 7c5c            jl      nt!NtSuspendThread+0xb9 (805d5969)
805d590d 8d45dc          lea     eax,[ebp-24h]
805d5910 50              push    eax
805d5911 ff75e4          push    dword ptr [ebp-1Ch]
805d5914 e869feffff      call    nt!PsSuspendThread (805d5782) // 第三个 E8 类型 call
805d5919 8bf8            mov     edi,eax
805d591b 8b4de4          mov     ecx,dword ptr [ebp-1Ch]


0: kd> u nt!PsSuspendThread
nt!PsSuspendThread:
805d5782 6a18            push    18h
805d5784 68e0b94d80      push    offset nt!ObWatchHandles+0x784 (804db9e0)
805d5789 e8f273f6ff      call    nt!_SEH_prolog (8053cb80)
805d578e 33f6            xor     esi,esi
805d5790 8975e4          mov     dword ptr [ebp-1Ch],esi
805d5793 64a124010000    mov     eax,dword ptr fs:[00000124h]
805d5799 8b7d08          mov     edi,dword ptr [ebp+8]
805d579c 3bf8            cmp     edi,eax
805d579e 752e            jne     nt!PsSuspendThread+0x4c (805d57ce)
805d57a0 8975fc          mov     dword ptr [ebp-4],esi
805d57a3 57              push    edi
805d57a4 e83f8df2ff      call    nt!KeSuspendThread (804fe4e8) // 第二个 E8 类型 call
805d57a9 8945e4          mov     dword ptr [ebp-1Ch],eax
805d57ac 8975dc          mov     dword ptr [ebp-24h],esi
805d57af 834dfcff        or      dword ptr [ebp-4],0FFFFFFFFh
805d57b3 e98a000000      jmp     nt!PsSuspendThread+0xc0 (805d5842)


0: kd> u 804fe4e8
nt!KeSuspendThread:
804fe4e8 8bff            mov     edi,edi
804fe4ea 55              push    ebp
804fe4eb 8bec            mov     ebp,esp
804fe4ed 83ec0c          sub     esp,0Ch
804fe4f0 53              push    ebx
804fe4f1 56              push    esi
804fe4f2 8b7508          mov     esi,dword ptr [ebp+8]
804fe4f5 57              push    edi
........


最后,马甲同学的惯用手法就是:
__asm
{
    mov   ebx, g_Addr
    push  xxx
    push  xxx
    ....
    call  ebx
}


1. 相对偏移需要自己计算一下 如果要 E8 类型 call hook 之类的话
2. 我个人极不推荐这种做法


IP 地址: 已记录   报告
   2008-12-02, 15:26 下午
neilhsu 离线,最后访问时间: 2009/12/23 17:02:23 手语

发帖数前10位
男
注册: 2008-06-06
发 贴: 73
Re: 求教:如何调用内核未引出的函数!
Reply Quote
学习了
鸿鹄安知燕雀之志
IP 地址: 已记录   报告
   2008-12-03, 14:56 下午
hollyhunter 离线,最后访问时间: 2009/10/10 9:42:36 holly

发帖数前50位
注册: 2008-07-14
发 贴: 22
Re: 求教:如何调用内核未引出的函数!
Reply Quote
汗颜,不知道怎么在代码中能够搞定这种事!
~~~~~~~~~

IP 地址: 已记录   报告
   2008-12-03, 16:43 下午
WANGyu 离线,最后访问时间: 2012/9/10 3:34:00 王宇

发帖数前10位
男
注册: 2007-05-08
发 贴: 306
Re: 求教:如何调用内核未引出的函数!
Reply Quote

暴力不难呀。

nt!NtSuspendThread 是 SSDT 表里的 API:

0: kd> u nt!ZwSuspendThread
nt!ZwSuspendThread:
80502104 b8fe000000      mov     eax,0FEh
80502109 8d542404        lea     edx,[esp+4]
8050210d 9c              pushfd
8050210e 6a08            push    8
80502110 e83c030400      call    nt!KiSystemService (80542451)
80502115 c20800          ret     8

0: kd> ?poi(80505450+0FE*4)
Evaluate expression: -2141366096 = 805d58b0

0: kd> ln 805d58b0
(805d58b0)   nt!NtSuspendThread   |  (805d5976)   nt!NtResumeThread
Exact matches:
    nt!NtSuspendThread = <no type information>

如果怕取的不正确就自己Map一份内核取到正确的地址。

然后开始反汇编这个地址,类似于下面的代码:

TotalSize = SizeOfProc( pTarFunction );

while( TRUE )
{
    if( CodeSize >= TotalSize ) break;

    Size = SizeOfCode( (PVOID) pTarget, &pOpcode );

    pTarget  += Size;
    CodeSize += Size;

    if( EnpCodeAnalysis(pOpcode, Size, CodeSize, TotalSize, HookNumber) )
    {
        if( !gs_TargetAnalysis.Types )
            INLINE_DBGPRINT( ("[keenjoy95 's Inline Hook Engine] - ERROR CODE 0xA0000001.\n") );

        break;
    }
}

明眼人一看就知道我这段代码用的是 Ms-Rem 的 反汇编引擎 LDasm,当然我自己的反汇编引擎也在编写中。

连续三次分析到长度为 5字节、E8 开头的指令就说明找到了 nt!PsSuspendThread,接下来找 nt!KeSuspendThread 的过程雷同。跳过 E8 是偏移 fff28d3f,需要计算一下。

我之所以不推荐这种方法的问题之一是跨平台,我简单看了一下,WIN-XP/2003/VISTA 下第三个 call 均是 nt!PsSuspendThread。

Windows 2000 Kernel Version 2195 (Service Pack 4) MP (2 procs) Free x86 下第三个 call 直接就是 nt!KeSuspendThread:

0: kd> u nt!NtSuspendThread
nt!NtSuspendThread:
804e6462 55              push    ebp
804e6463 8bec            mov     ebp,esp
804e6465 6aff            push    0FFFFFFFFh
804e6467 6828664080      push    offset nt!GUID_DEVICE_BATTERY+0x4b0 (80406628)
804e646c 68d00a4680      push    offset nt!_except_handler3 (80460ad0)
804e6471 64a100000000    mov     eax,dword ptr fs:[00000000h]
804e6477 50              push    eax
804e6478 64892500000000  mov     dword ptr fs:[0],esp
804e647f 51              push    ecx
804e6480 51              push    ecx
804e6481 83ec20          sub     esp,20h
804e6484 53              push    ebx
804e6485 56              push    esi
804e6486 57              push    edi
804e6487 8965e8          mov     dword ptr [ebp-18h],esp
804e648a 8365fc00        and     dword ptr [ebp-4],0
804e648e 64a124010000    mov     eax,dword ptr fs:[00000124h]
804e6494 8945cc          mov     dword ptr [ebp-34h],eax
804e6497 8a8034010000    mov     al,byte ptr [eax+134h]
804e649d 8845d8          mov     byte ptr [ebp-28h],al
804e64a0 84c0            test    al,al
804e64a2 8b750c          mov     esi,dword ptr [ebp+0Ch]
804e64a5 7417            je      nt!NtSuspendThread+0x5c (804e64be)
804e64a7 85f6            test    esi,esi
804e64a9 7413            je      nt!NtSuspendThread+0x5c (804e64be)
804e64ab a178474880      mov     eax,dword ptr [nt!MmUserProbeAddress (80484778)]
804e64b0 3bf0            cmp     esi,eax
804e64b2 7206            jb      nt!NtSuspendThread+0x58 (804e64ba)
804e64b4 c70000000000    mov     dword ptr [eax],0
804e64ba 8b06            mov     eax,dword ptr [esi]
804e64bc 8906            mov     dword ptr [esi],eax
804e64be 834dfcff        or      dword ptr [ebp-4],0FFFFFFFFh
804e64c2 6a00            push    0
804e64c4 8d45dc          lea     eax,[ebp-24h]
804e64c7 50              push    eax
804e64c8 ff75d8          push    dword ptr [ebp-28h]
804e64cb ff35285c4880    push    dword ptr [nt!PsThreadType (80485c28)]
804e64d1 6a02            push    2
804e64d3 ff7508          push    dword ptr [ebp+8]
804e64d6 e8e78ff6ff      call    nt!ObReferenceObjectByHandle (8044f4c2)
804e64db 85c0            test    eax,eax
804e64dd 0f8c9a000000    jl      nt!NtSuspendThread+0x11b (804e657d)
804e64e3 c745fc01000000  mov     dword ptr [ebp-4],1
804e64ea 64a124010000    mov     eax,dword ptr fs:[00000124h]
804e64f0 8945c8          mov     dword ptr [ebp-38h],eax
804e64f3 8b4ddc          mov     ecx,dword ptr [ebp-24h]
804e64f6 3bc8            cmp     ecx,eax
804e64f8 7419            je      nt!NtSuspendThread+0xb1 (804e6513)
804e64fa 83b92402000000  cmp     dword ptr [ecx+224h],0
804e6501 7410            je      nt!NtSuspendThread+0xb1 (804e6513)
804e6503 e89a92f6ff      call    nt!ObfDereferenceObject (8044f7a2)
804e6508 834dfcff        or      dword ptr [ebp-4],0FFFFFFFFh
804e650c b84b0000c0      mov     eax,0C000004Bh
804e6511 eb6a            jmp     nt!NtSuspendThread+0x11b (804e657d)
804e6513 51              push    ecx
804e6514 e86980f4ff      call    nt!KeSuspendThread (8042e582)

另外就是绕开入口函数直接调用 internal 实现有时往往会有一些问题。
比如外层函数修改了某些标志位再 call 的 internal_xxx,那么我们就需要手动设置这些标志位 等。


IP 地址: 已记录   报告
   2008-12-03, 18:56 下午
skyworth 离线,最后访问时间: 2009/12/15 16:03:09 skyworth

发帖数前25位
注册: 2008-06-07
发 贴: 55
Re: 求教:如何调用内核未引出的函数!
Reply Quote
直接调用未公开的函数不太好吧,既然未公开,那就不能确定微软会不会在某个时候改掉,然后就挂了……

个人觉得调用未公开的函数拿来练手是不错的,要是用在产品里,就不太合适了。
IP 地址: 已记录   报告
   2008-12-05, 13:58 下午
WANGyu 离线,最后访问时间: 2012/9/10 3:34:00 王宇

发帖数前10位
男
注册: 2007-05-08
发 贴: 306
Re: 求教:如何调用内核未引出的函数!
Reply Quote
上述暴力搜索解法是我不推荐的

我推荐的解法是栈回溯

但是至于如何回溯查找往往需要特别对待... ;)
IP 地址: 已记录   报告
   2008-12-05, 20:13 下午
MJ0011 离线,最后访问时间: 2009/12/24 22:33:41 MJ0011

发帖数前10位
注册: 2008-04-24
发 贴: 112
Re: 求教:如何调用内核未引出的函数!
Reply Quote
回溯不稳定啊~还是暴力搜索比较稳定
IP 地址: 已记录   报告
   2008-12-06, 11:59 上午
hollyhunter 离线,最后访问时间: 2009/10/10 9:42:36 holly

发帖数前50位
注册: 2008-07-14
发 贴: 22
Re: 求教:如何调用内核未引出的函数!
Reply Quote
内功不够深,打不通反汇编的任督二脉!
道理是懂了!~~~
IP 地址: 已记录   报告
高端调试 » 软件调试 » Windows内核调试 » Re: 求教:如何调用内核未引出的函数!

 
Legal Notice Privacy Statement Corporate Governance Corporate Governance
(C)2004-2020 ADVDBG.ORG All Rights Reserved.