gpt4 book ai didi

c++ - 防止 Visual C++ 内联函数

转载 作者:行者123 更新时间:2023-11-30 01:21:29 25 4
gpt4 key购买 nike

我用 C++ 写了一个简单的程序:

#include <stdio.h>

const signed char pass[] = "\x70\x61\x73\x73\x77\x6F\x72\x64";

bool __stdcall check_password(const signed char * str)
{
unsigned int i;
for(i=0;i<8;++i)
if(str[i]!=pass[i])
return false;
return true;
}

int main(int argc, char * argv[])
{
signed char buf[20];
printf("please enter the password: ");
scanf("%s",buf);
printf((check_password(buf)) ? "correct!\n" : "incorrect.\nPress any key to exit..\n");
getchar();
return 0;
}


并用visual studio express 2010编译。
我在 OllyDbg 中打开结果,这是我看到的:

Address   Hex dump            Command                                          Comments
00FF1011 ³. 8B35 A020FF00 MOV ESI,DWORD PTR DS:[<&MSVCR100.printf>]
00FF1017 ³. 68 0021FF00 PUSH OFFSET pass2.00FF2100 ; ASCII "please enter the password: "
00FF101C ³. FFD6 CALL ESI
00FF101E ³. 8D45 E8 LEA EAX,[LOCAL.6]
00FF1021 ³. 50 PUSH EAX
00FF1022 ³. 68 1C21FF00 PUSH OFFSET pass2.00FF211C ; ASCII "%s"
00FF1027 ³. FF15 A820FF00 CALL DWORD PTR DS:[<&MSVCR100.scanf>]
00FF102D ³. 83C4 0C ADD ESP,0C
00FF1030 ³. 33C0 XOR EAX,EAX
00FF1032 ³> 8A4C05 E8 MOV CL,BYTE PTR SS:[EAX+EBP-18]
00FF1036 ³. 3A88 F420FF00 CMP CL,BYTE PTR DS:[EAX+pass2.pass] ; ASCII "password"
00FF103C ³. 75 0D JNE SHORT pass2.00FF104B
00FF103E ³. 40 INC EAX
00FF103F ³. 83F8 08 CMP EAX,8
00FF1042 ³. 72 EE JB SHORT pass2.00FF1032
00FF1044 ³. B8 2021FF00 MOV EAX,OFFSET pass2.00FF2120 ; ASCII "correct!\n"
00FF1049 ³. EB 05 JMP SHORT pass2.00FF1050
00FF104B ³> B8 2C21FF00 MOV EAX,OFFSET pass2.00FF212C ; ASCII "incorrect.\nPress any key to exit..\n"
00FF1050 ³> 50 PUSH EAX
00FF1051 ³. FFD6 CALL ESI
00FF1053 ³. 83C4 04 ADD ESP,4
00FF1056 ³. FF15 9C20FF00 CALL DWORD PTR DS:[<&MSVCR100.getchar>]

看起来函数 check_password 已被内联,因为我看不到它的任何 CALL 指令。

所以我的问题是,如何防止这种情况发生?有什么方法可以告诉编译器我希望函数出现在可执行文件中吗?

我问的原因是因为我正在尝试执行 DLL 注入(inject),我的主要目标是将对 check_password 的调用重定向到另一个函数。

最佳答案

asm 中没有宏之类的东西(它只是文本替换您的代码,发生在代码编译之前)。你指的是函数已经内联,通常当编译器决定这样做时这是一件好事,没有 c++ 广泛的方法来做到这一点,但你可以做这样的事情

class X {
__declspec(noinline) int member_func() {
return 0;
}
};

代码取自 this answer .
这将防止函数被内联。请记住,大多数时候内联是一件好事,因为它摆脱了函数调用的开销,除了代码膨胀和调试之外,它也没有真正的负面影响。编译器非常聪明,通常会就内联做出正确的决定。您可能已经知道,您可以在 C++ 中使用 inline 说明符向编译器建议函数应该被内联。

我最初还认为防止函数内联的一种更便携的方法是从函数指针调用它,但是这 post另说。

对于使用 gcc 查看此答案的人,您可以像这样防止内联 void void __attribute__ ((noinline)) myfunc() 这看起来也适用于 clang (我使用的是 Apple clang 4.0 版)所以这应该涵盖人们将使用的大多数 c++ 编译器。

关于c++ - 防止 Visual C++ 内联函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17959140/

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