ASM-Funktion in C++

Die Funktion soll aus einer DLL aufgerufen werden,
die in das Zielprogramm geladen ist, die DLL soll dabei
auf die IAT des Zielprogramms zurückgreifen.

Das ist allerdings meine erste große ASM Funktion die
ich emulieren will.
Zu der Funktion:


Code:
/CALL to send                    Name: Send
|Socket = 2554                     Parameter4: Socket
|Data = 0012E52C                    Parameter3: Pointer zu dem Packet (nachher mehr)
|DataSize = 32 (50.)                    Parameter2: Größe des Packet in Hex(Dez)
\Flags = 0                     Paramter1: Flags (soll immer 0 sein)

Ich habe eine Funktion in c++ geschrieben, die die Adresse des Socket holt!
Mal eine Vorschau zum Packet (es befindet sich ja in "0012E52C")
Code:
0012E70C  FF 0E 0C 00 2F 77 68 6F 61 6D 69 00 F0 99 80 7C  ?../whoami. ??|
FF0E <- Chat Packet
0C <- Die Größe ist" C", also auch "C" als 2ter Parameter
00 <- Ab da beginnt dann der Text


Nun habe ich begonnen:
Als Parameter an die Funktion soll zunächst nur der Pointer zum Socket übergeben werden,
es soll ein festes packet mit einer festen Größe (C) senden!
Code:
	        void whoami(BYTE* socket)
	{

		char packet[16] = { 0xFF,0x0E,0x0C,0x00,0x2F,0x77,0x68,0x6F,0x61,0x6D,0x69,0x00,0xF0,0x99,0x80,0x7C };
		__asm
		{
			
			push 0
			push C
			push packet
			mov ecx,dword ptr ds:[socket]
			push ECX
		    call 0x719D732D
		}
	}

Bei dem Call bekomme ich folgenden Fehler:
Code:
error C2415: improper operand type

Bei dem Text des Packet:
Code:
error C2440: 'initializing' : cannot convert from 'const char [25]' to 'DWORD'

Danke schonmal für eure kompetente Hilfe :]
 
Formatieren kannst du binäre Daten so:
Code:
//entweder:
char *data = "\x12\xA7...";
//oder:
char data[] = { 0x74,0x37,0xee ... };
Desweiteren muss man vor hexadezimale Werte ein '0x' setzen und für einen Pointer muss t du für den Pointer auf "packet" einfach nur "push packet" schreiben, da ein Array intern nur einen Pointer auf das erste Element darstellt.(Vorher noch auf DWORD casten, wenn du eine DWORD-Variable haben willst(char* ist einfacher).)
Bei dem Call musst du der Funktion einen eigenen Namen geben und diese dann aufrufen:
Code:
void __declspec(naked) asmFunc()
{
__asm
{
  push ebp
  mov ebp,esp
....
}
}

....
__asm
{
   call asmFunc
}
 
Danke schonmal, das hilft mir sehr viel weiter,
habe jetzt

Code:
        void whoami(BYTE* socket)
	{

		char packet[16] = { 0xFF,0x0E,0x0C,0x00,0x2F,0x77,0x68,0x6F,0x61,0x6D,0x69,0x00,0xF0,0x99,0x80,0x7C };
		__asm
		{
			
			push 0
			push C
			push packet
			mov ecx,dword ptr ds:[socket]
			push ECX
		    call 0x719D732D
		}
	}

Aber wie meinst du das mit der Funktion einen eigenen Namen geben?
Wie Benenne ich denn jetzt "call 0x719D732D", oder kann ich einfach den Namen
der IAT einfügen, wie in Olly? :D

PS: es entstehen einige warnings bei deinem Code:

