【问题标题】:Handling a syscall via ASM (x86) (ebp needed)通过 ASM (x86) 处理系统调用(需要 ebp)
【发布时间】:2014-01-14 23:26:10
【问题描述】:

在 x64 上,我通过在堆栈上保留一些空间并将所有参数 (6) 复制到堆栈来处理系统调用(我挂钩系统调用,然后自己调用它们)。我保存了所有参数,以便稍后在代码中使用它们。

这就是我的代码的样子(intel 语法):

push rbp;
mov rbp, rsp;
sub rsp, 64;

mov [rbp - 8], rax;
mov [rbp - 16], rdi;
mov [rbp - 24], rsi;
mov [rbp - 32], rdx;
mov [rbp - 40], rcx;
mov [rbp - 48], r8;
mov [rbp - 56], r9;
...
...
...

请注意,我使用rbp 来访问堆栈。

现在我正在尝试为 x86 执行相同的代码。我认为这几乎是一样的,但后来我意识到(根据https://stackoverflow.com/a/2538212/940158ebp 用于系统调用的第 6 个参数,这意味着我不能使用ebp 来访问堆栈。或者我可以吗?

我怎样才能实现与我在 x64 中所做的相同的事情?

【问题讨论】:

    标签: linux assembly linux-kernel cpu-registers system-calls


    【解决方案1】:

    您可以这样做,只需(相当于您的代码)执行以下操作:

    push ebp
    mov ebp, esp
    sub esp, 64
    
    mov [ebp - 4], eax
    mov [ebp - 8], ebx
    mov [ebp - 12], ecx
    mov [ebp - 16], edx
    mov [ebp - 20], esi
    mov [ebp - 24], edi
    mov eax, [ebp]       ; restore original ebp into eax
    mov [ebp - 28], eax  ; and store into “ebp” location
    

    我想知道的是为什么你在这里引用 Linux/amd64 和 Linux/i386 系统调用 ABI,但似乎在做内核组件……(如果你正在破解自己的操作系统,有更好的调用约定用于系统调用;如果您正在破解 Linux,您将永远不会看到原始调用参数)。但不是手头的问题,所以……好吧。

    【讨论】:

    • 我不太确定您是如何恢复 ebp 的原始值的。你能再解释一下吗?关于你的第二个问题......如果你真的感兴趣,我可以解释,但这是一个很长的故事:)
    • 您不需要(不需要)恢复它,因为您只是将它存储在结构中的堆栈中。之后,您只需始终访问结构中的值并使用其他暂存寄存器。
    • 第二行 (mov ebp, esp) 用 esp 的值覆盖了 ebp 的值。我需要在某个时候恢复原始值,对吧?
    • @alexandernst 不,您事先将其推送,因此您可以从堆栈中获取该值。实际上这是我在取消引用[ebp] 时所做的,也就是之前的ebp 值。
    • 啊,我明白了 :) 最后一个问题。如果我想在完成后实际恢复 ebp(以及所有其他 5 个寄存器)的值,我该怎么做?
    猜你喜欢
    • 1970-01-01
    • 2012-05-09
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多