Parameter und Calling Convention finden

08/19/2014 11:38 .Infinite#1
Hey,

habe in einem Spiel mit ollydbg eine Funktion gefunden, von der ich glaube, dass sie Text auf dem Bildschirm ausgibt:

Code:
Address   Hex dump          Command                                  Comments
013CDB28    F30F1085 6CFFFF MOVSS XMM0,DWORD PTR SS:[EBP-94]		; FLOAT 42.00000
013CDB30    8D85 78FFFFFF   LEA EAX,[EBP-88]
013CDB36    F30F5805 5850CE ADDSS XMM0,DWORD PTR DS:[1CE5058]		; FLOAT 20.00000 (y coord?)
013CDB3E    D985 70FFFFFF   FLD DWORD PTR SS:[EBP-90]			; FLOAT 1760.00000 (x coord?)
013CDB44    83C4 08         ADD ESP,8
013CDB47    8B0D A8A80602   MOV ECX,DWORD PTR DS:[206A8A8]
013CDB4D    50              PUSH EAX					; ASCII "Ping(ms): 500" (text to display)
013CDB4E    83EC 08         SUB ESP,8
013CDB51    8D85 74FFFFFF   LEA EAX,[EBP-8C]
013CDB57    68 AC9BDE01     PUSH OFFSET 01DE9BAC
013CDB5C    50              PUSH EAX
013CDB5D    83EC 0C         SUB ESP,0C
013CDB60    F30F114424 08   MOVSS DWORD PTR SS:[ESP+8],XMM0		; FLOAT 6.236526e-22 (???)
013CDB66    D95C24 04       FSTP DWORD PTR SS:[ESP+4]			; FLOAT 1760.0000000000000000
013CDB6A    E8 918C0900     CALL 01466800
Wie kann ich nun rausfinden, welche calling convention verwendet wurde und welche Parameter in welcher Reihenfolge übergeben werden müssen, wenn ich die Funktion mit einer dll aufrufen möchte?
08/19/2014 12:12 Thr!ce#2
Poste mal die gecallte Funktion, da steht das relevante Zeugs drin.

Oder du nutzt einfach IDA.
08/19/2014 12:31 buFFy!#3
Poste die Funtion, die deine Funktion aufruft. Das erkennt man am Funktionsaufruf.
Du kannst auch einfach Hexrays nutzen, dann lernst du's aber nicht selbst zu sehen.
Wie auch immer, deine "erkannten" Parameter werden so wahrscheinlich nicht ganz stimmen.

Quote:
013CDB36 F30F5805 5850CE ADDSS XMM0,DWORD PTR DS:[1CE5058] ; FLOAT 20.00000 (y coord?)
Ziemlich unwahrscheinlich. Übrigens solltest du wohl auch mal auf den Stack gucken.
08/19/2014 12:44 .Infinite#4
Hier ist der Anfang der Funktion

Warum muss man sich die Funktion angucken? Müssen nicht die Parameter vorher auf den Stack geschoben werden oder schon in irgendwelchen Registern liegen? Ich dachte daran könnte man das erkennen...

€: Hab die komplette Funktion in den Spoiler gepackt
08/19/2014 12:59 buFFy!#5
Was davor passiert ist fast uninteressant, wenn du uns nicht die gesamte Funktion zeigst und was nach dem call passiert.

Code:
013CDB47    8B0D A8A80602   MOV ECX,DWORD PTR DS:[206A8A8]
sieht nach __thiscall aus, aber kann ich mit dem bissel Schnippsel da oben nicht sagen.
08/19/2014 13:41 .Infinite#6
Hab den Rest der Funktion oben reineditiert... Kannst du mir sagen, wie du anhand von dem Schnipsel auf __thiscall kommst?

Heißt
Code:
018E9A96    C2 0C00         RETN 0C
dass es __stdcall ist, weil der Stackpointer beim return zurückgesetzt wird?
08/19/2014 14:01 Padmak#7
Wenn die Datei mit MSVC++ compiled wurde, handelt es sich ziemlich sicher um einen __thiscall
Soweit ich weiß, ist der einzige Unterschied zwischen __stdcall und __thiscall (bei MSVC++), dass davor eben der MOV in ECX ausgeführt wird, wobei der 'this'-Pointer in ECX gemoved wird und damit an die Funktion übergeben wird. Die aufgerufene Funktion bereinigt mit deinem Return noch den Stack -> ergo __thiscall
Du kannst aber auch (wie buFFy! schon gesagt hat) einfach IDA + Decompiler verwenden, die haben ne recht hohe Trefferquote

Padmak
08/19/2014 21:37 buFFy!#8
Quote:
Originally Posted by .Infinite View Post
Hab den Rest der Funktion oben reineditiert... Kannst du mir sagen, wie du anhand von dem Schnipsel auf __thiscall kommst?

Heißt
Code:
018E9A96    C2 0C00         RETN 0C
dass es __stdcall ist, weil der Stackpointer beim return zurückgesetzt wird?
Aufrufkonvention ? Wikipedia

Quote:
Beim Microsoft Visual C++ Compiler wird der this-Zeiger im ECX-Register übergeben und die aufgerufene Funktion bereinigt den Stack, es wird also wie bei der stdcall Aufrufkonvention verfahren. Werden hingegen variable Argumentlisten verwendet bereinigt die aufrufende Funktion den Stack (also wie bei cdecl).
Wohl bemerkt nur bei MSVC++
08/20/2014 17:14 .Infinite#9
Hab mir jetzt IDA runtergeladen und die Funktion in Pseudocode anzeigen lassen. Jetzt funktionierts :)

Ich weiß zwar immer noch nicht wie man sicher die calling convention rausfindet, aber wenn IDA mir das so einfach macht ist das vielleicht auch garnicht nötig...
08/20/2014 17:47 Padmak#10
Wie wir schon sagten, du musst dir ansehen wie die Parameter übegeben werden und was der Stack macht. Mithilfe der vorher verlinkten Wiki-Page kannst du dann die calling convention rausfinden. Oder eben IDA, was wesentlich angenehmer ist :P

Padmak
08/21/2014 10:22 buFFy!#11
Generell ist zu sagen, dass man nicht alles wissen muss.
Jedoch auch wenn IDA mehr oder weniger zuverlässig ist, sind Menschen in der Regel zuverlässiger.
Es ist nicht unwahrscheinlich, dass dir IDA früher oder später eine Funktion wirft bei der die Analyse nicht ganz so verlaufen ist, wie sie hätte verlaufen sollen.

Es ist sinnvoll immer IDA zu nehmen, aber gleichzeitig in der Lage zu sein, IDA's Analyse auf ihre Richtigkeit überprüfen zu können.
08/21/2014 13:11 Padmak#12
Tipp: wenn IDA einen __stdcall mit 'nem int-Parameter am Anfang zeigt, ist in dem int-Parameter höchstwahrscheinlich 'this' versteckt und es entspricht eigentlich 'nem __thiscall

Padmak
08/21/2014 13:18 buFFy!#13
Quote:
Originally Posted by Padmak View Post
Tipp: wenn IDA einen __stdcall mit 'nem int-Parameter am Anfang zeigt, ist in dem int-Parameter höchstwahrscheinlich 'this' versteckt und es entspricht eigentlich 'nem __thiscall

Padmak
die neuste ida version macht das nurnoch so. der param heißt dann einfach this.
btw meinst du __fastcall? bei stdcall sollte das eigentlich nich sein. __fastcall hat ersten params in ecx und edx, rest von rechts->links aufm stack
08/21/2014 14:11 Padmak#14
IDA 6.1 zeigt manchmal __stdcalls, wie z.B. hier:
Code:
char __stdcall sub_44AF40(void *a1)
a1 wird aber als this verwendet in der Funktion.
__fastcall hab ich bei IDA persönlich noch nie gesehen^^
Aber egal, der TE scheint ja seine Antwort bekommen zu haben :P

Padmak
08/21/2014 18:11 MrSm!th#15
__userpurge bringt IDA auch gerne mal damit durcheinander, besonders wenn Float-Zahlen im Spiel sind.