zydis: Errors while using Zydis.lib in windows driver
Quick fixes for:
stdint.h
not found -> just add a copy from visual studiounresolved external symbol __imp_wassert
: redefineZYDIS_ASSERT
andZYDIS_UNREACHABLE
to;
unresolved external symbol __imp___stdio_common_vsprintf
: usewinkernel_mm.*
from capstone- missing
DriverEntry
/ALIGN
errors -> see this issue unresolved external symbol __imp___stdio_common_vsprintf
: add/D _NO_CRT_STDIO_INLINE
tocl
options 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_WINKERNEL
can be inferred from_KERNEL_MODE
, which MSVC sets for kernel mode projects (passing/kernel
to 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_ASSERT
is defined to be empty ifZYDIS_WINKERNEL
is defined, but this can be replaced withNT_ASSERT(condition)
, orNT_ASSERT_NOASSUME
for 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_WINKERNEL
withoutZYDIS_MSVC
is 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/kernel
switch, 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…/kernel
to 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 beGsDriverEntry
in 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 standardDriverEntry
in 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.