Вызовите функцию дважды с помощью Assembly и C ++ - PullRequest
4 голосов
/ 13 июля 2010

У меня есть код, который меняет вызываемую функцию на мою новую функцию, но я не хочу вызывать только мою новую функцию, я также хочу вызвать старую.Это пример, поэтому вы можете понять, что я говорю:

Если я разберу свой .exe, я посмотрю на эту часть:

L00123456:
      mov   eax, [L00654321] //doesn't matter
      mov   ecx, [eax+1Ch]   //doesn't matter
      push  esi              //the only parameter
0x123 call  SUB_L00999999    //this is the function I wanna overwrite
      //...

(0x123 - это адресэта строка) Итак, я использовал этот код:

DWORD old;
DWORD from = 0x123;
DWORD to   = MyNewFunction;
VirtualProtect(from, 5, PAGE_EXECUTE_READWRITE, &old);

DWORD disp = to - (from + 5);
*(BYTE *)(from) = 0xE8;
*(DWORD *)(from + 1) = (DWORD)disp;

Теперь, вместо вызова SUB_L00999999, он вызывает MyNewFunction ...

Итак ... любые идеи о том, как я все еще могу вызватьстарая функция?

Я пробовал подобные вещи (во многих отношениях), но это приводит к сбою моего приложения:

int MyNewFunction(int parameter)
{
    DWORD oldfunction = 0x00999999;
    _asm push parameter
    _asm call oldfunction
}

Примечания: я использую Visual Studio C ++ 2010, и эти коды находятся в.dll загружен в .exe.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 13 июля 2010

У меня была такая проблема некоторое время назад.Во всяком случае, _asm call dword ptr [oldfunction] работал на меня.

2 голосов
/ 13 июля 2010

ret ожидает, что аргумент верхнего стека будет адресом возврата. Вы можете воспользоваться этим, поместив адрес старой функции в стек непосредственно перед инструкцией ret в новой функции. Когда вызов вернется (или, скорее, перейдет к старой функции), указатель стека сместится, оставив исходный адрес возврата (здесь 0x128) сверху, поэтому стек будет выглядеть не поврежденным. (как и следовало бы, если бы вы не пошли в обход).

...