WinClock reversing
(hooking, dirottamento e manipolazione dell'ora del tray)


06/04/2000

by Ritz

 

 

UIC's Home Page

Published by Quequero



Bravo ritz, eccovi un ottimo esempio di come personalizzarsi win =)

 
UIC's form
E-mail: [email protected]
Ritz, #crack-it
UIC's form

Difficoltà

( )NewBies (X)Intermedio (X)Avanzato ( )Master

 

In questo tute spiegherò come reversare l'orologio del tray di Windows in modo da fargli segnare l'ora che vogliamo noi (precisamente i beat).


WinClock reversing
(hooking, dirottamento e manipolazione dell'ora del tray)
Written by Ritz

Introduzione

Salve raga!! Dovete sapere (tanto so che non ve ne frega un cazz ;) ) che qualche tempo fa un amico mi fece una domanda un po' strana, che sinceramente non mi era mai saltata per la testa, ovvero se era possibile fare in modo che l'orologio di Windowz (quello del tray) potesse essere "convertito" in modo che segnasse l'ora in beat. La cosa mi incuriosì molto, così dopo qualche giorno decisi di provare a dare un'occhiata su come win gestisce il clock del tray per vedere se (e come) si sarebbero potute apportare delle modifiche per far funzionare l'orologio come volevamo noi... La cosa era sicuramente più insolita e più interessante del puro cracking riferito alle protezioni dei programmi, e così, dopo alcuni giorni di impegno... eccovi questo tute:)). Perchè fare una cosa del genere? Beh è vero che non servirà a nulla in senso pratico (anche se non è detto), ma in ogni caso penso sia interessante capire come agisce Windoz anche in alcune situazioni apparentemente banali come appunto questa. Fatte ora queste dovute (????) considerazioni, passiamo pure al reversing vero e proprio.

Tools usati

# SoftIce 4.00
# Win32Dasm 8.93
# HIEW 6.16
# API Reference
# OpGen v1.0 by -NeuRaL_NoiSE (moooooooltooo utile)
# Patching Engine 2.0 beta by +MaLaTTiA (se volete diffondere l'opera ;) )

URL o FTP del programma

c:\windows\explorer.exe ;))

Notizie sul programma 

Spero che sappiate a cosa serva il clock del tray di windows:).

Essay

Bene raga, che ne dite di vivisezionare un pochetto quella bell'iconetta del tray che ci mostra l'ora? Hihihihihihi bene partiamo pure:))

Qual è il nostro obiettivo? Beh è semplice: vogliamo reversare l'orologio (d'ora in poi sarà sottinteso orologio del tray) in modo che riporti l'ora in beat appunto e non in formato "convenzionale".

Ah dimenticavo! Per chi non lo sapesse il beat (simbolo @) è (anzi, vorrebbe essere) un nuovo metodo di misurazione del tempo, secondo il quale una giornata viene divisa in 1000 parti uguali (1000 beat da 0 a 999 appunto), creato dalla Swatch.

Oki, almeno ora abbiamo le idee un po' + chiare sul da farsi. Dunque, concettualmente per raggiungere lo scopo bisognerà (naturalmente) passare varie fasi, + precismente bisognerà:

1- Scoprire quale funzione scrive l'ora nel tray.

2- Dirottare la funzione (prima che l'ora venga scritta) in un punto dove prenderà inizio la routine di manipolazione.

3- Scrivere la routine di manipolazione nel punto in cui è stata dirottata la funzione incriminata ;).

4- Far tornare il controllo come nulla fosse accaduto.

PRIMA di far tutto ciò bisognerà inoltre osservare bene con l'Ice la situazione che si presenta nella zona da cui partirà il dirottamento per prestare attenzione a come scrivere la nostra routine (hihihihi poi capirete perchè).

Bene, innanzi tutto dovremo capire quale API scrive l'ora nel tray. Beh non ci vuole molto per capire che sarà un'API che scrive del testo... contando quindi nell'intuito del coder (erm... chiamiamolo pure "culo") mettiamo un bpx su SetWindowTextA una volta che siamo nel desktop (possibilmente senza prog. in esecuzione). Aspettiamo un po' ed ecco che il Sice poppa proprio quando il clock si aggiorna di un minuto... Quando si dice coincidenza :))

