Copy Link
Add to Bookmark
Report

Reversing, aggiunta di funzioni, modifica del codice esistente e cracking classico in un bersaglio doc di casa Micro$oft: NOTEPAD.EXE....DESCR...

DrWatson's profile picture
Published in 
guide hacker
 · 6 years ago

Hiho!

'Mmazza che titolone impegnativo :)))
allora....eccoci qui di nuovo alle prese con mamma Micro$oft...in questo tutorial spieghero' per filo e per segno il procedimento che ho seguito per modificare qua e la' il caro vecchio Notepad.exe in modo da aggiungere/rimuovere/modificare qualche funzione, per meglio adattarlo al progetto che stiamo cercando di portare a termine io, Anub|s e Insanity.

Ho gia' pubblicato un tutorial sulla creazione di Hnotepad, ma chi ci ha dato un'occhiata si sara' reso conto che il tutorial precedente era improntato solo e unicamente alla compatibilita' con Windows 95, niente 98, e soprattutto avra' notato che la generazione del codice era strettamente legata al computer su cui veniva eseguita. Io stesso suggerivo a qualcuno di lavorarci su, ma alla fine ho reso il tutto trasportabile...e qui vi descrivero' come, con poche aggiunte/cambiamenti marginali, il vostro codice funzionera' sia sotto 98 che sotto 95.

Un'ulteriore miglioria rispetto al tutorial precedente sta nel fatto che dopo le modifiche che vi descrivero' in questo tutorial il vostro notepad leggera' files ben piu' grandi dei soliti ffff bytes (un ringraziamento particolare a GEnius per la sua idea, scusate il gioco di parole, a dir poco geniale :), fermo restando che potrete solo visualizzarli, non editarli -- ricordate il nag della memoria insufficiente ? ho ritenuto opportuno lasciarlo, puo' essere comodo avere un nag che vi avverte se la vostra pagina sta eccedendo i 50 k. Ciononostante potrebbe darsi che alla prossima edizione ci infilo un'opzione apposta, chi lo sa...hnotepad e' un progetto in continua evoluzione, ed e' strabiliante il numero di persone che mi chiede di aggiungere funzioni :)

Ecco le sezioni del tutorial:


* PARTE 1 : Premesse


* PARTE 2 : INTRO A HNOTEPAD


* PARTE 3 : CREAZIONE DI HNOTEPAD:

FASE 1 : IL NUOVO MENU
FASE 2 : L'ABOUT BOX
FASE 3 : AGGIUNTA DI MASKS ALLA STRUTTURA OPENFILENAME
FASE 4 : AGGIUNTA DEL FILE .INI
FASE 5 : RIMOZIONE DEL LIMITE NELLA GRANDEZZA DEI FILES APERTI


* PARTE 4 : Bugs conosciuti

* PARTE 5 : Saluti


PARTE 1: Premesse

Era un tempestoso giorno di bufera, quando mi avventurai per i meandri dell'IRC in cerca di un canale amico, che trovai essere #crack-it....c'erano i soliti amici di sempre, a partire da Insanity, fino a Quequero e ad Anub|s....chissa' come io ed Insa (che e' il webmaster di RingZ3r0) cominciammo a parlare della programmazione in raw html (cosa in cui lui e' particolarmente capace:), e mi disse che il tool usato per le sue pagine web e' semplicemente il Notepad di Window$....notai una certa partecipazione anche da parte di Anub|s, che evidentemente sosteneva le tesi del nostro amico...Ad un certo punto, mi venne un idea....perche' non iniziare un simpatico progetto ? proposi l'idea agli astanti: creare un bel file .hlp (tipo guida di Window$) con tutte le basi necessarie a fornire una COMPLETA conoscenza della programmazione in raw html, senza bisogno di ingombranti editors visuali (WYSIWYG).....ovviamente, unito a tale file, ci sarebbe stato il dovuto editor di testo, e chi meglio di un Notepad.exe "riveduto e corretto" sarebbe servito ai nostri scopi ?? Anub|s sembro' entusiasta dell'idea, e Insa successivamente gli promise che avrebbe messo la sua parte nella scrittura del file di help...cosicche' i compiti erano gia' stati divisi...a loro la scrittura dell'help, e a me il reversing e la modifica del notepad....
Ora so benissimo che questo tutorial non ha nessun motivo di essere :), ma ho ritenuto opportuno scrivere qualcosa, giusto per dimostrare quanto puo' essere (relativamente) semplice modificare, rimuovere e aggiungere funzioni a un qualsiasi target gia' compilato...e per questo semplice motivo, eccovi la descrizione completa della creazione di Hnotepad.exe...

