我正在尝试在不使用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
,这显然与CRT有关。
所以我想知道如何重写入口点的默认int wmain(int argc, wchar_t* argv[])
,以及如何摆脱安全cookie。
答案 0 :(得分:4)
_wmainCRTStartup是调用wmain()
的函数IIRC它应该可以在你可以链接的某个.o文件中找到,查看你的lib目录。
也许这也很有用:Reduce EXE and DLL Size with LIBCTINY.LIB (和Matt Pietrek摇滚: - )
答案 1 :(得分:3)
好吧,在这里回答自己总结,以防其他人发现此页面正在寻找信息。
正如MSalters建议的那样,安全cookie代码可以从CRT源中窃取,但这样做我发现/GS-
编译器标志可以用来完全避免安全性。
正如SoapBox所说,API函数需要__stdcall
,以及入口点。
我用链接器命令行标志/entry:wmain
修复了入口点问题。
最后,正如Tomek指出的那样,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 :(得分:2)
更正确的入口点声明将是:
int __stdcall wmain(PVOID ThreadParam)
没有由BaseThreadInitThunk直接调用的CRT入口点。它传递指向某事物的指针,但不是argc + argv。
答案 3 :(得分:1)
您可以在Windows.h中查看kernel32导入所需的原型。通常,Windows函数定义为WINAPI
,实际上是__stdcall
而不是__cdecl
。这至少会解决这个问题。
至于你的另一个问题,你需要探索链接器命令行参数,看看是否有办法让它不从CRT中寻找东西。我不知道是否有办法做到这一点。但是你必须找到一种方法或者定义你自己的那些功能(你可能不想这样做)。
我建议只使用不同的编译器/链接器。
答案 4 :(得分:1)
您需要将windows.h函数声明为extern“C”。
答案 5 :(得分:0)
正确的入口点是main()
,而不是wmain()
(因为您正在编译控制台应用程序)。
安全cookie代码可以从CRT源代码中删除;无需将其链接。