Почему мой обходной код падает с NOP

Привет, это мой первый вопрос, поэтому, пожалуйста, обращайтесь со мной осторожно. Я обхожу exe-файл, используя обходные пути MS и Visual Studio 2005, моя dll загружается, и мой хук работает хорошо, однако, когда я пытаюсь расширить свой код хука, что-то идет не так, и все это рушится, я думаю, что это создает исключение в exe, которое выводит сообщение в службу поддержки.

typedef void (__stdcall* GenterateStrings)(int,int,int);

GenterateStrings Real_GenterateStrings = (GenterateStrings)(0x06EDFA0);

extern "C" { static void __stdcall myGenterateStrings(int,int,int); }

void __stdcall myGenterateStrings(int a1, int a2, int a3) 
{   
    myLogMessage(L"its working");
    Real_GenterateStrings( a1,  a2,  a3);
    return;
}

Это работает без исключений, и мой файл журнала заполняется «работой», однако мне нужно захватить EAX после моего вызова Real_GenterateStrings(), поскольку он содержит указатель на строку Unicode.

но если я добавлю какой-либо код после вызова Real_GenterateStrings, это вызовет сбой, как только он подключится. Даже просто нет

void __stdcall PokerAdvisorGenterateStrings(int a1, int a2, int a3) 
{   
    myLogMessage(L"its working");
    Real_GenterateStrings( a1,  a2,  a3);
    __asm   
    {
        nop
    }   
    return;
}

Есть идеи?

Функция, которую я подключаю,

mov     eax, [rsp+0Ch]
mov     ecx, [rsp+8]
mov     edx, cs:113650Ah
push    rax
mov     eax, [rsp+8]
push    rcx
push    rdx
push    0A3CA2Ch
push    rax
call      near ptr unk_6AB8E0
add     esp, 14h
retn

Я не думаю, что он возвращает значение?


person Infromthecold    schedule 07.09.2011    source источник
comment
На минуту я подумал, что аргумент для '__asm' должен быть строкой. Затем я понял, что встроенная сборка Windows полностью отличается от GCC. Поэтому я удалил свой ответ. Я не вижу ничего явно неправильного в вашем коде.   -  person Mysticial    schedule 07.09.2011
comment
Запустите его с помощью отладчика и получите трассировку стека, содержимое регистров и выясните, что именно дает сбой.   -  person user786653    schedule 07.09.2011
comment
Я серьезно сомневаюсь, что дизассемблер правильный, он выглядит как 32-битный ассемблер со случайными 64-битными именами регистров. Кроме того: похоже, что функция использует __cdecl в качестве соглашения о вызовах. Вы уверены, что это должно быть __stdcall?   -  person user786653    schedule 07.09.2011


Ответы (1)


Откуда вы знаете, что в eax что-то есть?

Как правило, объездные сбои часто происходят из-за неточного соглашения о вызовах и/или прототипа. Я подозреваю, что обходная функция возвращает void* или что-то еще. Вам нужно зафиксировать возвращаемое значение и передать его вызывающей стороне, как только вы закончите, например:

typedef void* (__stdcall* GenterateStrings)(int,int,int);

GenterateStrings Real_GenterateStrings = (GenterateStrings)(0x06EDFA0);

extern "C" { static void __stdcall myGenterateStrings(int,int,int); }

void* __stdcall myGenterateStrings(int a1, int a2, int a3) 
{   
    myLogMessage(L"its working");
    void* ret = Real_GenterateStrings( a1,  a2,  a3);
    __asm   
    {
        nop
    }   

    return ret;
}
person Bahbar    schedule 07.09.2011
comment
Я провел 4 дня, просматривая exe с IDA pro, чтобы перейти к вызову функции, который я хочу обойти, и eax, содержащему нужный мне указатель. Я отредактировал свой вопрос, чтобы показать функцию сборки, однако предложенные вами изменения по-прежнему не работают. - person Infromthecold; 07.09.2011
comment
ИСПРАВЛЕНО я изменил __stdcall на __cdecl и бинго - person Infromthecold; 07.09.2011
comment
@Mike: не уверен, что ты имел в виду. прототип в вопросе не имел возвращаемого значения. Вот почему я спросил, как стало известно, что что-то находится в eax. Я предполагал (ошибался), что компилятор переопределяет регистр eax из-за блока asm. @lnfromthecold: я рад, что ты нашел это. Как вы могли заметить из disasm, функция, которую вы обходите, не очищает параметры своего стека. Так что это точно не был stdcall. Но, как упоминает Майк, eax является возвращаемым значением (также для всех соглашений). здесь возвращаемое значение является одним из call near ptr unk_6AB8E0 - person Bahbar; 09.09.2011