Остается заточить несложную процедуру, устанавливающую jump на thunk и восстанавливающую содержимое API-функции перед ее вызовом. Эта функция называется memcpy. Ну… почти memcpy. Чтобы установка jump'а завершилась успехом необходимо вызвать VirtualProtect с флагом PAGE_READWRITE, что слегка усложняет реализацию, однако, не столь радикально, чтобы впадать в депрессию. Это можно запрограммировать как на ассемблере, так и на Си. На Ассамблее — круче, на Си — быстрее.
Ниже приводится ассемблерный листинг с несколькими интересными хаками:
// устанавливает/удаляет thunk
//============================================================================
__declspec( naked ) _do_asm(char *src)
{
__asm
{
; сохраняем регистры, которые будут изменены
push ecx
push esi
push edi
; резервируем место под локальные переменные
push esp ; резервируем место под old-old (hack!!!)
push eax ; резервируем место под old
; вызываем VirtualProtect(p,0x1000,PAGE_READWRITE, &old);
; присваивая себе атрибут записи
push esp ; &old
push PAGE_READWRITE ; нельзя
PAGE_EXECUTE_READWRITE!
push
0x1000 ; size
push
[p] ; указатель на регион
call ds:VirtualProtect
; копируем память из src
в p
двойными словами
mov ecx, JUMP_SZ/4 ; size в дв. словах
mov esi, [esp+18h] ; src !!!следить за смещением!!!
mov edi, [p] ; dst
rep movsd ; копируем!
; вызываем VirtualProtect(p,0x1000,old,&old-old)
; восстанавливая прежние атрибуты зашиты
push esp ; old (hack!!!)
push
1000h ; size
push
[p] ; указатель на регион