1

我想将 Python 代码注入到一个进程中,它似乎在注入时使我的进程崩溃。我自己的程序没有出现任何错误,但目标进程停止工作。调用的非托管 API 没有给我任何错误,并且似乎已正确执行它们。

[DllImport("kernel32")]
    public static extern IntPtr CreateRemoteThread(IntPtr hProcess,IntPtr lpThreadAttributes,uint dwStackSize, IntPtr lpStartAddress,IntPtr lpParameter,uint dwCreationFlags, out uint lpThreadId);
    [Flags]
    enum ProcessAccessFlags : uint
    {
        All = 0x001F0FFF,
        Terminate = 0x00000001,
        CreateThread = 0x00000002,
        VMOperation = 0x00000008,
        VMRead = 0x00000010,
        VMWrite = 0x00000020,
        DupHandle = 0x00000040,
        SetInformation = 0x00000200,
        QueryInformation = 0x00000400,
        Synchronize = 0x00100000
    }
    [DllImport("kernel32.dll")]
    static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
    [Flags]
    public enum AllocationType
    {
        Commit = 0x1000,
        Reserve = 0x2000,
        Decommit = 0x4000,
        Release = 0x8000,
        Reset = 0x80000,
        Physical = 0x400000,
        TopDown = 0x100000,
        WriteWatch = 0x200000,
        LargePages = 0x20000000,
        VIRTUAL_MEM = (0x1000 | 0x2000)
    }
    [Flags]
    public enum MemoryProtection
    {
        Execute = 0x10,
        ExecuteRead = 0x20,
        ExecuteReadWrite = 0x40,
        ExecuteWriteCopy = 0x80,
        NoAccess = 0x01,
        ReadOnly = 0x02,
        ReadWrite = 0x04,
        WriteCopy = 0x08,
        GuardModifierflag = 0x100,
        NoCacheModifierflag = 0x200,
        WriteCombineModifierflag = 0x400,
        PAGE_EXECUTE_READWRITE = 0x00000040
    }
    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
    static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, AllocationType flAllocationType, MemoryProtection flProtect);
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);
    [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
    static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint dwFreeType);
    [DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
    internal static extern Int32 WaitForSingleObject( IntPtr handle,Int32 milliseconds);
    [DllImport("kernel32.dll")]
    public static extern Int32 CloseHandle(IntPtr hObject);
    private void InjectCode(string shellcode = "print('Hello, World!')")
    {
        foreach (Process proc in Process.GetProcesses())
        {
            if (proc.ProcessName == "Toontown")
            {
                int shellcode_length = shellcode.Length;
                IntPtr h_process = OpenProcess(ProcessAccessFlags.All, false, (int)proc.Id);
                IntPtr shellcode_address = (IntPtr)VirtualAllocEx(h_process, (IntPtr)0, (uint)shellcode_length, AllocationType.VIRTUAL_MEM, MemoryProtection.PAGE_EXECUTE_READWRITE);
                byte[] bytes = new byte[shellcode.Length * sizeof(char)];
                Buffer.BlockCopy(shellcode.ToCharArray(), 0, bytes, 0, bytes.Length);

                UIntPtr bytesout;
                uint t_id;

                bool Written = WriteProcessMemory(h_process, shellcode_address, bytes, (uint)shellcode_length, out  bytesout);
                IntPtr hThread = (IntPtr)CreateRemoteThread(h_process, (IntPtr)null, 0, (IntPtr)shellcode_length, (IntPtr)shellcode_address, 0, out t_id);
                int Result = WaitForSingleObject(hThread, 10 * 1000);
                if (Result == 0x00000080L || Result == 0x00000102L || Result == 0xFFFFFFFF)
                {
                    if (hThread != null)
                    {
                        CloseHandle(hThread);
                    }
                }
                Thread.Sleep(1000);
                VirtualFreeEx(h_process, shellcode_address, (UIntPtr)0, 0x8000);
                if (hThread != null)
                {
                    CloseHandle(hThread);
                }
            }
        }
    }

如您所见,我已将非托管 API 的返回值保存到我用来查看它是否正常工作的变量中,它似乎做得很好,但它使目标进程崩溃,日志没有记录任何相关的错误给它。托管程序可以注入非托管进程吗?我是否在转换错误的变量类型?shellcode 是否被错误地翻译成字节数组?请让我知道,谢谢。

编辑:它在 CreateRemoteThread 崩溃

4

2 回答 2

1

CreateRemoteThread在另一个进程中创建一个本地线程,它接收到的起始地址必须指向有效的机器代码,否则线程将导致进程崩溃。

您描述的场景不同,您想指示另一个进程的 Python 解释器执行一些代码。这是可以做到的,但它是不同的,而且要困难得多。

将本机库注入到执行两件事的另一个进程中:

  • 设置 Python 解释器
  • 设置一些进程间通信(IPC)的方式

使用 IPC 将您想要执行的 Python 代码发送到其他进程,然后您注入的库中的代码使用 Python 解释器执行该代码。

您可以在这篇 Codeproject 文章中找到如何将 DLL 注入另一个进程的示例。

于 2013-02-10T13:18:46.847 回答
0

看起来您正试图从 .net 运行一些任意 Python 代码。现在您正在尝试调用 Python 解释器来实际执行此操作。

这样做的缺点是:-

  • 如您所见,这很复杂。
  • 当您跨边界移动字节时,进程间通信变得更加困难
  • 然后,您需要将从每一方获得的信息解析为有意义的内容(可能使用某种 XML)
  • 最后,由于上述所有开销,它的速度很慢

现在解决这个问题的一种方法是直接在 .net 中调用 python 程序。现在我这辈子从来没有这样做过,我也从来没有见过蟒蛇(除了可能发出嘶嘶声的那种)。看看http://msdn.microsoft.com/en-us/library/ee461504.aspx,不幸的是,看起来他们将 python 存储在一个文件中并在那里调用它。但是我确信您可以调用存储为字符串的代码。

使用 python 的 DLR 实现的主要缺点是您依赖第三方来获得正确的 Python -> CLR 翻译。但我认为 IronPython 是微软赞助的开源项目。

有关更多信息,请参阅:http: //ironpython.codeplex.com/

于 2013-02-10T18:45:37.540 回答