diff options
author | 2023-10-10 14:33:42 +0000 | |
---|---|---|
committer | 2023-10-10 14:33:42 +0000 | |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /capstone/contrib/windows_kernel | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'capstone/contrib/windows_kernel')
-rw-r--r-- | capstone/contrib/windows_kernel/README | 11 | ||||
-rw-r--r-- | capstone/contrib/windows_kernel/libc.cpp | 143 | ||||
-rw-r--r-- | capstone/contrib/windows_kernel/libc.h | 40 |
3 files changed, 194 insertions, 0 deletions
diff --git a/capstone/contrib/windows_kernel/README b/capstone/contrib/windows_kernel/README new file mode 100644 index 000000000..d08039477 --- /dev/null +++ b/capstone/contrib/windows_kernel/README @@ -0,0 +1,11 @@ +For Windows kernel programming, the SDK does not offer some functions +needed by Capstone. The missing functions are: + + - Memory allocations: malloc(), calloc(), realloc() & free(). + - Format input variables & write out result to char buffer: vsnprintf() + +This directory contains some code providing above-mentioned functions, so you can +integrate Capstone with your Windows-kernel drivers using C++. + +All the code here is contributed by Peter Hlavaty <zer0mem@yahoo.com> +See the full example with Capstone integration at https://github.com/zer0mem/libc.git diff --git a/capstone/contrib/windows_kernel/libc.cpp b/capstone/contrib/windows_kernel/libc.cpp new file mode 100644 index 000000000..ac4a4eb9b --- /dev/null +++ b/capstone/contrib/windows_kernel/libc.cpp @@ -0,0 +1,143 @@ +/** + * @file libc.cpp + * @author created by: Peter Hlavaty + */ + +#include "libc.h" +#include <memory> +#include <Ntintsafe.h> + +#pragma warning(push) +#pragma warning (disable : 4565) + +#ifndef _LIBC_POOL_TAG +#define _LIBC_POOL_TAG 'colM' +#endif + +// very nice for debug forensics! +struct MEMBLOCK +{ + size_t size; +#pragma warning(push) +#pragma warning (disable : 4200) + __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) + char data[0]; +#pragma warning(pop) +}; + +EXTERN_C +__drv_when(return!=0, __drv_allocatesMem(pBlock)) +__checkReturn +__drv_maxIRQL(DISPATCH_LEVEL) +__bcount_opt(size) +void* +__cdecl malloc( + __in size_t size + ) +{ + /* A specially crafted size value can trigger the overflow. + If the sum in a value that overflows or underflows the capacity of the type, + the function returns nullptr. */ + size_t number_of_bytes = 0; + if (!NT_SUCCESS(RtlSizeTAdd(size, sizeof(MEMBLOCK), &number_of_bytes))){ + return nullptr; + } + MEMBLOCK *pBlock = static_cast<MEMBLOCK*>( + ExAllocatePoolWithTag( + NonPagedPoolNxCacheAligned, + number_of_bytes, + _LIBC_POOL_TAG)); + + if (nullptr == pBlock) + return nullptr; + + pBlock->size = size; + return pBlock->data; +} + +EXTERN_C +__drv_when(return != 0, __drv_allocatesMem(p)) +__checkReturn +__drv_maxIRQL(DISPATCH_LEVEL) +__bcount_opt(size * n) +void* +__cdecl calloc(size_t n, size_t size) +{ + size_t total = n * size; + void *p = malloc(total); + + if (!p) return NULL; + + return memset(p, 0, total); +} + +EXTERN_C +__drv_when(return!=0, __drv_allocatesMem(inblock)) +__checkReturn +__drv_maxIRQL(DISPATCH_LEVEL) +__bcount_opt(size) +void* +__cdecl realloc( + __in_opt void* ptr, + __in size_t size + ) +{ + if (!ptr) + return malloc(size); + + std::unique_ptr<unsigned char> inblock = std::unique_ptr<unsigned char>(static_cast<unsigned char*>(ptr)); + + // alloc new block + void* mem = malloc(size); + if (!mem) + return nullptr; + + // copy from old one, not overflow .. + memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data)->size, size)); + return mem; +} + +EXTERN_C +__drv_maxIRQL(DISPATCH_LEVEL) +void +__cdecl free( + __inout_opt __drv_freesMem(Mem) void* ptr + ) +{ + if (ptr) + ExFreePoolWithTag(CONTAINING_RECORD(ptr, MEMBLOCK, data), _LIBC_POOL_TAG); +} + +#pragma warning(pop) + +__drv_when(return!=0, __drv_allocatesMem(ptr)) +__checkReturn +__drv_maxIRQL(DISPATCH_LEVEL) +__bcount_opt(size) +void* +__cdecl operator new( + __in size_t size + ) +{ + return malloc(size); +} + +__drv_maxIRQL(DISPATCH_LEVEL) +void +__cdecl operator delete( + __inout void* ptr + ) +{ + free(ptr); +} + +int +__cdecl vsnprintf( + char *buffer, + size_t count, + const char *format, + va_list argptr +) +{ + return vsprintf_s(buffer, count, format, argptr); +} diff --git a/capstone/contrib/windows_kernel/libc.h b/capstone/contrib/windows_kernel/libc.h new file mode 100644 index 000000000..9498bac94 --- /dev/null +++ b/capstone/contrib/windows_kernel/libc.h @@ -0,0 +1,40 @@ +/** + * @file libc.h + * @author created by: Peter Hlavaty + */ + +#pragma once + +#include <ntifs.h> + +EXTERN_C +__drv_when(return!=0, __drv_allocatesMem(pBlock)) +__checkReturn +__drv_maxIRQL(DISPATCH_LEVEL) +__bcount_opt(size) +void* __cdecl malloc(__in size_t size); + + +EXTERN_C +__drv_when(return != 0, __drv_allocatesMem(p)) +__checkReturn +__drv_maxIRQL(DISPATCH_LEVEL) +__bcount_opt(size * n) +void* __cdecl calloc(size_t n, size_t size); + + +EXTERN_C +__drv_when(return!=0, __drv_allocatesMem(inblock)) +__checkReturn +__drv_maxIRQL(DISPATCH_LEVEL) +__bcount_opt(size) +void* __cdecl realloc(__in_opt void* ptr, __in size_t size); + + +EXTERN_C +__drv_maxIRQL(DISPATCH_LEVEL) +void __cdecl free(__inout_opt __drv_freesMem(Mem) void* ptr); + + +int __cdecl vsnprintf(char *buffer, size_t count, + const char *format, va_list argptr); |