Zoom Icon

Iczelion 25

From UIC

Bitmaps

Contents


Infos
Author: §-Death_Reaver-§
Email: death.reaver@leonardo.it
Website: deathreaver.altervista.org
Date: 03/06/2005 (dd/mm/yyyy)
Level: Some skills are required
Language: Italian Image:Flag_Italian.gif
Comments:



Introduction

Continua la traduzione dei tutorial di Iczelion…


Tools

Allegato Masm v8


Essay

Teoria

Le bitmap possono essere considerate come foto nel computer. Ci sono molti tipi di foto usati dal computer ma Windows supporta di standard solo le Windows Bitmap Graphic Files (.bmp).Le bitmap trattate in questo tutorial saranno proprio windows bitmap graphic files. La via più facile per usare una bitmap è di usarla come risorsa. Ci sono due metodi per farlo.

1)La si può inserire nel resource script(.rc) così:


#define IDB_MYBITMAP 100
IDB_MYBITMAP BITMAP "c:\immagini\esempio.bmp"


Questo metodo utilizza una costante per definire una bitmap. La prima riga crea una costante chiamata IDB_MYBITMAP che ha il valore 100. Useremo questo nome per "passare" la bitmap al programma. La riga successiva dichiara una risorsa di tipo BITMAP. Dice al resource-compiler dove trovare il file bmp.


2)L'altro metodo usa un nome per rappresentare la bitmap


MyBitMap BITMAP "c:\immagini\esempio.bmp"

Con questo metodo passi la bitmap al programma tramite la stringa "MyBitMap" invece di un valore. Entrambi i metodi vanno bene finché sai che metodo stai usando. Adesso che abbiamo messo la bitmap nel file di risorse possiamo andare avanti mostrandola nella client area della nostra finestra.


1) Chiamiamo LoadBitmap per prendere l'handle della bitmap. LoadBitmap ha il seguente prototipo:


LoadBitmap proto hInstance:HINSTANCE,lpBitmapName:LPSTR

Questa funzione restituisce l'handle della bitmap. hInstance è l'instance-handel del tuo programma. lpBitmapName è un puntatore alla stringa che contiene il nome della bitmap(nel caso del secondo metodo). Se stai usando una costante per definire la bitmap, puoi metterne il valore qui. (nell'esempio sotto sarà 100).

Un piccolo esempio in ordine:


Primo metodo:

.386
.model flat, stdcall
...............
.const
IDB_MYBITMAP    equ 100
...............
.data?
hInstance  dd ?
..............
.code
.............
   invoke GetModuleHandle,NULL
   mov hInstance,eax
............
   invoke LoadBitmap,hInstance,IDB_MYBITMAP
...........


Secondo Metodo:


.386
.model flat, stdcall
................
.data
BitmapName  db "MyBitMap",0
...............
.data?
hInstance  dd ?
..............
.code
.............
   invoke GetModuleHandle,NULL
   mov hInstance,eax
............
   invoke LoadBitmap,hInstance,addr BitmapName
...........

2) Ottenere l'handle del Device Context (DC). Lo si può ottenere chiamando BeginPaint in risposta a WM_PAINT o chiamando GetDC dovunque.

3) Creare un device context in memoria che abbia gli stessi attributi del device context appena ottenuto. L'idea è di creare una specie di superficie invisibile dove possiamo disegnare la nostra bitmap. Quando abbiamo finito questa operazione, basta copiare il contenuto della superficie invisibile nell'attuale device context con una funzione. Questo è un esempio della tecnica a "doppio buffer" usata per mostrare velocemente le immagini sullo schermo. Si puo creare questa superfice invisibile chiamando CreateCompatibleDC.

CreateConpatibleDC proto hdc:HDC

Se la chiamata riesce, restituisce in eax l'handle del memory device context. hdc è l'handle del device context del quale vuoi che sia compatibile.


4) Adesso che abbiamo la nostra superficie invisibile, possiamo disegnare inserendo la bitmap dentro al mDC(memory device context). Questo si può fare chiamando SelectObject con l'handle del mDC come primo parametro e l'handle della bitmap come secondo. SelectObject ha il seguente prototipo:

SelectObject proto hdc:HDC, hGdiObject:DWORD

5) Ora la bitmap è disegnate nel mDC. Quello che rimane da fare è copiarlo nell'attuale device context, ossia il vero device context. Ci sono tante funzioni che ci permettono di farlo come BitBlt e StretchBlt. BitBlt copia semplicemente il contenuto di un DC a un altro e per questo è veloce, mentre, StretchBlt può estendere o comprimere la bitmap per riempire l'area di output. Qui useremo BitBlt:


BitBlt proto hdcDest:DWORD, nxDest:DWORD, nyDest:DWORD, 
nWidth:DWORD, nHeight:DWORD, hdcSrc:DWORD, nxSrc:DWORD,
nySrc:DWORD, dwROP:DWORD


hdcDest è l'handle del DC di destinazione

nxDest,nyDest sono le coordinate dell'angolo superiore sinistro della zna di destinazione

nWidth,nHeight sono la larghezza e l'altezza della zona di destinazione

hdcSource è l'handle del DC da copiare

nxSrc,nySrc sono le coordinate delangolo superiore sinistro da cui iniziare a copiare

dwROP è il codice di "rasterizzazione" (acronimo ROP) che decide come combinare i dati della bitmap con il colore già esistente nella zona di destinazione per


ottenere il risultato finale. La maggior parte delle volte si vuole sovrascrivere il colore esistente con uno nuovo.

6) Quando hai finito con la bitmap, cancellala con una chaimata a DeleteObject.


