首页
社区
课程
招聘
[原创]从内核创建用户态线程
发表于: 2014-7-29 11:56 28727

[原创]从内核创建用户态线程

2014-7-29 11:56
28727

简单方法从内核创建用户态线程.

在内核想要执行用户态的代码,通常的方式有.apc, usermodecallback等.
但是都各有缺点.

APC.
1.        apc的分发必须不被禁用,
2.        目标进程必须有处于alertable的线程.
特别是后者这个条件,很多时候不一定有.
比如explorer进程有很多线程,通常能找到.
但是像记事本这种单线程程序,就找不到.

UserModeCallback.
必须在目标进程空间调用,不能是attach.的.
必须加载过User32的.,这样才有Kernelcallbacktable

在某些特定的时机,我们是有机会执行的.
比如在进程刚刚创建的时候,我们可以修改OEP,修改IAT等加载我们的dll
在第一个线程创建之后,我们可以插入apc.这些条件都很好满足.

还有WOW64的兼容处理,在另一篇文章里说明.

但是如果任何时候.不限制调用的时机,比如在进程正常运行之后,这个时候,这些条件都不满足了.

虽然我们可以构造出场景,
比如,如果你是一个过滤驱动或者hook型的,那么总是有机会会切换到目标进程上空的,这个时候就有机会可以UserModeCallback.

现在要说的就是没有这些限制的做法.可以在任意时机,任意进程空间在任意进程中执行代码.
那就是直接在内核态给一个用户态进程创建一个用户态的线程.

模拟用户态进程给自己创建一个非远程线程的基本流程.

1.创建线程初始的栈,分配和保留栈空间.设置栈保护页.实现栈的自动增长.

2设置线程上下文,各个段寄存器和基本寄存器,设置eip指向Kernel32!BaseThreadTrunk

        .text:7C810473
