Posts: 714
Threads: 36
Joined: May 2022
Reputation:
13
Has anyone ever dealt with pointers in Basic?
Actually there are no pointers in Basic like in C, but maybe they can be imitated. I've tried this now with
VarPtr, Peek and
Poke , and I didn't find any error in my exercise to achieve this. I don't see any at the moment either. Access to the memory address is basically like in C, and I can also change the content.
Pointers are a powerful, but also dangerous, tool in C! One could definitely good use them in Basic too. I think so.
I would be grateful to anyone who is interested and takes a look at the program if they could point out whether and if so, where I made a mistake in my thinking.
The explanations/comments are of course in German, so I can understand what's going on.
Code: (Select All)
'Zeigerbeispiel in Basic - 16. Juli 2023
'Mit VarPtr und Peek und Poke ist es moeglich Zeiger in
'Basic nachzuahmen.
$Console:Only
Option _Explicit
Dim As Long zahl1, zahl2, wert, wert2
Dim As Long speicherAdresse, speicherAdresse2
Locate 2, 3
Input "Zahl 1: ", zahl1
Locate 3, 3
Input "Zahl 2: ", zahl2
Locate 5, 3
Print Using "Zeige Zahl 1: ### -- Zahl 2: ### "; zahl1, zahl2
'Adresse der Zahl im Speicher ermitteln
speicherAdresse = VarPtr(zahl1)
'Speicheradresse anzeigen
Locate 6, 3
Print "Speicheradress Zahl 1: ", speicherAdresse
'wert wird der Inhalt der Speicheradresse zugewiesen
wert = Peek(speicherAdresse)
Locate 8, 3
Print "Inhalt der Speicheradresse: ", wert
'wert erhoehen
wert = wert * 2
'Neuen Wert in die Speicheradresse einfuegen
Poke (speicherAdresse), wert
'Neuen Inhalt anzeigen
Locate 9, 3
Print "Neuer Inhalt in der Speicheradresse (Inhalt * 2): ", wert
'Speicheradresse der 2ten Variablen ermitteln
speicherAdresse2 = VarPtr(zahl2)
wert2 = Peek(speicherAdresse2)
'Inhalt der Speicheradresse
Locate 11, 3
Print "Inhalt der 2ten Speicheradresse: ", wert2
Locate 12, 3
Print "Jetzt auf die Adresse von Zahl 2 zugreifen, um den Inhalt zu aendern."
'Der 2ten Variablen den Wert von wert2 von der
'ersten Speicheradresse zuweisen
Locate 14, 3
wert2 = Peek(speicherAdresse)
Print "2te Variable hat jetzt den selben Wert wie Zahl 1: ", wert2
End
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
Check out the memory stuff, maybe start with Type.
https://qb64phoenix.com/qb64wiki/index.php/MEM
b = b + ...
Posts: 1,510
Threads: 53
Joined: Jul 2022
Reputation:
47
07-17-2023, 12:05 AM
(This post was last modified: 07-17-2023, 12:07 AM by mnrvovrfc .)
As bplus already elucidated, what I call the _MEM gang. But it's somewhat clunky to some people used to how code looks in C. They prefer Freebasic because those developers desired as close association to C/C++ as possible. It explains the "ZString" type and the folly with using fixed-length strings in UDT's and working with files.
QB64 allows the programmer to do pointer-heavy stuff in C if he/she wanted to. Just include stuff in "dot-H" files and have a matching "DECLARE LIBRARY... END DECLARE" to have subprogram and function prototypes. This is actually done extensively in QB64 itself to expand the language.
Show Content
Spoiler Do not look at a lot of Purebasic code, especially that targeted for Win32 API because it's confusing. They talk sometimes about using an integer type (declared as "something.i") to sometimes substitute for pointer. This was because the language used to be not sophisticated enough to handle pointer variables per se and there needed to be a way to give an address to point to a variable or function or something. The thing wrong with that is that most "pointers" in Win32 API were 32-bit for a 32-bit operating system, and therefore it was easy to assume the "dot-i" which is for 32-bit integer. Pointers should never have types in any language, it depends always on the CPU architecture.
Another thing to get confused about is the _OFFSET type in QB64. But that is actually a go-between so the programmer could call stuff from Win API and other places. _OFFSET is actually the "void" pointer type in C.
https://qb64phoenix.com/qb64wiki/index.p...KE_Library
Here is very close to what is called "PEEK" and "POKE" in Purebasic: just simple memory buffers to store stuff into. But this could be done about as easily with the _MEM statements.
Posts: 18
Threads: 1
Joined: Jul 2023
Reputation:
2
New Method
Code: (Select All)
DIM SEGBlock AS _MEM
DIM wert AS _UNSIGNED LONG
DIM wert2 AS _UNSIGNED LONG
wert = 4294967295
SEGBlock = _MEM (wert)
_MEMPUT SEGBlock, SEGBlock.OFFSET , _MEMGET (SEGBlock, SEGBlock.OFFSET , LONG ) - 5 AS LONG
wert2 = _MEMGET (SEGBlock, SEGBlock.OFFSET , LONG )
PRINT "Speicher Start Adresse :" ; SEGBlock.OFFSET
PRINT "Groesse des Blocks :" ; SEGBlock.SIZE
PRINT "Typ des Blocks :" ; SEGBlock.TYPE
PRINT "Datentyp des Blocks :" ; SEGBlock.ELEMENTSIZE
PRINT "Wert der Speicher Adresse:" ; wert2
_MEMFREE SEGBlock
Old Method:
Code: (Select All)
DIM SpeicherAdresse AS LONG
DIM wert AS LONG
wert = 65535
DEF SEG = VARSEG (SpeicherAdresse)
POKE SpeicherAdresse + 0 , (wert AND &HFF00 &) / &H100 &
POKE SpeicherAdresse + 1 , (wert AND &HFF &)
POKE SpeicherAdresse + 1 , PEEK (SpeicherAdresse + 1 ) - 5
wert2 = PEEK (SpeicherAdresse + 0 ) * &H100 & + PEEK (SpeicherAdresse + 1 )
PRINT "Verwendeter Segment Block: &H" + HEX$ (VARSEG (SpeicherAdresse))
PRINT "Speicher Start Adresse : &H" + HEX$ (VARPTR (SpeicherAdresse))
PRINT "Wert der SpeicherAdresse :" ; wert2
Posts: 263
Threads: 14
Joined: Apr 2022
Reputation:
23
I concur with what everyone else has stated here. Use the _MEM set of commands. They operate very similar to binary files and are a better protected (i.e. less dangerous) way of doing PEEKs & POKEs. There's essentially no chance of "going off the reservation". They can be a bit fussy to use, but worth the effort. Check out Steve's video tutorials on the subject, if you haven't already, that's where I learned them.
https://staging.qb64phoenix.com/showthread.php?tid=172
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
07-17-2023, 01:00 AM
(This post was last modified: 07-17-2023, 01:01 AM by bplus .)
"As bplus already elucidated,"
OMG I am elucidating again!
Well I think SagaraS is germaining. ;-))
b = b + ...
Posts: 131
Threads: 7
Joined: May 2022
Reputation:
20
Posts: 439
Threads: 17
Joined: Apr 2022
Reputation:
21
07-17-2023, 11:55 AM
(This post was last modified: 07-17-2023, 12:25 PM by SpriggsySpriggs .)
That reminds me a lot of my PeepingTom code
Code: (Select All)
'Begin $INCLUDE
Type PROCESSENTRY32
As Long dwSize, cntUsage, th32ProcessID
$If 64BIT Then
As String * 4 padding
$End If
As _Unsigned _Offset th32DefaultHeapID
As Long th32ModuleID, cntThreads, th32ParentProcessID, pcPriClassBase, dwFlags
As String * 260 szExeFile
End Type
Const PROCESS_VM_READ = &H0010
Const PROCESS_QUERY_INFORMATION = &H0400
Const PROCESS_VM_WRITE = &H0020
Const PROCESS_VM_OPERATION = &H0008
Const TH32CS_SNAPPROCESS = &H00000002
Const TOM_FALSE = 0
Declare Dynamic Library "Kernel32"
Function CreateToolhelp32Snapshot%& (ByVal dwFlags As Long , Byval th32ProcessID As Long )
Function Process32First%% (ByVal hSnapshot As _Offset , Byval lppe As _Offset )
Function Process32Next%% (ByVal hSnapshot As _Offset , Byval lppe As _Offset )
End Declare
Declare CustomType Library
Function OpenProcess%& (ByVal dwDesiredAccess As Long , Byval bInheritHandle As Long , Byval dwProcessId As _Unsigned Long )
Function ReadProcessMemory%% (ByVal hProcess As _Offset , Byval lpBaseAddress As _Offset , Byval lpBuffer As _Offset , Byval nSize As _Offset , Byval lpNumberOfBytesRead As _Offset )
Function WriteProcessMemory%% (ByVal hProcess As _Offset , Byval lpBaseAddress As _Offset , Byval lpBuffer As _Offset , Byval nSize As _Offset , Byval lpNumberOfBytesWritten As _Offset )
Sub TomCloseHandle Alias "CloseHandle" (ByVal hObject As _Offset )
Function strlen& (ByVal ptr As _Unsigned _Offset )
End Declare
Function PeekByte%% (process As String , address As _Unsigned _Offset )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As _Byte result
memo = ReadProcessMemory (hProcess, address, _Offset (result), 1 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PeekByte = result
End Function
Function PokeByte% (process As String , address As _Unsigned _Offset , value As _Byte )
Dim As _Offset hProcessSnap
Dim As _Offset hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim memo As _Byte
memo = WriteProcessMemory (hProcess, address, _Offset (value), 1 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PokeByte = memo
End Function
Function PeekUnsignedByte~%% (process As String , address As _Unsigned _Offset )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As _Unsigned _Byte result
memo = ReadProcessMemory (hProcess, address, _Offset (result), 1 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PeekUnsignedByte = result
End Function
Function PokeUnsignedByte% (process As String , address As _Unsigned _Offset , value As _Unsigned _Byte )
Dim As _Offset hProcessSnap
Dim As _Offset hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim memo As Integer
memo = WriteProcessMemory (hProcess, address, _Offset (value), 1 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PokeUnsignedByte = memo
End Function
Function PeekInt% (process As String , address As _Unsigned _Offset )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As Integer result
memo = ReadProcessMemory (hProcess, address, _Offset (result), 2 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PeekInt = result
End Function
Function PokeInt% (process As String , address As _Unsigned _Offset , value As Integer )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
memo = WriteProcessMemory (hProcess, address, _Offset (value), 2 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PokeInt = memo
End Function
Function PeekUnsignedInt~% (process As String , address As _Unsigned _Offset )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As _Unsigned Integer result
memo = ReadProcessMemory (hProcess, address, _Offset (result), 2 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PeekUnsignedInt = result
End Function
Function PokeUnsignedInt% (process As String , address As _Unsigned _Offset , value As _Unsigned Integer )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
memo = WriteProcessMemory (hProcess, address, _Offset (value), 2 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PokeUnsignedInt = memo
End Function
Function PeekLong& (process As String , address As _Unsigned _Offset )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As Long result
memo = ReadProcessMemory (hProcess, address, _Offset (result), 4 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PeekLong = result
End Function
Function PokeLong% (process As String , address As _Unsigned _Offset , value As Long )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
memo = WriteProcessMemory (hProcess, address, _Offset (value), 4 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PokeLong = memo
End Function
Function PeekUnsignedLong~& (process As String , address As _Unsigned _Offset )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As _Unsigned Long result
memo = ReadProcessMemory (hProcess, address, _Offset (result), 4 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PeekUnsignedLong = result
End Function
Function PokeUnsignedLong% (process As String , address As _Unsigned _Offset , value As _Unsigned Long )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
memo = WriteProcessMemory (hProcess, address, _Offset (value), 4 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PokeUnsignedLong = memo
End Function
Function PeekInt64&& (process As String , address As _Unsigned _Offset )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As _Integer64 result
memo = ReadProcessMemory (hProcess, address, _Offset (result), 8 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PeekInt64 = result
End Function
Function PokeInt64% (process As String , address As _Unsigned _Offset , value As _Integer64 )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
memo = WriteProcessMemory (hProcess, address, _Offset (value), 8 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PokeInt64 = memo
End Function
Function PeekUnsignedInt64~&& (process As String , address As _Unsigned _Offset )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As _Unsigned _Integer64 result
memo = ReadProcessMemory (hProcess, address, _Offset (result), 8 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PeekUnsignedInt64 = result
End Function
Function PokeUnsignedInt64% (process As String , address As _Unsigned _Offset , value As _Unsigned _Integer64 )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
memo = WriteProcessMemory (hProcess, address, _Offset (value), 8 , 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PokeUnsignedInt64 = memo
End Function
Function PeekString$ (process As String , address As _Unsigned _Offset )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As String result
result = Space$ (strlen (address))
memo = ReadProcessMemory (hProcess, address, _Offset (result), Len (result), 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PeekString = result
End Function
Function PokeString% (process As String , address As _Unsigned _Offset , value As String )
Dim As _Offset hProcessSnap, hProcess
Dim As PROCESSENTRY32 pe32
hProcessSnap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 )
pe32.dwSize = Len (pe32)
If Process32First (hProcessSnap, _Offset (pe32)) Then
While Process32Next (hProcessSnap, _Offset (pe32))
If _StrCmp (Left$ (pe32.szExeFile, InStr (pe32.szExeFile, ".exe" + Chr$ (0 )) + 3 ), process) = 0 Then
hProcess = OpenProcess (PROCESS_VM_READ Or PROCESS_QUERY_INFORMATION Or PROCESS_VM_WRITE Or PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
Dim As _Byte memo
Dim As Long lenaddress
lenaddress = strlen (address)
If Right$ (value, 1 ) <> Chr$ (0 ) Then
value = value + Chr$ (0 )
End If
If lenaddress > Len (value) Then
Dim As Long i
For i = 1 To lenaddress
value = value + Chr$ (0 )
Next
End If
memo = WriteProcessMemory (hProcess, address, _Offset (value), Len (value), 0 )
Exit While
End If
Wend
End If
TomCloseHandle hProcessSnap
TomCloseHandle hProcess
PokeString = memo
End Function
Sub RelaunchAsAdmin
If _ShellHide (">nul 2>&1 " + Chr$ (34 ) + "%SYSTEMROOT%\system32\cacls.exe" + Chr$ (34 ) + " " + Chr$ (34 ) + "%SYSTEMROOT%\system32\config\system" + Chr$ (34 )) = 5 Then 'not admin
Shell _Hide _DontWait "PowerShell Start-Process " + "'" + Chr$ (34 ) + Command$ (0 ) + Chr$ (34 ) + "'" + " -Verb runAs"
System
End If
End Sub
'End $INCLUDE
Attached Files
PeepingTom Example.txt (Size: 21.85 KB / Downloads: 54)
Ask me about Windows API and maybe some Linux stuff
Posts: 714
Threads: 36
Joined: May 2022
Reputation:
13
@SagraS - Thanks for the example and the description in German.
I tried a few things with the example to understand the whole thing. Well, it comes so slowly, understanding. The thing about _MEM is new for me in Basic.
The number in
SEGBlock.TYPE obviously depends on the variable declaration, because it changes depending on the variable type. Is there a table showing what each number means?
What still surprises me is that with a 2nd number, the memory address increases by 8 bytes, but
SEGBlock.SIZE and
SEGBlock.ELEMENTSIZE only show 4 bytes (4 + 4?).
Code: (Select All)
'SagraS, Beispiel fuer die Nutzung von _MEM - 16. Juli 2023
' 32Bit / 64Bit Speicher (Der von Windows)
' Reine 32/64 Bit Adressierung
' 32/64 Bit Pointer
' Funktioniert fuer Werte mit bis zu 64Bit (Integer64)
Option _Explicit
Dim SEGBlock As _MEM
Dim As _Unsigned Long wert, wert1, wert2
Dim As _Offset position, position1
Print
Input "Zahl eingeben : ", wert
Print
Input "Noch eine Zahl: ", wert1
' Speicherblock der Variable ermitteln
SEGBlock = _Mem(wert)
'Entspricht der Startadresse
position = _Offset(wert)
position1 = _Offset(wert1)
' Aendern des Wertes im Speicher um -5 / +5
_MemPut SEGBlock, SEGBlock.OFFSET, _MemGet(SEGBlock, SEGBlock.OFFSET, Long) + 5 As LONG
' Wert aus dem Speicher holen
wert2 = _MemGet(SEGBlock, SEGBlock.OFFSET, Long)
Print
Print "Position erste Zahlim Speicher : "; position
Print
Print "Position zweite Zahlim Speicher : "; position1
Print
Print "Speicher Startadresse : "; SEGBlock.OFFSET
Print "Groesse des Blocks(Byte) : "; SEGBlock.SIZE
Print "Type des Blocks(Nummer) : "; SEGBlock.TYPE
Print "Datentyp des Blocks(Nach Dim) : "; SEGBlock.ELEMENTSIZE
Print "Neuer Inhalt der Speicheradresse: "; wert2
Print
'Startadresse bleibt gleich, es wird ja nur der Inhalt geaendert
Print "Startadresse neuer Inhalt : "; SEGBlock.OFFSET
' Speicherblock freigeben
_MemFree SEGBlock
End
Posts: 18
Threads: 1
Joined: Jul 2023
Reputation:
2
Here a new Code Example:
variable wert2_I on line 62 is a test value for a example in the text (line 8 - 46)
Code: (Select All)
OPTION _EXPLICIT
DIM SEGBlock1 AS _MEM
DIM SEGBlock2 AS _MEM
DIM AS _UNSIGNED _INTEGER64 wert1_I, wert2_I
DIM AS _UNSIGNED LONG wert1_O, wert2_O
DIM AS _OFFSET position1, position2
PRINT
INPUT "Zahl eingeben : " , wert1_I
PRINT
INPUT "Noch eine Zahl: " , wert2_I
wert2_I = &HFEDCBA98 76543210
SEGBlock1 = _MEM (wert1_I)
SEGBlock2 = _MEM (wert2_I)
position1 = _OFFSET (wert1_I)
position2 = _OFFSET (wert2_I)
wert1_O = _MEMGET (SEGBlock1, SEGBlock1.OFFSET , LONG )
wert2_O = _MEMGET (SEGBlock2, SEGBlock2.OFFSET + 2 , LONG )
PRINT LEN (SEGBlock1)
PRINT
PRINT "Position 1te Zahl im Speicher : &H" + HEX$ (position1)
PRINT "Position 2te Zahl im Speicher : &H" + HEX$ (position2)
PRINT
PRINT "Position 1te Zahl im Speicher : &H" + HEX$ (SEGBlock1.OFFSET )
PRINT "Groesse des Blocks(Byte) : &H" + HEX$ (SEGBlock1.SIZE)
PRINT "Type des Blocks(Nummer) : &H" + HEX$ (SEGBlock1.TYPE )
PRINT "Datentyp des Blocks(Nach Dim) : &H" + HEX$ (SEGBlock1.ELEMENTSIZE)
PRINT "Inhalt der Speicheradresse : " + STR$ (wert1_O) + " HEX( " + HEX$ (wert1_O) + " )"
PRINT
PRINT "Position 2te Zahl im Speicher : &H" + HEX$ (SEGBlock2.OFFSET )
PRINT "Groesse des Blocks(Byte) : &H" + HEX$ (SEGBlock2.SIZE)
PRINT "Type des Blocks(Nummer) : &H" + HEX$ (SEGBlock2.TYPE )
PRINT "Datentyp des Blocks(Nach Dim) : &H" + HEX$ (SEGBlock2.ELEMENTSIZE)
PRINT "Inhalt der Speicheradresse : " + STR$ (wert2_O) + " HEX( " + HEX$ (wert2_O) + " )"
PRINT
PRINT "Startadresse neuer Inhalt : " ; SEGBlock1.OFFSET
_MEMFREE SEGBlock1
_MEMFREE SEGBlock2
END