#c #hook #inline-assembly
#c #перехват #встроенная сборка
Вопрос:
Я пытаюсь написать перехват батута для какой-либо функции win32 api, когда я пишу инструкцию JMP в начало исходной функции, я хочу, чтобы она переходила в кодовое хранилище вместо вызова функции.
Исходный запуск функции выглядит следующим образом в OllyDbg:
PUSH 14
MOV EAX, 12345678
...
И я исправляю его, чтобы:
JMP 87654321
NOP
NOP
Адрес следующей функции:
int HookFunc(int param)
{
DoStuff(param);
return ExecuteOriginal(param);
}
ExceuteOriginal выглядит так:
unsigned long address = AddressOfOriginalFunction 7;
int ExceuteOriginal(int param)
{
__asm
{
PUSH 0x14
MOV EAX, 0x12345678
JMP address
}
}
Который выполняет переопределенный код и переходит к исходной функции сразу после исправленного кода. Проблема в том, что, поскольку это функция, она испортит стек, потому что вызывающий должен его очистить, а функция вместо возврата переходит к коду другой функции. И я думаю, именно поэтому программа вылетает.
Есть ли способ с помощью компилятора Visual C поместить ассемблерный код в раздел кода программы, не помещая его внутри функции? Таким образом, я могу перейти туда, выполнить что угодно и вернуться обратно без риска испортить стек.
Ответ №1:
Решение: __declspec(naked)
Для функций, объявленных с атрибутом naked, компилятор генерирует код без кода prolog и epilog. Вы можете использовать эту функцию для написания собственных последовательностей кода prolog / epilog, используя встроенный ассемблерный код.
Пример:
__declspec( naked ) int ExceuteOriginal(int param)
{
__asm
{
PUSH 14
MOV EAX, 0x12345678
JMP address
}
}
Комментарии:
1. Большое спасибо! Это именно то, что я искал! 1 для простого решения