IrfanView 3.17

By Alien & Christal

Outils : Wdasm
Softice

Pour ne rien changer on commence par lancer wdasm ,on désassemble la bête et la horreur et stupéfaction : pas de référence.
Petit moment de réflexion j'ai un doute. Grâces au petit soft créé par Alsindor (asp) je trouve l'explication aspack est dans le coup. Ca c'est une mauvaise blague pour le news. Que faire, laisser tomber ou essayer de trouver une autre soluce, un coup d'śil sur about, le gars qui a fait le soft est étudiant a l'université technologique de vienne donc c'est une grosse tete, c'est pas gagné.
Pour le fun on va essayer de se le faire histoire de voir si on est beau avec une grosse tete.
Changement de méthode, on l'attaque avec Softice et le tut va comprendre deux parties :

1 : la compression que je laisse avec joie a Christal c'est lui l'artiste.
2 : le code c'est pour moi ( du moins j'espère )

c'est parti, boite d'enregistrement on rentre un nom et un code : alien 123456
ctrl+d, boum softice, pose du bp, bpx hmemcpy, F5 retour dans le soft clic sur ok, retour sous
softice et on trace.
Comme toujours on va trouver une analyse sur ce qui a été entré dans la boite d'enregistrement. Nombre de caractères pour le nom et pour le code.

004273ED  mov edx, [004CB594]............. edx = alien
00446518  lea edi, [esp+00001474]..........edi = 123456

Comme je n'ai pas les références sous wdasm pas de copier/coller donc je dois taper les références. Donc a vous de voir comment ca se passe car vous n'aurez pas pas la valeur de ebx au premier passage, faites comme moi, trace ( touche F8 on commence a la connaître et si vous avez déja des
crampes à l'index j'ai un truc ; on change de main )

00498713 lea ebx, [eax*2+esi-30].............ebx = 1E240 = valeur hexa de 123456

C'est déja une base on a trouvé quelque chose, c'est peu mais c'est un début qui nous donne un espoir pour la suite.
On arrive maintenant sur un truc qui tripote le nom entré, vérifions ca

:0042712E 0FBE0C32                movsx ecx, byte ptr [edx+esi]
:00427132 03D9                    add ebx, ecx
:00427134 8BFE                    mov edi, esi
:00427136 83C9FF                  or ecx, FFFFFFFF
:00427139 33C0                    xor eax, eax
:0042713B 42                      inc edx
:0042713C F2                      repnz
:0042713D AE                      scasb
:0042713E F7D1                    not ecx
:00427140 49                      dec ecx
:00427141 3BD1                    cmp edx, ecx
:00427143 7CE9                    jl 0042712E

Dans cette partie il prend la valeur hexa de chaque caractère du nom entré, e t les additionne. Au départ
Ebx = 0 et ecx = 61 ; la valeur finale de ebx sera 209.
Continuons a suivre cette ficelle pour arriver ici

:00427167 8D3448       lea esi, dword ptr [eax+2*ecx]
:0042716A C1E603       shl esi, 03             > esi = 44558 valeur décimale = 279896
:0042716D 56           push esi

Aurions nous trouvé notre bonheur, pour le savoir suffit de tester. On ferme tout, relance de irfan
entrée des données alien 279896 réponse incorrect registration ce qui est logique si le gars a utilisé
aspack ce n'est pas pour nous donner le code si facilement.
On peut donc continuer a tracer ( changer de main si crampes )
Je sais que je me répète mais il ne faut pas croire que tout ca vient facilement et je n'ai pas envie de taper toutes les lignes de code ; c'est au lecteur de ce tut de voir se qui se passe entre chaque découverte exposée ici.Ceci dit continuons.
Ce qui nous amène a ceci :

004A5784 cmp ecx, 09................ecx = 6

le code que nous avons entré comporte bien 6 caractères donc si ma pensée est juste nous cherchons un code qui comportera 9 caractères. Nous savons au moins pourquoi il nous a viré tantot.
C'est reparti pour un tour et on se retrouve ici :

00427173 add esp, 0C
on va faire une petite interogation :

d esp+10 résultat...........279896...dD

ca c'est du déja vu, mais pourquoi interroger justement esp+10 et pas autre chose, pour ceux qui ont
vus le film la septième compagnie c'est facile a comprendre. Que disait souvent l'autre con :
mais pas si vite la réponse va bientôt arriver.
On continue a tracer et on fait la même interrogation

