aboutsummaryrefslogtreecommitdiffstats
path: root/capstone/tests/test_winkernel.cpp
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /capstone/tests/test_winkernel.cpp
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'capstone/tests/test_winkernel.cpp')
-rw-r--r--capstone/tests/test_winkernel.cpp172
1 files changed, 172 insertions, 0 deletions
diff --git a/capstone/tests/test_winkernel.cpp b/capstone/tests/test_winkernel.cpp
new file mode 100644
index 000000000..6413b1a2c
--- /dev/null
+++ b/capstone/tests/test_winkernel.cpp
@@ -0,0 +1,172 @@
+/* Capstone Disassembly Engine */
+/* By Satoshi Tanda <tanda.sat@gmail.com>, 2016 */
+
+#include <ntddk.h>
+
+#include <capstone/platform.h>
+#include <capstone/capstone.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../utils.h" // for cs_snprintf
+
+#ifdef __cplusplus
+}
+#endif
+
+EXTERN_C DRIVER_INITIALIZE DriverEntry;
+
+#pragma warning(push)
+#pragma warning(disable : 4005) // 'identifier' : macro redefinition
+#pragma warning(disable : 4007) // 'main': must be '__cdecl'
+
+// Drivers must protect floating point hardware state. See use of float.
+// Use KeSaveFloatingPointState/KeRestoreFloatingPointState around floating
+// point operations. Display Drivers should use the corresponding Eng... routines.
+#pragma warning(disable : 28110) // Suppress this, as it is false positive.
+
+// "Import" existing tests into this file. All code is encaptured into unique
+// namespace so that the same name does not conflict. Beware that those code
+// is going to be compiled as C++ source file and not C files because this file
+// is C++.
+
+namespace basic {
+#include "test_basic.c"
+} // namespace basic
+
+namespace detail {
+#include "test_detail.c"
+} // namespace detail
+
+namespace skipdata {
+#include "test_skipdata.c"
+} // namespace skipdata
+
+namespace iter {
+#include "test_iter.c"
+} // namespace iter
+
+namespace customized_mnem_ {
+#include "test_customized_mnem.c"
+} // namespace customized_mnem_
+
+namespace arm {
+#include "test_arm.c"
+} // namespace arm
+
+namespace arm64 {
+#include "test_arm64.c"
+} // namespace arm64
+
+namespace mips {
+#include "test_mips.c"
+} // namespace mips
+
+namespace m68k {
+#include "test_m68k.c"
+} // namespace m68k
+
+namespace ppc {
+#include "test_ppc.c"
+} // namespace ppc
+
+namespace sparc {
+#include "test_sparc.c"
+} // namespace sparc
+
+namespace systemz {
+#include "test_systemz.c"
+} // namespace systemz
+
+namespace x86 {
+#include "test_x86.c"
+} // namespace x86
+
+namespace xcore {
+#include "test_xcore.c"
+} // namespace xcore
+
+#pragma warning(pop)
+
+// Exercises all existing regression tests
+static void test()
+{
+ KFLOATING_SAVE float_save;
+ NTSTATUS status;
+
+ // Any of Capstone APIs cannot be called at IRQL higher than DISPATCH_LEVEL
+ // since our malloc implementation using ExAllocatePoolWithTag() is able to
+ // allocate memory only up to the DISPATCH_LEVEL level.
+ NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+ // On a 32bit driver, KeSaveFloatingPointState() is required before using any
+ // Capstone function because Capstone can access to the MMX/x87 registers and
+ // 32bit Windows requires drivers to use KeSaveFloatingPointState() before and
+ // KeRestoreFloatingPointState() after accessing them. See "Using Floating
+ // Point or MMX in a WDM Driver" on MSDN for more details.
+ status = KeSaveFloatingPointState(&float_save);
+ if (!NT_SUCCESS(status)) {
+ printf("ERROR: Failed to save floating point state!\n");
+ return;
+ }
+
+ basic::test();
+ detail::test();
+ skipdata::test();
+ iter::test();
+ customized_mnem_::test();
+ arm::test();
+ arm64::test();
+ mips::test();
+ m68k::test();
+ ppc::test();
+ sparc::test();
+ systemz::test();
+ x86::test();
+ xcore::test();
+
+ // Restores the nonvolatile floating-point context.
+ KeRestoreFloatingPointState(&float_save);
+}
+
+// Functional test for cs_winkernel_vsnprintf()
+static void cs_winkernel_vsnprintf_test()
+{
+ char buf[10];
+ bool ok = true;
+ ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "") == 0 && strcmp(buf, "") == 0);
+ ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "0") == 1 && strcmp(buf, "0") == 0);
+ ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "012345678") == 9 && strcmp(buf, "012345678") == 0);
+ ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "0123456789") == 10 && strcmp(buf, "012345678") == 0);
+ ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "01234567890") == 11 && strcmp(buf, "012345678") == 0);
+ ok = (ok && cs_snprintf(buf, sizeof(buf), "%s", "0123456789001234567890") == 22 && strcmp(buf, "012345678") == 0);
+ if (!ok) {
+ printf("ERROR: cs_winkernel_vsnprintf_test() did not produce expected results!\n");
+ }
+}
+
+// Driver entry point
+EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+ UNREFERENCED_PARAMETER(RegistryPath);
+ cs_winkernel_vsnprintf_test();
+ test();
+ return STATUS_CANCELLED;
+}
+
+// This functions mimics printf() but does not return the same value as printf()
+// would do. printf() is required to exercise regression tests.
+_Use_decl_annotations_
+int __cdecl printf(const char * format, ...)
+{
+ NTSTATUS status;
+ va_list args;
+
+ va_start(args, format);
+ status = vDbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, format, args);
+ va_end(args);
+ return NT_SUCCESS(status);
+}