目标程序:http://bbs.pediy.com/showthread.php?s=&threadid=13753
工具: Driver Studio v3.2/IceExt v0.67,LoadPE,ImportRec
步骤:
: bpmb SetThreadContext x do "d (*(esp+8) + b8)"
: bpmb WaitForDebugEvent x
运行,断在WaitForDebugEvent,F12回程序空间(即注入winlogon的代码)
: bd 2(禁止WaitForDebugEvent)
: bpx xxxx076C do "d eax" ; 对测试dwDebugEventCode处下断,xxxx0000为分
; 配内存的基地址,offset=076C
壳代码引起的EXCEPTION_DEBUG_EVENT有3次:
1. 地址010204E4,代码为int 3
然后SetThreadContext,eip->0102060A
2. 地址01020F88,代码为lock cmpxchg8b eax
SetThreadContext,eip->01026583
3. 地址01027945代码int 3,这里明显在解码
可以看到,3次异常地址都在壳代码的section内。显然,原程序与
壳代码之间没有联系。
对ContinueDebugEvent下断:
: bpmb ContinueDebugEvent x
断下后:
: proc ->查calc的KTEB
: addr KTEB
: u 01027945
在int 3后的NOP下断,禁止除此之外的其他断点,F5
继续调试,断到子进程内。直接用esp定律:
: bpmb 23:6FFC0 w
断下2次后F8单步很快到这里:
01028ED8: jmp eax ; eax=00550EED
stolen code:
00550EED push 00000070
jmp 00550EF4
-> push 01001606
jmp 00550EFE
add dword ptr [ecx],-1b
-> push 00550F09 ; 变形的call的返回
push 01012C18
ret
00550F09 jmp 00550F0E
_JUNKCODE
-> push 010128B1
ret ; 回原程序
得到OEP为010128A5,stolen codes为:
push 70
push dumped.01001608
call dumped.01012C18
Dump: Correct Imagesize,dump full,rebuild PE.
修复IAT,可以直接用ImportRec手工完成,可看出真正的api(不仔细点
容易认错),但数量多了点,还是跟一跟.
iat开始: 01001000, 结束01001238, size=0x238
在2次SetThreadContext后,可以看到iat中还未填入redirected api(实际
iat内是加密api name的rva).
:bpmb LoadLibraryA x
F12返回到01027BDC,单步跟,很快会出现第1个iat项的地址: 01001020
到这里:
01027FFF call [ebp+40BAFB] -> 550000
跳到GetProcAddress+0xF的地址。取到api地址,第1个为WaitForSingleObject
patch下面的标记检测,即可得到干净的IAT。
or ecx,ecx (此时=1)
01028257 jz .... -> Patch为jmp
建议:
1. 花指令过于单一,作用不大(是否源代码每行都用了,实在太多)
2. 对内核debugger防范不够,不用IceExt都可以跑
3. anti-debug不够,缺少自校验,可较轻松地设断,Hying的壳就难缠得多
4. IAT加密太容易被跳过了.
5. 被保护程序与壳代码联系不够,可加入replaced code.
6. stolen code温柔了点
个人意见,纯属信口开河。不喜欢用inject的壳,脱壳不好调试 :-)
(手伸得太长,有被列入病毒的危险吧)
请问simonzh:
我开始是用OD的,使代码注入到自己而不是winlogon,这样可以继续用OD调试.
但用WriteProcessMemory向子进程写入"\??\d:\windows\system32\winlogon.exe"
(用winlogon的路径替代calc)后,下一个调试事件是EXIT_PROCESS_DEBUG_EVENT,
即子进程退出了,能否解释一下?(我没有调试子进程,而且DebugActiveProcessStop
我用不来)。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!