Code:
warning C4309: 'initializing' : truncation of constant value (char packet[16] = { ...... }
Code:
warning C4409: illegal instruction size (push packet)
sind die unwichtig?
 
Ist 0x719D732D eine API? Wenn ja, kannst du einfach den Namen der Api direkt verwenden, den Rest erledigt der Kompiler.
Die erste Warnung kommt afaik daher, dass 0x77 usw. intern ints sind und auf die Größe eines chars reduziert werden.
Die zweite Warnung kommt dadurch, dass packet[] ein Array ist und normalerweise ein DWORD-Wert erwartet wird. Wenn du die weghaben möchtest kannst du auch "char *packet = { 0x77,... }" schreiben(Ohne Gewähr).
 
Original von Lesco
Ist 0x719D732D eine API? Wenn ja, kannst du einfach den Namen der Api direkt verwenden, den Rest erledigt der Kompiler.
Die erste Warnung kommt afaik daher, dass 0x77 usw. intern ints sind und auf die Größe eines chars reduziert werden.
Die zweite Warnung kommt dadurch, dass packet[] ein Array ist und normalerweise ein DWORD-Wert erwartet wird. Wenn du die weghaben möchtest kannst du auch "char *packet = { 0x77,... }" schreiben(Ohne Gewähr).

Naja das ganze sieht im Programm so aus:
Code:
719D7328    E8 00000000     CALL <JMP.&WS2_32.#19>
>>
719D732D  - FF25 B4139B71   JMP DWORD PTR DS:[<&WS2_32.#19>]         ; WS2_32.send
>>
71A1428A >  8BFF            MOV EDI,EDI
Aber der Compiler kennt die API's ja nicht, weil die DLL ja erst beim injecten in den Prozess "eindringt (^^)"
 
Achso, ich habe den Teil mit der Dll-Injection überlesen, aber egal:
Entweder du bindest die entsprechenden Header ein und schreibst "call send" oder verwendest die IAT des "Host-Programms":
Code:
DWORD addr = 0x719D732D; //addresse des "jmp <api>" hier einfügen
__asm
{
   call addr
}
(Könnte auch einfacher gehen, aber ich habe noch keinen Weg gefunden, den Kompiler zu überreden, einen absoluten Wert anzunehmen).
 
Original von Lesco
Achso, ich habe den Teil mit der Dll-Injection überlesen, aber egal:
Entweder du bindest die entsprechenden Header ein und schreibst "call send" oder verwendest die IAT des "Host-Programms":
Code:
DWORD addr = 0x719D732D; //addresse des "jmp <api>" hier einfügen
__asm
{
   call addr
}
(Könnte auch einfacher gehen, aber ich habe noch keinen Weg gefunden, den Kompiler zu überreden, einen absoluten Wert anzunehmen).

Es geht, danke du hasst echt Ahnung von der Materie ;-)

Ich muss noch einmal stören, dass hier ist, was jetzt für ein Call reinkommt
(mit olly nachgeprüft)

Code:
0955FDA4   094327DD  /CALL to send from mydll.094327DA
0955FDA8   051C00B4  |Socket = 51C00B4
0955FDAC   000C0EFF  |Data = 000C0EFF
0955FDB0   0000000C  |DataSize = C (12.)
0955FDB4   00000000  \Flags = 0

000C0EFF existiert im Programm leider nicht, und 51C00B4 auch nicht,
habe ich was beim
Code:
push packet
falsch gemacht?
 
Also, es ist nicht egal, wie man das schreibt:
Verwendet man die Schreibweise:
Code:
char packet[];
Dann wird der Inhalt(das erste DWORD) von Paket gepusht.
Wenn es so schreibt:
Code:
char *packet = "\x34..";
Wird (korrekterweise) die Adresse gepusht, da "packet" dann nur einen Pointer zu "\x34" enthält, was nicht auf dem Stack liegt, im ersten Fall liegt jedoch der Inhalt selbst auf dem Stack und nicht nur ein Pointer dazu.(Kompiler:Visual C++ 6.0)
 
Gut, es geht schon fast :D

Code:
08A3FDB4   088F279A  /CALL to send from mydll.088F2797
08A3FDB8   08B200B4  |Socket = 8B200B4
08A3FDBC   088F7F98  |Data = mydll.088F7F98
08A3FDC0   0000000C  |DataSize = C (12.)
08A3FDC4   00000000  \Flags = 0

Alles ist nun korrekt, außer der Socket,
er soll nicht "8B200B4" als Socket nehmen sondern das,
was in der Adresse drin steht!
Es ist ja nur der Pointer, das habe ich bis jetzt mit
Code:
mov ecx,dword ptr ds:[socket]
versucht,
um das benötigte in den stack zu holen.

Wenn wir das noch hinkriegen jetzt, dann hab ich mein erstes
ASM projekt (oder ehr du) erfolgreich geschafft :-)
 
Was soll den gepusht werden? Das DWORD auf das Socket zeigt(wie es jetzt ist), oder socket selbst?
Bei zweiterem müsste es einfach so aussehen:
Code:
push socket
 
Original von Lesco
Was soll den gepusht werden? Das DWORD auf das Socket zeigt(wie es jetzt ist), oder socket selbst?
Bei zweiterem müsste es einfach so aussehen:
Code:
push socket

Die Funktion ist ja so:
Code:
       void whoami(BYTE* socket)
	{

        	__asm
		{
			
			mov ecx,dword ptr ds:[socket]
			push ECX
		        call send
		}
	}
