[ kajla @ 22.07.2001. 17:42 ] @
Da li neko zna kako mogu da saznam adresu MessageBoxA u user32.dll? (adrese se razlikuju u zavisnosti od win-a)

poz.
[ slash @ 22.07.2001. 18:19 ] @
Citat:
kajla je napisao:
Da li neko zna kako mogu da saznam adresu MessageBoxA u user32.dll? (adrese se razlikuju u zavisnosti od win-a)

poz.



skini SoftICE pa probaj s njim...cim se bavis inace ?
[ Vojislav Milunovic @ 22.07.2001. 22:31 ] @
Hmm probaj sa GetProcAddress ili tako nesto ima API fja....
Kod bi ovako nesto trebao da ide:

void *handler;
void *func;
handel = LoadLibray("user32.dll");
func = GetProcAddress(handler,"MessageBoxA");

ili je pak to GetProcAddr proveri u MSDN ;o)
[ kajla @ 23.07.2001. 13:49 ] @
Da, to sa GetProcAddress radi tako.

Inace pravim buffer overflow exploit pa hocu da napravim shell_code koji ce da prikazuje MessageBox (tek da bi video da exploit radi).

poz.

PS. koja je najnovija verzija SoftICE-a?
[ kajla @ 24.07.2001. 13:05 ] @
Nasao sam adresu MessageBoxA (0xBFF5412E)
i napravio shell_code:

55 8B EC 33 FF 57 C6 45 FC 48 C6 45 FD 69 C6 45 FE 21 BA
2E 41 F5 BF 52 57 8D 55 FC 52 52 57 FF 55 F8

u eip sam stavio jmp esp, koji sam nasao u kernel32.dll (0x8012F5CD), shell_code u stack. Tako da bi trebo da se pojavi MessageBox, pa da se program srusi. Ali desi se sledece:

Program se odmah srusi ne pojavi se MessageBox, onda ja u SoftICE pogledam stack:

55 8B EC 33 FF 57 C6 45 FC 48 C6 45 FD 69 C6 45 FE 21 BA
2E 41 F5 BF 52 05 00 00 C0 52 52 57 FF 55 F8
.........................^^^^^^^^ (tackice su zbog formatiranja)
ovo se razlikuje zasto?
sad ja adresu iz esp-a upisem u eip, i izadjem iz SoftICE, sada se pojavi MessageBox ali sa nekim potpuno bezveze tekstom!

Jos jedno pitanje u vezi SoftICE, da li je moguce da ja njemu zadajem asemblerske instrtukcije (recimo umesto sto sam adresu iz esp-a upisao u eip, kako mogu da izvrsim mov esp,eip)

poz.


[Ovu poruku je menjao kajla dana 07-24-2001 u 01:07 PM GMT]
[ Vojislav Milunovic @ 24.07.2001. 15:31 ] @
Code:

push   %ebp
mov    %esp,%ebp
xor    %edi,%edi
push   %edi
movb   $0x48,0xfffffffc(%ebp)
movb   $0x69,0xfffffffd(%ebp)
movb   $0x21,0xfffffffe(%ebp)
mov    $0xbff5412e,%edx
push   %edx
push   %edi 
lea    0xfffffffc(%ebp),%edx
push   %edx
push   %edx
push   %edi
call   *0xfffffff8(%ebp)


Malo ti je cudan ceo shellcode.
Za stampanje stringa uopste nemoras da koristis ovako nesto.
Recimo call *MessageBoxA bi resilo probelme.
Naime na ebp - 8 ne znam da li uopste imas adresu ... logicinije bi bilo call *0xfffffff8(%esp)
[ Vojislav Milunovic @ 24.07.2001. 15:34 ] @
+ da kazem da ne vidim nigde string koji ces da stampas ,a pripremanje frame pointera(ebp) ( push %ebp,movl %esp,%ebp) nije potrebno u shellcodeu ;o)
[ kajla @ 24.07.2001. 16:27 ] @
Citat:
predator je napisao:
Code:

