ReadProcessMemory declaration - vb.net

I currently have it defined as
Private Declare Function ReadProcessMemory1 Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByRef lpBuffer As Integer, ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As Integer
and I have another declaration for each type.
I'm trying to use this instead
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Shared Function ReadProcessMemory( _
ByVal hProcess As IntPtr, _
ByVal lpBaseAddress As Integer, _
<Out()> ByRef lpBuffer As Byte(), _
ByVal dwSize As Integer, _
ByRef lpNumberOfBytesRead As Integer) As Boolean
End Function
Which is off pvinvoke.net, heres how I'm trying to use it:
Public Shared Function Int(address As Integer)
Dim buffer(3) As Byte
ReadProcessMemory(pHandle, address, buffer, 4, 0)
Return BitConverter.ToInt32(buffer, 0)
End Function
This errors and says Attempt to read or write protected memory, but I use the old RPM declaration I have like this and it works fine.
Public Shared Function Int(address As Integer)
Dim buffer As Integer
ReadProcessMemory(pHandle, address, buffer, 4, 0)
Return buffer
End Function
What am I doing wrong?

Your p/invoke declaration is wrong. It should be:
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Shared Function ReadProcessMemory( _
ByVal hProcess As IntPtr, _
ByVal lpBaseAddress As IntPtr, _
<Out()> ByVal lpBuffer As Byte(), _
ByVal dwSize As IntPtr, _
ByRef lpNumberOfBytesRead As IntPtr) As Boolean
End Function

Related

How can I call class functions from a Form?

Public Class gFunctions
Public Function gSerialPortWrite(ByVal msg As String, comport As Object)
SerialPort1.Write(msg)
End Function
'Pinvoke.Net stackoverflow.com/questions/11238898/reading-from-an-ini-file
Public Declare Auto Function GetPrivateProfileString Lib "kernel32" (ByVal lpAppName As String,
ByVal lpKeyName As String,
ByVal lpDefault As String,
ByVal lpReturnedString As StringBuilder,
ByVal nSize As Integer,
ByVal lpFileName As String) As Integer
Public Declare Auto Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" _
(ByVal lpSectionName As String,
ByVal lpKeyName As String,
ByVal lpValue As String,
ByVal lpFilename As String) As Integer
End Class
How do I call these functions in my form1.vb if I place them in my class1.vb? thanks for any help or added information. New to Visual Studio, although I have experience with VB in Excel. In Excel I just added another module.bas.

'System.Runtime.InteropServices.DllImportAttribute' cannot be applied to instance method

I'm trying to use some winapi methods. how ever, when I try to use the function I get the following error:
'System.Runtime.InteropServices.DllImportAttribute' cannot be applied to instance method.
code:
Public Class Anti
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAdress As Integer, ByRef lpBuffer As Integer, ByVal nSize As Integer, Optional ByRef lpNumberOfBytesRead As Integer = 0) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Sub ZeroMemory(ByVal handle As IntPtr, ByVal length As UInt32)
End Sub
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Function VirtualProtect(ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal flNewProtect As Integer, ByRef lpflOldProtect As UInteger) As Boolean
End Function
Public Sub AntiDump()
Try
Dim x(0) As Process
Well, the message is pretty clear. Methods that you apply the DllImport attribute to must be class methods (shared).

Access Violation Exception RegEnumValue

