Hi folks,
I'm having some trouble with a function that is compiled in a DLL to be called by a Visual Basic program. It exspects two parameters: Parameter1 is a pointer to a (Text-)String, Parameter2 the length of that string. The intention is to decrypt the string with a simple XOR encryption and decrypt it again (yeah, senseless, I know... ::) ):
.386
.model flat, stdcall
option casemap: none
include \masm32\include\windows.inc
include \masm32\include\wininet.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\wininet.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
.data?
Param1 DWORD ?
Param2 DWORD ?
.code
Funktion proc Parameter1:DWORD, Parameter2:DWORD
mov eax, Parameter1
mov Param1, eax
mov eax, Parameter2
mov Param2, eax
;load segments with the correct addresses for lodsb/stosb
mov ax,ds
mov es,ax
;load edi/esi with the address of the string
mov edi,Param1
mov esi,Param1
;Encrypt
mov ecx,Param2
cld
Schleife:
lodsb
xor al,45
stosb
dec ecx
jnz Schleife
;set back edi/esi
mov edi,Param1
mov esi,Param1
;Decrypt
mov ecx,Param2
Schleife2:
lodsb
xor al,45
stosb
dec ecx
jnz Schleife2
mov eax, Param1
ret
Funktion endp
In some cases it works fine, but mostly it crashes with an access violation.
Can anybody tell me, what's wrong?
Thank you very much!
Greetz,
Daniel
A couple of things strike me:
1) you don't need to fiddle with the segment registers.
2) Make sure that you save esi and edi at the start and restore them at the end.
I think you want something more like this (but I'm not too sure that this is what you want it to be doing):
.386
.model flat, stdcall
option casemap: none
include \masm32\include\windows.inc
include \masm32\include\wininet.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\wininet.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
.code
Funktion proc Parameter1:DWORD, Parameter2:DWORD
push esi
push edi
;load edi/esi with the address of the string
mov edi,Parameter1
mov esi,Parameter1
;Encrypt
mov ecx,Parameter2
cld
Schleife:
lodsb
xor al,45
stosb
dec ecx
jnz Schleife
;set back edi/esi
mov edi,Parameter1
mov esi,Parameter1
;Decrypt
mov ecx,Parameter2
Schleife2:
lodsb
xor al,45
stosb
dec ecx
jnz Schleife2
pop edi
pop esi
mov eax, Parameter1
ret
Funktion endp
It's a bit odd - the net result of that function is to do nothing?!?!
Also make sure that you realise that xor encryption is very weak (i take it this was a trial though, so it doesn't matter?)
Ossa
I am not familiar with VB, but it would be wise to save and restore ebx register as well. (in case you are planning to add some code that modifies it). Otherwise it could cause some problems in the calling app.
Hi! Thanks for your answers!
@Ossa:
you're right, it should do nothing :wink the actual intention is firstly to act as a trial, because I'm a beginner at ASM and secondly a speed comparison between a VB routine and the assembler routine. If it really was for encryption, I would not use XOR.
you're surely right about the Save and Restore of the used registers, I've modified the code that way; but the problem does not occur after returning to the calling process, it seems to be in the routine I posted, so this doesn't help...
HappyTeddy,
Welcome a Board !!! :U
Forum 'Search' is your friend, along with Google. :dance:
Please read the forum rules. :naughty:
What are you using to develope this code?
This is not dll code. Where is LibMain?
You don't use segment registers for data with a flat model.
Register preservation is nil.
What version of VB are you talking about?
This does not appear to be called correctly, given the data type.
So tell us more of what your trying to do. Post some code of use.
Is this Homework?
'Search' can get you up and running with code techniques, to help you along your way. I suggest you install MASM32 package too. And through the Examples and Helps.
Regards, P1 :8)
:: Welcome a Board !!!
Thanks.
:: Forum 'Search' is your friend, along with Google.
ok, but search for WHAT? Can you give me a hint?
:: Please read the forum rules.
done already.
:: What are you using to develope this code?
Hutch's MASM32 package.
:: This is not dll code. Where is LibMain?
I didn't post LibMain (which is called "DllMain" in my case) to simplify the problem, because the DLL is obviously called correctly, so this can't be the problem. Here you are:
DllMain proc hInstDll :DWORD,
dwNotification:DWORD,
lpReserved :DWORD
.if dwNotification==DLL_PROCESS_ATTACH
;eigener Initialisierungscode für Prozesse
.elseif dwNotification==DLL_PROCESS_DETACH
;eigener DeInitialisierungscode für Prozesse
.elseif dwNotification==DLL_THREAD_ATTACH
;eigener Initialisierungscode für Threads
.elseif dwNotification==DLL_THREAD_DETACH
;eigener DeInitialisierungscode für Threads
.endif
ret
DllMain endp
:: You don't use segment registers for data with a flat model.
ok, thanks...! :red As you may have regocnized, I'm new to ASM.
:: Register preservation is nil.
yeah, see above. :red I fixed that, but it doesn't solve the problem.
:: What version of VB are you talking about?
6.0
:: This does not appear to be called correctly, given the data type.
Maybe this is the problem. Could you explain this nearer, plz?
:: So tell us more of what your trying to do. Post some code of use.
I've posted ALL code of the DLL now. I've already explained as clear as possible, what the routine intends to do. It is mainly a trial for me, because I'm new to Assembler and it should use as a speed comparison between a VB routine and an asm routinel.
DLL_PROCESS_ATTACH should return TRUE.
Dll wont load if any other value is returned.
.if dwNotification==DLL_PROCESS_ATTACH
;eigener Initialisierungscode für Prozesse
mov eax, TRUE
ret