Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Please Help - NASM DLL

103 views
Skip to first unread message

George Marcus

unread,
Sep 19, 2003, 11:46:22 AM9/19/03
to
I am new to assembly programming and am having problems with a DLL I
have created using NASM. I have a function in the DLL that I would
like to have display a message box using the Windows API. When I call
this function from VB, I get an error saying, "The instruction at
'0x03383040' referenced memory at '0x00338100b'. The memory could not
be 'written'."

I tried explicitly setting the data segment register to the data
segment in my DLL before pushing the message box parameters onto the
stack (thinking that may be the problem), but the linker wouldn't let
me do that.

What am I missing? Any help that anyone could offer would be greatly appreciated.

I'm running this on a Pentium III based machine under Windows 2000. My
code follows.

~~~~~ GMENCRPT.ASM ~~~~~
; GMENCRPT.DLL
;
; Author: George F Marcus Jr
; Edition: 09.17.2003

GLOBAL EncryptA
EXPORT EncryptA
GLOBAL GMEncrptVer
EXPORT GMEncrptVer

EXTERN MessageBoxA

[SEGMENT CODE PUBLIC USE32 CLASS=CODE]

; STDCALL Entry Point - Flag success & return 3 parameters (DWORD)
..start:
mov EAX, 1 ;Flag success
ret 12 ;Remove 3 parameters (DWORD) from stack

EncryptA: ;Expects one DWORD on stack - Address of C
string
ret 4 ;Clean up stack

GMEncrptVer:
push dword 0 ;OK button
push dword VerTitle ;Title
push dword VerText ;MsgBox Text
push dword 0 ;Window Handle
call MessageBoxA ;Call API Function
ret

[SEGMENT DATA PUBLIC USE32 CLASS=DATA]

VerTitle: db 'GMarc Encryption Library',0
VerText: db 'Version 1.0.1',0
~~~~~ End GMENCRPT.ASM ~~~~~


~~~~~ GMLIB.ASM ~~~~~
; GMLIB.OBJ
;
; Author: George F Marcus Jr
; Edition: 09.17.2003

GLOBAL MessageBoxA
IMPORT MessageBoxA User32.DLL
~~~~~ End GMLIB.ASM ~~~~~


I assembled the above two files using the following:

NASMW -fobj -E GMLIB.ERR GMLIB.ASM
NASMW -fobj -E GMENCRPT.ERR GMENCRPT.ASM

I linked the two object files with ALINK using the following:

ALINK -oPE -dll GMENCRPT.OBJ GMLIB.OBJ

The declaration and function call I'm using within VB is as follows:

Public Declare Sub GMEncrptVer Lib "GMEncrpt" ()

Sub ShowGMEncrptVer
GMEncrptVer
End Sub

Matt Taylor

unread,
Sep 19, 2003, 3:41:33 PM9/19/03
to
Most of it looks okay. (I'm assuming you meant to make EncryptA do nothing,
i.e. a placeholder?)

I'm not sure if this is true of Nasm, but when I do inline assembly in VC
all the functions I call in other DLLs are really function pointers, and you
have to use an extra level of indirection. This is probably the problem
since you make a direct call. The way DLLs work is that you link against a
"stub" for the function. You get a 4-byte pointer in your data segment, and
when you load the loader places the address of that function in the stub.
The symbol MessageBoxA points to the stub, not the function MessageBoxA.
Here's an example if it helps to elaborate:

section .data
funptr dd myfunc

section .text
...start:
call myfunc ; Direct call
call dword [funptr] ; Indirect call like DLL imports
mov [funptr], dword myfunc2
call dword [funptr] ; Calls myfunc2 this time
ret

myfunc:
ret

myfunc2:
ret

Now, it is also possible to do this:

MessageBoxA: ; symbol visible to you
jmp MessageBoxAStub ; dummy stub for loader (it doesn't care about
symbol name)

MessageBoxAStub resd 1 ; Loader fills this in with MessageBoxA

But that would depend on your libraries, and I doubt that is the case.

Oh, and btw, you should never need to play with cs, ds, es, or ss. In fact,
don't. Windows assumes that cs = base 0, limit 4 GB - 1,
read-only/executable and ds = es = ss = base 0, limit 4 GB - 1, read-write.
The other segment registers are also off-limits.

-Matt

"George Marcus" <george...@encompassins.com> wrote in message
news:f93e2486.03091...@posting.google.com...

George Marcus

unread,
Sep 22, 2003, 11:18:31 AM9/22/03
to
Matt,

Thank you very much for your help. Dereferencing the typed pointer
worked like a charm. I tried this with out explicitly declaring the
function pointer as a 'dword' (ex. call [MessageBoxA]) before making
my initial post. That didn't work and I was really at a loss as to
what the problem was. Again, thanks for your help. I guess programming
in assembly is all in the details.

George

"Matt Taylor" <pa...@tampabay.rr.com> wrote in message news:<NZIab.9946$Od.4...@twister.tampabay.rr.com>...

0 new messages