简体   繁体   English

防止Visual C ++内联函数

[英]Preventing Visual C++ From Inlining a Function

i wrote a simple program in c++ : 我用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;
} 


and compiled it with visual studio express 2010. 并使用Visual Studio Express 2010进行了编译。
i opened the result in OllyDbg, and this is what i saw: 我在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>]

And it looks like the function check_password has been inlined, because I can't see any CALL instruction to it. 看来函数check_password已被内联,因为我看不到任何CALL指令。

So my question is, how can I prevent this from happening? 所以我的问题是,如何防止这种情况发生? is there any way to tell the compiler that I want the function to appear in the executable? 有什么办法告诉编译器我希望函数出现在可执行文件中吗?

The reason I'm asking is because I'm trying to perform DLL injection, and my primary goal is to redirect the call to check_password into another function. 我问的原因是因为我正在尝试执行DLL注入,而我的主要目标是check_password的调用重定向到另一个函数。

There is no such thing as a macro in asm(it is just text replacement your code and takes place before the code is compiled). asm中没有宏(它只是文本替换您的代码,并在编译代码之前发生)。 What your referring to is the function has been inlined, usually when the compiler decides to do it it's a good thing, there is no c++ wide way to do this but you can do something like this 您所指的是已内联的函数,通常在编译器决定执行此操作时是好事,没有c ++广泛的方法可以执行此操作,但是您可以执行以下操作

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

code taken from this answer . 从此答案中获取的代码。
This will prevent the function from being inlined. 这将防止内联函数。 Keep in mind that most of the time inlining is a good thing because it gets rid of the overhead of the function call, it also has no real negative affects other than code bloat and debugging. 请记住,大多数情况下,内联是一件好事,因为它消除了函数调用的开销,除了代码膨胀和调试之外,它还没有真正的负面影响。 Compilers are very smart and generally make good decisions about inlining. 编译器非常聪明,通常会对内联做出良好的决策。 As you may already know you can use the inline specifier in c++ to suggest to the compiler that the function should be inlined. 您可能已经知道,可以在c ++中使用inline说明符向编译器建议应内联函数。

I also originally thought that a more portable way to prevent function inlining would be to call it from a function pointer, however this post says otherwise. 我还原本以为,以防止内联函数一个更便携的方式是从一个函数指针调用它,但是这个职位 ,否则说。

For people looking at this answer using gcc you can prevent inline like this void void __attribute__ ((noinline)) myfunc() this looks like it works for clang too ( I am using Apple clang version 4.0 ) so that should cover most of the c++ compilers people will be using. 对于使用gcc查看此答案的人,您可以防止像这样的内联void void __attribute__ ((noinline)) myfunc()这似乎也适用于clang(我使用的是Apple clang 4.0版),因此应涵盖大多数c ++人们将使用的编译器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM