Access Violation (ErrorCode: 5) bei DLL
-
Hallo,
ich habe ein meiner Meinung nach sehr seltsames Problem:
Programm (C++):
HMODULE hDll; GetLastError() ; <- 0 hDll = LoadLibraryA(PFAD_ZUR_DLL);
Dll (ASM):
DllMain PROC hInstance:DWORD, dwReason:DWORD, lpReserved:DWORD xor EAX, EAX call GetLastError ; <- 5, Access Violation DllMain ENDP
Jetzt frag ich mich wie das passieren kann, da ich doch eigentlich garnichts falsch machen KANN, ich bin langsam echt am verzweifeln....
Win7 x64
Visual Studio 2010Mit freundlichen Grüßen
-
Wie ist den GetLastError definiert?
-
da fehlt RET ...
-
Nene, das ret hab ich nur aus Platzgründen weggelassen. GetLastError() ist aus den includes von masm32...
Ich hab jetzt allerdings einfach nochmal von 0 angefangen. Als ich nur den "rohen" aufbau von DllMain hatte...
DllMain: push EBP mov EBP, ESP xor EAX, EAX call GetLastError mov ESP, EBP pop EBP ret
...da gab es keinen Error.
Dann habe ich die Funktionen eingefügt, [siehe unten]. Plötzlich kommt wieder Error:5, wobei ich GetLastError VOR allen Funktionen aufrufe:DllMain: push EBP mov EBP, ESP xor EAX, EAX call GetLastError ... Funktionen ... mov ESP, EBP pop EBP ret
Am Ende der DllMain crasht alles beim Rücksprung, (wieder Access Violation)...
Hier der gesammte Code (ist noch nicht wirklich übersichtlich).586 .model flat, stdcall option casemap:none includelib C:\masm32\lib\user32.lib includelib C:\masm32\lib\kernel32.lib includelib C:\masm32\lib\shell32.lib include C:\masm32\include\windows.inc include C:\masm32\include\kernel32.inc include C:\masm32\include\user32.inc .data? szModulePath DB 1024 DUP(?) szModuleFile DB 1024 DUP(?) .data szPattern DB "\" .code ; DLL MAIN DllMain: push EBP mov EBP, ESP ; DS == ES für "movsx" push DS pop ES xor EAX, EAX call GetLastError <- Error 5, warum ??? ; GetModuleFileName push SIZEOF szModulePath push OFFSET szModulePath push 0 call GetModuleFileName ; StringLastIndexOf (OFFSET szModulePath, EAX [lstrlen], OFFSET szPattern) push OFFSET szModulePath call lstrlen push OFFSET szPattern push EAX push OFFSET szModulePath call StringLastIndexOf ; szModuleFile = szModulePath - Index, also NUR der DateiName mov EBX, EAX mov ESI, OFFSET szModulePath add ESI, EBX mov EDI, OFFSET szModuleFile push OFFSET szModulePath call lstrlen mov ECX, EAX sub ECX, EBX rep movsb ; Testausgabe invoke MessageBoxA, 0, OFFSET szModuleFile, OFFSET szModuleFile, 0 ; Return True mov EAX, 1h mov ESP, EBP pop EBP ret ; Die Funktion die mir den letzten Index von "\" gibt. StringLastIndexOf: push EBP mov EBP, ESP push EBX push ECX push EDX push EDI push ESI mov ESI, [EBP + 8] ; Address Of String mov ECX, [EBP + 12] ; StringLength mov EAX, [EBP + 16] ; Address Of SearchPattern mov BX, [EAX] xor EDX, EDX xor EDI, EDI StringLastIndexOf_Start: cmp ECX, 0h jle StringLastIndexOf_Done dec ECX xor EAX, EAX mov AL, [ESI + EDX] cmp AX, BX jne StringLastIndexOf_NotEqual mov EDI, EDX StringLastIndexOf_NotEqual: inc EDX jmp StringLastIndexOf_Start StringLastIndexOf_Done: add EDI, 1h mov EAX, EDI pop EBX pop ECX pop EDX pop EDI pop ESI mov ESP, EBP pop EBP ret 12d ; Wegen den 3 Parametern (Addresse (4Byte), EAX (4byte), Addresse (4Byte) = 3*4Byte = 12byte) END DllMain
-
- DllMain hat 3 Parameter -> ret 12
- du kannst (und brauchst) die Segmentregister nicht modifizieren (Win32)
- du Sicherst die Register edi, esi und ebx falsch (push/pop->FIFO)
-
1. Okay, wurde gemacht
2. Alles klar, okay
3.dämlicher Fehler...
Aber das Problem bleibt:
ret spring ins Nirvana...
"Unbehandelte Ausnahme bei 0x00000000 in Test.exe: 0xC0000005: Access violation."D.h. Ich hab entweder zu viel auf dem Stack, oder zu wenig. Jedenfalls sitzt dort, wo nach EIP gesucht wird, wohl ein anderer Wert...
Aber ich finde den Fehler nicht...Oder seh ich da etwas falsch...?
-
Edit:
DllMain: push EBP mov EBP, ESP xor EAX, EAX call GetLastError ; <- Error 5
Gibt mir immer noch Error 5.
Ich denke da wird wohl das Problem sein, allerdings hab ich überhaupt keine Ahnung, woher der Fehler kommen soll....Wenn ich alles in der Funktion auskommentiere, gibts keinen Fehler...aber wie kann den eine Fehler auftreten, BEVOR ich irgendetwas mache ?
DllMain: push EBP mov EBP, ESP xor EAX, EAX call GetLastError ; <- Kein Error comment * ... * mov EAX, 1h mov ESP, EBP pop EBP ret 12d
-
Sorry, für 3fachen Post, aber ich bin ein Stück weiter gekommen:
Bei Ret crasht das programm nicht mehr, ich muss dafür allerdings:
StringLastIndexOf: ... ret 12d <- CRASH ret 16h <- Läuft !
.Es werden doch keine 22 Bytes übergeben !?
Allerdings bleibt GetLastError am anfang auf 5...
-
Den Fehler durch GetLastError() kannst du ignorieren, da er Außerhalb deines Codes erzeugt wurde (obwohl es merkwürdig ist…). Außerdem beachtest du nicht die WinABI - DllMain ist eine Callback-Funktion - dementsprechend darfst du ebx, edi und esi nicht verändern. Außerdem behandelst du nicht die Verschiedenen Fälle, in denen DllMain Aufgerufen wird. So müsste es gehen:
include masm32rt.inc .data? szModulePath DB 1024 DUP(?) szModuleFile DB 1024 DUP(?) .data szPattern DB "\" .code StringLastIndexOf proto pBuffer:ptr CHAR,cbBuffer:DWORD,cPattern:DWORD DllMain proc hinstDLL:HINSTANCE,fdwReason:DWORD,lpvReserved:LPVOID .if fdwReason == DLL_PROCESS_ATTACH invoke GetModuleFileName,0,OFFSET szModulePath ,SIZEOF szModulePath invoke StringLastIndexOf,OFFSET szModulePath,SIZEOF szModulePath,'\' .if eax invoke MessageBox,0,eax,0,0 .else fn MessageBox,0,"error","error",0 .endif .endif mov eax,1 ret DllMain endp StringLastIndexOf proc uses esi ebx pBuffer:ptr CHAR,cbBuffer:DWORD,cPattern:DWORD mov esi, pBuffer movzx ebx,CHAR ptr cPattern xor ecx,ecx xor edx,edx .while ecx < cbBuffer && CHAR ptr [esi+ecx] movzx eax,CHAR ptr [esi+ecx] .if eax == ebx lea edx,[esi+ecx+1] .endif lea ecx,[ecx+1] .endw mov eax,edx ret StringLastIndexOf endp END DllMain
-
Hm...ja, die WinAPI hab ich erst einmal extra ingnoriert, weil unnötig...
Okay, soweit läuft es ja, aber die Access Violation wundert mich sehr; das hatte ich vorher noch nie...
Naja, muss wohl in der LoadLibraryA bzw LoadLibraryW Prozedur ablaufen...Danke dir jedenfalls für deine Zeit
PS:
Die ganzen masm32 Macros wie PROC, .if, uses, proto, etc. habe ich extra nicht verwendet, da ich gerade erst mit ASM anfange und somit so wenig "Hilfen" wie möglich verwenden möchte...