.text:7C810473                         ; =============== S U B R O U T I N E =======================================
.text:7C810473
.text:7C810473                         ; Attributes: bp-based frame
.text:7C810473
.text:7C810473                         ; int __stdcall BaseInitializeContext(PCONTEXT Context, PVOID Parameter, PVOID StartAddress, PVOID StackAddress, ULONG ContextType)
.text:7C810473                         _BaseInitializeContext@20 proc near     ; CODE XREF: CreateRemoteThread(x,x,x,x,x,x,x)+84↓p
.text:7C810473                                                                 ; CreateProcessInternalW(x,x,x,x,x,x,x,x,x,x,x,x)+690↓p ...
.text:7C810473
.text:7C810473                         Context         = dword ptr  8
.text:7C810473                         Parameter       = dword ptr  0Ch
.text:7C810473                         StartAddress    = dword ptr  10h
.text:7C810473                         StackAddress    = dword ptr  14h
.text:7C810473                         ContextType     = dword ptr  18h
.text:7C810473
.text:7C810473                         ; FUNCTION CHUNK AT .text:7C81F10A SIZE 00000019 BYTES
.text:7C810473                         ; FUNCTION CHUNK AT .text:7C8316A2 SIZE 0000000F BYTES
.text:7C810473
.text:7C810473 8B FF                                   mov     edi, edi
.text:7C810475 55                                      push    ebp
.text:7C810476 8B EC                                   mov     ebp, esp
.text:7C810478 8B 45 08                                mov     eax, [ebp+Context]
.text:7C81047B 8B 4D 10                                mov     ecx, [ebp+StartAddress]
.text:7C81047E 83 A0 8C 00 00 00 00                    and     [eax+CONTEXT.SegGs], 0
.text:7C810485 83 7D 18 01                             cmp     [ebp+ContextType], 1
.text:7C810489 89 88 B0 00 00 00                       mov     [eax+CONTEXT._Eax], ecx
.text:7C81048F 8B 4D 0C                                mov     ecx, [ebp+Parameter]
.text:7C810492 89 88 A4 00 00 00                       mov     [eax+CONTEXT._Ebx], ecx
.text:7C810498 6A 20                                   push    20h
.text:7C81049A 59                                      pop     ecx
.text:7C81049B 89 88 94 00 00 00                       mov     [eax+CONTEXT.SegEs], ecx
.text:7C8104A1 89 88 98 00 00 00                       mov     [eax+CONTEXT.SegDs], ecx
.text:7C8104A7 89 88 C8 00 00 00                       mov     [eax+CONTEXT.SegSs], ecx
.text:7C8104AD 8B 4D 14                                mov     ecx, [ebp+StackAddress]
.text:7C8104B0 C7 80 90 00 00 00 38 00+                mov     [eax+CONTEXT.SegFs], 38h
.text:7C8104BA C7 80 BC 00 00 00 18 00+                mov     [eax+CONTEXT.SegCs], 18h
.text:7C8104C4 C7 80 C0 00 00 00 00 30+                mov     [eax+CONTEXT.EFlags], 3000h
.text:7C8104CE 89 88 C4 00 00 00                       mov     [eax+CONTEXT._Esp], ecx
.text:7C8104D4 0F 85 30 EC 00 00                       jnz     loc_7C81F10A
.text:7C8104DA C7 80 B8 00 00 00 29 07+                mov     [eax+CONTEXT._Eip], offset _BaseThreadStartThunk@8 ; BaseThreadStartThunk(x,x)
.text:7C8104E4
.text:7C8104E4                         loc_7C8104E4:                           ; CODE XREF: BaseInitializeContext(x,x,x,x,x)+ECAB↓j
.text:7C8104E4                                                                 ; BaseInitializeContext(x,x,x,x,x)+21239↓j
.text:7C8104E4 83 C1 FC                                add     ecx, 0FFFFFFFCh
.text:7C8104E7 C7 00 07 00 01 00                       mov     [eax+CONTEXT.ContextFlags], 10007h
.text:7C8104ED 89 88 C4 00 00 00                       mov     [eax+CONTEXT._Esp], ecx
.text:7C8104F3 5D                                      pop     ebp
.text:7C8104F4 C2 14 00                                retn    14h
.text:7C8104F4                         _BaseInitializeContext@20 endp
.text:7C8104F4
.text:7C8104F4                         ; ---------------------------------------------------------------------------

3对于vista以后,还得分配TEB的ActiveContextStackPointer.要不然执行某些用户态的API的时候,那些API没有检查TEB的ActiveContextStackPointer是否为NULL就从中取值,造成崩溃.
windows的CreateThread也做了这些事.

