********************************************                                   
                                            RingZer0 Presents                   
                                              
                                 "Win32asm PATCH" by PUSILLUS 
                                                               05/02/1999
                                ********************************************
------------------------------------------------------------------------------------------------------------
Anche questo � un ottimo tutorial su come creare una generica patch in MASM.....il tutorial � buono, � il Masm che non ci piace vero? Nulla di personale ma la Microsoft non mi gusta pi� di tanto. In realt� il tutorial � ottimo, il sorgente � commentato estremamente bene per� se non avete neanche la vaga idea di cosa sia il MASM, bh�, procuratevi i tutorial di Iczelion su Iczelion.cjb.net, l'indirizzo preciso ve lo dice Pusillus pi� gi� nel tutorial
------------------------------------------------------------------------------------------------------------
 
Quello che cercher� di illustrare � un template per una patch generica in
win32asm compilabile con il MASM della Micro$oft

Qcaricate
qui i sorgenti

Per Iniziare:

dal sito: http://www.pbq.com.au/home/hutch/masm.htm scaricatevi: masm32v3.zip,
le "Import Libraries" e l2inc.exe . Sono tutti i tools necessari x la
compilazione di programilli in win32asm tramite MASM.

manuale del MASM: http://catalyst.intur.net/~Iczelion/files/asm-tools/programmers_guide.zip

Win32.hlp: file guida x le API di window, lo trovate in molti compilatori C++
oppure lo trovate su molti siti ma � grande 12Mbytes.
UltraEdit: www.ultraedit.com e' un'editor con il sintax highlighting, molto
utile per i programmatori, oppure usatene uno che vi aggrada di pi�.
SoftIce: lo si usa x il debugging.
Un editor di risorse (.rc) si trova insieme ai pacchetti dei compilatori. In
alternativa potete prelevarne alcuni sulla pagina di Iczelion oppure farvi
i file .rc a mano. (O meglio scaricate Borland Resource Workshop su questo sito alla sezione tools)

*OBBLIGATORIA* la lettura dei tutes di Iczelion al sito:
http://catalyst.intur.net/~Iczelion/win32asm/

come usare il compilatore:
nell'autoexec.bat inserite il path della directory \bin del masm

COMANDI:

* ml /c /coff /Cp /Zi patch.asm : ML.EXE, il compilatore, genera il file .obj
per la lista delle opzioni lanciare ML /?
* rc patch.rc : compilatore di risorse viene generato il file
.RES che sara' linkato all'applicazione e
contiene tutte le informazioni relative a
bottoni finestre ecc.
* Link /SUBSYSTEM:WINDOWS /VERSION:4.0 /LIBPATH:c:\masm\lib /DEBUG /DEBUGTYPE:COFF patch.obj patch.res
: il linker genera l'EXE vero e proprio

in altenativa si pu� usare un MAKEFILE che esegue la compilazione automaticamente tramite nmake.exe e nmaker.exe che vedr� di allegare ai sorgenti.
Da notare che nelle righe di comando sono inseriti gli switch per la generazione
delle informazioni di debug che ci permetteranno, una volta dato in pasto al
softice l'eseguibile, di visualizzare riferimenti a labels e variabili con i
nomi da noi assegnati nel sorgente. Eliminando gli switch per il debugging
l'eseguibile avr� dimesioni piu ridotte.


Schema di principio del prgramma:

-----------------
| Winmain | tasto "EXIT"
|--------->| |----------------> uscita
| -----------------
| |
| | tasto "OK"
| |
| |
| -----------------
| | | errore 1
| | aprifile |------------------------|
| ----------------- |
| | |
| |OK |
| | |
| | |
| ----------------- |
| | controllo | errore 2 |
| | dim. file |-------------------| |
| ----------------- | |
| | | |
| |OK | |
| | | |
| ----------------- | |
| | controllo | errore 3 | |
| | corrispondenza|---------------| | |
| |bytes originali| | | |
| ----------------- | | |
| | | | |
| |OK ------------
| | | Tabella |
| ----------------- | errori |
| | Applicazione | | |
| | patch | ------------
| ----------------- |
| | |
| |<--------------------------|
| |
|-------------------


