StarForce 4.70.X ou l'ami du poly
Par Baboon le mercredi, février 4 2009, 14:58 - Lien permanent
Salut les zouaves
J'ai eu récemment l'occasion d'étudier un programme protégé par StarForce 4.70.X cette version de StarForce à l'air d'être conçue spécialement pour les logiciels contrairement a StarForce 3 qui lui visait surtout les jeux. Cette version donc est beaucoup moins robuste que celle utilisée pour les jeux, pas de drivers, pas de VM, pas de stolen bytes, pas de code redirigés MAIS une protection des imports pas mal foutue. J'exposerai donc dans ce post la technique que j'ai utilisée pour rebuild tout ca ...
Il y a 2 grandes familles de protection des imports, la redirection vers un code se chargeant de retrouver l'API correspondante à partir de l'adresse de retour de l'appel (Obsidium par exemple) et la redirection vers une page mémoire allouée dans laquelle le protector va placer les instructions de l'API polymorphisées / junkées (Asprotect -Asprotect utilise les 2 techniques en fait mais bon ..-) c'est cette deuxième famille qu'implémente StarForce.
Généralement lorsque l'on a affaire à ce type de protection, on cherche l'endroit où est polymorphisé le code de l'API et on a directement l'adresse de l'API ce qui se fait assez bien par exemple avec Asprotect le hic c'est que la partie du code de StarForce qui se charge de cette opération est particulièrement junké et longue il a donc fallut trouver une autre solution.
Pour retrouver l'API correspondant aux instructions polymorphisées il suffit simplement de dé-polymorphiser le code et de rechercher un code semblable dans les DLLs loadées reste "juste" à réussir à dé-polymorphiser :D
StarForce contrairement aux protections que j'ai déjà eu l'occasion d'étudier ne se contente pas de junker les X premières instructions ou s'arrêter au premier jmp / call, il va polymorphiser TOUT le code de l'API y compris le code situé dans une boucle, les différentes branches d'un saut etc. de plus il utilise 18 règles de poly différentes ce qui complique un peu la tache ...
Heureusement, j'avais commencé quelque temps auparavant à coder un désassembleur spécialisé dans l'étude de code (il ne retourne qu'une structure détaillant l'instruction et non une string) ce qui m'a été bien utile :p car une fois isolé les règles de poly il a suffit de coder une fonction pour éliminer chacune de ces règles.
Les règles de poly de StarForce sont juste ici :
LEA R32 , [R32 + X] LEA R32 , [R32 + 0x100000000 - X] = NOP ********************************** LEA ESP , [ESP - 4] MOV [ESP] , X = PUSH X ********************************** XCHG R32a , R32b PUSH R32b XCHG R32a , R32b = PUSH R32a ********************************** XCHG R32a , R32b XCHG R32b , R32a = NOP ********************************** XCHG R32a , R32b XCHG R32c , R32a XCHG R32c , R32b XCHG R32c , R32a = NOP ********************************** PUSH R32a MOV R32a , X XCHG [ESP] , R32a = PUSH X ********************************** PUSH X POP Y = MOV Y , X(avec X ou Y qui ne sont pas du type [X] ) ********************************** CMC CMC = NOP ********************************** MOV / XCHG R32a , R32a = NOP ********************************** LEA R32a , [R32a] = NOP ********************************** NOP = NOP(tu m'en diras tant baboon !) ********************************** CALL &+5 XCHG [ESP],EAX LEA EAX,[EAX+F] XCHG [ESP],EAX PUSH X RETN = CALL X ********************************** XCHG [ESP] , R32a LEA ESP , [ESP+4] = POP R32a ********************************** MOV R32 , [ESP] LEA ESP , [ESP+4] = POP R32a ********************************** PUSH R32a PUSH X MOV R32a , [ESP] XCHG [ESP+4] , R32a LEA ESP , [ESP+4] = PUSH X ********************************** PUSH X INSa [instruction ne modifiant et n'utilisant pas esp] LEA ESP , [ESP+4] = INSa ********************************** XCHG Xa , Xb MOV Xb , Xa = MOV Xa , Xb ********************************** PUSH R32a XCHG [ESP] , R32a = PUSH R32a **********************************
Vous remarquerez la règle de poly "PUSH X | INSa | LEA ESP , [ESP+4]" <=> "INSa" avec INSa ne modifiant pas esp qui impose d'avoir un désassemblage avancé de l'instruction, ce genre de polymorphisme est amha le poly du futur ! les dépendances inter-instructions permettent de polymorphiser du code bien plus efficacement que lorsqu'on se contente de travailler instruction par instruction.
Comme je vous l'ai dit StarForce polymorphise TOUTES les instructions des APIs y compris les sauts j'ai donc choisis lorsque je désassemble le code polymorphisé de toujours suivre les sauts inconditionnel et de ne pas suivre les conditionnels
Ensuite pour la comparaison avec les APIs des DLLs loadées j'ai utilisé un de mes anciens code servant à parser l'export table, ce code va se charger, à l'initialisation du call fixer, de rechercher toutes les DLLs loadées, pour chaque DLL il va parcourir la table des imports, désassembler et dépolymorphiser les 20 premières instructions de l'API (les mov edi , edi étant considérés comme du junk par mon dé-polymorphiseur, il faut les supprimer des listings des APIs), à chaque instruction le pointeur vers cette instruction est vérifié (les DLLs exportant parfois des variables, il peut arriver que mon désassembleur en suivant un saut atterrisse à une adresse invalide) si l'instruction désassemblée est un retn ou n'est pas reconnue par mon désassembleur le désassemblage s'arrête enfin toutes ses informations sont stockées dans une liste chainée de structures.
voila le fonctionnement globale de mon call fixer :
- desassemble les 20 premières instructions de toutes les APIs des DLLs présentes
- pour chaque entrée de l'IAT :
- si l'adresse ne correspond pas à une API ou si elle n'est pas nulle :
- desassemble et dépolymorphise les 20 premières instructions
- compare ces instructions à toutes celles des APIs listées
- si pas de correspondance trouvée ou si on trouve plus d'une correspondance on affiche un message d'erreur
- retour à l'etape 1
- tout est fixé alors on mange un bonbon
voili voilou :D
J’espère que ce petit article vous donnera envie de vous frotter un peu aux codes junkés / polymorphisé et que grâce à cela vous deviendrez riches et célèbres
Le code de mon call fixer ainsi que celui de mon désassembleur sont disponibles ICI, mon désassembleur n'est pas fini et n'est pas exempt de bugs enfin (une fois n'est pas coutume) ces codes sont distribués sous la licence Creative Commons suivante :
Dernière chose : prière aux zozos de ne pas utiliser mes codes pour se faire mousser en rlzant des cracks de logiciels ….
Commentaires
Nice work ! T'as du en chier pour faire tout ça !
C'est du bon boulot baboon. Voila une utilisation intéressante des outils de désassemblage. As-tu une adresse mail pour qu'on discute un tout petit peu de la licence que tu poses sur ton code source parce que il y a comme qui dirait un chti problème
Oui bien sur :
baboon hat lyua pouin org
Bravo babs
(à quand la version pour les jeux :-?)
moi je le repete, tu vas finir sataniste dans une team de satanistes qui font du gamez
nice work !
ahah
c'est deja le cas avec la fat !
L'ours vaincra !
Hi!!! excellent post!!!
I can't download the dissasembler
Could you send it to my mail?
Thanks!!
PD: If i can, I will write something about your post in my blog team.
Hi Spark
Sources' link is broken and I've loose my code :/
You can get my disassembler source in next post with my starforce imprec plugin (http://baboon.rce.free.fr/index.php...)
Remember that my disassembler is a beta version and will not be updated (you can use Beatrix's Disasm engine => http://beatrix2004.free.fr/tools.ht...)
Thanks for your comment and your future post in your blog