我有
Private Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
但我也需要
Private Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Single, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
以及其他一些变化。因此,如上例所示,lpBuffer为Single而不是Integer。我怎样才能做到这一点?
更新:好的,现在我正在这样做:
Imports System.Math
Imports System.Threading
Imports System.Runtime.InteropServices
Public Class Form1
'Declare ReadProcessMemory with lpBuffer As IntPtr
Private Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Integer, ByVal lpBaseAddress As Integer, ByRef lpBuffer As IntPtr, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
'This is the function I am now having trouble with
Public Function memfloat(ByVal address As Long, ByVal processHandle As IntPtr)
Dim floatvalueinmemory As Single
ReadProcessMemory(processHandle, address, floatvalueinmemory, 4, 0)
Dim letstryagain As Single 'floatvalueinmemory didn't give the desired result, so going to try to TryParse
Single.TryParse(floatvalueinmemory, letstryagain)
Return CStr(letstryagain) 'returns the same result as floatvalueinmemory did
End Function
End Class
Partial Public Class NativeMethods
<DllImport("user32.dll")> _
Public Shared Function ReadProcessMemory(ByVal hProcess As System.IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As System.IntPtr, ByVal nSize As UInteger, ByVal lpNumberOfBytesRead As IntPtr) As Boolean
End Function
End Class
memfloat函数用于返回类似“-75,48196”的内容,现在它返回类似“-1,012555E + 09”的内容(实际值不匹配,仅使用这些作为示例),这是为什么我想首先声明多次..如何从IntPtr转换为Single?
的作用是:
Public Function memstring(ByVal address As Long, ByVal length As Int32, ByVal processHandle As IntPtr)
Dim stringinmemory As Long
Dim ret1 As Byte() = Nothing
Dim tStr(length) As Char
Dim retStr As String = ""
For i As Int32 = 0 To length - 1
ReadProcessMemory(processHandle, address + i, stringinmemory, 1, 0)
ret1 = BitConverter.GetBytes(stringinmemory)
tStr(i) = System.Text.Encoding.ASCII.GetString(ret1) : retStr += tStr(i)
Next
Return retStr
End Function
这正确地将内存值作为字符串返回。所以,是的,现在只是造成问题的单身。
答案 0 :(得分:2)
无论如何,您正在使用Alias
关键字,因此请充分利用它:
Private Declare Function ReadProcessMemoryInt Lib "kernel32" _
Alias "ReadProcessMemory" (ByVal hProcess As Integer, _
ByVal lpBaseAddress As Integer, _
ByRef lpBuffer As Integer, _
ByVal nSize As Integer, _
ByRef lpNumberOfBytesWritten As Integer) As Integer
Private Declare Function ReadProcessMemorySingle Lib "kernel32" _
Alias "ReadProcessMemory" (ByVal hProcess As Integer, _
ByVal lpBaseAddress As Integer, _
ByRef lpBuffer As Single, _
ByVal nSize As Integer, _
ByRef lpNumberOfBytesWritten As Integer) As Integer
您为该函数指定的名称可以是任意的。只有Alias
名称必须与库中的名称匹配。在您的代码中,您可以参考ReadProcessMemoryInt
和ReadProcessMemorySingle
(或您选择的任何名称)。
(注意:我没有检查您是否正确使用了API,我刚刚回答了有关如何使用不同签名定义相同API函数两次的问题。)
答案 1 :(得分:1)
我启动了P/Invoke Interop Assistant
工具(link),找到了ReadProcessMemory
并在vb.net
中生成了签名:
Partial Public Class NativeMethods
'''Return Type: BOOL->int
'''hProcess: HANDLE->void*
'''lpBaseAddress: LPCVOID->void*
'''lpBuffer: LPVOID->void*
'''nSize: SIZE_T->ULONG_PTR->unsigned int
'''lpNumberOfBytesRead: SIZE_T*
<System.Runtime.InteropServices.DllImportAttribute("kernel32.dll", EntryPoint:="ReadProcessMemory")> _
Public Shared Function ReadProcessMemory(<System.Runtime.InteropServices.InAttribute()> ByVal hProcess As System.IntPtr, <System.Runtime.InteropServices.InAttribute()> ByVal lpBaseAddress As System.IntPtr, ByVal lpBuffer As System.IntPtr, ByVal nSize As UInteger, ByVal lpNumberOfBytesRead As System.IntPtr) As <System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)> Boolean
End Function
End Class
因此,您需要将缓冲区IntPtr
转换为各种类型的数组。我建议你研究Marshal
类及其静态方法。此处还有指向相关文章SO link,url 1,url 2的链接。可能需要从c#到vb.net的翻译。我还注意到这些在线示例中的函数定义可能会被重载(让我感到惊讶)。