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 2010

    Mit 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...


Anmelden zum Antworten