[ASM] Wie bekommt eine mit _cdecl Aufgerufene Funktion mit das sie mit optionalen parametern aufgerufen wurde?

GM,
Ich habe eine funktion in Assember die als cdecl aufgerufen wird, ein paar parameter übergeben bekommt und evtl auch einen optionalen.
quasi sowas:
int _cdecl function(int a, int b, optional int c)

normalerweise rufe ich sie ja in der art auf:
push b
push a
call function
add esp, 0x04

wenn ich der funktion jetzt allerdings noch den parameter int c übergebe, wie kann ich innerhalb der funktion rausfinden ob dieser verwendet wird?
ich kann int c, wenn alles WORD lange int's sind, ja mit [ebp+12] innerhalb der funktion abrufen, wenn er nun aber nicht übergeben wurde weil er ja optional ist kommt murks raus weil ich dann irgendwelche daten vom stack hole. wie kann ich also innerhalb der funktion rausfinden ob der parameter übergeben wurde?

mike2007-04-19T00:20:19Z

Beste Antwort

Die Anwesenheit des zusätzlichen Parameters kann eigentlich nur erkannt werden, wenn es sich aus den anderen nicht optionalen Parametern ergibt. Bestes Beispiel hierfür ist "printf". Anhand der Vorgaben im Formatstring kann auf die Anzahl der Parameter geschlossen werden.

Anonym2007-04-22T23:11:31Z

Bei cdecl ist der erste Parameter der vom Stack geholt wird auch der erste der "übergeben" wurde, darum weiss die Assemblerroutine auch nicht wieviele übergeben wurden und du holst dir müll vom Stack. Ich wusste gar nicht dass man mit cdecl überhaupt optionale Parameter gestalten kannst, der einzige Weg der mir einfällt wäre die Anzahl der Parameter immer als ersten zu übergeben und dann dementsprechend viele vom Stack zu pop-en.

Von der "printf" aka "varargs" Lösung ist dringenst abzuraten(!). Wenn der Formatstring oder die Parameter irgendwie manipulierbar sind, ist ein Sicherheitsrisiko vorhanden. Das ganze fällt unter "formatstring exploit" ( lässt sich gut in deiner Lieblingssuchmaschine suchen ).

Ich kenne natürlich den Kontext deines Problems nicht genau, jedoch, so wie es hier geschildert wurde, könntest du auch zwei Funktionsrümpfe in Assembler bauen, einen mit drei Parametern und der andere mit zweien, der aber ersteren mit den übergebenen Paramtern + einem zusätzlichen default-Wert aufruft.
Je nach Hochsprache die du dann benutzt kannst du mit Funktionspointern/Makros, so tricksen dass eben die eine oder andere Assemblerroutine aufgerufen wird und die Syntax einheitlich ausschaut. Aber wäre schon ein bisl von hinten durch die Brust ins Auge :(