0042718E mov [esp+16], cl..............d esp+10 = 2798969

00427196 mov [esp+18], al..............d esp+10 = 2798969.6

0042719E mov [esp+12], cl..............d esp+10 = 2778969.6

004271A6 mov [esp+13], al...............d esp+10 = 2779969.6

004271B0 mov [esp+15], dl...............d esp+10 = 2779989.6

004271F5 mov [esp+17], dl..............d esp+10 = 277998906

0042723F mov [esp+14], dl..............d esp+10 = 277928906

0042736C mov [esp+11], dl..............d esp+10 = 247928906

00427370 lea edx, [esp+10].............d esp+10 = 247928906


voila la réponse a la question posée plus haut, content ?
Petite comparaison, nous avions vu passer plus haut 279896 nous avons maintenant 247928906 ce qui fait bien cette fois 9 caractères.Ca y est maintenant c'est le bon code ! ! ! ! oui mais tantot on a été viré comme des cochons et comme c'est pas marrant on continue a tracer.
Oui je sais moi aussi j'ai des crampes et F8 donne des signes de faiblesses, encore un peu de courage la réponse approche.

0042737F cmp ebp, eax

ebp = 1E240................ = 123456
eax = EC7184A............. = 247928906


Et cette fois on ferme tout pour refaire le test d'enregistrement ; que nous dit la jolie boite ?

Registration successful !
Thanks

C'est ti pas beau tout ca, bien sur vu sous cet angle cela parait simple mais devant l'ensemble des lignes de code c'est une autre histoire.

Et voila le fichier ini dans le répertoire windows après l'enregistrement
[Others]
FileSortOrder=0
ResampleFilter=5
ResizeAspectRatio=1

[WinPosition]
xKoord=0
yKoord=0

[Registration]
Name=alien
Code=247928906


[Copy-Move]
OpenDir=C:\ANIMALS

[MRUD]
Dir1=
Dir2=C:\ANIMALS
Dir3=
Dir4=
Dir5=

[Effects]
UseResample=1


Conclusion
Je cours vite devant une glace pour voir comment je suis avec une grosse tête, ben je suis vraiment pas propre avec donc vite fait je la réduit.
Bien sur pour le news que je suis le plaisir est présent car malgré aspack j'ai bien baisé le gars mais que cela serve de lecon aux news qui liront ce tut, tête basse et humilité le vrai boulot c'est la partie compression et ca c'est Christal qui le fait, c'est lui l'artiste mais nous aurons-nous aussi un jour ce plaisir mais ca c'est une autre histoire.

A+

alien



Artiste, artiste, c'est vite dit…
Bon, on à quoi comme version d'ASPack ?

Une rapide recherche avec un hexéditeur…
Rien, juste l'un des noms de section, aspack

pour travailler dans de bonnes conditions, commençons par modifier les caractéristiques de la première section en remplaçant C00000040 par E0000020.
Avec cette nouvelle valeur, le programme va pouvoir se lancer via le Symbol Loader de Sice :
:004FB001  60                  PUSHAD           > entry Point
:004FB002  E870050000          CALL    004FB577  
:004FB007  EB4C                JMP     004FB055
:004FB009  0000                ADD     [EAX],AL
:004FB00B  0000                ADD     [EAX],AL
:004FB053  0000                ADD     [EAX],AL

Après le break sur l'Entry Point, où l'on voit que les registres sont sauvés, traçons into le call 004FB577

:004FB577  8B2C24              MOV     EBP,[ESP]
:004FB57A  81EDAB394400        SUB     EBP,004439AB
:004FB580  C3                  RET

ASPack utilise un mov EBP,[ESP] pour récupérer la valeur de retour après le call appelant, soit 004FB007, lui soustrait 004439AB, et place le résultat dans EBP. EBP prendra donc la valeur 004FB007 - 004439AB = 000B765C

Moralité :

