Files
2024-07-07 10:34:16 +08:00

241 lines
6.6 KiB
C++

#pragma once
#include "LinkedList.h"
#include "typesdefs.h"
#pragma pack(push,1)
struct OpcodesInfo {
#ifdef _WIN64
unsigned short int mov = 0xB848;
#else
unsigned char mov = 0xB8;
#endif // _WIN64
ULONG_PTR addr; // mov rax,addr
unsigned char push = 0x50; // push rax
unsigned char ret = 0xc3; // ret
};
struct InlineOpcodesInfo {
unsigned char push = 0x68;
ULONG lowAddr; // push xxxxxxxx
#ifdef _WIN64
unsigned char op1 = 0xc7;
unsigned char op2 = 0x44;
unsigned char op3 = 0x24;
unsigned char op4 = 0x04;
ULONG highAddr; // mov dword ptr[rsp+4],xxxxxxxx
#endif
unsigned char ret = 0xc3; // ret
unsigned short int nop = 0x9090; // nop
};
#pragma pack(pop)
struct HookInfo {
ULONG_PTR Address;
OpcodesInfo Opcodes;
unsigned char Original[sizeof(OpcodesInfo)];
// SSDT and shadow SSDT extension
int Index;
LONG Old;
LONG New;
ULONG_PTR OriginalAddress;
};
struct InlineHookInfo {
ULONG_PTR Address;
InlineOpcodesInfo Opcodes;
unsigned char Original[sizeof(InlineOpcodesInfo)];
};
struct SystemServiceTable {
PULONG ServiceTableBase;
PVOID ServiceCounterTableBase;
#ifdef _WIN64
ULONGLONG NumberOfServices;
#else
ULONG NumberOfServices;
#endif // _WIN64
PVOID ParamTableBase;
};
typedef struct _RTL_PROCESS_MODULE_INFORMATION {
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES {
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES;
typedef enum _KTHREAD_STATE {
Initialized,
Ready,
Running,
Standby,
Terminated,
Waiting,
Transition,
DeferredReady,
GateWaitObsolete,
WaitingForProcessInSwap,
MaximumThreadState
} KTHREAD_STATE, * PKTHREAD_STATE;
typedef struct _SYSTEM_THREAD_INFORMATION {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitches;
KTHREAD_STATE ThreadState;
KWAIT_REASON WaitReason;
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER WorkingSetPrivateSize; // since VISTA
ULONG HardFaultCount; // since WIN7
ULONG NumberOfThreadsHighWatermark; // since WIN7
ULONGLONG CycleTime; // since WIN7
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation)
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_THREAD_INFORMATION Threads[1]; // SystemProcessInformation
// SYSTEM_EXTENDED_THREAD_INFORMATION Threads[1]; // SystemExtendedProcessinformation
// SYSTEM_EXTENDED_THREAD_INFORMATION + SYSTEM_PROCESS_INFORMATION_EXTENSION // SystemFullProcessInformation
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
struct ShadowServiceNameEntry {
UNICODE_STRING Name;
ULONG Index;
LIST_ENTRY Entry;
void Free() {
if (Name.Buffer) {
//DbgPrint("[Library]FreeType:NameBuffer Ptr:%llx\n", (ULONG_PTR)Name.Buffer);
ExFreePool(Name.Buffer);
Name.Buffer = nullptr;
}
}
};
extern "C"
NTSTATUS NTAPI ZwQuerySystemInformation(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_Inout_ PVOID SystemInformation,
_In_ ULONG SystemInformationLength,
_Out_opt_ PULONG ReturnLength
);
enum class HookType {
SSDT,
ShadowSSDT
};
class khook{
public:
//PVOID GetFunctionAddress(const char* apiName);
static PVOID GetApiAddress(PCWSTR name);
static bool GetApiAddress(ULONG index, PVOID* address);
static bool GetShadowApiAddress(ULONG index, PVOID* address);
static bool GetSystemServiceTable();
static bool GetShadowSystemServiceTable();
ULONG GetShadowServiceLimit();
bool HookSSDT(const char* apiName,void* newfunc);
bool UnhookSSDT();
bool HookShadowSSDT(PUNICODE_STRING apiName, void* newfunc);
bool UnhookShadowSSDT();
bool GetSystemServiceNumber(const char* exportName, PULONG index);
static bool GetKernelAndWin32kBase();
bool GetShadowSystemServiceNumber(PUNICODE_STRING symbolName, PULONG index);
static bool SearchSessionProcess();
static bool GetSectionStart(ULONG_PTR va);
static bool GetShadowSectionStart(ULONG_PTR va);
static PVOID FindCaveAddress(PVOID start, ULONG size, ULONG caveSize);
bool Hook(PVOID api, void* newfunc);
bool Unhook();
NTSTATUS RtlSuperCopyMemory(_In_ VOID UNALIGNED* Destination, _In_ VOID UNALIGNED* Source, _In_ ULONG Length);
PVOID GetOriginalFunction(HookType type,const char* apiName,PUNICODE_STRING symbolName);
// µØÖ·±ØÐë16×Ö½Ú¶ÔÆë
bool HookKernelApi(PVOID api,void* newfunc,bool first);
bool UnhookKernelApi(bool end);
NTSTATUS SecureExchange(PVOID opcodes);
static void DetectInlineHook(KInlineData* pInfo,KernelInlineHookData* pData);
static ULONG GetInlineHookCount(ULONG_PTR base);
private:
HookInfo* _info = nullptr;
InlineHookInfo* _inlineInfo = nullptr;
public:
static SystemServiceTable* _ntTable;
static SystemServiceTable* _win32kTable;
static PVOID _kernelImageBase;
static ULONG _kernelImageSize;
static PVOID _win32kImageBase;
static ULONG _win32kImageSize;
static PVOID _sectionStart;
static ULONG _sectionSize;
static PVOID _shadowSectionStart;
static ULONG _shadowSectionSize;
static LinkedList<ShadowServiceNameEntry> _shadowServiceNameList;
static HANDLE _pid;
bool _success = false;
};