Entwickler-Ecke

Dateizugriff - kann dll funktion nicht ausführen...


SchwiegerSohn - Sa 12.02.05 10:55
Titel: kann dll funktion nicht ausführen...
Folgendes Problem :
Ich versuche grade ein Basic Programm nach Delphi zu übersetzen.
In dem Basic Programm ist eine DLL Folgendermassen Declariert :


Quelltext
1:
Declare Function YMSG Lib "YMSG.dll" (ByVal username As String, ByVal password As String, ByVal Seed As String, ByVal result_6 As String, ByVal result_96 As String, intt As Long) As Boolean                    


und der aufruf der dll im basic :

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
Function PostLogin(ID As String, PW As String, SD As String)
Dim Enc(1) As String
On Error GoTo Error
Enc(0) = String(80, 0)
Enc(1) = String(80, 0)
yea... (im not 100% sure)
If YMSG(ID, PW, SD, Enc(0), Enc(1), 1) = False Then
    'incase of error
    MsgBox "Error on: YMSG.DLL", vbCritical, "YMSG.DLL"
    GoTo Error
End If
 For i = 0 To 1
    Enc(i) = Left$(Enc(i), InStr(1, Enc(i), Chr(0)) - 1)
 Next

in result_6 und Result_96 sind dann die ergebnisse drin..

Ich übergebe der dll die gleichen parametern wie in basic... aber das programm gibt immer einen adress fehler aus..
hier mein code :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
  function YMSG12(username,password,Seed,result_6,result_96:string;intt:integer):Boolean; external 'YMSG.dll';

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,d,e:string;
    I:Integer;
begin
  a:='username';
  b:='pass';
  c:='a%5|j^l%(d^i^b%3+(m-y+n-3+p/x%8+b*x-(k*b%3*o|v^r|(r+(4^z&x^z*(w/(x+z&x)))))))';
  d:='';
  e:='';
  YMSG12_ScriptedMind_Encrypt(a,b,c,d,e,1);
end;


:cry:

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt


AXMD - Sa 12.02.05 11:51

Versuch mal stdcall

AXMD


Anonymous - Sa 12.02.05 12:08

AXMD hat folgendes geschrieben:
Versuch mal stdcall

Das Problem ist, daß VB/VBA leider _nur_ stdcall verstehen - daher ist die die einzige Möglichkeit, die sich zu testen lohnt.
Ist die Funktion also mit einer anderen Aufrufkonvention exportiert, müßtest du zB wie folgt vorgehen (_nur wenn_ o.g. Funktion nicht stdcall ist):
- Du schreibst eine eigene DLL in Delphi, welche die Funktion unter gleichem Namen, mit gleichen Parametern und stdcall exportiert
- Diese Delphi-DLL importiert aus o.g. DLL die Funktion der YMSG.DLL und reicht direkt die Parameter weiter.

So kannst du die Aufruf konventionen "transformieren". Ach ja, falls du wissen mußt wie man eine DLL schreibt und wie das alles funktioniert (auch bzgl. Aufrufkonventionen), schau mal hier [http://assarbad.net/de/stuff/tutorials/dll_tutorial/] rein.


SchwiegerSohn - Sa 12.02.05 12:13

erstmal Thx :)
Stdcall hilft leider nicht...

ich werd mal assarbad's verschlag ausprobieren..


Anonymous - Sa 12.02.05 12:35

SchwiegerSohn hat folgendes geschrieben:
erstmal Thx :)
Stdcall hilft leider nicht...

Im Zweifelsfall sag mir, wo man die DLL herbekommt (vermutlich Yahoo Messenger, oder???) und ich kann mit dem Disassembler nachschauen. In diesem Falle ist übrigens "cdecl" sehr wahrscheinlich.


SchwiegerSohn - Sa 12.02.05 12:51

genau ist die YMSG12Encrypt.dll
die dll gibt es hier : http://www.geocities.com/httpymsg/ymsg12crypt.zip
die exportierte funktion heisst : YMSG12_ScriptedMind_Encrypt

@assarbad das mit der dll.. klappt leider auch nicht :-s


Anonymous - Sa 12.02.05 14:21

Stop, da sehe ich doch gerade noch was. Du hast "string" als Typ verwendet. Dieser Typ ist in Delphi komplett anders als in anderen Sprachen. Teste bitte mal statt "String" den Typ "PChar" und die Aufrufkonvention STDCALL.