push   %ebp
mov    %esp,%ebp
xor    %edi,%edi
push   %edi
movb   $0x48,0xfffffffc(%ebp)
movb   $0x69,0xfffffffd(%ebp)
movb   $0x21,0xfffffffe(%ebp)
mov    $0xbff5412e,%edx
push   %edx
push   %edi 
lea    0xfffffffc(%ebp),%edx
push   %edx
push   %edx
push   %edi
call   *0xfffffff8(%ebp)


Malo ti je cudan ceo shellcode.
Za stampanje stringa uopste nemoras da koristis ovako nesto.
Recimo call *MessageBoxA bi resilo probelme.
Naime na ebp - 8 ne znam da li uopste imas adresu ... logicinije bi bilo call *0xfffffff8(%esp)


Pogledaj malo pazljivije:

movb $0x48,0xfffffffc(%ebp)
movb $0x69,0xfffffffd(%ebp)
movb $0x21,0xfffffffe(%ebp)

Shell_code inace stampa "Hi!" (bez navodnika), kao sto znas 0x48=H,
0x69=i,0x21=!. Inace resio sam problem, tako da sada exploit radi, dodao sam shell_cod-u da pozove exit(0).

Jos uvek stoje ona pitanja u vezi SoftICE-a.

poz.
[ Vojislav Milunovic @ 24.07.2001. 16:37 ] @
Ali kod ti poziva -0x8(%ebp) a tamo se ne nalazi ova adresa od MessageBoxA to ja kazem ;o)
[ kajla @ 24.07.2001. 18:18 ] @
Kod zapravo ide ovako:

Code:

push ebp
mov ebp,esp
xor edi,edi
push edi
mov byte ptr[ebp-04h],48h
mov byte ptr[ebp-03h],69h
mov byte ptr[ebp-02h],21h
mov edx, 0xBFF5412E
push edx
push edi
lea edx,[ebp-04h]
push edx
push edx
push edi
call dword ptr[ebp-08h]


poz.
[ Vojislav Milunovic @ 24.07.2001. 19:58 ] @
Opet sam se ja istripovao nesto,dobro je...ummm jebem ti mozak kad stane !!!
[ kajla @ 26.07.2001. 13:34 ] @
Ne vidim kako u gdb-u da uradim sledece:
$ gdb

(gdb) file main
Reading symbols from main...done.
(gdb) break overflow
Breakpoint 1 at 0x8048486
(gdb) run
Starting program: /home/trifold/main

Breakpoint 1, 0x08048486 in overflow ()
(gdb)nexti
(gdb)nexti

e sad ja hocu da izvrsim:

call 0x8048480

kako? tj kako da izvrsim bilo koju asm instrukciju?

poz.
[ Vojislav Milunovic @ 26.07.2001. 13:59 ] @
Ako oces da izvrsis neku asm instrukciju onda moras da napravis program za to.Ja licno nisam video u gdb dokumentaciji da se tako nesto pominje.
[ kajla @ 26.07.2001. 15:49 ] @
Hoces da kazes da je to nemoguce uraditi iz gdb-a? Cudno jer mi to ponekad zatreba. Nego me zanima kako u gdb-u da ocitam vredonst sa neke momorijske lokacije (to je moglo u SoftICE da se uradi sa "d 0xBF70000" - pokazuje sadrzaj momerijske lokacije 0xBF7000), jos me zanima:
sa naredbom disassemble gdb pretvara "opcodes" sa zadate memorijske lokacije u asm instrukcije, da li je moduce uraditi suprotno?

poz.
[ kajla @ 26.07.2001. 15:55 ] @
Zaboravih da pitam: zanima me jos kako se iz gdb-a edituje neka memorijska lokacija kao i kako da editujem registre. (u SoftICE se to radilo "e 0xBFF7000" - edituje, "r eip" - edituje eip).

poz.
[ Vojislav Milunovic @ 26.07.2001. 17:51 ] @
Za sadrzaj neke promenljive korsti :
x/x adresaq

A za menjanje sadrzaja registra to ne znam.Za pretvaranje asm instrukcije u binarno mozes da koristis x/bx adresa pa koliko ti treba ili samo x/x za 4 byte-a ;o)
[ kajla @ 28.07.2001. 14:43 ] @
Napravio sam sledeci progy:
Code:

main()
{
__asm{
push 0
call 0x1020af90
}
}


e sad ovaj MS VC se is3povo pa mi javlja kod ovog call "invalid operand type" , ne kapiram sto neradi ja sam meni je u A86 ovo radilo:
Code:

push 0
call 1020af90h

poz.

PS. treba mi opcodes za ovu instrukciju "call 0x1020AF90".



[Ovu poruku je menjao kajla dana 07-28-2001 u 02:44 PM GMT]
[ Vojislav Milunovic @ 28.07.2001. 16:10 ] @
Posto samo call 0x0x1020af90 nesto se folira evo ti jedan drugi nacin koji je takodje veoma uspesan ;o)

Code:

int main(){
 __asm__ (
   "movl $0x1020af90,%eax \n"
   "call *%eax \n" );
}


sto u HEX izgleda vako :

Code:

char code[]="\xb8\x90\xaf\x20\x10\xff\xd0";
[ kajla @ 29.07.2001. 23:51 ] @
Ma znam za taj nacin, prebacis adresu u neki registar, pa ona ides sa:
Code:

call <ime_registra>


Ali kod je kraci kad ides sa:
Code:

call 0x1020AF90


poz.

[ tOwk @ 30.07.2001. 02:35 ] @
samo kod za tu call instrukciju:

0xe8 0x8b 0xaf 0x20 0x10

ovako radi za svaki far call, pa prema tome

0xe8 na pocetak, pa adresa u little endian obliku...

Toliko.
[ Vojislav Milunovic @ 30.07.2001. 11:45 ] @
Nije bre tako...evo ti sta gdb kaze za taj tvoj kod :

Code:

0x80494d4 <gg>: call   0x18254464


i
Code:

char gg[] = {0xe8, 0x8b, 0xaf, 0x20, 0x10};
[ tOwk @ 31.07.2001. 02:19 ] @
Ma nemoguce, pomocu NASM-a sam proverio.

Uostalom, pogledacu i instruction set reference od Intela, pa cu da budem siguran.

Ali, to malo kasnije.

Toliko.
[ tOwk @ 31.07.2001. 02:27 ] @
U pravu si, znam zasto sam istripovao.

U pitanju je relativna adresa, pa ona moze uvek biti razlicita. Zbog toga, mislim da ova adresa zavisi od toga gde je kod ucitan. Nemam sad vremena time da se bakcem, pogledacu samo jos da nema neka far call instrukcija sa direktnim operandom, a ne relativnim.

[ Vojislav Milunovic @ 31.07.2001. 12:17 ] @
Ma turis u register i cepas ;o) sta je to 7 instrukcija u odnosu na 5 instrukcija.mislim kod se moze optimizovati na mali milion mesta
[ tOwk @ 01.08.2001. 12:59 ] @
Citat:
Intel Software Developer's Manual 3: Instruction Set reference:

Opcode - Instruction - Description

E8 cw CALL rel16 Call near, relative, displacement relative to next instruction

E8 cd CALL rel32 Call near, relative, displacement relative to next instruction

FF /2 CALL r/m16 Call near, absolute indirect, address given in r/m16

FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32

9A cd CALL ptr16:16 Call far, absolute, address given in operand

9A cp CALL ptr16:32 Call far, absolute, address given in operand

FF /3 CALL m16:16 Call far, absolute indirect, address given in m16:16

FF /3 CALL m16:32 Call far, absolute indirect, address given in m16:32


Tabela bas i nije lepo poravnata, ali mislim da bi "FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32" bilo ono sto se trazi.

Prema tome, treba probati 0xff 0x10 0x10 0x10 0x10 da bi bio u pitanju call 0x10101010