NOTA IMPORTANTE: Nonostante in questo tutorial venga descritta la creazione di un Hnotepad universale (sia per 95 che per 98), io usero' il file Notepad.exe che viene fornito con WINDOWS 95...quindi vi consiglio di procurarvi quello per seguire questo tutorial. Funzionera' perfettamente anche sotto il vostro Windows 98, garantito.

La premessa finale e' quella solita, consiglio vivamente al lettore una buona conoscenza di base del linguaggio Assembly per Windows, e del reversing in generale.

TOOLS USATI:

* W32Dasm v8.93
* SoftICE v3.24
* HIEW v6.1
* Borland Resource Workshop (BRW) v4.5
* ProcDump32 v1.3
* API Reference


PARTE 2 : INTRO A HNOTEPAD

C'e' poco da dire....comunque vi enunciero' in modo sommario cio' che faremo in questo tutorial:

* Aggiungeremo un menu a Notepad, che aprira' il nostro nuovo file .hlp
* Creeremo l'about box (ora come ora non ne esiste uno vero, ma capirete in seguito)
* Faremo in modo che nelle masks (*.bla) dei dialogs "Apri file" e "Salva con nome" compaiano anche i "Files HTML" (sia *.htm che *.html), "Files JS", e i "Files VBS".
* Aggiungeremo un comodo file .INI, in cui verra' salvato lo stato del WordWrapping (A capo automatico) e il nome dell'ultimo file aperto. Al riavvio, il wrapping verra' riposizionato nello stato definito dal file, e l'ultimo file aperto sara' riaperto automaticamente se hnotepad viene lanciato senza command line. Inoltre, tale file .INI viene creato automaticamente da Hnotepad ad ogni uscita dal programma, quindi non c'e' problema nel danneggiarlo o nello scriverci dentro.
* Elimineremo la limitazione nella grandezza del file aperto, il vostro Hnotepad non avra' limiti di dimensione del file visualizzato. Per fare cio', non toccheremo la Import Table ma utilizzeremo codice di scansione del Kernel (e di qualsiasi altra libreria in memoria), che, come vedrete in seguito, e' universale e potra' ritornarvi MOLTO utile quando non avete spazio per inserire GetProcAddress tra le API importate.

Ecco tutto....andiamo!!!!


PARTE 3 : LA CREAZIONE DI HNOTEPAD

FASE 1 : IL NUOVO MENU

