Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Показать сообщение отдельно
Kastaneda
Jesus loves me
Эксперт С++
4940 / 3017 / 346
Регистрация: 12.12.2009
Сообщений: 7,612
Записей в блоге: 2
Завершенные тесты: 1
09.08.2013, 21:39 0

Как обмануть компилятор и "перепрыгнуть через функцию"?

09.08.2013, 21:39. Просмотров 821. Ответов 10
Метки (Все метки)

Ответ

Ты манипулируешь с ebp, который используется для организации стек-фрейма и только компилятору известно где-что лежит. Т.е. я хочу сказать, что совсем не факт, что вот это
C++
1
mov [ebp+4], eax;
кладет адрес возврата туда, откуда он будет прочитан после "разрушения" стек-фрейма. Это первое, второе - не факт, что вот это
C++
1
2
mov eax, [ebp+4];
mov ret_address, eax;
сохраняет именно адрес возврата, а не, например, предыдущее значение ebp (т.к. при организации стек-фрема ebp сохраняется как раз на стеке). Ну и третье (самое важное) - здесь (и везде в подобных случаях)
C++
1
2
int get6(){
    _asm{
между первой и второй строкой есть ассемблерный код, который неизвестно что делает с регистрами, как и здесь
C++
1
2
    }
    return 6;
между закрывающейся скобкой и return.

Твоя затея может сработать так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
 
void *ptr = NULL;
 
void* f0()
{
lbl:
    if (ptr != NULL) {
        printf("Hello\n");
    }
 
    return &&amp;lbl;
}
 
void f1(void *exit)
{
    asm("pushl %0" :"=d"(exit));
    goto *ptr;
}
 
int main()
{
    ptr = f0();
    f1(&&exit);
 
exit:
    return 0;
}
gcc позволяет брать адреса меток оператором &&. В асм вставке мы подсовываем адрес метки exit инструкции ret из функции f0() (вообще-то этот пример писался в качестве ответа на вопрос как перейти при помощи gotо из одной ф-ции в другую). Он работает лишь чудом, потому что: 1 - маленькому коду сложей сломаться, чем большому, 2 - чудо Внутри f0() и f1() создаются собственные стек-фреймы и при вмешательстве асма за ними никто не следит, следовательно в функции main когда дело дойдет до exit: стек-фрема main'а фактически не существует, он нарушен и настроен, скорее всего, для ф-ции f1().

Вернуться к обсуждению:
Как обмануть компилятор и "перепрыгнуть через функцию"?
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.08.2013, 21:39

Как заменить функцию printf из "С" в "С++"?
Я знаю, что саму функцию printf можно заменить функцией cout, но меня...

Где ошибка невозможно преобразовать указатель "this" из "const pers" в "pers &" при выводе объектов через cout
Добрый день! Переписал код из книг Лафоре, создание мультимножества из...

Компилятор выдаёт ошибку: error C2011: Confection::Date: переопределение типа "struct". Как исправить?
#pragma once #pragma warning #ifndef Confection_H #define Confection_H...

0
Другие темы раздела
C++ vector<[class]> in class и перегрузка (ostream) http://www.cyberforum.ru/cpp-beginners/thread935871.html
Доброе всем время суток ) столкнулся с проблемой Есть у меня несколько классов и есть класс внутри которого созданы векторы хранящие элементы других 3-х классов Пытался перегрузить острим для...
C++ Структура в классе Здраствуйте! Хотел спросить можно ли использовать структуру в классе и соответствует ли оно принципам ООП? #include <iostream> #include <cmath> using namespace std; class Quad { protected:... http://www.cyberforum.ru/cpp-beginners/thread935858.html
ошибка в коде C++
#include <string.h> #include <iostream> #include <stdio.h> int main() { char m1="=id"; char m2; char m3;
C++ Как програмно узнать сколько элементов в перечислении?
Допустим, есть такое перечисление. enum Month{JANUARY=1, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER}; sizeof(Month) показывает размер одного элемента
C++ EOF что это http://www.cyberforum.ru/cpp-beginners/thread935822.html
В книге встречается записи типа ..если встретится указанный символ-ограничитель, по умолчанию это EOF... Что за EOF?
C++ Использование printf в функции Подскажите, пожалуйста: передаю в функцию два параметра для вывода void fun(string x, int y) { printf("%s%d",x,y); } надо, чтобы вывел подробнее
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru