Microsoft Detour - функция Hook с инструкцией "вызова" ассемблера - PullRequest
1 голос
/ 15 августа 2011

Первый вопрос на этой доске и уже довольно длинный - я прошу прощения за это (и тем самым благодарю всех за отличные советы, которые я получил от этой платформы).

Я пытаюсь подключить несколько функций (это более или менее подключаемый код, поэтому функция, которую я хочу подключить, не написана / не может быть изменена мной, но может быть доступна напрямую в том же процессе / потоке) с помощью Microsoft обходит.

Каждая функция, которая должна быть подключена, генерируется компилятором в стиле c и всегда имеет следующий код запуска "ассемблера":

045A1A85  push        ebp  
045A1A86  push        ebx  
045A1A87  push        esi  
045A1A88  push        edi  
045A1A89  call        045A1A8E  
045A1A8E  pop         eax  
045A1A8F  mov         ebx,eax  
//go on with a little bit more assembler code

Как вы можете видеть, некоторые регистры помещаются в стек, а затем вызывается инструкция вызова на следующую строку (пожалуйста, не просите изменить это, поскольку уже сказано, что у меня нет доступа к этому сгенерированному коду). Инструкция вызова изменяет стек - это изменение стека сохраняется в регистре eax и используется для дальнейшей обработки (!!!)

Этот метод будет подключен к:

045A1A85  jmp         hooking_function (528040h)  
045A1A8A  int         3  
045A1A8B  int         3  
045A1A8C  int         3  
045A1A8D  int         3  
045A1A8E  pop         eax  

Функция перехвата определяется как голая функция, которая просто переходит к функции батута.

__inline __declspec(naked) void hooking_function()
{
    //more code in future
    __asm {
        jmp org_func_trampoline
    }
}

Со следующей функцией батута:

031F0060  push        ebp  
031F0061  push        ebx  
031F0062  push        esi  
031F0063  push        edi  
031F0064  call        045A1A8E  
031F0069  jmp         045A1A8E  

Основная проблема в том, что инструкция вызова в коде ассемблера батута 1) добавляет в стек неверное значение (в данном случае 031f0064 вместо 045A1A89) -> дальнейшая обработка с помощью eax даст неверные результаты 2) более или менее разрушает кадр стека, так как следующий «ret» вернется к «031F0069» ==> одна и та же обработка будет выполнена дважды; ret будет вызываться СНОВА, приводит к неправильной функции ..

Пожалуйста, поймите, что НЕ гарантируется, что каждая функция, которую я хочу подключить, начинается с указанной выше преамбулы ... поэтому я не могу переписать функцию подключения и игнорирую метод батута ...

Итак, основной вопрос после всего этого текста: Можно ли подключить функцию с помощью Microsoft Detour, где в первых 5 байтах функции вызывается инструкция вызова? (если нет, есть ли альтернативы?)

Большое спасибо за чтение (и, надеюсь, за вашу помощь)

1 Ответ

1 голос
/ 16 августа 2011

Исходный код выполняет

045A1A89  call        045A1A8E  
045A1A8E  pop         eax  

, который является простым способом получить содержимое регистра eip. pop eax немедленно удаляет адрес возврата (045A1A8E) из стека и устанавливает eax в значение eip в точке его выполнения.

Очевидно, что у Detours нет возможности узнать это, и он обращается с ней как с любой подпрограммой, поэтому он выполняет call 045A1A8E на батуте, что приводит к другому значению eax (другому eip).

Я не совсем уверен, почему он вернется к 031F0069, после чтения кода, который вы разместили, он не должен этого делать.

Итак, да , это очень особый случай. Detours обычно вполне способен перехватывать функции, вызывающие вызовы среди первых нескольких инструкций. Этому просто удалось идеально разместить эти 2 инструкции для обхода, чтобы разбить их невыгодным способом.

...