News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

2 questions

Started by Parse, June 08, 2005, 07:01:13 PM

Previous topic - Next topic

Parse

1) Is it possible to recover the registers of the calling process in the DLL initialization when u load a DLL with LoadLibrary?

2) How do you allocate more stack to a thread? because I use the stack as a buffer. can i make this buffer bigger?

QvasiModo

1) The loading process is the one that executes the DLL initialization routine, no matter how the library is loaded. I'm not sure I understand the question... :(

2) The stack "grows" automatically as you use it. To use a buffer in the stack you can just decrement the bytes you need from ESP, but you better know what you're doing, I'd recommend testing it first on a debugger if you're not familiar with the stack yet.

You will also have a problem if your buffer is bigger than 4 kilobytes, search the board for "stack probe" for more info.

Hope that helps! :U

Parse

1)
ebx, ebp, edx = diamonds
i call LoadLibrary("MyLib.dll")
so control shifts to the DllMain function of the DLL
now, can i recover ebx, ebp and edx in the dLL without calling a function from the DLL?

2) so is there any way to allocate more stack at runtime?

hutch--

Parse,

A DLL uses the stack size in the EXE that calls it so if you need more stack space, set it with the linker for the calling EXE file. You tend to need oversized stack allocations only if you run massive recursion.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

tenkey

LoadLibrary needs to do a lot of processing before it transfers control to a DLL. (It needs to do file I/O.) So by the time the DLL initialization routine is called, the registers will probably be trashed. The only guarantee is that EBP, EBX, ESI, and EDI are restored before returning from LoadLibrary.

No special care is provided to keep register values intact through a chain of calls.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

donkey

Hi Parse,

If you are the author of the DLL you can just preserve any register value you wish and use them as you will. The only place you will loose or modify register data is with instructions that alter the register or in calling Windows APIs which are only guaranteed to preserve EBP, ESP, EDI, ESI and EBX. However, generally speaking the entry procedure for a DLL should NEVER make any calls to the API as the library is not necessarily loaded when the entry proc is called. The only DLL that is sure to be resident when you call DllEntryProc is Shell32, all others are dependant on whatever the OS decides on for load order.

CreateThread
  HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  SIZE_T dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddress,
  LPVOID lpParameter,
  DWORD dwCreationFlags,
  LPDWORD lpThreadId

dwStackSize
[in] Initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

QvasiModo

Quote from: donkey on June 11, 2005, 03:18:51 AM
However, generally speaking the entry procedure for a DLL should NEVER make any calls to the API as the library is not necessarily loaded when the entry proc is called. The only DLL that is sure to be resident when you call DllEntryProc is Shell32, all others are dependant on whatever the OS decides on for load order.

If your DLL calls an API from an imported library, the OS must load the imported library first... the DLL imports are fully processed by the time the entry point is called (unless there are circular imports). Or am I missing something? :dazzled:

donkey

Quote from: QvasiModo on June 13, 2005, 09:13:15 PM
Quote from: donkey on June 11, 2005, 03:18:51 AM
However, generally speaking the entry procedure for a DLL should NEVER make any calls to the API as the library is not necessarily loaded when the entry proc is called. The only DLL that is sure to be resident when you call DllEntryProc is Shell32, all others are dependant on whatever the OS decides on for load order.

If your DLL calls an API from an imported library, the OS must load the imported library first... the DLL imports are fully processed by the time the entry point is called (unless there are circular imports). Or am I missing something? :dazzled:

You can create dependancy chains that can result in access violations as well as deadlocks. MSDN has this to say about entry points to DLLs

QuoteDo not call LoadLibrary in the entry-point function, because you might create dependency loops in the DLL load order. This can cause a DLL to be used before the system executes its initialization code.

Similarly, do not call the FreeLibrary function in the entry-point function on detach, because this can cause a DLL to be used after the system executes its termination code.

Calling Microsoft® Win32® functions other than TLS, object-creation, and file functions can cause problems that are difficult to diagnose.

For example, calling User, Shell, COM, and Windows Sockets functions (or functions that call these functions) can cause access violation errors, because their DLLs call LoadLibrary to load other system components.

Although it is acceptable to create synchronization objects in DllMain, do not perform synchronization in DllMain (or a function called by DllMain), because all calls to DllMain are serialized. Waiting on synchronization objects in DllMain can cause a deadlock.

To provide more complex initialization, create an initialization routine for the DLL.

You can require applications to call the initialization routine before calling other routines in the DLL. Otherwise, you can have the initialization routine create a named mutex, and have each routine in the DLL call the initialization routine if the mutex does not exist.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

QvasiModo

Good to know that... :eek thanks :U