zydis: Errors while using Zydis.lib in windows driver
Quick fixes for:
stdint.hnot found -> just add a copy from visual studiounresolved external symbol __imp_wassert: redefineZYDIS_ASSERTandZYDIS_UNREACHABLEto;unresolved external symbol __imp___stdio_common_vsprintf: usewinkernel_mm.*from capstone- missing
DriverEntry/ALIGNerrors -> see this issue unresolved external symbol __imp___stdio_common_vsprintf: add/D _NO_CRT_STDIO_INLINEtocloptions in Zydis project
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 20 (17 by maintainers)
Oh yeah, I’d be happy to contribute user/kernel mode Visual Studio project files if there is interest in it (meaning proper ones, not the garbage CMake generates). I know that the feelings w.r.t. doing this are mixed among CMake users, after all CMake can technically make Visual Studio project files so it is duplicating part of the build system. But non-VS users will never know the pain of having to hand-edit 15 XML files to ‘un-CMake’ them.
ZYDIS_WINKERNELcan be inferred from_KERNEL_MODE, which MSVC sets for kernel mode projects (passing/kernelto cl.exe is enough for this, you don’t need a full-blown WDK project).Some other things I came across that may be of use (I am working on a Windows driver using Zydis at the moment, which is how I found this):
ZYDIS_ASSERTis defined to be empty ifZYDIS_WINKERNELis defined, but this can be replaced withNT_ASSERT(condition), orNT_ASSERT_NOASSUMEfor asserts that should always execute. This does come at the cost of including <wdm.h>, but you’re going to have a hard time compiling a driver without including wdm.h anyway.ZYDIS_UNREACHABLE:__assume(0)compiles in MSVC in both user and kernel mode. But maybe there’s another reason for leaving this macro empty that I’m missing.ZYDIS_WINKERNELwithoutZYDIS_MSVCis a faulty build configuration. However it has been possible to compile drivers with Clang/LLVM for quite some time 😃 (both Clang/C2 and the ‘proper’ LLVM toolchain.) It’s not something I would recommend for production drivers, but Clang’s static analysis is unparalleled so I make very frequent use of it. Unfortunately the clang-cl frontend does not recognise MSVC’s/kernelswitch, so you have to manually define_KERNEL_MODE. Naturally, doing this in an MSVC project results in a fatal error for defining a reserved macro. Sigh…/kernelto the compiler flags for a static library. But, if you try to link a driver against a static library that was not compiled with/kernel, the linker will flat out refuse the .lib as it cannot guarantee that it will work correctly in kernel mode. So that part does matter.Re:
DriverEntry: it is correct that the standard WDK build configuration hijacks the driver entry point to beGsDriverEntryin order to initialize stack cookie support. Counterintuitively it is not enough to disable stack cookies to actually get rid of the forced implant in your driver when you link against KernelBufferOverflowK.lib. So the solution is to (1) disable /GS cookie support, (2) remove KernelBufferOverflowK.lib from the linker inputs and (3) explicitly set the driver entry point to the standardDriverEntryin the linker options under ‘advanced’. This will reduce your driver file size by a few KB free of charge, as well as make it easier to step through in a debugger. Prefast and Clang are much better ways to prevent stack overflows since they add no runtime overhead and they also don’t have the BSOD/kernel panic + reboot cycle overhead that stack cookies do.