Co do długości instrukcji - chodzi chyba o długość w bajtach instrukcji JMP rel32
czyli 5 bajtów.
długość instrukcji (chodzi o to, by skopiować całą instrukcję, która zostanie zmieniona przez skok do naszego kodu, zazwyczaj jest to 5)
- możesz spróbować.
Nie dam głowy jak powinno być, bo nigdy z takich ułatwień nie korzystałem ;).
Ok, ad rem. Spróbuję coś wytłumaczyć na przykładzie kodu napisanego przeze mnie przed wiekami (dokładniej - jakieś 2 lata temu). Zadaniem było przechwytywać komunikaty wypisywane przez puts na konsolę i logować do pliku.
Kod wygląda mniej-więcej tak:
char tramp[] = { 0xB8, 0xD3, 0xDE, 0xAD, 0xAD, // mov eax addr
0xFF, 0xD0 // call eax
};
Tworzymy 'trampolinę' (terminologia zerżnięta od Gynvaela którego oglądałeś).Tak naprawdę jest tam mov eax, 0xADADDED3, adres wypełniamy w czasie wykonania.
DWORD addr_hook_wrapper = (DWORD)wrapper; // adres funkcji mającej się wykonać zamiast
DWORD addr_puts = (DWORD)GetProcAddress(GetModuleHandle("msvcrt"), "puts"); // adres funkcji zastępowanej
memcpy(tramp+1, &addr_hook_wrapper, 4);
pobranie adresu wrappera puts do zmiennej i zmienienie trampoliny tak żeby skakała pod ten adres.
Ja użyłem wrappera bo potrzebowałem wywołać oryginalną funkcję po tym jak mój hook zrobi co powinien - jeśli tego nie potrzebujesz możesz sobie darować wrappera a twoje życie będzie dużo łatwiejsze - w takim wypadku po prostu wstawiasz zamiast wrappera, adres twojej funkcji.
hooker(tramp, 7, addr_puts);
Ostatni krok - funkcja wrzucająca hook - żadnego rocket science tu nie ma
void hooker(char *tramp, int t_size, DWORD addr)
{
DWORD old;
VirtualProtect((LPVOID)addr, t_size, PAGE_EXECUTE_READWRITE, &old);
memcpy((LPVOID)addr, tramp, t_size);
VirtualProtect((LPVOID)addr, t_size, old, &old);
}
To by było w sumie wszystko, ale nie do końca - potrafimy już sprawić żeby wykonał się wskazany przez nas kod.
Z wrapperem byłoby trochę trudniej bo bez asma by się nie obeszło, ale to temat na inny post chyba skoro i tak tego nie potrzebujesz.
(w miarę) pełen kod:
void hooker(char *tramp, int t_size, DWORD addr)
{
DWORD old;
VirtualProtect((LPVOID)addr, t_size, PAGE_EXECUTE_READWRITE, &old);
memcpy((LPVOID)addr, tramp, t_size);
VirtualProtect((LPVOID)addr, t_size, old, &old);
}
int main()
{
char tramp[] = { 0xB8, 0xD3, 0xDE, 0xAD, 0xAD, // mov eax addr
0xFF, 0xD0 // call eax
};
DWORD addr_hook_wrapper = (DWORD)twoja_funkcja_mająca_się_wykonać;
DWORD addr_puts = (DWORD)GetProcAddress(GetModuleHandle("msvcrt"), "puts"); // adres funkcji zastępowanej
memcpy(tramp+1, &addr_hook_wrapper, 4);
hooker(tramp, 7, addr_puts);
}
edit: tak czytam swój post i nie wiem czy cokolwiek chociaż w miarę jasno wytłumaczyłem... Mam nadzieję że tak.