0

我正在尝试使用 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 调用约定?

4

2 回答 2

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
于 2013-06-24T06:46:13.903 回答
-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" 

编译器有一个汇编顺序,它在程序中搜索内部调用,然后查找外部调用(即 Windows 调用)

这一切都归结为您的编译器如何针对这些事情进行操作

开始尝试更简单的调用可能更容易

    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"

ETC

于 2013-06-24T09:05:34.080 回答