^aCkZsZ)P<(HCGPzeCj
z65#EFgwq?72ct@-DshS0X_<7MBM1C!M_I&DJaK7Ez7w^O_pJDkKTArGuoS?Ku#(4t
zL`#?nZlT)tVYGgi3T;YU#`Ga3Dw3K0PX>Pd05DCcyFq&TI*BpdrGUZtf8fl2j@?4K
zbmNa}u`T)kUPSV^_r9xXti3BBq3v&PoMv!9O$oJ{>p?ulRl9BuV3fs>t+_#<3AfRR*U-V
zU7&?wv__pO`LZ>lNxC+p^74KD8nk>sS)sJ45_cc)w}hUt3!+YF`wMbOZyv^130|+Z*a?>luO!hlTC^fmPi|ur4see_l^8
zYC1reJlPq=)z;T7NlsT@?k)F}m#-hy5)L=6a=Yy9XG(PbXt1jz)YQ?}<@W`9R`f<{
zy$y?)e>mV0fEOBBzcz~5rcGEsl%h{V=-VLrvs5`9QcV@~rc;ovURftHoQGSY!~Mt<
zL^pIGOB4RtC4Q&|nRx}eBZ4K7A6+&TKR-Gvigf*I-bRF&Pb?z*v2J9!e%&OCDt6@W
z#_yz?ei<3IY1(C1OxWw${^l;Vee{!AW$2~qil7guxCSbPL{^Rh94L}&mof7@FWC6l
z>K*5JUf%G=-JNZIR3?C51W386Xhu3kxz4m@GSR;>=)}{xT*lv*iTG-qGini*
z*$n+$#-E=4C*!Zj^LDDUXSH&^))oDd&l)%Wn2G;6%kDq|4*)*h3g{n5A$b~{NwMpFa6_#qn?;h
z_16jRH$T1SZ${4)S=nP>5{ZOO7(Fe&4PbBcG0OZ2QPxa|
zb5bu((U25bI@te9$jVLvSjC^negg7y3l^du}bU;W$L+7m~KGBT~dL@M+DeAhpj@LO5`>8Xo(P2+d;?SHVZ|7tMCB9Jy{Wr@O%TOZ=>
zl`eE#4)cE~3OrpabP4csVYL8boK&X)yo8jeSDh95nPyxI%>S(E59h0tf9gQtYB7sk
z`1gX-*`V)sz^{w#|8W+4{|`xzq<_}%r{DiG4&@yJuu6ZBG=^W$cdirz=m|+_xEren
zac$_0^nGwT+W#1ocT^Vm|BSS<{RO?72MMG$#tQ_+P3BA-nL;-1M1JY2K>tq0#Ss9j
z&;LiH{aB;_$>UEd0%W`q&6T+6lmCo|FKLkeo>}-!+(>->7L56o;Id6B7ZNKmJKBS5
zu`Y0i7K}%s%b*%U?{eY4Z=is~wL&t{Up+3P@Rx!9XS@Cxr2ldK-|JH^{c!FFLvJ(`
z*v<7{v9-x6A->CL!$kupX(s(yEI(2wuRlqAx*-zv;!X=hvM|aNexs(kvBXjGlvRmXlhp;JRAJzk9>W_MIzEQ~vkS
zZ|>yIj+Cb`(m%%AkA$QY;CraVH^YJ7T31bFb!Dxu+~)R`du*;UPnFG6=P0+;`J8pG
zvO1U3?W|nCZeCY+UvFcJ$+GaE(f=mvPfMXyr6kgajtZk;$#u+huT%q5Qt=}_HDz4a
zUJnpMN~|BO=%7tn%M?k@f>E
ze`ftNtrg~u`akX`Vk)cnxqkkkR%B-UEZy8m{ih^3<|*TMu14@$?J_g|s(40&ki^ea
zR-d1^@6gJ+dOz!5X#b+=g(UrnQy!VvbmNO>o;Ex@dh`GN{UugWwyX518`aByca~&3
z+ZwRnyAN|b45mU0Q1a}vWByX-LG70d^%9mAT3r}2PaiMU4w}H#6y-Qd&$HG(_ry<^
zHf@{m%&!l*aLxT689i67^4}GC_TMF1{%jd|t_(2F$a(I9z5ewJ#%{f6sPFU9{VVr2
zjD6*3qt-FEP4?%;zvKMVn*5Oq-{ym4bOSCw$!7ofTZ@GmOD|8L0{jPfG^R{4*9{bjuWtQAzb4OE(IUa6BXo=UL4CGZI2REe=ZT)ses
z3EV=Mi8?^lDW@gtc$Z?IKqiOvZ^@}hG!bC+`8`OxK`Yn`K12@KqspB@XaSOIp(Ql&
zsQ=;;-~@nG{QCAUg8hvOJgOAM_5-=n*|O!KiEW_?+aCA7a@XxUUs3lzN~SLT)?V&L
zX~|%+N?4l=(*G>i&q?(EU|;|D7G8dk+qca3{kZl%|H$qSk6ZnVjXR#bcf|FEf^Pc#
zM=|-O5qqTk>OQF|ce;I2-Tszns6QBO40UmLmtR}{o0)|Z=2(3HmkANdBid;HS2o4T
z{a@MS(Wm`rk8{@%7d%owd->j%ubwteZVT5Z`AUa#x1X;BkEShD*iO08qFuT6hxbpp
z`K795SAF>Q$QPrRs#|v?ahHCg{eMH2>leL!l)L%nqZV9a`N6BXQz3Pq0&T0@e#gCV
z@tv-eEV>cLTL1o&@9uWAKlQ-#V{X~Fr?zbsJ6zUQ`o_BlLy9K9TUGYtT78jEzgV96
z*>>B@ZF_b<<**&%`oUV-AW|yLxD0M7+HQ%;u*2$Zt5wi=u}AySHktN*v1rOaT(Ze_
z%79M2-H(51|4O#$s%7iY^(y@%}53*65%1
zFXENXC{1$Q?-9|iMJD5?y_@Zx>D-+xllq@yaY1_y>mcLP`8#n_+Mm7x_MfcVUoZb2
zjP`$?*ScIAAer@#w62*usejC7{B!@WRsE-x^B-KL(FSdG{NIAKQvZu!-cCNdRs4A)
zOe!EB{DbrV;6DFxF!KL*Fnpb6G?bGK|9=bVCI8Pv|DCL4
z8b|wIw)E!$ly{p}W+wdUPydSjH>aVjsQ|0(Pdn|s8h(!dRz+$$v$1@N0*=S?ACDln
zQ(DEZmp?K+fBMsh;`zDvLH2>DRr>$Sa9i@fO!&!L(>dAyBaq1I^WTHC4{L>H!e5;Z
zIqp&aDWBac{`-(m_J1b)d@oo!NBQS4Bp3^@ihm2z@;xYYnenF|0aE^ADy#S(LRtb{
zCj2gu%=DlAKN)wY0IcHwC#2>3VCXX8Pk;JdjDO-i17%so`Z{{nK0ja~psEoCW^$
zyC1~!pN{g#1FSy(W~AK&piAaIgXg~vyz^gj?~B#`e*yhIQtkctdy2@D2s}qiT2AvA
z(~z$n3LuT6j4>KOS%>s)9DsT!?!Be`k1`d{!BHPXo-`3~41l^B>L`u_@SFnq#$yonzbvumiY;WqnEaC?il#A*~|4kk3Ni#W2r@
z&jg$am<2csFdHxj!231uy;`^yejQ*g;B3G=z&U{VfCYehz`1~hfJK0B02Tup080Sp
z0hR*J2P^|L0{#K896($b!vCfgz6gF3pcxPVv;cyDRzMq|9S{OA-wOC)KqsIJ5CL=p
zz6FQ^dH}tEKEO%<^Q?lu8n6bi7O)Pm9&j<>+ki^|ndmRuFr6FZ|3gYRHaY&$~H(qvhCz9xx2~O
z&6jwBiB_SdklJ~Qhr9RE&mZ!xt3iFUduv4Up20$$K^44p6}S=WBUh!x+EkyssZCgA
z!bQL?PSs1pxDT96*bBwJ;r=3Ej2Xzm9TN{2$PFoqQi8s}EX%&n)qt1I{wSoZ)*`e*
z@=gT%+|*vFAeSzEmLxUz6qdNZlWtA8pW^
ze1#OweQJfK4svE1Z&?wmf#T1U9!R|0H_h{IesymFPlR#@U?1dLTI$932L^sj@O?o7
zKi5aapjYX8fcw$KTC1Z7y`M}a#LJ1q`tGXzJpSeTCB*9Uy8Tw0l~{=-?{*O@WH}nG
z($ZWxNa_|4u`=g+)deYs|4xikC(gpG$2xa0<`H+Ti1QWew0Cv?d<
z7qdNobyw=|?VMIkoeHB$I@-F&>+c~h(aC-k&tylBkv9zCAn17E<4xy0*FWbj|K&IT
z`RSi$gMZ5B_s#cyXVX0?_;>a0z0>>HtK%P-q}=}E*nQ8*x+PXhT*=o5MwJm8yRHoW
z?cAFXuRaz0^l!+aF6A(hdZ;qVTxx@sDfK)hh=QJODhgND67N+dh3Av0RS^5l5|69e
z!65?b`%J{Q4Ok3nux@{_%K*ddLT1NC_c4jW~HliJ?38J^^a|NaLsltW3fytcZH7l(~)TCf_(d3)MrdrJ@Vy)s9mUW;BV*9Ha}N558;ISRwI?J4qs
z^%kJrps;nxrza@66-G|8))V6C3yIZOQp+??#fT_oJ*3@OesJdYZBTmDa(w5FXoc@
zx{NdENi2XU!;MhxlJ766uBff`R=GVkuhWJ1mpCfjHcv%`*H%?gT~k|KQ&;1wsawA;
z;W$(5wbWkiwbUu^iB3NMl$brx-MwzzTA!n~%v0fY+iIK@)izhHtISqi<967bPIpDM
zd@1#916s|-ws54mDQwT8f?H$-ExiXudyRH-^T^|2VSi^+sEg=lT5j6Zyy)KqH&IdF
znW&4ST8%@-cYut7@hRhHhUNAtWL8}hszK4R*TkYHKEsUx+(hTQU5<-{`9-Z(+#)gz
z2?yT(b1^7KE*fns@1W4@2aI3BF7~W!039n<9gMUFM)n5oAt=6XpfT?kb$$&(q<61#|^YitQeHh3ZJ5!
z{N=L8T~b8OZNxQGcdQ(RHW{=ECQ`=Ojw%cGCvscr#=rVjxq-8AW@G=6_CLKXC%x4t
zewTTQX8*&ONOZ>bqh=&3l>KfqYGQY?}q}6@UeptvB$fqX?
zXF==8jUk&auDQ9GNAM&Aj&Bx!YxT*$I%(%$9=`9y5g&dubK)irEqUyLW`{$|6y-;N
z{`v8Erb+9H|Ng1WyIR-3_Wqsj<0EUn_gd}9%~y=(@vPW`$p?`%b
z&IOUC7GF4QZ?|e%Ib5Hq!m>U+|6Iw9n`)m}2I-TlDT?b5xrO6Nlfn;w^QmFSNf*AY
zbhLURQ`REcPpv%Hc04obGcXP1w!1TRCxx}0Era&^#NANl^D@_d$&D-IZ^>0ZCLv!%
z$xrrLob>z-8D;Qc%1@+ys=V4+UGDW&+B}{*ug&Fj)!3?>)fF~RrK8O4aaY1CTfdIf
zB^dP!&x-vwFm-CuJ215(!fHv`m{@cB)CO87W*W_{!m;cztE|OVUcXf~t|gduV*7pOr?sNF5j{gd)%E$=#jGvPWu3d
zToK;?oKAofN2_d~wGY34&xR$({pGbM-~VX7lbQ?T{=fKL
z$I{ytx7r`Q{@S-c?H=)C&SSaAmpHxNS`Y`!?vbwh~8CNPl8lxqNv->Z<
zRF=9&FFUrKA`a%6-MEzx7bla{o5yNly_O;2t^FxgGA=WV{eMzy&2@h*D-ctN=xUQs
zoT@aksQ-~DxqKc8>!9eCgWi+}Gt_1pIRx?uz-?<3fcmu<`N)P5Lh
z+*a(XjDH_dUUSdJK=+k#jYKTp2+Bz_u%jojMzl2r&}RJFWDs?cj_;2!{{|&@?9#>C
zIJ@sZa{lw_b7O;6cHpvh+$G0xklO!}{)klKpWo)=+yAYMNRmofM!I(LtM8FW9g+X-
zg#t=-x%Iz_oP1kW;&4*F#Xjweb&Hw;E1KGZ(@K{HqdlQW*DSZ)X?NHi(@MR4;oiPz
za8_5auQ%Eho>sc3uQ?nF%nzZdcG*F^mWvFKJla(;Mux
zdn4g6KI4KCd+c+AUBPH5U|$gG>Ak3I`SSWuAR6h3So@gL;P>AS?(e^)e&}afY2gR&
zg%?t?8POQR*zFnK*b`b49NCDk5pha@f_btUvI$k@tl*6M29^+uqLH>}Q)g*iC>-o5
zJ$+S`dy2olp{6esZt=%4c)Pp({Vu!1zqG8}kr=Ngwf8nf+k(A3H=&F;v#T#0K1*@7
z_x5(rm_EHH&>rk;>almmrdS}-IlU#=9}GvjgVE`oJ
+
+
+
+ Win7 Debug
+ Win32
+
+
+ Win7 Release
+ Win32
+
+
+ Win7 Debug
+ x64
+
+
+ Win7 Release
+ x64
+
+
+
+ {95EEC86A-C34A-4076-A55C-859BE9BFBDBF}
+ {1bc93793-694f-48fe-9372-81e2b05556fd}
+ v4.5
+ 11.0
+ Win8.1 Debug
+ Win32
+ TitanHide
+ driver_inject
+
+
+
+ Windows7
+ true
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+ Windows7
+ false
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+ Windows7
+ true
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+ Windows7
+ false
+ WindowsKernelModeDriver8.1
+ Driver
+ WDM
+
+
+
+
+
+
+
+
+
+ DbgengKernelDebugger
+ Temp\$(ProjectName)\$(Platform)\$(ConfigurationName)\
+ $(SolutionDir)\Bin\
+
+
+ DbgengKernelDebugger
+ Temp\$(ProjectName)\$(Platform)\$(ConfigurationName)\
+ $(SolutionDir)\Bin\
+
+
+ DbgengKernelDebugger
+ $(SolutionDir)\Bin\
+ Temp\$(ProjectName)\$(Platform)\$(ConfigurationName)\
+ $(TargetName.Replace(' ',''))_x64_d
+
+
+ DbgengKernelDebugger
+ $(TargetName.Replace(' ',''))_x64
+ Temp\$(ProjectName)\$(Platform)\$(ConfigurationName)\
+ $(SolutionDir)\Bin\
+
+
+
+ false
+ trace.h
+ true
+ false
+ _DEBUG;_X86_=1;i386=1;STD_CALL;%(PreprocessorDefinitions)
+
+
+ 5.01
+
+ false
+
+
+
+
+ false
+ trace.h
+ true
+ false
+
+
+ 5.01
+
+ false
+ false
+
+
+
+
+ false
+ trace.h
+ true
+ false
+ _DEBUG;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions)
+
+
+ 5.01
+
+ false
+
+
+
+
+ false
+ trace.h
+ true
+ false
+
+
+ 5.01
+
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/driver_inject.vcxproj.filters b/driver_inject.vcxproj.filters
new file mode 100644
index 0000000..9953489
--- /dev/null
+++ b/driver_inject.vcxproj.filters
@@ -0,0 +1,72 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/hooklib.cpp b/hooklib.cpp
new file mode 100644
index 0000000..a2e39aa
--- /dev/null
+++ b/hooklib.cpp
@@ -0,0 +1,56 @@
+#include "hooklib.h"
+
+
+static HOOK hook_internal(ULONG_PTR addr, void* newfunc)
+{
+ //allocate structure
+ HOOK hook = (HOOK)RtlAllocateMemory(true, sizeof(HOOKSTRUCT));
+ //set hooking address
+ hook->addr = addr;
+ //set hooking opcode
+#ifdef _WIN64
+ hook->hook.mov = 0xB848;
+#else
+ hook->hook.mov = 0xB8;
+#endif
+ hook->hook.addr = (ULONG_PTR)newfunc;
+ hook->hook.push = 0x50;
+ hook->hook.ret = 0xc3;
+ //set original data
+ RtlCopyMemory(&hook->orig, (const void*)addr, sizeof(HOOKOPCODES));
+ if(!NT_SUCCESS(RtlSuperCopyMemory((void*)addr, &hook->hook, sizeof(HOOKOPCODES))))
+ {
+ RtlFreeMemory(hook);
+ return 0;
+ }
+ return hook;
+}
+
+HOOK Hooklib::Hook(PVOID api, void* newfunc)
+{
+ ULONG_PTR addr = (ULONG_PTR)api;
+ if(!addr)
+ return 0;
+ DbgPrint("[DeugMessage] hook(0x%p, 0x%p)\r\n", addr, newfunc);
+ return hook_internal(addr, newfunc);
+}
+
+bool Hooklib::Hook(HOOK hook)
+{
+ if(!hook)
+ return false;
+ return (NT_SUCCESS(RtlSuperCopyMemory((void*)hook->addr, &hook->hook, sizeof(HOOKOPCODES))));
+}
+
+bool Hooklib::Unhook(HOOK hook, bool free)
+{
+ if(!hook || !hook->addr)
+ return false;
+ if(NT_SUCCESS(RtlSuperCopyMemory((void*)hook->addr, hook->orig, sizeof(HOOKOPCODES))))
+ {
+ if(free)
+ RtlFreeMemory(hook);
+ return true;
+ }
+ return false;
+}
diff --git a/hooklib.h b/hooklib.h
new file mode 100644
index 0000000..7180563
--- /dev/null
+++ b/hooklib.h
@@ -0,0 +1,40 @@
+#ifndef _HOOKLIB_H_
+#define _HOOKLIB_H_
+
+#include "_global.h"
+
+#pragma pack(push,1)
+struct HOOKOPCODES
+{
+#ifdef _WIN64
+ unsigned short int mov;
+#else
+ unsigned char mov;
+#endif
+ ULONG_PTR addr;
+ unsigned char push;
+ unsigned char ret;
+};
+#pragma pack(pop)
+
+typedef struct HOOKSTRUCT
+{
+ ULONG_PTR addr;
+ HOOKOPCODES hook;
+ unsigned char orig[sizeof(HOOKOPCODES)];
+ //SSDT extension
+ int SSDTindex;
+ LONG SSDTold;
+ LONG SSDTnew;
+ ULONG_PTR SSDTaddress;
+}* HOOK;
+
+class Hooklib
+{
+public:
+ static HOOK Hook(PVOID api, void* newfunc);
+ static bool Hook(HOOK hook);
+ static bool Unhook(HOOK hook, bool free = false);
+};
+
+#endif //_HOOKLIB_H_
diff --git a/misc.cpp b/misc.cpp
new file mode 100644
index 0000000..21b1772
--- /dev/null
+++ b/misc.cpp
@@ -0,0 +1,29 @@
+#include "misc.h"
+#include "undocumented.h"
+
+ULONG Misc::GetProcessIDFromProcessHandle(HANDLE ProcessHandle)
+{
+ PROCESS_BASIC_INFORMATION PBI;
+ if(NT_SUCCESS(Undocumented::ZwQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &PBI, sizeof(PBI), NULL)))
+ return (ULONG)PBI.UniqueProcessId;
+ else
+ return 0;
+}
+
+ULONG Misc::GetProcessIDFromThreadHandle(HANDLE ThreadHandle)
+{
+ typedef struct _THREAD_BASIC_INFORMATION
+ {
+ NTSTATUS ExitStatus;
+ PVOID TebBaseAddress;
+ CLIENT_ID ClientId;
+ KAFFINITY AffinityMask;
+ KPRIORITY Priority;
+ KPRIORITY BasePriority;
+ } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
+ THREAD_BASIC_INFORMATION TBI;
+ if(NT_SUCCESS(Undocumented::ZwQueryInformationThread(ThreadHandle, ThreadBasicInformation, &TBI, sizeof(TBI), NULL)))
+ return (ULONG)TBI.ClientId.UniqueProcess;
+ else
+ return 0;
+}
diff --git a/misc.h b/misc.h
new file mode 100644
index 0000000..4f1b56f
--- /dev/null
+++ b/misc.h
@@ -0,0 +1,13 @@
+#ifndef _MISC_H
+#define _MISC_H
+
+#include "_global.h"
+
+class Misc
+{
+public:
+ static ULONG GetProcessIDFromProcessHandle(HANDLE ProcessHandle);
+ static ULONG GetProcessIDFromThreadHandle(HANDLE ThreadHandle);
+};
+
+#endif
\ No newline at end of file
diff --git a/ntdll.cpp b/ntdll.cpp
new file mode 100644
index 0000000..601850f
--- /dev/null
+++ b/ntdll.cpp
@@ -0,0 +1,100 @@
+#include "ntdll.h"
+
+#include "pe.h"
+
+unsigned char* NTDLL::FileData = 0;
+ULONG NTDLL::FileSize = 0;
+
+NTSTATUS NTDLL::Initialize()
+{
+ UNICODE_STRING FileName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ RtlInitUnicodeString(&FileName, L"\\SystemRoot\\system32\\ntdll.dll");
+ InitializeObjectAttributes(&ObjectAttributes, &FileName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL, NULL);
+
+ if(KeGetCurrentIrql() != PASSIVE_LEVEL)
+ {
+#ifdef _DEBUG
+ DbgPrint("[DeugMessage] KeGetCurrentIrql != PASSIVE_LEVEL!\n");
+#endif
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ HANDLE FileHandle;
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS NtStatus = ZwCreateFile(&FileHandle,
+ GENERIC_READ,
+ &ObjectAttributes,
+ &IoStatusBlock, NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ,
+ FILE_OPEN,
+ FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL, 0);
+ if(NT_SUCCESS(NtStatus))
+ {
+ FILE_STANDARD_INFORMATION StandardInformation = { 0 };
+ NtStatus = ZwQueryInformationFile(FileHandle, &IoStatusBlock, &StandardInformation, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);
+ if(NT_SUCCESS(NtStatus))
+ {
+ FileSize = StandardInformation.EndOfFile.LowPart;
+ DbgPrint("[DeugMessage] FileSize of ntdll.dll is %08X!\r\n", StandardInformation.EndOfFile.LowPart);
+ FileData = (unsigned char*)RtlAllocateMemory(true, FileSize);
+
+ LARGE_INTEGER ByteOffset;
+ ByteOffset.LowPart = ByteOffset.HighPart = 0;
+ NtStatus = ZwReadFile(FileHandle,
+ NULL, NULL, NULL,
+ &IoStatusBlock,
+ FileData,
+ FileSize,
+ &ByteOffset, NULL);
+
+ if(!NT_SUCCESS(NtStatus))
+ {
+ RtlFreeMemory(FileData);
+ DbgPrint("[DeugMessage] ZwReadFile failed with status %08X...\r\n", NtStatus);
+ }
+ }
+ else
+ DbgPrint("[DeugMessage] ZwQueryInformationFile failed with status %08X...\r\n", NtStatus);
+ ZwClose(FileHandle);
+ }
+ else
+ DbgPrint("[DeugMessage] ZwCreateFile failed with status %08X...\r\n", NtStatus);
+ return NtStatus;
+}
+
+void NTDLL::Deinitialize()
+{
+ RtlFreeMemory(FileData);
+}
+
+int NTDLL::GetExportSsdtIndex(const char* ExportName)
+{
+ ULONG_PTR ExportOffset = PE::GetExportOffset(FileData, FileSize, ExportName);
+ if(ExportOffset == PE_ERROR_VALUE)
+ return -1;
+
+ int SsdtOffset = -1;
+ unsigned char* ExportData = FileData + ExportOffset;
+ for(int i = 0; i < 32 && ExportOffset + i < FileSize; i++)
+ {
+ if(ExportData[i] == 0xC2 || ExportData[i] == 0xC3) //RET
+ break;
+ if(ExportData[i] == 0xB8) //mov eax,X
+ {
+ SsdtOffset = *(int*)(ExportData + i + 1);
+ break;
+ }
+ }
+
+ if(SsdtOffset == -1)
+ {
+ DbgPrint("[DeugMessage] SSDT Offset for %s not found...\r\n", ExportName);
+ }
+
+ return SsdtOffset;
+}
\ No newline at end of file
diff --git a/ntdll.h b/ntdll.h
new file mode 100644
index 0000000..cbe337c
--- /dev/null
+++ b/ntdll.h
@@ -0,0 +1,18 @@
+#ifndef _NTDLL_H
+#define _NTDLL_H
+
+#include "_global.h"
+
+class NTDLL
+{
+public:
+ static NTSTATUS Initialize();
+ static void Deinitialize();
+ static int GetExportSsdtIndex(const char* ExportName);
+
+private:
+ static unsigned char* FileData;
+ static ULONG FileSize;
+};
+
+#endif //_NTDLL_H
\ No newline at end of file
diff --git a/pe.cpp b/pe.cpp
new file mode 100644
index 0000000..58f3c27
--- /dev/null
+++ b/pe.cpp
@@ -0,0 +1,135 @@
+#include "pe.h"
+
+
+static ULONG RvaToSection(IMAGE_NT_HEADERS* pNtHdr, ULONG dwRVA)
+{
+ USHORT wSections;
+ PIMAGE_SECTION_HEADER pSectionHdr;
+ pSectionHdr = IMAGE_FIRST_SECTION(pNtHdr);
+ wSections = pNtHdr->FileHeader.NumberOfSections;
+ for(int i = 0; i < wSections; i++)
+ {
+ if(pSectionHdr[i].VirtualAddress <= dwRVA)
+ if((pSectionHdr[i].VirtualAddress + pSectionHdr[i].Misc.VirtualSize) > dwRVA)
+ {
+ return i;
+ }
+ }
+ return (ULONG) - 1;
+}
+
+static ULONG RvaToOffset(PIMAGE_NT_HEADERS pnth, ULONG Rva, ULONG FileSize)
+{
+ PIMAGE_SECTION_HEADER psh = IMAGE_FIRST_SECTION(pnth);
+ USHORT NumberOfSections = pnth->FileHeader.NumberOfSections;
+ for(int i = 0; i < NumberOfSections; i++)
+ {
+ if(psh->VirtualAddress <= Rva)
+ {
+ if((psh->VirtualAddress + psh->Misc.VirtualSize) > Rva)
+ {
+ Rva -= psh->VirtualAddress;
+ Rva += psh->PointerToRawData;
+ return Rva < FileSize ? Rva : PE_ERROR_VALUE;
+ }
+ }
+ psh++;
+ }
+ return PE_ERROR_VALUE;
+}
+
+ULONG PE::GetExportOffset(const unsigned char* FileData, ULONG FileSize, const char* ExportName)
+{
+ //Verify DOS Header
+ PIMAGE_DOS_HEADER pdh = (PIMAGE_DOS_HEADER)FileData;
+ if(pdh->e_magic != IMAGE_DOS_SIGNATURE)
+ {
+ DbgPrint("[DeugMessage] Invalid IMAGE_DOS_SIGNATURE!\r\n");
+ return PE_ERROR_VALUE;
+ }
+
+ //Verify PE Header
+ PIMAGE_NT_HEADERS pnth = (PIMAGE_NT_HEADERS)(FileData + pdh->e_lfanew);
+ if(pnth->Signature != IMAGE_NT_SIGNATURE)
+ {
+ DbgPrint("[DeugMessage] Invalid IMAGE_NT_SIGNATURE!\r\n");
+ return PE_ERROR_VALUE;
+ }
+
+ //Verify Export Directory
+ PIMAGE_DATA_DIRECTORY pdd = NULL;
+ if(pnth->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+ pdd = ((PIMAGE_NT_HEADERS64)pnth)->OptionalHeader.DataDirectory;
+ else
+ pdd = ((PIMAGE_NT_HEADERS32)pnth)->OptionalHeader.DataDirectory;
+ ULONG ExportDirRva = pdd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ ULONG ExportDirSize = pdd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
+ ULONG ExportDirOffset = RvaToOffset(pnth, ExportDirRva, FileSize);
+ if(ExportDirOffset == PE_ERROR_VALUE)
+ {
+ DbgPrint("[DeugMessage] Invalid Export Directory!\r\n");
+ return PE_ERROR_VALUE;
+ }
+
+ //Read Export Directory
+ PIMAGE_EXPORT_DIRECTORY ExportDir = (PIMAGE_EXPORT_DIRECTORY)(FileData + ExportDirOffset);
+ ULONG NumberOfNames = ExportDir->NumberOfNames;
+ ULONG AddressOfFunctionsOffset = RvaToOffset(pnth, ExportDir->AddressOfFunctions, FileSize);
+ ULONG AddressOfNameOrdinalsOffset = RvaToOffset(pnth, ExportDir->AddressOfNameOrdinals, FileSize);
+ ULONG AddressOfNamesOffset = RvaToOffset(pnth, ExportDir->AddressOfNames, FileSize);
+ if(AddressOfFunctionsOffset == PE_ERROR_VALUE ||
+ AddressOfNameOrdinalsOffset == PE_ERROR_VALUE ||
+ AddressOfNamesOffset == PE_ERROR_VALUE)
+ {
+ DbgPrint("[DeugMessage] Invalid Export Directory Contents!\r\n");
+ return PE_ERROR_VALUE;
+ }
+ ULONG* AddressOfFunctions = (ULONG*)(FileData + AddressOfFunctionsOffset);
+ USHORT* AddressOfNameOrdinals = (USHORT*)(FileData + AddressOfNameOrdinalsOffset);
+ ULONG* AddressOfNames = (ULONG*)(FileData + AddressOfNamesOffset);
+
+ //Find Export
+ ULONG ExportOffset = PE_ERROR_VALUE;
+ for(ULONG i = 0; i < NumberOfNames; i++)
+ {
+ ULONG CurrentNameOffset = RvaToOffset(pnth, AddressOfNames[i], FileSize);
+ if(CurrentNameOffset == PE_ERROR_VALUE)
+ continue;
+ const char* CurrentName = (const char*)(FileData + CurrentNameOffset);
+ ULONG CurrentFunctionRva = AddressOfFunctions[AddressOfNameOrdinals[i]];
+ if(CurrentFunctionRva >= ExportDirRva && CurrentFunctionRva < ExportDirRva + ExportDirSize)
+ continue; //we ignore forwarded exports
+ if(!strcmp(CurrentName, ExportName)) //compare the export name to the requested export
+ {
+ ExportOffset = RvaToOffset(pnth, CurrentFunctionRva, FileSize);
+ break;
+ }
+ }
+
+ if(ExportOffset == PE_ERROR_VALUE)
+ {
+ DbgPrint("[DeugMessage] Export %s not found in export table!\r\n", ExportName);
+ }
+
+ return ExportOffset;
+}
+
+PVOID PE::GetPageBase(PVOID lpHeader, ULONG* Size, PVOID ptr)
+{
+ if((unsigned char*)ptr < (unsigned char*)lpHeader)
+ return 0;
+ ULONG dwRva = (ULONG)((unsigned char*)ptr - (unsigned char*)lpHeader);
+ IMAGE_DOS_HEADER* pdh = (IMAGE_DOS_HEADER*)lpHeader;
+ if(pdh->e_magic != IMAGE_DOS_SIGNATURE)
+ return 0;
+ IMAGE_NT_HEADERS* pnth = (IMAGE_NT_HEADERS*)((unsigned char*)lpHeader + pdh->e_lfanew);
+ if(pnth->Signature != IMAGE_NT_SIGNATURE)
+ return 0;
+ IMAGE_SECTION_HEADER* psh = IMAGE_FIRST_SECTION(pnth);
+ int section = RvaToSection(pnth, dwRva);
+ if(section == -1)
+ return 0;
+ if(Size)
+ *Size = psh[section].SizeOfRawData;
+ return (PVOID)((unsigned char*)lpHeader + psh[section].VirtualAddress);
+}
\ No newline at end of file
diff --git a/pe.h b/pe.h
new file mode 100644
index 0000000..c73f57a
--- /dev/null
+++ b/pe.h
@@ -0,0 +1,15 @@
+#ifndef _PE_H
+#define _PE_H
+
+#include "_global.h"
+
+#define PE_ERROR_VALUE (ULONG)-1
+
+class PE
+{
+public:
+ static PVOID GetPageBase(PVOID lpHeader, ULONG* Size, PVOID ptr);
+ static ULONG GetExportOffset(const unsigned char* FileData, ULONG FileSize, const char* ExportName);
+};
+
+#endif
\ No newline at end of file
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..5544544
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,3 @@
+# Driver Memory Inject Dll
+Use Driver Global Memory Load DLL
+
diff --git a/ssdt.cpp b/ssdt.cpp
new file mode 100644
index 0000000..1748506
--- /dev/null
+++ b/ssdt.cpp
@@ -0,0 +1,288 @@
+#include "ssdt.h"
+#include "undocumented.h"
+#include "pe.h"
+
+#include "ntdll.h"
+
+//structures
+struct SSDTStruct
+{
+ LONG* pServiceTable;
+ PVOID pCounterTable;
+#ifdef _WIN64
+ ULONGLONG NumberOfServices;
+#else
+ ULONG NumberOfServices;
+#endif
+ PCHAR pArgumentTable;
+};
+
+//Based on: https://github.com/hfiref0x/WinObjEx64
+static SSDTStruct* SSDTfind()
+{
+ static SSDTStruct* SSDT = 0;
+ if(!SSDT)
+ {
+#ifndef _WIN64
+ //x86 code
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"KeServiceDescriptorTable");
+ SSDT = (SSDTStruct*)MmGetSystemRoutineAddress(&routineName);
+#else
+ //x64 code
+ ULONG kernelSize;
+ ULONG_PTR kernelBase = (ULONG_PTR)Undocumented::GetKernelBase(&kernelSize);
+ if(kernelBase == 0 || kernelSize == 0)
+ return NULL;
+
+ // Find KiSystemServiceStart
+ const unsigned char KiSystemServiceStartPattern[] = { 0x8B, 0xF8, 0xC1, 0xEF, 0x07, 0x83, 0xE7, 0x20, 0x25, 0xFF, 0x0F, 0x00, 0x00 };
+ const ULONG signatureSize = sizeof(KiSystemServiceStartPattern);
+ bool found = false;
+ ULONG KiSSSOffset;
+ for(KiSSSOffset = 0; KiSSSOffset < kernelSize - signatureSize; KiSSSOffset++)
+ {
+ if(RtlCompareMemory(((unsigned char*)kernelBase + KiSSSOffset), KiSystemServiceStartPattern, signatureSize) == signatureSize)
+ {
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ return NULL;
+
+ // lea r10, KeServiceDescriptorTable
+ ULONG_PTR address = kernelBase + KiSSSOffset + signatureSize;
+ LONG relativeOffset = 0;
+ if((*(unsigned char*)address == 0x4c) &&
+ (*(unsigned char*)(address + 1) == 0x8d) &&
+ (*(unsigned char*)(address + 2) == 0x15))
+ {
+ relativeOffset = *(LONG*)(address + 3);
+ }
+ if(relativeOffset == 0)
+ return NULL;
+
+ SSDT = (SSDTStruct*)(address + relativeOffset + 7);
+#endif
+ }
+ return SSDT;
+}
+
+PVOID SSDT::GetFunctionAddress(const char* apiname)
+{
+ //read address from SSDT
+ SSDTStruct* SSDT = SSDTfind();
+ if(!SSDT)
+ {
+ DbgPrint("[DeugMessage] SSDT not found...\r\n");
+ return 0;
+ }
+ ULONG_PTR SSDTbase = (ULONG_PTR)SSDT->pServiceTable;
+ if(!SSDTbase)
+ {
+ DbgPrint("[DeugMessage] ServiceTable not found...\r\n");
+ return 0;
+ }
+ ULONG readOffset = NTDLL::GetExportSsdtIndex(apiname);
+ if(readOffset == -1)
+ return 0;
+ if(readOffset >= SSDT->NumberOfServices)
+ {
+ DbgPrint("[DeugMessage] Invalid read offset...\r\n");
+ return 0;
+ }
+#ifdef _WIN64
+ return (PVOID)((SSDT->pServiceTable[readOffset] >> 4) + SSDTbase);
+#else
+ return (PVOID)SSDT->pServiceTable[readOffset];
+#endif
+}
+
+static void InterlockedSet(LONG* Destination, LONG Source)
+{
+ //Change memory properties.
+ PMDL g_pmdl = IoAllocateMdl(Destination, sizeof(LONG), 0, 0, NULL);
+ if(!g_pmdl)
+ return;
+ MmBuildMdlForNonPagedPool(g_pmdl);
+ LONG* Mapped = (LONG*)MmMapLockedPages(g_pmdl, KernelMode);
+ if(!Mapped)
+ {
+ IoFreeMdl(g_pmdl);
+ return;
+ }
+ InterlockedExchange(Mapped, Source);
+ //Restore memory properties.
+ MmUnmapLockedPages((PVOID)Mapped, g_pmdl);
+ IoFreeMdl(g_pmdl);
+}
+
+#ifdef _WIN64
+static PVOID FindCaveAddress(PVOID CodeStart, ULONG CodeSize, ULONG CaveSize)
+{
+ unsigned char* Code = (unsigned char*)CodeStart;
+
+ for(unsigned int i = 0, j = 0; i < CodeSize; i++)
+ {
+ if(Code[i] == 0x90 || Code[i] == 0xCC) //NOP or INT3
+ j++;
+ else
+ j = 0;
+ if(j == CaveSize)
+ return (PVOID)((ULONG_PTR)CodeStart + i - CaveSize + 1);
+ }
+ return 0;
+}
+#endif //_WIN64
+
+HOOK SSDT::Hook(const char* apiname, void* newfunc)
+{
+ SSDTStruct* SSDT = SSDTfind();
+ if(!SSDT)
+ {
+ DbgPrint("[DeugMessage] SSDT not found...\r\n");
+ return 0;
+ }
+ ULONG_PTR SSDTbase = (ULONG_PTR)SSDT->pServiceTable;
+ if(!SSDTbase)
+ {
+ DbgPrint("[DeugMessage] ServiceTable not found...\r\n");
+ return 0;
+ }
+ int FunctionIndex = NTDLL::GetExportSsdtIndex(apiname);
+ if(FunctionIndex == -1)
+ return 0;
+ if((ULONGLONG)FunctionIndex >= SSDT->NumberOfServices)
+ {
+ DbgPrint("[DeugMessage] Invalid API offset...\r\n");
+ return 0;
+ }
+
+ HOOK hHook = 0;
+ LONG oldValue = SSDT->pServiceTable[FunctionIndex];
+ LONG newValue;
+
+#ifdef _WIN64
+ /*
+ x64 SSDT Hook;
+ 1) find API addr
+ 2) get code page+size
+ 3) find cave address
+ 4) hook cave address (using hooklib)
+ 5) change SSDT value
+ */
+
+ static ULONG CodeSize = 0;
+ static PVOID CodeStart = 0;
+ if(!CodeStart)
+ {
+ ULONG_PTR Lowest = SSDTbase;
+ ULONG_PTR Highest = Lowest + 0x0FFFFFFF;
+ DbgPrint("[DeugMessage] Range: 0x%p-0x%p\r\n", Lowest, Highest);
+ CodeSize = 0;
+ CodeStart = PE::GetPageBase(Undocumented::GetKernelBase(), &CodeSize, (PVOID)((oldValue >> 4) + SSDTbase));
+ if(!CodeStart || !CodeSize)
+ {
+ DbgPrint("[DeugMessage] PeGetPageBase failed...\r\n");
+ return 0;
+ }
+ DbgPrint("[DeugMessage] CodeStart: 0x%p, CodeSize: 0x%X\r\n", CodeStart, CodeSize);
+ if((ULONG_PTR)CodeStart < Lowest) //start of the page is out of range (impossible, but whatever)
+ {
+ CodeSize -= (ULONG)(Lowest - (ULONG_PTR)CodeStart);
+ CodeStart = (PVOID)Lowest;
+ DbgPrint("[DeugMessage] CodeStart: 0x%p, CodeSize: 0x%X\r\n", CodeStart, CodeSize);
+ }
+ DbgPrint("[DeugMessage] Range: 0x%p-0x%p\r\n", CodeStart, (ULONG_PTR)CodeStart + CodeSize);
+ }
+
+ PVOID CaveAddress = FindCaveAddress(CodeStart, CodeSize, sizeof(HOOKOPCODES));
+ if(!CaveAddress)
+ {
+ DbgPrint("[DeugMessage] FindCaveAddress failed...\r\n");
+ return 0;
+ }
+ DbgPrint("[DeugMessage] CaveAddress: 0x%p\r\n", CaveAddress);
+
+ hHook = Hooklib::Hook(CaveAddress, (void*)newfunc);
+ if(!hHook)
+ return 0;
+
+ newValue = (LONG)((ULONG_PTR)CaveAddress - SSDTbase);
+ newValue = (newValue << 4) | oldValue & 0xF;
+
+ //update HOOK structure
+ hHook->SSDTindex = FunctionIndex;
+ hHook->SSDTold = oldValue;
+ hHook->SSDTnew = newValue;
+ hHook->SSDTaddress = (oldValue >> 4) + SSDTbase;
+
+#else
+ /*
+ x86 SSDT Hook:
+ 1) change SSDT value
+ */
+ newValue = (ULONG)newfunc;
+
+ hHook = (HOOK)RtlAllocateMemory(true, sizeof(HOOKSTRUCT));
+
+ //update HOOK structure
+ hHook->SSDTindex = FunctionIndex;
+ hHook->SSDTold = oldValue;
+ hHook->SSDTnew = newValue;
+ hHook->SSDTaddress = oldValue;
+
+#endif
+
+ InterlockedSet(&SSDT->pServiceTable[FunctionIndex], newValue);
+
+ DbgPrint("[DeugMessage] SSDThook(%s:0x%p, 0x%p)\r\n", apiname, hHook->SSDTold, hHook->SSDTnew);
+
+ return hHook;
+}
+
+void SSDT::Hook(HOOK hHook)
+{
+ if(!hHook)
+ return;
+ SSDTStruct* SSDT = SSDTfind();
+ if(!SSDT)
+ {
+ DbgPrint("[DeugMessage] SSDT not found...\r\n");
+ return;
+ }
+ LONG* SSDT_Table = SSDT->pServiceTable;
+ if(!SSDT_Table)
+ {
+ DbgPrint("[DeugMessage] ServiceTable not found...\r\n");
+ return;
+ }
+ InterlockedSet(&SSDT_Table[hHook->SSDTindex], hHook->SSDTnew);
+}
+
+void SSDT::Unhook(HOOK hHook, bool free)
+{
+ if(!hHook)
+ return;
+ SSDTStruct* SSDT = SSDTfind();
+ if(!SSDT)
+ {
+ DbgPrint("[DeugMessage] SSDT not found...\r\n");
+ return;
+ }
+ LONG* SSDT_Table = SSDT->pServiceTable;
+ if(!SSDT_Table)
+ {
+ DbgPrint("[DeugMessage] ServiceTable not found...\r\n");
+ return;
+ }
+ InterlockedSet(&SSDT_Table[hHook->SSDTindex], hHook->SSDTold);
+#ifdef _WIN64
+ if(free)
+ Hooklib::Unhook(hHook, true);
+#else
+ if(free)
+ RtlFreeMemory(hHook);
+#endif
+}
\ No newline at end of file
diff --git a/ssdt.h b/ssdt.h
new file mode 100644
index 0000000..5b0e1a7
--- /dev/null
+++ b/ssdt.h
@@ -0,0 +1,16 @@
+#ifndef _SSDT_H
+#define _SSDT_H
+
+#include "_global.h"
+#include "hooklib.h"
+
+class SSDT
+{
+public:
+ static PVOID GetFunctionAddress(const char* apiname);
+ static HOOK Hook(const char* apiname, void* newfunc);
+ static void Hook(HOOK hHook);
+ static void Unhook(HOOK hHook, bool free = false);
+};
+
+#endif
\ No newline at end of file
diff --git a/undocumented.cpp b/undocumented.cpp
new file mode 100644
index 0000000..60b1416
--- /dev/null
+++ b/undocumented.cpp
@@ -0,0 +1,420 @@
+#include "undocumented.h"
+#include "ssdt.h"
+
+
+typedef NTSTATUS(NTAPI* ZWQUERYINFORMATIONPROCESS)(
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength OPTIONAL
+);
+
+typedef NTSTATUS(NTAPI* ZWQUERYINFORMATIONTHREAD)(
+ IN HANDLE ThreadHandle,
+ IN THREADINFOCLASS ThreadInformationClass,
+ IN OUT PVOID ThreadInformation,
+ IN ULONG ThreadInformationLength,
+ OUT PULONG ReturnLength OPTIONAL
+);
+
+typedef NTSTATUS(NTAPI* NTQUERYOBJECT)(
+ IN HANDLE Handle OPTIONAL,
+ IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
+ OUT PVOID ObjectInformation OPTIONAL,
+ IN ULONG ObjectInformationLength,
+ OUT PULONG ReturnLength OPTIONAL
+);
+
+typedef NTSTATUS(NTAPI* ZWQUERYSYSTEMINFORMATION)(
+ IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
+ OUT PVOID SystemInformation,
+ IN ULONG SystemInformationLength,
+ OUT PULONG ReturnLength OPTIONAL
+);
+
+typedef NTSTATUS(NTAPI* NTQUERYSYSTEMINFORMATION)(
+ IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
+ OUT PVOID SystemInformation,
+ IN ULONG SystemInformationLength,
+ OUT PULONG ReturnLength OPTIONAL
+);
+
+typedef NTSTATUS(NTAPI* NTCLOSE)(
+ IN HANDLE Handle
+);
+
+typedef NTSTATUS(NTAPI* NTSETCONTEXTTHREAD)(
+ IN HANDLE ThreadHandle,
+ IN PCONTEXT Context
+);
+
+typedef NTSTATUS(NTAPI* NTCONTINUE)(
+ IN PCONTEXT Context,
+ BOOLEAN RaiseAlert
+);
+
+typedef NTSTATUS(NTAPI* NTDUPLICATEOBJECT)(
+ IN HANDLE SourceProcessHandle,
+ IN HANDLE SourceHandle,
+ IN HANDLE TargetProcessHandle,
+ OUT PHANDLE TargetHandle,
+ IN ACCESS_MASK DesiredAccess OPTIONAL,
+ IN ULONG HandleAttributes,
+ IN ULONG Options
+);
+
+typedef NTSTATUS(NTAPI* KERAISEUSEREXCEPTION)(
+ IN NTSTATUS ExceptionCode
+);
+
+typedef NTSTATUS(NTAPI* NTSETINFORMATIONTHREAD)(
+ IN HANDLE ThreadHandle,
+ IN THREADINFOCLASS ThreadInformationClass,
+ IN PVOID ThreadInformation,
+ IN ULONG ThreadInformationLength
+);
+
+typedef NTSTATUS(NTAPI* NTSETINFORMATIONPROCESS)(
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ IN PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength
+);
+
+typedef NTSTATUS(NTAPI* NTQUERYINFORMATIONPROCESS)(
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength OPTIONAL
+);
+
+typedef NTSTATUS(NTAPI* NTSYSTEMDEBUGCONTROL)(
+ IN SYSDBG_COMMAND Command,
+ IN PVOID InputBuffer OPTIONAL,
+ IN ULONG InputBufferLength,
+ OUT PVOID OutputBuffer OPTIONAL,
+ IN ULONG OutputBufferLength,
+ OUT PULONG ReturnLength OPTIONAL
+);
+
+static ZWQUERYINFORMATIONPROCESS ZwQIP = 0;
+static ZWQUERYINFORMATIONTHREAD ZwQIT = 0;
+static NTQUERYOBJECT NtQO = 0;
+static ZWQUERYSYSTEMINFORMATION ZwQSI = 0;
+static NTQUERYSYSTEMINFORMATION NtQSI = 0;
+static NTCLOSE NtClo = 0;
+static NTSETCONTEXTTHREAD NtSCT = 0;
+static NTCONTINUE NtCon = 0;
+static NTDUPLICATEOBJECT NtDO = 0;
+static KERAISEUSEREXCEPTION KeRUE = 0;
+static NTSETINFORMATIONTHREAD NtSIT = 0;
+static NTSETINFORMATIONPROCESS NtSIP = 0;
+static NTQUERYINFORMATIONPROCESS NtQIP = 0;
+static NTSYSTEMDEBUGCONTROL NtSDBC = 0;
+
+NTSTATUS NTAPI Undocumented::ZwQueryInformationProcess(
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength OPTIONAL)
+{
+ return ZwQIP(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength);
+}
+
+NTSTATUS NTAPI Undocumented::ZwQueryInformationThread(
+ IN HANDLE ThreadHandle,
+ IN THREADINFOCLASS ThreadInformationClass,
+ IN OUT PVOID ThreadInformation,
+ IN ULONG ThreadInformationLength,
+ OUT PULONG ReturnLength OPTIONAL)
+{
+ return ZwQIT(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength, ReturnLength);
+}
+
+NTSTATUS NTAPI Undocumented::NtQueryObject(
+ IN HANDLE Handle OPTIONAL,
+ IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
+ OUT PVOID ObjectInformation OPTIONAL,
+ IN ULONG ObjectInformationLength,
+ OUT PULONG ReturnLength OPTIONAL)
+{
+ return NtQO(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength);
+}
+
+NTSTATUS NTAPI Undocumented::ZwQuerySystemInformation(
+ IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
+ OUT PVOID SystemInformation,
+ IN ULONG SystemInformationLength,
+ OUT PULONG ReturnLength OPTIONAL)
+{
+ return ZwQSI(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
+}
+
+NTSTATUS NTAPI Undocumented::NtQuerySystemInformation(
+ IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
+ OUT PVOID SystemInformation,
+ IN ULONG SystemInformationLength,
+ OUT PULONG ReturnLength OPTIONAL)
+{
+ return NtQSI(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
+}
+
+NTSTATUS NTAPI Undocumented::NtClose(
+ IN HANDLE Handle)
+{
+ return NtClo(Handle);
+}
+
+NTSTATUS NTAPI Undocumented::NtSetContextThread(
+ IN HANDLE ThreadHandle,
+ IN PCONTEXT Context)
+{
+ return NtSCT(ThreadHandle, Context);
+}
+
+NTSTATUS NTAPI Undocumented::NtContinue(
+ IN PCONTEXT Context,
+ BOOLEAN RaiseAlert)
+{
+ return NtCon(Context, RaiseAlert);
+}
+
+NTSTATUS NTAPI Undocumented::NtDuplicateObject(
+ IN HANDLE SourceProcessHandle,
+ IN HANDLE SourceHandle,
+ IN HANDLE TargetProcessHandle,
+ OUT PHANDLE TargetHandle,
+ IN ACCESS_MASK DesiredAccess OPTIONAL,
+ IN ULONG HandleAttributes,
+ IN ULONG Options)
+{
+ return NtDO(SourceProcessHandle, SourceHandle, TargetProcessHandle, TargetHandle, DesiredAccess, HandleAttributes, Options);
+}
+
+NTSTATUS NTAPI Undocumented::KeRaiseUserException(
+ IN NTSTATUS ExceptionCode)
+{
+ return KeRUE(ExceptionCode);
+}
+
+NTSTATUS NTAPI Undocumented::NtSetInformationThread(
+ IN HANDLE ThreadHandle,
+ IN THREADINFOCLASS ThreadInformationClass,
+ IN PVOID ThreadInformation,
+ IN ULONG ThreadInformationLength)
+{
+ return NtSIT(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength);
+}
+
+NTSTATUS NTAPI Undocumented::NtSetInformationProcess(
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ IN PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength)
+{
+ return NtSIP(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength);
+}
+
+NTSTATUS NTAPI Undocumented::NtQueryInformationProcess(
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength OPTIONAL)
+{
+ return NtQIP(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength);
+}
+
+NTSTATUS NTAPI Undocumented::NtSystemDebugControl(
+ IN SYSDBG_COMMAND Command,
+ IN PVOID InputBuffer,
+ IN ULONG InputBufferLength,
+ OUT PVOID OutputBuffer,
+ IN ULONG OutputBufferLength,
+ OUT PULONG ReturnLength)
+{
+ return NtSDBC(Command, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, ReturnLength);
+}
+
+bool Undocumented::UndocumentedInit()
+{
+ //Exported kernel functions after this
+ if(!ZwQIP)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");
+ ZwQIP = (ZWQUERYINFORMATIONPROCESS)MmGetSystemRoutineAddress(&routineName);
+ if(!ZwQIP)
+ return false;
+ }
+ if(!ZwQIT)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"ZwQueryInformationThread");
+ ZwQIT = (ZWQUERYINFORMATIONTHREAD)MmGetSystemRoutineAddress(&routineName);
+ if(!ZwQIT)
+ return false;
+ }
+ if(!ZwQSI)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"ZwQuerySystemInformation");
+ ZwQSI = (ZWQUERYSYSTEMINFORMATION)MmGetSystemRoutineAddress(&routineName);
+ if(!ZwQSI)
+ return false;
+ }
+ if(!NtQSI)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"NtQuerySystemInformation");
+ NtQSI = (NTQUERYSYSTEMINFORMATION)MmGetSystemRoutineAddress(&routineName);
+ if(!NtQSI)
+ return false;
+ }
+ if(!NtClo)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"NtClose");
+ NtClo = (NTCLOSE)MmGetSystemRoutineAddress(&routineName);
+ if(!NtClo)
+ return false;
+ }
+ if(!NtDO)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"NtDuplicateObject");
+ NtDO = (NTDUPLICATEOBJECT)MmGetSystemRoutineAddress(&routineName);
+ if(!NtDO)
+ return false;
+ }
+ if(!KeRUE)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"KeRaiseUserException");
+ KeRUE = (KERAISEUSEREXCEPTION)MmGetSystemRoutineAddress(&routineName);
+ if(!KeRUE)
+ return false;
+ }
+ if(!NtSIT)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"NtSetInformationThread");
+ NtSIT = (NTSETINFORMATIONTHREAD)MmGetSystemRoutineAddress(&routineName);
+ if(!NtSIT)
+ return false;
+ }
+ if(!NtSIP)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"NtSetInformationProcess");
+ NtSIP = (NTSETINFORMATIONPROCESS)MmGetSystemRoutineAddress(&routineName);
+ if(!NtSIP)
+ return false;
+ }
+ if(!NtQIP)
+ {
+ UNICODE_STRING routineName;
+ RtlInitUnicodeString(&routineName, L"NtQueryInformationProcess");
+ NtQIP = (NTQUERYINFORMATIONPROCESS)MmGetSystemRoutineAddress(&routineName);
+ if(!NtQIP)
+ return false;
+ }
+ //SSDT-only functions after this
+ if(!NtQO)
+ {
+ NtQO = (NTQUERYOBJECT)SSDT::GetFunctionAddress("NtQueryObject");
+ if(!NtQO)
+ return false;
+ }
+ if(!NtSCT)
+ {
+ NtSCT = (NTSETCONTEXTTHREAD)SSDT::GetFunctionAddress("NtSetContextThread");
+ if(!NtSCT)
+ return false;
+ }
+ if(!NtCon)
+ {
+ NtCon = (NTCONTINUE)SSDT::GetFunctionAddress("NtContinue");
+ if(!NtCon)
+ return false;
+ }
+ if(!NtSDBC)
+ {
+ NtSDBC = (NTSYSTEMDEBUGCONTROL)SSDT::GetFunctionAddress("NtSystemDebugControl");
+ if(!NtSDBC)
+ return false;
+ }
+ return true;
+}
+
+//Based on: http://alter.org.ua/docs/nt_kernel/procaddr
+PVOID Undocumented::GetKernelBase(PULONG pImageSize)
+{
+ typedef struct _SYSTEM_MODULE_ENTRY
+ {
+ HANDLE Section;
+ PVOID MappedBase;
+ PVOID ImageBase;
+ ULONG ImageSize;
+ ULONG Flags;
+ USHORT LoadOrderIndex;
+ USHORT InitOrderIndex;
+ USHORT LoadCount;
+ USHORT OffsetToFileName;
+ UCHAR FullPathName[256];
+ } SYSTEM_MODULE_ENTRY, *PSYSTEM_MODULE_ENTRY;
+
+#pragma warning(disable:4200)
+ typedef struct _SYSTEM_MODULE_INFORMATION
+ {
+ ULONG Count;
+ SYSTEM_MODULE_ENTRY Module[0];
+ } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
+
+ PVOID pModuleBase = NULL;
+ PSYSTEM_MODULE_INFORMATION pSystemInfoBuffer = NULL;
+
+ ULONG SystemInfoBufferSize = 0;
+
+ NTSTATUS status = Undocumented::ZwQuerySystemInformation(SystemModuleInformation,
+ &SystemInfoBufferSize,
+ 0,
+ &SystemInfoBufferSize);
+
+ if(!SystemInfoBufferSize)
+ {
+ DbgPrint("[DeugMessage] ZwQuerySystemInformation (1) failed...\r\n");
+ return NULL;
+ }
+
+ pSystemInfoBuffer = (PSYSTEM_MODULE_INFORMATION)ExAllocatePool(NonPagedPool, SystemInfoBufferSize * 2);
+
+ if(!pSystemInfoBuffer)
+ {
+ DbgPrint("[DeugMessage] ExAllocatePool failed...\r\n");
+ return NULL;
+ }
+
+ memset(pSystemInfoBuffer, 0, SystemInfoBufferSize * 2);
+
+ status = Undocumented::ZwQuerySystemInformation(SystemModuleInformation,
+ pSystemInfoBuffer,
+ SystemInfoBufferSize * 2,
+ &SystemInfoBufferSize);
+
+ if(NT_SUCCESS(status))
+ {
+ pModuleBase = pSystemInfoBuffer->Module[0].ImageBase;
+ if(pImageSize)
+ *pImageSize = pSystemInfoBuffer->Module[0].ImageSize;
+ }
+ else
+ DbgPrint("[DeugMessage] ZwQuerySystemInformation (2) failed...\r\n");
+
+ ExFreePool(pSystemInfoBuffer);
+
+ return pModuleBase;
+}
diff --git a/undocumented.h b/undocumented.h
new file mode 100644
index 0000000..633fb4d
--- /dev/null
+++ b/undocumented.h
@@ -0,0 +1,130 @@
+#ifndef _UNDOCUMENTED_H
+#define _UNDOCUMENTED_H
+
+#include "_global.h"
+
+//structures
+typedef struct _OBJECT_TYPE_INFORMATION
+{
+ UNICODE_STRING TypeName;
+ ULONG TotalNumberOfHandles;
+ ULONG TotalNumberOfObjects;
+} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
+
+typedef struct _OBJECT_ALL_INFORMATION
+{
+ ULONG NumberOfObjects;
+ OBJECT_TYPE_INFORMATION ObjectTypeInformation[1];
+} OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION;
+
+/*
+//enums
+typedef enum _OBJECT_INFORMATION_CLASS
+{
+ ObjectTypeInformation = 2,
+ ObjectTypesInformation = 3
+} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
+*/
+
+typedef enum _SYSTEM_INFORMATION_CLASS
+{
+ SystemModuleInformation = 11,
+ SystemKernelDebuggerInformation = 35
+} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;
+
+typedef enum _SYSDBG_COMMAND
+{
+ SysDbgGetTriageDump = 29,
+} SYSDBG_COMMAND, *PSYSDBG_COMMAND;
+
+class Undocumented
+{
+public:
+ static NTSTATUS NTAPI ZwQueryInformationProcess(
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength OPTIONAL);
+
+ static NTSTATUS NTAPI ZwQueryInformationThread(
+ IN HANDLE ThreadHandle,
+ IN THREADINFOCLASS ThreadInformationClass,
+ IN OUT PVOID ThreadInformation,
+ IN ULONG ThreadInformationLength,
+ OUT PULONG ReturnLength OPTIONAL);
+
+ static NTSTATUS NTAPI NtQueryObject(
+ IN HANDLE Handle OPTIONAL,
+ IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
+ OUT PVOID ObjectInformation OPTIONAL,
+ IN ULONG ObjectInformationLength,
+ OUT PULONG ReturnLength OPTIONAL);
+
+ static NTSTATUS NTAPI ZwQuerySystemInformation(
+ IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
+ OUT PVOID SystemInformation,
+ IN ULONG SystemInformationLength,
+ OUT PULONG ReturnLength OPTIONAL);
+
+ static NTSTATUS NTAPI NtQuerySystemInformation(
+ IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
+ OUT PVOID SystemInformation,
+ IN ULONG SystemInformationLength,
+ OUT PULONG ReturnLength OPTIONAL);
+
+ static NTSTATUS NTAPI NtClose(
+ IN HANDLE Handle);
+
+ static NTSTATUS NTAPI NtSetContextThread(
+ IN HANDLE ThreadHandle,
+ IN PCONTEXT Context);
+
+ static NTSTATUS NTAPI NtContinue(
+ IN PCONTEXT Context,
+ BOOLEAN RaiseAlert);
+
+ static NTSTATUS NTAPI NtDuplicateObject(
+ IN HANDLE SourceProcessHandle,
+ IN HANDLE SourceHandle,
+ IN HANDLE TargetProcessHandle,
+ OUT PHANDLE TargetHandle,
+ IN ACCESS_MASK DesiredAccess OPTIONAL,
+ IN ULONG HandleAttributes,
+ IN ULONG Options);
+
+ static NTSTATUS NTAPI KeRaiseUserException(
+ IN NTSTATUS ExceptionCode);
+
+ static NTSTATUS NTAPI NtSetInformationThread(
+ IN HANDLE ThreadHandle,
+ IN THREADINFOCLASS ThreadInformationClass,
+ IN PVOID ThreadInformation,
+ IN ULONG ThreadInformationLength);
+
+ static NTSTATUS NTAPI NtSetInformationProcess(
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ IN PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength);
+
+ static NTSTATUS NTAPI NtQueryInformationProcess(
+ IN HANDLE ProcessHandle,
+ IN PROCESSINFOCLASS ProcessInformationClass,
+ OUT PVOID ProcessInformation,
+ IN ULONG ProcessInformationLength,
+ OUT PULONG ReturnLength OPTIONAL);
+
+ static NTSTATUS NTAPI NtSystemDebugControl(
+ IN SYSDBG_COMMAND Command,
+ IN PVOID InputBuffer OPTIONAL,
+ IN ULONG InputBufferLength OPTIONAL,
+ OUT PVOID OutputBuffer,
+ IN ULONG OutputBufferLength,
+ OUT PULONG ReturnLength OPTIONAL);
+
+ static bool UndocumentedInit();
+ static PVOID GetKernelBase(PULONG pImageSize = NULL);
+};
+
+#endif