Makar mislim, nisam ispitao ceo pricucnik.

A sto se optimizacije tice, predatorova tvrdnja stoji. Cak, zasto koristiti call kad se moze koristiti jmp. Call je sporiji i rizicniji (menja stack), pa bih predlozio jmp. Ali o tom, potom.

Toliko.
[ Vojislav Milunovic @ 01.08.2001. 14:34 ] @
call je koristan kad treba neki string da pokupis koji se nalazi u kodu : "/bin/sh" najcesce mada moze sa push da se napravi nesto ali jmp-call je mnogo lepsa i elegantnija varijanta ;o)
[ tOwk @ 02.08.2001. 03:37 ] @
Ovo poslednje nisam razumeo, pa ako mozes da mi objasnis, bio bih zahvalan.

Toliko.
[ Vojislav Milunovic @ 02.08.2001. 10:26 ] @
Pa call sluzi da se nadje adresa necega u memoriji !

call offset
nesto
offset:
pop %ebx i sad u ebx imas adresu od nesto,to nesto je najcesce string "/bin/sh" mada sa push moze da se kreira string.http://www.hack.co.za hell code za Linux 22byte (ili za FreeBSD) pa pogledaj nasta mislim
[ tOwk @ 03.08.2001. 02:30 ] @
Ok, shvatio sam (ili mi se makar cini).

call smesta EIP na stack kako bi mogao da se vrati sa ret, a to se naravno moze i rucno iscitati sa steka, kada ret bas i nece dobro raditi.

Ali, zar ne postoje jos neki nacini da se sazna adresa necega u kodu. Samo iscitavanje EIP sa mov npr. bi trebalo da uradi posao (ili movl :).
Jedino je problem sto tada treba dodati velicinu trenutne komande (mozda) na EIP. Mozda i ne ako procesor uveca EIP u trenutku izmedju ucitavanja komande i njenog izvrsavanja, ali to treba proveriti.

To je nesto kao caka, i koliko vidim korisno je zato sto je jednostavno, i najverovatnije manje mesta zauzima od jednog mov-a i add-a.

Toliko.

[ Vojislav Milunovic @ 03.08.2001. 11:35 ] @
E pa ne mozes da citas EIP sa movl ;o) To je bre ne moguce...njega inkrementira procesor a puni se sa call / jmp instrukcijama ;o)
[ kajla @ 03.08.2001. 15:31 ] @
Citat:
predator je napisao:
E pa ne mozes da citas EIP sa movl ;o) To je bre ne moguce...njega inkrementira procesor a puni se sa call / jmp instrukcijama ;o)


Nisam svatio sta je nemoguce: da se cita EIP sa mov ili je nemoguce da se cita EIP?
ovo drugo mora da je moguce jer kako debuger-i citaju CPU registre(izmedju ostalog i EIP)?

poz.
[ kajla @ 03.08.2001. 15:35 ] @
Citat:
tOwk je napisao:
Citat:
Intel Software Developer's Manual 3: Instruction Set reference:

Opcode - Instruction - Description

E8 cw CALL rel16 Call near, relative, displacement relative to next instruction

E8 cd CALL rel32 Call near, relative, displacement relative to next instruction

FF /2 CALL r/m16 Call near, absolute indirect, address given in r/m16

FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32

9A cd CALL ptr16:16 Call far, absolute, address given in operand

9A cp CALL ptr16:32 Call far, absolute, address given in operand

FF /3 CALL m16:16 Call far, absolute indirect, address given in m16:16

FF /3 CALL m16:32 Call far, absolute indirect, address given in m16:32


Tabela bas i nije lepo poravnata, ali mislim da bi "FF /2 CALL r/m32 Call near, absolute indirect, address given in r/m32" bilo ono sto se trazi.

Prema tome, treba probati 0xff 0x10 0x10 0x10 0x10 da bi bio u pitanju call 0x10101010

Makar mislim, nisam ispitao ceo pricucnik.

