private unsafe static void RestoreLink(KernelMemoryIO memoryIO, IntPtr deletedLink) { if (deletedLink == IntPtr.Zero) { return; } IntPtr baseLink = GetActiveProcessLinksFromAnotherProcess(memoryIO); if (baseLink == IntPtr.Zero) { Console.WriteLine("Can't find an appropriate ActiveProcessLinks"); return; } Console.WriteLine($"Restore {deletedLink.ToInt64():x} to {baseLink.ToInt64():x}"); _LIST_ENTRY baseEntry = memoryIO.ReadMemory <_LIST_ENTRY>(baseLink); IntPtr nextItem = baseEntry.Flink; memoryIO.WriteMemory <IntPtr>(deletedLink + 0 /* deletedLink.Flink */, nextItem); memoryIO.WriteMemory <IntPtr>(deletedLink + sizeof(IntPtr) /* deletedLink.Blink */, baseLink); memoryIO.WriteMemory <IntPtr>(baseLink + 0 /* baseLink.Flink */, deletedLink); memoryIO.WriteMemory <IntPtr>(nextItem + sizeof(IntPtr) /* nextItem.Blink */, deletedLink); }
private static IntPtr GetActiveProcessLinksFromAnotherProcess(KernelMemoryIO memoryIO) { foreach (Process process in Process.GetProcesses()) { Console.WriteLine("Try-Target process name: " + process.ProcessName + ", " + process.Id); IntPtr ethreadPtr = GetEThread(process.Id); if (ethreadPtr == IntPtr.Zero) { continue; } { // +0x648 Cid : _CLIENT_ID IntPtr clientIdPtr = _ethreadOffset.GetPointer(ethreadPtr, "Cid"); _CLIENT_ID cid = memoryIO.ReadMemory <_CLIENT_ID>(clientIdPtr); if (cid.Pid != process.Id) // Check that ethreadPtr is valid { Console.WriteLine("NOT Match with Cid"); Console.WriteLine(); continue; } } IntPtr processPtr = _kthreadOffset.GetPointer(ethreadPtr, "Process"); IntPtr eprocessPtr = memoryIO.ReadMemory <IntPtr>(processPtr); IntPtr activeProcessLinksPtr = _eprocessOffset.GetPointer(eprocessPtr, "ActiveProcessLinks"); return(activeProcessLinksPtr); } return(IntPtr.Zero); }
private unsafe static IntPtr Unlink(KernelMemoryIO memoryIO, IntPtr linkPtr) { _LIST_ENTRY entry = memoryIO.ReadMemory <_LIST_ENTRY>(linkPtr); IntPtr pNext = entry.Flink; IntPtr pPrev = entry.Blink; memoryIO.WriteMemory <IntPtr>(pNext + sizeof(IntPtr) /* pNext.Blink */, pPrev); memoryIO.WriteMemory <IntPtr>(pPrev + 0 /* pPrev.Flink */, pNext); memoryIO.WriteMemory <IntPtr>(linkPtr + sizeof(IntPtr) /* linkPtr.Blink */, linkPtr); memoryIO.WriteMemory <IntPtr>(linkPtr + 0 /* linkPtr.Flink */, linkPtr); return(linkPtr); }
static void Main(string[] _) { int processId = Process.GetCurrentProcess().Id; Console.WriteLine($"ThisPID: {processId}"); IntPtr ethreadPtr = GetEThread(processId); if (ethreadPtr == IntPtr.Zero) { Console.WriteLine("THREAD handle not found"); return; } Console.WriteLine($"_ETHREAD address: {ethreadPtr.ToInt64():x}"); Console.WriteLine(); using (KernelMemoryIO memoryIO = new KernelMemoryIO()) { if (memoryIO.IsInitialized == false) { Console.WriteLine("Failed to open device"); return; } { // +0x648 Cid : _CLIENT_ID IntPtr clientIdPtr = _ethreadOffset.GetPointer(ethreadPtr, "Cid"); _CLIENT_ID cid = memoryIO.ReadMemory <_CLIENT_ID>(clientIdPtr); Console.WriteLine($"PID: {cid.Pid} ({cid.Pid:x})"); Console.WriteLine($"TID: {cid.Tid} ({cid.Tid:x})"); if (cid.Pid != processId) { return; } } { // +0x220 Process : Ptr64 _KPROCESS IntPtr processPtr = _kthreadOffset.GetPointer(ethreadPtr, "Process"); IntPtr eprocessPtr = memoryIO.ReadMemory <IntPtr>(processPtr); IntPtr activeProcessLinksPtr = _eprocessOffset.GetPointer(eprocessPtr, "ActiveProcessLinks"); // _LIST_ENTRY entry = memoryIO.ReadMemory<_LIST_ENTRY>(activeProcessLinksPtr); Console.WriteLine("Press any key to hide this process from Task Manager"); Console.ReadLine(); IntPtr deletedEntry = IntPtr.Zero; try { deletedEntry = Unlink(memoryIO, activeProcessLinksPtr); Console.WriteLine(); Console.WriteLine("Press any key to unhide this process"); Console.ReadLine(); } finally { RestoreLink(memoryIO, deletedEntry); } Console.WriteLine("Check this process appeared again in Task Manager"); Console.WriteLine("Press any key to exit"); Console.ReadLine(); } } }
// Prerequisite: // Register and start "KernelMemoryIO" kernel driver // https://github.com/stjeong/KernelMemoryIO/tree/master/KernelMemoryIO // // sc create "KernelMemoryIO" binPath= "D:\Debug\KernelMemoryIO.sys" type= kernel start= demand // sc delete "KernelMemoryIO" // net start KernelMemoryIO // net stop KernelMemoryIO static void Main(string[] _) { Console.WriteLine("Version 1.0"); int processId = Process.GetCurrentProcess().Id; using (KernelMemoryIO memoryIO = new KernelMemoryIO()) { if (memoryIO.IsInitialized == false) { Console.WriteLine("Failed to open device"); return; } /* * // 0xFFFF850953C62080 from process explorer (Handles view pane: Ctrl+H) * // It must be a Handle of Thead type. * IntPtr ethreadPtr = new IntPtr(unchecked((long)0xFFFF850953C62080)); */ IntPtr ethreadPtr = GetEThread(); var ethreadOffset = DbgOffset.Get("_ETHREAD"); var kthreadOffset = DbgOffset.Get("_KTHREAD"); var eprocessOffset = DbgOffset.Get("_EPROCESS"); { // +0x648 Cid : _CLIENT_ID IntPtr clientIdPtr = ethreadOffset.GetPointer(ethreadPtr, "Cid"); _CLIENT_ID cid = memoryIO.ReadMemory <_CLIENT_ID>(clientIdPtr); if (cid.UniqueProcess.ToInt32() != processId) { Console.WriteLine("failed to read"); return; } Console.WriteLine($"PID: {cid.Pid} ({cid.Pid:x})"); Console.WriteLine($"TID: {cid.Tid} ({cid.Tid:x})"); } { // +0x220 Process : Ptr64 _KPROCESS IntPtr kprocessPosPtr = kthreadOffset.GetPointer(ethreadPtr, "Process"); IntPtr kprocessPtr = memoryIO.ReadMemory <IntPtr>(kprocessPosPtr); Console.WriteLine($"_EPROCESS: {kprocessPtr} ({kprocessPtr.ToInt64():x})"); { // +0x3d0 Cookie : Uint4B IntPtr cookiePtr = eprocessOffset.GetPointer(kprocessPtr, "Cookie"); int oldCookie = memoryIO.ReadMemory <int>(cookiePtr); Console.WriteLine($"[OLD] _EPROCESS.cookie: {oldCookie}({oldCookie:x})"); int writtenBytes = memoryIO.WriteMemory <int>(cookiePtr, 0x5000); Console.WriteLine("Written = " + writtenBytes); int newCookie = memoryIO.ReadMemory <int>(cookiePtr); Console.WriteLine($"[NEW] _EPROCESS.cookie: {newCookie}({newCookie:x})"); memoryIO.WriteMemory <int>(cookiePtr, oldCookie); Console.WriteLine("Written = " + writtenBytes); } } //Console.WriteLine($"Current Position: {memoryIO.Position}({memoryIO.Position.ToInt64():x})"); //memoryIO.Position = ethreadPtr; //Console.WriteLine($"Current Position: {memoryIO.Position}({memoryIO.Position.ToInt64():x})"); } }