How to manually initialise the c runtime in an exe? - c++

I'm trying to provide my own entry point to a visual c++ executable using the linker switch "/entry". The associated Microsoft documentation goes into some detail about how to manually initialise the c runtime in a dll, but I can't grasp how to initialise it in my exe. The best I've got is that I need to call _CRT_init, but I don't know if that's a function or a macro, or where it might be defined, and Visual Studio (and msbuild) don't recognise the identifier, so no hints there.
The rationale here is that I'm attempting to unit test, with Google Test, an executable, and it won't link because main() clashes. The two approaches mentioned in the GTest FAQ aren't really generalisable and would require considerable rework to about 30 legacy executables to implement. Renaming each unit test application's main() seems like a super-easy approach, if only I could initialise the c runtime.

So I searched through the C Runtime source this afternoon, and the answer is "no". You cannot provide your own executable entry point not named main if you want to use the C Runtime. Quite aside from _CRT_INIT() being the an initialisation function for a dll (mainCRTStartup() is one of the initialisation functions for executables), mainCRTStartup() and its like call main() by name.

You could initialize the CRT in a standalone wrapper module which has
main; obj1
Rename the main of all existing exe modules to xx_main; obj2, obj3.... objn
Link obj1 (main) with (obj2, obj3.... objn).
To test a foo.cc file, you need to compile and link it into your unit
test program
What's the issue with this scheme ?

Though not specifically documented, it is possible to initialize the CRT in an executable in the same way it can be done in a DLL.
EXTERN_C BOOL WINAPI _CRT_INIT( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved );
// ThreadProc for CreateRemoteThread, a possible use case.
DWORD WINAPI ArbitraryAlternateEntryPoint( LPVOID )
{
_CRT_INIT( GetModuleHandle( NULL ), DLL_PROCESS_ATTACH, NULL );
// CRT functions can be used here.
_CRT_INIT( GetModuleHandle( NULL ), DLL_PROCESS_DETACH, NULL );
return 0;
}
The documentation suggests that _CRT_INIT should be called for each new thread in addition to the initial call, but in practice this is not necessary.

Related

How force unload library in C++ (Dev C++ compiler)?

I saw a Delphi (Object Pascal) code that force unloads any module (dll) that is loaded inside my software. Then with base in this code, I'm wanting and needing of something similar now in C++ (Dev C++).
Someone can help me please?
Here is Delphi code that I saw:
procedure ForceRemove(const ModuleName: string);
var
hMod: HMODULE;
begin
hMod := GetModuleHandle(PChar(ModuleName));
if hMod=0 then
exit;
repeat
until not FreeLibrary(hMod);
end;
The functions
HMODULE GetModuleHandle(LPCTSTR modulename)
BOOL FreeLibrary(HMODULE)
are functions of the Windows API. It can be called from any language that supports programming against the Windows API, as C++
Only recommendation: Remove the loop (the repeat until not ...) in your sample above. It should be replaced by code that interprets the return value of the call to FreeLibrary, documentation here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms683152(v=vs.85).aspx
The DLL will be unloaded from memory (that is to say, the address space of the executing process), as soon as its per-process reference count goes zero; you cannot force unloading a DLL globally by repeatedly executing FreeLibrary() if another process still holds a reference.
EDIT: included a direct translation of OP's sample into a C++ snippet:
void ForceRemove(LPCTSTR ModuleName)
{
HMODULE hMod;
hMod = ::GetModuleHandle(ModuleName);
if(hMod==0)
return;
/* DISCLAIMER potentially infinite loop
* not advisable in production code,
* included by request of the OP to
* match his original */
while(::FreeLibrary(hMod));
}

CRT Initialization: runtime error - CRT not initialized

today I have been trying to get standard functions to work in my application such as sprintf, ect.
When ever using functions like sprintf, fgets or anything else standard my application crashes with runtime error - CRT not initialized
Current linker options:
/ignore:4098 /dll /entry:"_DllMainCRTStartup" /include:"XboxKrnlBuildNumber" /ALIGN:128,4096
Entry point:
BOOL APIENTRY DllMain(HANDLE hInstDLL, DWORD reason, LPVOID lpReserved)
Tried to init it my self by defining _CRT_INIT is an extern that takes no arguments and calling it in my DLL_PROCESS_ATTACH with no luck.
I've been stuck on this issue for months but just thought i'd come back to it and look a little deeper.
If you are doing something non-trivial in your DllMain function, this may be of help:
http://blog.barthe.ph/2009/07/30/no-stdlib-in-dllmai/
http://blogs.msdn.com/b/larryosterman/archive/2006/06/15/632502.aspx

C++ LoadLibrary ERROR_NOACCESS "Invalid access to memory location."