Finito! Per ricapitolare: hai bisogno di mettere la bitmap nel resource script. Quindi la carichi con LoadBitmap. Otterrai l'handle della bitmap. Dopo prendi l'handle del DC dell'area dove vuoi disegnare. Quindi crei un device context in memoria compatibile con il device context precedentemente ottenuto. Metti la bitmap nel mDC ottenuto e copi il contenuto del mDC nel DC reale.

Esempio:


.386

.model flat,stdcall

option casemap:none

include \masm32\include\windows.inc

include \masm32\include\user32.inc

include \masm32\include\kernel32.inc

include \masm32\include\gdi32.inc

includelib \masm32\lib\user32.lib

includelib \masm32\lib\kernel32.lib

includelib \masm32\lib\gdi32.lib



WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

IDB_MAIN equ 1



.data

ClassName db "SimpleWin32ASMBitmapClass",0

AppName db "Win32ASM Simple Bitmap Example",0



.data?

hInstance HINSTANCE ?

CommandLine LPSTR ?

hBitmap dd ?



.code

start:

invoke GetModuleHandle, NULL

mov hInstance,eax

invoke GetCommandLine

mov CommandLine,eax

invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT

invoke ExitProcess,eax



WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD

LOCAL wc:WNDCLASSEX

LOCAL msg:MSG

LOCAL hwnd:HWND

mov wc.cbSize,SIZEOF WNDCLASSEX

mov wc.style, CS_HREDRAW or CS_VREDRAW

mov wc.lpfnWndProc, OFFSET WndProc

mov wc.cbClsExtra,NULL

mov wc.cbWndExtra,NULL

push hInstance

pop wc.hInstance

mov wc.hbrBackground,COLOR_WINDOW+1

mov wc.lpszMenuName,NULL

mov wc.lpszClassName,OFFSET ClassName

invoke LoadIcon,NULL,IDI_APPLICATION

mov wc.hIcon,eax

mov wc.hIconSm,eax

invoke LoadCursor,NULL,IDC_ARROW

mov wc.hCursor,eax

invoke RegisterClassEx, addr wc

INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\

WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\

CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\

hInst,NULL

mov hwnd,eax

invoke ShowWindow, hwnd,SW_SHOWNORMAL

invoke UpdateWindow, hwnd

.while TRUE

invoke GetMessage, ADDR msg,NULL,0,0

.break .if (!eax)

invoke TranslateMessage, ADDR msg

invoke DispatchMessage, ADDR msg

.endw

mov eax,msg.wParam

ret

WinMain endp



WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

LOCAL ps:PAINTSTRUCT

LOCAL hdc:HDC

LOCAL hMemDC:HDC

LOCAL rect:RECT

.if uMsg==WM_CREATE

invoke LoadBitmap,hInstance,IDB_MAIN

mov hBitmap,eax

.elseif uMsg==WM_PAINT

invoke BeginPaint,hWnd,addr ps

mov hdc,eax

invoke CreateCompatibleDC,hdc

mov hMemDC,eax

invoke SelectObject,hMemDC,hBitmap

invoke GetClientRect,hWnd,addr rect

invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY

invoke DeleteDC,hMemDC

invoke EndPaint,hWnd,addr ps

.elseif uMsg==WM_DESTROY

invoke DeleteObject,hBitmap

invoke PostQuitMessage,NULL

.ELSE

invoke DefWindowProc,hWnd,uMsg,wParam,lParam

ret

.ENDIF

xor eax,eax

ret

WndProc endp

end start

 ;---------------------------------------------------------------------
 ; Il resource script
 ;---------------------------------------------------------------------
#define IDB_MAIN 1

IDB_MAIN BITMAP "tweety78.bmp"

Analisi: Non c'è molto da analizzare in questo tutorial ;)

#define IDB_MAIN 1
IDB_MAIN BITMAP "tweety78.bmp"

Definiamo una costante chiamata IDB_MAIN con valore 1.Usiamo questo valore come ID della bitmap. Il file incluso nelle risorse è "tweety78.bmp" che stà nella stessa cartella del resource script.

.if uMsg==WM_CREATE
     invoke LoadBitmap,hInstance,IDB_MAIN
     mov hBitmap,eax

In risposta a WM_CREATE chiamiamo LoadBitmap per caricare la bitmap dalle risorse, passandogli l'ID della bitmap come secondo parametro. Otterremo l'handle della bitmap. Adesso che la bitmap è caricata, possiamo disegnarla nella client-area della nostra finestra.

.elseif uMsg==WM_PAINT
     invoke BeginPaint,hWnd,addr ps
     mov    hdc,eax
     invoke CreateCompatibleDC,hdc
     mov    hMemDC,eax
     invoke SelectObject,hMemDC,hBitmap
     invoke GetClientRect,hWnd,addr rect
     invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY
     invoke DeleteDC,hMemDC
     invoke EndPaint,hWnd,addr ps

Abbiamo scelto di disegnare la bitmap in risposta a WM_PAINT. Prima chiamiamo BeginPaint per ottenere l'handle del DC. Quindi creiamo un DC compatibile in memoria con CreateCompatibleDC. Dopo mettiamo la bitmap nel DC in memoria con SelectObject. Determiniamo le dimensioni della client area con GetClientRect.

Possiamo ora mostrare la bitmap nella client-area chiamando BitBlt che copia la bitmap dal mDC al DC reale. Quando abbiamo finito di disegnare, non abbiamo più bisogno del mDC e quindi lo cancelliamo con DeleteDC. Terminiamo la sezione di disegno con EndPaint.

.elseif uMsg==WM_DESTROY
 invoke DeleteObject,hBitmap
 invoke PostQuitMessage,NULL

Quando non avremo più bisogno della bitmap, la cancelliamo con DeleteObject.


Note Finali

Saluto tutti i compagni di cracking e coding


Disclaimer

I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.

Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevoli e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.