Перехват вызова внутренних функций
От: Alphelion  
Дата: 02.07.11 08:00
Оценка:
Здравствуйте.
Столкнулся с проблемой — не выполняется функция перехватчик одной из внутренних функций приложения. Я назвал ее 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), который я определил в ИДА.

Может кто-то сказать что я делаю не так?
примеров-то перехвата АПи функций кучи, а как перехват внутренних функций делать не очень много... по крайней мере я не нашел
Re: Перехват вызова внутренних функций
От: jyuyjiyuijyu  
Дата: 02.07.11 11:57
Оценка:
Здравствуйте, 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);
}
Re[2]: Перехват вызова внутренних функций
От: Alphelion  
Дата: 02.07.11 12:19
Оценка:
Это очень крутой пример, за что я премного благодарен!
Но опять же, используется для перехвата апи функций.
У меня же проблема в чем-то другом. Видимо с адресом ориганильной функции я ошибаюсь или с адресом функции перехватчика... я попробую посмотреть что получиться с вашим примером. Не зря же он такой крутой вдруг будет пахать
Re[3]: Перехват вызова внутренних функций
От: jyuyjiyuijyu  
Дата: 02.07.11 12:30
Оценка: 3 (1)
Здравствуйте, Alphelion, Вы писали:

A>Это очень крутой пример, за что я премного благодарен!

A>Но опять же, используется для перехвата апи функций.
A>У меня же проблема в чем-то другом. Видимо с адресом ориганильной функции я ошибаюсь или с адресом функции перехватчика... я попробую посмотреть что получиться с вашим примером. Не зря же он такой крутой вдруг будет пахать
тот не скомпилится этот поправленный http://slil.ru/31369071
а вообще какая разница апи или нет передавай адрес своей функции вместо апи и все
Re[4]: Перехват вызова внутренних функций
От: Alphelion  
Дата: 02.07.11 12:39
Оценка:
J>тот не скомпилится этот поправленный http://slil.ru/31369071
J>а вообще какая разница апи или нет передавай адрес своей функции вместо апи и все
Так мой код пашет для перехвата АПИ функций )) Я тоже думал всего лишь передать адрес внутренней функции вместо адреса АПИ функции и все, а не катит
Я пока boosts устанавливал, как раз наткнулся на проблемы при компиляции :D спасибо за поправки. Все проверю
Re[3]: Перехват вызова внутренних функций
От: jyuyjiyuijyu  
Дата: 02.07.11 12:51
Оценка:
Здравствуйте, Alphelion, Вы писали:

A>с вашим примером.

автор дизассемблера slesh это не мой код
Re[5]: Перехват вызова внутренних функций
От: jyuyjiyuijyu  
Дата: 02.07.11 12:59
Оценка:
Здравствуйте, Alphelion, Вы писали:

J>>тот не скомпилится этот поправленный http://slil.ru/31369071

J>>а вообще какая разница апи или нет передавай адрес своей функции вместо апи и все
A>Так мой код пашет для перехвата АПИ функций )) Я тоже думал всего лишь передать адрес внутренней функции вместо адреса АПИ функции и все, а не катит
A>Я пока boosts устанавливал, как раз наткнулся на проблемы при компиляции :D спасибо за поправки. Все проверю
поставьте точку останова на нужном адресе и запустите под отладчиком прогу в которую инжектите в студии properties->debugging->command пишите туда аппу которую запустить при отладке и запускайте отладку точки останова ставьте прямо в разрабатываемой длл в студии после запуска проги под отладчиком надо как то заинжектить длл самое простое это взять lord pe и исправить таблицу импорта у хукаемой проги вписать туда свою длл и при запруске она будет подгружатся загрузчиком и брякатся на ваших точках останова но можно и динамически инжектить
Re[4]: Перехват вызова внутренних функций
От: Alphelion  
Дата: 02.07.11 13:01
Оценка:
Краши это уже что-то
Сигнатура проблемы:
Имя события проблемы: APPCRASH
Имя приложения: main.exe
Штамп времени приложения: 49b87baa
Имя модуля с ошибкой: StackHash_e52f
Код исключения: c0000005
Смещение исключения: 24a48df0
Дополнительные сведения 1: e52f
Дополнительные сведения 2: e98dfca8bcf81bc1740adb135579ad53
Дополнительные сведения 3: 860f
Дополнительные сведения 4: 6eabdd9e0dc94904be3b39a1c0583635

Буду думать...
Re[6]: Перехват вызова внутренних функций
От: Alphelion  
Дата: 02.07.11 13:06
Оценка:
J>поставьте точку останова на нужном адресе и запустите под отладчиком прогу в которую инжектите в студии properties->debugging->command пишите туда аппу которую запустить при отладке и запускайте отладку точки останова ставьте прямо в разрабатываемой длл в студии после запуска проги под отладчиком надо как то заинжектить длл самое простое это взять lord pe и исправить таблицу импорта у хукаемой проги вписать туда свою длл и при запруске она будет подгружатся загрузчиком и брякатся на ваших точках останова но можно и динамически инжектить
большая беда — прога (main.exe), в которую я внедряю длл, запускается как-то хитро другой прогой. если запустить сам main.exe, она будет не работоспособна и я ничего не смогу проверить. параметры проверял, ничего в нее не передается. есть startupinfo, но ковырять его пока не хочу.
а с внудрением длл у меня проблем нет, я подменил оригинальную длл на свою (типа враппер сделал) и моя длл внедряется сама по себе
Re[4]: Перехват вызова внутренних функций
От: Alphelion  
Дата: 02.07.11 13:35
Оценка:
С небольшими поправками кода, хук стал вызываться! Премного благодарен вам
Re[5]: Перехват вызова внутренних функций
От: DPbIH Украина http://banderlogi.blogspot.com
Дата: 04.07.11 21:09
Оценка:
Здравствуйте, Alphelion, Вы писали:

A>С небольшими поправками кода, хук стал вызываться! Премного благодарен вам


А можно ли подробнее, если не сложно?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.