Windows API in assembly using MinGW assembler – 3

Shared Memory in a dll:
A data variable/constant in a dll is mapped to the address space of the calling process unless it is part of shared memory. There are instances when one needs to share a variable in a dll across all the applications that load the dll. We can make use of .section directive flags to create a shared-memory segment. Please refer to the example for implementation.

# file - dll.asm

.intel_syntax noprefix
.include "macroA.inc"
.include "user32.inc"
.include "kernel32.inc"

.section .data
    msg_box_title:
        .ascii "Message Box Title\0"
    msg:
        .ascii "Hello DLL\0"

.section .text
    .global dllMain
    .global _hello

	dllMain:
        # function prologue
        push	ebp
        mov	    ebp, esp

        mov     ebx, dword ptr [ebp+12]

        cmp     ebx, DLL_PROCESS_DETACH
        jz      process_detach

        cmp     ebx, DLL_PROCESS_ATTACH
        jz      process_attach

        cmp     ebx, DLL_THREAD_ATTACH
        jz      thread_attach

        cmp     ebx, DLL_THREAD_DETACH
        jz      thread_detach

	process_attach:
        jmp     exit_dll

	thread_attach:
        jmp     exit_dll

	thread_detach:
        jmp     exit_dll

	process_detach:
        jmp     exit_dll

        # return boolean value
        mov     eax, TRUE

    # function epilogue
    exit_dll:
        mov     esp, ebp
        pop     ebp
        ret

    _hello:
        # function prologue
        push	ebp
        mov	    ebp, esp

        inc     dword ptr shared_var
        invoke  MessageBox, 0, "offset msg", "offset msg_box_title", 0

        # function epilogue
        mov	    esp, ebp
        pop     ebp
        ret

# share_var becomes a shared-memory segment with the name myshared
.global shared_var
.section myshared, "bs"
    shared_var:
        .space 4

.section .drectve
	.ascii " -export:hello"
# file - hello.asm

.intel_syntax

.include "macroA.inc"
.include "kernel32.inc"

.section .data
    dll_lib:
        .ascii "message.dll\0"
    dll_func:
        .ascii "hello\0"

.section .text
    .globl _start
	_start:
        # load message.dll library
        invoke  LoadLibrary, "offset dll_lib"

        # get the address of the hello exported function in message.dll
        invoke  GetProcAddress, eax, "offset dll_func"

        # call hello function
        invoke  eax

        invoke  ExitProcess, 0

.end

Use the following commands to build this example.

as -o dll.o dll.asm -ID:\examples\includes
ld -s -shared -o message.dll dll.o -LD:\MinGW\lib -luser32 -lkernel32
as -o hello.o hello.asm -ID:\examples\includes
ld -s --subsystem windows -o hello.exe hello.o -LD:\MinGW\lib -luser32 -lkernel32

Try running two instances of the hello.exe and observe the value of the shared-memory segment in a debugger of your choice.

Leave a Reply