internal T CallRoutine <T>(IntPtr routineAddress, params dynamic[] arguments) where T : unmanaged { var returnSize = typeof(T) == typeof(IntPtr) ? Architecture == Architecture.X86 ? sizeof(int) : sizeof(long) : Unsafe.SizeOf <T>(); var returnAddress = Process.AllocateBuffer(returnSize, ProtectionType.ReadWrite); try { // Assemble the shellcode used to call the routine Span <byte> shellcodeBytes; if (Architecture == Architecture.X86) { var descriptor = new CallDescriptor <int>(routineAddress, Array.ConvertAll(arguments, argument => (int)argument), returnAddress); shellcodeBytes = Assembler.AssembleCall32(descriptor); } else { var descriptor = new CallDescriptor <long>(routineAddress, Array.ConvertAll(arguments, argument => (long)argument), returnAddress); shellcodeBytes = Assembler.AssembleCall64(descriptor); } ExecuteShellcode(shellcodeBytes); // Read the return value if (typeof(T) != typeof(IntPtr)) { return(Process.ReadStruct <T>(returnAddress)); } var pointer = Architecture == Architecture.X86 ? UnsafeHelpers.WrapPointer(Process.ReadStruct <int>(returnAddress)) : UnsafeHelpers.WrapPointer(Process.ReadStruct <long>(returnAddress)); return(Unsafe.As <IntPtr, T>(ref pointer)); } finally { Executor.IgnoreExceptions(() => Process.FreeBuffer(returnAddress)); } }
internal void InsertListEntry(IntPtr listAddress, IntPtr listEntryAddress) { if (Architecture == Architecture.X86) { // Read the list entry var listHead = Process.ReadStruct <ListEntry32>(listAddress); var listTailAddress = UnsafeHelpers.WrapPointer(listHead.Blink); var listTail = Process.ReadStruct <ListEntry32>(listTailAddress); // Insert the entry into the list if (listAddress == listTailAddress) { Process.WriteStruct(listAddress, new ListEntry32(listEntryAddress.ToInt32(), listEntryAddress.ToInt32())); } else { Process.WriteStruct(listAddress, listHead with { Blink = listEntryAddress.ToInt32() });
internal IntPtr GetHeapAddress() { if (Architecture == Architecture.X86) { // Read the process WOW64 PEB var pebAddress = Process.QueryInformation <IntPtr>(ProcessInformationType.Wow64Information); var peb = Process.ReadStruct <Peb32>(pebAddress); return(UnsafeHelpers.WrapPointer(peb.ProcessHeap)); } else { // Read the process PEB var basicInformation = Process.QueryInformation <ProcessBasicInformation64>(ProcessInformationType.BasicInformation); var pebAddress = UnsafeHelpers.WrapPointer(basicInformation.PebBaseAddress); var peb = Process.ReadStruct <Peb64>(pebAddress); return(UnsafeHelpers.WrapPointer(peb.ProcessHeap)); } }