有时候调试某程序时,动态加载dll,执行完就释放了,无法拦截,本文尝试修改某dll入口代码实现延时挂载,原理时通过调用Sleep,阻塞dll线程,为挂载争取时间,挂载完成后就可以下断点调试,为所欲为了。入口点位置:[Asm] 纯文本查看 复制代码 65E8230F > $ 8BFF mov edi,edi ; WECDecry.<ModuleEntryPoint>
65E82311 ? 55 push ebp
65E82312 ? 8BEC mov ebp,esp
65E82314 > 837D 0C 01 cmp dword ptr ss:[ebp+0xC],0x1
65E82318 . 75 05 jnz XWECDecry.65E8231F
65E8231A . E8 3B040000 call WECDecry.65E8275A
此时寄存器状态,可以开到eax还是0。 [Asm] 纯文本查看 复制代码 EAX 00000000
ECX 65E8230F WECDecry.<ModuleEntryPoint>
EDX 65E80000 WECDecry.65E80000
EBX 00000000
ESP 0019FBD0 截图和以上代码有细微差别,在于dll每次加载都会有地址重定位。
file:///C:/Users/fei/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png 搜索一块全00区域准备写代码。修改入口跳转到空白区域。 [Asm] 纯文本查看 复制代码 65E8230F > $ /E9 1C050000 jmp WECDecry.65E82830
65E82314 > |837D 0C 01 cmp dword ptr ss:[ebp+0xC],0x1
65E82318 . |75 05 jnz XWECDecry.65E8231F
65E8231A . |E8 3B040000 call WECDecry.65E8275A
65E8231F > |FF75 08 push dword ptr ss:[ebp+0x8] file:///C:/Users/fei/AppData/Local/Temp/msohtmlclip1/01/clip_image004.png 现在分析下Sleep函数的特征:因为程序里可以找到现成的,所以直接拿来。
[Asm] 纯文本查看 复制代码
65E82105 |. 68 E8030000 |push 0x3E8 ; /Timeout = 1000. ms
65E8210A |. FF15 2C30E865 |call dword ptr ds:[<&KERNEL32.Sleep>] ; \Sleep 分析可以看出,push 时间参数,call调用即可,堆栈在call里面平衡了。而最复杂的就是Sleep地址重定位的问题,dll的地址每次加载的都可能不一样。 file:///C:/Users/fei/AppData/Local/Temp/msohtmlclip1/01/clip_image006.png 回车进去看: file:///C:/Users/fei/AppData/Local/Temp/msohtmlclip1/01/clip_image008.png
[Asm] 纯文本查看 复制代码 76550EFE CC int3
76550EFF CC int3
76550F00 >- FF25 6C0C5B76 jmp dword ptr ds:[<&KERNELBASE.Sleep>] ; KERNELBA.Sleep
76550F06 CC int3
76550F07 CC int3
76550F08 CC int3 继续回车跟进:[Asm] 纯文本查看 复制代码 773949BD CC int3
773949BE CC int3
773949BF CC int3
773949C0 > 8BFF mov edi,edi ;这里是真正的 KERNELBA.Sleep 地址。
773949C2 55 push ebp
773949C3 8BEC mov ebp,esp
773949C5 6A 00 push 0x0
773949C7 FF75 08 push dword ptr ss:[ebp+0x8]
773949CA E8 11000000 call KERNELBA.SleepEx
773949CF 5D pop ebp
773949D0 C2 0400 retn 0x4
773949D3 CC int3 观察ecx值,和调用Sleep的地方。65E8230F-65E8210A=0x205 ,我们把ecx 减去 0x203即是 2C30E865 call的地址。最终修改结果如下:
file:///C:/Users/fei/AppData/Local/Temp/msohtmlclip1/01/clip_image010.png [Asm] 纯文本查看 复制代码 65E8282F 00 db 00
65E82830 > 68 30750000 push 0x7530 ; 延时时间30秒
65E82835 8BC1 mov eax,ecx ; 处理地址
65E82837 2D 03020000 sub eax,0x203 ; 相减
65E8283C 8B00 mov eax,dword ptr ds:[eax] ; 取call的地址
65E8283E 8B00 mov eax,dword ptr ds:[eax] ; 取实际的地址
65E82840 FFD0 call eax ; 执行Sleep成功后eax为0,就不清零了。
65E82842 8BFF mov edi,edi ; 恢复jmp替换的3句代码
65E82844 55 push ebp
65E82845 8BEC mov ebp,esp
65E82847 ^ E9 C8FAFFFF jmp WECDecry.65E82314 ; 跳回去继续执行
65E8284C 90 nop |