gpt4 book ai didi

.net - vb 2008 WriteProcessMemory() 返回 0

转载 作者:可可西里 更新时间:2023-11-01 11:38:12 27 4
gpt4 key购买 nike

你好我正在使用 vb 2008 这是我的部分代码:

Private Declare Function WriteProcessMemory Lib "kernel32" Alias "WriteProcessMemory" ( _
ByVal hProcess As Integer, _
ByVal lpBaseAddress As Integer, _
ByVal lpBuffer As Integer, _
ByVal nSize As Integer, _
ByVal lpNumberOfBytesWritten As Integer _
) As Integer

Dim proc() As Process = Process.GetProcessesByName("process")
If proc.Length = 0 Then Console.WriteLine("Process Not Found") : Exit Sub
Dim p = proc(0)
Dim pH As Integer = OpenProcess(PROCESS_ALL_ACCESS, 0, p.Id)
Dim address As Integer
address = &H98544
Dim memory As IntPtr
Call ReadProcessMemory(pH, address, memory, 4, 0)
Console.WriteLine(memory.ToString)
Dim data As Integer = 2000
Call WriteProcessMemory(pH, address, data, Len(data), 0&)

但是,WriteProcessMemory() 返回 0,并且值不会改变

解决方案:

<DllImport("kernel32", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function WriteProcessMemory( _
ByVal hProcess As IntPtr, _
ByVal lpBaseAddress As IntPtr, _
ByVal lpBuffer As Byte(), _
ByVal nSize As UInt32, _
ByRef lpNumberOfBytesWritten As UInt32 _
) As Boolean
End Function

Dim proc() As Process = Process.GetProcessesByName("process")
If proc.Length = 0 Then Console.WriteLine("Process Not Found") : Exit Sub
Dim p = proc(0)
Dim pH As Integer = OpenProcess(PROCESS_ALL_ACCESS, 0, p.Id)
Dim address As Integer
address = &H98544
Dim memory As IntPtr
Call ReadProcessMemory(pH, address, memory, 4, 0)
Console.WriteLine(memory.ToString)
Dim data() As Byte = BitConverter.GetBytes(2000)
Call WriteProcessMemory(pH, address, data, 4, 0&)

最佳答案

当您调用 Windows API 函数时,您必须自己实现错误检查代码。当出现问题时,它们不会像标准 .NET Framework 函数那样抛出异常。

所需的具体错误检查因功能而异。 (像这样的不一致正是 .NET 使用异常的原因。)检查文档是必不可少的。

WriteProcessMemory以一种相当常见的方式工作。返回值是 BOOL(Win32 库将其视为 bool 值的整数,其中 0 = FALSE 和 1 = TRUE)。如果函数失败,则返回值为 0 (FALSE)。如果成功,返回值为 1 (TRUE):

If the function succeeds, the return value is nonzero.

If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError. The function fails if the requested write operation crosses into an area of the process that is inaccessible.

当然,这里有趣的部分是我们被告知必须调用 GetLastError 函数才能确定函数失败的原因。部分是真的。 You only call GetLastError when you're writing unmanaged C++ code .在 .NET 中,您需要做一些其他事情。有两个步骤:

  1. SetLastError = True 标记 P/Invoke 签名,这会导致 CLR 自动调用 GetLastError 并保存其值。
  2. 调用Marshal.GetLastWin32Error检索该值。

因此,要对其进行调试,您需要像这样重写代码(使用标准的 P/Invoke 语法,而不是 VB 独有的更受限制的 Declare 关键字。网):

<DllImport("kernel32", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function WriteProcessMemory(
ByVal hProcess As Integer, _
ByVal lpBaseAddress As Integer, _
ByVal lpBuffer As Integer, _
ByVal nSize As Integer, _
ByVal lpNumberOfBytesWritten As Integer _
) As Integer
End Function

Dim proc() As Process = Process.GetProcessesByName("process")
If proc.Length = 0 Then Console.WriteLine("Process Not Found") : Exit Sub
Dim p = proc(0)
Dim pH As Integer = OpenProcess(PROCESS_ALL_ACCESS, 0, p.Id)
Dim address As Integer
address = &H98544
Dim memory As IntPtr
Call ReadProcessMemory(pH, address, memory, 4, 0)
Console.WriteLine(memory.ToString)
Dim data As Integer = 2000
If WriteProcessMemory(pH, address, data, Len(data), 0&) = 0 Then
' The function failed, so find out what the error was
MessageBox.Show("WriteProcessMemory failed with error " & Marshal.GetLastWin32Error)
End If

知道错误代码后,您可以在 list of System Error Codes 中查找它看看它是什么意思。


原来错误是编号 299,ERROR_PARTIAL_COPY,文档说这意味着:

Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

嗯,不是很有帮助...我希望你能得到更好的东西。 C'est la vie

您将需要掌握一些额外的知识才能解决该问题。文档中再次给出了提示。任何时候它说参数是一个“指针”(在 C++ 语法中用星号 * 表示),这意味着在 VB.NET 中,它需要被传递作为引用,而不是作为值。要指定某些内容作为引用传递,请使用 ByRef 关键字。当然,要按值传递,您需要指定默认的 ByVal 关键字。

此外,请注意,当文档说某物是句柄地址 时,您应该在VB.NET 中将其声明为IntPtr type。 , 而不是整数。 IntPtr 是特殊的,因为它的大小会发生变化,具体取决于底层操作系统是 32 位还是 64 位(不同于整数,整数是固定大小,无论您在什么平台上运行).即使这不会导致您的直接问题,但它在您编译 64 位代码时导致兼容性问题。

所以事实证明你的声明实际上是错误的。像这样重新声明它:

<DllImport("kernel32", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function WriteProcessMemory(
ByVal hProcess As IntPtr, _
ByVal lpBaseAddress As IntPtr, _
ByVal lpBuffer As Integer, _
ByVal nSize As Integer, _
ByRef lpNumberOfBytesWritten As Integer _
) As Integer
End Function

您可能还认为第三个参数 (lpBuffer) 应该是一个字节数组 (Byte()),因为它指定要写入的数据地址空间。

关于.net - vb 2008 WriteProcessMemory() 返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6001371/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com