View Full Version : asm stringhe
PUSH 0
PUSH EDX
PUSH *indirizzo stringa 1*
PUSH 0
CALL MessageBoxW
Domanda:
se ho due stringhe invece di una come le mando tutte e due a messagebox ?
Dipende dalla convenzione che stai usando.
Ad esempio mi pare che la convenzione C classica sia di passare i parametri sullo stack, quindi dovrai riempire lo stack per quanti sono i parametri della funzione che vai ad invocare.
Un'altra convenzione potrebbe essere di passare i parametri sui registri general purpose finché possibile e poi usare lo stack.
Dipende dal compilatore e da quale convenzione si sta adottando.
http://en.wikipedia.org/wiki/Calling_convention
PUSH 0
PUSH EDX
PUSH *indirizzo stringa 1*
PUSH 0
CALL MessageBoxW
Domanda:
se ho due stringhe invece di una come le mando tutte e due a messagebox ?
Sembra Winapi, quindi potrebbe essere __stdcall, quindi push dei parametri da destra a sinistra e poi call.
Qualcuno ti saprà dire meglio di sicuro.
lorenzo001
28-06-2014, 14:52
Forse non ho capito ma il problema è che tu vuoi visualizzare due stringhe concatenate con la MessageBox ?
Perché in questo caso non è un problema di come passare i parametri alla funzione (o con quale metodo) ma di concatenare le due stringhe prima in modo da ottenerne una sola e dopo passare l'indirizzo della stringa ottenuta alla MesageBox
Ho dimenticato di dire, sto usando ollydbg per provare la tecnica del codecave ma c'è poco spazio quindi devo mettere le stringhe sparse qua e là :mc:
I parametri passano dall'ultimo al primo come dice van9
lorenzo001
28-06-2014, 15:10
I parametri della MessageBox sono
int WINAPI MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
Quindi puoi visualizzare una stringa come testo e uno come titolo (sono il secondo e il terzo parametro)
Si quello lo so :fagiano:
Il problema è che nell'exe compilato c'è poco spazio libero quindi per formare una frase devo mettere più stringhe in indirizzi diversi
Daniels118
30-06-2014, 09:51
Come ti ha detto lorenzo001 devi prima concatenare le stringhe e poi passarle a MessageBox.
Puoi chiamare HeapAlloc per ottenere spazio in memoria a runtime, quindi vi concateni le stringhe attraverso chiamate successive a CopyMemory e poi richiami MessageBox passando l'indirizzo ottenuto da HeapAlloc.
C'è troppo poco spazio, ho risolto injectando una dll :muro:
cmq ho cambiato exe con uno con più spazio per fare qualche prova:
<$mirc_34.195447>
JMP $$2266D8 ; Bottone Timer, jmp al pushad
NOP
<$mirc_34.2266D8>
NOP; Y HALO THAR CAVA DESU~
pushad
CALL DWORD PTR DS:[$$227300] ; KERNEL32.GetProcessHeap
test eax, eax ; test if eax=0
jz @No
mov edx, eax
;MOV EBX,256
PUSH 256
PUSH 8
PUSH edx
CALL DWORD PTR DS:[$$2272B4] ; KERNEL32.HeapAlloc
test eax, eax ; test if eax=0
jz @No
mov ebp, eax
push 0xB
push @Dest
push 256
push ebp
call memcpy_s
test eax, eax ; test if eax=0
jnz @No ; Zero if successful; an error code on failure.
push 0x2
push @Yes
push 256
push ebp
call memcpy_s
test eax, eax ; test if eax=0
jz @Test ; Zero if successful; an error code on failure.
jmp @No
@Yes:
PUSH 0
PUSH @Test1
PUSH @TestYes
PUSH 0
CALL 75C2FD1E
jmp @Fine
@No:
PUSH 0
PUSH @Test1
PUSH @TestNo
PUSH 0
CALL 75C2FD1E
jmp @Fine
@Test:
PUSH 0
PUSH @Test1
PUSH ebp
PUSH 0
CALL 75C2FD1E
jmp @Fine2
@Fine2:
push edx
push 1
push ebp
call HeapFree
test eax, eax ; test if eax=0
jz @Fine ; If the function succeeds, the return value is nonzero.
jmp @No
@Fine:
popad
jmp $$1955AA
@Dest:
"0123456789\0"
@Test1:
"Test 1\0"
@TestYes:
"Yes\0"
@TestNo:
"No\0"
Non capisco perchè mi copia una "j" invece di "Ye", e poi crasha...
Se al posto di @Yes metto @Test1 mi copia giusto "Tes3456789", poi però crasha comunque :mc:
Sto usando mIrc 7.34 per fare prove :help:
Daniels118
02-07-2014, 08:36
Forse volevi scrivere "push @TestYes", attualmente stai copiando il codice macchina della routine "Yes" invece della stringa.
Il motivo per cui mettendo @Test1 ti esce quella roba è che memcpy_s non serve per copiare le stringhe, per cui non inserisce automaticamente il terminatore zero binario, devi specificare la lunghezza esatta della stringa più uno (idem quando copi @TestYes).
Il motivo per cui crasha sempre è che probabilmente la CALL 75C2FD1E legge la stringa, ma non trovando il terminatore sfora e fa una violazione di accesso alla memoria.
Correggi il numero di byte da copiare in accordo con la lunghezza della stringa e vedrai che funziona.
Oddio ci sono stato ore e non avevo fatto caso a quell'errore enorme con la label :muro:
Continua a crashare comunque anche se ho aggiunto un memset e la stringa è così:
http://www.japantrip.tk/imgboard/src/1404286171004.jpg
Daniels118
02-07-2014, 09:35
Hai modificato "push 0x2" prima di "push @TestYes" in "push 0x4"?
il \0 di @Dest c'è ed è quello che conta perchè la string deve finire lì.
lo \0 di @TestYes non lo devo mettere sennò poi MessageBoxA (75C2FD1E) mi tronca la frase li, l'ho seguita con il debugger fa un loop finchè non trova \0 quello che c'è dopo non lo guarda.
cmq ho tolto i memcpy_s e fatto andare sia @Yes @No e non danno problemi, ho fatto andare anche @Test passando il puntatore creato con heapalloc senza toccarlo mettendoci qualcosa e va anche cosi, il messagebox è vuoto perchè prima o poi becca conumque un \0
aggiungendo anche solo un memset con \0 va in crash dopo aver chiamato @Test :muro:
edit:
ho provato a mettere un breakpoint per vedere dove punta ebp, sono andato li, ho modificato a mano aggiungendo del testo poi ho fatto ripartire, facendo così non crasha...
crasha solo se uso memset, memcpy o_O
Daniels118
02-07-2014, 12:26
Non ho ben capito su quale istruzione crasha, 75C2FD1E o HeapFree?
Questo non crasha.
http://pastebin.com/qRYtQXbF
Se aggiungo memcpy e/o freeheap crasha sempre dopo 75C2FD1E (che sarebbe MessageBoxA)
Daniels118
02-07-2014, 14:37
Ok, ma dove crasha esattamente? Voglio dire, seguendolo con il debugger dov'è che si ferma?
Con freeheap crasha qui:
http://www.japantrip.tk/imgboard/src/1404308633562.jpg
senza freeheap fa popad poi torna alla funzione originale di mirc ma poi salta sul kernel dà stack buffer overrun
Daniels118
02-07-2014, 16:12
Credo che tu abbia dimenticato di invertire l'ordine dei parametri nella "call HeapFree", vedi un po'...
:stordita:
Ok ora non crasha più su freeheap, dà solo quel stack buffer overrun quando ritorna alla funzione orignale :mc:
Daniels118
02-07-2014, 16:49
Intendi quando passa da FreeHeap al tuo codice, o dal tuo codice al chiamante?
codice originale
-> jump al mio (parte di codice originale cancellato)
pushad
mio codice
popad
la parte del codice originale che è andato perso per fare il jump l'ho messo qui
-> jump al codice originale
codice originale <- qui fa errore
credo ci sia un problema con i registri:
http://www.japantrip.tk/imgboard/src/1404312919793.jpg
quello in giallo è quando fa il jump originale->miocodice
quello sotto è da miocodice->originale
usando pushad e popad non dovrebbero essere uguali quando entra e quando esce?
Edit:
Così tutto ok:
push 0x00
push 0xFF
push ebp
call RtlFillMemory
push 0x40
push 0xFe
push ebp
call RtlFillMemory
push 0x41
push 0x30
push ebp
call RtlFillMemory
push 0x42
push 0x20
push ebp
call RtlFillMemory
jmp @Test
questo da buffer overrun... anche cambiando 0xff con meno
push 0x3
push @TestYes
push 0xff
push ebp
call memcpy_s
test eax, eax ; test if eax=0
jnz @No ; Zero if successful; an error code on failure.
jmp @Test
Daniels118
02-07-2014, 18:50
usando pushad e popad non dovrebbero essere uguali quando entra e quando esce?
Si... non ho guardato ancora il codice nel dettaglio, però se nel mezzo hai chiamato push un numero di volte diverso da pop o hai passato il numero di parametri errato ad una call è normale che poi popad non ripristina gli stessi valori salvati con pushad.
Controlla che tutte le call siano corrette, se non riesci a risolvere vedo di approfondire.
memcpy_s(
void *dest,
size_t numberOfElements,
const void *src,
size_t count
);
push 0x3
push @TestYes
push 0xff
push ebx
call memcpy_s
test eax, eax ; test if eax=0
jnz @No ; Zero if successful; an error code on failure.
jmp @Test
MSVCR100.memcpy_s -> buffer overrun
msvcrt.memcpy_s -> INT 3
ntdll.memcpy_s -> INT 3
senza non crasha :muro:
Daniels118
02-07-2014, 21:09
Mi sembra abbastanza strano, potresti provare con CopyMemory invece di memcpy_s? Assicurati anche con il debugger che ebp contenga sempre l'indirizzo restituito da HeapAlloc.
CopyMemory is defined in ntdll.dll as RtlCopyMemory. It points to the same function as RtlMoveMemory..
mIrc non importa CopyMemory ma c'è RtlMoveMemory da kernel32 quindi ho usato quello... Crasha dando previleged instruction.
Usando call ntdll.RtlMoveMemory invece funziona tutto senza crash :D
Alcuni registri cambiano a caso quando chiamo fillmemory ma quelli con il puntatore no quindi non è quello :fagiano:
Ho modificato così pastebin (http://pastebin.com/wS06Gy6F) ora funziona tutto
Comunque non capisco perchè va solo ntdll.RtlMoveMemory, che può essere :confused:
Daniels118
03-07-2014, 09:12
Alcuni registri cambiano a caso quando chiamo fillmemory ma quelli con il puntatore no quindi non è quello
Dipende dalle convenzioni di chiamata, la conservazione di alcuni registri è a carico del chiamate e di altri a carico del chiamato.
Comunque non capisco perchè va solo ntdll.RtlMoveMemory, che può essere
Forse memcpy_s usa cdecl, se ti va di provare rimetti com'era prima ed aggiungi la seguente istruzione subito dopo la call:
add esp, 16
Crasha :muro:
push 0x3
push @TestYes
push 0xff
push edx
call ntdll.memcpy_s
add esp, 16
test eax, eax ; test if eax=0
jnz @No ; Zero if successful; an error code on failure.
jmp @Test
.
.
.
@Fine2:
pop ecx ; recupero
push ebx
push 0
push ecx
call RtlFreeHeap <- crash
test eax, eax ; test if eax=0
jnz @Fine ; If the function succeeds, the return value is nonzero.
jmp @No
prò così no :mbe:
push 0x3
push @TestYes
push 0xff
push edx
call ntdll.memcpy_s
;------------
test eax, eax ; test if eax=0
jnz @No ; Zero if successful; an error code on failure.
jmp @Test
.
.
.
@Fine2:
pop ecx ; recupero
pop ecx ; recupero
pop ecx ; recupero
pop ecx ; recupero
pop ecx ; recupero
push ebx
push 0
push ecx
call RtlFreeHeap <-- no crash
test eax, eax ; test if eax=0
jnz @Fine ; If the function succeeds, the return value is nonzero.
jmp @No
Daniels118
03-07-2014, 10:29
Anche se metti i 4 pop dopo la call?
push 0x3
push @TestYes
push 0xff
push edx
call ntdll.memcpy_s
pop ecx
pop ecx
pop ecx
pop ecx
Dici così ?
Non crasha...
con add esp, 16 crasha dando DATATYPE_MISALIGNEMENT
edit:
ahhhhhhhhhhhhhhhhh san gennaro
add esp, 16 -> lo vede come 0x16 :muro: :muro: :muro:
messo 10 ora va :stordita:
in pratica il problema era cdecl invece di stdcall ? :doh:
Daniels118
03-07-2014, 12:29
add esp, 16 -> lo vede come 0x16
Beh, meno male che te ne sei accorto, senza debugger ci avrei messo secoli per arrivarci! :D
in pratica il problema era cdecl invece di stdcall ?
Esattamente! La convenzione di chiamata cdecl prevede che sia il chiamante a rimuovere i parametri dallo stack dopo la call... non capisco per quale assurdo criterio qualcuno dovrebbe mischiare due standard di chiamata nella stessa libreria, ma alla microsoft avranno trovato sicuramente un motivo valido :sofico:
http://www.japantrip.tk/imgboard/src/1404388509278.png
Eccoti 5000 internet per l'aiuto :asd:
Comincia a piacermi l'asm, ora mi cerco qualche guida da 0 :stordita:
Daniels118
03-07-2014, 14:13
Grazie, sei molto gentile, sto provando a prenderla ma è rimaso uno strano segno circolare color arcobaleno sul monitor :wtf: :D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.