Как создать функцию батута с помощью DetourAttachEx?(с обходами MS) - PullRequest
2 голосов
/ 02 декабря 2010

У меня есть DLL, и я хочу создать объезд для одной из ее экспортируемых функций,

  • DLL не является частью Windows.
  • Мне нужно иметь возможностьвызов реальной функции после моего обхода (вызов реальной функции из обходной)
  • Я знаю точную сигнатуру функции.
  • Я уже смог отменить функцию, но вернотеперь я не могу назвать реальную.

Я понимаю, что мне нужно использовать функцию батута, я видел примеры в Интернете.проблема в том, что все эти примеры показывают, как обойти функцию Windows API, мне нужно сделать то же самое для функции, которую я тщательно импортирую.

любая помощь будет приветствоваться

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

, который даже не падает, но похоже, что он входит в бесконечный цикл (я предполагаю, потому что в исходной функции естьпрыгнуть в объезд)

редактировать - решено!не уверен, что это решило, использовал this в качестве ссылки.

  • прекратил использовать getProcadder и вместо этого начал использовать DetourFindFunction вместо
  • очистил код (уверен, я очистилвне зависимости от того, что вызвало проблему)

работает, все равно спасибо

1 Ответ

4 голосов
/ 02 декабря 2010

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

Шаг 1: вставка JMP <your code> в начале функции, занимает 5 байт, возможно, немного больше для выравнивания с ближайшей инструкцией. как пример

начало функции для подключения:

SUB ESP,3C
PUSH EDI
PUSH ESI
//more code

станет:

JMP MyFunction
//more code

можно было бы сделать это, написав 0xE9 в первом байте, а затем записав значение (function_addr - patch_addr + sizeof(INT_PTR)) в следующем DWORD. запись должна выполняться с помощью WriteProcessMemory после установки разрешений на чтение / запись / выполнение с помощью VirtualProtectEx

Шаг 2: Далее мы создаем интерфейс сборки:

void __declspec(naked) MyFunc()
{

    __asm
    {
        call Check             ;call out filter func
        test eax,eax           ; test if we let the call through
        je _EXIT
        sub esp,3c             ; its gone through, so we replicate what we overwrote
        push edi
        push esi
        jmp NextExecutionAddress ; now we jump back to the location just after our jump
    _EXIT:
        retn                   ; note, this must have the correct stack cleanup
    }

}

NextExecutionAddress необходимо будет заполнить во время выполнения, используя ModuleBase + RVA.


Если честно, проще и лучше (!) Просто EAT (таблица адресов экспорта) перехватить таблицу экспорта dll, или IAT (таблица адресов импорта) перехватить таблицы импорта того, что вызывает нужные вам функции фильтровать. У обходов должны быть функции для этого типа хуков, если нет, то для этого есть другие свободно доступные библиотеки.

Другим способом будет использование обходного пути для перехвата каждого вызова в приложениях с использованием dll для перенаправления их на прокси-функцию в вашем собственном коде, это дает преимущество, позволяющее фильтровать только определенные вызовы, а не все через двоичный файл (можно сделать то же самое, используя _ReturnAddress, но это больше работы), однако недостатком является захват местоположений для исправления (я использую ollydbg + пользовательский механизм исправлений), и он не будет работать на нестандартных функции соглашения о вызовах (например, сделанные с помощью #pragma aux в Watcom или оптимизированные вызовы, генерируемые VC7 +).

Одна важная вещь, на которую следует обратить внимание: если вы подключаете многопоточное приложение, ваши патчи должны быть сделаны с приостановленным приложением, или же они должны быть сделаны с использованием InterlockedExchange, InterlockExchange64 и InterlockedExchangePointer (я использую последнее для всех Перехватчики IAT / EAT, особенно при подключении стороннего процесса)


Глядя на пост, на который вы ссылаетесь, метод, на мой взгляд, ужасен, в основном из-за предположения: P, но как вы называете этот указатель, который вы получаете, и как он получается?

...