zmienne funkcje asm c++

matx

Użytkownik
Dołączył
Styczeń 30, 2006
Posty
12
ok, załóżmy że amm taki pseudo kod

Kod:
funkcja(parametr)

{



__asm

   {

push parametr

call Sleep

    }





}

to jest załóżmy w C , w jakim rejestrze sie znajduje ten paramter po przykładowym wywołaniu funkcji funkcja(5000) ? gdzie jest wartość 5000 ? w eax, esp ? ecx ? niewiem, pomocy. dzięki.
 

fl3a

Użytkownik
Dołączył
Marzec 12, 2005
Posty
538
Kod:
.text:7935AC6E Sleep           proc near

.text:7935AC6E

.text:7935AC6E dwMilliseconds  = dword ptr  4

.text:7935AC6E

.text:7935AC6E                 push    0              ; bAlertable

.text:7935AC70                 push    [esp+4+dwMilliseconds]; dwMilliseconds

.text:7935AC74                 call    SleepEx

.text:7935AC79                 retn    4

.text:7935AC79 Sleep           endp

Kod:
.text:7935AC7C; DWORD __stdcall SleepEx(DWORD dwMilliseconds,BOOL bAlertable)

.text:7935AC7C                 public SleepEx

.text:7935AC7C SleepEx         proc near              ; CODE XREF: Sleep+6p

.text:7935AC7C                                        ; Beep+143p

.text:7935AC7C

.text:7935AC7C var_8           = dword ptr -8

.text:7935AC7C var_4           = dword ptr -4

.text:7935AC7C dwMilliseconds  = dword ptr  8

.text:7935AC7C bAlertable      = dword ptr  0Ch

.text:7935AC7C

.text:7935AC7C; FUNCTION CHUNK AT .text:7937A562 SIZE 0000002C BYTES

.text:7935AC7C

.text:7935AC7C                 push    ebp

.text:7935AC7D                 mov     ebp, esp

.text:7935AC7F                 push    ecx

.text:7935AC80                 push    ecx

.text:7935AC81                 push    esi

.text:7935AC82                 push    edi

.text:7935AC83                 push    [ebp+dwMilliseconds]

.text:7935AC86                 lea     eax, [ebp+var_8]

.text:7935AC89                 push    eax

.text:7935AC8A                 call    sub_7934AAB9

.text:7935AC8F                 mov     edi, eax

.text:7935AC91                 test    edi, edi

.text:7935AC93                 jz      loc_7937A562

.text:7935AC99

.text:7935AC99 loc_7935AC99:                          ; CODE XREF: SleepEx+1F8F3j

.text:7935AC99                 mov     esi, ds:NtDelayExecution

.text:7935AC9F                 push    edi

.text:7935ACA0                 push    [ebp+bAlertable]

.text:7935ACA3                 call    esi; NtDelayExecution

.text:7935ACA5                 cmp     [ebp+bAlertable], 0

.text:7935ACA9                 jnz     loc_7937A574

.text:7935ACAF

.text:7935ACAF loc_7935ACAF:                          ; CODE XREF: SleepEx+1F8FDj

.text:7935ACAF                 mov     ecx, 0C0h

.text:7935ACB4                 cmp     eax, ecx

.text:7935ACB6                 jz      loc_7937A587

.text:7935ACBC                 xor     eax, eax

.text:7935ACBE

.text:7935ACBE loc_7935ACBE:                          ; CODE XREF: SleepEx+1F90Dj

.text:7935ACBE                 pop     edi

.text:7935ACBF                 pop     esi

.text:7935ACC0                 leave

.text:7935ACC1                 retn    8

.text:7935ACC1 SleepEx         endp

.text:7935ACC1

Jak nadal masz problem z rozwiazaniem to zerknij do tematu RE - jest tam link do fragmentu ksiazki Undocumented NT. W udostepnionym rozdziale opisane jest czytanie kodu (zasad kompilacji).
 

matx

Użytkownik
Dołączył
Styczeń 30, 2006
Posty
12
ale nei, mi chodziło o to, jak już w __asm {.....} wyciągnąć ten parametr, czyli to co wejdzie do funkcji jak mam


funkcja(parametr)
{

__asm
{
//jak z czystym asm uzyskać ten parametr ? gdzie on jest ? w esp ? ebp ? zeby bez uzycia slowa parametr dostac sie do wartosci jego, jak go odczytac z rejestrow, albo wlozyc go do eax ale nie uzywajac mov eax,parametr tylko biorac juz adres tego parametru z pamieci, on gdzies musi byc ta wartosc parametr w jakim rejestrze ?

}


}
 

fl3a

Użytkownik
Dołączył
Marzec 12, 2005
Posty
538
Nie jestem pewien czy dobrze zrozumialem... Mamy parametr param_1 wpierw odkladamy go na stos - push param_1 przez ta operacje parametr ten wedruje na stos czyli mamy do niego dostep przez esp. Jesli nic nie bedzie odkladane i zdejmowane ze stosu to na jego szczycie bedzie ten parametr. Po wywolaniu funkcj call func ulegnie to zmianie poniewaz odlozony na stos zostaje adres powrotu z funkcji.

Kod:
PUSH    30

PUSH    20

PUSH    10

CALL    _sum@12



If you take a look at the Assembly code, the compiler generates the code to set the EBP register to the start of the stack frame. (The stack frame for the function starts from EBP+8 since the compiler pushes the EBP register to maintain the stack frame set up by the caller function.) Hence, the parameters passed to the function start at EBP+8. Therefore, the first parameter x is accessed as [EBP+8] by the generated Assembly code. The parameters y and z are accessed as [EBP+C] and [EBP+10]. For implementing local variables, compilers typically generate code, which decrements the ESP register by the total number of bytes required to hold all the local variables defined in the function. In the previous code, there is only one local variable sum; therefore, the compiler allocates space for 4 bytes (1 DWORD) on the stack by generating the instruction SUB ESP, 4. The EBP register accesses all such local variables as negative offsets. The variable sum is accessed as [EBP-4] in the code. The LEAVE instruction used in the end restores the contents of EBP register and cleans up the local variables.

Stad tez przekazanie parametru do kolejnej funkcji w ten sposob:
Kod:
push    [esp+4+dwMilliseconds];
 

matx

Użytkownik
Dołączył
Styczeń 30, 2006
Posty
12
ok, bo chodzi mi zeby u siebie zrobic cos podobnego do tego:

http://72.14.203.104/search?q=cache:X8sUFX...t=clnk&cd=1

albo prościej, jak to dalej zroibć ? :
Kod:
#include <windows.h>

int funkcja_beep(DWORD dwFreq, DWORD dwDuration)

{

  __asm

  {

    //teraz jak mam pobrac te parametry ? ale bezposrednio ze stosu !!

    //nie uzywajac push dwFreq push dwDuration chce to zrobic,

    //gdzie one sa na stosie teraz albo w jakim rejestrze ?



    /*        NIE CHCE ROBIC TAK, ONE PEWNEI JUZ SA GDZIES NA STOSIE TYLKO GDZIE ?



    push dwFreq

    push dwDuration  */



    //i dalej wywolac Beep





//tu pewnie da sie je sciahgnac ze stosu gdzies chyba sa ? tylko gdzie jak je wyciagnac ?

    mov ebx, 0x7c838a53

 call ebx

  }

}





int main(int argc, char *argv[])

{



  //oczywiscie teraz nie zadziala bo tamte parametry nie sa przekazywane

  funkcja_beep(100, 100);

  return 0;

}
 

fl3a

Użytkownik
Dołączył
Marzec 12, 2005
Posty
538
Mam nadzieje ze o to chodzi
<


Kod:
unsigned int add(unsigned int l1, unsigned int l2) {

    int suma = l1 + l2;

    return suma;

} 



void main(void)  {

    add(8,32); 

}

Tak wyglada funkcja add(unsigned int l1, unsigned int l2);
Kod:
.text:00401000 sub_401000      proc near              

.text:00401000 arg_0           = dword ptr  4

.text:00401000 arg_4           = dword ptr  8

.text:00401000

.text:00401000                 mov     eax, [esp+arg_4]

.text:00401004                 mov     ecx, [esp+arg_0]

.text:00401008                 add     eax, ecx

.text:0040100A                 retn

.text:0040100A sub_401000      endp

Tu zas main:
Kod:
.text:0040100B sub_40100B      proc near               

