Autor |
Beitrag |
SchwiegerSohn
      
Beiträge: 25
|
Verfasst: Sa 12.02.05 10:55
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; |
Moderiert von raziel: Code- durch Delphi-Tags ersetzt
_________________ Wer rechtschreibfehler findet darf sie behalten!
|
|
AXMD
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Sa 12.02.05 11:51
|
|
Gast
Gast
Erhaltene Danke: 1
|
Verfasst: 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 rein.
|
|
SchwiegerSohn 
      
Beiträge: 25
|
Verfasst: Sa 12.02.05 12:13
erstmal Thx
Stdcall hilft leider nicht...
ich werd mal assarbad's verschlag ausprobieren..
_________________ Wer rechtschreibfehler findet darf sie behalten!
|
|
Gast
Gast
Erhaltene Danke: 1
|
Verfasst: 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 
      
Beiträge: 25
|
Verfasst: Sa 12.02.05 12:51
genau ist die YMSG12Encrypt.dll
die dll gibt es hier : www.geocities.com/httpymsg/ymsg12crypt.zip
die exportierte funktion heisst : YMSG12_ScriptedMind_Encrypt
@assarbad das mit der dll.. klappt leider auch nicht :-s
_________________ Wer rechtschreibfehler findet darf sie behalten!
|
|
Gast
Gast
Erhaltene Danke: 1
|
Verfasst: 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 
      
Beiträge: 25
|
Verfasst: Sa 12.02.05 14:26
mit pchar anstatt string.. gehts leider auch nicht :-s
thx @assarbad
_________________ Wer rechtschreibfehler findet darf sie behalten!
|
|
AXMD
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Sa 12.02.05 14:27
Was is mit Shortstring?
AXMD
|
|
SchwiegerSohn 
      
Beiträge: 25
|
Verfasst: Sa 12.02.05 14:40
shortstring geht
*thx* @ all
_________________ Wer rechtschreibfehler findet darf sie behalten!
|
|
uall@ogc
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: Sa 12.02.05 14:42
mir zeigt olly nur an das es eine funktion gibt die exportiert wird: Ymsg12Crypt
|
|
Gast
Gast
Erhaltene Danke: 1
|
Verfasst: 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.
|
|
Gast
Gast
Erhaltene Danke: 1
|
Verfasst: 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
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: 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 
      
Beiträge: 25
|
Verfasst: 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; stdcall; external '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(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 raziel: Code- durch Delphi-Tags ersetzt.
_________________ Wer rechtschreibfehler findet darf sie behalten!
|
|
Gast
Gast
Erhaltene Danke: 1
|
Verfasst: 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.
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.
Zuletzt bearbeitet von Gast am Sa 12.02.05 15:09, insgesamt 1-mal bearbeitet
|
|
Gast
Gast
Erhaltene Danke: 1
|
Verfasst: 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 
      
Beiträge: 25
|
Verfasst: 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
ich wollte keine verwirrung stiften 
_________________ Wer rechtschreibfehler findet darf sie behalten!
|
|
Gast
Gast
Erhaltene Danke: 1
|
Verfasst: Sa 12.02.05 15:42
Na dann guck ich mir die auch nochmal schnell an.
|
|
Gast
Gast
Erhaltene Danke: 1
|
Verfasst: 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: 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';
|
|
|