Hallo, gibt es spezielle Konstrukte bei denen ein C/C++ Programm welches mit dem msvc++ übersetzt wurde, Parameter einer Funktion im Register ebx übergibt? In den Dokumentationen habe ich darüber nichts finden können, mir liegt aber ein Programm vor bei dem ich so etwas vermute.
https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions?view=vs-2017 Oliver
Oliver S. schrieb: > https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions?view=vs-2017 > > Oliver Das habe ich schon gelesen, aber laut der Dokumentation wird ebx nie zur Parameterübergabe verwendet. Wenn dann nur ecx und/oder edx je nach Aufrufkonvention wie fastcall. Ich habe aber ein Assemblat vorliegen, in dem innerhalb einer Funktion einer anderen Funktion mit Parameterübergabe über den Stack wie memset, über push ebx ein Parameter auf dem Stack übergeben wird, aber ebx innerhalb der Funktion weder beschrieben, noch im Prolog auf dem Stack gesichert wird.
Thomas W. schrieb: > In den Dokumentationen habe ich darüber nichts finden können, mir liegt > aber ein Programm vor bei dem ich so etwas vermute. Konkreter ASM-Code? Sicher, dass es von C/C++ Code kommt?
A. K. schrieb: > Konkreter ASM-Code? > > Sicher, dass es von C/C++ Code kommt? Die Stelle an der in der besagten Funktion ebx zum erstem Mal verwendet wird ist die folgende:
1 | push 80 ; size_t |
2 | push 0 ; int |
3 | push ebx ; void * |
4 | call memset |
Die gesamte Funktion ist etwas umfangreicher, zumindest wird bis dahin ebx weder gelesen noch geschrieben. Bevor die Funktion aufgerufen wird aber schon mit "lea ebx, locale_var", was auch einen Sinn ergeben würde. Nur ist das in den Beschreibungen zu den Parameterübergaben nirgends so beschrieben.
Es bringt nichts, nur jenen Code zu posten, in dem die Frage nicht aufgeworfen wird.
:
Bearbeitet durch User
Also denn:
1 | sub_xxxxxx |
2 | |
3 | push ebp |
4 | mov ebp, esp |
5 | mov eax, 12C4h |
6 | call sub_xxxxxx |
7 | mov eax, dword_xxxxxx |
8 | xor eax, ebp |
9 | mov [ebp+var_4], eax |
10 | mov eax, [ebp+arg_0] |
11 | push esi |
12 | mov esi, [ebp+arg_4] |
13 | and eax, 0FF00h |
14 | push edi |
15 | mov edi, [ebp+arg_8] |
16 | mov [ebp+var_12A0], edx |
17 | mov edx, [ebp+arg_C] |
18 | or eax, 10010h |
19 | push ecx |
20 | mov [ebp+var_12A4], ecx |
21 | mov [ebp+var_129C], esi |
22 | mov [ebp+var_1294], edi |
23 | mov [ebp+var_1298], edx |
24 | mov [esi+8], eax |
25 | mov dword ptr [esi+0Ch], 0 |
26 | call sub_xxxxxx |
27 | mov eax, [esi+8] |
28 | and eax, 0FF00h |
29 | mov dword ptr [edi+0Ch], 0 |
30 | or eax, 10001h |
31 | mov [edi+8], eax |
32 | mov ecx, 7 |
33 | mov esi, offset xxxxxx |
34 | lea edi, [ebp+var_12C4] |
35 | rep movsd |
36 | movsw |
37 | push 1Eh |
38 | lea ecx, [ebp+var_12C4] |
39 | push ecx |
40 | push 0 |
41 | movsb |
42 | call sub_xxxxxx |
43 | lea edx, [ebp+var_1C] |
44 | push 18h |
45 | push edx |
46 | call sub_xxxxxx |
47 | mov esi, [ebp+var_1294] |
48 | lea eax, [ebp+var_1C] |
49 | push eax |
50 | call sub_xxxxxx |
51 | push 80 ; size_t |
52 | push 0 ; int |
53 | push ebx ; void * |
54 | call memset |
Es lässt sich auch nur sehen, dass ebx bis zum memset in der Funktion nicht verwendet wird.
Thomas W. schrieb: > anderen Funktion mit Parameterübergabe über den Stack wie memset, > über push ebx ein Parameter auf dem Stack übergeben wird, aber ebx Sieht für mich eher so aus als hätte da der Optimizer seine Arbeit getan. Ohne den C/C++ Source kann man da aber recht wenig zu sagen.
Im Funktionsprolog push ebp mov ebp, esp mov eax, 12C4h call sub_xxxxxx wird in der dort aufgerufenen Funktion Platz auf dem Stack für 12C4h Bytes an lokalen Variablen reserviert, die relativ zu EBP adressiert werden. Es werden dort sicherlich auch ein paar Register gesichert. Das ist keine C-Funktion, sondern eine zum Compiler gehörende Hilfsfunktion. Möglicherweise liefert die dein EBX.
:
Bearbeitet durch User
Die Funktion die da aufgerufen wird ist alloca_probe, fasst aber ebx nicht an. Dass der Compiler den Code so gut optimiert wäre eine Möglichkeit, aber dann könnte der Compiler ja immer wenn möglich andere Register zur Parameterübergabe verwenden. Was dort in ebx übergeben wird ist vermutlich ein Zeiger auf eine struct, und es wird noch ca. 10 mal schreibend indirekt darauf zugegriffen.
:
Bearbeitet durch User
Die meisten C++ Compiler, die ich kenne, benutzen ebx als selfpointer. Es ist also durchaus wahrscheinlich, dass der in einer Funktion gar nicht verwendet wird. Im Kontext sollte das aber klar werden. Lass mal die freie IDA Version über deinen code laufen. Dann bekommst du einige Hinweise. Thomas
Der this-Zeiger wird beim msvc++ in ecx übergeben, siehe: https://docs.microsoft.com/en-us/cpp/cpp/thiscall?view=vs-2017 ebx wird laut Wikipedia nur von einem Watcom Compiler zur Parameterübergabe verwendet.
Habe ich auch schon mal beobachtet, nachdem der Optimizer seine Arbeit getan hat. Natürlich passiert das nur bei Aufrufen innerhalb eines EXEs oder einer DLL, nicht über solche Grenzen hinweg.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.