MSDN系列(43)--从僵死的调试器中抢救被调试进程
2021-12-24 08:42:34 Author: mp.weixin.qq.com(查看原文) 阅读量:49 收藏

☆ 背景介绍

云海在测试机中误操作,直接Attach lsass了,然后windbg僵死。碰上过这事的可能知道,此时大概率杀不掉windbg,也不敢杀啊,杀了lsass也挂了。同时没法Detach,因为windbg失去响应了。他来问我有啥办法旁路Detach,否则只能重启系统了。我还真在十三年前看过Skywing的神操作,这事某些情况下有解,但云海来问时,我没想起细节。

本文在Win10企业版2016 LTSB 1607(OS Build 14393.4704)上测试。

☆ Skywing的技术方案

Recovering a process from a hung debugger - Ken Johnson [2009-02-21]
http://www.nynaeve.net/?p=274

要点是给windbg指定"-pe"二次Attach,然后Resume线程,最后qd退出。

二十一世纪初时,Skywing和Skape这对双S组合在安全领域很是拉风。Skape真名是Matt Miller,大约在2008年底加入微软,负责MSRC?这我不确认,反正后来给微软报漏洞、报缓解措施的可能跟他打过交道。他的个人主页还在维护中。

Skywing的真名是Ken Johnson,大约在2009年初加入微软,比Skape晚了没几个月,去了同一个安全团队吧。这是不输Alex Ionescu的顶级神人,曾经从他那儿学了好多东西,其个人主页停更于2010年,但仍活着。

云海说Skywing应该还在微软。Matt Miller提过一次,说他们试图让Skywing用Twitter,失败了,但他们说服Skywing重新写blog,下面这篇就是Skywing写的

https://msrc-blog.microsoft.com/2018/03/23/kva-shadow-mitigating-meltdown-on-windows/

总的来说,Skywing进入了神隐模式,不更新自己的旧blog,也不用Twitter。他这种神仙范儿,真心佩服。只是有些遗憾,再也不能从他那里学东西了。

☆ 调试lsass引发的死锁

在管理员级cmd中执行

C:\temp\cdb.exe -sins -y "srv*http://msdl.microsoft.com/download/symbols" -noinh -snul -hd -o -pn lsass.exe

依次尝试访问任务栏上的"桌面"、开始菜单、资源管理器,尝试Ctrl-Shift-Esc、Win-R,确保整个系统进入死锁状态。

若此刻Host与Guest之间有kd接入,可以看到发生了什么。

kd> !process 0 0x1f lsass.exe
PROCESS ffffda884002a800
    SessionId: 0  Cid: 0314    Peb: e6548a7000  ParentCid: 02ac
FreezeCount 1
    ...
    DebugPort                         ffffda8843215970

        THREAD ffffda8840027080  Cid 0314.0324  Teb: 000000e6548ac000 Win32Thread: 0000000000000000 WAIT: (Suspended) KernelMode Non-Alertable
SuspendCount 1
FreezeCount 1
            ffffda8840027360  NotificationEvent
        Not impersonating
        DeviceMap                 ffffa08d0bc17c50
        Owning Process            ffffda884002a800       Image:         lsass.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      98653130       Ticks: 10534 (0:00:02:44.593)
        Context Switch Count      583            IdealProcessor: 0
        UserTime                  00:00:00.000
        KernelTime                00:00:00.000
        Win32 Start Address lsass!LsapRmServerThread (0x00007ff772ec3570)
        Stack Init ffffb10165dddc90 Current ffffb10165ddd180
        Base ffffb10165dde000 Limit ffffb10165dd8000 Call 0000000000000000
        Priority 11 BasePriority 9 PriorityDecrement 0 IoPriority 2 PagePriority 5
        Child-SP          RetAddr           Call Site
        ffffb101`65ddd1c0 fffff802`b7c751bd nt!KiSwapContext+0x76
        ffffb101`65ddd300 fffff802`b7c74c5f nt!KiSwapThread+0x17d
        ffffb101`65ddd3b0 fffff802`b7c76a37 nt!KiCommitThreadWait+0x14f
        ffffb101`65ddd450 fffff802`b7cb95ad nt!KeWaitForSingleObject+0x377
        ffffb101`65ddd500 fffff802`b7c77c4a nt!KiSchedulerApc+0x231
        ffffb101`65ddd620 fffff802`b7c753a4 nt!KiDeliverApc+0x22a
        ffffb101`65ddd6b0 fffff802`b7c74c5f nt!KiSwapThread+0x364
        ffffb101`65ddd760 fffff802`b7c76a37 nt!KiCommitThreadWait+0x14f
        ffffb101`65ddd800 fffff802`b7cfb18a nt!KeWaitForSingleObject+0x377
        ffffb101`65ddd8b0 fffff802`b80079cd nt!AlpcpWaitForSingleObject+0x3e
        ffffb101`65ddd8f0 fffff802`b7ffd59b nt!AlpcpReceiveMessagePort+0x44d
        ffffb101`65ddd980 fffff802`b7ffd3fe nt!AlpcpReceiveLegacyMessage+0x10b
        ffffb101`65ddda20 fffff802`b7ffd323 nt!NtReplyWaitReceivePortEx+0xce
        ffffb101`65dddac0 fffff802`b7d75103 nt!NtReplyWaitReceivePort+0xf
        ffffb101`65dddb00 00007fff`88d95de4 nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffb101`65dddb00)
        000000e6`
