Использование недокументированных классов в C ++
-
26-09-2019 - |
Вопрос
Я в процессе обратного инженерии исполняемый файл Windows. Я нашел класс, который я хочу использовать из некоторых кода, который я вводил в исполняемый файл (разные потоки, собственные стеки). Как бы я пошел в объявление такого класса, учитывая метод адреса и структуру переменных членов?
Например, скажем, я нашел класс под названием Foo, с его конструктором @ 0x4012d30 и функцией dothemario @ 40125d4. Я также знаю, что он содержит три рациональных данных. Поскольку оба метода являются _Thiscalls, я объявляю класс, как в моем коде:
class GuessedFoo {
private:
int bar;
char *cafebabe;
float deadbeef;
public:
GuessedFoo(int a, int b);
void doTheMario();
};
Теперь это идеально Dandy Class, но теперь есть ли способ сделать компилятор / линкер привязать методы класса к двум предыдущим адресам, которые я заявил? Конечно, я могу написать обертку ASM, чтобы преобразовать stdcall в этот экран для каждого метода, который мне нужно использовать, а затем использовать структуры вместо классов, но должен быть лучший способ.
Я использую GCC / G ++ в данный момент, но я могу переключиться на VC ++ (поскольку встроенный ASM GCC дает мне головные боли в любом случае).
Решение
Если у класса нет VTable, вы можете, в принципе, создайте такой класс в своем собственном коде, где все вызовы функций вызывают соответствующие реальные реализации. Вы можете сделать это, написав члены функции как Голые функции содержащий инструкцию скачка сборки к реальной реализации.
Если у класса есть VTable, вещи могут получить гораздо более сложный; Скорее всего, вам понадобится явно создать VTable в качестве структуры указателей функциональных указателей и сделать ваши функциональные заглушки в них. Это означает более сложные прокладки; Простая обнаженная функция с прыжком может быть недостаточно, и может быть лучше пойти с реальной функцией. Помните, однако, что функции члена на Win32 используют Разная конвенция о вызове; Это означает, что обычный звонок функции члена не будет работать. Ты мая быть в состоянии уйти с созданием указателей на участниках, но имейте в виду, что у них есть Скорее странная структура Для них, и вам нужно будет сопоставить его с тем, что имеет то же представление, что и указатели VTable. Удачи!
Другие советы
Вы здесь с реверсию, следовательно, (почти, наверное) вынуждены снизить, когда речь идет о взаимодействии с существующим кодом.
Я бы назвал эту функцию с помощью чистого кода сборки.
Если базовый адрес EXE исправлен, это еще проще.
Пример кода:
void main()
{
int bar = 5;
int * cafebabe = &bar;
__asm
{
push [bar];
push [cafebabe];
mov eax, 123456; // address of the function
call eax;
}
}
Просто проверьте, как эта функция называется оригинальным кодом, чтобы увидеть, в каком порядке вам нужно нажать аргументы. Не забывайте, что некоторые аргументы могут потребоваться пропустить через регистры!
Я не совсем уверен, что я вас правильно понимаю, но инако: я думаю, что самый простой маршрут к методам «вручную» используют функциональные указатели.
C ++ не определяет какой-либо двоичный интерфейс, что делает все это, кроме невозможно реализовать любые виды динамического связывания для классов C ++.
Лучшее, что вы можете сделать, это объявить два структура - один, содержащий C-функцию Typedefs для каждого метода, другие отражают макет данных класса.
Конечно - потому что __thishall на методе класса пропускает «Это» через регистр ECS, я не уверен, что вы действительно можете сделать явную декларацию функции C, которая будет иметь тот же эффект, поэтому вам может потребоваться выполнить все вызовы через обычай «CallThiscallMethodwithParameters», что вы писали в Сборке.