Hello, I have the problem of reading and writing values in addresses of a process of the type "7FFFFFFFFFFFF" that exceeds the maximum capacity of long
For this I use "ReadProcessMemory" and "writeProcessMemory", which does not present any problem for 32-bit processes. Since the LongLong datatype is not available for vb6, I have confirmed from vba that "ReadProcessMemory" and "writeProcessMemory" work using longlong with no problem.
Since I need to address this in vb6, I have found out that by using a "variant" and using "VariantChangeTypeEx" we can transform our data type to a longlong without problems (Verified with vartype = 20)
My problem is that in the declaration of the read write function I don't know how to carry the longlong transformed for lpBaseAddress.
If I try to declare it like this, vb6 closes.
"Private Declare Function ReadProcessMem Lib" kernel32 "Alias" ReadProcessMemory "(ByVal hProcess As Long, ByVal lpBaseAddress As Variant, ByRef lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long"
Also in this way
"Private Declare Function ReadProcessMem Lib" kernel32 "Alias" ReadProcessMemory "(ByVal hProcess As Long, ByVal lpBaseAddress, ByRef lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long"
From vba (vb7) check that the previous statements do not make it work, however if we define it as longlong it works.
I found a class module that allows me to create longlong variables, but I also can't find a way to write the declaration as "lpBaseAddress as LongLong"
since it asks me to create the object and I can't use new on the same line.
Could this have a solution? or another alternative to read and write values to 64-bit process addresses that exceed the long.
Re: Help when using a longlong for ReadProcessMemory
you can not change api declarations types. The dll expects a very specific type of data to be passed.
I think trick gave you a solution to do reads to an x64 address space in your other thread. Looks like there
is a NtWow64WriteVirtualMemory64 function as well. The functions themselves will just return a success or error code,
Re: Help when using a longlong for ReadProcessMemory
NtWow64ReadVirtualMemory64 worked fine for me, forgive the added dependencies..see src for links
edit:
added write example but it requires an address in a writable memory section (such as stack address)
I did not see a 32 bit callable, 64 bit enabled, VirtualProtectEx to change memory permissions
If you have to really do writes I would just write a small x64 helper app which receives args on the
command line and spits out results.
I would not want to get into heavens gate from the 32 bit vb side just to run the 64 bit version of NtProtectVirtualMemory
Re: Help when using a longlong for ReadProcessMemory
Ok, a few different things. For one, the LongLong is available in VB6, but only when stuffed into a Variant, and it takes some API work to even get that done. Here's some info about that. There are some other caveats to that, and I'd recommend reading that entire thread.
On another point, VB6 has the Currency type (as one of its native types, no need for Variant). A Currency is basically a two's complement LongLong, but, when used in VB6, a forced decimal point is placed in the fourth decimal position. However, knowing this, a Currency can be passed to a DLL (and vice-versa) expecting a LongLong, and it'll work just fine. We just have to take care in the way we treat it while in VB6. One possibility is to ignore the forced decimal point, and move these Currency types into Decimal types (via a Variant) when we need to know their true integer values. Here are procedures for doing precisely that.
Maybe that'll help.
Last edited by Elroy; Oct 15th, 2021 at 09:35 AM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: Help when using a longlong for ReadProcessMemory
Originally Posted by dz32
NtWow64ReadVirtualMemory64 worked fine for me, forgive the added dependencies..see src for links
edit:
added write example but it requires an address in a writable memory section (such as stack address)
I did not see a 32 bit callable, 64 bit enabled, VirtualProtectEx to change memory permissions
If you have to really do writes I would just write a small x64 helper app which receives args on the
command line and spits out results.
I would not want to get into heavens gate from the 32 bit vb side just to run the 64 bit version of NtProtectVirtualMemory
Wow, your example is excellent! You really pulled me out of a hole.
This is all I needed.
Thanks a lot dz32!
Last edited by Maatooh; Oct 15th, 2021 at 01:57 PM.
Re: Help when using a longlong for ReadProcessMemory
Originally Posted by Elroy
Ok, a few different things. For one, the LongLong is available in VB6, but only when stuffed into a Variant, and it takes some API work to even get that done. Here's some info about that. There are some other caveats to that, and I'd recommend reading that entire thread.
On another point, VB6 has the Currency type (as one of its native types, no need for Variant). A Currency is basically a two's complement LongLong, but, when used in VB6, a forced decimal point is placed in the fourth decimal position. However, knowing this, a Currency can be passed to a DLL (and vice-versa) expecting a LongLong, and it'll work just fine. We just have to take care in the way we treat it while in VB6. One possibility is to ignore the forced decimal point, and move these Currency types into Decimal types (via a Variant) when we need to know their true integer values. Here are procedures for doing precisely that.
Maybe that'll help.
Thank you very much for all the information, what you document is very useful to me. having found out about the possibility of longlong in vb6 was a great surprise and I will try to follow the path you indicate, you enlightened my mind with possibilities.
regards!
Re: Help when using a longlong for ReadProcessMemory
Originally Posted by dz32
NtWow64ReadVirtualMemory64 worked fine for me, forgive the added dependencies..see src for links
edit:
added write example but it requires an address in a writable memory section (such as stack address)
I did not see a 32 bit callable, 64 bit enabled, VirtualProtectEx to change memory permissions
If you have to really do writes I would just write a small x64 helper app which receives args on the
command line and spits out results.
I would not want to get into heavens gate from the 32 bit vb side just to run the 64 bit version of NtProtectVirtualMemory
The project is excellent, but now I have had a problem with writing for 8 bytes with very long values, like "124411939811874204", how could I repair it?
The reading is correct for these very long values, but since doing the inverse that exceeds the long variable, I have tried to use the ulong64 class module but when trying to write the data they are wrong.
Thank you! their help has been fundamental and very useful.
Last edited by Maatooh; Nov 18th, 2021 at 03:50 AM.
Re: Help when using a longlong for ReadProcessMemory
try
Code:
Dim writeVal As New ULong64, c as currency
If Not writeVal.fromString("124411939811874204", mUnsigned) Then
MsgBox "Failed to convert x64 write value from string"
Exit Sub
End If
c = writeVal.rawValue 'dont use varptr(writeVal.rawValue) directly as its a property get
retCode = WriteMem64(VarPtr(c), addr.rawValue, 8, written)
Note that if the memory is not writable the value will not change. You may have to find a way to call
VirtualProtectEx on the 64 bit process from the 32bit process. I am not sure if Microsoft was kind enough to
provide new 32bit api to allow VirtualProtectEx calls with 64 bit address arguments.
I can not help further on this. I would use a 64 bit command line exe to do the dirty work.
Re: Help when using a longlong for ReadProcessMemory
Originally Posted by dz32
try
Code:
Dim writeVal As New ULong64, c as currency
If Not writeVal.fromString("124411939811874204", mUnsigned) Then
MsgBox "Failed to convert x64 write value from string"
Exit Sub
End If
c = writeVal.rawValue 'dont use varptr(writeVal.rawValue) directly as its a property get
retCode = WriteMem64(VarPtr(c), addr.rawValue, 8, written)
Note that if the memory is not writable the value will not change. You may have to find a way to call
VirtualProtectEx on the 64 bit process from the 32bit process. I am not sure if Microsoft was kind enough to
provide new 32bit api to allow VirtualProtectEx calls with 64 bit address arguments.
I can not help further on this. I would use a 64 bit command line exe to do the dirty work.