.text:0DCEBD8A 23 4D 10                                and     ecx, [ebp+dwStackSize]
.text:0DCEBD8D 51                                      push    ecx             ; MaximumStackSize
.text:0DCEBD8E F7 D8                                   neg     eax
.text:0DCEBD90 1B C0                                   sbb     eax, eax
.text:0DCEBD92 23 45 10                                and     eax, [ebp+dwStackSize]
.text:0DCEBD95 50                                      push    eax             ; StackSize
.text:0DCEBD96 53                                      push    ebx             ; ZeroBits
.text:0DCEBD97 56                                      push    esi             ; CreateThreadFlags
.text:0DCEBD98 FF B5 B8 FD FF FF                       push    [ebp+StartContext] ; StartContext
.text:0DCEBD9E FF B5 D0 FD FF FF                       push    [ebp+StartRoutine] ; StartRoutine
.text:0DCEBDA4 FF B5 CC FD FF FF                       push    [ebp+ProcessHandle] ; ProcessHandle
.text:0DCEBDAA FF B5 BC FD FF FF                       push    [ebp+ObjectAttributes] ; ObjectAttributes
.text:0DCEBDB0 68 FF FF 1F 00                          push    1FFFFFh         ; DesiredAccess
.text:0DCEBDB5 8D 85 E4 FD FF FF                       lea     eax, [ebp+hThread]
.text:0DCEBDBB 50                                      push    eax             ; ThreadHandle
.text:0DCEBDBC FF 15 74 13 CE 0D                       call    ds:__imp__NtCreateThreadEx@44 ; NtCreateThreadEx(x,x,x,x,x,x,x,x,x,x,x)
.text:0DCEBDC2 89 85 E8 FD FF FF                       mov     [ebp+var_218], eax
.text:0DCEBDC8 3B C3                                   cmp     eax, ebx
.text:0DCEBDCA 0F 8C A5 F8 01 00                       jl      loc_DD0B675
.text:0DCEBDD0 89 5D FC                                mov     [ebp+ms_exc.disabled], ebx
.text:0DCEBDD3 64 A1 18 00 00 00                       mov     eax, large fs:18h
.text:0DCEBDD9 8B 8D C0 FD FF FF                       mov     ecx, [ebp+var_240]
.text:0DCEBDDF 3B 48 20                                cmp     ecx, [eax+20h]
.text:0DCEBDE2 75 73                                   jnz     short loc_DCEBE57
.text:0DCEBDE4 8D 85 E0 FD FF FF                       lea     eax, [ebp+var_220]
.text:0DCEBDEA 50                                      push    eax
.text:0DCEBDEB FF 15 70 13 CE 0D                       call    ds:__imp__RtlAllocateActivationContextStack@4 ; RtlAllocateActivationContextStack(x)
.text:0DCEBDF1 89 85 E8 FD FF FF                       mov     [ebp+var_218], eax
.text:0DCEBDF7 3B C3                                   cmp     eax, ebx
.text:0DCEBDF9 0F 8C B2 F8 01 00                       jl      loc_DD0B6B1
.text:0DCEBDFF 8B 85 E0 FD FF FF                       mov     eax, [ebp+var_220]
.text:0DCEBE05 8B 8D D4 FD FF FF                       mov     ecx, [ebp+var_22C]
.text:0DCEBE0B 89 81 A8 01 00 00                       mov     [ecx+1A8h], eax
.text:0DCEBE11 53                                      push    ebx
.text:0DCEBE12 6A 08                                   push    8
.text:0DCEBE14 8D 85 D8 FD FF FF                       lea     eax, [ebp+var_228]
.text:0DCEBE1A 50                                      push    eax
.text:0DCEBE1B 56                                      push    esi

4获取当前进程的BaseObject目录,可以是默认的

5 ZwCreateThread创建线程对象了.挂起的

6最重要的一点了.通知csrss进程,有新线程创建了.

.text:0DCEBE65 8B 85 E4 FD FF FF                       mov     eax, [ebp+hThread]
.text:0DCEBE6B 89 85 18 FE FF FF                       mov     [ebp+var_1E8], eax
.text:0DCEBE71 8B 85 C0 FD FF FF                       mov     eax, [ebp+var_240]
.text:0DCEBE77 89 85 1C FE FF FF                       mov     [ebp+var_1E4], eax
.text:0DCEBE7D 8B 85 C4 FD FF FF                       mov     eax, [ebp+var_23C]
.text:0DCEBE83 89 85 20 FE FF FF                       mov     [ebp+var_1E0], eax
.text:0DCEBE89 6A 0C                                   push    0Ch
.text:0DCEBE8B 68 01 00 01 00                          push    10001h
.text:0DCEBE90 53                                      push    ebx
.text:0DCEBE91 8D 85 F0 FD FF FF                       lea     eax, [ebp+var_210]
.text:0DCEBE97 50                                      push    eax
.text:0DCEBE98 FF 15 F0 11 CE 0D                       call    ds:__imp__CsrClientCallServer@16 ; CsrClientCallServer(x,x,x,x)
.text:0DCEBE9E 8B 85 10 FE FF FF                       mov     eax, [ebp+var_1F0]
.text:0DCEBEA4
.text:0DCEBEA4                         loc_DCEBEA4:                            ; CODE XREF: GetDiskFreeSpaceExA(x,x,x,x)+2FB9↓j
.text:0DCEBEA4 89 85 E8 FD FF FF                       mov     [ebp+var_218], eax

