3


I'm working on an application that injects a dll when a process starts (Suspend --> Inject --> Resume) The very first call in DllMain with DLL_PROCESS_ATTACH (in the dll I injected) is a call to MessageBox() (just for debugging purpose). However, this call to MessageBox() sometimes pops an error and crashes the injected process.

Runtime Error!
Program: C:\Program Files\Microsoft Office\Office14\OUTLOOK.EXE

R6030
- CRT not initialized

This is reproducible with Outlook and Winword for example. Though Notepad, IE, CMD, Calc and many others - print the message box and continue normally.

Printing a message box is not a must-have for me, so I just want to be able to check whether CRT has done initialization or not, so I can continue normally like this:

case DLL_PROCESS_ATTACH:
     if (IsCRTInitialized())
        MessageBox(...);

Please let me know if some information is missing. Thanks!

Elad
  • 123
  • 1
  • 7

2 Answers2

3

Kernel32.dll is guaranteed to be loaded in the process address space when the entry-point function DLLMain is called. MessageBox resides in user32.dll and as per Best practices for creating DLL calling functions from user32.dll is a strict no-no.

You can either

  1. Call OutputDebugString for any debugger tracing. This function resides in kernel32.dll and should be safe to call.

  2. Before your application loads any other dlls, call MessageBox yourself. This will ensure that user32.dll and its dependencies are already loaded. This way calling MessageBox in DllMain may have a better chance of succeeding. But your mileage may vary.

parapura rajkumar
  • 24,045
  • 1
  • 55
  • 85
  • Thanks @parapura. I'm aware of OutputDebugString (actually it is already in use). However this does not solve this issue. The main purpose for this message box is not just to show me some text, but to be able to debug-attach to any process creation in the very first steps of it. Most of the processes are able to call MessageBox() at this very early stage. – Elad Nov 22 '11 at 13:44
  • Continue: I'm not trying to find a way to force the presence of a message box (I know I can't), but at least knowing that the CRT was not initialized will be good enough. I thought I can try to check it using **GetModuleHanlde** on *user32.dll* (and not **LoadLibrary**) but I actually do get a valid handle HMODULE to *user32.dll*... I do not want to load *user32.dll* in my injected dll since it might not be needed. – Elad Nov 22 '11 at 13:44
  • If your goal is to debug attach process creation. Use [Image file executation options](http://msdn.microsoft.com/en-us/library/a329t4ed(v=vs.71).aspx) – parapura rajkumar Nov 22 '11 at 13:47
  • Thanks once again. The **Image file execution** is nice and useful, but this is still not what I'm looking for. Using it, any execution of a selected process will run in debug (even when my injected dll is not there) + another instance of VisualStudio is being launched instead of using the same one + I cannot use code-rules (for example, I want to be able to debug-attach only for exe(s) that have the substing "out" (outlook.exe / shout.exe ...) . Do you happen to know whether it is actually possible to know whether the CRT is already initialized? – Elad Nov 22 '11 at 14:17
  • @Elad I think you might have better luck somebody answering your question if you ask "How can I do blah" rather than how to find CRT is initialized. Launching exe from DllMain is not something people typically do. – parapura rajkumar Nov 22 '11 at 16:03
2

The problem isn't the CRT. You're not allowed to call MessageBox or any other non-trivial function from DllMain

MSalters
  • 173,980
  • 10
  • 155
  • 350