
			-----------------------------------
			 Immortal Descendants CrackMe 6.0
			          (par TORN@DO)
			Tutorial de Lucifer48, 18 juin 1999
			-----------------------------------


=====================
1. APPROCHE THEORIQUE
=====================

On observant attentivement la structure de l'exe on dcouvre plusieurs choses.
Premire observation: il y a six segments 'suspects': .CRYP, .ID60, http://L, EARN2CR, RK.CBJ., NET.
Les quatre segments .CRYP, http://L, EARN2CR, RK.CBJ. ont mme taille (remarque: a me fait penser
 l'enpacketage de 'idcrkme40', avec plusieurs segments nomms .Stone)
Premiere certitute: le crackme est pack plusieurs fois avec un mme packer (appellons le
PACKER #2). Ce packer rajoute un nouveau segment  la fin de l'exe qui contient les informations
ncessaires pour le dcompactage (comme pour Stone's PE Encrypter 1.13 dans idcrkme40.exe).
Deuxime observation: .ID60 et NET ont mme taille (Phys size & Virt size), apparament un autre
packer (appellons le PACKER #1), utilis  deux reprises.
Troisime observation: entrypoint: RVA: 00019319h
Le "319", a vous dit rien ???? Ne serait-ce pas la taille d'un segment pack via PACKER #2.
On y voit plus clair: le PACKER #1 se recopie  la fin du dernier segment (augmente la taille),
et crypte l'exe (nous allons voir o et comment aprs).

Finalement: on a le schma suivant:
  exe initial (unpacked)
+ crypte 2 fois avec PACKER #2
+ crypte 1 fois avec PACKER #1
+ crypte 4 fois avec PACKER #2
+ crypte 1 fois avec PACKER #1
------------------------------
= idcrkme60.exe


=====================
2. ETUDE DU PACKER #1
=====================

On charge le crackme avec le symbol loader, EAX=00419319, c'est le dbut (la premire instrcution)
(entrypoint en anglais).

XXXX:00419319  PUSHFD                           ;sauvegarde des flags dans la pile (occupe 32 bits)
XXXX:0041931A  PUSH EBP
XXXX:0041931B  CALL 0041940C                    ;pas interessant (call trs court)
XXXX:00419320  XCHG EDX,EBP
XXXX:00419322  POP  EBP
XXXX:00419323  PUSHAD                           ;sauvegarde des registres
XXXX:00419324  XCHG EDX,EBP                     ;ebp=00016CFE
XXXX:00419326  CMP  BYTE PTR [EBP+00412715],01
XXXX:0041932D  JZ   00419368                    ;(no jump)
XXXX:0041932F  MOV  BYTE PTR [EBP+00402715],01
XXXX:00419336  JMP  0041941F

on continue:

XXXX:0041941F  CALL 0041943F
XXXX:00419424  MOV  ESP,[ESP+08]
XXXX:00419428  CALL 0041940C                    ;pas interessant (call trs court)
XXXX:0041942D  MOV  BYTE PTR [EBP+004026CC],C3
XXXX:00419434  CALL 00419384                    ;ICI, call  explorer absolument!! (*)
XXXX:00419439  JMP  00419354

(*) Ce call est incontournable, puisque c'est ici prcisment que se passe le dcompatage/dcrytage
des diffrents segments du programme.

XXXX:00419384  LEA  EDI,[EBP+004026CD]         ;offset RVA (c'est un "tableau" de plusieurs RVA)
XXXX:0041938A  MOV  ESI,[EDI]                  ;RVA        (voir remarque)
XXXX:0041938C  OR   ESI,ESI                    ;si ESI=0 on a tout fini de dcompacter
XXXX:0041938E  JZ   004193C1
XXXX:00419390  ADD  ESI,[EBP+0040270D]         ;ajoute l'image base (00400000)
XXXX:00419396  MOV  ECX,[EDI+04]               ;taille de la zone  unpacker (Phys size)
XXXX:00419399  PUSH EDI
XXXX:0041939A  MOV  EDI,ESI
...
dcompacte 32 bits par 32 bits (ADD / XOR / ROR / SUB)
...
XXXX:004193B5  STOSD                           ;<=> MOV [EDI],EAX / ADD EDI,4
XXXX:004193B6  SUB  ECX,04
XXXX:004193B9  JAE  004193A6                   ;tant que ecx n'est pas nul, on continue
XXXX:004193BB  POP  EDI
XXXX:004193BC  ADD  EDI,08                     ;on va dcompacter la zone suivante
XXXX:004193BF  JMP  0041938A                   ;retour, ci dessus
XXXX:004193C1  RET                             ;fin du call 00419384

Remarque:
-----IDCRKME60!NET+03C2---------------------------byte--------------PROT---(0)--
XXXX:004193C2 00 10 00 00 08 0A 00 00-00 40 00 00 10 03 00 00  .........@......
XXXX:004193D2 00 30 01 00 19 03 00 00-00 40 01 00 00 06 00 00  .0.......@......
XXXX:004193E2 00 60 01 00 19 03 00 00-00 70 01 00 19 03 00 00  ..`......p......
XXXX:004193F2 00 00 00 00                                      ....
---------------------------------------------------------------------------------

On retrouve les tailles (Phys size) et les adresses des differents segments, qui sont tour 
tour dcompacts. Peut-tre qu'un tableau sera plus clair:

RVA       Phys size    Name
00401000    A08        .text           ;premire boucle
00404000    310        .data           ;seconde boucle
00413000    319        .CRYP           ;troisime boucle
00414000    600        .ID60           ;quatrime boucle
00416000    319        http://L        ;cinquime boucle
00417000    319        EARN2CR         ;sixime boucle

on a arrive  la fin du packer (fin assez classique):

XXXX:00419374  POPAD                           ;restaure tous les registres
XXXX:00419375  POPFD                           ;restaure tous les flags
XXXX:00419376  MOV  EBX,[EDX+00402709]         ;EBX=00419000 (segment NET)
XXXX:0041937C  MOV  [EDX+00402709],ECX
XXXX:00419382  JMP  EBX                        ;fin de PACKER #1

Tout ce passe donc comme prvu, le PACKER #1, a fait son travail et il passe donc la main au
PACKER #2.


=====================
3. ETUDE DU PACKER #2
=====================

Il dbute de la sorte:

XXXX:00419000  PUSH EBP
XXXX:00419001  PUSH EDI
XXXX:00419002  PUSH ESI
XXXX:00419003  PUSH EDX
XXXX:00419004  PUSH ECX
XXXX:00419005  PUSH EBX
XXXX:00419006  CALL 0041900B
XXXX:0041900B  POP EBP                            ;bonne astuce pour rcuprer l'adresse

on continue:

XXXX:00419025  CALL 004190C3
XXXX:0041902A  CMP  DWORD PTR [EBP+0040378F],00   ;nous avons [EBP+0040378F]=0 
XXXX:00419031  JZ   0041907F                      ;jmp = quitte le programme, pas de dcompactage
XXXX:00419033  SUB  EDX,[EBP+00403655]
XXXX:00419039  SUB  EDX,0B
XXXX:0041903C  MOV  [EBP+0040365D],EDX            ;sauvegarde l'image base (ici: 00400000)
XXXX:00419042  MOV  ESI,004037B7                  ;petit buffer de 8*32 bits
XXXX:00419047  ADD  ESI,EBP                       ;buffer situ dans le segment courant (NET)
XXXX:00419049  PUSH ESI
XXXX:0041904A  CALL [EBP+00403793]                ;CALL [KERNEL32!GetLocalTime]
XXXX:00419050  CMP  WORD PTR [EBP+004037B9],01    ;mois
XXXX:00419058  JB   0041908B                      ;saut vers la routine de dcompactage
XXXX:0041905A  CMP  WORD PTR [EBP+004037B7],07D0  ;anne
XXXX:00419063  JB   0041908B                      ;saut vers la routine de dcompactage
XXXX:00419065  MOV  EAX,00403769
XXXX:0041906A  ADD  EAX,EBP                       ;d EAX: "Ding Boy's PE-lockv0.07    1999-2000"
XXXX:0041906C  MOV  EBX,004037F9
XXXX:00419071  ADD  EBX,EBP                       ;d EBX: "  " (deux espaces)
XXXX:00419073  PUSH 00                            ;MB_OK
XXXX:00419075  PUSH EAX                           ;offset texte
XXXX:00419076  PUSH EBX                           ;offset titre
XXXX:00419077  PUSH 00                            ;pas de handle
XXXX:00419079  CALL [EBP+0040378F]                ;CALL [USER32!MessageBoxA]
XXXX:0041907F  MOV  EAX,FFFFFFFF                  ;quitte prmaturment le programme

Quelques explications: le call 004190C3, sert  initialiser les adresses systmes, en effet,
PACKER #2, peut avoir  utiliser CALL [KERNEL32!GetLocalTime] et CALL [USER32!MessageBoxA],
et c'est le rle du call 004190C3 de trouver ces adresses. Trois cas sont possibles:
* tout ce passe bien, on a trouv les adresses => on saute vers la procdure de dcompactage
* Nous sommes en l'an 2000, on recoit une messagebox, le dcompactage n'a pas lieu.
* Pour une raison inconnue, PACKER #2 n'a pas russi  trouver les adresses, l encore le
  dcompactage n'a pas lieu.


Dans notre cas, c'est la dernire proposition, le programme quitte. Mais nous, on veut
dcompacter l'exe, donc on va passer  travers le JZ 0041907F, allez jusqu'en XXXX:00419042
et faire dans soft-ice r eip=0041908B, pour sauter dans la routine de dcompactage.
Remarque: evidement, il ne faut pas tenter d'executer les call qui appellent l'api, car on
obtiendrait immdiatement une GPF (General Protection Fault).

Voil la procdure de "dcompactage"

XXXX:00419092  CMP  DWORD PTR [ESI],00            ;y'a-t-il encore un segment  dcompacter ?
XXXX:00419095  JZ   004190AD                      ;si oui => (no jump)
XXXX:00419097  MOV  EBX,[EBP+0040365D]            ;00400000
XXXX:0041909D  ADD  EBX,[ESI]
XXXX:0041909F  MOV  ECX,[ESI+04]                  ;taille de la zone
XXXX:004190A2  SUB  BYTE PTR [EBX],01             ;"dcompactage": trs trs simple!
XXXX:004190A5  INC  EBX                           ;on y a va octet par octet
XXXX:004190A6  LOOP 004190A2                      ;boucle
XXXX:004190A8  ADD  ESI,08                        ;[ESI+0]: RVA, [ESI+4]: size
XXXX:004190AB  JMP  00419092                      ;boucle
XXXX:004190AD  MOV  EAX,[EBP+00403659]            ;00018000
XXXX:004190B3  MOV  EBX,[EBP+0040365D]            ;00400000
XXXX:004190B9  ADD  EAX,EBX                       ;00418000 (RK.CJB.)
XXXX:004190BB  POP  EBX
XXXX:004190BC  POP  ECX
XXXX:004190BD  POP  EDX
XXXX:004190BE  POP  ESI
XXXX:004190BF  POP  EDI
XXXX:004190C0  POP  EBP
XXXX:004190C1  JMP  EAX                           ;fin de PACKER #2

La procedure de dcompactage est trs simple...


=================
4. PHASE PRATIQUE
=================

Il est maintenant temps de dcompacter le crackme.

 Debut         Fin         Segment      Owner               Segments dcompacts
00419319  *  00419382  *  NET       *  PACKER #1  *  .text .data .CRYP .ID60 http://L EARN2CR
00419000  *  004190C1  *  NET       *  PACKER #2  *  .text .data
00418000  *  004180C1  *  RK.CJB.   *  PACKER #2  *  .text .data
00417000  *  004170C1  *  EARN2CR   *  PACKER #2  *  .text .data
00416000  *  004160C1  *  http://L  *  PACKER #2  *  .text .data
00414319  *  00414382  *  .ID60     *  PACKER #1  *  .text .data .CRYP .ID60
00414000  *  004140C1  *  .ID60     *  PACKER #2  *  .text .data
00413000  *  004130C1  *  .CRYP     *  PACKER #2  *  .text .data
004011CB  <--- dvinez ce que c'est!!!

Quand vous arrivez  la fin de la derniere procdure de dcompactage (XXXX:004130C1 JMP EAX);
n'oubliez pas de dumper le processus.... (sous soft-ice, tapez A puis JMP EIP afin de mettre
le programme dans une boucle infinie, appuyer sur F5, et lancer Procdump).

N'oublier pas de changer l'entrypoint (11CB) dans l'exe. Le crackme est dcompact!!!!!


================================
5. RE-ENABLER LE BOUTTON REQUEST
================================

Les fentres sont cres avec l'appel  "DialogBoxParamA", donc il faut jeter un coup d'oeuil
du cte de la "dialog box procedure", juste avant la vrification si on a clicke sur un boutton
(message WM_COMMAND = 0111h), on voit un autre message: WM_INITDIALOG (= 0110h) qui comme son
nom l'indique... on appercoit donc l'appel  EnableWindow, mais un peu avant, il y a ceci:

:004012E9 837DFC00                cmp dword ptr [ebp-04], 00000000
:004012ED 7515                    jne 00401304

si [ebp-04]=0 alors le programme disable le boutton (de la fentre principale).
Donc changer JNE => JMP
Un peu plus loin:

:00401379 837DFC00                cmp dword ptr [ebp-04], 00000000
:0040137D 751C                    jne 0040139B

mme chose, ici! 

Remarque: si vous ne changer que le premier JNE, alors le boutton apparaitra bien enabl mais
n'activera rien du tout, la creation de la bote de dialogue "Request" ne se fera pas.


=============
6. CONCLUSION
=============

Voil pour ce crackme! Que dire de plus...
Greetings: TORN@DO (of course, for his crackme), Volatility (will we work together ?),
           Eternal Bliss (for his site), MiZ (what a good essay for idcrkme5.0), ACiD BuRN,
           and others people i forgot.


Lucifer48
