flat assembler
Message board for the users of flat assembler.

Index > Windows > How to pass string from DLL to a HLL

Author
Thread Post new topic Reply to topic
DustWolf



Joined: 26 Jan 2006
Posts: 373
Location: Ljubljana, Slovenia
DustWolf 24 Nov 2006, 23:22
Hello,

(my third thread today *sigh*)

What is the correct way to pass a string from a (stdcall) DLL procedure to the host program, if the host program is written in a high level language which expects that everything is standard?

I immagine it is done by putting an offset to the null-terminated string into eax upon ret, however I don't know where to put the string itself.

If I reserve a buffer for the string in the DLL's local:
Code:
locals
feedback     rb      1024
             db      0
endl    


...Then it seems to work, except that the string occasionally turns out corrupt for no particular reason.

I guess I could always use malloc or something like that, but if I want to do that I'd have to be sure that the host program knows it has to free the allocation or I'd end up with a memory leak. (Can't seem to find an exisitng example simple enough to reverse engineer it.)

Since DLLs written in a HLL seem to work fine with any other HLL, I'm guessing there must be some sort of standard in this. How should I implement this according to it then?
Post 24 Nov 2006, 23:22
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 24 Nov 2006, 23:31
If you will return a non-constant string then the proper way is that the caller provide you with a buffer to place a copy of the null terminated string.

Quote:


...Then it seems to work, except that the string occasionally turns out corrupt for no particular reason.

Well actually there is a very good reason, you should never provide a pointer to local variables as a return value because that space lives only during the execution of the module, when you return that stack space is free to be used for other modules which obiously will corrupt your data.

PS: Make sure that your HLL handles strings as ASCIIZ (it's PCHAR on Delphi for example)
Post 24 Nov 2006, 23:31
View user's profile Send private message Reply with quote
DustWolf



Joined: 26 Jan 2006
Posts: 373
Location: Ljubljana, Slovenia
DustWolf 24 Nov 2006, 23:47
LocoDelAssembly wrote:
If you will return a non-constant string then the proper way is that the caller provide you with a buffer to place a copy of the null terminated string.

Quote:


...Then it seems to work, except that the string occasionally turns out corrupt for no particular reason.

Well actually there is a very good reason, you should never provide a pointer to local variables as a return value because that space lives only during the execution of the module, when you return that stack space is free to be used for other modules which obiously will corrupt your data.


Figures. Smile

So... if the caller provides an offset to a reserved buffer (as if there was a way to reserve a buffer in the HLL... I'll think of something) and my DLL catches it a bit like this:
Code:
proc ReadEntry         uses esi edi ebx,feedbackBuffer    

then the code to fill in the needed bytes would be something like this:
Code:
        mov     esi,[feedbackBuffer]
        mov     [esi+ecx],al
        inc     ecx    

Right? (...last time I did that I ended up with an access violation... might have to recheck my code for register corruption tho.)
Post 24 Nov 2006, 23:47
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 25 Nov 2006, 00:35
Supposing you are using C as HLL you can do something like this:
Code:
ReadEntry((buffer = malloc(256)) 256);
Or 
char buffer[256]; 
ReadEntry(buffer, sizeof(buffer));    


Then in your ASM code you do this:
Code:
proc ReadEntry uses esi edi, outBuffer, outBufferSize
; This proc copies up to outBufferSize bytes from dllString
  mov     ecx, [outBufferSize]
  test    ecx, ecx
  jz     .end

  mov     esi, dllString
  mov     edi, [outBuffer]

.loop:
  lodsb
  stosb
  test    al, al
  jz      .endLoop

  dec     ecx
  jnz     .loop

.endLoop:
  mov     byte[edi-1], 0 ; To ensure that the string is  NULL terminated when outBufferSize < dllString size

.end:
  ret
endp

dllString db "Hello World Very Happy",0    

Note that the ASM code is just to demostrate how to store data in HLL data area, but it's not doing what its name says of course Laughing
Post 25 Nov 2006, 00:35
View user's profile Send private message Reply with quote
MichaelH



Joined: 03 May 2005
Posts: 402
MichaelH 25 Nov 2006, 00:54
Another way would be to export the buffer address in your fasm dll and have the hll import the address.

Code:

Message: db "This is a message from a fasm assembled dll!"

section '.edata' export data readable
                                                           
  export 'YOUR.DLL',\      
         Message,'Message'

section '.reloc' fixups data discardable

    



Or maybe the address in your dll can be a structure that gives buffer as well as buffer length etc.

Don't know if this is a good way of solving what you're doing and I haven't tested it but it should work.
Post 25 Nov 2006, 00:54
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 25 Nov 2006, 04:01
I think that MichaelH code works (MSN Messenger uses that trick to provide all countries with the same executable except for one DLL which exports the localized strings that way if I'm right), but as I said before, my code is just a demostration of how to access HLL memory space but not a real life example.

I also want to add that sometimes it's OK that the DLL allocate the space for you, at least that way it is in practice with FormatMessage API function when you pass the FORMAT_MESSAGE_ALLOCATE_BUFFER flag (though, the most common way is that the caller provides the buffer)
Post 25 Nov 2006, 04:01
View user's profile Send private message Reply with quote
DustWolf



Joined: 26 Jan 2006
Posts: 373
Location: Ljubljana, Slovenia
DustWolf 27 Nov 2006, 21:24
LocoDelAssembly wrote:
(MSN Messenger uses that trick to provide all countries with the same executable except for one DLL which exports the localized strings that way if I'm right)


(Actually the msgslang.dll file which contains this information has no exports. MSN Messenger probably uses Windows APIs to gain access to the DLL file's resources and extracts it's text and pictures from there.)
Post 27 Nov 2006, 21:24
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.