Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building console apps without CRT & default headers?

I'm trying to build a console application without using the CRT, or any other imports than kernel32.lib in any case. I get my code to compile, but can't wrap the linker around a few problems:

unresolved external symbol @__security_check_cookie@4
unresolved external symbol "int __cdecl FreeLibrary(void *)" (?FreeLibrary@@YAHPAX@Z)
unresolved external symbol "void * __cdecl LoadLibraryW(wchar_t *)" (?LoadLibraryW@@YAPAXPA_W@Z)
unresolved external symbol "int (__cdecl*__cdecl GetProcAddress(void *,char *))(void)" (?GetProcAddress@@YAP6AHXZPAXPAD@Z)
unresolved external symbol _wmainCRTStartup

FreeLibrary, LoadLibraryW and GetProcAddress I've brought in to program explicitly, not using windows.h:

#pragma comment(lib, "kernel32.lib")

typedef int(*FARPROC)();

void* LoadLibraryW( wchar_t* lpLibFileName );
FARPROC GetProcAddress( void* hModule, char* lpProcName );
int FreeLibrary( void* hLibModule );

I suppose something is wrong with my prototypes. However, the bigger problem are __security_check_cookie and _wmainCRTStartup, which obviously have something to do with the CRT. So I'm wondering how I'd go about overriding the default int wmain(int argc, wchar_t* argv[]) for entrypoint, and how to get rid of whatever the security cookie is.

like image 956
anon6439 Avatar asked Nov 20 '08 11:11

anon6439


People also ask

How to build a net core application without IDE or Visual Studio?

We will see how we can build .NET Core based applications without using any IDE or Visual Studio. We will be using Command Line to create, build, and run the application. If we don’t need all the fancy features that Visual Studio and Visual Studio Code offer, then we can build a .NET Core application with just a Notepad.

How do I create a console app in Visual Studio Code?

On the Create a new project window, enter or type console in the search box. Next, choose C# from the Language list, and then choose Windows from the Platform list. After you apply the language and platform filters, choose the Console App (.NET Core) template, and then choose Next.

How to deploy and run NET Core Application without installed runtime?

Deploy and run .NET Core application without installed runtime. Self-contained applications. .NET Core framework provides one very useful feature - Self-contained application. You don't need to install any .net runtime on your computer, you can just copy your application to the target host and run it.

What platforms can I run a self-contained application on?

Furthermore, you can run it on any platform (Windows, Linux, OSX)! When you create a self-contained application, after publishing, you will see the whole .net runtime next to your application. You do not need to have installed .NET Core on a target machine


2 Answers

_wmainCRTStartup is the function that calls wmain()

IIRC it should be available in some .o file that you can link with, look in your lib directory.

Maybe this is useful reading too: Reduce EXE and DLL Size with LIBCTINY.LIB (and Matt Pietrek rocks :-)

like image 173
activout.se Avatar answered Sep 21 '22 13:09

activout.se


Well, answering myself here to sum up, in case someone else finds this page looking for info.

As MSalters advised, the security cookie code can be stolen from the CRT source, but doing that I found that the /GS- compiler flag can be used to avoid the security stuff altogether.

As SoapBox said, the API functions need to be __stdcall, as well as the entry point does. I fixed the entry point issue with linker command line flag /entry:wmain.

And finally, as Tomek pointed out, the API functions gotta be in extern C!

So:

#pragma comment(lib, "kernel32.lib")

typedef int(*FARPROC)();

extern "C" {
  void* __stdcall LoadLibraryW( wchar_t* lpLibFileName );
  FARPROC __stdcall GetProcAddress( void* hModule, char* lpProcName );
  int __stdcall FreeLibrary( void* hLibModule );
  typedef int (__stdcall *f_MessageBoxW_t)( unsigned long hWnd, wchar_t* lpText, wchar_t* lpCaption, unsigned long uType);
  f_MessageBoxW_t fnMsg;
  void* hUser;
};

int __stdcall wmain(int argc, wchar_t* argv[])
{
  hUser = LoadLibraryW( L"user32.dll" );
  fnMsg = (f_MessageBoxW_t)GetProcAddress( hUser, "MessageBoxW" );
  fnMsg( 0, L"foo", L"bar", 0 );
  FreeLibrary( hUser );
  return 0;
}
like image 38
anon6439 Avatar answered Sep 18 '22 13:09

anon6439