修改某dll入口代码实现延时挂载。
有时候调试某程序时,动态加载dll,执行完就释放了,无法拦截,本文尝试修改某dll入口代码实现延时挂载,原理时通过调用Sleep,阻塞dll线程,为挂载争取时间,挂载完成后就可以下断点调试,为所欲为了。入口点位置:65E8230F > $8BFF mov edi,edi ;WECDecry.<ModuleEntryPoint>65E82311 ?55 push ebp
65E82312 ?8BEC mov ebp,esp
65E82314 >837D 0C 01 cmp dword ptr ss:,0x1
65E82318 .75 05 jnz XWECDecry.65E8231F
65E8231A .E8 3B040000 call WECDecry.65E8275A
此时寄存器状态,可以开到eax还是0。 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区域准备写代码。修改入口跳转到空白区域。 65E8230F > $ /E9 1C050000 jmp WECDecry.65E82830
65E82314 > |837D 0C 01 cmp dword ptr ss:,0x1
65E82318 . |75 05 jnz XWECDecry.65E8231F
65E8231A . |E8 3B040000 call WECDecry.65E8275A
65E8231F > |FF75 08 push dword ptr ss: file:///C:/Users/fei/AppData/Local/Temp/msohtmlclip1/01/clip_image004.png 现在分析下Sleep函数的特征:因为程序里可以找到现成的,所以直接拿来。
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.png76550EFE 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 继续回车跟进: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:
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 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: ;取call的地址
65E8283E 8B00 mov eax,dword ptr ds: ;取实际的地址
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 思路不错 感谢分享 如果没有dll线程,直接主线程加载dll,Sleep不是卡死了 一直觉得动态加载dll很神秘~ 谢谢分享 谢谢楼主分享 。。。 调试器功能,直接选项设置中勾选 DLL入口 或者 DLL载入。如果就是想搞个时机,调messagebox比sleep好多了,想继续执行直接点击。 hl_ke 发表于 2021-9-15 11:34
调试器功能,直接选项设置中勾选 DLL入口 或者 DLL载入。如果就是想搞个时机,调messagebox比sleep好多了 ...
感谢关注。自己做了个messagebox的正在测试{:1_918:} 感谢分享 学会了
页:
[1]