Using exceptions without CRT - winapi

I want to use exceptions in my program. But my program have custom entrypoint and does not use CRT (C-runtime).
My program is simple as this:
MessageBox(NULL, L"exception will be thrown", L"ok", MB_ICONEXCLAMATION | MB_OK);
try {
throw 123;
} catch (...) {
MessageBox(NULL, L"exception thrown", L"ok", MB_ICONEXCLAMATION | MB_OK);
}
All works fine when I use standard entrypoint and CRT. But when I change EP of the program, it will crash with error 'Access violation' while calling function _CxxThrowException.
I've made a detailed screenshot of the crash: http://vs712.server4u.cz/exception.png
What is causing this error? Is there a workaround how to use exceptions without using CRT?
Thanks.

If your program is compiled by Visual C++. You SHOULD use CRT. You don't known what compiler do. Compiler can call any CRT function at anywhere in your code.
If you really don't want to use CRT. Then, use another compiler or another language like Assembly.

Related

How to solve LNK2019 unresolved external symbol DriverEntry referenced in function GsDriverEntry?

While I was compiling this project https://github.com/namazso/hdd_serial_spoofer
I got the error message above ,how can I solve this ?
I'm using vs 2017 and wdk 10 .
(Must compile in release ,debug mode is not supported .There is no DriverEntry function in this project ,the EntryPoint(void* ntoskrn, void* image, void* alloc) function in hwid.cpp is the real entry point .)
I did a lot of research but still failed to get it work .I'm a noob in kernel mode driver development .
The project uses (an apparently ignored) option
<EntryPointSymbol> to define EntryPoint as the entry.
This is documented here, but current documentation appears to mean this is really only for .exe and .dll projects.
The form of the mesage called from the Windows driver system
NTSTATUS DriverInitialize(
_DRIVER_OBJECT *DriverObject,
PUNICODE_STRING RegistryPath
)
Is incompatible with the EntryPoint in the project
EntryPoint(void* ntoskrn, void* image, void* alloc)
This is not so bad, as none of the parameters which are called for EntryPoint are used.
So the simplest implementation would be
extern "C"
{
DRIVER_INITIALIZE DriverEntry;
_Use_decl_annotations_
NTSTATUS
DriverEntry(
struct _DRIVER_OBJECT *DriverObject,
PUNICODE_STRING RegistryPath
)
{
EntryPoint(NULL, NULL, NULL);
return STATUS_SUCCESS;
}
}
Kernel development is not for the faint hearted, and running invalid kernel code on your computer could make it difficult to boot, or in extream cases damage the computer. I did not review any of the code in the project for correctness.
Please run the code in a virtual machine (vmware, virtualbox, hyper-v) to limit the damage it could do
This is not a normal driver, the kind that WDF directly supports. It is a "driverless driver", it uses an undocumented hack that is appealing to the kind of programmers that write rootkits for fun and profit. The DriverEntry() function is not actually the entrypoint for a driver, it is callback. Much like the WinMain() function is not actually the entrypoint for a native Win32 program. The EntryPoint() function in the project's source code is the replacement for the native driver entrypoint. Beware that the project appears to have rootkitty-like behavior, designed to fool a simplistic copy-protection scheme that checks a drive serial number.
The GsDriverEntry() function is the real entrypoint in a normal KMDF driver. It performs essential initialization to support the /GS compiler option, designed to detect buffer overflow. After that's done it calls DriverEntry(). The project replaces this entrypoint with EntryPoint().
This project was written with an old version of the Visual Studio project template. Several changes are necessary to get it to build properly:
C/C++ > Code Generation > Security Check. Must be "Disable security check (/GS-)", the original project file got this right.
Same property page > Control Flow Guard. Must be set to "No" to prevent a linker error. This option adds additional security checks that cannot work and must be disabled.
C/C++ > General > SDL checks. Use the dropdown arrow to override to "inherit from parent" so the option appears blank. More security checks that needs to be disabled, suppresses a warning that sdl- is incompatible with /gs-.
Same property page > Warning level. Override to "Level3 (/W3)", suppresses warnings about function arguments not being used.
Linker > Input > Additional Dependencies. Click the dropdown arrow > Edit. Untick the "Inherit from parent" checkbox and change to $(DDK_LIB_PATH)ntoskrnl.lib. Note the $(KernelBufferOverflowLib) entry in the Inherited values listbox, resolves to bufferoverflowfastfailk.lib, that is the one that contains GsDriverEntry() and produced the linker error.
Linker > Advanced > Entry Point. Must be "EntryPoint", the original project template got that right.
After this it builds clean. I did not test the resulting hwid.sys, looks a bit too evil to expose my machine to it.
Don't use .cpp source files to write your driver. Change them to .c and it should work. That was the case for me.
I know it looks trivial, or unlikely but remember Windows Kernel code is C code and Visual Studio makes various assumptions given the file extension of your source files.
There are several causes that generate the problem. In my case, a try/except in the code, which compiles on x64, but doesn't compile on x86.
Linker Tools Error LNK2019
https://learn.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-error-lnk2019?view=msvc-170

wxWidgets and Visual Studio Linker Error When Compiling with a Static Library

I'm getting this linker error when compiling wxWidgets in Visual Studio 2010.
msvcrt.lib(wcrtexew.obj) : error LNK2001: unresolved external symbol _wWinMain#16
Now here's the problem. The entry point for wxWidgets is this macro:
IMPLEMENT_APP(MyApp)
Which means I don't use wWinMain() as an entry.
I've tried disabling the entry point when I compile (/NOENTRY), but no dice. Nothing seems to work because if I define wWinMain(), then wxWidgets won't start because the entry is IMPLEMENT_APP.
I only receive this error when I compile as static. If I don't compile as static I'll have to supply the DLLs: msvcp100d.dll and msvcr100d.dll on Windows Server 2008 (and maybe more DLLs on older versions of Windows that don't have the library installed).
Now I understand I am linking again the debug library, but it shouldn't matter if I link again the release because I should receive the same error (unresolved external symbol _wWinMain#16).
Any solutions?
When you link to static libraries you have to ensure that the libraries were built with the EXACT SAME parameters as you used to build the application code.
So: go through all the compiler options for the library build and the application build and ensure that they match. Also, make sure that the application build is linking to the static libraries there were built using the configuration you have matched.
It is a pain! You have to decide wether you want to deal with this problem, or the problem of installing the correct DLLs on the target machine. Either way, you have to solve configuration management problems.
In your particular problem, I see the linker is looking for _wWinMain#16 which suggests that you have build your application code with unicode switched on, but are linking to a non unicode static library.
First compile wxWidgets' Library (wxWidgets\build\msw) all with the same settings you have in your project. So I enable "/MT", "Use MFC in a Static Library", and output the projects as "Release". Same exact settings on my wxWidgets' application I coded.
Now Comment out:
IMPLEMENT_APP(MyApp)
And use this for your entry point:
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
char *buf;
buf = new char[wcslen(lpCmdLine) + 1];
wcstombs(buf, lpCmdLine, wcslen(lpCmdLine) +1);
wxApp::SetInstance( new MyApp());
wxEntry(hInstance, prevInstance, buf, nShowCmd);
wxEntryCleanup();
}
Do you have
IMPLEMENT_APP(MyApp)
In a .cpp file? It is typically in the accompanying file to where IMPLEMENT_APP(MyApp) is located.
I am using wxWidgets as a static library and that is what I do to compile.
I had the same problem after I changed my project's character set to unicode. My project uses multi-threaded Debug DLL (/MDd). Above workaround worked for me, too, but I wanted to find out what was actually causing the problem and use IMPLEMENT_APP.
After I changed "Use of MFC" to "Use Standard Windows Libraries" I was able to successfully build the project.

"Vista-only" heap corruption in a MFC application

Ours is a MFC application, which links to a win32 DLL. When the application invokes this DLL function, the argument "buffer" becomes a "Bad Pointer", after entering the function stack. This results in an application crash.
static MyClass* Instance(string& buffer);
I changed the argument type to "char *", but it only pushes the crash to next statement in the function. How to detect this heap corruption?
Few hints
This crash is reproducible, even if I invoke this DLL function from the very start of our application (CWinApp constructor). Could this memory corruption be caused by loading of resources, manifest etc?
The crash is ocurring in Vista and Win7, but not in XP.
Both these projects were recently migrated from Visual Studio 2002 to VS2008.
Code that invokes the function
CString data = "some string";
string str = data.GetBuffer();
data.ReleaseBuffer();
MyClass *obj = MyClass::Instance(str);
There were two mistakes:
Couple of custom built C++ files were not compiled with MD switch. We had to add -MD to the custom build script to make the CRT consistant with other objects.
There were LNK2005 conflicts between LIBCMT.LIB and MSVCRT.LIB, which were otherwise ignored due to the /FORCE switch. We resolved these conflicts by removing LIBCMT.LIB in Linker->Input
Thanks all for your help.
My guess is this is wrong usage of calling conventions or a CRT mismatch (i go with calling conventions).
Try building a stub DLL with the same function signature (which does nothing) and make it work with your MFC app.
Here's an example...
HTH

Calling a function in a managed DLL from native Visual C++ code through COM

Apologies in advance for the following verbose question ; I am a COM noob.
Scenario: I need to call a managed DLL built with C# from native Visual C++ code. In my native VC++ code, I do the following after registering "SomeDLL.dll" and generating the "SomeDLL.tlb" file with RegAsm.exe.
Import the TLB file with #import "SomeDLL.tlb"
Use the class MyClass defined in the DLL with CComPtr<MyClass>.
Everything's great! It compiles, and I can run the code etc. It hits the fan when I try to run this application on a different machine (i.e. not the one I compiled it on). I copy all the required DLLs, and I register the same DLL with RegAsm.exe but it doesn't work.
It specifically fails when it tries to initialize the COM library with CoInitialize(0) and returns the S_FALSE error which means
The COM library is already initialized on this thread.
I can confidently state that I have not called this function anywhere else in my code.
Any suggestions?
Hard to help you find that code from here, you're a lot closer. Maybe a DLL that gets injected.
Getting S_FALSE is not an error, getting RPC_E_CHANGED_MODE would be quite bad. Be sure to use the FAILED macro:
HRESULT hr = CoInitialize(0);
if (FAILED(hr)) {
CallNineOneOne(hr);
exit(hr);
}
Maybe you called OleInitialize or another function which calls ComInitialize behind the scenes.
Anyway, it does not matter to call CoInitialize several times per thread if you match each of them with a call to CoUninitialize

Trying to use tcl threads on windows 7 results in access violation

I'm trying to get this simple program to work on windows, but it crashes:
unsigned (__stdcall testfoo)(ClientData x)
{
return 0;
}
int main()
{
Tcl_ThreadId testid = 0;
Tcl_CreateThread(&testid, testfoo, (ClientData) NULL, TCL_THREAD_STACK_DEFAULT, TCL_THREAD_NOFLAGS);
}
I am using a makefile generated by cmake and linking against a version of Tcl 8.5.7 I compiled myself using Visual C++ 2008 express. It was compiled using msvcrt,static,threads and the name of the resulting library is tcl85tsx.lib. The error is:
Unhandled exception at 0x77448c39 in main.exe: 0xC0000005: Access violation writing location 0x00000014.
The Tcl library works fine, and I can even run a threading script example by loading the Thread extension into it. My assumption is that there is something horribly wrong with a memory violation, but I have no idea what. Any help appreciated.
TclInitSubsystems is called when you call Tcl_FindExecutable(), which is public. If you don't have the executable name to hand, just pass NULL there.
I ended up compiling a debuggable version of Tcl. The issue is that you need to call TclInitSubsystems to initialize all the locks required for thread creation. Unfortunately, this isn't publically accessible, and an intepreter needs to be created with Tcl_CreateInterp. This was a test program for an application I was developing that has a Tcl interpreter, so it will not be an issue in production. I just need to create an interpreter for this simple test program.

Resources