Ich schaue mir inzwischen die DLL an.


SchwiegerSohn - Sa 12.02.05 14:26

mit pchar anstatt string.. gehts leider auch nicht :-s
thx @assarbad


AXMD - Sa 12.02.05 14:27

Was is mit Shortstring?

AXMD


SchwiegerSohn - Sa 12.02.05 14:40

shortstring geht :)
*thx* @ all


uall@ogc - Sa 12.02.05 14:42

mir zeigt olly nur an das es eine funktion gibt die exportiert wird: Ymsg12Crypt


Anonymous - Sa 12.02.05 14:44

AXMD hat folgendes geschrieben:
Was is mit Shortstring?

Kommt nicht in Frage. Die DLL ist in VC geschrieben und dor wäre Shortstring einfach ein Array von 255 Zeichen, wobei das erste Byte die Länge definiert. Sowas müßte man selber deklarieren und würde Kompatibilitätsprobleme bekommen!

____________________________________________________________________
DLL runtergeladen.

Es gibt nur einen Export ... keinen mit dem o.g. Namen!!!

Ausgangspunkt: Ymsg12Crypt(arg1, arg2, arg3, arg4)

Die Funktion hat einen Stackframe, also kann es schonmal kein CDECL sein, denn da kümmert sich der Aufrufer ums Saubermachen des Stack.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
.text:1000256A                 push    ebp
.text:1000256B                 mov     ebp, esp
.text:1000256D                 sub     esp, 668h
.text:10002573                 push    ebx
  .
  .
  .
.text:10002EBC                 add     esp, 18h
.text:10002EBF                 pop     edi
.text:10002EC0                 pop     esi
.text:10002EC1                 pop     ebx
.text:10002EC2                 leave
.text:10002EC3                 retn    10h


Damit sind wir schonmal unter bestimmten Annahmen bei STDCALL:
- MSVC kennt keine Delphi-Aufrufkonvention REGISTER.
- FASTCALL kommt nicht wirklich in Frage.
- NAKED fällt raus.

Meiner Meinung nach ist es also STDCALL.

Parameter 1 ist vom Typ PChar

Quelltext
1:
2:
3:
.text:100028D1                 call    sub_1000175F
.text:100028D6                 push    [ebp+Parameter01] ; char * -> Aha, einfaches PChar
.text:100028D9                 call    _strlen


Parameter 2 auch (mit einiger Sicherheit) PChar - bei leerem Paßwort schein ein Ersatzschlüssel benutzt zu werden:

