Zoom Icon

Patch in win32asm

From UIC Archive

Win32asm Patch

Contents


Patch in win32asm
Author: Pusillus
Email:
Website:
Date: 05/02/1999 (dd/mm/yyyy)
Level: Working brain required
Language: Italian Flag Italian.gif
Comments:



Introduzione

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 lo trovate piu' sotto nel tutorial.


Per Iniziare

Dal sito: scaricatevi 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.

utile per i programmatori, oppure usatene uno che vi aggrada di più.

alternativa potete prelevarne alcuni sulla pagina di Iczelion oppure farvi i file .rc a mano. (O meglio scaricate Borland Resource Workshop su questo sito)

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 programma

 -----------------
| Winmain  | tasto "EXIT"
|--------->| |----------------> uscita
| -----------------
| |
| | tasto "OK"
| |
| |
| -----------------
| | | errore 1
| | apri file |------------------------|
| ----------------- |
| | |
| |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.


Note finali

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.