Allora.....cominciamo con il cercare di capire COSA dovremo fare al nostro target: dobbiamo AGGIUNGERE un menu a quelli gia' presenti del programma...ma teniamo presente che nel corso della sessione avremo SICURAMENTE bisogno di aggiungere parti di codice "nostro" al file...nel caso del menu, dovremo aggiungere quella parte della window procedure che analizza le id di menu selezionate relativa alla scelta del nostro nuovo menu. Cominciamo con il vedere come si comporta il nostro target quando deve analizzare le id...potremmo risalire alla window procedure tramite la API RegisterClass e ottenere l'indirizzo della window procedure, ma saremo molto pratici, e breakeremo nel punto esatto che ci interessa. Abbiamo detto che ci interessa aggiungere un menu. Quindi proviamo ad analizzare il comportamento del programma nel caso in cui viene scelto un menu: l'API da utilizzare e' percio' WinHelpA (che fa partire il file winhelp.exe sotto \windows, che serve ad aprire qualsiasi file .HLP in formato guida di windows). In SoftICE, quindi, "BPX WinHelpA". Poi andiamo in notepad, e selezioniamo, dal menu "?", l'item "Guida in linea".
Sice breakkera' su WinHelpA: F12 e vi ritroverete al caller, che sara' qui:

 
:00401E51 FF7514 push [ebp+14]
:00401E54 57 push edi
:00401E55 FF7508 push [ebp+08]
:00401E58 E80FF3FFFF call 0040116C ; < -- TORNIAMO DA QUESTA CALL
:00401E5D 85C0 test eax, eax
:00401E5F 0F8582000000 jne 00401EE7
:00401E65 FF7514 push [ebp+14]
:00401E68 57 push edi
:00401E69 56 push esi
:00401E6A FF7508 push [ebp+08]

* Reference To: USER32.DefWindowProcA, Ord:0078h
|
:00401E6D FF1534744000 Call dword ptr [00407434]
:00401E73 EB74 jmp 00401EE9


Bene....DefWindowProcA sta a rappresentare la zona di codice della window procedure dove i messaggi vengono elaborati con le modalita' predefinite (ad es, se non analizziamo un tal messaggio, questi comunque verra' "catturato" da DefWindowProcA che lo elaborera' di conseguenza). Cio' significa che comunque il valore del menu item passa per (e viene controllato da) quella call a 1E58 (come il parametro 2/3, passato in EDI) dalla quale noi stiamo tornando.
Entriamovi:

 
* Referenced by a CALL at Address:
|:00401E58
|
:0040116C 55 push ebp
:0040116D 8BEC mov ebp, esp
:0040116F 81EC04010000 sub esp, 00000104
:00401175 33C0 xor eax, eax
:00401177 56 push esi
:00401178 57 push edi

:00401179 BE38614000 mov esi, 00406138
:0040117E 8DBDFCFEFFFF lea edi, dword ptr [ebp+FFFFFEFC]

:00401184 B940000000 mov ecx, 00000040
:00401189 A4 movsb
:0040118A 8DBDFDFEFFFF lea edi, dword ptr [ebp+FFFFFEFD]
:00401190 F3 repz
:00401191 AB stosd
:00401192 66AB stosw
:00401194 AA stosb
:00401195 0FB7750C movzx esi, word ptr [ebp+0C] ; < -- L'ID VALUE DEL MENU SCELTO
:00401199 83FE20 cmp esi, 00000020 ; COMPARA ESI E 20h
:0040119C 8BC6 mov eax, esi
:0040119E 7F1A jg 004011BA ; SE ESI > 20h, SALTA
:004011A0 0F84C1030000 je 00401567
:004011A6 48 dec eax
:004011A7 83F81B cmp eax, 0000001B
:004011AA 7736 ja 004011E2
:004011AC 0FB68838174000 movzx ecx, byte ptr [eax+00401738]
:004011B3 FF248DF8164000 jmp dword ptr [4*ecx+004016F8] ; ALTRIMENTI ELABORA DI
CONSEGUENZA


Abbiamo quindi l'ID del menu (potete controllarle una per una con il brw, sotto la voce menu) in esi, e poi un check se esi e' maggiore di 20h. 20h equivale a 32 dec, quindi sappiamo che le id con valore inferiore a 32 verranno elaborate da un jump variabile da caso a caso, che puntera' ogni volta al codice adeguato (il jmp a 11B3). Quindi, per non complicarci la vita, il nostro menu dovra' avere un ID value maggiore di 32, cosicche' potremo elaborarlo susseguentemente al jg a 119E, che porta qui:

 
* Referenced by a JUMP at Address:
|:0040119E(C)
|

