为什么有些函数位置密集,而另一些函数则用 int 3 指令对齐和填充?

发布于 2024-12-07 13:38:13 字数 804 浏览 2 评论 0原文

我使用 Visual C++ 10 编译以下程序:

include <Windows.h>
int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
    Sleep( 0 );
    return 0;
}

并研究反汇编。程序映像中有很多C++运行时函数。有些函数位置密集 - 某些函数的ret后面跟着下一个函数的第一条指令。例如,

` __declspec(noreturn) void __cdecl __report_gsfailure(ULONGLONG StackCookie)`

以地址 004013B7 结束(有一条 ret 指令),而地址 004013B8 包含一些调试器无法找到的其他函数来源。同时

BOOL __cdecl _ValidateImageBase(PBYTE pImageBase)

在地址 00401554 结束,但下一个函数

PIMAGE_SECTION_HEADER __cdecl _FindPESection( PBYTE pImageBase, DWORD_PTR rva )

从地址 00401560 开始,并且后两个地址之间有多个 int 3 指令。

为什么有区别?为什么有的函数放得很密,有的函数却用不可达的代码隔开?

I compile the following program with Visual C++ 10:

include <Windows.h>
int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
    Sleep( 0 );
    return 0;
}

and look into disassembly. There're lots of C++ runtime functions in the program image. Some functions are located densely - ret of some function is followed by the first instruction of the next function. For example,

` __declspec(noreturn) void __cdecl __report_gsfailure(ULONGLONG StackCookie)`

ends at address 004013B7 (there's a ret instruction) and address 004013B8 contains some other function for which the debugger can't find the source. Meanwhile

BOOL __cdecl _ValidateImageBase(PBYTE pImageBase)

ends at address 00401554 but the next function

PIMAGE_SECTION_HEADER __cdecl _FindPESection( PBYTE pImageBase, DWORD_PTR rva )

starts at address 00401560 and there're multiple int 3 instructions between the latter two addresses.

Why the difference? Why some functions are put densely and others are separated with unreachable code?

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

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

发布评论

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

评论(2

↙温凉少女 2024-12-14 13:38:13

我重现了这种行为。您还可以注意到这些函数以 mov edi,edi 指令开头。

int 3 指令以及函数开头的 mov edi,edi 指令允许热修补。
当函数需要热修补时,mov edi,edi 被替换为在函数入口点之前跳转的短跳转指令,并且 int 3 指令被替换为到修补函数的长跳转。

请参阅有人知道“mov edi,edi”的作用吗?

Don不知道为什么 __report_gsfailure 前面只有 2 int 3 即使它以 mov edi,edi 指令开头...

I reproduced this behavior. You can notice as well that these functions start with a mov edi,edi intruction.

The int 3 instructions, along with the mov edi,edi instruction at the beginning of the function allows hotpatching.
When a function needs to be hotpatched, the mov edi,edi is replaced by a short jump instruction that jumps before the entry point of the function and the int 3 instructions are replaced by a long jump to the patched function.

Refer to Anyone knows what "mov edi,edi " does?

Don't know why __report_gsfailure is only preceeded by 2 int 3 even if it starts with a mov edi,edi instruction...

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