__LOCAL_SIZE w c++ builder

0

Witam, mam problem z kompilacja kodu w c++ builder, kod wyglada nastepujaco:

void __declspec(naked) custom_WSASendTo(void)
{
__asm
{
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE

mov   eax, [ebp + MAGIC_STACKFRAME_SIZE + 4]
mov   [pWsa], eax
mov   eax, [ebp + MAGIC_STACKFRAME_SIZE + 8]
mov   [cnt], eax
}

....
};
//------------------------------------------------------------------------------

problem polega na tym ze builder nie rozpoznaje __LOCAL_SIZE co ma niby okreslac rozmiar zmiennych w funkcji, na msdn czytalem ze skladnia jest prawidlowa, czy ktos wie o co chodzi ????

0

[...] na msdn czytalem ze skladnia jest prawidlowa, czy ktos wie o co chodzi ????

Chodzi o to, że Borland to nie M$ ;) Szukaj odpowiednika tego makra dla Borland'a.

0

no i szukam posieci i nie moge znaleŹć, czy ktoś ma jakiś pomysł jak to zastąpić ;/

0

No a dlaczego ta funkcja musi być __declspec(naked) ??? Bo jeżeli masz zrobioną typową obsługę stosu (prolog/epilog) to chyba nie ma sensu komplikować sobie życie ;P Jeżeli musi być tak jak jest, to spróbuj skompilować funkcję bez specyfikatora naked i zobacz ile kompilator przydzielił pamięci na stosie (zakładając, że funkcja jest w całości gotowa i żadne nowe zmienne lokalne nie dojdą).

0

Witam

Nie bardzo rozumiem co masz na mysli, czy mozesz mi dac przykladowa funkcje, moze napisze o co mi chodzi bedzie latwiej. Funkcja custom_send() jest funkcja ktora jest wszczepiona to kazdego procesu ktory kozysta z opcji send(), sentto() etc. Chodzi mi ogolnie o to aby kontrolowac pakiety wychodzace z komputera. I teraz chce w tej funkcji wypelnic bufor danych ( pakiet ) i zwrocic dane bez modyfikacji, lub w zaleznosci od opcji zmodyfikowac pakiet. Ogolnie ma to byc FIREWALL

void custom_sendto(void)
{
// send params
BYTE *buf;
int len;
int iBytes;

iBytes = sizeof( iBytes ) + sizeof( buf ) + sizeof( len );

_asm
    {
    push  ebp
    mov   ebp, esp
    sub   esp, iBytes

    mov   eax, [ebp + MAGIC_STACKFRAME_SIZE + 4]
    mov   [buf], eax
    mov   eax, [ebp + MAGIC_STACKFRAME_SIZE + 8]
    mov   [len], eax
    }

some code here...

_asm
    {
    mov     esp, ebp
    pop     ebp
    ret
    }
};

Wywolanie tej funkcji powoduje blad aplikacji ktora ja wywoluje, nie znam sie na ASM wiec prosze o wsparcie ;/

0

Hmm o to sendto chodzi???

int WSAAPI sendto (
  SOCKET s,                        
  const char FAR * buf,            
  int len,                         
  int flags,                       
  const struct sockaddr FAR * to,  
  int tolen                        
);

gdzie WSAAPI to FAR PASCAL.

void __declspec(naked) custom_sendto(void)
{
    _asm
    {
        push  ebp
        mov   ebp, esp
        sub   esp, 0x24
    }
    
    SOCKET      s;
    char*       buf;
    int         len;
    int         flags;
    sockaddr*   to;
    int         tolen;
    char*       text="MyInject: wykryto custom_sendto";

    _asm
    {
        mov   eax, [ebp+8]
        mov   s, eax
        mov   eax, [ebp+8+4]
        mov   buf, eax
        mov   eax, [ebp+8+8]
        mov   len, eax
        mov   eax, [ebp+8+12]
        mov   flags, eax
        mov   eax, [ebp+8+16]
        mov   to, eax
        mov   eax, [ebp+8+20]
        mov   tolen, eax
    }

    ATOM Atom = ::GlobalAddAtom( text );
    UINT uiMyMessage = ::RegisterWindowMessage("InetMessage");
    ::SendMessage( HWND_BROADCAST  , uiMyMessage , (WPARAM)Atom , 0 );

    _asm

    {
        mov eax,len        //<--- zwracana wartość
        mov     esp, ebp
        pop     ebp
        ret      24
    }

};

i przykładowe wywołanie:

typedef int PASCAL(*sendto_ptr)(SOCKET,const char*,int,int,const struct sockaddr*,int);

sendto_ptr foo=(sendto_ptr)custom_sendto;

foo(1,(const char*)2,3,4,(const struct sockaddr*)5,6); //paramerty dla przykładu ;)

Z drugiej strony nie prościej tak:

int WSAAPI custom_sendto (SOCKET s,const char FAR * buf,int len,                         
                                         int flags,const struct sockaddr FAR * to,int tolen)
{
    char*       text="MyInject: wykryto custom_sendto";

    ATOM Atom = ::GlobalAddAtom( text );
    UINT uiMyMessage = ::RegisterWindowMessage("InetMessage");
    ::SendMessage( HWND_BROADCAST  , uiMyMessage , (WPARAM)Atom , 0 );

  return len;
}