Quelltext
1:
2:
3:
.text:10002649                 add     esp, 18h
.text:1000264C                 cmp     [edi], bl       ; Leerer String?? (erstes Zeichen #0)
.text:1000264E                 jz      loc_1000271F


Parameter 3 und 4 sind ebenfalls PChar:

Quelltext
1:
2:
3:
4:
5:
6:
7:
.text:10002EA4                 push    eax             ; char *
.text:10002EA5                 push    [ebp+Parameter03] ; char *
.text:10002EA8                 call    _strcpy
.text:10002EAD                 lea     eax, [ebp+var_F8]
.text:10002EB3                 push    eax             ; char *
.text:10002EB4                 push    [ebp+Parameter04] ; char *
.text:10002EB7                 call    _strcpy


Mehr Parameter gibt es lt. meiner Analyse nicht und der Delphi-Prototyp sollte so aussehen:


Quelltext
1:
procedure Ymsg12Crypt(arg1, arg2, arg3, arg4: PChar); stdcall; external 'YMSG12Crypt.dll';                    


oder ...

Quelltext
1:
function Ymsg12Crypt(arg1, arg2, arg3, arg4: PChar):Boolean; stdcall; external 'YMSG12Crypt.dll';                    

Es gibt allerdings keinen Hinweis auf einen Rückgabewert als Boolean.


Anonymous - Sa 12.02.05 14:46

Alles in der Funktion weist auf eine Caesarverschlüsselung hin. Die Schlüssel sind offen ersichtlich. Aber Achtung, dies ist nur eine Mutmaßung, die ich nicht durch intensive Codeanalyse anstelle!

Die Analyse kann überhaupt nicht als solche bezeichnet werden.


uall@ogc - Sa 12.02.05 14:49

dem
RET $10
nach müsste es doch stdcall sein cdecl würde doch nur ein normales ret haben und die aufrufenden funktion bereinigt den satck oder nicht


SchwiegerSohn - Sa 12.02.05 14:55

also ich habe es jetzt so gemacht :

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
  function YMSG12_ScriptedMind_Encrypt(username,password,Seed:string;result_6,result_96:Shortstring;intt:integer):Boolean; stdcallexternal 'YMSG12Encrypt.dll';

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,d,e:shortstring;
    I:Integer;
begin
  YMSG12_ScriptedMind_Encrypt('michwillkeine2000','*Pass*','a%5|j^l%(d^i^b%3+(m-y+n-3+p/x%8+b*x-(k*b%3*o|v^r|(r+(4^z&x^z*(w/(x+z&x)))))))',a,b,1);
  memo1.lines.add(char(a[0])+a);
//  memo1.lines.add(A);
  memo1.lines.add(char(b[0])+b);
end;


aus einem trace mit dem Originalen :
Input = a%5|j^l%(d^i^b%3+(m-y+n-3+p/x%8+b*x-(k*b%3*o|v^r|(r+(4^z&x^z*(w/(x+z&x)))))))
rückgabe = X=iB;W=bB;Z=3p,B=m3;k=02,U=4e,O=m3;O=0g,C=80,h=56,..96..W=j3;r=Aj;R=DC;Y=4C,R=l8;Q=n5,T=57,h=me,K=fn,r=Fp;

das programm gibt
X=iB;W=bB;Z=3p,B=m3;k=02,U=4e,O=m3;O=0g,C=80,h=56,
W=j3;r=Aj;R=DC;Y=4C,R=l8;Q=n5,T=57,h=me,K=fn,r=Fp;~ux~ux~u°ò
zurück.

also es ist so wie assarbad sagt.. er fängt an in null zu schreiben..

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt.


Anonymous - Sa 12.02.05 15:00

uall@ogc hat folgendes geschrieben:
dem
RET $10
nach müsste es doch stdcall sein cdecl würde doch nur ein normales ret haben und die aufrufenden funktion bereinigt den satck oder nicht

Lies doch einfach nach, was ich dazu sage. Na klar ist es STDCALL. :-P :mrgreen:

Habe soeben mal nach der Funktion gegoogelt und auf eine VB-Seite was gefunden:


Quelltext
1:
Private Declare Function Ymsg12Crypt Lib "YMSG12Crypt.DLL" (ByVal PassWord As String, ByVal seed As String, ByVal result6 As String, ByVal result96 As String) As Long                    


Davon, soviel kann ich aufgrund meiner VB-Erfahrung sagen, wäre folgendes der Delphi-Prototyp:


Quelltext
1:
function Ymsg12Crypt(PassWord : PChar; seed : PChar; result6 : PChar; result96 : PChar):Longint; stdcall; external 'YMSG12Crypt.DLL';                    


Und das sind komischerweise wieder anderer Name und 4 Parameter.


Anonymous - Sa 12.02.05 15:05

SchwiegerSohn hat folgendes geschrieben:
also es ist so wie assarbad sagt.. er fängt an in null zu schreiben..

Dann wäre Shortstring falsch.

Übrigens verwirrt mich immernoch, daß du eine komplett andere DLL und eine komplett andere Funktion benutzt, als du uns hier zum Vergleich gegeben hast. Siehe oben: Der Export der DLL heißt ganz anders und die DLL auch ... außerdem unterscheidet sich die Parameterzahl!

Ach warte mal ich glaube, daß du "intt:integer" einfach nur fälschlicherweise als Parameter angenommen hast. Laut der Angabe dort, muß es aber ein Longint sein, der als Rückgabewert auftaucht.

Da die Rückgabe exakt die Anzahl der kopierten Zeichen des letzten strcpy() enthält, muß ich meinen obigen Prototypen wie folgt anpassen:function Ymsg12Crypt(arg1, arg2, arg3, arg4: PChar) : Longint; stdcall; external 'YMSG12Crypt.dll';

Unter Anpassung der Parameternamen landen wir somit wieder bei dem direkt aus VB konvertierten Prototypen von direkt über diesem Beitrag:function Ymsg12Crypt(PassWord, seed, result6, result96 : PChar):Longint; stdcall; external 'YMSG12Crypt.dll';

Warum enthält EAX (also der LONG-Rückgabewert) die Anzahl der kopierten Zeichen? Dazu schauen wir uns nochmal den Epilog an:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
.text:10002EB3                 push    eax             ; char * ; <-- 2. Parameter für strcpy()
.text:10002EB4                 push    [ebp+Parameter04] ; char * ; <-- 1. Parameter für strcpy()
.text:10002EB7                 call    _strcpy ; <-- Aufruf von strcpy()
.text:10002EBC                 add     esp, 18h
.text:10002EBF                 pop     edi
.text:10002EC0                 pop     esi
.text:10002EC1                 pop     ebx
.text:10002EC2                 leave
.text:10002EC3                 retn    10h
.text:10002EC3 Ymsg12Crypt     endp


SchwiegerSohn - Sa 12.02.05 15:32

die dll die ich hier gepostet hatte.. war aus dem internet gesucht..

hier ist jetzt die die ich wirklich benutze : KLICK [http://com-puter-shop.de/ymsg12encrypt.dll]

ich wollte keine verwirrung stiften :oops:


Anonymous - Sa 12.02.05 15:42

SchwiegerSohn hat folgendes geschrieben:
die dll die ich hier gepostet hatte.. war aus dem internet gesucht..

hier ist jetzt die die ich wirklich benutze : [url=http://com-puter-shop.de/ymsg12encrypt.dll]KLICK[/URL]

Na dann guck ich mir die auch nochmal schnell an.


Anonymous - Sa 12.02.05 15:58

Okay, 2te DLL runtergeladen und mal angeguckt.

Aha ... wieder nur ein Export, diesmal aber mit dem o.g. Namen "YMSG12_ScriptedMind_Encrypt" aber wiederum nur 4 Parametern. Das heißt wohl, daß bei der obigen Übersetzungvon "SchwiegerSohn" etwas falsch ist!

Im Gegensatz zur ersten DLL wurde hier scheinbar direkt auf der MFC aufgesetzt, was die Analyse evtl. erschwert (OOP und RE vertragen sich oft nicht sehr gut ;)).

Prolog und Epilog sprechen wiederum für STDCALL, die Zuweisung nach AL im Epilog weist auf eine Boolean-Rückgabe hin:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
.text:100028F0 ; Exported entry   1. YMSG12_ScriptedMind_Encrypt
.text:100028F0
.text:100028F0 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:100028F0
.text:100028F0
.text:100028F0                 public YMSG12_ScriptedMind_Encrypt
.text:100028F0 YMSG12_ScriptedMind_Encrypt proc near
.text:100028F0
.text:100028F0 var_6B4         = dword ptr -6B4h
.text:100028F0 var_6B0         = word ptr -6B0h
.text:100028F0 var_6AC         = dword ptr -6ACh
.text:100028F0 var_6A8         = dword ptr -6A8h
.text:100028F0 var_6A4         = dword ptr -6A4h
.text:100028F0 var_6A0         = dword ptr -6A0h
.text:100028F0 var_69C         = dword ptr -69Ch
.text:100028F0 var_698         = dword ptr -698h
.text:100028F0 var_694         = dword ptr -694h
.text:100028F0 var_690         = dword ptr -690h
.text:100028F0 var_68C         = dword ptr -68Ch
.text:100028F0 var_688         = dword ptr -688h
.text:100028F0 var_684         = dword ptr -684h
.text:100028F0 var_680         = dword ptr -680h
.text:100028F0 var_67C         = dword ptr -67Ch
.text:100028F0 var_678         = dword ptr -678h
.text:100028F0 var_674         = dword ptr -674h
.text:100028F0 var_670         = dword ptr -670h
.text:100028F0 var_66C         = dword ptr -66Ch
.text:100028F0 var_668         = dword ptr -668h
.text:100028F0 var_664         = dword ptr -664h
.text:100028F0 var_660         = dword ptr -660h
.text:100028F0 var_65C         = dword ptr -65Ch
.text:100028F0 var_658         = dword ptr -658h
.text:100028F0 var_654         = dword ptr -654h
.text:100028F0 var_650         = dword ptr -650h
.text:100028F0 var_64C         = dword ptr -64Ch
.text:100028F0 var_648         = dword ptr -648h
.text:100028F0 var_638         = dword ptr -638h
.text:100028F0 var_5F8         = dword ptr -5F8h
.text:100028F0 var_5B8         = dword ptr -5B8h
.text:100028F0 var_578         = dword ptr -578h
.text:100028F0 var_538         = byte ptr -538h
.text:100028F0 var_4D4         = byte ptr -4D4h
.text:100028F0 var_470         = dword ptr -470h
.text:100028F0 var_418         = dword ptr -418h
.text:100028F0 var_3C0         = dword ptr -3C0h
.text:100028F0 var_264         = dword ptr -264h
.text:100028F0 var_260         = dword ptr -260h
.text:100028F0 var_100         = dword ptr -100h
.text:100028F0 var_FC          = dword ptr -0FCh
.text:100028F0 var_F8          = dword ptr -0F8h
.text:100028F0 arg_4           = dword ptr  8
.text:100028F0 arg_8           = dword ptr  0Ch
.text:100028F0 arg_C           = dword ptr  10h
.text:100028F0 arg_10          = dword ptr  14h
.text:100028F0
.text:100028F0                 sub     esp, 6B4h
.text:100028F6                 push    ebx
.text:100028F7                 push    ebp
.text:100028F8                 push    esi
  .
  .
  .
.text:100034CE                 mov     al, 1
.text:100034D0                 pop     edi
.text:100034D1                 pop     esi
.text:100034D2                 pop     ebp
.text:100034D3                 pop     ebx
.text:100034D4                 add     esp, 6B4h
.text:100034DA                 retn    18h
.text:100034DA YMSG12_ScriptedMind_Encrypt endp


Wie man sieht, ein riesiger Stackframe - hatte die andere Version aber auch!

Parameter 2 ebenfalls:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
.text:100029BA                 mov     edi, [esp+6CCh+arg_8]
.text:100029C1                 mov     [esp+6CCh+var_668], edx
.text:100029C5                 mov     [esp+6CCh+var_684], eax
.text:100029C9                 mov     [esp+6CCh+var_664], edx
.text:100029CD                 mov     al, [edi]
.text:100029CF                 add     esp, 8
.text:100029D2                 xor     esi, esi
.text:100029D4                 xor     ebx, ebx
.text:100029D6                 mov     [esp+6C4h+var_660], edx
.text:100029DA                 mov     [esp+6C4h+var_69C], esi
.text:100029DE                 test    al, al
Hier findet sich wieder der typische Vergleich des ersten Zeichens aus der ersten Version, womit getestet wird, ob das Paßwort leer ist.

Parameter 3 ist wiederum ein PChar:

Quelltext
1:
2:
3:
4:
.text:1000348C                 mov     ecx, [esp+6C8h+arg_C]
.text:10003493                 push    eax             ; char *
.text:10003494                 push    ecx             ; char *
.text:10003495                 call    ebx ; strncpy


Parameter 4 ist ebenfalls definitiv ein PChar:

Quelltext
1:
2:
3:
4:
5:
6:
7:
.text:100034AC                 mov     eax, [esp+6D0h+arg_10]
.text:100034B3                 not     ecx
.text:100034B5                 dec     ecx
.text:100034B6                 push    ecx             ; size_t
.text:100034B7                 push    edx             ; char *
.text:100034B8                 push    eax             ; char *
.text:100034B9                 call    ebx ; strncpy


Für Parameter 1 können wir es ohne tiefere Analyse des Programmflusses nur vermuten (daß es ein PChar ist), aber in diesem Falle wäre der Prototyp dieser:function YMSG12_ScriptedMind_Encrypt(arg1, arg2, arg3, arg4 : PChar) : Boolean; stdcall; external 'ymsg12encrypt.dll';


uall@ogc - Sa 12.02.05 16:06

ohne das du mich jetzt steinigst ich habs mir nicht angeguckt werfe aber einfach aml was in den raum


Delphi-Quelltext
1:
.text:100034DA                 retn    18h                    


18h = 24 div 4 = 6 parameter?

[img]
http://www.arschvoll.net/ymsg.jpg
[/img]

olly ist auch meiner meinung

bei stdcall ist es doch immer so das RET die anzahl der parameter zurückgibt oder sehe ich das falsch? (und über stdcall sind wir uns soch einig assarbad)


Sprint - Sa 12.02.05 16:30
Titel: Re: kann dll funktion nicht ausführen...
SchwiegerSohn hat folgendes geschrieben:
in result_6 und Result_96 sind dann die ergebnisse drin..

Dann musst du auch Speicher reservieren!!! Das macht nicht die DLL für dich. Ist doch klar im VB Beispiel zu erkennen.


Anonymous - Sa 12.02.05 16:33

uall@ogc hat folgendes geschrieben:
ohne das du mich jetzt steinigst ich habs mir nicht angeguckt werfe aber einfach aml was in den raum

.text:100034DA retn 18h

18h = 24 div 4 = 6 parameter?
Interessantes Argument. Allerdings kann man sich bei heutigen Compilern schwerlich auf dieses Argument verlassen, da die den Stackpointer jederzeit mal nach gusto modifizieren. Man müßte also zum Nachweis dieses Arguments alle Zugriffe auf ESP überprüfen.

Aber wäre immerhin möglich.

Ich nehme jedoch eher an, daß es sich um die Stackbereinigung nach den beiden C-Funktionen free() handelt. Es gibt zwar bereits das "add esp, 20h", aber man müßte eben mit einem Rechner durchgehen und die ESP-Werte notieren. Da IDA das für mich macht und anzeigt, falls mit dem Stackpointer was nicht stimmt, bin ich zuversichtlich, daß dies nur eine Optimierung seitens des Compilers ist:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
.text:100034BF                 mov     edi, ds:free
.text:100034C5                 push    ecx             ; void *
.text:100034C6                 call    edi ; free
.text:100034C8                 push    esi             ; void *
.text:100034C9                 call    edi ; free
.text:100034CB                 add     esp, 20h
.text:100034CE                 mov     al, 1
.text:100034D0                 pop     edi
.text:100034D1                 pop     esi
.text:100034D2                 pop     ebp
.text:100034D3                 pop     ebx
.text:100034D4                 add     esp, 6B4h
.text:100034DA                 retn    18h
.text:100034DA YMSG12_ScriptedMind_Encrypt endp


uall@ogc hat folgendes geschrieben:
bei stdcall ist es doch immer so das RET die anzahl der parameter zurückgibt oder sehe ich das falsch? (und über stdcall sind wir uns soch einig assarbad)
Jupp, sind wir ;)


uall@ogc - Sa 12.02.05 16:33

naja eigentlich schaue ich immer nur auf RET um bei einer stdcall Funktion zu gucken wieviele Parameter die Funktion hat, olly macht glaub ich nichts anderes

aber Delphi bzw. c++ wird aus einer stdcall Funktion nie irgendetwas wie das machen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure aha(a: integer); stdcall;
asm
  PUSH EAX
  ...
  ...
  ...
  RET 8 (weil EAX nicht vom stack genommen wurde)

end;


sondern es sieht immer so aus (um die register wieder herzustellen) dafür ist halt stdcall auch gedacht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure aha(a: integer); stdcall;
asm
  PUSH EAX
  ...
  ...
  ...
  POP EAX
  RET 4 (nur für den parameter)
end;


man kanns beim epilog ja sehen das die Funktion das genau so macht


man könnte nun einmal die Funktion mit 4 und 6 Parametern aufrufen, bei eins vom beiden MUSS es crashen da halt entweder zu viel vom stack genommen wird oder zu wenig und somit die Rücksprungadresse falsch ist


Anonymous - Sa 12.02.05 17:00

Mist :mrgreen:, du hast. Es könnte tatsächlich so sein. Es kommt vor, daß IDA nicht alle Parameter identifiziert, wenn sie nicht alle benutzt werden (innerhalb der Funktion). Ich schaue es mir gerade nochmal in IDA an.

//Edit

KORREKTUR:

Gucke ich mir die Stackanalyse von IDA an, kommt die Größe hin (arg_10 an Offset 14h + sizeof(arg_10) == 18h):

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
00000000  r              db 4 dup(?)
+00000004                 db ? ; undefined
+00000005                 db ? ; undefined
+00000006                 db ? ; undefined
+00000007                 db ? ; undefined
+00000008 arg_4           dd ?
+0000000C arg_8           dd ?
+00000010 arg_C           dd ?                    ; offset (FFFFFFFF)
+00000014 arg_10          dd ?                    ; offset (FFFFFFFF)
+00000018
+00000018 ; end of stack variables

Wäre natürlich die Frage, ob da an Offset 4 noch was rumlungert. Offset 0 ist ja die Return-Adresse.