Ciao gente,
oggi mi stavo facendo i fatti miei quando ho visto gli address postati da arow (grazie arow), sinceramente penso che siano gli stessi di prima visto che a me warrock non si è aggiornato
comunque il punto è un altro, negli addy ho fatto caso a questo:
#define dwASM_MESSAGEBOX 0x00418B8D // 23 April 2012
qui sorge la domanda, cosa sarà mai?
e la seconda, ma come si usa?
alla prima rispondo dicendo che è l'indirizzo della funzione che se chiamata visualizza a video una finestrella con un messaggio di testo
alla seconda rispondo tra poco.
Intanto vediamo cosa si ottiene riuscendo ad usarla:
e adesso vediamo come procedere.
Se guardiamo in IDA che faccia ha la funzione a quell'indirizzo vediamo questo:
come si vede (parte in alto, arg_0), la funzione si aspetta un solo parametro, ovvero il messaggio da visualizzare, quindi possiamo immaginare che la dichiarazione della funzione sarà qualcosa del genere:
Codice:
void (*msgbox)(char* testo);
cosi facendo abbiamo dichiarato "msgbox" come un puntatore ad una funzione che prende un puntatore a caratteri come parametri e che non torna nessun valore (void)
però sto puntatore lo dobbiamo inizializzare con l'indirizzo della funzione (quello trovato negli addies di arow) e quindi facciamo cosi:
Codice:
void (*msgbox)(char* testo)=(void (__cdecl *)(char*))0x00418B8D;
come si vede davanti all'indirizzo ho messo quello che si chiama "casting" ovvero devo dire al compilatore a che "tipo" deve convertire il numero che gli ho passato (0x418b8d)
vediamo meglio, controllando innanzitutto come appare di solito un casting molto piu semplice, ad esempio (visto spesso nelle hacks) :
Codice:
DWORD dwPlayerPtr = (DWORD*)0xA01808;
Questo dice "converti il numero 0xA01808 in puntatore a DWORD e assegnalo alla variabile dwPlayerPtr"
adesso vediamo quello piu complesso di prima
Codice:
(void (__cdecl *)(char*))
questo dice di interpretare il numero a destra a "puntatore a funzione che prende un parametro (puntatore a caratteri) e che non torna niente (void)"
e quel "__cdecl" ?
quello serve a specificare la "calling convention" della nostra funzione.
E' molto importante, perchè se per caso chiamassimo la funzione con la calling convention sbagliata il gioco crasherebbe.
Infatti la calling convention serve a stabilire tra le altre cose come vengono passati i parametri, chi si occupa di togliere i parametri passati dallo stack etc.
Come mai __cdecl allora?
perchè dando un occhio con IDA si direbbe che è il modo usato da warrock per chiamare la funzione, vediamo un esempio di chiamata:
come si vede viene pushato l'unico parametro (il testo da visualizzare) e dopo la chiamata troviamo un pop che si occupa di rimuovere il parametro.
Bene questo comportamento assomiglia tanto alla calling convention del __cdecl
dalla documentazione microsoft, riporto solo quello che ci interessa:
Codice:
Element Implementation
Argument-passing order Right to left
Stack-maintenance responsibility Calling function pops the arguments from the stack
quindi riassumendo vediamo nella nostra hack come andiamo a chiamarla sta funzione:
Codice:
void (*msgbox)(char* testo)=(void (__cdecl *)(char*))0x00418B8D;
msgbox("Ciaaaao HackMix!! :D ");
detto questo vi saluto sperando che lo abbiate trovato interessante
ciao
Digger