OK, so I have a situation in which I call LoadLibrary on a DLL that I wrote. This call to LoadLibrary returns error #998, or ERROR_NOACCESS "Invalid access to memory location."
The DLL in question uses MFC in one configuration, and not in another; only the MFC configuration has this problem. It used to work, but I have no idea what I changed: I'd actually moved on to the non-MFC version and been tinkering quite a lot with that and I have no idea what I could have done that affected the MFC version.
I don't know a lot about DLLs. The original loading code was actually given to me, and I haven't changed it. Below is that code:
// submodule loading
#ifndef MFC
// Project uses standard windows libraries, define an entry point for the DLL to handle loading/unloading
BOOL WINAPI DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
{
_MESSAGE("DllMain called.");
switch(dwReason)
{
case DLL_PROCESS_ATTACH: // dll loaded
hModule = (HMODULE)hDllHandle; // store module handle
_MESSAGE("Attaching Submodule ...");
break;
case DLL_PROCESS_DETACH: // dll unloaded
_MESSAGE("Detaching Submodule ...");
break;
}
return true;
}
#else
// Project uses MFC, we define here an instance of CWinApp to make this a 'well-formed' DLL
class CSubmoduleApp : public CWinApp
{
public:
virtual BOOL InitInstance()
{// dll loaded
hModule = m_hInstance; // store module handle
_MESSAGE("Attaching Submodule ...");
return true;
}
virtual int ExitInstance()
{// dll unloaded
_MESSAGE("Detaching Submodule ...");
return CWinApp::ExitInstance();
}
} gApp;
#endif
Obviously, MFC is defined in the MFC configuration, and not otherwise.
I doubt this is enough information to solve this problem; I realize that. What I'm actually hoping to learn is where to look for problems that might cause this error. I'll be happy to supply any information you need — once I know it's needed.
Thanks for any tips.
OK, this question was answered by a friend of mine (no idea if he has a StackOverflow account; not going to pester him with answering it twice).
The deal is that I had a global object, the class of which had a constructor that called a function that depended upon another global object (ironically enough, the function in question was _MESSAGE, but by the time DllMain or InitInstance gets called, that function works fine). C++ doesn't allow you to specify the order in which globals get initialized, so when this global's constructor got run (when the computer attempted to load the DLL), it caused a memory error by attempting to use another global that hadn't been created yet.
So... that's the answer. A really specific case, but I guess if anyone else finds they're getting 998 errors and need to know what sorts of problems to check, this is something to look for: make sure all your globals are independent!

How does GetModuleHandle work in Visual c++

I am new to c++ and this code always returns NULL even though i know the file exists:
HMODULE hModule = GetModuleHandle(TEXT("C:\\Users\\Steve\\Desktop\\stub.exe"));
Interestingly, if i copy stub.exe to C:\Windows\system32, it finds the module with this code:
HMODULE hModule = GetModuleHandle(TEXT("stub.exe"));
Am i missing something incredibly basic?
You can only call GetModuleHandle(L"C:\\Users\\Steve\\Desktop\\stub.exe"); when you're running C:\Users\Steve\Desktop\stub.exe.
But in general, you don't call GetModuleHandle for your EXE name. Since there's only one EXE per process, you just call GetModuleHandle(0).
Firstly, GetModuleHandle requires that you load the dll into the process before hand.
Windows has specific paths that it uses to search for modules, as well as some switches to force 'safe' dll loading, you may want to look into SetDllDirectory and AddDllDirectory if you wish to expand the locations searched. See this for an explanation of how Windows search for binaries.
Here is a quote from MSDN:
GetModuleHandle Function
Retrieves a module handle for the specified module. The module must have been loaded by the calling process.
This means that you have to load the module with LoadLibrary first. System32 might get special treatment, but you really should not be copying anything there. The folder is strictly for the operating system's usage.

Access Violation calling imported function

I've got a function imported from a DLL. I control the source of both the host executable and the dynamic library. Now, in DLLMain then I used MessageBox to pop up the address of the function I'm exporting, and compared it using a breakpoint to the function pointer returned by GetProcAddress, and they're identical.
However, when I try to call the function, I get an access violation. The function in question just returns NULL and has no logic, so it can't be thrown by the function specifically.
How can calling a known valid function pointer, with the correct signature, and verified safe logic, yield an access violation?
Edit: Information gained through another separate question about why the debugger is dying in this situation suggests that my stack is being smashed too? That would make more sense than an AV, but the function pointer and the function are completely compatible and the address is correct.
extern "C" Render* __cdecl CreateRender(WindowsOS* ptr) {
return nullptr;
}
typedef Render*(__cdecl *RendererCreateFunction)(WindowsOS*);
I used a simple, small piece of code in DLLMain to qualify that they are in fact compatible as far as the compiler is concerned.
BOOL WINAPI DllMain(
__in HINSTANCE hinstDLL,
__in DWORD fdwReason,
__in LPVOID lpvReserved
) {
RendererCreateFunction func = &CreateRender;
}
If they aren't compatible (they include the same header) then the compiler should throw an error and refuse to build the DLL, but it accepts this just fine.
If this is DLLMain you use in your code then it has no return statement and most likely returns a not initialized value, quite probably 0 as a good main function, which effectively unloads the DLL from the memory. Make sure DLLMain returns TRUE.
I completely failed this one. Wrote a class that manages a resource without respecting my move and copy semantics properly. Turns out that I was calling FreeLibrary() on the library in question mistakenly before I needed to use it.