Rog*_*son 31 .net c# il disassembly
在反汇编.NET函数时,我注意到它们都是以类似于similair的模式开始的.这个初始代码有什么作用?
此代码出现在函数应该执行的实际代码之前.它是某种参数计数验证吗?
FUNC1
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
Run Code Online (Sandbox Code Playgroud)
FUNC2
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
Run Code Online (Sandbox Code Playgroud)
FUNC3
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
Run Code Online (Sandbox Code Playgroud)
[编辑]这是对它的正确描述吗?
//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
Run Code Online (Sandbox Code Playgroud)
要么?
Cod*_*aos 19
这个序言有两个部分.
这会将当前EBP寄存器存储在堆栈中,然后将堆栈指针(ESP)的值分配给EBP.
push ebp
mov ebp,esp
Run Code Online (Sandbox Code Playgroud)
如果存在堆栈中存在局部变量(即寄存器中没有足够的空间可用),则ESP将按其大小移动以构建当前函数的堆栈帧.
在函数结束时,您将看到这些操作相反,因此前一个函数的堆栈帧将被恢复.
EBP应始终指向当前函数
ESP 的堆栈帧的开头到末尾(由于堆栈向下增长,因此在x86上具有较低的地址).
这是常见调用约定的一部分,在抛出异常时需要进行堆栈展开.这不是.net特定的,并且在windows/x86上被大多数调用约定使用.
在设置堆栈帧之后,它通常用于在堆栈上存储一些寄存器.那是因为您可能希望将某些寄存器用作临时变量,但调用约定需要您的函数来保存它们.所以你需要将它们备份到堆栈中.必须保留哪些寄存器以及哪些寄存器可以修改取决于您使用的调用约定.
当提及局部变量在堆栈上,你可以使用[ebp-x]其中ebp点到的StackFrame的开始,x是一个偏移量表示通过StackFrame变量的存储位置.或者,您可以使用[esp+y]堆栈帧末尾的偏移量.
正如danbystrom注意到第二部分很可能是对静态构造函数/初始化程序的调用.由于静态构造函数不是在程序启动时调用,而是在第一次访问时调用,因此抖动无法保证静态构造函数已经执行的每次访问都需要检查它是否已被调用,如果没有,则调用它.
00000004 cmp dword ptr ds:[006914A4h],0
0000000b je 00000012
0000000d call 65CC36CF
Run Code Online (Sandbox Code Playgroud)
这就像是if (globalVar!=0) Call Function_65CC36CF.最可能的全局变量指示静态构造函数是否已运行,并且该调用是对静态构造函数的调用.
据我所知,您对拆卸的评论是正确的.
在stackframes上检查这个OldNewThing博客条目:如何挽救损坏的堆栈跟踪:恢复EBP链
| 归档时间: |
|
| 查看次数: |
971 次 |
| 最近记录: |