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).
Related
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.
i write this code to change default printer in windows and work fine but in reload the INI file have a error
this is a code :
Private Sub SetDefaultPrinter(ByVal PrinterName As String, ByVal DriverName As String, ByVal PrinterPort As String)
Dim DeviceLine As String
'rebuild a valid device line string
DeviceLine = PrinterName & "," & DriverName & "," & PrinterPort
'Store the new printer information in the
'[WINDOWS] section of the WIN.INI file for
'the DEVICE= item
Call WriteProfileString("windows", "Device", DeviceLine)
'Cause all applications to reload the INI file
Call SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, "windows")
End Sub
Private Declare Function WriteProfileString Lib "kernel32" Alias "WriteProfileStringA" (ByVal lpszSection As String, ByVal lpszKeyName As String, ByVal lpszString As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lparam As String) As Long
Private Const HWND_BROADCAST As Long = &HFFFF&
Private Const WM_WININICHANGE As Long = &H1A
and this is a error :
A call to PInvoke function 'Test!Test.Form2::SendMessage' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
Does anyone have an idea to solve this problem?
Thankful
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lparam As String) As Long
Your data types are wrong. The hwnd parameter is pointer sized, wMsg is a 32 bit value, and wParam, lParam and the return value are pointer sized. Note that Long is a 64 bit type.
Instead it should be
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, _
ByVal lparam As String) As IntPtr
Note that I recommend that, in the modern day, you use pinvoke declarations rather than Declare. This offer much more flexibility.
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).
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
<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