Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
sion5
1 / 1 / 0
Регистрация: 15.10.2013
Сообщений: 42
#1

Вызов функции-члена класса по адресу в памяти - C++

09.07.2015, 13:22. Просмотров 723. Ответов 12
Метки нет (Все метки)

Всем хорошего дня

Допустим, что где-то есть static функция, не принимающая аргументов и ничего не возвращающая.
Имея один лишь только её адрес в памяти, можно сделать вот так:
void (*f)() = reinterpret_cast<void (*)()>(0x004028E0);
f()
Тут всё ясно.

Теперь допустим, что есть функция-член класса (не статическая). Её адрес в памяти тоже известен.
Нужно её вызвать...
Только не спешите возмущаться, что её нельзя вызвать, не имея объекта, на котором она вызывается. Адрес в памяти конкретного объекта тоже есть...
Имея два адреса (объекта и функции), нужно как-то это всё скастить и вызвать...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.07.2015, 13:22
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Вызов функции-члена класса по адресу в памяти (C++):

Объявление класса, создание объекта и вызов функции-члена - C++
Всем добрый день! Вот так я объявляю класс. typedef map&lt;string, double&gt; datablock; typedef map&lt;string, string&gt; groupvars; ...

Освобождение памяти для члена класса - C++
Добрый вечер :victory: Проблема, чувствую, тривиальная, но что-то я не могу сообразить :coffee2: В моём самописном классе есть член...

рекурсивный вызов функции-члена - C++
как осуществить рекурсивный вызов функции члена?

Сам вопрос: почему функция-член одного класса не вызывается из функции-члена другого класса? - C++
//Щас всё объясню. Так, имеем два класса, в одном я определил функцию-член. Все конструкторы и прочее //опущены для уменьшения кода ...

Вызов функции-члена элементов списка - C++
Вот есть список, хранящий указатели (на экземпляры классов). Можно ли в нем реализовать подобную функцию?, вызывая которую, мы будем...

вызов функции члена через std::function - C++
Суть в следующем Задача сделать обертку вызывающую функцию член класса с параметрами. Для этого используется класс: ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
sashatref
75 / 75 / 27
Регистрация: 21.05.2015
Сообщений: 257
Завершенные тесты: 1
09.07.2015, 13:25 #2
Если есть адрес объекта, почему нельзя его скастить к нужному типу и у него уже вызывать функцию?
DrOffset
7090 / 4231 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
09.07.2015, 13:27 #3
Цитата Сообщение от sion5 Посмотреть сообщение
нужно как-то это всё скастить и вызвать
Зачем что-то кастить, когда есть стандартные средства?
Указатель на функцию класса + указатель на объект: https://msdn.microsoft.com/en-us/library/k8336763.aspx
sion5
1 / 1 / 0
Регистрация: 15.10.2013
Сообщений: 42
09.07.2015, 13:33  [ТС] #4
Вопрос логичный... Но нельзя. Об объекте ничего не известно... Исходников и даже заголовочных файлов нету. Есть только его адрес и адрес функции... Не известно даже, что именно делает функция... Такое...
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,272
Завершенные тесты: 3
09.07.2015, 13:34 #5
sion5, по-моему, я где-то читал, что компилятор заменяет такой вызов obj.getSome() на ObjClass::getSome(ObjClass& obj). Можете покопать в этом направлении
DrOffset
7090 / 4231 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
09.07.2015, 13:41 #6
Цитата Сообщение от sion5 Посмотреть сообщение
Есть только его адрес и адрес функции... Не известно даже, что именно делает функция...
Тогда изучай calling conventions. Вот, например, для VS https://msdn.microsoft.com/ru-ru/library/ek8tkfbw.aspx
Если у тебя VS, то указатель на объект класса нужно будет передать через ECX, остальные аргументы через стек справа налево.
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,272
Завершенные тесты: 3
09.07.2015, 13:44 #7
DrOffset, это имеете в виду?
C++
1
2
3
4
5
6
class SomeClass;
typedef void (SomeClass::*SomeClassFunction) (void);
void Invoke(SomeClass *pClass, SomeClassFunction funcptr) 
{
  (pClass->*funcptr)(); 
};
----------------------------------------------
Вот интересную стать нашел: https://rsdn.ru/article/cpp/fastdelegate.xml то, что я имел в виду, рассказывается под заголовком "Указатели на функции-члены – почему они такие сложные?"
DrOffset
7090 / 4231 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
09.07.2015, 13:47 #8
Цитата Сообщение от tnk500 Посмотреть сообщение
это имеете в виду?
Это. Да. Но ТСу, как видно, это не подходит.
sion5
1 / 1 / 0
Регистрация: 15.10.2013
Сообщений: 42
09.07.2015, 13:55  [ТС] #9
Спасибо. Нужно теперь время, чтоб перечитать ссылки и попробовать.
DrOffset, честно говоря, до засовывания адреса в ECX я уже додумался... Видел в дебаггере, что через него передается адрес объекта. Это действительно именно то, что мнн нужно, и действительно работает. Но надеялся, что есть другие способы... Менее "олдскульные".
DrOffset
7090 / 4231 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
09.07.2015, 14:01 #10
Цитата Сообщение от sion5 Посмотреть сообщение
Но надеялся, что есть другие способы... Менее "олдскульные".
Если ты в требованиях отказался от поддержки компилятора (ну или вынужден был отказаться), то остается только "олдскул". Ну, как вариант, можно поискать библиотеку или что-то вроде того, которая это сделает за тебя.
sion5
1 / 1 / 0
Регистрация: 15.10.2013
Сообщений: 42
09.07.2015, 15:14  [ТС] #11
Наверное, надо было сразу пояснить, зачем мне это. Я ничего конкретного пока не пишу.
Но мне интересно разобраться, как работают разнообразные боты/трейнеры к играм и программы типа SKSE. SKSE, если не знаете, расширяет возможности скриптов в Skyrim. Ну это не интересно, а интересно то, что оно не только читает/меняет память, а еще и преспокойно вызывает функции из экзешника игры.
Сейчас еще подумаю над всем, что вы писали... В крайнем случае, придется понемногу разбираться с исходниками SKSE (они есть, на С++).

У меня уже получалось заинджектить dll в собственную программу и вызывать в ней static функции и функции-члены (с записью адреса объекта в ECX). Вот только беглый просмотр исходников SKSE не обнаружил там никакой работы с ECX... Интересно, как же оно работает.

Есть такое
#define CALL_MEMBER_FN(obj, fn) \
((*(obj)).*(*((obj)->_##fn##_GetPtr())))

Муть какая-то. Наверное, вообще к делу не относится. Ну исходников там 2 Мб и с ними разбираться - это только на крайний случай.
DrOffset
7090 / 4231 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
09.07.2015, 17:11 #12
Цитата Сообщение от sion5 Посмотреть сообщение
Наверное, вообще к делу не относится.
Относится. Но там еще несколько важных макросов до этого.
Там используется как раз стандартный синтаксис, который я предлагал в посте 3. Значит в address просто лежит смещение по базе от this.
sion5
1 / 1 / 0
Регистрация: 15.10.2013
Сообщений: 42
09.07.2015, 22:10  [ТС] #13
Немного подразобрался... Спасибо за советы и ссылки.
"реверс-инжениринг" макросов от SKSE тоже помог.
Большой затык был с кастингом void указателя в указатель на функцию-член класса. Просто так каститься не хотел ни в какую... Нагуглил много сообщений, в которых пишут, что так кастить и нельзя вовсе. Мол, у указателей на член класса даже размер другой (8 вместо 4).
Потом оказалось, что таки можно, если осторожно... Во всяком случае, иногда. Скастить можно через юнион или через указатель на указатель...

_Phonebook *_book = (_Phonebook *)(0x0022F238);

typedef void (_Phonebook::*printPhoneFunc)(const char *);

static const unsigned long long address = 0x004016D0;
printPhoneFunc *p = (printPhoneFunc *)&address;

(_book->*(*p))("Ragana");
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.07.2015, 22:10
Привет! Вот еще темы с ответами:

Как такое может быть? (вызов функции-члена без объекта) - C++
собственно вопрос озвучен. #include &lt;iostream&gt; using namespace std; class Test { public: void print() {

Функции в качестве члена класса - C++
Вот изучаю классы, и я так понял,можно описывать функции вне класса, достаточно знака &quot;: :&quot;. Вот решил написать, поэкспериментировать....

Определить операторы как функции члена класса - C++
Добрый вечер! Ребята, помогите решить вот такую задачку: Необходимо определить операторы +, =, +=, -=, *=, , как функции члена...

Перегруженный оператор сдвига '<<' не функции-члена класса для объекта ostream - C++
Добрый день. В учебнике попалось на первый взгляд простое задание: #include &lt;iostream&gt; int main() { std::cout &lt;&lt; &quot;Hello,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.07.2015, 22:10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru