static void Main() { IntPtr hKernelbase = Libloaderapi.GetModuleHandleA("KERNELBASE.dll"); IntPtr isDebuggerPresentAddr = Libloaderapi.GetProcAddress(hKernelbase, "IsDebuggerPresent"); int initialCrcCheckValue = default; int c = 1; while (c < 100) { CreateStaticAccumulateAtAddress(isDebuggerPresentAddr, 14, out int crcId); RunStaticCrc(crcId, out int crcValue); if (initialCrcCheckValue == default) { initialCrcCheckValue = crcValue; } else if (initialCrcCheckValue != crcValue) { Console.WriteLine("Memory change detected."); Environment.Exit(-1); } DeleteStaticCrc(crcId); Console.WriteLine($"{c}: {crcValue} (IDP: {isDebuggerPresentAddr:X})"); //Console.ReadLine(); c++; Thread.Sleep(10); } while (true) { ErrorCodes crcVal = DynamicAccumulateAtAddress(isDebuggerPresentAddr, 14, out int crcValue); if (crcVal != NO_ERROR) { Console.WriteLine($"{c}: CRC Check Failed for {isDebuggerPresentAddr}. Error Codes: {crcVal} (LastError: {Marshal.GetLastWin32Error()}"); } if (initialCrcCheckValue == default) { initialCrcCheckValue = crcValue; } else if (initialCrcCheckValue != crcValue) { Console.WriteLine("Memory change detected."); Environment.Exit(-1); } Console.WriteLine($"{c}: {crcValue} (IDP: {isDebuggerPresentAddr:X})"); //Console.ReadLine(); c++; Thread.Sleep(10); } ; //Free ModuleHandle. }
public static Task DetourWs2Send() { //ToDo: Add handling W32Send.p3cx = Process.GetProcessesByName("3CXWin8Phone").FirstOrDefault(); W32Send.ws2ModIndex = GetModuleIndex(W32Send.p3cx.Modules, "WS2_32"); if (W32Send.ws2ModIndex == -1) { Debug.WriteLine("Module not found"); return(null); } IntPtr hWinsock = Libloaderapi.LoadLibraryA("WS2_32"); if (hWinsock == IntPtr.Zero) { return(null); } IntPtr sendFunc = Libloaderapi.GetProcAddress(hWinsock, "send"); if (sendFunc == IntPtr.Zero) { return(null); } W32Send.sendOffset = (int)sendFunc - (int)hWinsock; Libloaderapi.FreeLibrary(hWinsock); //The address of the detour int detourAddr = (int)Memoryapi.VirtualAllocEx(W32Send.p3cx.Handle, IntPtr.Zero, (uint)W32Send.Detour.assembly.Length, Winnt.AllocationType.MEM_COMMIT, Winnt.MemoryProtection.PAGE_EXECUTE_READWRITE); byte[] detourAddrArr = BitConverter.GetBytes(detourAddr); //The address of the memory storage int storageAddr = (int)Memoryapi.VirtualAllocEx(W32Send.p3cx.Handle, IntPtr.Zero, (uint)W32Send.PageSize, Winnt.AllocationType.MEM_COMMIT, Winnt.MemoryProtection.PAGE_EXECUTE_READWRITE); byte[] storageAddrArr = BitConverter.GetBytes(storageAddr); //Patching the detour-calling function with the detour address for (int i = W32Send.CallDetour.StartOfMovInstruction; i < W32Send.CallDetour.EndOfMovInstruction; i++) { W32Send.CallDetour.assembly[i] = detourAddrArr[i - 1]; } //Patching the detour function with the storage address for (int i = W32Send.Detour.StartOfMovEaxInstruction; i <= W32Send.Detour.EndOfMovEaxInstruction; i++) { W32Send.Detour.assembly[i] = storageAddrArr[i - 1]; } //Patching the detour function with the return address byte[] returnAddr = BitConverter.GetBytes((int)W32Send.p3cx.Modules[W32Send.ws2ModIndex].BaseAddress + W32Send.sendOffset + 0xA); for (int i = W32Send.Detour.StartOfMovEdxInstruction, x = 0; i < W32Send.Detour.EndOfMovEdxInstruction; i++, x++) { W32Send.Detour.assembly[i] = returnAddr[x]; } //Detouring the send function to the detour calling function IntPtr jmpToDetourAddr = W32Send.p3cx.Modules[W32Send.ws2ModIndex].BaseAddress + W32Send.sendOffset + W32Send.JmpToCallDetour.Offset; if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, jmpToDetourAddr, W32Send.JmpToCallDetour.assembly, W32Send.JmpToCallDetour.assembly.Length, out IntPtr _)) { Debug.WriteLine(Marshal.GetLastWin32Error()); return(null); } ; //Writing the detour call if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, (jmpToDetourAddr - 19), W32Send.CallDetour.assembly, W32Send.CallDetour.assembly.Length, out IntPtr _)) { Debug.WriteLine(Marshal.GetLastWin32Error()); return(null); } ; //Writing the detour if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, (IntPtr)detourAddr, W32Send.Detour.assembly, W32Send.Detour.assembly.Length, out IntPtr _)) { Debug.WriteLine(Marshal.GetLastWin32Error()); return(null); } Task DetourTask = new Task(() => { while (W32Send.detour) { byte[] data = new byte[W32Send.PageSize]; if (!Memoryapi.ReadProcessMemory(W32Send.p3cx.Handle, (IntPtr)storageAddr, data, W32Send.PageSize, out _)) { Debug.WriteLine(Marshal.GetLastWin32Error()); } //IF the byte is signalled if (data[0] == 1) { //Memoryapi.ReadProcessMemory(p.Handle) SocketData sd = new SocketData() { length = BitConverter.ToInt32(data.Skip(1).Take(4).ToArray(), 0), bufferPtr = new byte[4], }; sd.bufferCont = new byte[sd.length]; Array.Copy(data, 5, sd.bufferPtr, 0, sizeof(int)); int bufferPtrAddr = BitConverter.ToInt32(sd.bufferPtr, 0); if (!Memoryapi.ReadProcessMemory(W32Send.p3cx.Handle, (IntPtr)bufferPtrAddr, sd.bufferCont, sd.length, out IntPtr _)) { Debug.Write(Marshal.GetLastWin32Error()); } #if DEBUG Trace.Write($"Socket Length {sd.length}\n"); Trace.Write($"Socket Payload {Encoding.ASCII.GetString(sd.bufferCont, 0, sd.length)}\n"); //Debug uses ascii so messages will be omitted Trace.Write("\n"); #endif //ToDo: USE THE CORRECT CODE HERE, UPDATE IT. Application.Current.Dispatcher.Invoke(() => { packetTable.Rows.Add("ws32_32.send", BitConverter.ToString(sd.bufferCont), sd.length, "NYI"); }); Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, (IntPtr)storageAddr, new byte[] { 0x0 }, 0x1, out IntPtr _); } //Performance Thread.Sleep(10); } //Remove the detour IntPtr origInstrAddr = W32Send.p3cx.Modules[W32Send.ws2ModIndex].BaseAddress + W32Send.sendOffset + W32Send.JmpToCallDetour.Offset; //Remove the detour jmp if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, origInstrAddr, W32Send.JmpToCallDetour.originalInstructions, W32Send.JmpToCallDetour.originalInstructions.Length, out IntPtr _)) { ;//ToDo: Do something here } //Remove the jne instruction incase the comparison is mid-check. if (!Memoryapi.WriteProcessMemory(W32Send.p3cx.Handle, (IntPtr)(detourAddr + W32Send.Detour.JNEOffset), new byte[] { 0x90, 0x90 }, 0x2, out IntPtr _)) { ;//ToDo: Do something here } //ToDo: free memory of allocated pages. int me = 5; }); return(DetourTask); }