54b7f3f8 00000000`00000000 ntdll!NtReplyWaitReceivePort+0x14

        ...

        THREAD ffffda8841a8b600  Cid 0314.1928  Teb: 000000e654962000 Win32Thread: 0000000000000000 WAIT: (Executive) KernelMode Non-Alertable
SuspendCount 1
FreezeCount 1
            ffffb10166027d80  SynchronizationEvent
        Not impersonating
        DeviceMap                 ffffa08d0bc17c50
        Owning Process            ffffda884002a800       Image:         lsass.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      98653131       Ticks: 10533 (0:00:02:44.578)
        Context Switch Count      9              IdealProcessor: 0
        UserTime                  00:00:00.000
        KernelTime                00:00:00.000
        Win32 Start Address ntdll!DbgUiRemoteBreakin (0x00007fff88dc0480)
        Stack Init ffffb10166028c90 Current ffffb101660279b0
        Base ffffb10166029000 Limit ffffb10166023000 Call 0000000000000000
        Priority 9 BasePriority 9 PriorityDecrement 0 IoPriority 2 PagePriority 5
        Child-SP          RetAddr           Call Site
        ffffb101`

660279f0 fffff802`b7c751bd nt!KiSwapContext+0x76
        ffffb101`
66027b30 fffff802`b7c74c5f nt!KiSwapThread+0x17d
        ffffb101`
66027be0 fffff802`b7c76a37 nt!KiCommitThreadWait+0x14f
        ffffb101`
66027c80 fffff802`b821f79c nt!KeWaitForSingleObject+0x377
        ffffb101`
66027d30 fffff802`b8220985 nt!DbgkpQueueMessage+0x230
        ffffb101`
66027f30 fffff802`b80fe7da nt!DbgkpSendApiMessage+0xa9
        ffffb101`
66027f80 fffff802`b7cbb521 nt!DbgkForwardException+0x14e
        ffffb101`
66028100 fffff802`b7d75702 nt!KiDispatchException+0x331
        ffffb101`
66028920 fffff802`b7d70298 nt!KiExceptionDispatch+0xc2
        ffffb101`
66028b00 00007fff`88d994f1 nt!KiBreakpointTrap+0x2d8 (TrapFrame @ ffffb101`66028b00)
        000000e6`671ffd08 00007fff`88dc04ca ntdll!DbgBreakPoint+0x1
        000000e6`671ffd10 00007fff`885b84d4 ntdll!DbgUiRemoteBreakin+0x4a
        000000e6`671ffd40 00007fff`88d41791 KERNEL32!BaseThreadInitThunk+0x14
        000000e6`671ffd70 00000000`00000000 ntdll!RtlUserThreadStart+0x21

lsass.exe中有很多线程,重点看上面列出来的两个线程。

第一个线程在调nt!AlpcpReceiveMessagePort,该线程负责处理RPC/ALPC的读取。第二个线程对应ntdll!DbgUiRemoteBreakin,这是cdb调试lsass时远程注入的调试线程。

现在看看cdb里发生了什么

kd> !process 0 0x1f cdb.exe
PROCESS ffffda8844326800
    SessionId: 1  Cid: 1680    Peb: f607a9c000  ParentCid: 1b0c
    ...

        THREAD ffffda884146e080  Cid 1680.0e80  Teb: 000000f607a9d000 Win32Thread: ffffda883f8b6370 WAIT: (WrLpcReply) UserMode Non-Alertable
            ffffda884146e6c0  Semaphore Limit 0x1
        Waiting for reply to ALPC Message ffffa08d2120ccf0 : queued at port ffffda8840064ad0 : owned by process ffffda884002a800
        Not impersonating
        DeviceMap                 ffffa08d1dc71550
        Owning Process            ffffda8844326800       Image:         cdb.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      98653131       Ticks: 10541 (0:00:02:44.703)
        Context Switch Count      252            IdealProcessor: 0
        UserTime                  00:00:00.000
        KernelTime                00:00:00.046
        Win32 Start Address cdb!wmainCRTStartup (0x00007ff7a7ddc8b0)
        Stack Init ffffb10165242c90 Current ffffb10165242300
        Base ffffb10165243000 Limit ffffb1016523d000 Call 0000000000000000
        Priority 13 BasePriority 13 PriorityDecrement 0 IoPriority 2 PagePriority 5
        Kernel stack not resident.
        Child-SP          RetAddr           Call Site
        ffffb101`65242340 fffff802`b7c751bd nt!KiSwapContext+0x76
        ffffb101`65242480 fffff802`b7c74c5f nt!KiSwapThread+0x17d
        ffffb101`65242530 fffff802`b7c76a37 nt!KiCommitThreadWait+0x14f
        ffffb101`652425d0 fffff802`b7c78048 nt!KeWaitForSingleObject+0x377
        ffffb101`65242680 fffff802`b8002b28 nt!AlpcpSignalAndWait+0x1d8
        ffffb101`65242720 fffff802`b80db059 nt!AlpcpReceiveSynchronousReply+0x58
        ffffb101`65242780 fffff802`b806412d nt!AlpcpProcessConnectionRequest+0x241
        ffffb101`65242890 fffff802`b80fb39c nt!AlpcpConnectPort+0x2c5
        ffffb101`65242a10 fffff802`b7d75103 nt!NtAlpcConnectPortEx+0x70
        ffffb101`65242a90 00007fff`88d96b34 nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffb101`65242b00)
        000000f6`
07c75bf8 00007fff`8813dc12 ntdll!NtAlpcConnectPortEx+0x14
        000000f6`
07c75c00 00007fff`8813e5e7 RPCRT4!LRPC_CASSOCIATION::AlpcConnect+0x28a
        000000f6`
07c75dc0 00007fff`881386ae RPCRT4!LRPC_CASSOCIATION::Connect+0x17f
        000000f6`
07c75e90 00007fff`8812ebf9 RPCRT4!LRPC_BASE_BINDING_HANDLE::DriveStateForward+0x47e
        000000f6`
07c75f20 00007fff`881d7072 RPCRT4!LRPC_BINDING_HANDLE::NegotiateTransferSyntax+0xa79
        000000f6`
07c76020 00007fff`881d6652 RPCRT4!NdrpClientCall3+0x7e2
        000000f6`
07c763c0 00007fff`84e34a5d RPCRT4!NdrClientCall3+0xf2
        000000f6`
07c76750 00007fff`84e344f1 SSPICLI!CreateRpcConnection+0x69
        000000f6`
07c767d0 00007fff`84e37a26 SSPICLI!InitState+0x55
        000000f6`
07c76820 00007fff`84e37790 SSPICLI!SspipGetUserName+0x1d6
        000000f6`
07c76910 00007fff`84e3a8ab SSPICLI!GetUserNameExW+0x50
        000000f6`
07c76960 00007fff`74b8fb9c SSPICLI!GetUserNameExA+0x6b
        000000f6`
07c769b0 00007fff`74b8fa66 wininet!WininetGetUserName+0x28
        000000f6`
07c769e0 00007fff`88d1a491 wininet!_InitOnceGlobalUserName+0x56
        000000f6`
07c76b60 00007fff`860bc7aa ntdll!RtlRunOnceExecuteOnce+0x91
        000000f6`
07c76ba0 00007fff`74b964ff KERNELBASE!InitOnceExecuteOnce+0xa
        000000f6`
07c76bd0 00007fff`74b3fa76 wininet!InitializeGlobalUserName+0x2f
        000000f6`
07c76c00 00007fff`74b42c7d wininet!CacheClientGlobalInitialize+0x56
        000000f6`
07c76c40 00007fff`74b4038e wininet!GetCurrentSettingsVersion+0x55
        000000f6`
07c76c70 00007fff`74bac303 wininet!GlobalDataInitialize+0xde
        000000f6`
07c76d30 00007fff`74bac0f9 wininet!InternetOpenA+0x183
        000000f6`
07c76e70 00007fff`73df87dc wininet!InternetOpenW+0x129
        000000f6`
07c76f10 00007fff`73df416e symsrv!StoreWinInet::connect+0x39c
        000000f6`
07c77430 00007fff`73deac47 symsrv!StoreHTTP::find+0x5e
        000000f6`
07c77b50 00007fff`73debb69 symsrv!cascade+0xe7
        000000f6`
07c77fa0 00007fff`73debcc6 symsrv!SymbolServerByIndexWorkerW+0x369
        000000f6`
07c78b70 00007fff`73deb49a symsrv!SymbolServerByIndexAndChecksumsW+0x66
        000000f6`
07c78bc0 00007fff`7063fb6f symsrv!SymbolServerW+0xba
        000000f6`
07c78e50 00007fff`70629be1 dbghelp!symsrvGetFile+0x2ef
        000000f6`
07c79710 00007fff`7062aa49 dbghelp!diaLocatePdb+0x595

cdb.exe中有多个线程。第一个线程正在试图加载PDB,由此发起RPC调用,这个调用的RPC服务端在lsass.exe里。lsass正被cdb调试,无法响应RPC请求,cdb又等着lsass响应自己发起的RPC请求,典型的死锁。

"Waiting for reply"这一行已经指明死锁关键,包括引起死锁的进程

可以利用调用栈上的数据获取cdb发起的RPC请求的更多信息

IID     4f32adc8-6052-4a04-8701-293ccf2096f0
ProcNum 0 (sspisrv!SspirConnectRpc)

☆ 利用kd detach

假设在Guest中cdb调试lsass.exe陷入死锁,但Host与Guest间有kd接入,如何用kd进行抢救?这个问题有现实意义。我一般用cdb,不怎么用GUI的windbg。调试lsass需要管理员级cmd,我只有一个管理员级cmd,还被cdb占用了,Skywing的技术方案不适用于此真实场景,这可能是一个用windbg而不用cdb的理由吧。当时我有kd,所以很不甘心重启或恢复快照,想利用kd直接抢救,后来找到一个可用方案。

我问了一下杨军锋、王宇,二位给了大致类似的思路,设法让cdb走detach的流程。杨军锋建议利用kd在cdb进程空间注入shellcode,调用DebugActiveProcessStop。后来证明,思路可行,但有一些细节要处理。

KERNELBASE!DebugActiveProcessStop(PID)
  KERNELBASE!ProcessIdToHandle(PID)
  ntdll!DbgUiStopDebugging(ProcessHandle)
    ntdll!NtRemoveProcessDebug(ProcessHandle,DebugObjectHandle)

假设中断在NtRemoveProcessDebug,kpn看调用栈,看不到DbgUiStopDebugging,因为在汇编层面有个优化,DbgUiStopDebugging是jmp到NtRemoveProcessDebug,不是call过去的。

真正进行detach操作的是NtRemoveProcessDebug,它需要两个参数,一个是被调试进程句柄,另一个是DebugObject句柄,这是被调试进程DebugPort在调试器进程空间的索引。虽然DebugActiveProcessStop只需要指定目标PID,但实际上要用到DebugObjectHandle,该值来自线程变量"NtCurrentTeb()->DbgSsReserved[1]"。

KERNELBASE!DebugActiveProcess
  ntdll!DbgUiConnectToDbg
    ntdll!NtCreateDebugObject

DbgUiConnectToDbg中调用NtCreateDebugObject设置DbgSsReserved[1]。cdb进程有多个线程,应该在调用DebugActiveProcess创建调试会话的那个线程中调用配对的DebugActiveProcessStop,因为它们共用同一个线程变量DbgSsReserved[1]。

但现代cdb实现,或者说dbgeng实现,不再使用DbgSsReserved[1]。detach时调用栈回溯如下

 # Call Site
00 ntdll!NtRemoveProcessDebug
01 dbgeng!LiveUserDebugServices::DetachProcess+0x77
02 dbgeng!LiveUserTargetInfo::DetachProcess+0xe0
03 dbgeng!ProcessInfo::Separate+0x354
04 dbgeng!ParseSeparateCurrentProcess+0xf5
05 dbgeng!DotCommand+0xf1
06 dbgeng!ProcessCommands+0xc90
07 dbgeng!ProcessCommandsAndCatch+0x86
08 dbgeng!Execute+0x346
09 dbgeng!DebugClient::ExecuteWide+0x94
0a cdb!MainLoop+0x532
0b cdb!wmain+0x4df
0c cdb!__wmainCRTStartup+0x14d
0d KERNEL32!BaseThreadInitThunk+0x14
0e ntdll!RtlUserThreadStart+0x21

detach时甚至没有调用DebugActiveProcessStop,直接调了NtRemoveProcessDebug。现代dbgeng实现有几个类,ProcessInfo、LiveUserTargetInfo、LiveUserDebugServices,原来保存在DbgSsReserved[1]的DebugObjectHandle现在应该是某个类成员变量。手工检查cdb所有线程TEB,所有DbgSsReserved[]都是NULL,无一被使用。

不必找那个保存DebugObjectHandle的类成员变量,"!process 0 1 lsass.exe"得到DebugPort地址,"!findhandle DebugPort cdb"得到DebugObjectHandle。咱有kd,干嘛不用?

既然有DebugObjectHandle,就想直接调NtRemoveProcessDebug来detach。起初用"!findhandle lsass cdb"得到一个ProcessHandle,测试发现这个Handle不能用于NtRemoveProcessDebug。看ProcessIdToHandle实现,应该与NtOpenProcess第2形参有关,是不是得指定PROCESS_SET_PORT啊?未进一步测试。不想自己打开进程,还是用DebugActiveProcessStop吧。不就是从DbgSsReserved[1]取DebugObjectHandle吗,提前填上有效值就是。

dx @$teb->DbgSsReserved[1]=(void*)0x16c

可以修改cdb!wmainCRTStartup附近的代码,用来存放定制的汇编代码,反正也不会用到了。

如果不在kd里,还可以用.dvalloc分配一块内存存放汇编代码。接下来的问题是,怎么让cdb的流程转向修改过的cdb!wmainCRTStartup?由于对Windows内核不熟,我用了个最直白的办法,杀掉cmd导致杀掉cdb,流程转ntdll!NtTerminateProcess。

在用户态用cdb调notepad,然后杀cmd间接杀cdb,有个调用栈回溯

 # Call Site
00 ntdll!NtTerminateProcess
01 ntdll!RtlExitUserProcess+0x5b
02 KERNELBASE!DefaultHandler+0xf
03 KERNELBASE!CtrlRoutine+0xa3
04 KERNEL32!BaseThreadInitThunk+0x14
05 ntdll!RtlUserThreadStart+0x21

用cdb调lsass时也一样。可以先对NtTerminateProcess设断,命中后强制修改rip到cdb!wmainCRTStartup,这样定制的汇编代码得到执行。

不要在kd中.kill杀cdb,那样的话流程不过ntdll!NtTerminateProcess。得去用户态杀cmd间接杀cdb。

为了验证思路可行,先用cdb调notepad,用kd帮cdb detach,即使出幺蛾子也没啥影响。起初在cdb中只调DebugActiveProcessStop,发现notepad的DebugPort确实关闭了,杀cmd间接杀cdb后,notepad没跟着一块儿完蛋。但是,notepad呈僵死状态。在kd里"!process 0 3 notepad.exe",一堆的"SuspendCount 1"、"FreezeCount 1"。没去查SuspendCount、FreezeCount的意义,前者应该是KeSuspendThread导致的,后者是啥概念?正常运行的notepad,这两种值都是0。

想了想,除了DebugActiveProcessStop,可能还得ResumeThread。实验表明,确实如此。又一次用了笨办法

.shell -ci "!process 0 2 notepad.exe" findstr "THREAD "
awk -F' ' '{print "!findhandle " $2 " ffffda883eaef800";}' some.txt

得到notepad所有线程在cdb进程空间的对应句柄,不是TID,ResumeThread用的是线程句柄。循环调用ResumeThread,继续执行notepad的所有线程。之后,notepad恢复正常,attach上来的cdb已经被杀,notepad还活着。相当于在cdb失去响应的情况下旁路detach成功。把同样的思路用于lsass死锁场景,成功解除死锁,系统恢复响应。

有无可能利用kd强制cdb走.detach对应的流程,直接使用现有代码,而不是定制一段汇编,尤其是lsass死锁场景。这也是各种遗留问题之一,留待有缘人解答。

☆ detach.nasm

很久不写Intel汇编代码,下面这段写得相当扯淡,但能用。这只是个模板,需要填写有效值再编译。

; nasm -f bin -o detach.bin detach.nasm

BITS 64

%macro pushaq 0
    pushfq
    push rcx
    push rdx
    push rbx
    push rbp
    push rsi
    push rdi
    push r8
    push r9
    push r10
    push r11
    push r12
    push r13
    push r14
    push r15
%endmacro

%macro popaq 0
    pop r15
    pop r14
    pop r13
    pop r12
    pop r11
    pop r10
    pop r9
    pop r8
    pop rdi
    pop rsi
    pop rbp
    pop rbx
    pop rdx
    pop rcx
    popfq
%endmacro

DebugActiveProcessStop  equ 0
ResumeThread            equ 8
TerminateProcess        equ 0x10

; dt nt!_TEB DbgSsReserved
DbgSsReserved           equ 0x16a0

_start:

    pushaq

    ; get rip relative to the next instruction after the lea
    lea     rbp, [rel $+7]

base:

    movzx   rax, word [rbp+DebugPort_handle-base]
    mov     rdx, [gs:0x30]
    mov     qword[rdx+DbgSsReserved+1*8], rax
    movzx   rcx, word [rbp+target_pid-base]
    call    qword [rbp+func_array+DebugActiveProcessStop-base]
    xor     rbx, rbx

loop:

    movzx   rcx, word [rbp+thread_handle_array-base+rbx*2]
    call    qword [rbp+func_array+ResumeThread-base]
    inc     rbx
    cmp     bx, word [rbp+thread_handle_count-base]
    jne     loop

    popaq

    lea     rax, [rel $+7]
    jmp     qword [rax+func_array+TerminateProcess-$]

func_array:

    ; KERNELBASE!DebugActiveProcessStop
    dq      0x7fff86136e10

    ; KERNELBASE!ResumeThread
    dq      0x7fff860dd770

    ; KERNELBASE!TerminateProcess
    dq      0x7fff860e1130

thread_handle_count:

    dw      ( thread_handle_end - thread_handle_array ) / 2

DebugPort_handle:

    dw      0x1314

target_pid:

    dw      0x1315

thread_handle_array:

    dw      0x1316
    dw      0x1317
    dw      0x1318
    dw      0x1319
    dw      0x131a
    dw      0x131b
    dw      0x131c

thread_handle_end:

☆ 使用示例

在管理员级cmd中执行

C:\temp\cdb.exe -sins -y "srv*http://msdl.microsoft.com/download/symbols" -noinh -snul -hd -o -pn lsass.exe

在kd中".process /i"切到cdb进程空间,执行如下操作

.readmem detach_lsass.bin cdb!wmainCRTStartup l 0n159
u cdb!wmainCRTStartup cdb!wmainCRTStartup+0n159
ba e1 /1 /p @$proc KERNELBASE!CtrlRoutine "r rip=cdb!wmainCRTStartup;gc"

回Guest对着僵死的cdb按下Ctrl-C解除死锁,管理员级cmd仍在。

上例假设detach_lsass.bin大小是159字节。

☆ 后记

相比Skywing的方案,我的方案没啥优势,但有时没机会用Skywing的方案,我碰上了,就研究了一下。绝大多数人这辈子都不需要了解这些东西,也用不上。

2021-12-22 06:04 bluerust

kill cmd来终止cdb这步我不一定会想到,如果是我的话,可能会想着塞一段kernel shellcode进去,然后KeStackAttachProcess,在内核分配用户进程空间,写入用户态shellcode,最后KeInsertQueueApc在cdb里执行shellcode,应该也行。当然,我这还是YY,实操不知道可行不。我很久没有用汇编写shellcode了,我都是用C。

Loading and Debugging Windows Kernel Shellcodes with Windbg - Javier Vicente Vallejo [2017-07-23]
https://vallejocc.wordpress.com/2017/06/23/loading-and-debugging-windows-kernel-shellcodes-with-windbg-debugging-doublepulsar-shellcode/

文章来源: http://mp.weixin.qq.com/s?__biz=MzUzMjQyMDE3Ng==&mid=2247485082&idx=1&sn=1d083c8e6aa86d20f1dfb129eb449f77&chksm=fab2c5a5cdc54cb33b2815cedd97fa7aae51ff004ee6777b9784b29ff714738514f9bcf7c127#rd
如有侵权请联系:admin#unsafe.sh