La version écrite pas Alexey Solodovnikov, le concepteur d'ASPack, commençait en 004439AB. Pour pouvoir être utilisé avec un autre programme, il a sauvé la différence entre les adresses de son propre programme et celles du programme en cours(000B765C) et ainsi en faisant un [EBP+004439D5], il utilisera l'adresse 004439D5 (de sa version) + 000B765C (la différence entre sa version et le programme packé), pour se rendre à l'adresse " réelle " du programme passé à la moulinette ASPack. C'est ce que Pulsar avait appelé du " Code relogeable ". Au passage, il est intéressant de noter qu'ASPack utilise le registre ESP pour récupérer l'adresse de retour après le RET. Lors d'un Call, cette valeur est placée au sommet de la pile, et dans le registre ESP. Un POP EBP aurait pu lui avoir le même résultat, à ceci prés que le RET l'aurait envoyé sur l'adresse suivante pointée par la pile, c'est à dire dans la nature. Une autre solution aurait consisté à faire un :

PUSHAD                > entry Point
CALL    004FB007      > call sur la ligne suivante
POP     EBP           > dépile la valeur placée sur la pile (004FB007)
SUB     EBP,004439AB  > et soustrait à EBP, la valeur d'origine d'ASPack
JMP     004FB055

Donc ne soyez pas surpris de voir des

:004FB05C  2B9DD5394400        SUB     EBX,[EBP+004439D5]
:004FB062  83BD0448440000      CMP     DWORD PTR [EBP+00444804],00
:004FB069  899D04484400        MOV     [EBP+00444804],EBX

C'est le seul moyen pour que le programme ne se promène pas n'importe où dans le segment où se trouve le code et les datas du programme packé.

En traçant gentiment, on va vite trouver le premier passage de relais vers la seconde partie d'ASPack (compressé en 3 couches, comme chacun le sait) :

:004FB0B2  8D85723B4400        LEA     EAX,[EBP+00443B72]
:004FB0B8  FFE0                JMP     EAX
:004FB0BA  0000                ADD     [EAX],AL
:004FB0BC  0000                ADD     [EAX],AL

Eax reçoit la valeur de l'adresse à laquelle le JMP EAX va l'envoyer.
A tout fin utile, on peut poser un breakpoint en 004FB0B8.
En continuant à tracer, vous verrez encore des [EBP+adresse], preuve que vous êtes encore dans le loader d'ASPack, au cas ou vous n'auriez pas regardé le bas de la fenêtre des codes où le nom de la section en cours est affiché…

Rendu à cette adresse, le passage de relais vers l'entry point d'IrfanView, dans sa version originelle, et théoriquement clean, ce qui va éviter un traçage step by step fastidieux. Il y a juste à utiliser l'ascenseur de la fenêtre des codes de softIce, à la recherche d'un POPAD (le contraire de PUSHAD, et qui va restaurer les registres).

:004FB4F1  61                  POPAD
:004FB4F2  7508                JNZ     004FB4FC
:004FB4F4  B801000000          MOV     EAX,00000001
:004FB4F9  C20C00              RET     000C
:004FB4FC  6800000000          PUSH    00000000
:004FB501  C3                  RET

Bingo !
BPX en 004FB4F1, et F5 pour relancer la décompression.

POP !
Nous y voilà :

:004FB4DB  8B85763A4400        MOV     EAX,[EBP+00443A76]
:004FB4E1  50                  PUSH    EAX
:004FB4E2  038504484400        ADD     EAX,[EBP+00444804]
:004FB4E8  59                  POP     ECX
:004FB4E9  0BC9                OR      ECX,ECX
:004FB4EB  8985A13E4400        MOV     [EBP+00443EA1],EAX

ASPack récupère la valeur de EAX placée dans [EBP+00443A76]= 004FB0D2
Un coup d'śil de ce qui se trouve à cette adresse donne
80 8F 09 00.
Il est amusant de retrouver cette valeur avec un éditeur hexadécimal. L'original Entry Point (du moins son RVA) est en clair, non codé, dans les codes du programme :

00057CB0 4400 8D85 723B 4400 FFE0 0000 0000 0000 4000 0000
00057CC4 0000 0000 0000 0000 0000 DC8B 0B00 808F 0900 0000
00057CD8 0000 0000 0000 0010 0000 0066 0A00 0080 0A00 002A

[EBP+00444804] contient l'Imagebase du programme, soit 00400000, comme une très (très) grande majorité de softWare. Aprsè la ligne 004FB4E2, EAX contient la valeur exacte de l'OEP, soit 00400000 (imageBase) + 00098F80 (RVA) = 00498F80, l'OEP d'IrfanView.

