All right, Actually I am manually mapping a module into a process, actually my mapper calls DllEntryPoint from standard struct IMAGE_NT_HEADERS thus IMAGE_NT_HEADERS::OptionalHeader::AddressOfEntryPoint etc...

The problem: consider following code:

void Log(const char*, ...);

class Test
        struct List_t
            const uint32_t x;
            const uint32_t y; 
        } List;

        Test(List_t z) : List(z) { Log("Called event 0! \n"); }
        ~Test() {}

void Entry()
    Test Instance

    Log("Called! \n");  

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)

    if(fdwReason == 1)

    return TRUE;

so if the module entry point gets called through IMAGE_NT_HEADERS::OptionalHeader::AddressOfEntryPoint from mapper, the constructor Test() never gets executed, while that Entry() function gets executed successfully, now if the module it's loaded with standard LoadLibraryA(); so Test() constructor gets called successfully...

Where i would find some information about this?

I have heard something about CRT initializers, but i can't find anything deeply...

1 Answer 1


In case of programs you'd also have to watch out for TLS callbacks. These run prior to the entry point, but I have only ever seen those on .exe files, never on DLLs. Still, Peter Ferrie stated that TLS callbacks exist for DLL files. I'd trust his expertise on this, even though I've never seen one of those myself, when reverse engineering a DLL.

Anyway, DllMain in your case has that fdwReason parameter. That one is kind of important here and you should not have used a literal 1 there but the proper symbolic name: DLL_PROCESS_ATTACH.

DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH are the currently defined values. A switch statement would therefore be much more sensible here.

Depending on the reason for which you're being called back in DllMain you can act.

Now while I don't know if that class is meant to be a singleton, it's clear that all that happens inside Entry() is the creation and destruction of an instance of that class on the stack. Once the scope of that function is left, the instance will be destroyed. You should be able to verify this by adding something like a Log() invocation to the dtor.

As for the CRT initializers, yes these exist. Kindly read this other answer by me before reading on.


Okay, assuming you read my answer, the difference between DllMain as expected by the CRT when you build with the default CRT is that it already includes that CRT initialization code you likely mean. Whereas if you told the linker to use an alternative /entry you would still use the same prototype for the DLL entry function, but you'd have to deal with initialization. Literally all the information you may need is in the above linked answer to that related question and inside the files mentioned in said answer.

  • Yes, it happens the same using a singleton class, tls callbacks were behind this all time... i am gonna fix this on my mapper... edit: looks like happens through tls callbacks when there stuff statically initialized...
    – MindLerp
    Commented Jan 24, 2019 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.