flat assembler
Message board for the users of flat assembler.

Index > Windows > Passing data to DLL

Author
Thread Post new topic Reply to topic
DustWolf



Joined: 26 Jan 2006
Posts: 373
Location: Ljubljana, Slovenia
DustWolf 16 Aug 2006, 18:49
Hello,

Quite a begginer problem. I'm trying to make my very first DLL and doing it by moving a simple encrypiton algorithm from an EXE into it and then calling the DLL from the EXE.

I'm wondering (and can't quite extrapolate it from the minimalistic DLL example packaged with FASM), how arguments are actually passed to a DLL and wether or not does the DLL have access to the host program's memory.

I made a DLL that is supposed to accept an offset of a byte array and an offset of the DWORD describing the string's lenght. It was then supposed to go trough the byte array and alter it. However all that actually happens is that my byte array gets nullified.

Here's the DLL procedure's code:
Code:
proc Encrypt   dataBuffer,dataLenght
                    xor     ecx,ecx
ecryptLoop:    mov     eax, dword [dataBuffer + ecx]
                    xor     eax, 'DSCX'
                    mov     dword [dataBuffer + ecx],eax
                    add     ecx,4
                    cmp     ecx,[dataLenght]
                     jne     ecryptLoop
endp    


...and the noteworthy code in the EXE:
Code:
                     invoke  Encrypt,DataBuffer,DataLen
...
DataBuffer      rb      1025
DataLen         dd      1024   
    


Could somebody please point me to the problem and explain what did I get wrong?

Thanks a lot. Smile
Post 16 Aug 2006, 18:49
View user's profile Send private message Reply with quote
UCM



Joined: 25 Feb 2005
Posts: 285
Location: Canada
UCM 16 Aug 2006, 19:44
Because the DLL is mapped into the host program's addressing space, it can access the host program's memory (in fact, only within the host program). What you are probably getting wrong is that first, you you forgot to put a "ret" at the end of your procedure, and because DataLen is the address of the variable, not the variable contents (like in MASM). In addition, [dataBuffer] is only the pointer to the data, so you must first load it into a register. The correct code, then, should be like this:
Code:
proc proc Encrypt   dataBuffer,dataLenght
                    xor     ecx,ecx
                    mov    esi,[dataBuffer]
ecryptLoop:         mov     eax, dword [esi + ecx]
                    xor     eax, 'DSCX'
                    mov     dword [esi + ecx],eax
                    add     ecx,4
                    cmp     ecx,[dataLenght]
                    jne     ecryptLoop
                    ret
endp
;and in the EXE:
invoke        Encrypt,DataBuffer,[DataLen] ;getting the value of DataLen, not the address
...
DataBuffer rb 1025
DataLen dd 1024
    


In fact, there are many things which could be optimized in your procedure, but I will not cover those, for now.
Post 16 Aug 2006, 19:44
View user's profile Send private message Reply with quote
DustWolf



Joined: 26 Jan 2006
Posts: 373
Location: Ljubljana, Slovenia
DustWolf 16 Aug 2006, 21:23
UCM wrote:
Code:
mov    esi,[dataBuffer]    


This can't be right. That would move the contens of the data buffer, namely the first 4 bytes into ESI. You will notice the code works with the offset, not with the contens (or the contens is dealt with only in the 3 lines where it is loaded into eax, xored and sent back).

Also, the intention of the DataLen part was to pass the offset to the variable value to the DLL since FASM disagreed with me providing the value there directly.
Code:
cmp     ecx,dataLenght    

throws: Invalid value "cmp ecx,..arg?0000641"

If you use:
Code:
invoke        Encrypt,DataBuffer,[DataLen]
;and then this
cmp     ecx,[dataLenght]    

...this would mean that the offset at DataLen would have to contain the offset to the top counter value, which is not the case as:
Code:
DataLen dd 1024    

indicates.