Le MOV [EBP+00443EA1],EAX suivant va " patcher " l'adresse 004FB4FD (comparez les deux listings que j'ai pu donner de ces lignes), pour y placer la valeur de EAX et donner le jour à un PUSH 00498F80

:004FB4F1  61                  POPAD
:004FB4F2  7508                JNZ     004FB4FC
:004FB4F4  B801000000          MOV     EAX,00000001
:004FB4F9  C20C00              RET     000C
:004FB4FC  68808F4900          PUSH    00498F80
:004FB501  C3                  RET

L'OEP étant placé sur la pile, le RET qui suit va se brancher sur la dernière entrée de cette pile. C'est une simulation de retour sur call appelant qui va brancher vers la section .text d'IrfanView comme si ASPack avait fait un jump.

Il ne reste plus qu'à faire un DUMP de l'application décompressée, en remplaçant le RET par un JMP EIP (boucle sans fin), et à quitter SoftIce (F5) pour aller ouvrir ProcDump.

Option : Rebuilt Import Table
Sélection du programme dans la fenêtre des tâches par un clic-droit
Dump Full
Kill Task
Et remplacement de l'EntryPoint d'ASPack par 098F80.

Glop ! Glop !
Vous avez un zoli Dump avec toutes les ressources…

Voyons ce que va donner la recherche du code de IrfanView en dead listing :

:00446597 E8640BFEFF              call 00427100   > call contrôle du code
:0044659C 83C408                  add esp, 00000008
:0044659F 85C0                    test eax, eax   > EAX=1 -> good Boy
:004465A1 752C                    jne 004465CF    > registration Successful

* Possible StringData Ref from Data Obj ->"Incorrect registration !"
                                  |
:004465A3 A138F94B00              mov eax, dword ptr [004BF938]

Que ce soit en partant de la String Data = "Incorrect registration " ou de " registration successful ", dans les deux cas on retombe sur le call 00427100

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004465A1(C)
|
:004465CF 8B3590814A00            mov esi, dword ptr [004A8190]
:004465D5 8D942474130000          lea edx, dword ptr [esp+00001374]

· Possible StringData Ref from Data Obj ->"I_VIEW32.INI"
· Inscrit les infos Name et serial dans le fichier INI
                                  |
:004465DC 6878DF4B00              push 004BDF78
:004465E1 52                      push edx

* Possible StringData Ref from Data Obj ->"Name"
                                  |
:004465E2 6848E14B00              push 004BE148

* Possible StringData Ref from Data Obj ->"Registration"
                                  |
:004465E7 6838E14B00              push 004BE138
:004465EC FFD6                    call esi
:004465EE 8D842474140000          lea eax, dword ptr [esp+00001474]

* Possible StringData Ref from Data Obj ->"I_VIEW32.INI"
                                  |
:004465F5 6878DF4B00              push 004BDF78
:004465FA 50                      push eax

* Possible StringData Ref from Data Obj ->"Code"
                                  |
:004465FB 6830E14B00              push 004BE130

* Possible StringData Ref from Data Obj ->"Registration"
                                  |
:00446600 6838E14B00              push 004BE138
:00446605 FFD6                    call esi

* Possible StringData Ref from Data Obj ->"Registration successful !"
                                  |
:00446607 8B0D3CF94B00            mov ecx, dword ptr [004BF93C]
:0044660D 8B1520584D00            mov edx, dword ptr [004D5820]
:00446613 6A40                    push 00000040

On va dans le call contrôle du code.
La seule comparaison significative qui y est faite est à la fin du call :

:0042737F 3BE8                    cmp ebp, eax
:00427381 5F                      pop edi
:00427382 5E                      pop esi
:00427383 0F94C1                  sete cl
:00427386 5D                      pop ebp
:00427387 8BC1                    mov eax, ecx
:00427389 5B                      pop ebx
:0042738A 83C414                  add esp, 00000014
:0042738D C3                      ret

Autant vous dire qu'il est aussi bien d'abandonner le Dead Listing pour passer en Live Approach :

BPX sur l'adresse 0042737F
EBP votre serial entré en Hexa
EAX, le bon serial en hexa

Un " ? EAX " vous donne la correspondance en décimal, il ne reste plus qu'à rentrer le code. 

Bonne Journée

Christal