* Possible Ref to Menu: MenuID_0001, Item: "Taglia CTRL+X"
|
:004011BA 3D00030000 cmp eax, 00000300 ; 300h (768 dec) = menu item "Taglia"
:004011BF 7C21 jl 004011E2

* Possible Ref to Menu: MenuID_0001, Item: "Copia CTRL+C"
|
:004011C1 3D01030000 cmp eax, 00000301
:004011C6 0F8E0F030000 jle 004014DB

* Possible Ref to Menu: MenuID_0001, Item: "Incolla CTRL+V"
|
:004011CC 3D02030000 cmp eax, 00000302
:004011D1 0F8427030000 je 004014FE
..............
..........

e cosi' via con gli altri checks. Ecco trovato un buon punto per inserire la deviazione al NOSTRO codice, che elaborera' per primo l'ID value relativo al nuovo menu. Ma prima dobbiamo crearlo, questo menu! :)
Per fare cio', andate in BRW e, nella sezione menu, sotto il menu "?", aggiungete un nuovo item, io l'ho chiamato "Anub|s+Insa's Help su HTML". Assegnategli il valore 33 (21h), che servira' a farlo analizzare da questa procedura e non dal jmp variabile di prima. Qualsiasi valore piu' alto di 32 andra' bene (purche' non sia gia' legato a qualche altro item).
Ora, nella sezione "KEY" aggiungete "VK_F1", che servira' a far uscire QUESTO menu e NON quello di notepad quando premiamo il tasto F1. Non dimenticatevi di cancellare la stessa dicitura dal menu attuale di notepad. Salvate, e come per magia al prossimo avvio di notepad vi ritroverete questo nuovo menu che come sapete ha id value 21h. Adesso, quindi, dobbiamo risolvere il problema dell'aggiunta del nostro codice al file. Come facciamo a inserirlo ?? Ci sono un paio di cosette da controllare. Se aprite il file con HIEW, con ProcDump o con chissa' quanti altri programmi, avrete tutte le info che vi servono all'aggiunta del vostro codice. Ovviamente, come sapete, non possiamo occupare PIU' bytes di quanti sono effettivamente presenti nella sezione .TEXT, e quindi siamo costretti ad APPENDERE il nostro codice alla fine del file, per poi ridirezionare i jumps dalla sezione .TEXT del pe alla sezione in cui abbiamo aggiunto il codice, che ora andremo a vedere qual'e'....solitamente, l'ultima sezione andra' bene: nel caso di notepad, pero', abbiamo gia' aggiunto un menu, cosa che ha portato all'aumento in dimensione della sezione .RSRC: questo ingrandimento ha portato allo spostamento della suddetta sezione alla fine del file. Potete controllare facilmente entrando in HIEW, premendo F8 (dal modo hex o asm) per visualizzare le info relative all'header e quindi F6 per le sezioni. Quindi, dicevo, il pe ora e' stato modificato da parte del brw, e ora l'ultima sezione e' la .RSRC. Ma resta il fatto che, "nativamente", il file notepad.exe finiva con la sezione .RELOC, che e' quella in cui andremo ad aggiungere il nostro codice (almeno all'inizio, quando finiremo lo spazio disponibile ci serviremo della .RSRC). La prima cosa da fare e' controllare lo SPAZIO che abbiamo (in termini di bytes) per aggiungere codice: controlliamo la dimensione virtuale (VirtSize, = 91Eh) e quella fisica (PhysSize, = A00h); la virtsize ci indica il numero di bytes che non dobbiamo modificare, quelli cioe' che sono gia' usati dal prog, mentre la physsize ci indica la dimensione "raw" della sezione: una semplice sottrazione A00h-91Eh ci dara' E2h (cioe' 226 dec.) bytes liberi, in cui potremo aggiungere il nostro codice. Non avremo bisogno di ingrandire la sezione, perche' abbiamo tutto lo spazio che ci serve; se la dovevate ingrandire, PRIMA di creare il menu con il brw, avreste dovuto caricare il file con procdump, editare la sezione, e aumentarne la dimensione fisica. Bene! Resta un problema....come fare a sapere A QUALE OFFSET scrivere il nostro codice?? Semplice...dobbiamo tenere d'occhio l'offset di inizio della sezione: sappiamo che e' 5000h, quindi Offset_Iniziale+VirtSize = 5000h+91Eh = 591Eh, il nostro entrypoint per l'aggiunta di codice. Abbiamo pero' anche un'ALTRO problema...CHE codice dobbiamo aggiungere ?? :))
Prima di tutto, tracciamo uno schema delle operazioni che vogliamo che il nostro nuovo codice compia. Per far si' che il codice salti dalla sezione .TEXT (dove c'e' la call che elabora le id values) alla sezione .RELOC (dove c'e' il nostro codice), avremo bisogno necessariamente di sostituire qualche byte con un jump....prenderemo il CMP a 11BA: dovremo fare quindi in modo di fare si che quel cmp diventi un jump ad un'altra sezione: questo, una volta, poteva comportare qualche fastidio: un tempo di solito un cracker che aggiungeva codice proprio ai programmi utilizzava un compilatore per generare gli opcodes validi, dovendo perdere tempo con sottrazioni inerenti il RVA della prima e della seconda sezione, ecc....poi, un bel giorno e' arrivato
SoftICE con la sua funzione A (Assemble instruction) :))))))))
Grazie a questa salvezza di tool, possiamo assemblare le istruzioni al runtime, volta per volta, e ottenere pertanto gli opcodes con i quali successivamente patcheremo fisicamente il target.
Gli opcodes saranno universali per le push, per i cmp ecc., e pertanto per QUESTO tipo di operazioni possiamo utilizzare HIEW direttamente, ma per i jumps a sezioni diverse avremo bisogno di SoftICE, poiche' la distanza tra gli offsets del punto di partenza e del punto di arrivo in due sezioni diverse non sono ottenibili con il patching da HIEW. Si, allora ok per i jumps, ma per le CALLS come facciamo ?? Le calls alle funzioni API (che noi utilizzeremo) non sono nient'altro che calls ad un puntatore dword, che punta ad uno specifico offset in una sezione denominata .IDATA (imported data): ogni API che verra' usata dal programma viene inserita in quella sezione all'avvio, e per servircene dal codice dovremo usare CALL [DWORD_PTR_DELLA_API]. Per scoprire quale Dword Pointer chiamare per una determinata API, utilizzeremo W32Dasm. Ad ogni API chiamata (basta fare una ricerca con il nome della funzione nel disassembly) corrispondera' una call dword ptr [xyz]: ogni volta che vi serve una tale API chiamerete da hiew quel dword ptr, niente piu' niente meno.
Tutto cio' e' molto semplice, tuttavia potreste chiedervi una cosa...COME facciamo a sapere, da SoftICE, a QUALE offset saltare dalla sezione .TEXT per raggiungere il nostro codice ?? La locazione non la possiamo trovare con W32Dasm perche' la parte disassemblata riguarda soltanto la sezione .TEXT, non la .RELOC (dove ci sara' il nostro codice)...la soluzione sta in HIEW: aprite notepad.exe con hiew: una volta in modo HEX o DISASM, premete ALT+F1 per cambiare tra visualizzazione degli offsets in modo Global o Local. Posizionatevi su LOCAL, e noterete che, se prima avevate "global", ora verra' mostrato l'offset completo di imagebase, che sara' tutto cio' di cui abbiamo bisogno per sapere a quale VA (Virtual Address) corrisponde l'offset a cui vogliamo saltare, e inserire "JMP VA_del_nuovo_codice" da Sice, lasciando a lui il compito della generazione degli opcodes. SOLO PER I JMPS (jump short, quelli da 2 opcodes per intenderci) e per quelli non troppo distanti non avremo bisogno di Sice, ma potremo inserire direttamente l'offset relativo in HIEW, in quanto il jump non esce da un raggio ristretto di codice, e HIEW e' ancora in grado di generare degli opcodes validi. Percio' d'ora in poi, quando vedrete degli asterischi (*******) a fianco dell'istruzione, significa che la stessa e' stata assemblata con softice, e che ho patchato il file con i bytes che questi mi ha restituito. Un'altra cosa....abbiamo detto che dobbiamo far aprire un nuovo file con questo menu, che sara' il file di Anub|s e Insanity sulla programmazione in HTML...questo file avra' pure un nome (qualcosa.hlp), anche se io non lo conosco ancora (ma nemmeno loro due mi sa :))), comunque per la prova useremo un file fittizio HNOTEPAD.HLP. Allora, dicevo, dobbiamo fare si che il codice riconosca anche il nome "HNOTEPAD.HLP",
solo che questo nome, ovviamente, non e' presente da nessuna parte....quindi dobbiamo aggiungerlo alla STRINGTABLE del target. La stringtable altro non e' che il posto dove possiamo visualizzare tutte le stringhe contenute in un file alle cui risorse abbiamo accesso. Potremmo anche sostituire qualche stringa vecchia con la nuova "HNOTEPAD.HLP", oppure inserire direttamente nel codice .exe la nostra stringa (ideale per quando non avete accesso alle risorse, e cosa che faremo anche nel corso di questo tutorial), ma visto che abbiamo accesso alle risorse di notepad.exe, la AGGIUNGEREMO alla stringtable, e la tratteremo proprio come una qualsiasi stringa esistente gia' da prima. Quindi il primo passo e', in BRW, selezionare l'ULTIMA stringtable (la 48), premere il tasto destro e EDITARLA IN MODO TESTUALE (attenti a non premere solo edit, o non potrete aggiungere items). Alche', semplicemente aggiungete questa riga alla fine:

 
58, "hnotepad.hlp"