.text:0040100B                 push    20h

.text:0040100D                 push    8

.text:0040100F                 call    sub_401000

.text:00401014                 pop     ecx

.text:00401015                 pop     ecx

.text:00401016                 retn

.text:00401016 sub_40100B      endp

Parametry pieknie wedruja na stos i w w funkcji add sa pobierane przez manipulacje wskaznikiem stosu. Zreszta wszystko widac jak na dloni
smile.gif
 

matx

Użytkownik
Dołączył
Styczeń 30, 2006
Posty
12
to czemu jak próbuje to zrobić to mam tak :

Kod:
bip(int wart1,int wart2)

{

__asm

  {



  mov eax, [esp+16]

  mov ecx, [esp+12]

  push eax

  push ecx

  call Beep

  }

}



int main(int argc, char* argv[])

{

bip(1000,100);

        return 0;

}
czemu te wartości mam dopiero w esp+16 i esp +12 ? ja doszedłem do tego metodą prób i błedów, wpisywałem raz esp +4 +8 + 16 i w końcu wyszło, ale skąd amm wiedzieć jakie to są numerki ? czy tak będzie działało na innych os-ach (win) też czy tylko na tym co to zrobiłem ? jak zdobyć te numerki esp+..... ??? dzięki.
 

fl3a

Użytkownik
Dołączył
Marzec 12, 2005
Posty
538
Wklej kod C++ oraz dasma z IDA to zobaczymy czemu to tak wyglada...
 

Jonny

Użytkownik
Dołączył
Kwiecień 7, 2002
Posty
401
<div class='quotetop'>CYTAT("matx")</div>
to czemu jak próbuje to zrobić to mam tak :

Kod:
bip(int wart1,int wart2)

{

__asm

  {



  mov eax, [esp+16]

  mov ecx, [esp+12]

  push eax

  push ecx

  call Beep

  }

}



int main(int argc, char* argv[])

{

bip(1000,100);

        return 0;

}
czemu te wartości mam dopiero w esp+16 i esp +12 ? ja doszedłem do tego metodą prób i błedów, wpisywałem raz esp +4 +8 + 16 i w końcu wyszło, ale skąd amm wiedzieć jakie to są numerki ? czy tak będzie działało na innych os-ach (win) też czy tylko na tym co to zrobiłem ? jak zdobyć te numerki esp+..... ??? dzięki.[/b]

dlaczego nie --- bo to nie asm. Nie masz kontroli nad kompilacja funkcji. Pewnie stawia ramke stosu albo seh'a i dlatego przed danymi na stosie jeszcze cos lezy oprocz adresu powrotu. Po prostu sprobuj wartosc zmiennej zaladowac bedzposrednio do rejestru -- kompilator sam powinien wstawic gdzie na stosie lezy jaki parametr. Przejdz po prostu na czystego asma i po bolu.
 

matx

Użytkownik
Dołączył
Styczeń 30, 2006
Posty
12
ok,. to jest kod z borlanda c++
Kod:
 #include<windows.h>





 wchar_t* func = L"TO JEST MOJA FUNKCJA." ;

bip(int wart1,int wart2)

{ 

__asm 

  { 

    push eax;

mov eax,func;

pop eax;





  mov eax, [esp+16] 

  mov ecx, [esp+12] 

  push eax 

  push ecx 

  call Beep

  } 

} 



int main(int argc, char* argv[]) 

{ 

bip(1000,100); 

        return 0; 

}
a teraz ida:
Kod:
; --------------- S U B R O U T I N E ---------------------------------------

.text:00401200

.text:00401200; Attributes: bp-based frame

.text:00401200

.text:00401200; int __cdecl sub_401200(DWORD dwFreq,DWORD dwDuration)

.text:00401200 sub_401200      proc near              ; CODE XREF: sub_401220+Ap

.text:00401200

.text:00401200 dwFreq          = dword ptr  8

.text:00401200 dwDuration      = dword ptr  0Ch

.text:00401200

.text:00401200                 push    ebp

.text:00401201                 mov     ebp, esp

.text:00401203                 push    ebx

.text:00401204                 push    eax

.text:00401205                 mov     eax, off_4090A4

.text:0040120A                 pop     eax

.text:0040120B                 mov     eax, [esp+4+dwDuration]