7恢复线程的执行.

.text:0DCEBEC8
.text:0DCEBEC8                         loc_DCEBEC8:                            ; CODE XREF: CreateRemoteThreadEx(x,x,x,x,x,x,x,x)+22A↑j
.text:0DCEBEC8 F6 45 1C 04                             test    byte ptr [ebp+dwCreationFlags], 4
.text:0DCEBECC 75 13                                   jnz     short loc_DCEBEE1
.text:0DCEBECE 8D 85 AC FD FF FF                       lea     eax, [ebp+var_254]
.text:0DCEBED4 50                                      push    eax
.text:0DCEBED5 FF B5 E4 FD FF FF                       push    [ebp+hThread]
.text:0DCEBEDB FF 15 3C 13 CE 0D                       call    ds:__imp__NtResumeThread@8 ; NtResumeThread(x,x)
.text:0DCEBEE1
.text:0DCEBEE1                         loc_DCEBEE1:                            ; CODE XREF: CreateRemoteThreadEx(x,x,x,x,x,x,x,x)+238↑j
.text:0DCEBEE1                                                                 ; GetDiskFreeSpaceExA(x,x,x,x)+2F6E↓j ...
.text:0DCEBEE1 C7 45 FC FE FF FF FF                    mov     [ebp+ms_exc.disabled], 0FFFFFFFEh
.text:0DCEBEE8 E8 34 00 00 00                          call    sub_DCEBF21
.text:0DCEBEED 8B 85 E4 FD FF FF                       mov     eax, [ebp+hThread]
.text:0DCEBEF3
.text:0DCEBEF3                         loc_DCEBEF3:                            ; CODE XREF: GetDiskFreeSpaceExA(x,x,x,x)+2F27↓j
.text:0DCEBEF3 E8 A1 AD FF FF                          call    __SEH_epilog4_GS
.text:0DCEBEF8 C2 20 00                                retn    20h
.text:0DCEBEF8                         _CreateRemoteThreadEx@32 endp
.text:0DCEBEF8
.text:0DCEBEF8                         ; ---------------------------------------------------------------------------

对于windows的CreateThread还有一些其他的操作,比如判断是否是csrss进程自己在创建线程.
vista以后对于远程的线程,还有session的检查等.

听起来很麻烦的一件事情,其实我们可以简化问题.
在我的实现里,不考虑csrss自己给自己创建线程的情况,
实际上我们创建的都是普通的线程,非远程的,

很多同学尝试过模拟这个过程,大部分都在第6步卡住了,.这一步比较麻烦.

每个用户态进程在创建的时候,都会连接 \\Windows\\ApiPort ,
但是发现,如果我们在内核直接连接csrss的这个port,是连不上的.需要patch.

其实可以不用patch.,直接切换到csrss空间,自己来操作CsrProcessTable等内置数据结构,但是不同意.

我用到的办法比较简单.
因为目标进程已经连接过了.这个句柄还是有符号的, CsrPortHandle.
既然从内核连接不上,我们可以在系统句柄表里去搜索这个句柄,

搜索所有的 LpcPort或 AlpcPort类型的句柄,
判断是否是我们需要的进程,
然后判断他们的ConnectionPort是否是\\Windows\\ApiPort.
找到句柄之后,duplicate到当前进程,

就可以ZwRequestWaitReplyPort 或ZwAlpcSendWaitReceivePort通知csrss了.

关于 Kernel32!BaseThreadTrunk 我并没有直接把eip指向这个地方,这个函数没有导出.

