Здравствуйте.
Столкнулся с проблемой — не выполняется функция перехватчик одной из внутренних функций приложения. Я назвал ее ShowMessageInChatLog.
Если декомпилировать эту функцию, то получаю следующую картину:
int __cdecl ShowMessageInChatLog(int ChatFlag, int a2, char *Caption, char *Message, int a5) {...}
Я загружаю в процесс свою длл, где пытаюсь установить хук на эту функцию. Все заканчивается тем, что моя функция перехватчик не выполняется, но и не выполняется оригинальная функция. И краша нет.
При том, что если из моей длл вызвать ShowMessageInChatLog следующим образом:
int* ShowMessageInChatLog = (int*)0x00480D20;
((int (__cdecl*)(int, int, char*, char*, int))ShowMessageInChatLog)(0, 0, "test", " asd", 0);
эта функция нормально отрабатывает и выводит что надо и где надо.
Теперь о процессе хукинга:
struct jmp_far
{
BYTE instr_push; //здесь будет код инструкции push
DWORD arg; //аргумент push
BYTE instr_ret; //здесь будет код инструкции ret
};
static DWORD written; //вспомогательная переменная
static jmp_far jump; //здесь будет машинный код инструкции перехода
void WriteToLog(char* str)
{
FILE* f = fopen("hook_log.txt", "a+");
fprintf(f, "%s\n", str);
fclose(f);
}
int __cdecl Hooked_ShowMessageInChatLog(int chat_flag, int unkn_0, char* caption, char* message, int unkn_1)
{
WriteToLog("Entered to message hook");
//Вызываем оригинальную функцию через указатель
int* ShowMessageInChatLog = (int*)0x00480D20;
int ret_val = ((int (__cdecl*)(int, int, char*, char*, int))ShowMessageInChatLog)(0, 0, "test", " asd", 0);
//int ret_val = ((DWORD (__stdcall*)(int, int, char*, char*, int))ShowMessageInChatLog)(chat_flag, unkn_0, caption, message, unkn_1);
WriteToLog("message hook executed");
return ret_val;
}
void InterceptFunctions(void)
{
// Зададим машинный код инструкции перехода, который затем впишем
// в начало полученного адреса:
jump.instr_push = 0x68;
jump.arg = (DWORD)&Hooked_ShowMessageInChatLog;
jump.instr_ret = 0xC3;
//Запишем команду перехода на нашу функцию поверх этих 6-ти байт
WriteProcessMemory(GetCurrentProcess(), (void*)0x00480D20, &jump, sizeof(jmp_far), &written);
}
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
InterceptFunctions();
}
В
WriteProcessMemory(GetCurrentProcess(), (void*)0x00480D20, &jump, sizeof(jmp_far), &written); 0x00480D20 это адрес начала функции (которую я зову ShowMessageInChatLog), который я определил в ИДА.
Может кто-то сказать что я делаю не так?
примеров-то перехвата АПи функций кучи, а как перехват внутренних функций делать не очень много... по крайней мере я не нашел
Здравствуйте, Alphelion, Вы писали:
A>Здравствуйте.
A>Столкнулся с проблемой — не выполняется функция перехватчик одной из внутренних функций приложения. Я назвал ее ShowMessageInChatLog.
A>Если декомпилировать эту функцию, то получаю следующую картину:
A>int __cdecl ShowMessageInChatLog(int ChatFlag, int a2, char *Caption, char *Message, int a5) {...}
A>Я загружаю в процесс свою длл, где пытаюсь установить хук на эту функцию. Все заканчивается тем, что моя функция перехватчик не выполняется, но и не выполняется оригинальная функция. И краша нет.
A>При том, что если из моей длл вызвать ShowMessageInChatLog следующим образом:
A>int* ShowMessageInChatLog = (int*)0x00480D20;
A>((int (__cdecl*)(int, int, char*, char*, int))ShowMessageInChatLog)(0, 0, "test", " asd", 0);
A>эта функция нормально отрабатывает и выводит что надо и где надо.
A>Теперь о процессе хукинга:
A>struct jmp_far
A>{
A> BYTE instr_push; //здесь будет код инструкции push
A> DWORD arg; //аргумент push
A> BYTE instr_ret; //здесь будет код инструкции ret
A>};
A>static DWORD written; //вспомогательная переменная
A>static jmp_far jump; //здесь будет машинный код инструкции перехода
A>void WriteToLog(char* str)
A>{
A> FILE* f = fopen("hook_log.txt", "a+");
A> fprintf(f, "%s\n", str);
A> fclose(f);
A>}
A>int __cdecl Hooked_ShowMessageInChatLog(int chat_flag, int unkn_0, char* caption, char* message, int unkn_1)
A>{
A> WriteToLog("Entered to message hook");
A> //Вызываем оригинальную функцию через указатель
A> int* ShowMessageInChatLog = (int*)0x00480D20;
A> int ret_val = ((int (__cdecl*)(int, int, char*, char*, int))ShowMessageInChatLog)(0, 0, "test", " asd", 0);
A> //int ret_val = ((DWORD (__stdcall*)(int, int, char*, char*, int))ShowMessageInChatLog)(chat_flag, unkn_0, caption, message, unkn_1);
A> WriteToLog("message hook executed");
A> return ret_val;
A>}
A>void InterceptFunctions(void)
A>{
A> // Зададим машинный код инструкции перехода, который затем впишем
A> // в начало полученного адреса:
A> jump.instr_push = 0x68;
A> jump.arg = (DWORD)&Hooked_ShowMessageInChatLog;
A> jump.instr_ret = 0xC3;
A> //Запишем команду перехода на нашу функцию поверх этих 6-ти байт
A> WriteProcessMemory(GetCurrentProcess(), (void*)0x00480D20, &jump, sizeof(jmp_far), &written);
A>}
A>BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
A>{
A> if (ul_reason_for_call == DLL_PROCESS_ATTACH)
A> InterceptFunctions();
A>}
A>В WriteProcessMemory(GetCurrentProcess(), (void*)0x00480D20, &jump, sizeof(jmp_far), &written); 0x00480D20 это адрес начала функции (которую я зову ShowMessageInChatLog), который я определил в ИДА.
A>Может кто-то сказать что я делаю не так?
A>примеров-то перехвата АПи функций кучи, а как перехват внутренних функций делать не очень много... по крайней мере я не нашел
держи
http://slil.ru/31368983
пример
SPLICE_JmpBuf jmp;
int
WINAPI
hook(
__in_opt HWND hWnd,
__in_opt LPCSTR lpText,
__in_opt LPCSTR lpCaption,
__in UINT uType)
{
return Call(MessageBoxA,jmp,0,0,0,0);
}
int main()
{
HMODULE hMod = GetModuleHandle("user32.dll");
void *proc = GetProcAddress(hMod, "MessageBoxA");
SPLICE_Set(proc, hook, &jmp);
MessageBoxA(0, "", "", 0);
SPLICE_UnSet(proc, &jmp);
}
Это очень крутой пример, за что я премного благодарен!
Но опять же, используется для перехвата апи функций.
У меня же проблема в чем-то другом. Видимо с адресом ориганильной функции я ошибаюсь или с адресом функции перехватчика... я попробую посмотреть что получиться с вашим примером. Не зря же он такой крутой
вдруг будет пахать
Здравствуйте, Alphelion, Вы писали:
A>Это очень крутой пример, за что я премного благодарен!
A>Но опять же, используется для перехвата апи функций.
A>У меня же проблема в чем-то другом. Видимо с адресом ориганильной функции я ошибаюсь или с адресом функции перехватчика... я попробую посмотреть что получиться с вашим примером. Не зря же он такой крутой вдруг будет пахать
тот не скомпилится этот поправленный
http://slil.ru/31369071
а вообще какая разница апи или нет передавай адрес своей функции вместо апи и все
J>тот не скомпилится этот поправленный http://slil.ru/31369071
J>а вообще какая разница апи или нет передавай адрес своей функции вместо апи и все
Так мой код пашет для перехвата АПИ функций )) Я тоже думал всего лишь передать адрес внутренней функции вместо адреса АПИ функции и все, а не катит
Я пока boosts устанавливал, как раз наткнулся на проблемы при компиляции :D спасибо за поправки. Все проверю
Здравствуйте, Alphelion, Вы писали:
J>>тот не скомпилится этот поправленный http://slil.ru/31369071
J>>а вообще какая разница апи или нет передавай адрес своей функции вместо апи и все
A>Так мой код пашет для перехвата АПИ функций )) Я тоже думал всего лишь передать адрес внутренней функции вместо адреса АПИ функции и все, а не катит
A>Я пока boosts устанавливал, как раз наткнулся на проблемы при компиляции :D спасибо за поправки. Все проверю
поставьте точку останова на нужном адресе и запустите под отладчиком прогу в которую инжектите в студии properties->debugging->command пишите туда аппу которую запустить при отладке и запускайте отладку точки останова ставьте прямо в разрабатываемой длл в студии после запуска проги под отладчиком надо как то заинжектить длл самое простое это взять lord pe и исправить таблицу импорта у хукаемой проги вписать туда свою длл и при запруске она будет подгружатся загрузчиком и брякатся на ваших точках останова но можно и динамически инжектить
Краши это уже что-то
Сигнатура проблемы:
Имя события проблемы: APPCRASH
Имя приложения: main.exe
Штамп времени приложения: 49b87baa
Имя модуля с ошибкой: StackHash_e52f
Код исключения: c0000005
Смещение исключения: 24a48df0
Дополнительные сведения 1: e52f
Дополнительные сведения 2: e98dfca8bcf81bc1740adb135579ad53
Дополнительные сведения 3: 860f
Дополнительные сведения 4: 6eabdd9e0dc94904be3b39a1c0583635
Буду думать...
С небольшими поправками кода, хук стал вызываться! Премного благодарен вам
Здравствуйте, Alphelion, Вы писали:
A>С небольшими поправками кода, хук стал вызываться! Премного благодарен вам
А можно ли подробнее, если не сложно?