cominciamo a dare una spiegazione del sorgente:
+++++++++
.386
.model FLAT, STDCALL
include winicz2.inc ; includefile di Iczelion modificato da me
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib
+++++++++

In ordine vengono specificati il tipo di processore (.386) e il tipo di modello
di memoria da usare FLAT, l'unico disponibile in win32. STDCALL indica che i
parametri nelle call vengono passati da destra a sinistra. vengono di seguito
specificati il file di include e le librerie usate.
Non mi soffermo molto su queste cose perche i tutes di Iczelion sono molto pi�
autorevoli delle mie spiegazioni!

++++++++++
UpdateBuffer PROTO :DWORD,:DWORD
log PROTO :DWORD,:DWORD
Patch PROTO :DWORD,:DWORD,:DWORD

PDWORD TYPEDEF PTR DWORD
++++++++++

Vengono definite i prototipi delle procedure e PDWORD che e' un puntatore a
una DWORD

++++++++++
.data
DlgName db "MyDialog",0 ; riferimento alla dialogbox

;---------Valori modificabili-----------------------------
AppName db "Patch template By Pusillus ",0

TestString db "E' possibile inserire dei ",0dh,0ah
db "commenti come ad esempio ",0dh,0ah
db "il nome del progrmma da ",0dh,0ah
db "patchare ed altre info ",0dh,0ah
db "cracker, release ecc. ",0dh,0ah,0dh,0ah,0
;--------Dati x la Patch
FileName db "prova.exe",0 ;nome del File da patchare
FileSize dd 3096 ;dimensioni del file da patchare

Offset1 dd 020h,021h,022h,024h, 0 ;Offsets del file
Original1 db 00h,00h,00h,00h ;bytes del file originale
Patch1 db 011h,022h,033h,044h ;bytes x la modifica del file
;---------------------------------------------------------


;---messaggi x la log window
opening db "Opening File %s... ",0
checkingSize db "Checking File Size... ",0
checkingCRC db "Checking CRC... ",0
Patching db "Patching... ",0
MsgOk db "OK",0dh,0ah,0
TuttoOk db "File PATCHED !! ",0dh,0ah,0

;----messaggi di errore
errFileNotFound db 0dh,0ah,"FILE NOT FOUND !!! ",0dh,0ah,0
errBadFileSize db 0dh,0ah,"BAD FILE SIZE !!! ",0dh,0ah,0
errBadCRC db 0dh,0ah,"BAD CRC or alredy patched !!! ",0dh,0ah,0
;----puntatore ai messaggi di errore
Perr PDWORD errFileNotFound
PDWORD errBadFileSize
PDWORD errBadCRC
++++++

La sezione .DATA non merita particolari spiegazioni, soltanto "Perr" che e'
un'array di tipo PDWORD, precedentemente definito, a cui vengono assegnati gli
indirizzi che contengono i messaggi di errore.

++++++
.data?

hInstance1 HINSTANCE ? ; Hanle della dialogbox
hInstButt HINSTANCE ? ; Handle del bottone "Ok"
CommandLine LPSTR ?
buffer db 512 dup(?),0 ; buffer per il log
ReadBuffer db ? ; buffer per la memorizz. del byte letto dal file
ptbuffer dd ? ; puntatore al buffer del log
hFile dd ? ; handle del file da patchare
byteWriRead dd ? ; numero di bytes scritti/letti
++++++

nella sezione .DATA? vengono dichiarate le variabili.

++++++
.const

IDC_EXIT equ 3003
IDC_BUTTON equ 3002
IDC_STATIC equ -1
IDC_EDIT1 equ 3004
++++++

