【问题标题】:How to call memmove in assembly?如何在汇编中调用 memmove?
【发布时间】:2019-11-18 13:31:29
【问题描述】:

我尝试使用

mov rdx, 4
push rdx
mov rsi, temp_str
push rsi
mov rdi, temp_str1
push rdi
call memmove

sub rsp, 24
mov [rsp + 16], rdx
mov [rsp + 8], rsi
mov [rsp], rdi
call memmove
add rsp, 24

和其他种类的魔法,但没有任何作用。哪个法术能胜任?

(temp_str 和 temp_str1 定义为

temp_str db "abc", 0
temp_str1 db "def", 0

,memmove 来自 msvcrt)

编辑:

sub rsp, 32
mov rcx, temp_str1
mov rdx, temp_str
mov r8, 4
call memmove

也会崩溃。

编辑 2:完整代码:

format PE64 console
entry prog

include "win64ax.inc"

section '.idata' import data readable writeable

library kernel32, 'kernel32.dll', msvcrt, 'msvcrt.dll'

import kernel32, ExitProcess,'ExitProcess'
import msvcrt, memmove, 'memmove'

section '.text' code readable executable

prog:

;;mov rdx, 4
;;push rdx
;;mov rsi, temp_str
;;push rsi
;;mov rdi, temp_str1
;;push rdi
;;call memmove


;;sub   rsp, 24
;;mov   [rsp + 16], rdx
;;mov   [rsp + 8], rsi
;;mov   [rsp], rdi
;;call memmove
;;add rsp, 24


;;push rbp
;;mov rbp, rsp
;;push rdx
;;push rsi
;;push rdi
;;call memmove
;;mov rsp, rbp
;;pop rbp


sub rsp, 32
mov rcx, temp_str1
mov rdx, temp_str
mov r8, 3
call memmove         ; crash
add rsp, 32

end_prog:
    invoke ExitProcess, 0

section '.data' data readable writeable
    temp_str db "abc", 0
    temp_str1 db "def", 0

【问题讨论】:

  • 您似乎将 sysv abi 与 microsoft 混淆了。请参阅documentation。 TL;DR:分配 32 字节的影子空间并在 rcxrdxr8 中传递参数。此外,如果您使用的是汇编,那么调用 memmove 真的毫无意义,尤其是如果您知道您的范围不重叠。
  • 也不起作用(见编辑)。为什么 memmove 毫无意义?
  • @Jester 实际上并不是那么毫无意义。简单的rep movs 可能不是最佳解决方案,即使范围不重叠。参见例如how memmove's backward part is implemented in glibc.
  • 我建议也检查一下 FASM 论坛board.flatassembler.net,因为它可能有一个宏
  • 宏 cinvoke 有 bug,所以我正在寻找直接方法。

标签: assembly x86-64 fasm


【解决方案1】:

无论出于何种原因,我的 fasm 无法组装它,但等效的 nasm 代码可以正常工作:

extern memmove
extern puts
extern exit

section .text
global WinMain
WinMain:
push rbp
mov rbp, rsp
sub rsp, 32
mov rcx, temp_str1
mov rdx, temp_str
mov r8, 4
call memmove
mov rcx, temp_str1
call puts
mov rsp, rbp
pop rbp
jmp exit

section .data
temp_str db "abc", 0
temp_str1 db "def", 0

【讨论】:

    【解决方案2】:

    board.flatassembler.net 上的用户革命建议解决方案:

    call memmove
    

    必须是

    call [memmove]    
    

    【讨论】:

    • 对 DLL 函数的调用通常是通过函数指针的间接调用来完成的。动态链接设置函数指针,而不是在调用代码中的各处修复call rel32 偏移量。显然在 Windows / FASM 中,函数符号名称最终解析为指针。但是这个答案没有涵盖问题中的其他错误:错误的调用约定。
    猜你喜欢
    • 2019-05-04
    • 2021-07-16
    • 2016-07-25
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多