函数的参数将在堆栈上还是在寄存器中传递?

发布于 2024-07-24 05:12:00 字数 381 浏览 14 评论 0原文

我目前正在分析我在汇编中编写的程序,并正在考虑在汇编中移动一些代码。 我有一个需要一个参数的过程,但我不确定它是在堆栈上还是在寄存器上传递。

当我在 IDA Pro 中打开程序时,过程中的第一行是:

ThreadID= dword ptr -4

如果我将光标悬停在声明上,还会出现以下内容:

ThreadID dd ?
 r db 4 dup(?)

我假设它会指向堆栈变量?

然而,当我在 OllyDbg 中打开相同的程序时,堆栈上的这个位置有一个很大的值,该值与可能传递的任何参数不一致,使我相信它是在寄存器中传递的。

有人能指出我正确的方向吗?

I'm currently analyzing a program I wrote in assembly and was thinking about moving some code around in the assembly. I have a procedure which takes one argument, but I'm not sure if it is passed on the stack or a register.

When I open my program in IDA Pro, the first line in the procedure is:

ThreadID= dword ptr -4

If I hover my cursor over the declaration, the following also appears:

ThreadID dd ?
 r db 4 dup(?)

which I would assume would point to a stack variable?

When I open the same program in OllyDbg however, at this spot on the stack there is a large value, which would be inconsistent with any parameter that could have been passed, leading me to believe that it is passed in a register.

Can anyone point me in the right direction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

第七度阳光i 2024-07-31 05:12:01

参数传递给函数的方式取决于函数的调用约定。 默认调用约定取决于语言、编译器和体系结构。

我无法根据您提供的信息确定任何内容,但是您不应该忘记像 OllyDbg 这样的汇编级调试器和像 IDA 这样的反汇编器经常使用启发式方法对程序进行逆向工程。 研究编译器生成的代码的最好方法是指示它编写汇编列表。 大多数编译器都可以选择执行此操作。

The way arguments are passed to a function depends on the function's calling convention. The default calling convention depends on the language, compiler and architecture.

I can't say anything for sure with the information you provided, however you shouldn't forget that assembly-level debuggers like OllyDbg and disassemblers like IDA often use heuristics to reverse-engineer the program. The best way to study the code generated by the compiler is to instruct it to write assembly listings. Most compilers have an option to do this.

GRAY°灰色天空 2024-07-31 05:12:01

它肯定是一个局部变量。 要检查参数,请查找 [esp+XXX] 值。 IDA 自动命名这些 [esp+arg_XXX]。

.text:0100346A sub_100346A     proc near               ; CODE XREF: sub_100347C+44p
.text:0100346A                                         ; sub_100367A+C6p ...
.text:0100346A
.text:0100346A arg_0           = dword ptr  4
.text:0100346A
.text:0100346A                 mov     eax, [esp+arg_0]
.text:0100346E                 add     dword_1005194, eax
.text:01003474                 call    sub_1002801
.text:01003474
.text:01003479                 retn    4
.text:01003479
.text:01003479 sub_100346A     endp

正如上面评论中概述的快速调用约定使用寄存器来传递参数。 我押注于 Microsoft 或 GCC 编译器,因为它们使用更广泛。 因此首先检查 ECX 和 EDX 寄存器。

Microsoft 或 GCC [2] __fastcall[3]
约定(又名 __msfastcall)通过
前两个参数(评估
从左到右)适合 ECX 和
EDX。 剩余的参数被推送
从右到左入栈。
http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall

It is a local variable for sure. To check out arguments look for [esp+XXX] values. IDA names those [esp+arg_XXX] automatically.

.text:0100346A sub_100346A     proc near               ; CODE XREF: sub_100347C+44p
.text:0100346A                                         ; sub_100367A+C6p ...
.text:0100346A
.text:0100346A arg_0           = dword ptr  4
.text:0100346A
.text:0100346A                 mov     eax, [esp+arg_0]
.text:0100346E                 add     dword_1005194, eax
.text:01003474                 call    sub_1002801
.text:01003474
.text:01003479                 retn    4
.text:01003479
.text:01003479 sub_100346A     endp

And fastcall convention as was outlined in comment above uses registers to pass arguments. I'd bet on Microsoft or GCC compiler as they are more widely used. So check out ECX and EDX registers first.

Microsoft or GCC [2] __fastcall[3]
convention (aka __msfastcall) passes
the first two arguments (evaluated
left to right) that fit into ECX and
EDX. Remaining arguments are pushed
onto the stack from right to left.
http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文