Создание консольных приложений без CRT и заголовков по умолчанию? - PullRequest
7 голосов
/ 20 ноября 2008

Я пытаюсь создать консольное приложение без использования CRT или любого другого импорта, кроме kernel32.lib в любом случае. Я получаю свой код для компиляции, но не могу обернуть компоновщик несколькими проблемами:

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 и GetProcAddress, которые я ввел в программу явно, не используя 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 );

Полагаю, что-то не так с моими прототипами. Тем не менее, большая проблема - __security_check_cookie и _wmainCRTStartup, которые, очевидно, имеют отношение к ЭЛТ. Поэтому мне интересно, как бы я переопределил стандартную int wmain(int argc, wchar_t* argv[]) для точки входа и как избавиться от любого файла cookie безопасности.

Ответы [ 6 ]

4 голосов
/ 20 ноября 2008

_wmainCRTStartup - это функция, которая вызывает wmain ()

IIRC он должен быть доступен в каком-то файле .o, с которым вы можете связать, посмотрите в вашем каталоге lib.

Может быть, это тоже полезно для чтения: Уменьшите размер EXE и DLL с помощью LIBCTINY.LIB (и Мэтт Питрек качает: -)

3 голосов
/ 20 ноября 2008

Ну, отвечая себе здесь, чтобы подвести итог, на случай, если кто-то найдет эту страницу в поисках информации.

Как советовал MSalters, код cookie безопасности может быть украден из источника CRT, но, сделав это, я обнаружил, что флаг компилятора /GS- можно использовать, чтобы вообще избежать мер безопасности.

Как сказал SoapBox, функции API должны быть __stdcall, как и точка входа. Я исправил проблему точки входа с флагом командной строки компоновщика /entry:wmain.

И, наконец, как указал Томек, функции API должны быть во внешнем C!

Итак:

#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;
}
2 голосов
/ 27 февраля 2011

Более правильное объявление точки входа будет:

int __stdcall wmain(PVOID ThreadParam)

Без точки входа CRT, вызываемой напрямую BaseThreadInitThunk. Он передает указатель на что-то, но не на argc + argv.

1 голос
/ 20 ноября 2008

Вам необходимо объявить функции windows.h как внешние "C".

1 голос
/ 20 ноября 2008

Вы можете заглянуть в Windows.h, чтобы увидеть прототипы, необходимые для импорта в ядро32. В общем, функции окон определены WINAPI, что на самом деле __stdcall, а не __cdecl. Это решит эту проблему, по крайней мере.

Что касается вашей другой проблемы, вам нужно изучить аргументы командной строки компоновщика и посмотреть, есть ли способ заставить его не искать вещи из CRT. Я не знаю, есть ли способ сделать это или нет. Но вам придется найти способ или определить эти функции самостоятельно (что, вероятно, вам не нужно).

Я бы порекомендовал просто использовать другой компилятор / компоновщик.

0 голосов
/ 20 ноября 2008

Правильная точка входа - main(), а не wmain() (поскольку вы компилируете консольное приложение). Код cookie безопасности можно получить из исходного кода CRT; нет необходимости связывать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...