【问题标题】:Send null terminated string as byte array to WriteProcessMemory() via P/Invoke通过 P/Invoke 将 null 终止的字符串作为字节数组发送到 WriteProcessMemory()
【发布时间】:2015-09-05 04:26:57
【问题描述】:

我的 P/Invoke WriteProcessMemory 方法目前看起来像这样:

        [DllImport("kernel32", SetLastError = true)]
        [return : MarshalAs(UnmanagedType.Bool)]
        static extern bool WriteProcessMemory(
            IntPtr hProcess,
            IntPtr baseAddress,
            byte[] bufferToWrite,
            uint numBytesToWrite,
            out IntPtr numBytesWritten
            );

我需要向bufferToWrite 参数发送一个字符串,但它需要一个byte[],所以我在传入之前将其转换为byte[]

我的问题是,由于 .NET 字符串不是以 null 结尾的,因此它不会将终止的 null 写入远程内存。如果我在非托管代码中执行此操作,我将分配字符串的长度 + 终止 null,并将所有内容放入分配的内存中,因为我正在阅读的“字符串”包含 null。但托管字符串不包含它。

也许我可以分配一个足够大的缓冲区来包含终止空值,然后再次调用WriteProcessMemory 来写入空值;或者我可以创建一个足够大的byte[] 来保存字符串+ null,将两者都写入数组,然后像这样传递它。

但是对于这个问题有更优雅的解决方案吗?

【问题讨论】:

    标签: c# interop pinvoke


    【解决方案1】:

    像这样声明一个重载:

    [DllImport("kernel32", SetLastError = true)]
    [return : MarshalAs(UnmanagedType.Bool)]
    static extern bool WriteProcessMemory(
        IntPtr hProcess,
        IntPtr baseAddress,
        string bufferToWrite,
        uint numBytesToWrite,
        out uint numBytesWritten
    );
    

    这样你强制编组器为空终止字符串。

    您可以将数据作为IntPtr 传递并使用Marshal.StringToPtrAnsi。但是你需要管理内存。

    如果文本是 Unicode,请使用 CharSet.Unicode 选项。

    【讨论】:

    • 如果我这样做,numBytesToWrite 是否应该考虑终止 null 的字节,即使当前 clr 字符串中不存在这么多字节?
    • 编组器会将string 编组为指向以空字符结尾的字符数组的指针。您可以而且应该考虑 numBytesToWrite 中的空终止符
    • 太好了,这正是我正在寻找的解决方案。
    【解决方案2】:

    您还可以分配字符串加上一个空终止符。例如。如果你想写字符串

    string szToWrite = "This is what I want to write";
    

    我会通过例如将它转换为byte[]使用 ASCII 转换

    byte[] aBytes = Encoding.ASCII.GetBytes(szToWrite);
    

    然后将它与一个额外的空字节连接起来。

    aBytes = aBytes.Concat(new byte[] { 0x00 }).ToArray();
    

    如果您愿意,可以创建自己的函数WriteProcessMemoryString,让它接受string 而不是byte[],并使用与上述相同的概念。另请注意,您可能希望使用与 ASCII 不同的编码,例如UTF7/UTF8,或任何您本机需要的东西(例如宽字符串)。

    【讨论】:

    • 是的,这基本上是我考虑过的选项之一,我只是希望得到比手动附加空值少一点的东西。我想正如你所说,我可以创建一个函数并让它处理字符串转换+附加空值。我会稍等一下,看看有没有其他人有更多的想法......
    猜你喜欢
    • 1970-01-01
    • 2020-02-27
    • 2012-08-10
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多