??? :P

0

Zmienilem budowe funkcji na:

int WSAAPI custom_send( SOCKET s, const char* buf, int len, int flags )
{
char* text="MyInject: wykryto custom_send";

ATOM Atom = ::GlobalAddAtom( text );
UINT uiMyMessage = ::RegisterWindowMessage("InetMessage");
::SendMessage( HWND_BROADCAST , uiMyMessage , (WPARAM)Atom , 0 );

return len;
};

ale nadal aplikacja ktora ja wywola wykonuje blad, wiem ze problem lezy w tej funkcji poniewaz jak zmodyfikowalem pierwotna funkcje tak ze wstawilem zamiast iBytes wartosc 4 dla jednej zmiennej INT to wszystko bylo ok

0

No to jak masz możliwość debugowania tej funkcji to zobacz jak zachowuje się stos: EBP i ESP na początku i na końcu funkcji powinny być takie same.

PS. sprawdzałeś moją wersję sendto??? Wcześniejsza wersja nie ściągała parametrów ze stosu, ale już jest poprawione ;)

0

Powiem tak, nie znam sie na ASM, chce napisac soft ktory bedzie przechwytywal pakiety przed wyslaniem ich do sieci dlatego do procesow jest wstrzykiwana moja funkcja sent(), sendto() etc. Caly program juz dziala prawidlowo, pozostal mi jedynie problem z wykonaniem funkcji a ona zawiera kod asm ktorego nie znam. Bazuje na kodzie programu: http://www.viksoe.dk/code/wepmetering.htm

Czy moge cie prosic o komentarze do twojej funkcji i operacji pobierania danych ktore tam wykonujesz tak abym to mogl zrozumiec.

Najbardziej mnie interesuje rodzaj zmiennych i jak go okreslasz

SOCKET s; // <= 12
char* buf; // <= 1
int len; // <= 4
int flags; // <= 4
sockaddr* to; // <= ????
int tolen; // <= 4
char* text="MyInject: wykryto custom_sendto"; // <= 1

oraz znaczenie tych operacji czy je dobrze rozumiem

_asm
{
push ebp
mov ebp, esp
sub esp, 0x24 // <= mi wyszlo wiecej niz 24, gdzie sie pomylilem

mov   eax, [ebp+8]     // <= stack frame
mov   s, eax           // <= przeslanie danych do s
mov   eax, [ebp+8+4]   // <= przesuniecie wskaznika
mov   buf, eax
mov   eax, [ebp+8+8]
mov   len, eax
mov   eax, [ebp+8+12]
mov   flags, eax
mov   eax, [ebp+8+16]
mov   to, eax
mov   eax, [ebp+8+20]
mov   tolen, eax
}
0
void __declspec(naked) custom_send(void)
{
    SOCKET  s; //<---- w tym miejscu nie możesz nic inicjować
    char*   buf;
    int     len;
    int     flags;

    _asm
    {
        push  ebp
        mov   ebp, esp
        sub   esp, 0x7C    //<--- tu miałeś za mało. W tym miejscu przydzielasz pamięć (stosu) dla zmiennych lokalnych

       //<--- od tego miejsca możesz inicjować zmienne --->

        mov   eax, [ebp+32+8]     //<--- ściągamy parametry (oryginalnej) funkcji send ze stosu
        mov   s, eax                
        mov   eax, [ebp+32+8+4]
        mov   buf, eax
        mov   eax, [ebp+32+8+8]
        mov   len, eax
        mov   eax, [ebp+32+8+12]
        mov   flags, eax
    }

    char text[100]={"MyInject: wykryto custom_send"};

    ATOM Atom = ::GlobalAddAtom(text);
    UINT uiMyMessage = ::RegisterWindowMessage("InetMessage");
    ::SendMessage( HWND_BROADCAST  , uiMyMessage , (WPARAM)Atom , 0 );

    _asm
    {
        mov     esp, ebp
        pop     ebp
        ret
    }
}

To __LOCAL_SIZE to marko specyficzne dla VC. Zresztą ten kod, który kodałeś w linku był zrobiony w VC więc... w Borlandzie zawsze pod górkę ;P Jeżeli chodzi o obliczanie przydziału na stosie to możesz to zrobić tak jak to już mówiłem lub zliczyć wielkości wszystkich zmiennych i wpisać we wskazane wyżej miejsce. Problem w tym, że kompilator może wyrównywać rozmiar takich typów jak char, short itd. do 4 i wtedy lipa, przydział może być za mały. Dlatego też, te wszystkie 'małe' typy traktuj jako 4 bajtowe (to samo z elementami struktur) - lepiej przydzielić za dużo niż za mało.

Dobra, na razie sprawdź czy ta funkcja działa....

---edit---

Tam chyba powinno być 40 zamiast 32 - być może zapomniałem o adresie powrotu oryginalnej funkcji send

1 użytkowników online, w tym zalogowanych: 0, gości: 1