OllyDead By Synapsus par Kharneth | |||
---|---|---|---|
Outils utilisés | Public | Cible | |
- OllyDbg 1.10 - www.Google.com - Papier, Crayon, Cerveau 5.0 | Débutant avancé en Cracking ayant de bonnes connaissances en programmation | OllyDead.exe | |
1 - Introduction | |||
Il faut trouver la seule et unique date à laquelle le programme veut bien afficher le message de félicitations. Avant de commencer, quelques précisions: | |||
2 - OllyDbg | |||
On commence par tracer dès le début du programme et les choses sérieuses commencent rapidement avec une utilisation très particulière de l'api lstrcpy qui va faire office de JMP. D'abord, la chaine "NGEN" est remplacée par les caractères {0xD7, 0x13, 0x40, 0x00} correspondant à l'adresse sur laquelle on veut sauter. C'est la chaine à copier. ![]() Voici une capture de la pile pour comprendre que String2 va être copiée dans String1 et ainsi remplacer l'adresse de retour de l'api(004010C1) par 004013D7. ![]() On arrive donc en 004013D7 sur un code illisible qui correspond en fait à une boucle qui va décrypter la suite du code. (Lorsque le code est rempli de CCA, je trace tranquillement avec F7 en surveillant l'exécution). Voici cette boucle une fois nettoyée: ![]()
On continue à tracer jusqu'en 004016B8 ou le NOP précédent est remplacé par un RETN. On verra plus tard que cette boucle sera exécutée une nouvelle fois pour recrypter le code. ![]() Finalement, le service est détruit tout comme le fichier temporaire. Puis, le programme retourne en 004013D7 au début de la boucle de cryptage pour recrypté le code qui vient d'être exécuté. Mais cette fois, le RETN à la fin de la boucle nous envoie en 004010C1, juste après le lstrcpy du début! Ensuite, l'interface est créée de manière classique, mais "l'évènement" WM_CREATE contient ce code: ![]() La variable qui va déterminer l'enregistrement du programme se situe en 0040626F et doit contenir la valeur 0x57. On voit que cette variable est remplie en 004017D5 par la valeur de retour de l'api GetLastError, elle-même déterminée par l'api StartServiceA. Il devient donc évident que le service contient une fonction qui va vérifier la date de l'ordinateur puis la comparer à la date attendue. Et enfin générer une erreur de type 57h == 87d == ERROR_INVALID_PARAMETER. | |||
3 - Crackme.sys | |||
Pour les raisons évoquées en Introduction, ce qui suit peut sembler être (est) du bricolage. ![]() Quand à la 2ème, c'est justement la fonction de vérification de la date! Elle va lire le jour, le mois et l'année dans l'horloge interne (RealTimeClock) à l'aide du code suivant: ![]() Ce code est exécuté 4 fois, la valeur mise dans AL déterminant quelle information est récupérée, 7 pour le jour, 8 pour le mois, 32h pour le siecle et 9 pour l'année. Le résultat est une chaine de caractères de la forme: "11062004" pour le 11 juin 2004 par exemple. Ensuite cette chaine est cryptée avec le code réversible suivant: ![]() Finalement, le résultat est comparé à la chaine hexa B310AE1162136611. Si les 2 chaines sont différentes, la valeur 0xC0000010 est placée en 104A4. ![]() Au début du programme, on voit que l'adresse contient la valeur 0xC0000182. ![]() De plus, la valeur contenue à cette adresse est renvoyée lorsque le service quitte. ![]()
Une rapide recherche nous indique ceci: BSWAP ( NOT ( ( 136210B3 - 29A ) XOR DEADC0DE ) ) = 38313032 BSWAP ( NOT ( ( 116611AE - 29A ) XOR DEADC0DE ) ) = 35303430 Pour vérifier, on lance une fenêtre d'invité de commande et on tape "date 18.05.04" pour modifier la date du système. Puis on lance le Crackme et voilà ce qui apparait: ![]()
| |||
Kharneth | |||
The killer awoke before dawn, he put his boots on | |||
![]() |