.text:7C810729
.text:7C810729                         ; =============== S U B R O U T I N E =======================================
.text:7C810729
.text:7C810729                         ; Attributes: noreturn
.text:7C810729
.text:7C810729                         ; int __stdcall BaseThreadStartThunk(int, int)
.text:7C810729                         _BaseThreadStartThunk@8 proc near       ; DATA XREF: BaseInitializeContext(x,x,x,x,x)+67↑o
.text:7C810729
.text:7C810729                         arg_0           = dword ptr  4
.text:7C810729                         arg_4           = dword ptr  8
.text:7C810729
.text:7C810729 33 ED                                   xor     ebp, ebp
.text:7C81072B 53                                      push    ebx             ; Param
.text:7C81072C 50                                      push    eax             ; StartAddress
.text:7C81072D 6A 00                                   push    0
.text:7C81072F E9 BE AF FF FF                          jmp     _BaseThreadStart@8 ; BaseThreadStart(x,x)
.text:7C81072F                         _BaseThreadStartThunk@8 endp
.text:7C81072F
.text:7C81072F                         ; ---------------------------------------------------------------------------

.text:7C80B6F2
.text:7C80B6F2                         ; =============== S U B R O U T I N E =======================================
.text:7C80B6F2
.text:7C80B6F2                         ; Attributes: noreturn bp-based frame
.text:7C80B6F2
.text:7C80B6F2                         ; int __stdcall BaseThreadStart(int StartAddress, int ThreadParam)
.text:7C80B6F2                         _BaseThreadStart@8 proc near            ; CODE XREF: BaseThreadStartThunk(x,x)+6↓j
.text:7C80B6F2                                                                 ; BaseFiberStart()+12↓p
.text:7C80B6F2
.text:7C80B6F2                         Teb             = dword ptr -20h
.text:7C80B6F2                         ms_exc          = CPPEH_RECORD ptr -18h
.text:7C80B6F2                         StartAddress    = dword ptr  8
.text:7C80B6F2                         ThreadParam     = dword ptr  0Ch
.text:7C80B6F2
.text:7C80B6F2 6A 10                                   push    10h
.text:7C80B6F4 68 30 B7 80 7C                          push    offset stru_7C80B730
.text:7C80B6F9 E8 D8 6D FF FF                          call    __SEH_prolog
.text:7C80B6FE 83 65 FC 00                             and     [ebp+ms_exc.disabled], 0
.text:7C80B702 64 A1 18 00 00 00                       mov     eax, large fs:18h
.text:7C80B708 89 45 E0                                mov     [ebp+Teb], eax
.text:7C80B70B 81 78 10 00 1E 00 00                    cmp     dword ptr [eax+10h], 1E00h
.text:7C80B712 75 0F                                   jnz     short loc_7C80B723
.text:7C80B714 80 3D 08 50 88 7C 00                    cmp     _BaseRunningInServerProcess, 0
.text:7C80B71B 75 06                                   jnz     short loc_7C80B723
.text:7C80B71D FF 15 F8 12 80 7C                       call    ds:__imp__CsrNewThread@0 ; CsrNewThread()
.text:7C80B723
.text:7C80B723                         loc_7C80B723:                           ; CODE XREF: BaseThreadStart(x,x)+20↑j
.text:7C80B723                                                                 ; BaseThreadStart(x,x)+29↑j
.text:7C80B723 FF 75 0C                                push    [ebp+ThreadParam]
.text:7C80B726 FF 55 08                                call    [ebp+StartAddress]
.text:7C80B729 50                                      push    eax             ; dwExitCode
.text:7C80B72A
.text:7C80B72A                         loc_7C80B72A:                           ; CODE XREF: .text:7C83AB3B↓j
.text:7C80B72A E8 C9 09 00 00                          call    _ExitThread@4   ; ExitThread(x)
.text:7C80B72A                         _BaseThreadStart@8 endp
.text:7C80B72A
.text:7C80B72A                         ; ---------------------------------------------------------------------------

而且我还需要分配ActiveContextStackPointer,.
所以新线程的eip实际上是指向一段stub,
在stub里分配ActiveContextStackPointer,然后模拟的call 线程的起始地址,
然后调用RtlExitUserThread,确保在StartAddress ret的时候,可以自行退出.
就像系统做的那样.

        mov edi,API_RtlExitUserThread
        test edi,edi
        je _DirectRet
       
        ;调用用户提供的线程函数地址
        mov eax,var_StartAddress
        mov ebx,var_ThreadParam
       
        push ebx        ;线程的参数
        call eax        ;线程的起始地址
       
        ;是的用户线程函数返回时,我们可以让线程退出
        push eax
        call API_RtlExitUserThread

