WinMain is a function that 'replaces' the default main entry point 'main'.
The user can then define its main entry point like
int WINAPI WinMain(...) { }
How is this kind of encapsulation done?
Well, most likely, at some point it looks like this:
int main() // This must be defined somewhere in windows.h
{
return WinMain(...);
}
Question: How can I accomplish such an encapsulation of my own, which then calls WinMain? Note: The library which I made is a DLL, so it will look like this:
// This is the minimal code for the application which uses 'MyLibrary'
#pragma comment(lib, "MyLibrary.lib")
include "MyLibrary.h"
void Main(MyCustomParameter *params)
{
// Write user code here
}
The problem however is, that the DLL doesn't 'know' the Main() function and therefore throws an 'unresolved external symbol' compile error. So how can I encapsulate it like this?
You have to decide on a signature of your custom main function and declare it as "extern" (extern "C" in case of C++). Then, application code will have to define that function and link against your static library that has the actual _main entry point. For example:
extern "C" int my_main(int argc, char *argv[]);
int main(int argc, char *argv[])
{
return my_main(argc, argv);
}
Actually, the real entry point is neither main nor WinMain. The real entry point is one of wWinMainCRTStartup, WinMainCRTStartup, wmainCRTStartup, and mainCRTStartup. But they're not defined in Windows.h, they're part of the CRT. You can see their code in <VS installation folder>\VC\crt\src\crtexe.c. They each do some initialization and then call one of wWinMain, WinMain, wmain, and main, respectively.
As mentioned by someone else you can override the entry point with the /ENTRY switch, but you still can't have custom parameters, which is the whole reason you want to do this in the first place.
The linker default entry point name is "main".
You can override the default to start with any function you want.
/ENTRY (Entry-Point Symbol)
Related
I have read a lot about how to change the WinMain entry point procedure, some say you can change the entry point from the linker and some others say you can put the WinMain into DLL (dllMain) and so on.
Honestly, I am confused. I believe that there are one or more ways to change the entry point procedure to a custom procedure because there are some examples like MFC don't have a direct WinMain function and the Qt framework also has a custom entry point procedure it's similar to the console application main function int main(int argc, char *argv[]), so, there are ways as I expected.
I want a whatever way to replace/change the entry point procedure for GUI application on Windows from the traditional procedural WinMain to int main(int argc, char *argv[]) like Qt or even any other custom function but it must be compatible with (MS, GCC, Clang) compilers.
///////////Windows main/////////////
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdParam, int cmdShow){
}
///////////Console main and Qt framework////////////
int main(int argc, char *argv[]) {
}
//////////MFC////////////
class CMyFrame : public CFrameWnd {
public:
CMyFrame() {}
};
class CExample : public CWinApp {
BOOL InitInstance() {}
};
CExample theApp;
How do I do that?
entry point of exe can by any function with signature
ULONG CALLBACK ep(void* )
possible and use ULONG CALLBACK ep() - despite on x86 will be wrong stack pointer (esp) after return, this not lead to error, because windows just call ExitThread after entry return, if it return control at all - usually it call ExitProcess instead return.
the name of this entry point of course not play any role at all - it can be any valid c/c++ name. entry point found/called not by name but by AddressOfEntryPoint offset from IMAGE_OPTIONAL_HEADER
but when we build PE - we need tell linker name of this function, for it can set AddressOfEntryPoint, but this info (name of function) used only during build process (not used in runtime)
different linkers of course have different options for do this, link.exe have option /ENTRY. this option is optional and by default, the starting address is a function name from the C run-time library.
if /ENTRY:MyEntry explicitly stated - it used as is - MyEntry will be used as entry point. if no /ENTRY option set - used default:
if /SUBSYSTEM:CONSOLE set - used mainCRTStartup or if it not found wmainCRTStartup
if /SUBSYSTEM:WINDOWS set - used WinMainCRTStartup or if it not found wWinMainCRTStartup
but in most case c/c++ developers use CRT libraries. regardless of whether static or dynamic linking used with CRT - some lib code always statically linked with your exe and this code containing function which you used as entry point. for ms windows crt - this is mainCRTStartup or wmainCRTStartup (for console apps), WinMainCRTStartup or wWinMainCRTStartup for gui apps.
in all this 4 functions - called hardcoded function by name
mainCRTStartup call main
wmainCRTStartup call wmain
WinMainCRTStartup call WinMain
wWinMainCRTStartup call wWinMain
of course called function must be implemented somewhere in your code or in another lib code. for example if you use MFC - it implement wWinMain by self and called your code in another way ( via calling virtual functions on object which you override - InitApplication and InitInstance)
if back to question how change name of your custom entry point - but for what ? you really not need change name. you need only understand how your entry point is called. if you understand this - you can do almost all.
assume we want use main as "entry point". i take this in quotes because we really want have real entry point in CRT code and we want that CRT code call exactly main function.
possible ? simply !
set /ENTRY: mainCRTStartup linker option. so mainCRTStartup will be real entry point and it call main.
another question, i personally think that this is senseless trick, which nothing change and nothing give
also possible simply call main from WinMain
typedef struct
{
int newmode;
} _startupinfo;
/*
* new mode flag -- when set, makes malloc() behave like new()
*/
EXTERN_C _CRTIMP int __cdecl _query_new_mode( );
EXTERN_C _CRTIMP int __cdecl _set_new_mode( _In_ int _NewMode);
EXTERN_C
_CRTIMP int __cdecl __getmainargs(__out int * _Argc,
__deref_out_ecount(*_Argc) char *** _Argv,
__deref_out_opt char *** _Env,
__in int _DoWildCard,
__in _startupinfo * _StartInfo);
int __cdecl main(__in int _Argc, __in_ecount_z(_Argc) char ** _Argv, ...);
int CALLBACK WinMain( _In_ HINSTANCE , _In_opt_ HINSTANCE , _In_ LPSTR , _In_ int )
{
int _Argc, r;
char ** _Argv;
char ** _Env;
_startupinfo _StartInfo { _query_new_mode( ) };
if (!(r = __getmainargs(&_Argc, &_Argv, &_Env, 0, &_StartInfo)))
{
r = main(_Argc, _Argv, _Env);
if (_Argv) free(_Argv);
}
return r;
}
it must be compatible with (MS, GCC, Clang) compilers
How you do that depends on your compiler. Most of them will have some flags to choose which "subsystem" (the Windows term) you are targeting and even customize the entry point manually.
Put another way, there is no standard way of doing so because this is outside the scope of the C++ standard.
Having said that, some compilers provide the means to emulate the flags of other compilers. For instance, Clang can imitate Microsoft's.
I want to write a very, very small program that parses the launch arguments and chooses one of several DLLs to "boot into."
I've already written an application that I'd like to "run" as a DLL by writing it as an application, then changing the Visual Studio project properties to build it as a DLL instead. I know I need to use LoadLibrary and GetProcAddress in concert to get the functionality I want, but I'm having trouble finding clear and comprehensive documentation on this, as a lot of the use cases aren't really of this nature. Also, I have to go this route based on the project and platform restrictions.
I found this page, which has some information, but it's not clear enough for me to adapt for my purposes.
Edit: Here's where I'm at right now.
I have a DLL project whose main function signature looks something like this:
__declspec(dllexport) int cdecl main(int argc, char *argv[])
I also have an application project whose attempt at loading the DLL and running the above function looks like this:
typedef int (CALLBACK* LPFNDLLFUNC1)(int, char *);
...
HMODULE dllHandle = NULL;
BOOL freeResult, runTimeLinkSuccess = FALSE;
LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
if (args->IsEmpty())
{
dllHandle = LoadLibrary(L"TrueApplication.dll");
if (NULL != dllHandle)
{
lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(dllHandle, "main");
if (lpfnDllFunc1)
{
int retVal = lpfnDllFunc1(0, "1");
}
Currently, the LoadLibrary call works, but not GetProcAddress.
First of all, changing project type from executable to DLL is not enough to make a DLL. You also need to export some symbols to create your API. At least, you need to decorate the functions you are exporting with __declspec(dllexport). However, I recommend that you export C API, meaning extern "C" functions with C-compatible arguments. So, the functions you export should be prepended with extern "C" __declspec(dllexport).
Once you have done that, you can dynamically load your DLL like this:
const char* dllname = "myfile.dll";
h = LoadLibrary(dllname);
if( h == nullptr )
{
/*handle error*/
}
using myfunc_type = bool (*)(int x, double y); //example
auto myfunc = reinterpret_cast<myfunc_type>(GetProcAddress(h, "myfunc"));
//......
myfunc(x,y); //call the imported function
This solution takes more work than static loading with /delayload shown by Jerry Coffin, but it has an advantage: if a DLL is required but not found, you can give users your own error message instead of relying on the message coming from Windows (which is often unacceptable for non-tech people). You can also include API version verification with its own custom error message in the API.
Edit: the code sample will work if you change it like this
extern "C" __declspec(dllexport) int main(int argc, char *argv[]){...}
typedef int (* LPFNDLLFUNC1)(int, char **);
You do not need GetProcAddress (...) to do this, though that approach (Option #2) is simpler once you understand how the compiler generates symbol names.
Option #1
DllMain Spawns a Main Thread
Never do anything complicated inside of DllMain, you may deadlock your software.
DLLs have their own entry-point (and exit-point and thread attach-point ... it's a really busy function). Just calling LoadLibrary (...) on your DLL causes at minimum one call to DllMain (...) for process attach.
BOOL
APIENTRY
DllMain ( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
You can actually treat ul_reason_for_call == DLL_PROCESS_ATTACH as a mandate to execute DllMain as if it were your program's main function.
Now, by no means should you actually start a program loop here... anytime DllMain runs it holds a very important operating system lock (DLL Loader) and you need to release that by returning for normal program operation.
That means if you want to use DllMain as your program's entry-point, it needs to spawn a thread and your original main method must not return until that thread finishes...
Option #2
DLL Exports a main Function.
Be very mindful of calling convention, the compiler will rename the symbols for you and make locating functions in a DLL with GetProcAddress less than intuitive.
In your DLL, export main:
__declspec (dllexport)
int
__cdecl main (int argc, char *argv [])
{
printf ("foobar");
return 0;
}
In your program, import main from the DLL:
// Need a typedef for the function you are going to get from the DLL
typedef int (__cdecl *main_pfn)(int argc, char *argv[]);
int main (int argc, char *argv[])
{
HMODULE hModMyDLL = LoadLibraryA ("MyDll.dll");
if (hModMyDLL != 0) {
//
// The preceding underscore deals with automatic decorations
// the compiler added to the __cdecl function name.
//
// It is possible to do away with this completely if you use a .def
// file to assign export names and ordinals manually, but then you
// lose the ability to tell a function's calling convention by its
// name alone.
//
main_pfn MyMain = (main_pfn)
GetProcAddress (hModMyDLL, "_main");
// Call the main function in your DLL and return when it does
if (MyMain != nullptr)
return MyMain (argc, argv);
}
return -1;
}
Both approaches have their merits.
Spawning a thread from DllMain avoids knowing anything at all about how the DLL you want to load is is implemented, but it also requires you to design your main function never to return -- the DLL will call ExitProcess (...).
Exporting functions and later importing them by name allows you to avoid pussyfooting around the Windows DLL loaderlock. However, if you do not use a .def file to explicitly name the exported symbols, the compiler is going to add decorations such as _... (__cdecl) or ...#n (__stdcall) to the names and you have to learn these conventions to do anything useful with GetProcAddress.
You don't have to use LoadLibrary and GetProcAddress to invoke the functionality in the DLL.
More often, you'd create your DLLs, each with its own entry point. For the moment, let's assume you want to parse the command line, choose a DLL, and invoke its entry point without arguments. You end up with something like this:
void DLL_a();
void DLL_b();
void DLL_c();
int main(int argc, char **argv) {
// we'll assume DLL_a is the default:
if (argc < 2)
DLL_a();
// For now, we'll do a *really* trivial version of parsing the command line
// to choose the right DLL:
if (argv[1][0] == 'A')
DLL_a();
else if (argv[1]][0] == 'B')
DLL_b();
else if (argv[1][0] == 'C')
DLL_c();
else {
std::cerr << "Unrecognized argument\n";
return 1;
}
}
When you link your main, you'll specify the .lib corresponding to each DLL, and you'll probably want to specify the /delayload flag to the linker. This means a DLL won't be loaded until a function in the DLL is actually invoked. If, for example, you want to distribute a reduced-functionality version of your program that only includes DLL A, it'll still be able run (without DLL B or C present on the user's system) as long as no function from DLL B or C is ever called. If you don't specify /delayload, the loader will attempt to map all the DLLs to RAM as the program starts up, run their DllMain to initialize them for use, do the same recursively for all the DLLs they depend on, etc.
/delayload has one other advantage: it avoids mapping the other DLLs to addresses at all if they're never used. It sounds like any given invocation will only use one DLL, so that's probably a win in your case.
I get this error in a C++ file where I am writing some tests:
error: no member named 'Session' in namespace 'Catch'
testResult = Catch::Session().run(test_argc, test_argv);
~~~~~~~^
Looking at the catch.hpp single header file, I noticed that the code that should implement the Session() member function is greyed out, probably because of an #ifdef somewhere, which I cannot find.
Is there any macro to set to use the Session class?
Catch versions: 1.5.3 and 1.5.6.
Reference: https://github.com/philsquared/Catch/blob/master/docs/own-main.md
You're attempting to call the constructor of Catch::Session from a file where you're not defining your own main to execute. According to the documentation on defining your own main, there is supposed to be only one instance of Catch::Session:
Catch::Session session; // There must be exactly once instance
It's likely Catch is preventing construction of Catch::Session in translation units where it can't be used in a custom main definition (since that's where it's supposed to be used), to prevent exactly the mistake you've made from compiling.
Reference to https://github.com/catchorg/Catch2/blob/master/docs/own-main.md
You can only provide main in the same file you defined CATCH_CONFIG_RUNNER.
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
int main( int argc, char* argv[] ) {
// global setup...
int result = Catch::Session().run( argc, argv );
// global clean-up...
return result;
}
I've project where I need to distinguish files belongs to linux daemon (witten in C) and simple linux program (written in C++). Those two projects used 2 shared files (helpers_functions). Daemon and program has different logging system. Daemon write to file, program to stdout.
Problem occurs when I want to log something in common functions for both programs (inside helper_functions file). I don't want to pass via parameter, that this is program A, or program B.
I've compile files belongs to separate programs with g++ flag -D, but what can I do, when I want to log from common files? I cannot define there anything, because I don't know when I use it for program A, or when for program B.
You could add a global variable
const int iamprogram = ...;
which is defined to be PROGRAM_A in program A and PROGRAM_B in program B to solve the immediate problem. You could also make this variable directly contain the file you want to log to:
const char *program_logfile = "/path/to/logfileA";
In the long run, I suggest you to refactor your code such that the common code doesn't depend on which program it is part of. That's much more maintainable and expandable for the case where you want to use the code for a third program as well.
I'm not 100% sure if runtime dynamic linking can handle this. It would definitely work if you statically link the helper functions into each executable.
Provide a logging function with the same API in both programs. Have the library functions that want to log something call this function. They get the implementation provided by the program that's using the library.
Header file included by each program, and by the library
// common_log.h
#ifdef __cplusplus
extern "C" // for the following definition only, no opening {
#endif
// used by code that can be part of either program
void common_log(char *msg, int log_prio);
Implementation in the tty C++ program (simple logging):
#include "common_log.h"
#include <iostream>
// used by the rest of the C++ program
void simple_logger(char *msg) {
cerr << msg;
}
extern "C" void common_log(char *msg, int log_prio) {
simple_logger(msg);
}
Implementation in the daemon C program:
#include "common_log.h"
#include <stdio.h>
#include <errno.h>
static FILE *logfp;
static int log_level;
// used by daemon code
void fancy_logger(char *msg, int log_prio) {
if (log_prio < log_level)
return;
if (EOF == fputs(logfp, msg)) {
perror("failed to write log message to log file: ");
}
}
// or use linker tricks to make common_log an alias for fancy_log,
// if they both have the same signature and you don't need to do anything in the wrapper.
//extern "C" // this is already C
void common_log(char *msg, int log_prio) {
fancy_logger(msg, log_prio);
}
This requires the linker to be able to resolve undefined symbols in the library using symbols from the program that's linked against it. I think that works, similar to a library providing a weak definition of a global variable, so the main program's definition takes precedence.
If it was ok for simple_logger to also be extern "C" and have the same signature, you could just name them the same and avoid the bounce function. Or if the common function could be an alias for the program's own logging function in either of the programs, I think there are linker tricks to actually do that, instead of compiling to a single jmp instruction (tail-call optimization).
You could implement a callback for getting the program specific output. There's two benefits: no dependency from common part to application (common part defines the interface) and you can make the distinction at run time vs compile time, which gives more legroom for future development, such as changing the output via command line parameters or user interaction.
In the following example, let's refer to the common code part as "library".
library.h
typedef void (*logFunc_t)( logBuffer_t );
void setLogOutput( logFunc_t applicationLog );
library.c
logFunc_t logger; // might be good idea to initialize to an empty function, but omitted here
void setLogOutput( logFunc_t applicationLog )
{
logger = applicationLog;
}
void log( logBuffer_t data )
{
logger( data );
}
application.cpp / application.c
// here you should have the extern "C" in C++ application to ensure linkage compatibility
// I am assuming your shared code is C
extern "C" void myLogger( logBuffer_t data );
int main( int argc, char* agv[] )
{
setLogOutput( &myLogger );
// ...do your thing
return 0;
}
void myLogger( logBuffer_t data )
{
// ...log wherever
}
I want to monitor an external program using dll injection
I managed to follow this tutorial and it work
http://www.codeproject.com/Articles/4118/API-Monitoring-Unleashed
Now i want to be able to monitor any function in the external program without knowing
it signature
I want to be able to copy the parameters sent to the original function and pass them to wrapper function and than back to the original
How it can be done?
I rather not use assembly language because i am not used to it.
Here is some code to demonstrate what i am trying to do:
#include "stdafx.h"
void (*pointerToOriginalFunctionForOverride)(...);
void (*copyPointerOfOriginalFucntion)(...);
//let say we dont know the signature of this function
void _cdecl originalFunction(char *s)
{
printf("%s",s);
}
void functionWrapper(void *first)
{
printf("Some debug info\n");
//HERE IS MY PROBLEM
copyPointerOfOriginalFucntion(?????????????);
}
int _tmain(int argc, _TCHAR* argv[])
{
pointerToOriginalFunctionForOverride = (void (*)(...))(&functionWrapper);
copyPointerOfOriginalFucntion = (void (*)(...))(&originalFunction);
//let say this line runs from an external program that we injected a dll into
pointerToOriginalFunctionForOverride("some text in external program");
}
This is impossible at the C++ level (also your code is disgusting C, not really C++). Your example code won't even work for functionWrapper as all variadic arguments must be passed on the stack, but the ABI calls for regular arguments (the first few) to be passed in a register.
You will have to go down to assembly.
thanks to to the answer here
http://www.rohitab.com/discuss/topic/39969-hook-function-without-knowing-signature/
I guess, you almost there with your code... you just need to make your trampoline function not >damaging the stack... firstly the function should be declared naked (without default prologue, in >studio I believe it would be something like __declspec(naked) or something)... secondly you need to >think about do you need to do something after the call to original function... if not, I think it is >better just to simply make a jmp instead of call (using inline assembler or something)...
Here is my code. used vs2012 on windows 7 64bit but 32bit compile. simple win32 console app . hope it helps anyone else
#include "stdafx.h"
void originalFunction(int x,int y,int z)
{
printf("running originalFunction with x=%d\n",x);
}
__declspec(naked) void trampolineFunction()
{
__asm jmp [originalFunction]
}
int _tmain(int argc, _TCHAR* argv[])
{
((void (*)(...))trampolineFunction)(7,8,9);
getchar();
return 0;
}