Have I got this all wrong? Does passing the parameters with invoke and proc automatically make turn them into offsets to the data provided?
Post 16 Aug 2006, 21:23
View user's profile Send private message Reply with quote
UCM



Joined: 25 Feb 2005
Posts: 285
Location: Canada
UCM 16 Aug 2006, 21:57
You, in fact, are indeed getting it all wrong. Within the procedure, [dataBuffer] may as well be DataBuffer from the main executable. (Sorry, I can't explain this properly at the moment.) Just try it.
Post 16 Aug 2006, 21:57
View user's profile Send private message Reply with quote
DustWolf



Joined: 26 Jan 2006
Posts: 373
Location: Ljubljana, Slovenia
DustWolf 16 Aug 2006, 22:25
UCM wrote:
You, in fact, are indeed getting it all wrong. Within the procedure, [dataBuffer] may as well be DataBuffer from the main executable. (Sorry, I can't explain this properly at the moment.) Just try it.


Okay I got it.

when you refer to something in a proc, it doesn't pass on the actual values but always pointers to those values even if the values themselves are pointers.

You mentioned optimization earlier... could you show me something of that? The code as it is now runs at 100 MB in 30 seconds and it is held back heavily by the speed of my RAID array (2% CPU usage). I wonder just how fast can this code be.

I am especially puzzled about this optimization since FASM's own optimizer left my code mostly unchanged.


Last edited by DustWolf on 16 Aug 2006, 23:03; edited 1 time in total
Post 16 Aug 2006, 22:25
View user's profile Send private message Reply with quote
UCM



Joined: 25 Feb 2005
Posts: 285
Location: Canada
UCM 16 Aug 2006, 22:31
If the function was called with "invoke DLLCall,DataBuffer" then within the procedure (defined as "proc DLLCall ProcDataBuffer" to avoid confusion) "[ProcDataBuffer]" is the same as "DataBuffer". If the function was called with "invoke DLLCall,[DataBuffer]" then within the function "[ProcDataBuffer]" is equal to "[DataBuffer]". So, [ProcDataBuffer] is the same as the argument passed to it.
Post 16 Aug 2006, 22:31
View user's profile Send private message Reply with quote
DustWolf



Joined: 26 Jan 2006
Posts: 373
Location: Ljubljana, Slovenia
DustWolf 16 Aug 2006, 23:05
UCM wrote:
If the function was called with "invoke DLLCall,DataBuffer" then within the procedure (defined as "proc DLLCall ProcDataBuffer" to avoid confusion) "[ProcDataBuffer]" is the same as "DataBuffer". If the function was called with "invoke DLLCall,[DataBuffer]" then within the function "[ProcDataBuffer]" is equal to "[DataBuffer]". So, [ProcDataBuffer] is the same as the argument passed to it.


That's weird. Confused But thanks. Smile
Post 16 Aug 2006, 23:05
View user's profile Send private message Reply with quote
daluca



Joined: 05 Nov 2005
Posts: 86
daluca 17 Aug 2006, 06:21
Quote:


I'm wondering (and can't quite extrapolate it from the minimalistic DLL example
packaged with FASM),how arguments are actually passed to a DLL and wether or not
does the DLL have access to the host program's memory.


arguments are passed to a dll in the stack. they are pushed in it
with the push instruction, and they are accessed by the dll through
the EBP register so inside your proc you always have to access your
arguments as if you were reading memory: in the [ ] way
so:
Code:
mov  eax,dword [dataBuffer + ecx]
    

after this gets executed you are loading in eax the pointer to the data
not the first four bytes of it.
so as UCM said you must first load it into a register do you can
access the data through the register.

although this is just a convention you can pass
arguments in registers too.

proc is a macro that deals with this convention
Code:
mov    esi,[dataBuffer]
    

would move the contens of the data buffer, namely the first 4 bytes into ESI
as you said, but this is true only outside the proc/endp
and as long as you have a label with this name
Post 17 Aug 2006, 06:21
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.