gpt4 book ai didi

windows - 一个简单的 MASM32 程序的奇怪行为

转载 作者:可可西里 更新时间:2023-11-01 11:54:43 25 4
gpt4 key购买 nike

我想编写类似于以下 C++ 程序的 MASM 程序:

#include <Windows.h>
#include <iostream>

typedef UINT (_stdcall *FuncPtr)(LPCSTR lpCmdLine, UINT uCmdShow);

int main(void)
{
HMODULE hDll = LoadLibrary(TEXT("Kernel32.dll"));
FuncPtr func_addr = reinterpret_cast<FuncPtr>(GetProcAddress(hDll, "WinExec"));

(*func_addr)("C:\\WINDOWS\\system32\\calc.exe", SW_SHOWDEFAULT);
FreeLibrary(hDll);

return (0);
}

如您所见,这段代码执行了微软计算器。我只想使用 MASM 做同样的事情,但执行失败。

这是 MASM 源代码:

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\msvcrt.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\msvcrt.lib

.data

LpFileName db "kernel32.dll", 0
procName db "WinExec", 0
display db "addr_func = 0x%x", 0

.data?

hModule HMODULE ?
procAddr FARPROC ?

.code

start:

invoke LoadLibrary, offset LpFileName
mov hModule, eax
invoke GetProcAddress, hModule, ADDR procName
mov procAddr, eax

INVOKE crt_printf, ADDR display, procAddr

mov esi, procAddr
call esi

db "C:\WINDOWS\system32\calc.exe"

invoke FreeLibrary, hModule
invoke ExitProcess, NULL

end start

crt_printf 输出是正确的。与 C++ 程序一样打印相同的地址。所以传递给 call 的地址是同一个。但是执行失败。

这是一个有效的 MASM32 代码,但这次函数 WinExec 的地址是硬编码的,如下所示:

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc

.code

start:
jmp _Debut

_Final:
TCHAR 233
dword 42424242h

_Suite:
mov esi, 779e304eh
call esi
jmp _Final

_Debut:
xor eax, eax
push eax
call _Suite
db "C:\WINDOWS\system32\calc.exe"

end start

请参阅行 mov esi, 779e304eh。但是动态地,有一个问题。如果我反汇编上面的代码,我们可以看到字节顺序颠倒了。

8EEH047E379

也许动态情况并非如此,也许我需要在下一行中添加一个关键字(在逗号和 procAddr 之间):

mov esi, procAddr

我找不到解决方案。我迷路了。谁能帮帮我?

非常感谢您的帮助。

最佳答案

执行失败,因为您没有传递它的参数。

在这里,您只需在不带任何参数或使用无效参数的情况下调用该函数(因为当前在堆栈上的任何内容都将被获取,并且堆栈在此过程中被破坏)。

mov esi, procAddr
call esi

你应该这样做

push SW_SHOWDEFAULT
push offset YourPathToCalc
mov esi, procAddr
call esi

在您的示例代码中,这是隐式完成的

xor eax, eax
push eax ; uCmdShow
call _Suite ; Returnadress is the address of the commandline so this is bascially the "push path"

您缺少的另一件事是,当WinExec返回,它将开始执行您的情况下的路径,因此您需要 jmp somewhere通话后。

正如 Gunner 指出的那样,路径必须以 0 终止。

关于windows - 一个简单的 MASM32 程序的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20271552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com