|
Jpeg Optimizer 3.50 |
|
Written by:
|
|
A propos de la protection: Serial protection .... |
| Le Tut... |
|
Salut les gars! :) :004290ED 8D95BCFEFFFF lea edx, dword ptr [ebp+FFFFFEBC] :004290F3 8B0D84484800 mov ecx, dword ptr [00484884] :004290F9 A1D8494900 mov eax, dword ptr [004949D8] :004290FE E845DD0300 call 00466E48 -> le Bug ! C good? * RefereNced by a (U)NcoNditioNal or (C)oNditioNal Jump at Address: |:00428F70(C) -> saut qui doit perm&tre d'éviter d'aller eN "code iNvalide" :00428F68 E8F3FC0100 call 00448C60 :00428F6D 59 pop ecx :00428F6E 84C9 test cl, cl > si cl = 0 :00428F70 0F8440010000 je 004290B6 > saute eN code iNvalide BoN tu peux essayer de patcher de suite toN prog, mais faudrait d'abord
êtes sur Ke t'es pas seulemeNt eN traiN de dérouter l'affichage code valide/code iNvalide, mais Ke
t'as fait uN crack vrai de vrai, & qu't'es pas uN bourriN! :00428F48 52 push edx > le code KoN a eNtré :00428F49 E8FE0B0000 call 00429B4C > à visiter! :00428F4E 59 pop ecx > vire ecx de la pile :00428F4F 84C0 test al, al > test AL :00428F51 7504 jNe 00428F57 > si al=0 alors eax=0 :00428F53 33C0 xor eax, eax > le code est faux :00428F55 EB05 jmp 00428F5C > va vers l'aut call :00428F57 B801000000 mov eax, 00000001 > si eax=1 c good!
:00429BD8 84C0 test al, al > al = 0 ? :00429BDA 7404 je 00429BE0 > si oui va eN 9BEA :00429BDC B001 mov al, 01 > si NoN, AL=1 :00429BDE EB0C jmp 00429BEC > évite le xor eax, eax :00429BE0 poa la place mov dword ptr [00484888], 9603BCEB :00429BEA 33C0 xor eax, eax > m& EAX à 0 BeN j'espère Ke tu compreNds ce ke ça veut dire? J'espère Ke t'auras appris qque chose en lisaNt ce texte. Allez @+ |
|
Hello D.LiriUm
TrèS MinCe, > The Registered Version enables batch processing ie compressing multiple files at one time. · Time
limit, n'empéchant pas le programme de fonctionner, mais ajoutant
le nombre de jours de "retard" dans l'acquittement de la contribution
due, dans le bandeau d'écran. · le sérial est en toute lettres dans les String Data Références (rare) Pour délimiter
la zone de recherche, je procède comme toi en posant un bpx hmemcpy,
et en cherchant l'adresse où la boite "code invalide"
va apparaître… :00428F33 83F806 cmp eax, 00000006 > une comparaison avec 6 ? :00428F36 751B jne 00428F53 > et si le flag Z =0 -> eax=0 :00428F38 837DF800 cmp dword ptr [ebp-08], 00000000 :00428F3C 7405 je 00428F43 > edx pointera vers 0047E1F3 :00428F3E 8B55F8 mov edx, dword ptr [ebp-08] :00428F41 EB05 jmp 00428F48 > va pousser edx sur la pile :00428F43 BAF3E14700 mov edx, 0047E1F3 :00428F48 52 push edx > edx poussé sur la pile :00428F49 E8FE0B0000 call 00429B4C > ?????? :00428F4E 59 pop ecx > dépile edx :00428F4F 84C0 test al, al > test al en sortie de call :00428F51 7504 jne 00428F57 > si al= 0 :00428F53 33C0 xor eax, eax > eax = 0 :00428F55 EB05 jmp 00428F5C > va vers ???? :00428F57 B801000000 mov eax, 00000001 > sinon eax = 1 Dans cette portion
du code, le cmp eax, 06 peut déjà attirer l'attention, et
je crois que tu as eu de la chance en entrant un code 123456 dont le nombre
de caractères correspondait justement à celui attendu… :00429B85 83F846 cmp eax, 00000046 :00429B88 7547 jne 00429BD1 :00429B8A 0FBE4301 movsx eax, byte ptr [ebx+01] :00429B8E 50 push eax :00429B8F E8B0580400 call 0046F444 :00429B94 59 pop ecx :00429B95 83F859 cmp eax, 00000059 :00429B98 7537 jne 00429BD1 :00429B9A 0FBE5302 movsx edx, byte ptr [ebx+02] :00429B9E 83FA39 cmp edx, 00000039 :00429BA1 752E jne 00429BD1 :00429BA3 0FBE4B03 movsx ecx, byte ptr [ebx+03] :00429BA7 83F932 cmp ecx, 00000032 :00429BAA 7525 jne 00429BD1 :00429BAC 0FBE4304 movsx eax, byte ptr [ebx+04] :00429BB0 83F838 cmp eax, 00000038 :00429BB3 751C jne 00429BD1 :00429BB5 0FBE5305 movsx edx, byte ptr [ebx+05] :00429BB9 83FA31 cmp edx, 00000031 :00429BBC 7513 jne 00429BD1 :00429BBE C705884848001443FC69 mov dword ptr [00484888], 69FC4314 :00429BC8 E80FAAFDFF call 004045DC :00429BCD B001 mov al, 01 :00429BCF EB1B jmp 00429BEC Le sérial
devant comporter 6 caractères, il y a justement des [ebx+XX] allant
de 1 à 5, avec à chaque fois une comparaison avec une valeur
fixe et différente, soit 46h, 59h, 39h, 32h, 38h, 31h, et systématiquement
un branchement en cas d'égalité fausse vers 00429BD1, puis
un mov al,01. :00429B59 8A10 mov dl, byte ptr [eax] > 1er caract du sérial dans dl :00429B5B 8813 mov byte ptr [ebx], dl > met dl dans EBX :00429B5D 8A4801 mov cl, byte ptr [eax+01] > second caract dans cl :00429B60 884B01 mov byte ptr [ebx+01], cl > met cl dans EBX+1 :00429B63 8A5002 mov dl, byte ptr [eax+02] > etc... :00429B66 885302 mov byte ptr [ebx+02], dl :00429B69 8A4803 mov cl, byte ptr [eax+03] :00429B6C 884B03 mov byte ptr [ebx+03], cl :00429B6F 8A5004 mov dl, byte ptr [eax+04] :00429B72 885304 mov byte ptr [ebx+04], dl :00429B75 8A4005 mov al, byte ptr [eax+05] :00429B78 884305 mov byte ptr [ebx+05], al :00429B7B 0FBE0B movsx ecx, byte ptr [ebx] > met le contenu de EBX dans ecx Soit un (très indiscret, et très laborieux) transvasement du code de l' adresse pointée par EAX dans celle pointée par EBX, puis dans un call suivant: :0042BB3A 83FA06 cmp edx, 00000006 > 6 caractères? :0042BB3D 7CF6 jl 0042BB35 :0042BB3F 0FBE0B movsx ecx, byte ptr [ebx] :0042BB42 83F93A cmp ecx, 0000003A > 3a = : :0042BB45 7548 jne 0042BB8F > vers code invalide :0042BB47 0FBE4301 movsx eax, byte ptr [ebx+01] :0042BB4B 83F83D cmp eax, 0000003D :0042BB4E 753F jne 0042BB8F :0042BB50 0FBE5302 movsx edx, byte ptr [ebx+02] :0042BB54 83FA55 cmp edx, 00000055 :0042BB57 7536 jne 0042BB8F :0042BB59 0FBE4B03 movsx ecx, byte ptr [ebx+03] :0042BB5D 83F959 cmp ecx, 00000059 :0042BB60 752D jne 0042BB8F :0042BB62 0FBE4304 movsx eax, byte ptr [ebx+04] :0042BB66 83F859 cmp eax, 00000059 :0042BB69 7524 jne 0042BB8F :0042BB6B 0FBE5305 movsx edx, byte ptr [ebx+05] :0042BB6F 83FA5F cmp edx, 0000005F :0042BB72 751B jne 0042BB8F :0042BB74 C705884848001443FC69 mov dword ptr [00484888], 69FC4314 > Hey :0042BB7E C605F447480001 mov byte ptr [004847F4], 01 > Ho Ho ! :0042BB85 E8528AFDFF call 004045DC :0042BB8A B001 mov al, 01 :0042BB8C 5B pop ebx :0042BB8D 5D pop ebp :0042BB8E C3 ret Exactement le
même type de routine que celle que nous venons déjà
de voir, et qui "produit" cette fois-ci un code de ce type:
:=UYY_ :0042BB2D 59 pop ecx :0042BB2E 884301 mov byte ptr [ebx+01], al :0042BB31 33D2 xor edx, edx :0042BB33 8BC3 mov eax, ebx :0042BB35 80306D xor byte ptr [eax], 6D :0042BB38 42 inc edx :0042BB39 40 inc eax :0042BB3A 83FA06 cmp edx, 00000006 :0042BB3D 7CF6 jl 0042BB35 En regardant juste
au dessus, un étrange Xor [eax],6D pourrait bien ressembler à
un principe de cryptage … * Reference To: ADVAPI32.RegQueryValueExA, Ord:0000h
|
:0045B527 E8BCAE0100 Call 004763E8
:0045B52C 85C0 test eax, eax
L'affichage se fait ensuite, et par un des ShowWindow que j'avais vu dans la liste des fonctions importées, comme j'en aurais la confirmation en posant un bpx sur cette API (break, F12 -> @004503CE). La modification que tu as apportée en 00429BDA (le JE à changer en JNE) permet au programme de fonctionner pleinement, et sans aucune limitation. Le flag utilisateur, ou son équivalent, est donc placé après ce jump et au plus tard avant l'ouverture d'un fichier, puisque dans sa version shareware l'icône-bitmap "auto" est (et reste) grisée, alors que dans la version enregistrée (ou patchée) l'icône devient active. Le plus probable est que ce flag est mis en place dans la foulée de la validation du sérial. :004042C5 E896490400 call 00448C60
:004042CA 837DF400 cmp dword ptr [ebp-0C], 00000000 > récupère le contenu de code dans la
> BdR et si code est non vide c'est ok
:004042CE 7405 je 004042D5 > reg/unreg
:004042D0 8B4DF4 mov ecx, dword ptr [ebp-0C]
:004042D3 EB05 jmp 004042DA
:004042D5 B9E8844700 mov ecx, 004784E8
:004042DA 51 push ecx
:004042DB E86C580200 call 00429B4C > contrôle du code
:004042E0 59 pop ecx
:004042E1 84C0 test al, al > contrôle validité du code
:004042E3 0F85E8010000 jne 004044D1 > vers Version Enregistrée
:004042E9 66C7853CFFFFFFA001 mov word ptr [ebp+FFFFFF3C], 01A0
:004042F2 33C0 xor eax, eax
:004042F4 89856CFFFFFF mov dword ptr [ebp+FFFFFF6C], eax
:004042FA 8D956CFFFFFF lea edx, dword ptr [ebp+FFFFFF6C]
:00404300 FF8548FFFFFF inc dword ptr [ebp+FFFFFF48]
:00404306 8B3DF8404800 mov edi, dword ptr [004840F8]
:0040430C 8BC7 mov eax, edi
:0040430E E855DC0300 call 00441F68
:00404313 8D956CFFFFFF lea edx, dword ptr [ebp+FFFFFF6C]
:00404319 52 push edx
* Possible StringData Ref from Data Obj ->" - Unregistered"
:00429BB5 0FBE5305 movsx edx, byte ptr [ebx+05] :00429BB9 83FA31 cmp edx, 00000031 :00429BBC 7513 jne 00429BD1 :00429BBE C705884848001443FC69 mov dword ptr [00484888], 69FC4314 (!) :00429BC8 E80FAAFDFF call 004045DC :00429BCD B001 mov al, 01 :00429BCF EB1B jmp 00429BEC C'est celui qui
a servi à la validation du sérial entré dans la boite
d'enregistrement, et qui permet de confirmer que la modification réalisée
va bien servir à lancer le programme en version complète.
Il n'en reste pas moins qu'il doit y avoir un autre test de l'état
utilisateur enregistré puisque dans la Full Version, les items
du menu Help ne comptent plus les "Register", et qu'il n'y aura
plus d'appels au call 00429B4C, celui ci n'étant sollicité
que deux fois (validation du sérial, et contrôle du code
utilisateur). :0042BB74 C705884848001443FC69 mov dword ptr [00484888], 69FC4314 :0042BB7E C605F447480001 mov byte ptr [004847F4], 01 :0042BB85 E8528AFDFF call 004045DC :0042BB8A B001 mov al, 01 Par contre entre
ces deux routines de validation du code, celle ci dispose en plus d'un
mov dword ptr [004847F4],01. Il s'agit de la version avec sérial
crypté. Ce Flag ne servira qu'un seule fois, et en mettant tout
une série d'autres drapeaux à 01 dans le call suivant. On
se perd ensuite dans les méandres des call indirects… Mais il y
a fort à parier que ce sérial crypté ouvre plus d'opportunités
que son petit frère… :00429BD1 53 push ebx :00429BD2 E8391F0000 call 0042BB10 > contrôle du code crypté :00429BD7 59 pop ecx :00429BD8 84C0 test al, al > Al modifié :00429BDA 7404 je 00429BE0 :00429BDC B001 mov al, 01 > flag code oK :00429BDE EB0C jmp 00429BEC :00429BE0 C70588484800EBBC0396 mov dword ptr [00484888], 9603BCEB > Unreg En plaçant
systématiquement 69FC4314 dans les mov dword ptr [00484888], tu
pourras disposer de toutes les fonctions du programme, mais "- Unregistered"
et les Items Register n'auront pas disparus pour autant… :0047347F 8B7510 mov esi, dword ptr [ebp+10] > le jour :00473482 8B5D0C mov ebx, dword ptr [ebp+0C] > le mois - 1 (!) :00473485 8B7D08 mov edi, dword ptr [ebp+08] > 99 Si tu modifies
la date à ce niveau, tu pourras faire croire ce que tu veux à
Jpeg Optimizer: · Possible StringData Ref from Data Obj ->" for %d days" Attention au drapeau -> mov byte ptr [00484864], 01
:004043A3 E8ACF20600 call 00473654 > appel GetLocalTime :004043A8 59 pop ecx :004043A9 898524FFFFFF mov dword ptr [ebp+FFFFFF24], eax :004043AF 8B8524FFFFFF mov eax, dword ptr [ebp+FFFFFF24] :004043B5 2BC6 sub eax, esi > esi = date instal :004043B7 B980510100 mov ecx, 00015180 :004043BC 99 cdq :004043BD F7F9 idiv ecx :004043BF 83F81E cmp eax, 0000001E > 1E= 30 jours :004043C2 0F8E09010000 jle 004044D1 > évite "for %d days" En modifiant le
saut, Unregistered s'affichera seul sans l'indication des jours, et le
drapeau [00484864] ne sera jamais mis à 01. CreateMenu création d'un menu vide (initialisation) CreatePopopMenu création d'un menu Popup vide (initialisation) DeleteMenu efface les sous-menus associés DestroyMenu devine... DrawMenuBar là aussi... EnableMenuItem sert à activer, désactiver, ou griser un item InsertMenuA création d'un menu InsertMenuItemA création d'un item de menu RemoveMenu efface un item de menu Evidemment c'est
DeleteMenu et RemoveMenu qui vont m'intéresser en premier…. :0042BB7E C605F447480001 mov byte ptr [004847F4], 01 :0042BB85 E8528AFDFF call 004045DC :0042BB8A B001 mov al, 01 Et le call 004045DC
commence à m'intéresser sérieusement! * Referenced by a CALL at Addresses: |:00429BC8 , :0042BB85 | :004045DC A1F8404800 mov eax, dword ptr [004840F8] :004045E1 33D2 xor edx, edx :004045E3 8B8048020000 mov eax, dword ptr [eax+00000248] :004045E9 E81A5D0500 call 0045A308 > break sur RemoveMenu pour "register" etc... :0040462F 8B81B8020000 mov eax, dword ptr [ecx+000002B8] :00404635 E8CE5C0500 call 0045A308 > break sur RemoveMenu pour "registered version benefits" :0040463A 8B0DF8404800 mov ecx, dword ptr [004840F8] :00404640 B201 mov dl, 01 :00404642 8B81E8020000 mov eax, dword ptr [ecx+000002E8] :00404648 E8EB5B0500 call 0045A238 :0040464D 8B0DF8404800 mov ecx, dword ptr [004840F8] :00404653 B201 mov dl, 01 :00404655 8B81EC020000 mov eax, dword ptr [ecx+000002EC] :0040465B E8D85B0500 call 0045A238 :00404660 C3 ret C'est bien ça… * Reference To: USER32.RemoveMenu, Ord:0000h
|
:0045A004 E871CA0100 Call 00476A7A
Conclusion, si on veut bénéficier d'un soft ayant TOUTES les apparences d'un programme Full Version, il faut impérativement atterrir en 0042BB7E ou en 0042BB74, et donc détourner ce saut : :0042BB3F 0FBE0B movsx ecx, byte ptr [ebx] :0042BB42 83F93A cmp ecx, 0000003A :0042BB45 7548 jne 0042BB8F > celui ci :0042BB47 0FBE4301 movsx eax, byte ptr [ebx+01] Mais un 7548 JNE
0042BB8F qui doit être changé en EB2D JMP 0042BB74, va engendrer
une différence de (75+48 =) 189d - (EB+2D =) 280d = +91d de différence
dans le poids des octets... 017F:004290C3 2BF9 SUB EDI,ECX 017F:004290C5 8DB5BCFEFFFF LEA ESI,[EBP-0144] 017F:004290CB 87F7 XCHG ESI,EDI 017F:004290CD 8BD1 MOV EDX,ECX va devenir: 017F:004290C3 2BF9 SUB EDI,ECX 017F:004290C5 8DB00CFEFFFF LEA ESI,[EAX-01F4] 017F:004290CB 87F7 XCHG ESI,EDI 017F:004290CD 8BD1 MOV EDX,ECX
Bonne journée Christal |