我正在尝试使用Windows注册表功能在汇编语言的“Software \ Microsoft \ Windows \ CurrentVersion \ Run”键中创建注册表项。我的程序崩溃并显示Windows错误消息。这是代码:
includelib \Masm64\Lib\Kernel32.lib
includelib \Masm64\Lib\Advapi32.lib
extrn ExitProcess : proc
extrn RegCreateKeyExA : proc
dseg segment para 'DATA'
rhdl dd 0
sbky db 'Software\Microsoft\Windows\CurrentVersion\Run\startupprogram.exe', 0
dseg ends
cseg segment para 'CODE'
start proc ;Use link.exe to define entry point
sub rsp, 28h
push 0
push qword ptr [rhdl]
push 0
push 0
push 0
xor r9d, r9d
xor r8d, r8d
lea rdx, [sbky]
mov rcx, 8000001h
call RegCreateKeyExA
xor ecx, ecx ; exit code = 0
call ExitProcess
start endp
cseg ends
end
感谢您的帮助。也许我已经忽视了Windows调用约定?
答案 0 :(得分:2)
在Win64 x64调用约定中,您必须为寄存器中传递的四个参数保留堆栈槽:
来自http://msdn.microsoft.com/en-us/library/ms235286.aspx:
调用者负责为被调用者分配参数空间,并且必须始终为4个寄存器参数分配足够的空间,即使被调用者没有那么多参数也是如此。
所以RegCreateKeyExA()
函数将你推入堆栈的最后四件事视为为四个寄存器参数保留的位置,然后尝试从第一个push 0
获取其他参数然后随机垃圾位于您使用sub rsp,28h
保留的堆栈区域中。
尝试:
push 0
push qword ptr [rhdl]
push 0
push 0
push 0
sub rsp, 20h ; reserve slots for arguments passed in regs
xor r9d, r9d
xor r8d, r8d
lea rdx, [sbky]
mov rcx, 8000001h
call RegCreateKeyExA
答案 1 :(得分:-1)
这不是我曾经做过的事情,但我有一个非MASM的例子
SYS“SetWindowPos”,@ hwnd%,0,xpos%,ypos%,0,0,5
变为
push 5
push 0
push 0
push ypos%
push xpos%
push 0
push @hwnd%
call "SetWindowPos"
编译器有一个汇编顺序,它在程序中搜索内部调用然后查找外部调用(即窗口调用)
这一切都归结为编译器如何操作这些东西
可能更容易尝试使用
开始的简单调用 push 16d
call "MessageBeep"
和
push 8d
call "MessageBeep"
例如
发出两声哔声
push 8
call "MessageBeep"
mov eax,1
.ag
inc eax
cmp eax,&FFFFFFF
jb ag
push 16
call "MessageBeep"
等