你好,我正在使用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&)
发布于 2011-05-14 11:16:59
当您调用Windows函数时,必须自己实现错误检查代码。当出现诸如标准.NET框架函数之类的错误时,它们不会抛出异常。
所需的特定错误检查取决于函数的不同。(这正是.NET使用异常的原因。)检查文档是非常重要的。
WriteProcessMemory
的工作方式是相当常见的。返回值是BOOL
( Win32库将其视为布尔值的整数,其中0= FALSE和1= TRUE)。如果函数失败,则返回值为0 (FALSE)。如果成功,则返回值为1 (TRUE):
如果函数成功,则返回值为非零。 如果函数失败,则返回值为0(零)。要获得扩展的错误信息,请调用
GetLastError
。如果请求的写操作跨入进程中无法访问的区域,则函数将失败。
当然,有趣的是,我们被告知我们必须调用GetLastError
函数,以确定函数失败的原因。部分是真的。当您编写非托管C++代码时。在.NET中,您需要做一些其他的事情。有两个步骤:
SetLastError = True
标记P/Invoke签名,这将使CLR自动调用GetLastError
并保存其值。Marshal.GetLastWin32Error
来检索该值。因此,要调试它,您需要像这样重写代码(使用标准的P/Invoke语法,而不是VB.NET特有的更有限的VB.NET关键字):
<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
一旦您知道了错误代码,就可以在系统错误码列表中查找它,以了解它的含义。
结果,错误是299号,ERROR_PARTIAL_COPY
,文档中说这意味着:
只完成了ReadProcessMemory或WriteProcessMemory请求的一部分。
嗯,没什么用.我希望你能得到更好的东西。拉维先生。
为了解决这个问题,你必须有一些额外的知识。文档中再次给出了提示。当它说参数是“指针”(用C++语法表示,星号为*
)时,这意味着在VB.NET中,它需要作为引用传递,而不是作为值传递。若要指定将某物作为引用传递,请使用ByRef
关键字。当然,要按值传递,可以指定默认的ByVal
关键字。
此外,请注意,当文档显示某物是句柄或地址时,您应该在VB.NET中将其声明为类型,而不是整数。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()
),因为它指定要写入地址空间的数据。
发布于 2011-05-14 11:13:08
文档指出:
如果函数失败,则返回值为0(零)。要获得扩展的错误信息,请调用GetLastError。如果请求的写操作跨入进程中无法访问的区域,则函数将失败。
我建议你照它说的去找出失败的原因。
指出这一点后,失败的原因似乎很可能是您试图写入的地址2000在此过程中不是有效的地址。
lpBuffer
参数是一个指针,您将整数值2000作为该参数传递。因此,这将被解释为一个内存地址。我怀疑你实际上是想传递data
的地址。
https://stackoverflow.com/questions/6001371
复制相似问题