.text:0040120F                 mov     ecx, [esp+4+dwFreq]

.text:00401213                 push    eax            ; dwDuration

.text:00401214                 push    ecx            ; dwFreq

.text:00401215                 call    Beep

.text:0040121A                 pop     ebx

.text:0040121B                 pop     ebp

.text:0040121C                 retn

.text:0040121C sub_401200      endp

dlaczego tak jest ? i tak jak w moim poprzednim pytaniu, skąd mam zawsze brać te numery(XXXX) esp+XXXX żeby wiedzieć gdzie na stosie jest zmienna ?
 

fl3a

Użytkownik
Dołączył
Marzec 12, 2005
Posty
538
Tak jak Jonny powiedzial tak tez moze sie zdarzyc i sie dzieje. Tez namawiam do wykonania tego w czystym Asmie. Zajrzyj tez na forum NT Internals - goliat podal tam link do materialu o optymalizacji kodu wynikowego pod VC. Na stronie y0da'y tez jest o tym mowa... Moze sie przyda
smile.gif
 

matx

Użytkownik
Dołączył
Styczeń 30, 2006
Posty
12
czyli taki kod zadziała dobrze i będzie ok ?

Kod:
 #include<windows.h> 





 wchar_t* func = L"TO JEST MOJA FUNKCJA." ; 

bip()

{ 

__asm 

  {

    push eax; 

mov eax,func;

pop eax; 





  mov eax, ecx

  mov ecx, edx

  push eax

  push ecx

  call Beep

  }

}



int main(int argc, char* argv[])

{

__asm

{

mov ecx,3e8h

mov edx, 3e8h

}

bip();

}

bo to skompilowałem i działa, ale będzie zawsze dobrze działąć ?
 

fl3a

Użytkownik
Dołączył
Marzec 12, 2005
Posty
538
Nie rozumiem czemu nie chcesz czegos napisac w czystym Asmie - prosciej i pewnie... (wyjasnij w innym miejscu NT Internals w czym rzecz - zawsze moge sie mylic).

//Zamiast odkladac zawartosc rejestru na stos a pozniej ja zdejmowac mozesz uzyc innego rejestru zas przekazane parametry w main mozesz rowniez bez przesylania do innych rejestrow od razu na stos wladowac... (chyba ze to bylo celowe...).
 

matx

Użytkownik
Dołączył
Styczeń 30, 2006
Posty
12
ok, wyjaśnie tylko powiedz czy może być tak jak zrobiłem ?
 

goliat

Użytkownik
Dołączył
Styczeń 16, 2005
Posty
23
chyba chodzilo ci o to:

Kod:
DWORD bip(DWORD dwFreq, DWORD dwDuration)

{

    DWORD ret = 0;

    __asm 

    {    

        push dwDuration

        push dwFreq

        call dword ptr Beep

        mov ret,eax

    }

    return ret;

}

jak wpisywalem ten kod byl sformatowany
smile.gif
 

Jonny

Użytkownik
Dołączył
Kwiecień 7, 2002
Posty
401
<div class='quotetop'>CYTAT("goliat")</div>
chyba chodzilo ci o to:

Kod:
DWORD bip(DWORD dwFreq, DWORD dwDuration)

{

    DWORD ret = 0;

    __asm 

    {    

        push dwDuration

        push dwFreq

        call dword ptr Beep

        mov ret,eax

    }

    return ret;

}

jak wpisywalem ten kod byl sformatowany
smile.gif
[/b]

Dokladnie tak jak goliat napisal. poza tym jak przyjrzysz sie listingowi to odklada jeszcze ebx ktory uzywa wczesniej do jakiegos celu (seh najczesciej) i dlatego to wszystko przeskakuje. poza tym dodatkowo dochodzi rejestr ebp ktory zawsze jest odkladany gdy przekazujesz parametry przez stos -- ramka. dlatego pisalem zebys zmienne zapodal bezposrednio -- tak jak wyzej goliat writnoł.
 

matx

Użytkownik
Dołączył
Styczeń 30, 2006
Posty
12
nie bo wtedy nie mógłbym tego napisać w formacie :

BYTE buf[]="x0x......" itd shellcode, wiecie o co mi chodzi ?
 
Do góry Bottom