queste costanti sono gli id degli elementi della dialogbox assegnate dal
resource editor

++++++
.code

start:

mov eax,offset buffer
mov ptbuffer, eax
invoke WinMain, NULL,NULL,NULL, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD
mov eax, OFFSET DlgProc
invoke DialogBoxParam, hInst, ADDR DlgName,NULL,eax,NULL
ret
WinMain endp
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
mov eax,hWnd
mov hInstance1,eax
mov eax,uMsg
.IF eax==WM_INITDIALOG

invoke GetDlgItem, hWnd,IDC_BUTTON
mov hInstButt,eax
invoke SetWindowText, hWnd, addr AppName
invoke log, addr TestString,NULL
invoke SetFocus,eax
.ELSEIF eax==WM_CLOSE
invoke EndDialog, hWnd,NULL
.ELSEIF eax==WM_COMMAND
mov eax,wParam
.IF ax==IDC_BUTTON
shr eax,16
.IF ax == BN_CLICKED
;se viene premuto il tasto "OK" viene chiamata la routine x la patch
invoke Patch,addr Offset1 ,addr Original1,addr Patch1

.ENDIF
.ELSEIF ax == IDC_EXIT
shr eax,16
.IF ax==BN_CLICKED
invoke EndDialog, hWnd,NULL
.ENDIF
.ENDIF
.ELSE
mov eax,FALSE
ret
.ENDIF
mov eax,TRUE
ret
DlgProc endp

++++++

Questa parte di codice usa una dialogbox come main window; scopiazzata, lo
devo ammettere, dai tutes di Iczelion e ripulita delle cose che non servivano.

Qui sotto c'e' la routine principale del programma :


++++++
;Routine principale x la patch
Patch proc aPatchAddr:DWORD,aOriginalData:DWORD, aPatchData:DWORD
invoke log, addr opening, addr FileName ;log iniziale
;-----apertura del file---
invoke CreateFile,addr FileName,GENERIC_READ + GENERIC_WRITE, 0,0,OPEN_EXISTING,0,0
cmp eax,-1
; la funzione restituisce -1
jz @@exit
; se non e' riuscita ad aprire il file.
mov hFile, eax
; salva l'handle del file.
invoke log, addr MsgOk,NULL ;
invoke log, addr checkingSize,NULL
; messaggi x la log
invoke GetFileSize, hFile,NULL ;
cmp eax,[FileSize]
; confronta le dim. del file
je @@read
; se le dimensioni sono ok salta a @@read
mov eax, -2
; altrimenti salva il valore -2 in EAX
jmp @@exit
; e salta a @@exit
; routine di controllo dei bytes del file non patchato
@@read:
invoke log, addr MsgOk,NULL ;
invoke log, addr checkingCRC,NULL
; messaggi x la log window
mov edi, aPatchAddr
; in EDI viene caricato l'indirizzo degli offsets
mov esi, aOriginalData
; in ESI l'indirizzo dei dati da confrontare
xor ebx,ebx
@@loop1:
mov edx,[edi+ebx*4]
; EDX valore dell'offset, EBX indicizza
test edx,edx
; se EDX e' 0 termina il controllo. Notare
je @@finecomp
; che l'array 'Offset1' e' terminato con 0
invoke SetFilePointer, hFile, edx, 0, FILE_BEGIN
; si sposta all'offset indicato da EDX nel file
invoke ReadFile,hFile,addr ReadBuffer,1,addr byteWriRead,0
;legge un byte
mov al, ReadBuffer
; sposta in AL il byte letto
cmp al,[esi+ebx]
; confronta AL con il contenuto dell'indirizzo puntato da ESI indic. EBX
jnz @@errorecomp
; i due bytes non sono uguali
inc ebx
; incrementa l'indice
jmp @@loop1 ;
@@finecomp:
mov eax,0
; flag x esito POSITIVO della comparazione
jmp @@exit
@@errorecomp:
mov eax,-3
; flag esito NEGATIVO della comparazione
@@exit:
cmp eax,0
je @@modifica
; salta a @@modifica se il flag e' 0
neg eax
dec eax ; viene spostato l'indice in modo da
mov esi,dword ptr Perr[eax*4]
; puntare ESI al messaggio di errore
invoke log,esi,NULL
; indicato da EAX
jmp @@close

