Nynaeve ce grand malade commence une série sur les optimisations du compilo. Dans ce premier post on retrouve le fameaux xor eax,eax à la place du mov eax, 0 qui à l’avantage d’être plus rapide et de prendre moins de place en mémoire. Autre chose intéressante l’utilisation de l’instrution lea pour réaliser des opérations arithmétiques avec le moins d’instructions possible, par exemple lea eax, [eax*4+1] permet de mettre dans eax, eax*4+1 tout ca en 1 seule instruction, c’est pas beau ca :]
L’article en anglais ici : http://www.nynaeve.net/?p=64
Moi je dis à suivre.
février 10th, 2007
Yop, après une semaine d’idlage larvaire intensif je me décide à poster quelque chose. Une chose qu’on aime faire lorsque qu’on veut faire mumuse avec le système est de détourner le fonctionnement normal de ses fonctions, pour cela on utilise un « hook », le principe est simple on modifie légèrement le programme pour qu’il appel notre fonction au lieu d’appeler la fonction original. Le plus souvent on détourne une fonction afin de modifier ses résultats, ainsi il est possible de faire croire ce qu’on veut au programme :}
Il existe en gros 2 méthodes pour hooker, la première consiste à modifier la table des imports qui contient les adresses des différentes fonctions importées des DLL. Par exemple si l’on désire détourner la fonction GetModuleHandle(), on modifie dans l’IAT (Import Address Table) le pointeur sur cette fonction par l’adresse de la notre. Evidemment niveau discrétion c’est pas trop ca, il suffit de scanner les entrées de l’IAT et de les comparer aux adresses des vrai fonctions pour détecter se type de hook.
D’ou l’invention d’une seconde méthode, l’inline hook, cette fois plus question de toucher à l’IAT, on va directement modifier le prologue de la fonction. En fait l’on place au début de la fonction un jump sur la notre, le problème c’est qu’on écrase ses premiers bytes et si l’on veut la réutiliser ca pose problème :p
Pour ne pas déteriorer la fonction de départ on sauvegarde ses premieres instructions suivit d’un petit jump, je m’explique, voulant exécuter toutes les instructions de la fonction hooké on doit commencer par appeler ses premiers bytes puis le reste qui n’a pas bougé on l’appel en jumpant dessus, on obtient donc le schéma suivant:
{//buffer en mémoire
[premiers bytes sauvegardés]
[jump @begin]
}
{//fonction hookée
[jump sur notre fonction]
[@begin, instructions inchangées de la fonction hookée]
}
On commence par call sur les premiers bytes saved, on les exécute, puis on jump sur la suite.
Reste encore un petit soucis, la taille d’un jmp en assembleur est des 5 octects, or sauvegarder les 5 premiers bytes de l’API hooké serait une erreur, en effet si par exemple on se retrouve avec 2 instrutions, 1 de 3 bytes et l’autre de 4 bytes, la seconde sera tronqué et lors du jump on exécutera n’importe quoi. La solution est d’utiliser un moteur qui calcul la taille des instructions oO, on calcul la taille des instructions jusqu’à trouver un bloc de taille supérieure ou égale à 5 octets. Si on doit copier 7 bytes alors les 5 premiers seront pour les jump et les 2 autres contiendront des nop (0×90).
Le mieux est évidemment de voir ce que ca donne, dans l’exemple suivant je hook l’api native NtOpenFile :
Avant le hook:
7C91DCFD > B8 74000000 MOV EAX,74
7C91DD02 BA 0003FE7F MOV EDX,7FFE0300
7C91DD07 FF12 CALL NEAR DWORD PTR DS:[EDX]
7C91DD09 C2 1800 RET 18
Après la hook :
7C91DCFD >- E9 374C6E93 JMP 10002939
7C91DD02 BA 0003FE7F MOV EDX,7FFE0300
7C91DD07 FF12 CALL NEAR DWORD PTR DS:[EDX]
7C91DD09 C2 1800 RET 18
A noter que le hasard veut que la première instruction fasse 5 octets ...
On la retrouve sauvegardé ici, suivit du jump vers les suite des instructions
000A9518 B8 74000000 MOV EAX,74
000A951D - E9 E047877C JMP ntdll.7C91DD02
Now reste plus qu’a lancé cela dans la mémoire d’un process, pour cela on utilise une dll qui lors du DLL_PROCESS_ATTACH place le hook, et l’enlève lors du DLL_PROCESS_DETACH. Je ne reviens sur la méthode pour injecter une DLL, il y à assez de doc sur le net pour apprendre ça.
La fonction qui place le hook s’appelle, InstallInlineHook() elle prend 3 arguments :
-L’adresse de l’API à hooker
-L’adresse de notre fonction de substitution
-Un pointeur sur la zone mémoire qui contiendra les instructions sauvegardées.
Pour l’enlever on utilise RemoveInlineHook() avec comme paramètres:
-L’addresse de l’API hooké
-L’adresse des premières instructions sauvegardées
-La taille des instruction sauvegardées
Vous touverez dans les sources:
InlineHook.cpp : le moteur d’inline hook
ZDisasm.h et ZDisasm.C la moteur codé par Z0MBiE qui calcul la taille des instructions.
NtOpenFile_spy.cpp : la dll qui hook l’api native NtOpenFile et qui écrit dans c:\logfile.txt les noms des fichiers passés en paramètre.
Pour l’utiliser il faut d’abord injecter la dll dans le process choisit :
C:\\ProgHack\\c\\InlineHook>inject_dll notepad.exe c:\\proghack\\c\\InlineHook\\NtOpenFile_spy.dll
[*]Ownage du processus: notepad.exe
[*]Handle: 0x7f4
[*]CodeSize: 44
[*]Emplacement memoire: 0x3c0000
[*]Target injected
Après vous pouvez voir dans le fichier c:\logfile.txt les noms des fichers ouverts par le notepad.
Puis pour enlever le hook :
C:\ProgHack\c\InlineHook>unload_dll notepad.exe NtOpenFile_spy.dll
[*]Ownage du processus: notepad.exe
[*]Handle: 0x7f4
[*]Target injected
Voilà j’espère que j’ai été clair, sinon n’hésitez pas à mes poser de questions
Tout est dispo ici:
http://ivanlef0u.fr/repo/InlineHook.rar
Enjoy :}
février 10th, 2007