流程说完了.现在我们已经在内核模拟一个用户态线程给自己创建了一个线程.
非远程的,支持WOW64.

没有那么多限制条件执行用户态代码之后,可以做的事情就只局限于你的想象力了.
给目标进程注入一个dll简直是一个小意思了.

如果有事先执行的机会,就可以伪造各个杀毒软件或者系统进程的身份了.

附一些代码,因为依赖比较多,只贴关键的说明问题.

全文代码在下列系统测试通过.

xp/2003 32
win7/8/8.1 32/64

xSpy@binvul.com
xSpy@vxjump.net

排版的问题,代码还是传word吧.
CreateUserModeThreadFromKernelLand.doc


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (41)
雪    币: 13258
活跃值: (4306)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
同mark。。
2014-7-29 12:16
0
雪    币: 55
活跃值: (519)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
3
谢谢撸主,坐下仔细看看。
2014-7-29 12:25
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
mark
2014-7-29 13:11
0
雪    币: 21
活跃值: (87)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
mark
2014-7-29 14:32
0
雪    币: 144
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
很久以前,为了解决这个问题大伤脑筋,终于遇到高人啦
2014-7-29 23:44
0
雪    币: 1651
活跃值: (1425)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
7
alertable等于1也行,因为过一段时间线程会进去alertable为0的状态。
2014-7-30 00:14
0
雪    币: 66
活跃值: (960)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
mark
2014-7-30 09:22
0
雪    币: 138
活跃值: (306)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
9
如果你找不到alertable等于1 的
2014-7-30 09:44
0
雪    币: 35
活跃值: (96)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
文章有嚼头啊
2014-7-30 15:23
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
11
不通知csrss也没问题
2014-7-30 20:32
0
雪    币: 85
活跃值: (51)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
mark
2014-7-30 20:44
0
雪    币: 124
活跃值: (469)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
mark
2014-8-1 01:14
0
雪    币: 11
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
厉害!研究研究
2014-8-1 12:26
0
雪    币: 8764
活跃值: (5240)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
15
好文章,值得学习。
2014-8-5 10:59
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
这样会不会被查杀的厉害
2014-8-6 09:14
0
雪    币: 362
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
mark
2014-8-8 13:34
0
雪    币: 273
活跃值: (472)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
PVOID pLocalThunk = NULL;                //内核的Thunk数据
这是个什么数据 是个地址吗 我没在内核找到 我只找到了用户层的
mov dword ptr ds:[eax+0xB8],0x7C810729  //
mov     [eax+CONTEXT._Eip], offset _BaseThreadStartThunk@8
2014-11-15 23:38
0
雪    币: 576
活跃值: (2035)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
mark了 3q
2014-11-17 19:14
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
精品帖.
2014-12-3 12:57
0
雪    币: 265
活跃值: (81)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
mark 学习
2014-12-5 10:43
0
雪    币: 78
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
很多结构没弄清楚 ,希望楼主放出点完整代码
2015-8-4 23:37
0
雪    币: 334
活跃值: (92)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
23
都把关键的代码上传了,还不如直接传完整的呢。也能照顾一下我们这些低手是不?
2015-9-15 11:50
0
雪    币: 75
活跃值: (723)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
24
在内核hook nttestalert(), 分配用户态空间保存shellcode,修改trapframe返回的eip为shellcode.nttestalert返回用户态就跑去执行shellcode了,在shellcode里加载dll该干嘛干嘛。
2015-9-16 19:29
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
25
都不如直接挂起线程,然后EIP插入~
2016-5-24 20:06
0
游客
登录 | 注册 方可回帖
返回
//