gpt4 book ai didi

c# - .NET 函数反汇编

转载 作者:IT王子 更新时间:2023-10-29 04:09:47 24 4
gpt4 key购买 nike

反汇编 .NET 函数时,我注意到它们都以相似的模式开头。这段初始代码的作用是什么?

这段代码出现在函数应该做什么的实际代码之前。是某种参数计数验证吗?

函数1

private static void Foo(int i)
{
Console.WriteLine("hello");
}

00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 mov dword ptr [ebp-4],ecx
00000007 cmp dword ptr ds:[005C14A4h],0
0000000e je 00000015
00000010 call 65E0367F
//the console writleline code follows here and is not part of the question

函数2

static private void Bar()
{
for (int i = 0; i < 1000; i++)
{
Foo(i);
}
}

00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 cmp dword ptr ds:[006914A4h],0
0000000b je 00000012
0000000d call 65CC36CF
// the for loop code follows here

函数3

private static void Foo()
{
Console.WriteLine("hello");
}

00000000 push ebp
00000001 mov ebp,esp
00000003 cmp dword ptr ds:[005614A4h],0
0000000a je 00000011
0000000c call 65E3367F

[编辑]那么这是对它的正确描述吗?

//fix stackframe
00000000 push ebp
00000001 mov ebp,esp
//store eax so it can be used locally
00000003 push eax
//ensure static ctor have been called
00000004 cmp dword ptr ds:[006914A4h],0
//it has been called, ignore it
0000000b je 00000012
//it hasn't been called, call it now
0000000d call 65CC36CF

还是?

最佳答案

这个序言有两个部分。

设置堆栈框架

这会将当前 EBP 寄存器存储在堆栈中,然后将堆栈指针(ESP)的值赋给 EBP。

push        ebp 
mov ebp,esp

如果有局部变量存储在堆栈中(即寄存器中没有足够的可用空间),则 ESP 将移动它们的大小以构建当前函数的堆栈帧。

在函数的末尾,您会看到这些操作被颠倒了,因此前一个函数的堆栈框架得到了恢复。

EBP应该总是指向当前函数栈帧的开始
ESP 到最后(它在 x86 上的地址较低,因为堆栈向下增长)。

这是通用调用约定的一部分,并且在抛出异常时需要堆栈展开。这不是 .net 特定的,并且被 windows/x86 上的大多数调用约定所使用。

设置栈帧后,通常会在栈上存储一些寄存器。那是因为您可能希望将某些寄存器用作临时变量,但调用约定要求您的函数保存它们。所以你需要在堆栈上备份它们。哪些寄存器必须保留,哪些可以修改取决于您使用的调用约定。

当引用堆栈上的局部变量时,您可以使用 [ebp-x],其中 ebp 指向堆栈帧的开头,x 是一个偏移量,表示变量存储在栈帧中的位置。或者,您可以使用 [esp+y] 从堆栈帧的末尾开始偏移。

调用静态构造函数/初始化器

作为danbystrom注意到第二部分很可能是对静态构造函数/初始化程序的调用。由于静态构造函数不是在程序启动时调用的,而是在第一次访问时调用的,因此抖动不能保证静态构造函数已经执行过的每次访问都需要检查是否调用过,如果没有调用则调用。

00000004  cmp         dword ptr ds:[006914A4h],0 
0000000b je 00000012
0000000d call 65CC36CF

这类似于 if (globalVar!=0) Call Function_65CC36CF。全局 var 最有可能指示静态构造函数是否已运行,并且调用是对静态构造函数的调用。


据我所知,您对反汇编的评论是正确的。


检查堆栈框架上的 OldNewThing 博客条目:How to rescue a broken stack trace: Recovering the EBP chain

关于c# - .NET 函数反汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4957802/

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