@@modifica:
; routine x la modifica del file
invoke log, addr MsgOk,NULL
invoke log, addr Patching,NULL
mov edi, aPatchAddr
; in EDI l'indirizzo degli offsets
mov esi, aPatchData
; in ESI l'indirizzo dei bytes della Patch
xor ebx,ebx
@@loop2:
mov edx,[edi+ebx*4]
; routine analoga a quella di comparazione
test edx,edx
je @@finescrittura
invoke SetFilePointer, hFile, edx, 0, FILE_BEGIN
invoke WriteFile,hFile,esi,1,addr byteWriRead,0
inc ebx
inc esi
jmp @@loop2

@@finescrittura:
; la patch e' stata applicata
invoke log, addr MsgOk,NULL
invoke log, addr TuttoOk,NULL
@@close: ;
invoke EnableWindow,hInstButt,FALSE
; viene disabilitato il button "OK"
invoke CloseHandle,hFile
; chiusura del file
ret
Patch endp
+++++++

spero che i commenti inseriti siano abbastanza esaurienti.


+++++++
;routine x l'aggiornamento del buffer del log
UpdateBuffer proc aMessage:DWORD,addiction:DWORD
invoke wsprintfA, ptbuffer,aMessage,addiction
add esp, 12
add ptbuffer, eax
ret
UpdateBuffer endp
+++++++
UpdateBuffer si occupa di aggiornare il buffer della log window aggiungendo
il testo indicato da "aMessage" e spostando ptbuffer alla fine del testo
memorizzato in modo che alla prossima chiamata di UpdateBuffer il testo sia
aggiunto alla coda di stringhe.

++++++++
;routine x l'aggiornamento della finestra di log
log proc aTesto,optional:DWORD
invoke UpdateBuffer,aTesto,optional
invoke SendDlgItemMessage,hInstance1,IDC_EDIT1,WM_SETTEXT,0,addr buffer
invoke SendDlgItemMessage,hInstance1,IDC_EDIT1,EM_LINESCROLL,0,10
ret
log endp


end start
+++++++++
"log" � la routine che 'spara' il contenuto del buffer nella log window con
id IDC_EDIT1, prima di fare questo per� chiama la routine di aggiornamento
del buffer passandogli come parametri "aTesto", che e' l'indirizzo della
stringa da scrivere e "optional" che serve come parametro supplementare x la
funzione wsprintf.

Files:

patch.rc : risorse
afxres.h : include x le risorse
MAKEFILE : makefile x nmake.exe
resource.k : altro include per le risorse
patch.exe : patch
patch.asm : sorgente della patch .asm
WinICZ2.inc : file di include di Iczelion con alcune modifiche
readme.txt : questo file
prova.exe : file sul quale verr� applicata la patch
Copia di prova.exe : copia di prova.exe
NMAKER.EXE : utility x i Makefile
NMAKE.EXE : " " "


Non lanciate prova.exe perch� non fa nulla serve solo x applicare la patch.
ne ho fatta anche una copia, perch� una volta patchato l'originale patch.exe
non riapplicher� la patch sul file gi� patchato.

Grazie Iczelion, Kill3xx e a tutti i membri di RingZer0!
happy CrAkInG... Pusillus.
============================================================================
Copyright:

Questo testo pu� essere liberamente divulgato a patto di non essere modificato in nessuna sua parte.
La presente copia in particolare � riservata al progetto UIC su richiesta di Quequero.
============================================================================
Pusillus