Ecco la situazione:

:00406684 56 push esi
:00406685 FF7508 push [ebp+08]

* Reference To: USER32.SetWindowTextA, Ord:0259h
|
:00406688 FF15C4124000 Call dword ptr [004012C4]
:0040668E 668B45F8 mov ax, word ptr [ebp-08]
:00406692 663B053A524100 cmp ax, word ptr [0041523A]
:00406699 752E jne 004066C9

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004066C7(U), :004066E5(U)
|
:0040669B 0FB74DFC movzx ecx, word ptr [ebp-04]
:0040669F 69C9E8030000 imul ecx, 000003E8
:004066A5 B860EA0000 mov eax, 0000EA60
:004066AA 5E pop esi
:004066AB 2BC1 sub eax, ecx
:004066AD C9 leave
:004066AE C20400 ret 0004


Hoho che bello... non ci avrei sperato... la sintassi dell'API è tutta lì che ci aspetta... beh vabbè non è che sia così complicata :) Esi punterà naturalmente al testo da scrivere e ebp+08 sarà l'handle. Esi infatti punta proprio al valore aggiornato da scrivere ("d esi" dal Sice). Beh fin qui sembrerebbe quasi troppo facile. Sappiamo che Esi punta alla stringa da scrivere, e sarà proprio Esi quindi il nostro punto di riferimento.

Osserviamo facilmente che l'ora puntata da esi è scritta semplicemente come stringa ASCII (es. 17.23).

Steppiamo un po' per vedere cosa ci appare in seguito di fronte.


:00406533 8945F8 mov dword ptr [ebp-08], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406529(C)
|
:00406536 8D45DC lea eax, dword ptr [ebp-24]
:00406539 50 push eax
:0040653A FF7508 push [ebp+08]

* Reference To: USER32.GetClientRect, Ord:00EEh
|
:0040653D FF1594114000 Call dword ptr [00401194]
:00406543 A1E0514100 mov eax, dword ptr [004151E0]
:00406548 3BC7 cmp eax, edi

* Reference To: GDI32.SelectObject, Ord:0170h
|
:0040654A 8B3D48114000 mov edi, dword ptr [00401148]
:00406550 7407 je 00406559
:00406552 50 push eax
:00406553 53 push ebx
:00406554 FFD7 call edi
:00406556 8945F4 mov dword ptr [ebp-0C], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406550(C)
|

* Reference To: USER32.GetSysColor, Ord:0140h
|
:00406559 8B35B4114000 mov esi, dword ptr [004011B4]
:0040655F 6A0F push 0000000F
:00406561 FFD6 call esi
:00406563 50 push eax
:00406564 53 push ebx

* Reference To: GDI32.SetBkColor, Ord:0176h
|
:00406565 FF154C114000 Call dword ptr [0040114C]
:0040656B 6A12 push 00000012
:0040656D FFD6 call esi
:0040656F 50 push eax
:00406570 53 push ebx

* Reference To: GDI32.SetTextColor, Ord:019Ah
|
:00406571 FF1528114000 Call dword ptr [00401128]
:00406577 8D45EC lea eax, dword ptr [ebp-14]
:0040657A BE18524100 mov esi, 00415218
:0040657F 50 push eax
:00406580 FF353C524100 push dword ptr [0041523C]
:00406586 56 push esi
:00406587 53 push ebx

* Reference To: GDI32.GetTextExtentPointA, Ord:0129h
|
:00406588 FF153C114000 Call dword ptr [0040113C]
:0040658E 6A00 push 00000000
:00406590 8D45DC lea eax, dword ptr [ebp-24]
:00406593 FF353C524100 push dword ptr [0041523C]
:00406599 56 push esi
:0040659A 50 push eax
:0040659B 8B45E8 mov eax, dword ptr [ebp-18]
:0040659E 6A02 push 00000002
:004065A0 2B45F0 sub eax, dword ptr [ebp-10]
:004065A3 99 cdq
:004065A4 2BC2 sub eax, edx
:004065A6 D1F8 sar eax, 1
:004065A8 50 push eax
:004065A9 8B45E4 mov eax, dword ptr [ebp-1C]
:004065AC 2B45EC sub eax, dword ptr [ebp-14]
:004065AF 99 cdq
:004065B0 2BC2 sub eax, edx
:004065B2 D1F8 sar eax, 1
:004065B4 50 push eax
:004065B5 53 push ebx

* Reference To: GDI32.ExtTextOutA, Ord:006Ah
|
:004065B6 FF1550114000 Call dword ptr [00401150]


Si vede infatti che con la semplice chiamata SetWindowTextA la stringa non viene stampata subito nel tray, ma al contrario prima che ciò avvenga bisogna passare attraverso altre API quali GetClientRect, SelectObject, GetSysColor, SetBkColor, SetTextColor, GetTextExtentPointA e finalmente ExtTextOutA, che stampa la benedetta ora. Non penso serva spiegare cosa fa ognuna di queste API (al massimo guardatevi un'API Reference), ma è interessante notare che proprio ExtTextOutA è responsabile dell'apparizione dell'ora nuova. Eccone la sintassi:

BOOL ExtTextOut(

HDC hdc,    // handle to device context
int X,    // x-coordinate of reference point
int Y,    // y-coordinate of reference point
UINT fuOptions,    // text-output options
CONST RECT *lprc,    // optional clipping and/or opaquing rectangle
LPCTSTR lpString,    // points to string
UINT cbCount,    // number of characters in string
CONST INT *lpDx     // pointer to array of intercharacter spacing values
);

Beh non semplicissima a prima vista, ma cmq a noi basta sapere che l'ultimo parametro pushato è l'handle e il 3° punta alla stringa da scrivere... perchè dico questo? Beh perchè sia in quest'API che nelle altre sopra bisogna fare MOLTA attenzione a una cosa... prima che venga chiamata SetWindowTextA infatti ebx ha un certo valore che NON cambia fino ad arrivare a ExtTextOut... esso infatti è proprio l'handle dell'oggetto dove porre il testo, e viene chiamato anche in varie altre API precedenti. Di conseguenza esso NON deve ASSOLUTAMENTE essere modificato dalla nostra routine, a patto di non essere salvato in qualche altro punto, ma cmq ciò non è necessario in quanto oltre a esi bastano solamente un altro paio di registri, l'immancabile eax e ecx ad esempio.

Ora che abbiamo capito la situazione, che facciamo, prima scriviamo la routine di conversione o prima troviamo lo spazio dove metterla? Meglio la prima credetemi ;).

Allora i modi per procedere sono più d'uno (almeno penso), ma io ho cercato di attuare quello + semplice. Abbiamo detto che l'ora è sotto semplicissima forma ASCII nel buffer. Ciò significa che se ad esempio sono le 17.23 esi punterà a un buffer contenente

    31 37 2E 32 33 <---- Codice esadecimale del carattere ASCII
| | | | |
1 7 . 2 3

Che schifo di disegno... vabbe non importa... beh non sarebbe + semplice poter avere tutti i valori ASCII espressi in byte puri per manipolarli (ad esempio invece che 37h (7) avere proprio 7h)? Beh secondo me si (o almeno è ciò che ho pensato da subito). Ecco quindi che innanzi tutto sarà necessario togliere a ogni byte dell'ora (tranne il punto ;) il valore 30h. Ora la situazio sarà

    1 7 2E 2 3

invece quella sopra.

Ragionando semplicemente in dec, per attuare la conversione basta calcolare i secondi totali che compongono un dato orario e quindi dividerli per un certo valore. Per trovare tale valore basta considerare che alle 23.59 i beat dovranno essere 999, quindi 23.59 = 86340 sec, 86340 / 999 = 86,42...... Il numero da usare per convertire un certo numero di secondi in beat è infatti 86,42. Per essere + precisi moltiplicheremo sia il valore da convertire che il fattore di conversione per 10 prima di effettuare l'operazione. Beh, adesso sappiamo anche come farlo in dec, per farlo in hex basterà semplicemente sostituire a tutti i valori dec quelli hex corrispondenti, nulla di più semplice. Ecco che la routine prende forma...


xor eax, eax
|- xor ecx, ecx
| mov al, byte ptr [esi+4] ;ultimo valore dell'ora
| sub al, 30h         ;valore ASCII -> byte
| imul eax, 3Ch         ;secondi totali
| mov ecx, eax        
|- xor eax, eax
| mov al, byte ptr [esi+3] ;viene preso il numero delle decine di
| sub al, 30h ;minuti, convertito in secondi e
| imul eax, 258h ;aggiunto al valore finora trovato [x*A(10d)*3C(60d)]
| add ecx, eax
|- xor eax, eax
| mov al, byte ptr [esi+1] ;stessa cosa per le ore
| sub al, 30h
| imul eax, E4BC0h
| add ecx, eax
|- xor eax, eax
| mov al, byte ptr esi ;e le decine di ore
| sub al, 30h
| imul eax, 8CA0h
|- add ecx, eax
imul ecx, 10h
mov eax, ecx
mov ecx , 566h
cdq
idiv ebx

Fatto ciò avremo in eax il valore hex che convertito in dec sarà proprio il nostro orario. Adesso bisogna fare in modo che tale valore venga appunto convertito e poi stampato al posto dell'ora convenzionale. La cosa è fattibile con una particolare API che fa tutto ciò al posto nostro, precisamente wsprintfa. Eccone la sintassi:

int wsprintf(

LPTSTR lpOut,    // pointer to buffer for output
LPCTSTR lpFmt,     // pointer to format-control string
...    // optional arguments
);

Quest'api infatti prende da un registro il valore che convertito sarà la stringa da scrivere, lo converte e lo salva NON come byte ma proprio come stringa ASCII in un buffer. Bello eh? :). Beh in questo caso i parametri da pushare saranno tre, eccoli:

mov [esi+07], 6425
1 push eax
    add esi, 7
2 push esi
sub esi, 7
add esi, 1
3 push esi
sub esi, 1
    call wsprintfa

Eax contiene proprio la stringa famosa, esi (2° parametro) sarà il tipo di formato della stringa che vogliamo avere, noi metteremo %d (scusate l'estetica orrenda per pushare il 2° parametro, mi faccio schifo da solo ma quel giorno non avevo proprio voglia di andarmi a cercare come si pusha in linguaggio macchina l'offset esi+7).

Beh adesso in esi+1 avremo la nostra bella stringa pronta per essere visualizzata a schermo.

Che fare adesso?

Ora basta semplicemente formattarla a piacere, ovvero scegliere il layout preferito ;) . Convenzionalmente (anzi, meglio forse dire "usualmente") l'ora in beat viene espressa col simbolo @ davanti all'ora (es. @123), quindi basterà con una semplicissima routine fare proprio una cosa del genere:

    sub esi, 1
    mov cl, 40h
    mov byte ptr [esi+1], cl
    mov cl, 20h
    mov byte ptr esi, cl
    mov byte ptr [esi+5], cl
    mov byte ptr [esi+6], cl
    mov byte ptr [esi+7], cl

Beh, semplicemente qui viene messo proprio il simbolo "@" prima del valore, una cosa da notare è che al posto degli eventuali byte indesiderati NON deve venir messo 00h, in quanto la funzione ExtTextOut non si basa sul byte 00 di terminazione stringa per delimitare i charz da scrivere, bensì essi devono essere definiti attraverso un normale push. Di conseguenza sarà opportuno mettere degli spazi (mettendo 00h al posto di 20 il clock visualizza infatti un quadratino tipo ).

Infine basterà chiamare SetWindowTextA (con relativi push) e far tornare l'esecuzione della routine dove era stata interrotta. Ecco come si presenta la mia routine di conversione:

    33C0 xor eax, eax
    33C9 xor ecx, ecx
    8A4604 mov al, byte ptr [esi+04]
    2C30 sub al, 30
    6BC03C imul eax, 0000003C
    8BC8 mov ecx, eax
    33C0 xor eax, eax
    8A4603 mov al, byte ptr [esi+03]
    2C30 sub al, 30
    69C058020000 imul eax, 00000258
    03C8 add ecx, eax
    33C0 xor eax, eax
    8A4601 mov al, byte ptr [esi+01]
    2C30 sub al, 30
    6BC03C imul eax, 0000003C
    6BC03C imul eax, 0000003C
    03C8 add ecx, eax
    33C0 xor eax, eax
    8A4600 mov al, byte ptr [esi+00]
    2C30 sub al, 30
    6BC00A imul eax, 0000000A
    6BC03C imul eax, 0000003C
    6BC03C imul eax, 0000003C
    03C8 add ecx, eax
    6BC910 imul ecx, 00000010
    8BC1 mov eax, ecx
    B966050000 mov ecx, 00000566
    99 cdq
    F7F9 idiv ecx
    66B96425 mov cx, 2564
    66C746072564 mov [esi+07], 6425
    50 push eax
    81C607000000 add esi, 00000007
    8BCE mov ecx, esi
    51 push ecx
    83EE07 sub esi, 00000007
    83C601 add esi, 00000001
    56 push esi
    83EE01 sub esi, 00000001

    FF1548134000 Call wsprintfA
    83EE01 sub esi, 00000001
    B140 mov cl, 40
    884E01 mov byte ptr [esi+01], cl
    B120 mov cl, 20
    884E05 mov byte ptr [esi+05], cl
    884E00 mov byte ptr [esi+00], cl
    884E06 mov byte ptr [esi+06], cl
    884E07 mov byte ptr [esi+07], cl
    56 push esi
    FF7508 push [ebp+08]

    FF15C4124000 Call SetWindowTextA

Naturalmente non è molto ottimizzata, anzi. Infatti sfortunatamente non è nemmeno definitiva. Come mai? Beh, semplice, modificatevi il file in questo modo (creando una nuova sezione, usando i byte in coda al file, insomma come volete) e cambiate l'ora alle 23.59... @999, bene, aspettate la mezzanotte;) dovrebbe apparire @000... nooooo perchè non appare? Al posto suo compare un numero che non centra un cazzo (mi pare qualcosa tipo @688), perchè mai?
Hehe, fino ad ora non abbiamo considerato una cosa: in windoze le ore con 1 cifra delle ore (es. 9.32) vengono visualizzate come x.yz, NON come 0x.yz. Bella sfiga per noi. Che fare dunque? Basta semplicemente traslare fisicamente ;) i byte dell'ora comune in modo che si mettano al giusto posto. Esempio:

    cmp byte ptr [esi+04], 00
    jne tutto_ok
mov eax, dword ptr [esi]
    mov dword ptr [esi+01], eax
    mov cl, 30
    mov byte ptr [esi+00], cl

tutto_ok:
    ... esecuzione normale ...

Puntando esi infatti a una sequenza del tipo tx.yz, se t non esiste allora l'ora sarà del tipo x.yz, quindi il 4° byte sarà 00h. Se accade ciò, allora il prog mette in eax il valore dei 4 byte del buffer e li rimette poi in esi+1, scalandoli in pratica di 1 posizione. Fatto ciò, basterà mettere uno 00h al byte puntato da esi. Bene, a prima vista adesso dovrebbe essere tutto a posto, vero?
Hum chissà perchè mi sa proprio di no ;). Il problema questa volta ce lo dà l'API wsprintfA, in quanto sfortunatamente se la stringa risultante è di 2 cifre invece che 3 allora lo 0 iniziale non lo mette neanche :((. Moltobbbbbeeeeeeneeeee, cerchiamo di vedere anche questa situazione.
Se la stringa risultante è di 3 charz, l'API nel buffer puntato da esi scrive una roba del tipo "n111" (5° byte null), se invece essa è di 2 charz scrive una cosa del tipo "011" (il 4° byte è null), se poi è di 1 solo char allora è del tipo "01" (3° byte null). Cosa significa tutto ciò? Significa che anche in questo caso ci troviamo scombinati di 1 o 2 byte. Come prima bisognerà porre rimedio in modo simile:

    Call wsprintfa
    cmp byte ptr [esi+02], 00
    jne 1_ok
    mov eax, dword ptr [esi]
    mov dword ptr [esi+02], eax
    mov cl, 00   
    mov byte ptr [esi+04], cl
    mov cl, 30
    mov byte ptr [esi+00], cl
    mov byte ptr [esi+01], cl

1_ok:
    cmp byte ptr [esi+03], 00
    jne 2_ok
    mov eax, dword ptr [esi]
    mov dword ptr [esi+01], eax

2_ok:
    ... esecuzione normale ...

Tutto molto semplice: in tale maniera si fa in modo di tornare alla forma originale del tipo "n111". Bene, fatto ciò la nostra routine (stavolta completa) si dovrebbe presentare così:

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406684(U)
|
:00414DCF 807E0400 cmp byte ptr [esi+04], 00
:00414DD3 750E jne 00414DE3
:00414DD6 8B06 mov eax, dword ptr [esi]
:00414DD8 894601 mov dword ptr [esi+01], eax
:00414DDB B130 mov cl, 30
:00414DDD 884E00 mov byte ptr [esi+00], cl
:00414DE0 884E02 mov byte ptr [esi+02], cl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414DD3(C)
|
:00414E1D 33C0 xor eax, eax
:00414E1F 33C9 xor ecx, ecx
:00414E21 8A4604 mov al, byte ptr [esi+04]
:00414E25 2C30 sub al, 30
:00414E27 6BC03C imul eax, 0000003C
:00414E2A 8BC8 mov ecx, eax
:00414E2C 33C0 xor eax, eax
:00414E2E 8A4603 mov al, byte ptr [esi+03]
:00414E32 2C30 sub al, 30
:00414E34 69C058020000 imul eax, 00000258
:00414E3A 03C8 add ecx, eax
:00414E3C 33C0 xor eax, eax
:00414E3E 8A4601 mov al, byte ptr [esi+01]
:00414E41 90 nop
:00414E42 2C30 sub al, 30
:00414E44 6BC03C imul eax, 0000003C
:00414E47 6BC03C imul eax, 0000003C
:00414E4A 03C8 add ecx, eax
:00414E4C 33C0 xor eax, eax
:00414E4E 8A4600 mov al, byte ptr [esi+00]
:00414E51 90 nop
:00414E52 2C30 sub al, 30
:00414E54 6BC00A imul eax, 0000000A
:00414E57 6BC03C imul eax, 0000003C
:00414E5A 6BC03C imul eax, 0000003C
:00414E5D 03C8 add ecx, eax
:00414E5F 6BC910 imul ecx, 00000010
:00414E62 8BC1 mov eax, ecx
:00414E64 B966050000 mov ecx, 00000566
:00414E69 99 cdq
:00414E6A F7F9 idiv ecx
:00414E6C 66B96425 mov cx, 2564
:00414E70 66C746072564 mov [esi+07], 6425
:00414E76 50 push eax
:00414E77 81C607000000 add esi, 00000007
:00414E7D 8BCE mov ecx, esi
:00414E7F 51 push ecx
:00414E80 83EE07 sub esi, 00000007
:00414E83 83C601 add esi, 00000001
:00414E86 56 push esi
:00414E87 83EE01 sub esi, 00000001

* Reference To: USER32.wsprintfA, Ord:02A4h
|
:00414E8A FF1548134000 Call dword ptr [00401348]
:00414E90 807E0200 cmp byte ptr [esi+02], 00
:00414E94 7512 jne 00414EA8
:00414E96 8B06 mov eax, dword ptr [esi]
:00414E98 894602 mov dword ptr [esi+02], eax
:00414E9B B100 mov cl, 00
:00414E9D 884E04 mov byte ptr [esi+04], cl
:00414EA0 B130 mov cl, 30
:00414EA2 884E00 mov byte ptr [esi+00], cl
:00414EA5 884E01 mov byte ptr [esi+01], cl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414E94(C)
|
:00414EA8 807E0300 cmp byte ptr [esi+03], 00
:00414EAC 750A jne 00414EB8
:00414EAE 8B06 mov eax, dword ptr [esi]
:00414EB0 894601 mov dword ptr [esi+01], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00414EAC(C)
|
:00414ECA 83EE01 sub esi, 00000001
:00414ECD B140 mov cl, 40
:00414ECF 884E01 mov byte ptr [esi+01], cl
:00414ED2 B120 mov cl, 20
:00414ED4 884305 mov byte ptr [ebx+05], al
:00414ED7 884300 mov byte ptr [ebx+00], al
:00414EDA 884306 mov byte ptr [ebx+06], al
:00414EDD 884307 mov byte ptr [ebx+07], al
:00414EE0 FF7508 push [ebp+08]

* Reference To: USER32.SetWindowTextA, Ord:0259h
|
:00414EE3 FF15C4124000 Call dword ptr [004012C4]
:00414EE9 E9A017FFFF jmp 0040668E

Ecco la versione finale disassemblata... senza vari nop (ne ho usati un casino :). In questo caso viene usata la miriade di byte finali in coda al file (un peccato sprecarli ;), ma naturalmente si sarebbe potuto aggiungere benissimo una nuova sezione, solo che questo avrebbe dato dei problemi per fare la patch. Il codice sopra natralmente non è per nulla ottimizzato, sono stati sprecati molti byte, l'ottimizzazione fatela come meglio credete.

A proposito di patch, se adesso vogliamo distribuire la nostra copia dell'exploder nuovo? Beh scrivere un patcher in qualsiasi linguaggio 16bit (infatti essa sarà eseguita necessariamente da dos) non è per nulla complicato, si può fare in asm, pascal, c, insomma ciò che volete. Il problema sono la quantità enorme di byte da cambiare. Per questo può usare qualche utile prog. tipo patcher engine di +MaLa ad esempio, che ci toglie molto lavoro inutile.

Beh, a questo punto la missione sembra conclusa, il clock conta il tempo in beat, ma l'ora naturalmente si può ancora regolare in tempo convenzionale.
Considerazioni finali e saluti

In quanto a considerazioni finali che dire, questo è stato solo un esempio di come poter utilizzare l'asm per cambiare il nostro amato (si fa per dire) Windoze e fargli fare, almeno in parte, quello che vogliamo noi, discorso che vale naturalmente per tutti gli altri programmi.

Per quanto riguarda i ringraziamenti e saluti, cose da dire ne ho varie. Ringrazio specialmente:

§ +MaLaTTiA: per la grandissima disponibilità (beta-testing compreso) e sostegno morale, e perchè finalmente ogni tanto lo si vede su irc ;)).

§ Kill3xx: perchè mi ha tolto dal dubbio di come convertire eax in ASCII usando wsprintfa ;).

§ Quequero: per i vari consigli asm compreso quello sopra.

§ cod: v.s. :)

§ Yado: anche lui per vari cosigli asm & betatesting.

§ -NeuRaL_N.: per l'OpGen, utilissimo nei salti.

§ BlackDruiD: perchè non scoprirò mai come cazzo fa a fare le sue magie e perchè è troppo disponibile a farmele ;) (pure per il betatesting).

Saluto inoltre i vari [aLT255], AndreaGeddon, Int19, TiN_MaN, ^courier, grisu, nobody88 e tutti gli altri che sanno di dover essere salutati;).

Beh prima di finire un particolare ringraziamento va pure a colui che mi ha dato l'insana idea di fare tutto ciò: ciao Defra!!

Bene, se volete mandare critiche, far domande, ecc... fatelo pure a [email protected].

Ve saludo!!!

@2000 by Ritz

Disclaimer

Vorrei ricordare che il software va comprato e  non rubato, dovete registrare il vostro prodotto dopo il periodo di valutazione. Non mi ritengo responsabile per eventuali danni causati al vostro computer determinati dall'uso improprio di questo tutorial. Questo documento è stato scritto per invogliare il consumatore a registrare legalmente i propri programmi, e non a fargli fare uso dei tantissimi file crack presenti in rete, infatti tale documento aiuta a comprendere lo sforzo immane che ogni singolo programmatore ha dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.
Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.

 
UIC's page of reverse engineering, scegli dove andare:

Home   Anonimato   Assembly    CrackMe   ContactMe   Forum   Iscrizione      
       Lezioni    Links   Linux   NewBies   News   Playstation        
  Tools   Tutorial   Search   UIC Faq

UIC