CrackMe 02 de Chronos par Kharneth | |||
---|---|---|---|
Outils utilisés | Public | Cible | |
- PEId - SmartCheck - Exdec - OllyDbg - Calculatrice - Papier, Crayon, Cerveau 5.0 | Débutant en Cracking ayant de bonnes connaissances en programmation |
CrackMe02_Chronos | |
1 - PEId | |||
Une petite analyse de PeId pour vérifier que le programme n'est pas compressé ou crypté.
Il ne l'est pas. Par contre on voit qu'il a été compilé avec Visual Basic 5.0. | |||
2 - SmartCheck | |||
On lance SmartCheck et on charge le programme avec Ctrl+o. De retour dans SmartCheck, on double-click sur l'événement _Click, et on ne voit que la MsgBox... Pas bon! :o( On se démonte pas, on sélectionne la MsgBox puis on click sur le bouton "Show All Events". On parcours chaque ligne en surveillant la fenêtre de droite mais la seule ligne intéressante est varR8FromStr qui convertie notre chaîne en Réel. On remarque aussi que toutes les adresses données par SmartCheck sont dans la dll. Il va donc falloir regarder plus profondément en utilisant OllyDbg. Avant de se lancer, il faut comprendre comment fonctionne le P-Code. | |||
3 - P-Code | |||
Un programme compilé en P-code utilise une machine virtuelle (MSVBVM60.DLL ou 50 suivant la version de VB) qui charge les opcodes pour les interpréter à l'exécution. Chaque fonction utilisée dans un programme VB possède un numéro identifiant. Lorsque le programme est compilé, c'est ce numéro qui est écrit à la place des instructions ASM classiques. Puis quand on l'exécute, le moteur est chargé en mémoire et lit la liste d'opcode en exécutant les fonctions correspondantes, au fur et à mesure. Ces opcodes étant propres à VB, le debugger ne sait pas les traduire et les affiche tel quel:
Les opcodes sont codés sur 8 bits et offrent donc 256 fonctions différentes. En réalité, il en existe pas loin de 1500! En fait, les 5 dernières valeurs, 0xFB à 0xFF sont réservés pour spécifier une nouvelle table offrant 256 nouvelles fonctions. Par exemple, dans le listing ci-dessus, pour accéder à la fonction CR8Str, le moteur lit l'opcode 0xFC à l'adresse 00402AD2, voit qu'il doit utiliser la table Lead1, puis lit l'opcode suivant, 0x33 à l'adresse 00402AD3, correspondant à la fonction dans la nouvelle table. Nous avons donc la table de base plus les 5 tables Lead0 à Lead4. Les opcodes servent à déterminer l'adresse de la fonction dans la dll.
Ceci est la fonction MulR8, son opcode est 0xB3 et elle ne prend aucun paramêtre. Toutes les instructions avant XOR EAX, EAX sont propres à la fonction. Ici on voit que cette fonction multiplie 2 réels entre eux stockés dans ST0 et ST1. Ensuite, toutes les fonctions respectent le schéma suivant: | |||
4 - Exdec | |||
Proc: 402b90 402AB4: 00 LargeBos 402AB6: 00 LargeBos 402AB8: 4b OnErrorGoto 402ABB: 00 LargeBos 402ABD: 04 FLdRfVar local_008C 402AC0: 21 FLdPrThis 402AC1: 0f VCallAd text 402AC4: 19 FStAdFunc local_0088 402AC7: 08 FLdPr local_0088 402ACA: 0d VCallHresult get__ipropTEXTEDIT 402ACF: 6c ILdRf local_008C 402AD2: Lead1/33 CR8Str 402AD4: f3 LitI2: 0x29a 666 (..) 402AD7: eb CR8I2 402AD8: b3 MulR8 402AD9: Lead2/6b CVarR8 402ADD: Lead1/f6 FStVar local_009C 402AE1: 2f FFree1Str local_008C 402AE4: 1a FFree1Ad local_0088 402AE7: 00 LargeBos 402AE9: Lead3/c1 LitVarI4: ( local_61FF00AC )0x1c9e00 (1875456) 402AF1: Lead1/f6 FStVar local_00BC 402AF5: 00 LargeBos 402AF7: 04 FLdRfVar local_009C 402AFA: 04 FLdRfVar local_00BC 402AFD: 28 LitVarI2: ( local_00AC ) 0x2 (2) 402B02: Lead0/b4 MulVar 402B06: Lead0/33 EqVarBool 402B08: 1c BranchF: 402B46 402B0B: 00 LargeBos 402B0D: 27 LitVar_Missing 402B10: 27 LitVar_Missing 402B13: 27 LitVar_Missing 402B16: f5 LitI4: 0x0 0 (....) 402B1B: 3a LitVarStr: ( local_00AC ) Bravo, tu peu aller
Voici le début du listing généré par Exdec, la fin n'étant pas intéressante. Les adresses indiquées sont les mêmes que dans le debugger. On peut donc mettre un point d'arrêt sous OllyDbg (Memory On Access) à l'adresse voulue puis tracer dans la dll pour étudier ou suivre l'exécution d'une fonction. Lorsque le moteur lira l'opcode, l'exécution du programme s'arrètera au début de la fonction. | |||
Kharneth | |||
Ride the snake, ride the snake To the lake, the ancient lake, baby | |||