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

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

Восстановить пароль Регистрация
 
sion5
1 / 1 / 0
Регистрация: 15.10.2013
Сообщений: 42
09.07.2015, 13:22     Вызов функции-члена класса по адресу в памяти #1
Всем хорошего дня

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

Теперь допустим, что есть функция-член класса (не статическая). Её адрес в памяти тоже известен.
Нужно её вызвать...
Только не спешите возмущаться, что её нельзя вызвать, не имея объекта, на котором она вызывается. Адрес в памяти конкретного объекта тоже есть...
Имея два адреса (объекта и функции), нужно как-то это всё скастить и вызвать...
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
sashatref
75 / 75 / 27
Регистрация: 21.05.2015
Сообщений: 257
Завершенные тесты: 1
09.07.2015, 13:25     Вызов функции-члена класса по адресу в памяти #2
Если есть адрес объекта, почему нельзя его скастить к нужному типу и у него уже вызывать функцию?
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,588
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,211
Завершенные тесты: 3
09.07.2015, 13:34     Вызов функции-члена класса по адресу в памяти #5
sion5, по-моему, я где-то читал, что компилятор заменяет такой вызов obj.getSome() на ObjClass::getSome(ObjClass& obj). Можете покопать в этом направлении
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,588
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,211
Завершенные тесты: 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
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,588
09.07.2015, 13:47     Вызов функции-члена класса по адресу в памяти #8
Цитата Сообщение от tnk500 Посмотреть сообщение
это имеете в виду?
Это. Да. Но ТСу, как видно, это не подходит.
sion5
1 / 1 / 0
Регистрация: 15.10.2013
Сообщений: 42
09.07.2015, 13:55  [ТС]     Вызов функции-члена класса по адресу в памяти #9
Спасибо. Нужно теперь время, чтоб перечитать ссылки и попробовать.
DrOffset, честно говоря, до засовывания адреса в ECX я уже додумался... Видел в дебаггере, что через него передается адрес объекта. Это действительно именно то, что мнн нужно, и действительно работает. Но надеялся, что есть другие способы... Менее "олдскульные".
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,588
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
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,588
09.07.2015, 17:11     Вызов функции-члена класса по адресу в памяти #12
Цитата Сообщение от sion5 Посмотреть сообщение
Наверное, вообще к делу не относится.
Относится. Но там еще несколько важных макросов до этого.
Там используется как раз стандартный синтаксис, который я предлагал в посте 3. Значит в address просто лежит смещение по базе от this.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.07.2015, 22:10     Вызов функции-члена класса по адресу в памяти
Еще ссылки по теме:

C++ Определить операторы как функции члена класса
Освобождение памяти для члена класса C++
C++ Объявление класса, создание объекта и вызов функции-члена

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

Или воспользуйтесь поиском по форуму:
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");
Yandex
Объявления
09.07.2015, 22:10     Вызов функции-члена класса по адресу в памяти
Ответ Создать тему
Опции темы

Текущее время: 17:22. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru