static IntPtr WriteProgramArgs(IntPtr hProcess, string args) { //We need room for ANSI and Unicode representation of args IntPtr regionSize = new IntPtr(args.Length * 2 + 2 + args.Length + 1); IntPtr remoteArgAddress = IntPtr.Zero; byte[] argBytesUnicode = Encoding.Unicode.GetBytes(args); byte[] argBytesANSI = Encoding.ASCII.GetBytes(args); IntPtr bytesWritten; remoteArgAddress = Execute.DynamicInvoke.Native.NtAllocateVirtualMemory(hProcess, ref remoteArgAddress, IntPtr.Zero, ref regionSize, 0x00001000, (int)4); WinAPI.WriteProcessMemory(hProcess, remoteArgAddress, argBytesUnicode, argBytesUnicode.Length, out bytesWritten); WinAPI.WriteProcessMemory(hProcess, new IntPtr(remoteArgAddress.ToInt64() + argBytesUnicode.Length + 2), argBytesANSI, argBytesANSI.Length, out bytesWritten); return(remoteArgAddress); }
static bool WriteProcessMemory(IntPtr hProcess, IntPtr baseAddress, byte[] data, int size, out uint bytesWritten) { if (IntPtr.Size == 8) { IntPtr regionSize = (IntPtr)size; IntPtr protectionBase = baseAddress; uint oldProtect = 0; bytesWritten = 0; GCHandle pinnedArray = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr intptrData = pinnedArray.AddrOfPinnedObject(); uint result = NtProtectVirtualMemorySysCall(hProcess, ref protectionBase, ref regionSize, 0x40 /*RWX*/, ref oldProtect); if (result != 0) { throw new System.ComponentModel.Win32Exception((int)result); } result = NtWriteVirtualMemorySysCall(hProcess, baseAddress, intptrData, (uint)size, ref bytesWritten); if (result != 0) { throw new System.ComponentModel.Win32Exception((int)result); } result = NtProtectVirtualMemorySysCall(hProcess, ref protectionBase, ref regionSize, oldProtect, ref oldProtect); if (result != 0) { throw new System.ComponentModel.Win32Exception((int)result); } return(result == 0); } else { IntPtr bytesWrittenPtr; bool result = WinAPI.WriteProcessMemory(hProcess, baseAddress, data, size, out bytesWrittenPtr); bytesWritten = (uint)bytesWrittenPtr; return(result); } }
static string PatchEntryPointIfNeeded(IntPtr moduleHandle, IntPtr imageBase, IntPtr hProcess) { long fileSize; StringBuilder dllPath = new StringBuilder(1024); if (!WinAPI.GetFileSizeEx(moduleHandle, out fileSize) || fileSize == 0) { return(null); } IntPtr handle = WinAPI.CreateFileMapping(moduleHandle, IntPtr.Zero, WinAPI.FileMapProtection.PageReadonly | WinAPI.FileMapProtection.SectionImage, 0, 0, null); if (handle == IntPtr.Zero) { return(null); } IntPtr mem = WinAPI.MapViewOfFile(handle, WinAPI.FileMapAccess.FileMapRead, 0, 0, UIntPtr.Zero); if (mem == IntPtr.Zero) { return(null); } if (WinAPI.GetFinalPathNameByHandle(moduleHandle, dllPath, (uint)dllPath.Capacity, 0) == 0) { return(null); } dllPath = dllPath.Replace("\\\\?\\", ""); PE.IMAGE_DOS_HEADER dosHeader = (PE.IMAGE_DOS_HEADER)Marshal.PtrToStructure(mem, typeof(PE.IMAGE_DOS_HEADER)); PE.IMAGE_FILE_HEADER fileHeader = (PE.IMAGE_FILE_HEADER)Marshal.PtrToStructure(new IntPtr(mem.ToInt64() + dosHeader.e_lfanew), typeof(PE.IMAGE_FILE_HEADER)); UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100; IntPtr entryPoint; if ((fileHeader.Characteristics & IMAGE_FILE_32BIT_MACHINE) == IMAGE_FILE_32BIT_MACHINE) { PE.IMAGE_OPTIONAL_HEADER32 optionalHeader = (PE.IMAGE_OPTIONAL_HEADER32)Marshal.PtrToStructure (new IntPtr(mem.ToInt64() + dosHeader.e_lfanew + Marshal.SizeOf(typeof(PE.IMAGE_FILE_HEADER))), typeof(PE.IMAGE_OPTIONAL_HEADER32)); entryPoint = new IntPtr(optionalHeader.AddressOfEntryPoint + imageBase.ToInt32()); } else { PE.IMAGE_OPTIONAL_HEADER64 optionalHeader = (PE.IMAGE_OPTIONAL_HEADER64)Marshal.PtrToStructure (new IntPtr(mem.ToInt64() + dosHeader.e_lfanew + Marshal.SizeOf(typeof(PE.IMAGE_FILE_HEADER))), typeof(PE.IMAGE_OPTIONAL_HEADER64)); entryPoint = new IntPtr(optionalHeader.AddressOfEntryPoint + imageBase.ToInt64()); } if (ShouldBlockDLL(dllPath.ToString())) { Console.WriteLine($"[+] Blocked DLL {dllPath}"); byte[] retIns = new byte[1] { 0xC3 }; IntPtr bytesWritten; Console.WriteLine("[+] Patching DLL Entry Point at 0x{0:x}", entryPoint.ToInt64()); if (WinAPI.WriteProcessMemory(hProcess, entryPoint, retIns, 1, out bytesWritten)) { Console.WriteLine("[+] Successfully patched DLL Entry Point"); } else { Console.WriteLine("[!] Failed patched DLL Entry Point"); } } return(dllPath.ToString()); }