昨天发现OD在释放loaddll.exe的时候并不是规规矩矩的写出,
好像还做了什么解压缩的工作类似的,
总之资源里的RES_LOADDLL和实际loaddll.exe不一样,
里面那边好多好多判断,看不懂了,
今天看能不能直接写出,
同样删除目的OD目录里的loaddll.exe,在File菜单历史里点击历史dll,
设置消息断点WM_COMMAND,
会先判断dll是否存在,然后判断当前目录是否存在loaddll.exe,
如果不存在则从资源里提取RES_LOADDLL,
直接此处设置断点,
0040F48B |. 52 push edx ; /edx=当前OD路径+"loaddll.exe"
0040F48C |. E8 B1FB0900 call 004AF042 ; \GetFileAttributesA
0040F491 |. 83F8 FF cmp eax,-1
0040F494 |. 74 07 je short 0040F49D ; 因为把"loaddll.exe"手动删掉了,此时条件成立
0040F496 |. 33C0 xor eax,eax
0040F498 |. E9 9E000000 jmp 0040F53B ; XmPushD.0040F53B
0040F49D |> 68 91134B00 push 4B1391 ; /KNOWNRESTYPE
0040F4A2 |. 68 81174B00 push 4B1781 ; |RES_LOADDLL
0040F4A7 |. 6A 00 push 0 ; |hModule = NULL
0040F4A9 |. E8 52FB0900 call 004AF000 ; \FindResourceA
0040F4AE |. 85C0 test eax,eax ; eax=hResInfo
0040F4B0 |. 75 08 jnz short 0040F4BA ; XmPushD.0040F4BA
0040F4B2 |. 83C8 FF or eax,FFFFFFFF
0040F4B5 |. E9 81000000 jmp 0040F53B ; XmPushD.0040F53B
0040F4BA |> 50 push eax ; /hResource
0040F4BB |. 6A 00 push 0 ; |hModule = NULL
0040F4BD |. E8 7CFC0900 call 004AF13E ; \LoadResource
0040F4C2 |. 85C0 test eax,eax ; eax=hResData
0040F4C4 |. 75 05 jnz short 0040F4CB ; XmPushD.0040F4CB
0040F4C6 |. 83C8 FF or eax,FFFFFFFF
0040F4C9 |. EB 70 jmp short 0040F53B ; XmPushD.0040F53B
0040F4CB |> 50 push eax ; /hResource
0040F4CC |. E8 73FC0900 call 004AF144 ; \LockResource
前面的准备工作已经做好,
试试在下面进行CreateFile和WriteFile,
直接写入这些代码,
0040F4DA |> \6A 00 push 0 ; /hTemplateFile = NULL
0040F4DC |. 68 80000000 push 80 ; |Attributes = NORMAL
0040F4E1 |. 6A 02 push 2 ; |Mode = CREATE_ALWAYS
0040F4E3 |. 6A 00 push 0 ; |pSecurity = NULL
0040F4E5 |. 6A 00 push 0 ; |ShareMode = 0
0040F4E7 |. 68 00000040 push 40000000 ; |Access = GENERIC_WRITE
0040F4EC |. 68 F8F44000 push 40F4F8 ; |FileName = "XmPushL.exe"
0040F4F1 |. E8 D4FA0900 call 004AEFCA ; \CreateFileA
0040F4F6 |. EB 0E jmp short 0040F506 ; XmPush2.0040F506
0040F4F8 | 58 db 58 ; CHAR 'X'
0040F4F9 | 6D db 6D ; CHAR 'm'
0040F4FA | 50 db 50 ; CHAR 'P'
0040F4FB | 75 db 75 ; CHAR 'u'
0040F4FC | 73 db 73 ; CHAR 's'
0040F4FD | 68 db 68 ; CHAR 'h'
0040F4FE | 4C db 4C ; CHAR 'L'
0040F4FF | 2E db 2E ; CHAR '.'
0040F500 | 65 db 65 ; CHAR 'e'
0040F501 | 78 db 78 ; CHAR 'x'
0040F502 |. 65004B00 dd XmPush2.004B0065 ; 填充出一个字符串"XmPushL.exe"
接下来保存所有修改,OD重新载入,在0040F4F1处摁下F2断点,
可以发现随着CreateFileA的执行会在OD目录生成出"XmPushL.exe",
但只是0个字节,因为资源里的RES_LOADDLL还未写入,
loaddll.exe的大小为34816,
接下来再重新编码直接写出RES_LOADDLL资源
0040F4D1 . 85C0 test eax,eax
0040F4D3 75 48 jnz short 0040F51D ; XmPush3.0040F51D
0040F4D5 . 83C8 FF or eax,FFFFFFFF
0040F4D8 . EB 61 jmp short 0040F53B ; XmPush3.0040F53B
0040F4DA > 6A 00 push 0 ; /hTemplateFile = NULL
0040F4DC . 68 80000000 push 80 ; |Attributes = NORMAL
0040F4E1 . 6A 02 push 2 ; |Mode = CREATE_ALWAYS
0040F4E3 . 6A 00 push 0 ; |pSecurity = NULL
0040F4E5 6A 03 push 3
0040F4E7 68 000000C0 push C0000000
0040F4EC . 68 F8F44000 push 40F4F8 ; |FileName = "XmPushL.exe"
0040F4F1 . E8 D4FA0900 call 004AEFCA ; \CreateFileA
0040F4F6 . EB 0E jmp short 0040F506 ; 跳过下面的字符串,因为下面的不是指令不可执行
0040F4F8 58 db 58 ; CHAR 'X'
0040F4F9 6D db 6D ; CHAR 'm'
0040F4FA 50 db 50 ; CHAR 'P'
0040F4FB 75 db 75 ; CHAR 'u'
0040F4FC 73 db 73 ; CHAR 's'
0040F4FD 68 db 68 ; CHAR 'h'
0040F4FE 4C db 4C ; CHAR 'L'
0040F4FF 2E db 2E ; CHAR '.'
0040F500 65 db 65 ; CHAR 'e'
0040F501 78 db 78 ; CHAR 'x'
0040F502 . 65004B00 dd XmPush3.004B0065 ; 拼凑出"XmPushL.exe"这个字符串
0040F506 6A 00 push 0
0040F508 68 21F54000 push 40F521
0040F50D 68 00880000 push 8800
0040F512 53 push ebx
0040F513 50 push eax
0040F514 8BD8 mov ebx,eax ; 将文件句柄备份到ebx后面释放
0040F516 E8 FBFC0900 call 004AF216 ; <jmp.&KERNEL32.WriteFile>
0040F51B EB 0A jmp short 0040F527 ; XmPush3.0040F527
0040F51D 8BD8 mov ebx,eax ; 将资源里的RES_LOADDLL保存在ebx
0040F51F ^ EB B9 jmp short 0040F4DA ; 转到上面的CreateFileA
0040F521 90 nop
0040F522 90 nop
0040F523 90 nop
0040F524 90 nop
0040F525 90 nop
0040F526 90 nop
0040F527 53 push ebx ; 完成RES_LOADDLL写出
0040F528 E8 8BFA0900 call 004AEFB8 ; <jmp.&KERNEL32.CloseHandle>
0040F52D 90 nop
0040F52E 90 nop
0040F52F 90 nop
0040F530 90 nop
0040F531 90 nop
0040F532 90 nop
0040F533 90 nop
0040F534 90 nop
0040F535 90 nop
0040F536 90 nop
0040F537 90 nop
0040F538 90 nop
0040F539 33C0 xor eax,eax
0040F53B > 81C4 08420000 add esp,4208
0040F541 . 5E pop esi
0040F542 . 5B pop ebx
0040F543 . C3 ret
因为WriteFile的参数需要,所以将40F521-40F526作为一段不放代码的空间,
当WriteFile执行完毕后直接跳过nop至0040F527,
接着保存所有修改点击OD里File菜单的历史dll,
系统提示错误,
可能是因为代码区是不可写所致,因为WriteFile会在0040F51F这个地址写入6个字节的值,
打开"LordPE.exe",PE编辑器,选择目标OD,区段".text"勾选可写入并保存,
然后再次点击OD菜单File的历史dll,OD目录成功写出34816字节的"XmPushL.exe",
现在OD已经可以实现无论当前目录是否存在"loaddll.exe"都能够载入dll文件了,
如果不存在先写出RES_LOADDLL生成"loaddll.exe"再载入,
因为之前将OD拖入了"HEdit.exe"把"loaddll.exe"修改为了"XmPushL.exe",
所以我的这个OD,即"XmPushD.exe"载入dll的时候会将RES_LOADDLL写出为"XmPushL.exe",
至此终于将OD内资源RES_LOADDLL替换完毕,
最后临睡觉之前来张OD全家福,