сборка — предотвращение вставки функции в Visual 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;
}

и скомпилировал его с 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, и моя основная цель — перенаправить вызов на check_password в другую функцию.

1

Решение

В asm нет такого понятия, как макрос (это просто замена текста в вашем коде и происходит до его компиляции). То, на что вы ссылаетесь — функция была встроена, обычно, когда компилятор решает это сделать, это хорошо, нет никакого широкого способа сделать это на c ++, но вы можете сделать что-то подобное

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

код взят из этот ответ.
Это предотвратит встроенную функцию. Имейте в виду, что в большинстве случаев вставка является хорошей вещью, потому что она избавляет от накладных расходов при вызове функции, она также не имеет реальных негативных последствий, кроме раздувания кода и отладки. Компиляторы очень умны и, как правило, принимают правильные решения о встраивании. Как вы уже знаете, вы можете использовать inline спецификатор в C ++ для предложить компилятору, что функция должна быть встроена.

Я также изначально думал, что более переносимым способом предотвращения встраивания функции будет вызов его из указателя функции, однако это сообщение говорит иначе.

Для людей, которые ищут этот ответ, используя НКУ вы можете предотвратить встраивание, как эта пустота void __attribute__ ((noinline)) myfunc() похоже, это работает и для clang (я использую Apple clang версии 4.0), так что это должно охватывать большинство компиляторов c ++, которые будут использовать люди.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]