A sto se optimizacije tice, predatorova tvrdnja stoji. Cak, zasto koristiti call kad se moze koristiti jmp. Call je sporiji i rizicniji (menja stack), pa bih predlozio jmp. Ali o tom, potom.

Toliko.


tOwk mozes da mi posaljes taj "Intel Software Developer's Manual" na [email protected], bio bi ti zahvalan...

poz.
[ Vojislav Milunovic @ 03.08.2001. 17:31 ] @
Citat:
kajla je napisao:

Nisam svatio sta je nemoguce: da se cita EIP sa mov ili je nemoguce da se cita EIP?
ovo drugo mora da je moguce jer kako debuger-i citaju CPU registre(izmedju ostalog i EIP)?


EIP ne mozes da diras sa movl instrukcije koje mogu da sacuvaju/promene eip su call,jmp,ret i srodne funkcije.
Za to kako radi debuger mozes da pogledas man ptrace,mada Intel ima debug registre koji su nama obicnim programerima nevidljivi...o njima znam malo mada u ovom Intel Developer Manualu mozes da nadjes opsirno o njima.
[ tOwk @ 03.08.2001. 23:15 ] @
Probao sam i vidim da si u pravu. Cak ni push ne moze da ga iscita, pa sam morao da pogledam Intelovu dokumentaciju, a ono tamo stvarno kaze da je jedini nacin da se iscita EIP pomocu call-a i onda citanja sa steka.

Sto se tice izmena EIP-a jasno mi je da se to ne moze direktno uraditi, ali sam mislio da postoji neka mogucnost kao sto je za CS (moze da se cita, ne moze da se menja sa mov), ali ocigledno da sam pogresio.

U svakom slucaju, hvala na prosvetljenju.

Toliko. (Gotovo)
[ Vojislav Milunovic @ 04.08.2001. 11:12 ] @
lcall moze da odradi posao sto se tice CS ;o)
[ kajla @ 04.08.2001. 22:35 ] @
ZAnima me jos sledece:
int i=0xFF;

while (i)
{
clrscr();
--i;
}

sad ovo kad sam sa kompajlirao sa tcc -S dobio sa asm kod ali nigde loop
instrukcije, vec idu sa cmp pa onda sa kondicionim jump-om (jne) za nebi moglo to ovako:
Code:

push ebp
mov ebp,esp
push esi
mov esi,0xFF
lbl: call far ptr _clrscr
loop lbl


poz
[ tOwk @ 05.08.2001. 13:36 ] @
kajla>
uputstva na developer.intel.com/design/PentiumII/manuals/, ima nekih i za optimizaciju i jos ponesto.

predatore> CS moze da se menja sa POP zar ne? naravno i JMP i CALL u FAR varijantama to isto rade.

A sto se tice tog primera koji si dao kajla jednostavno je objasniti. Moraces da se postavis u poziciju onog koji pravi kompajler.

while (uslov) { rad(); } ciklus se implementira u tom kompajleru najverovatnije uvek na isti nacin.

Na primer, prvo cemo staviti label na pocetak (kompajler naravno ne stavlja label posto ide preko adresa :).
Zatim ide testiranje uslova, kakav god on bio: jednostavan kakav si ti naveo, ili mozda ((i>5) && (p || q)). Kada implementiras while ciklus, ti ne zelis da proveravas kakve sve mogucnosti postoje, pa da svaku pojedinacno obradjujes. Jasno je da taj kompajler (tc zar ne) ima losu optimizaciju, i zato to tako radi.

U boljem slucaju bi bilo uradjeno sa AND i JNE, a ne CMP i JNE, posto je ovde bitno samo da li je jednako nuli.

Svaki uslov treba da bude moguce istestirati na samom pocetku, pa pretpostavljam da tc generise ovakav kod.

Code:

MOV AX,i    ; ili mu je i vec u registru, ili mozda radi preko memorije
pocetak:
 CMP AX,AX ; ovde moze doci obrada bilo kakvog uslova
 JNE ciklus   ; i u zavisnosti od toga na kraju ukoliko ispunjava neki JMP na ciklus
 JMP kraj
ciklus:
 call rad  ; ili sta god da se radi ovde
kraj:
; nastavak


Mislim da je jasno da se na ovaj nacin moze implementirati bilo koji while ciklus, dok sa loop se retko koji moze (tvoj je jedan primer), pa se nadam da ti to objasnjava zasto je ko god je pravio tc izabrao taj nacin.

I samo da napomenem, vestacki sam se drzao "JNE" iako bi bilo bolje tu ubaciti "JE kraj" ili "JZ kraj", a onda sledeca JMP instrukcija ne bi bila potrebna. Naravno, sve ovo su samo pretpostavke, najverovatnije tc ne generise ovakav kod, ali ovako se dosta jednostavno implementira while(i) ciklus u asembleru (iako ne bas najbolje).

Toliko.
[ tOwk @ 05.08.2001. 13:44 ] @
E da, zaboravio sam da se promenljive nalaze na steku, pa treba ubaciti esp, i citati sa adrese koju on sadrzi. U svakom slucaju, ideja je uopstena.

A sto se tice tvog primera kajla, moguce da moze. Medjutim, zasto nije tako, pokusao sam da objasnim u prethodnom postu.

Ali tvoj kod mi nesto cudno izgleda. Zar loop komanda ne koristi CX ili ECX registar? Mislim da bi onda bilo potrebno da negde u njega smestis vrednost sa steka, tj. promenljive.

Ziveli.

[Ovu poruku je menjao tOwk dana 08-05-2001 u 01:48 PM GMT]
[ kajla @ 05.08.2001. 17:50 ] @
Citat:
tOwk je napisao:
E da, zaboravio sam da se promenljive nalaze na steku, pa treba ubaciti esp, i citati sa adrese koju on sadrzi. U svakom slucaju, ideja je uopstena.

A sto se tice tvog primera kajla, moguce da moze. Medjutim, zasto nije tako, pokusao sam da objasnim u prethodnom postu.

Ali tvoj kod mi nesto cudno izgleda. Zar loop komanda ne koristi CX ili ECX registar? Mislim da bi onda bilo potrebno da negde u njega smestis vrednost sa steka, tj. promenljive.

Ziveli.

[Ovu poruku je menjao tOwk dana 08-05-2001 u 01:48 PM GMT]


Jeste ja sam se zajebo...treba ecx a ne esi znaci ovako:
Code:

mov ecx,0xFF
lbl: call far ptr _clrscr
loop lbl


u stvari loop lbl se moze zameniti sa:
Code:

dec ecx
jne lbl


poz.
[ kajla @ 06.08.2001. 14:28 ] @
Kad smo vec kod loop instrukcije, napravio sam program
koji vrti petlju 0xFFFFFFFF do 0x00, i pri svakom prolasku poziva
printf("%xn",index_petlje); , e problem je sada sto program lepo
stampa sve od 0xFFFFFFFF pa stane na 0xFFFF0280, i tu mi javi
stack overflow ili se win "blokira".
Evo kod-a sa komentarima:

Code:

int counter()
{
__asm{
mov ecx,0xFFFFFFFF
xor esi,esi
mov dword ptr[edx],0x0d0a7825 ;string "%xn"
mov dword ptr[edx+04h],esi
PrintLp:
push ebp
mov ebp,esp
push 0x78022a28 ;adresa printf() u kernel32.dll
push ecx
push edx
mov esi,edx
mov edi,ecx
call dword ptr[esp+08h] ;poziva printf(),ciju sam adresu stavio u stack
mov edx,esi
mov ecx,edi
loop PrintLp
}
}


poz.

PS. ovo isto pitanje je postovano i u C forumu pod nazivom LOOP
[ Vojislav Milunovic @ 06.08.2001. 16:58 ] @
Odgovor na ove blokadu sam dao u C/C++ pod temom LOOP