将 64 位 asm 转换为 32 位?

Converting 64bit asm to 32bit?

提问人:iegrm 提问时间:10/13/2023 最后编辑:iegrm 更新时间:10/13/2023 访问量:67

问:

我正在做一个项目,该项目涉及将 dll 加载到具有 64 位和 32 位版本的应用程序中。我无权访问此应用程序的源代码,我正在将指令注入代码洞穴以使用导入的 LoadLibrary,并且加载的 dll 将钩接函数调用。

对于 64 位版本,我执行以下操作:

JMP codecave (this is at entry, replaces func that I call in codecave lbl to return)

在 codecave 中:

unicode  u"example.dll"

PUSH     EAX
MOV      RCX, [dllstr] (address of unicode string for name of dll)
CALL     qword ptr [loadlibraryw] (address of LoadLibraryW)
POP      EAX
JMP      entryfunc (return to original code)

这很好用!


在应用程序的 32 位版本中,改用 LoadLibraryA,因此我的字符串不再是 unicode:

ds       "example.dll"

JMP 到 codecave 使用相同的入口点,但替换了 func,并且 codecave 位置类似,位于可执行 .text 部分的末尾。

我不确定的是要在 32 位中使用哪些寄存器。从函数签名来看,LoadLibraryA 似乎仍在使用 EAX 进行存储,因此我认为我仍然需要推送/弹出 EAX。

我不确定将字符串移动到哪里,从我看到的示例来看,我似乎应该在没有寄存器的情况下使用PUSH,例如:

PUSH     EAX
PUSH     dllstr
CALL     dword ptr [loadlibrarya]
POP      EAX
JMP      entryfunc

但这会导致应用程序崩溃。我怀疑是因为我正在更改这里的堆栈,但我需要对此进行澄清,任何帮助将不胜感激。

程序集 x86-64 64 32 位

评论

0赞 JasonTrue 10/13/2023
LoadLibraryW 不是您的选择吗?我不确定它是否会在 Windows 2000 之前的唯一 Win32 环境(即便如此,我认为它在 Win95/98/ME 上,但行为略有不同,可能在内部转换为 ANSI 代码页)learn.microsoft.com/en-us/archive/msdn-magazine/2002/march/......
0赞 iegrm 10/13/2023
对不起,如果不是很明显:我无权访问应用程序的代码,我正在注入 asm 以利用应用程序中导入的 LoadLibrary 加载 dll。LoadLibraryW 位于 64 位版本的导入中,32 位版本较旧,改为导入 LoadLibraryA。我使用它并不真正相关,因为唯一的区别是接受作为参数的字符串类型,这很容易更改。
0赞 Peter Cordes 10/13/2023
PUSH EAX不是有效的 64 位指令。(/只有 16 位或 64 位操作数大小)。 不是有效的 32 位指令;普通通话只有 32 位。(你不想要一个远距离调用,那将是一个 48 位操作数,也不是 qword)。所以 IDK 你实际注入了什么指令,但不是这些。pushpopCALL qword ptr [loadlibrarya]dword ptr
0赞 Peter Cordes 10/13/2023
32 位和 64 位之间的另一个显着区别是,64 位使用相对寻址来寻址模式,例如 ,并具有 RIP 相对 LEA 来获取指向寄存器的指针。但是您没有使用 ,您正在从您未显示的某个静态存储中加载绝对地址,大概是 。(MASM 默认使用 RIP 相对,NASM 和 GAS 不;我不知道你实际使用什么汇编程序来做这些。无论如何,32 位代码中的那些寻址模式在机器代码中需要正确的绝对地址,而不仅仅是相对地址[loadlibraryw]lea rcx, [unicode]dllstr: dq unicode[foo]
0赞 Peter Cordes 10/13/2023
此外,EAX 并不是唯一一个被调用的寄存器。在 32 位代码中,还有 EDX 和 ECX。在 Windows x64 中,还有更多,包括 R8-R11。它们是 64 位的,如 RAX、RDX 和 RCX。此外,Windows x64 具有影子空间,在返回地址上方 32 个字节处,你没有保留该空间,因此会踩到调用方的堆栈空间。如果有的话,我希望 64 位代码是被破坏的代码。call [loadlibraryw]

答: 暂无答案