Salvate il file, ed il gioco e' fatto! Adesso abbiamo una stringa nuova di zecca che potremo utilizzare a nostro piacimento...cominciate ad intravedere l'enormita' delle possibilita' che ci si parano davanti ?? :D
Allora....a questo punto dovete sapere (se non lo sapevate gia':) che le stringhe si caricano dalla stringtable con la funzione LoadStringA, la cui sintassi e':

 
int LoadString(
INSTANCE hInstance, // handle del modulo contenente la risorsa della stringa
UINT uID, // ID della stringa (nel nostro caso 58, quindi 3Ah)
LPTSTR lpBuffer, // Indirizzo del buffer di ricezione della stringa
int nBufferMax // dimensione massima del buffer (n. di chars da prelevare dalla stringa)
// se la stringa e' piu' corta non fa niente, ma se e' piu' lunga viene
// troncata!
);


Hmmm....il problema qui e' il buffer....come facciamo a sapere quale buffer utilizzare per inserirvi la nostra nuova stringa ?? Beh, un po' di esperienza pratica direi...cominciate a settare breakpoints, e troverete molto presto un buffer adatto alla ricezione. Avete due scelte: trovare un buffer che viene caricato UNA volta all'inizio e MAI piu' (in tal caso dovrete usare il loadstring una volta in piu', una specie di PUSH e POP con gli indirizzi per intenderci), o usare un buffer che viene caricato da un altro LoadStringA quando serve....in tal caso, potete sfruttarlo quando e quanto volete, tanto alla fine sara' il programma stesso a ripristinare il suo contenuto originale, all'occorrenza. Quest'ultima e' la scelta piu' comoda, decisamente. Quindi, ad esempio, prendiamo la message box "Questo documento e' troppo grande per notepad, aprire wordpad??"...se premete si, noterete un LoadStringA che carica in un buffer la variabile "wordpad.exe", che serve ad avviare il programma....eccovi il disasm (ricordatevi che i valori vengono pushati sulla stack in ordine inverso):

 
:00402D70 6804010000 push 00000104 ; PUSHA N.DI CARATTERI DA PRENDERE DALLA STRINGA
:00402D75 8D85B8FEFFFF lea eax, dword ptr [ebp+FFFFFEB8] ; EAX DIVENTA=63F8C4h
:00402D7B 50 push eax ; PUSHA 63F8C4h COME BUFFER DI RICEZIONE DELLA STRING

* Reference To: USER32.LoadStringA, Ord:0168h
|
:00402D7C 8B1DB0734000 mov ebx, dword ptr [004073B0]
:00402D82 837D1001 cmp dword ptr [ebp+10], 00000001 ; (DUMMY)
:00402D86 1BFF sbb edi, edi ; (DUMMY)

* Possible Reference to String Resource ID=00056: "wordpad.exe"
|
:00402D88 6A38 push 00000038 ; ID DI "WORDPAD.EXE" NELLA TABLE
:00402D8A FF3570514000 push dword ptr [00405170] ; HANDLE DEL MODULO CON LA TABLE
:00402D90 FFD3 call ebx ; CHIAMA LOADSTRING


Ottimo! Abbiamo trovato il nostro buffer...segnatevi quell'indirizzo di memoria : 63F8C4h...anche se vi sovrascriveremo la nostra stringa "hnotepad.hlp", il buffer verra' ripristinato da questo loadstring ogni qual volta si cerchera' di avviare wordpad. Notate che possiamo, in questo modo, anche impossessarci dell' informazione "invariabile" relativa alla funzione, ovvero l'handle del modulo contenente la stringtable (il "dword ptr [405170]" pushato a 2D8A, che contiene il valore 400000h, che sara' il nostro handle). Potremmo pushare direttamente 400000h all'occorrenza, ma utilizzeremo sempre questo puntatore (ricordatevi che quando modificate targets gia' compilati, e' sempre piu' sicuro, soprattutto per chi non ha molta dimistichezza, verificare i dati due volte, e in linea generale usare IL PIU' POSSIBILE i puntatori e IL MENO POSSIBILE i valori immediati).

Adesso sappiamo come ottenere la stringa "hnotepad.hlp" nel nostro codice, ma ci manca ancora il dettaglio finale....COME chiamiamo la funzione WinHelpA? Ancora una volta la API reference ci viene in soccorso:

 
BOOL WinHelp(

HWND hWndMain, // handle della finestra che sta aprendo l'help
LPCTSTR lpszHelp, // indirizzo della stringa con la path
UINT uCommand, // tipo di help
DWORD dwData // dati extra
);


Beh, qui e' semplice....ancora una volta, ci renderemo conto del modo in cui viene chiamata la funzione esaminando esempi PRATICI della stessa all'interno del codice: quindi, un BPX WinHelpA ci servira' per analizzare il codice quando premiamo ?/Guida in linea... ecco a voi:

 
:0040121C 6A00 push 00000000 ; NIENTE DATI EXTRA
:0040121E A194604000 mov eax, dword ptr [00406094] ; EAX=PUNTATORE A STRINGA "NOTEPAD.HLP"
:00401223 6A0B push 0000000B ; =HELP_FINDER, SEMPLICEMENTE UN MODO DI CHIAMATA HELP
:00401225 50 push eax ; PUSHA "NOTEPAD.HLP"
:00401226 FF3500604000 push dword ptr [00406000] ; ECCO IL PUNTATORE ALL'HANDLE DELLA WINDOW

* Reference To: USER32.WinHelpA, Ord:0225h
|
:0040122C FF154C744000 Call dword ptr [0040744C] ; CHIAMA WINHELPA


Fantastico....l'handle (che era la cosa che ci premeva di piu') lo troveremo, a tempo debito, nel dw

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT