调试之前使用windbg打开notepad观察
00007ffd`23ae0670 cc int 3
0:000> u ntdll!LdrInitializeThunk
ntdll!LdrInitializeThunk:
00007ffd`23a84b10 4053 push rbx
00007ffd`23a84b12 4883ec20 sub rsp,20h
00007ffd`23a84b16 488bd9 mov rbx,rcx
00007ffd`23a84b19 e81a000000 call ntdll!LdrInitializeThunk+0x28 (00007ffd`23a84b38)
00007ffd`23a84b1e b201 mov dl,1
00007ffd`23a84b20 488bcb mov rcx,rbx
00007ffd`23a84b23 e8488a0200 call ntdll!NtContinue (00007ffd`23aad570)
00007ffd`23a84b28 8bc8 mov ecx,eax
为了调试目标进程,可以有多种方法:
1.将windbug放入沙箱,然后再通过windbg启动notepad,为了观察注入的初始化过程,启动后将Loadmodule勾选上

为了方便调试lowlevel,编译的时候打开这一项:

这样在编译目录下可以看到代码和二进制的对应关系文件init.cod和inject.cod
2.使用glfags设置目标进程notepad.exe的调试程序为windbg,将txt放入沙箱,启动,观察
0:000> u ntdll!LdrInitializeThunk
ntdll!LdrInitializeThunk:
00007ffd`23a84b10 b8c00bbc00 mov eax,0BC0BC0h
00007ffd`23a84b15 ffe0 jmp rax
00007ffd`23a84b17 8bd9 mov ebx,ecx
00007ffd`23a84b19 e81a000000 call ntdll!LdrInitializeThunk+0x28 (00007ffd`23a84b38)
00007ffd`23a84b1e b201 mov dl,1
00007ffd`23a84b20 488bcb mov rcx,rbx
00007ffd`23a84b23 e8488a0200 call ntdll!NtContinue (00007ffd`23aad570)
00007ffd`23a84b28 8bc8 mov ecx,eax
其中
0BC0BC0是跳转的地址。
u 0BC0BC0
0:000> u 0BC0BC0
00000000`00bc0bc0 4883ec28 sub rsp,28h
00000000`00bc0bc4 48894c2420 mov qword ptr [rsp+20h],rcx
00000000`00bc0bc9 4889542428 mov qword ptr [rsp+28h],rdx
00000000`00bc0bce 4c89442430 mov qword ptr [rsp+30h],r8
00000000`00bc0bd3 4c894c2438 mov qword ptr [rsp+38h],r9
00000000`00bc0bd8 e800000000 call 00000000`00bc0bdd 这个地方是EntrypointC
00000000`00bc0bdd 59 pop rcx
00000000`00bc0bde 488bd9 mov rbx,rcx
按照该位置加载LowLevel地址,dll长度0x2000,如下加载符号表
.reload lowlevel=00BC0BC0,2000
加载完毕,查找lowlevel所有的符号:
00000000`00bc0bde 488bd9 mov rbx,rcx
0:000> x lowlevel!*
00000000`00bc4bc8 lowlevel!`__local_stdio_scanf_options'::`2'::_OptionsStorage = 0
00000000`00bc4bc0 lowlevel!`__local_stdio_printf_options'::`2'::_OptionsStorage = 0
00000000`00bc2a0f lowlevel!SbieLowData = 0x00000161`c2c74900
00000000`00bc2250 lowlevel!InitInject (void *, void *)
00000000`00bc1d00 lowlevel!InitSyscalls (void *)
00000000`00bc2640 lowlevel!InitInjectWow64 (void *)
00000000`00bc1c10 lowlevel!SbieApi_QueryProcessInfo (unsigned long)
00000000`00bc1fe0 lowlevel!EntrypointC (void *, void *, void *)
00000000`00bc1cb0 lowlevel!findChromeTarget (unsigned char *)
00000000`00bc2130 lowlevel!FindDllExport2 (void *, unsigned char *)
00000000`00bc20c0 lowlevel!FindDllExport (void *, unsigned char *)
00000000`00bc27e5 lowlevel!myService (void)
00000000`00bc1fa0 lowlevel!InitConsole (void)
00000000`00bc1bc0 lowlevel!SbieApi_Ioctl (void *)
00000000`00bc203c lowlevel!InitConsole = (inline caller) lowlevel!EntrypointC+5c
00000000`00bc1dc3 lowlevel!findChromeTarget = (inline caller) lowlevel!InitSyscalls+c3
00000000`00bc1e06 lowlevel!findChromeTarget = (inline caller) lowlevel!InitSyscalls+106
00000000`00bc1c1f lowlevel!SbieApi_Ioctl = (inline caller) lowlevel!SbieApi_QueryProcessInfo+f
00000000`00bc231e lowlevel!FindDllExport = (inline caller) lowlevel!InitInject+ce
00000000`00bc2287 lowlevel!FindDllExport = (inline caller) lowlevel!InitInject+37
00000000`00bc240b lowlevel!InitInjectWow64 = (inline caller) lowlevel!InitInject+1bb
00000000`00bc0bdd 这个是EntrypointC的地址,但是根据加载的符号位置却是00000000`00bc1fe0,说明符号表加载的位置靠后了。
所以需要向前移动00bc1fe0-00bc0bdd=1403
0BC0BC0-1403=BB F7BD
.reload /u lowlevel
.reload lowlevel=BBF7BD,2000
0:000> u 0BC0BC0
*** WARNING: Unable to verify timestamp for lowlevel
lowlevel!EntrypointC+0x3f [E:\works\opensource\Sandboxie\Sandboxie\core\low\init.c @ 555]:
00000000`00bc0bc0 4883ec28 sub rsp,28h
00000000`00bc0bc4 48894c2420 mov qword ptr [rsp+20h],rcx
00000000`00bc0bc9 4889542428 mov qword ptr [rsp+28h],rdx
00000000`00bc0bce 4c89442430 mov qword ptr [rsp+30h],r8
00000000`00bc0bd3 4c894c2438 mov qword ptr [rsp+38h],r9
00000000`00bc0bd8 e800000000 call lowlevel!EntrypointC(00000000`00bc0bdd)
00000000`00bc0bdd 59 pop rcx
00000000`00bc0bde 488bd9 mov rbx,rcx
--------------------------------------------------
以下为win7 64环境的情况?记不清了
首先查看LdrInitializeThunk的指令,查看之前的文章(),看到如下的信息:
001> u ntdll!LdrInitializeThunk
ntdll!LdrInitializeThunk:
00000000`7775c320 e90b47a088 jmp 00000000`00160a30
这个是跳转到entry.asm
001>u 00000000`00160a30
00000000`00160a30 4883ec28 sub rsp,28h
00000000`00160a34 48894c2420 mov qword ptr [rsp+20h],rcx
00000000`00160a39 4889542428 mov qword ptr [rsp+28h],rdx
00000000`00160a3e 4c89442430 mov qword ptr [rsp+30h],r8
00000000`00160a43 4c894c2438 mov qword ptr [rsp+38h],r9
00000000`00160a48 e800000000 call 00000000`00160a4d
00000000`00160a4d 59 pop rcx
00000000`00160a4e 488bd9 mov rbx,rcx
00000000`00160a51 4881c172020000 add rcx,272h
00000000`00160a58 488bd3 mov rdx,rbx
00000000`00160a5b 4881c2f3000000 add rdx,0F3h
00000000`00160a62 4c8bc3 mov r8,rbx
00000000`00160a65 4981c048000000 add r8,48h
00000000`00160a6c 4c8bcb mov r9,rbx
00000000`00160a6f 4981c185010000 add r9,185h
00000000`00160a76 e865f9ffff call 00000000`001603e0 ;预期:lowlevel!EntrypointC
按照该位置加载LowLevel地址,dll长度0x2000,如下加载符号表
.reload lowlevel=000160a30,2000
加载完毕,查找lowlevel所有的符号:
x lowlevel!*,得到如下的符号表,注意下面的符号是按照地址做过排序的,实际情况不会是这样的。
| 00000000`00161a30 | lowlevel!SbieApi_Ioctl |
| 00000000`00161a80 | lowlevel!SbieApi_QueryProcessInfo |
| 00000000`00161a99 | lowlevel!SbieApi_Ioctl |
| 00000000`00161b20 | lowlevel!WaitForDebugger |
| 00000000`00161b70 | lowlevel!findChromeTarget |
| 00000000`00161bc0 | lowlevel!InitSyscalls |
| 00000000`00161c78 | lowlevel!findChromeTarget |
| 00000000`00161cc2 | lowlevel!findChromeTarget |
| 00000000`00161dd0 | lowlevel!InitConsole |
| 00000000`00161e10 | lowlevel!EntrypointC |
| 00000000`00161e4f | lowlevel!WaitForDebugger |
| 00000000`00161eaa | lowlevel!InitConsole |
| 00000000`00161f40 | lowlevel!FindDllExport |
| 00000000`00161fb0 | lowlevel!FindDllExport2 |
| 00000000`001620d0 | lowlevel!InitInject |
| 00000000`00162110 | lowlevel!FindDllExport |
| 00000000`0016219a | lowlevel!FindDllExport |
| 00000000`00162390 | lowlevel!InitInjectWow64 |
| 00000000`001624c5 | lowlevel!myService |
| 00000000`001626ef | lowlevel!SbieLowData |
| 00000000`00164a30 | lowlevel!`__local_stdio_printf_options'::`2'::_OptionsStorage |
| 00000000`00164a38 | lowlevel!`__local_stdio_scanf_options'::`2'::_OptionsStorage |
可以看到符号表对应的EntryPointC的地址00000000`00161e10
而实际地址是00000000`001603e0
也就是按照000160a30加载后,EntryPointC的地址偏移了。
EntryPointC = 00000000`00161e10 = 000160a30+x
得到x = 13E0
为了让EntryPointC = 00000000`001603e0,需要再如下的地址加载lowlevel
00000000`001603e0-x=00000000`001603e0-13E0=15F000
取消之前的符号表:
001>.reload /u lowlevel
001>.reload lowlevel=0015F000,2000
调整后的代码
ntdll!LdrInitializeThunk:
00000000`7775c320 e90b47a088 jmp lowlevel!InitInjectWow64+0xd0 (00000000`00160a30)
00000000`7775c325 20488b and byte ptr [rax-75h],cl
00000000`7775c328 d9e8 fld1
00000000`7775c32a 2200 and al,byte ptr [rax]
00000000`7775c32c 0000 add byte ptr [rax],al
00000000`7775c32e b201 mov dl,1
00000000`7775c330 488bcb mov rcx,rbx
00000000`7775c333 e808540200 call ntdll!NtContinue (00000000`77781740)
0:001> u 00160a30
lowlevel!InitInjectWow64+0xd0 [E:\works\Sandboxie_Open_Source_Code_5.40_2\core\low\entry.asm @ 65]:
00000000`00160a30 4883ec28 sub rsp,28h
00000000`00160a34 48894c2420 mov qword ptr [rsp+20h],rcx
00000000`00160a39 4889542428 mov qword ptr [rsp+28h],rdx
00000000`00160a3e 4c89442430 mov qword ptr [rsp+30h],r8
00000000`00160a43 4c894c2438 mov qword ptr [rsp+38h],r9
00000000`00160a48 e800000000 call lowlevel!InitInjectWow64+0xed (00000000`00160a4d)
00000000`00160a4d 59 pop rcx
00000000`00160a4e 488bd9 mov rbx,rcx
0:001> u
lowlevel!InitInjectWow64+0xf1 [E:\works\Sandboxie_Open_Source_Code_5.40_2\core\low\entry.asm @ 79]:
00000000`00160a51 4881c172020000 add rcx,272h
00000000`00160a58 488bd3 mov rdx,rbx
00000000`00160a5b 4881c2f3000000 add rdx,0F3h
00000000`00160a62 4c8bc3 mov r8,rbx
00000000`00160a65 4981c048000000 add r8,48h
00000000`00160a6c 4c8bcb mov r9,rbx
00000000`00160a6f 4981c185010000 add r9,185h
00000000`00160a76 e865f9ffff call lowlevel!EntrypointC (00000000`001603e0)
0:001> u
lowlevel!InitInjectWow64+0x11b [E:\works\Sandboxie_Open_Source_Code_5.40_2\core\low\entry.asm @ 89]:
00000000`00160a7b 488b4c2420 mov rcx,qword ptr [rsp+20h]
00000000`00160a80 488b542428 mov rdx,qword ptr [rsp+28h]
00000000`00160a85 4c8b442430 mov r8,qword ptr [rsp+30h]
00000000`00160a8a 4c8b4c2438 mov r9,qword ptr [rsp+38h]
00000000`00160a8f 4883c428 add rsp,28h
00000000`00160a93 ffe0 jmp rax
实际上只要lowlevel没修改,知道EntryPointC的jmp地址Addr就够了
Addr - 13E0 得到 lowlevel的加载地址

本文介绍了如何在Sandboxie环境中利用windbg调试目标进程,特别是通过设置调试器和加载pdb文件来调试lowlevel代码。详细步骤包括观察注入过程、分析LdrInitializeThunk的调用,并动态调整符号表加载位置,以正确定位EntrypointC。
1008

被折叠的 条评论
为什么被折叠?



