Просто думал, что если я смогу что-то превратить в jmp, тогда я смогу поместить свой код в другое место, сделать все, что я перезаписал, и потом вернуться к следующей инструкции?
... это хороший подход для исправления кода во время выполнения, да. Но могут быть какие-то подробности, которые нужно учитывать, в зависимости от того, что именно делают переписанные инструкции. В любом случае, внедрение кода может оказаться сложнее, чем вы ожидаете: например, код может отображаться только для чтения.
весь код для этого очень и очень длинный, поскольку он, как правило, может вызывать любую функцию с количеством аргументов до 16, а также соответствующим управлением памятью для строк и поддержкой __stdcall или __cdecl)
Итак: этот код вызывает ваш код и может передавать аргументы? Можете ли вы зарегистрировать хотя бы один аргумент размером с указатель вместе с функцией, которая будет вызываться обратно?
Если это так, вы можете передать указатель this
самостоятельно, немного повозившись. Вам необходимо зарегистрировать функцию, которая не требует указатель this
(например, статическая функция-член) в качестве обратного вызова, наряду с указателем this
в качестве аргумента для обратного вызова; этот обратный вызов может затем развернуть аргумент, чтобы вызвать функцию-член, которую вы действительно хотите вызвать.
Примерно так (с извинениями, если очевидно, что я трачу большую часть своей жизни на написание C, а не C ++):
#include <iostream>
// Simple C callback interface
extern "C" {
typedef void (*tCallbackFn)(void *);
static struct {
tCallbackFn fn;
void *context;
} callback;
static void set_callback(tCallbackFn fn, void *context)
{
callback.fn = fn;
callback.context = context;
}
static void call_callback(void)
{
(callback.fn)(callback.context);
}
}
// Simple test class
class MyClass
{
public:
// We'll use this for test purposes
int id;
// This is the actual member function we want to invoke
void DoIt(void)
{
std::cout << "Callback - id = " << id << std::endl;
}
// Static wrapper which we can pass as the function in the callback interface
static void CallbackWrapper(void *context)
{
static_cast<MyClass *>(context)->DoIt();
}
// Register wrapper as callback function, with "this" pointer as context
void Test(void)
{
set_callback(CallbackWrapper, static_cast<void *>(this));
call_callback();
}
};
// Test it
int main(void)
{
MyClass m1, m2;
m1.id = 1;
m2.id = 2;
m1.Test();
m2.Test();
return 0;
}