Я пытаюсь подключить функцию, используя ее адрес, и пока она отлично работает!Сбой приложения при использовании функции hooked с cout
Единственная проблема при использовании std::cout
в сочетании с наличием MessageBoxA
с WinAPI, а затем сбой! Странная вещь, он выходит из строя только в этом конкретном случае, а не если она вызывается в сочетании с printf
или просто int i = MessageBoxA(...);
Для тестирования, я сделал так, что инструкции на адрес функции непосредственно возвращает 32
. Не знаю, что я знаю, но это просто для тестирования.
// mov eax, 32
// ret
const DWORD instructionCount = 6;
BYTE instructions[instructionCount] = { 0xB8, 0x20, 0x00, 0x00, 0x00, 0xC3 };
Кроме того, чтобы изменить защиту на области с VirtualProtect()
, то теперь я в основном просто сделать
memcpy(MessageBoxA, instructions, instructionCount);
Теперь тестирования с помощью этого:
int i = MessageBoxA(NULL, "Hello World", "Injector", MB_OK);
printf("Works: %d\n", i);
printf("Works: %d\n", MessageBoxA(NULL, "Hello World", "Injector", MB_OK));
std::cout << "Works: " << i << std::endl;
std::cout << "Doesn't: " << MessageBoxA(NULL, "Hello World", "Injector", MB_OK) << std::endl;
printf("Hello World\n");
Затем он выходит из строя только после std::cout << MessageBoxA(...)
. Удаление этой линии, и все работает!
Обратите внимание, что он успешно печатает 32
, он падает при достижении следующего утверждения.
Опять же это только в том случае, когда он не работает, так что с помощью этого:
__declspec(noinline) int testFunction(int i)
{
return i;
}
Затем повторно использовать код выше и изменения MessageBoxA
к testFunction
(а также аргументы), и теперь все 4 заявления работают!
Подводя итог, есть ли у кого-нибудь идеи, почему и что вызывает крушение в этом конкретном случае? Когда другие дела работают отлично.
запустите его в отладчике и покажите нам asm, register и stack backtrace в точке, где он сбой. Какая конвенция вызова используется MessageBoxA? Предполагается ли, что он выталкивает свои аргументы из стека? Если это так, вызывающий код будет толкать args и ожидать, что вызываемая функция очистит стек (применима только к 32-битовому коду, поскольку win64 ABI помещает первые 4 аргумента в regs). –
«std :: cout <<» Не делает: «<< (int) MessageBoxA (NULL,« Hello World »,« Injector », MB_OK) << std :: endl;' Work? –
@AdamMartin приводит к той же ошибке. – Vallentin