ich möchte ja das, was in der Adresse "socket" drinsteht pushen, und nicht die Adresse selber, aber bis jetzt pusht er die Adresse!

Ich hab mal
Code:
push socket
genommen, bekomme aber wieder das gleiche:

Code:
0940FDB4   091B2799  /CALL to send from mydll.091B2796
0940FDB8   08B100B4  |Socket = 8B100B4 <--Das ist der Pointer
0940FDBC   091B7F98  |Data = mydll.091B7F98
0940FDC0   0000000C  |DataSize = C (12.)
0940FDC4   00000000  \Flags = 0
 
Original von sd333221
ich möchte ja das, was in der Adresse "socket" drinsteht pushen, und nicht die Adresse selber, aber bis jetzt pusht er die Adresse!

Laut WinSock-Dokumentation soll der Socket gepusht werden, was auch mit "push socket" funktionieren dürfte(Vorrausgesetzt, dass der Funktion der Socket-Deskriptor übergeben wird(Ein Socket-Deskriptor ist intern ein Zeiger auf uints, also dürfte es richtig sein, dass dort eine Adresse steht(habe nie etwas mit WinSock gemacht):
Code:
//Aus WinSock2.h
typedef UINT_PTR        SOCKET;
 
Original von Lesco
Original von sd333221
ich möchte ja das, was in der Adresse "socket" drinsteht pushen, und nicht die Adresse selber, aber bis jetzt pusht er die Adresse!

Laut WinSock-Dokumentation soll der Socket gepusht werden, was auch mit "push socket" funktionieren dürfte(Vorrausgesetzt, dass der Funktion der Socket-Deskriptor übergeben wird(Ein Socket-Deskriptor ist intern ein Zeiger auf uints, also dürfte es richtig sein, dass dort eine Adresse steht(habe nie etwas mit WinSock gemacht):
Code:
//Aus WinSock2.h
typedef UINT_PTR        SOCKET;
Das ist ja schön und gut, aber ich weiss wie ein richtiger Socket aussieht,
nähmlich so:

Code:
0012E994   0041A4AD  /CALL to send
0012E998   00002554  |Socket = 2554
0012E99C   0012EA00  |Data = 0012EA00
0012E9A0   0000002F  |DataSize = 2F (47.)
0012E9A4   00000000  \Flags = 0
Code:
045AF7D0   0041A4AD  /CALL to send
045AF7D4   00002554  |Socket = 2411
045AF7D8   045AF83C  |Data = 045AF83C
045AF7DC   00000018  |DataSize = 18 (24.)
045AF7E0   00000000  \Flags = 0
Code:
0012E504   0041A4AD  /CALL to send
0012E508   00002554  |Socket = 2321
0012E50C   0012E570  |Data = 0012E570
0012E510   00000006  |DataSize = 6
0012E514   00000000  \Flags = 0

Normal müsste ich ja auch den Socket pushen, aber der hat eine _variable_ Adresse,
ich habe auch schon eine sehr lange (über eine Seite) Funktion geschrieben, die einen Pointer ausfindig macht, mehr habe ich leider nicht zur Verfügung, aber es müsste doch möglich sein, den Pointer auszulesen, und dann den Wert auf den der Pointer Verweist zu pushen.

Der Pointer ist immer "????0B4" :-D
 
Also bekommt die Funktion sowas hier übergeben: "SOCKET *socket". In diesem Fall, müsste man das ganze so machen:
Code:
mov eax,socket
push dword ptr ds:[eax]
Ich hoffe, jetzt habe ich das Problem richtig verstanden.
Wenn nicht, dann poste mal bitte die Bytes die an Adresse 8***** stehen, und wie diese die übergebene Adresse mit dem socket zusammenhängt, das hier erinnert mehr an ein Ratespiel.
 
Original von Lesco
Also bekommt die Funktion sowas hier übergeben: "SOCKET *socket". In diesem Fall, müsste man das ganze so machen:
Code:
mov eax,socket
push dword ptr ds:[eax]
Ich hoffe, jetzt habe ich das Problem richtig verstanden.
Ja, jetzt geht es endlich! Danke :-)

Der stellt sich aber schon komisch an, dass er
Code:
mov esi,socket
mov ecx,dword ptr ds:[esi]
push ecx

aber nicht
Code:
mov ecx,dword ptr ds:[socket]
push ecx

Naja bin jetzt froh das es geht,
vielen Dank.

Durch dich hab ich für heute viel gelernt :-)
So langsam beginnt mein C++ und mein ASM Wissen zu verschmelzen :D
 
Zurück
Oben