能力值:
( LV12,RANK:300 )
2 楼
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include advapi32.inc
includelib advapi32.lib
.data
szRealsize dd 50
szType dd ?
hInstance dd ?
szSubKey db "Software\test",0
szKeyName db "test",0
szValue db "test a test",0
hKey dd ?
lpdwDis dd ?
szBuffer db 50 dup (?)
.code
_proc proc
LOCAL @test
LOCAL @szBuffer[50]:byte
LOCAL @szType,@szRealsize ; 你说不行我偏这么放,没事!
mov @szRealsize, 50 ; 这句是关键
invoke RegQueryValueEx,hKey,offset szKeyName,0,addr @szType,addr @szBuffer,addr @szRealsize
invoke MessageBox,NULL,addr @szBuffer,addr @szBuffer,MB_OK
ret
_proc endp
start:
invoke RegCreateKeyEx,80000001h,offset szSubKey,0,0,0,KEY_ALL_ACCESS,0,offset hKey,offset lpdwDis
invoke RegSetValueEx,hKey,offset szKeyName,0,REG_SZ,offset szValue,sizeof szValue
invoke RegQueryValueEx,hKey,offset szKeyName,0,offset szType,offset szBuffer,offset szRealsize ; 不行吗?当然行!
invoke MessageBox,NULL,offset szBuffer,offset szBuffer,MB_OK
call _proc
invoke RegCloseKey,hKey
invoke RegDeleteKey,80000001h,offset szSubKey
invoke ExitProcess,NULL
end start
看红字部分。
MSDN中RegQueryValueEx原型:
LONG RegQueryValueEx(
HKEY hKey,
LPCTSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
);
最后一个参数lpcbData说明:
lpcbData
[in, out] Pointer to a variable that specifies the size of the buffer pointed to by the lpData parameter, in bytes. When the function returns, this variable contains the size of the data copied to lpData.
也就是说这个参数不只是在接收写入的长度的,在调用前它还必须指定传入的缓冲区大小。
我标的红字部分,就是楼主原本漏掉的这一点。
start函数中的调用失败,是因为楼主该参数初始化为0了,因此认为缓冲区长度为0,当然就失败。
_proc函数中的调用,出现所谓“局部变量不能随便排列”的问题,也只是因为楼主没有对参数进行初始化,这样调用是否成功依赖于栈上原来这个位置的参数值(一个不能预料的值),所以是撞运气,一变换位置就不行了。
局部变量不能变换位置和不能使用全局变量这两个“原因”,纯属楼主瞎猜。
能力值:
( LV4,RANK:50 )
3 楼
哎呀,茅塞顿开!多谢!