I'm using this code to enumerate all values in a registry key.
Private ReadOnly HKeyLocalMachine As New IntPtr(-2147483646)
Private Const KeyQueryValueWow64Key As Integer = &H101
Private Const ErrorNoMoreItems As Integer = &H103
Private Const errorSuccess As Integer = &H0
Dim keyHandle As IntPtr = Nothing
RegOpenKeyEx(HKeyLocalMachine, newPath, 0, KeyQueryValueWow64Key, keyHandle)
If keyHandle = Nothing Then
Return "Error accessing registry key"
End If
Dim index As Integer = 0
Dim valueName As New StringBuilder(1000)
Dim valueLenght As UInteger
Dim valueDataLenght As IntPtr
If RegQueryInfoKey(keyHandle, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, valueLenght, valueDataLenght, Nothing, Nothing) = errorSuccess Then
Debug.WriteLine("SUCCESS IN REGQUERYINFOKEY")
End If
Do
returnValue = RegEnumValue(keyHandle, index, valueName, valueLenght, Nothing, Nothing, datalenght, valueDataLenght)
If returnValue = errorSuccess Then
Debug.WriteLine("Success")
End If
index = index + 1
Loop Until returnValue = ErrorNoMoreItems
Here are my API declarations:
<DllImport("advapi32.dll", CharSet:=CharSet.Unicode)> _
Private Shared Function RegOpenKeyEx( _
hKey As IntPtr, _
subKey As String, _
ulOptions As Integer, _
samDesired As Integer, _
ByRef hkResult As IntPtr _
) As Integer
End Function
<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function RegEnumValue( _
ByVal hKey As IntPtr, _
ByVal dwIndex As Integer, _
ByVal lpValueName As StringBuilder, _
ByRef lpcValueName As UInteger, _
ByVal lpReserved As IntPtr, _
ByVal lpType As IntPtr, _
ByVal lpData As IntPtr, _
ByVal lpcbData As IntPtr _
) As Integer
End Function
<DllImport("advapi32.dll")> _
Private Shared Function RegQueryInfoKey( _
hkey As IntPtr, _
ByRef lpClass As StringBuilder, _
ByRef lpcbClass As UInteger, _
lpReserved As IntPtr, _
ByRef lpcSubKeys As UInteger, _
ByRef lpcbMaxSubKeyLen As UInteger, _
ByRef lpcbMaxClassLen As UInteger, _
ByRef lpcValues As UInteger, _
ByRef lpcbMaxValueNameLen As UInteger, _
ByRef lpcbMaxValueLen As IntPtr, _
ByRef lpcbSecurityDescriptor As UInteger, _
lpftLastWriteTime As IntPtr _
) As Integer
End Function
And i'm getting AccessViolationException when i pass the last parameter of RegEnumValue non-null, if i pass a null IntPtr the function succeeds but no data is retrieved, only the name.
I've tried changing the API variables with no luck, the other two functions always succeed.
The reason that the code fails is that you did not initialise valueDataLenght. Incidentally, you mean to name this variable valueDataLength.
You need the IntPtr variable valueDataLength to refer to a DWORD that contains the length of the data buffer. Using IntPtr here makes life difficult for you. I'd declare the parameter like this instead:
ByRef lpcbData As Integer

How do I declare IEGetProtectedModeCookie in vb.net?

<DllImport("ieframe.dll", EntryPoint:="IEGetProtectedModeCookie")> _
Public Function IEGetProtectedModeCookie( _
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal lpszURL As String, _
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal lpszCookieName As String, _
<MarshalAs(UnmanagedType.LPWStr)> ByVal pszCookieData As StringBuilder, _
ByRef pcchCookieData As UInteger, _
ByVal dwFlags As UInteger) As Integer
End Function
First of all this seems to be very different than my regular API declaration
Declare Function InternetGetCookieEx Lib "wininet.dll" Alias "InternetGetCookieExA" (ByVal pchURL As String, ByVal pchCookieName As String, ByVal pchCookieData As String, ByRef pcchCookieData As System.UInt32, ByVal dwFlags As System.UInt32, ByVal lpReserved As Integer) As Boolean
Moreoever it simply doesn't compile. StringBuilder is not defined. MarshalAs is not defined. In is not define. I wonder what I should include or import to make them work.
This is the .Net way of declaring API functions.
(Declare Function was inherited from VB6)
You need to import System.Text and System.Runtime.InteropServices

Multiple ByVal type declarations

I have
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
But I also need
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
And some other variations. So, as in the example above, lpBuffer as Single instead of Integer. How can I achieve this?
UPDATE: Alrighty, now I'm doing this:
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
The memfloat function used to return something like "-75,48196", now it returns something like "-1,012555E+09" (the actual values don't match, just using these as an example), this is why I wanted to declare multiple times in the first place.. how do I convert from the IntPtr to a Single ?
What does work is:
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
This correctly returns the memory value as string. So yeah, now it's just the Single that's causing issues.
You are using the Alias keyword anyway, so take advantage of it:
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
The name you give to the function can be arbitrary. Only the Alias name must match the name in the library. In your code, you can refer to ReadProcessMemoryInt and ReadProcessMemorySingle (or whatever name you chose).
(Note: I didn't check whether you are actually using the API correctly, I've just answered your question about how to define the same API function twice with different signatures.)
I fired up the P/Invoke Interop Assistant tool (link), found ReadProcessMemory and generated the signature in vb.net as:
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
So the bufffer is IntPtr that you need to convert into an array of various types. I suggest you look into the Marshal class and its static methods. Also here are links to possible relevant articles SO link,url 1,url 2. Translation from c# to vb.net may be needed. I also noticed on these online examples that the function definition can be overloaded (which surprised me).