Author Topic: Rewrite of PeepingTom library (Peek/Poke replacement)  (Read 307 times)

0 Members and 1 Guest are viewing this topic.

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1057
  • If you're API and you know it clap your hands
    • My GitHub
Rewrite of PeepingTom library (Peek/Poke replacement)
« on: February 17, 2021, 11:51:22 PM »
I had written a library a while back called "PeepingTom". I decided to open it today and I noticed I had a lot of wrong variables and an unnecessary declaration of an entire TYPE for 32 Bit. So, I've cleaned up the code quite a bit, brought it to the new 1.5 DIM syntax (which means that dev build 1.5 is required), and fixed all the variables. Everything should be the exact right sizes and types. Also, following the new CamelCase style of 1.5, all functions have been renamed using this standard. Below is a screenshot showing example code running for each function. This is Windows only right now but I am still looking at what can be done in Linux and Mac. I'd love for it to be cross-platform. I have a feeling @NOVARSEG would be interested in this code.

 


And the code, (The $INCLUDE starts at the "Begin $INCLUDE" comment):
Code: QB64: [Select]
  1.  
  2. $IF VERSION < 1.5 THEN
  3.     $ERROR Requires QB64 v1.5 OR greater
  4.  
  5. exe = MID$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\") + 1)
  6. DIM AS INTEGER pokey
  7.  
  8. DIM AS _BYTE testbyte
  9. testbyte = -126
  10. PRINT "Value at _Offset(testbyte):", , PeekByte(exe, _OFFSET(testbyte))
  11. pokey = PokeByte(exe, _OFFSET(testbyte), -108)
  12. PRINT "Value after PokeByte:", , testbyte
  13.  
  14. DIM AS _UNSIGNED _BYTE testunsignedbyte
  15. testunsignedbyte = 243
  16. PRINT "Value at _Offset(testunsignedbyte):", PeekUnsignedByte(exe, _OFFSET(testunsignedbyte))
  17. pokey = PokeUnsignedByte(exe, _OFFSET(testunsignedbyte), 204)
  18. PRINT "Value after PokeUnsignedByte:", testunsignedbyte
  19.  
  20. DIM AS INTEGER testint
  21. testint = -5005
  22. PRINT "Value at _Offset(testint):", , PeekInt(exe, _OFFSET(testint))
  23. pokey = PokeInt(exe, _OFFSET(testint), -4080)
  24. PRINT "Value after PokeInt:", , testint
  25.  
  26. DIM AS _UNSIGNED INTEGER testunsignedint
  27. testunsignedint = 5234
  28. PRINT "Value at _Offset(testunsignedint):", PeekUnsignedInt(exe, _OFFSET(testunsignedint))
  29. pokey = PokeUnsignedInt(exe, _OFFSET(testunsignedint), 5500)
  30. PRINT "Value after PokeUnsignedInt:", , testunsignedint
  31.  
  32. DIM AS LONG testlong
  33. testlong = -55000
  34. PRINT "Value at _Offset(testlong):", , PeekLong(exe, _OFFSET(testlong))
  35. pokey = PokeLong(exe, _OFFSET(testlong), -32872)
  36. PRINT "Value after PokeLong:", , testlong
  37.  
  38. DIM AS _UNSIGNED LONG testunsignedlong
  39. testunsignedlong = 56985
  40. PRINT "Value at _Offset(testunsignedlong:", PeekUnsignedLong(exe, _OFFSET(testunsignedlong))
  41. pokey = PokeUnsignedLong(exe, _OFFSET(testunsignedlong), 57234)
  42. PRINT "Value after PokeUnsignedLong:", testunsignedlong
  43.  
  44. DIM AS _INTEGER64 testint64
  45. testint64 = -58698560
  46. PRINT "Value at _Offset(testint64):", , PeekInt64(exe, _OFFSET(testint64))
  47. pokey = PokeInt64(exe, _OFFSET(testint64), -98758763)
  48. PRINT "Value after PokeInt64:", , testint64
  49.  
  50. DIM AS _UNSIGNED _INTEGER64 testunsignedint64
  51. testunsignedint64 = 5854324590
  52. PRINT "Value at _Offset(testunsignedint64):", PeekUnsignedInt64(exe, _OFFSET(testunsignedint64))
  53. pokey = PokeUnsignedInt64(exe, _OFFSET(testunsignedint64), 3248506902)
  54. PRINT "Value after PokeUnsignedInt64:", testunsignedint64
  55.  
  56. DIM AS STRING teststring
  57. teststring = "This is a test of peeking a string stored at _Offset(teststring)" + CHR$(0)
  58. PRINT PeekString(exe, _OFFSET(teststring))
  59. pokey = PokeString(exe, _OFFSET(teststring), "This is the value of the string after poking")
  60. PRINT teststring
  61.  
  62.  
  63. 'Begin $INCLUDE
  64.  
  65. TYPE PROCESSENTRY32
  66.     dwSize AS LONG
  67.     cntUsage AS LONG
  68.     th32ProcessID AS LONG
  69.     $IF 64BIT THEN
  70.         padding AS LONG
  71.     $END IF
  72.     th32DefaultHeapID AS _UNSIGNED _OFFSET
  73.     th32ModuleID AS LONG
  74.     cntThreads AS LONG
  75.     th32ParentProcessID AS LONG
  76.     pcPriClassBase AS LONG
  77.     dwFlags AS LONG
  78.     szExeFile AS STRING * 260
  79.  
  80. CONST PROCESS_VM_READ = &H0010
  81. CONST PROCESS_QUERY_INFORMATION = &H0400
  82. CONST PROCESS_VM_WRITE = &H0020
  83. CONST PROCESS_VM_OPERATION = &H0008
  84. CONST STANDARD_RIGHTS_REQUIRED = &H000F0000
  85. CONST SYNCHRONIZE = &H00100000
  86. CONST PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED OR SYNCHRONIZE OR &HFFFF
  87.  
  88. CONST TH32CS_INHERIT = &H80000000
  89. CONST TH32CS_SNAPHEAPLIST = &H00000001
  90. CONST TH32CS_SNAPMODULE = &H00000008
  91. CONST TH32CS_SNAPMODULE32 = &H00000010
  92. CONST TH32CS_SNAPPROCESS = &H00000002
  93. CONST TH32CS_SNAPTHREAD = &H00000004
  94. CONST TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST OR TH32CS_SNAPMODULE OR TH32CS_SNAPPROCESS OR TH32CS_SNAPTHREAD
  95.  
  96. CONST TOM_TRUE = -1
  97. CONST TOM_FALSE = 0
  98.  
  99.     FUNCTION CreateToolhelp32Snapshot%& (BYVAL dwFlags AS LONG, BYVAL th32ProcessID AS LONG)
  100.     FUNCTION Process32First% (BYVAL hSnapshot AS _OFFSET, BYVAL lppe AS _OFFSET)
  101.     FUNCTION Process32Next% (BYVAL hSnapshot AS _OFFSET, BYVAL lppe AS _OFFSET)
  102.     FUNCTION OpenProcess%& (BYVAL dwDesiredAccess AS LONG, BYVAL bInheritHandle AS _BYTE, BYVAL dwProcessId AS LONG)
  103.     FUNCTION ReadProcessMemory% (BYVAL hProcess AS _OFFSET, BYVAL lpBaseAddress AS _OFFSET, BYVAL lpBuffer AS _OFFSET, BYVAL nSize AS LONG, BYVAL lpNumberOfBytesRead AS _OFFSET)
  104.     FUNCTION WriteProcessMemory% (BYVAL hProcess AS _OFFSET, BYVAL lpBaseAddress AS _OFFSET, BYVAL lpBuffer AS _OFFSET, BYVAL nSize AS LONG, BYVAL lpNumberOfBytesWritten AS _OFFSET)
  105.     FUNCTION CloseHandle% (BYVAL hObject AS _OFFSET)
  106.  
  107.     FUNCTION strlen& (BYVAL ptr AS _UNSIGNED _OFFSET)
  108.  
  109. FUNCTION PeekByte%% (process AS STRING, address AS _UNSIGNED _OFFSET)
  110.     DIM AS _OFFSET hProcessSnap, hProcess
  111.     DIM AS PROCESSENTRY32 pe32
  112.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  113.     pe32.dwSize = LEN(pe32)
  114.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  115.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  116.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  117.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  118.                 DIM AS INTEGER memo
  119.                 DIM AS _BYTE result
  120.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 1, 0)
  121.                 EXIT WHILE
  122.             END IF
  123.         WEND
  124.     END IF
  125.     DIM AS INTEGER closeh
  126.     closeh = CloseHandle(hProcessSnap)
  127.     closeh = CloseHandle(hProcess)
  128.     PeekByte = result
  129.  
  130. FUNCTION PokeByte% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS _BYTE)
  131.     DIM AS _OFFSET hProcessSnap
  132.     DIM AS _OFFSET hProcess
  133.     DIM AS PROCESSENTRY32 pe32
  134.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  135.     pe32.dwSize = LEN(pe32)
  136.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  137.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  138.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  139.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  140.                 DIM memo AS INTEGER
  141.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 1, 0)
  142.                 EXIT WHILE
  143.             END IF
  144.         WEND
  145.     END IF
  146.     DIM closeh AS LONG
  147.     closeh = CloseHandle(hProcessSnap)
  148.     closeh = CloseHandle(hProcess)
  149.     PokeByte = memo
  150.  
  151. FUNCTION PeekUnsignedByte~%% (process AS STRING, address AS _UNSIGNED _OFFSET)
  152.     DIM AS _OFFSET hProcessSnap, hProcess
  153.     DIM AS PROCESSENTRY32 pe32
  154.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  155.     pe32.dwSize = LEN(pe32)
  156.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  157.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  158.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  159.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  160.                 DIM AS INTEGER memo
  161.                 DIM AS _UNSIGNED _BYTE result
  162.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 1, 0)
  163.                 EXIT WHILE
  164.             END IF
  165.         WEND
  166.     END IF
  167.     DIM AS INTEGER closeh
  168.     closeh = CloseHandle(hProcessSnap)
  169.     closeh = CloseHandle(hProcess)
  170.     PeekUnsignedByte = result
  171.  
  172. FUNCTION PokeUnsignedByte% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS _UNSIGNED _BYTE)
  173.     DIM AS _OFFSET hProcessSnap
  174.     DIM AS _OFFSET hProcess
  175.     DIM AS PROCESSENTRY32 pe32
  176.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  177.     pe32.dwSize = LEN(pe32)
  178.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  179.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  180.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  181.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  182.                 DIM memo AS INTEGER
  183.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 1, 0)
  184.                 EXIT WHILE
  185.             END IF
  186.         WEND
  187.     END IF
  188.     DIM closeh AS LONG
  189.     closeh = CloseHandle(hProcessSnap)
  190.     closeh = CloseHandle(hProcess)
  191.     PokeUnsignedByte = memo
  192.  
  193. FUNCTION PeekInt% (process AS STRING, address AS _UNSIGNED _OFFSET)
  194.     DIM AS _OFFSET hProcessSnap, hProcess
  195.     DIM AS PROCESSENTRY32 pe32
  196.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  197.     pe32.dwSize = LEN(pe32)
  198.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  199.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  200.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  201.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  202.                 DIM AS INTEGER memo
  203.                 DIM AS INTEGER result
  204.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 2, 0)
  205.                 EXIT WHILE
  206.             END IF
  207.         WEND
  208.     END IF
  209.     DIM AS INTEGER closeh
  210.     closeh = CloseHandle(hProcessSnap)
  211.     closeh = CloseHandle(hProcess)
  212.     PeekInt = result
  213.  
  214. FUNCTION PokeInt% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS INTEGER)
  215.     DIM AS _OFFSET hProcessSnap, hProcess
  216.     DIM AS PROCESSENTRY32 pe32
  217.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  218.     pe32.dwSize = LEN(pe32)
  219.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  220.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  221.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  222.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  223.                 DIM AS INTEGER memo
  224.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 2, 0)
  225.                 EXIT WHILE
  226.             END IF
  227.         WEND
  228.     END IF
  229.     DIM AS INTEGER closeh
  230.     closeh = CloseHandle(hProcessSnap)
  231.     closeh = CloseHandle(hProcess)
  232.     PokeInt = memo
  233.  
  234. FUNCTION PeekUnsignedInt~% (process AS STRING, address AS _UNSIGNED _OFFSET)
  235.     DIM AS _OFFSET hProcessSnap, hProcess
  236.     DIM AS PROCESSENTRY32 pe32
  237.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  238.     pe32.dwSize = LEN(pe32)
  239.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  240.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  241.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  242.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  243.                 DIM AS INTEGER memo
  244.                 DIM AS _UNSIGNED INTEGER result
  245.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 2, 0)
  246.                 EXIT WHILE
  247.             END IF
  248.         WEND
  249.     END IF
  250.     DIM AS INTEGER closeh
  251.     closeh = CloseHandle(hProcessSnap)
  252.     closeh = CloseHandle(hProcess)
  253.     PeekUnsignedInt = result
  254.  
  255. FUNCTION PokeUnsignedInt% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS _UNSIGNED INTEGER)
  256.     DIM AS _OFFSET hProcessSnap, hProcess
  257.     DIM AS PROCESSENTRY32 pe32
  258.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  259.     pe32.dwSize = LEN(pe32)
  260.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  261.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  262.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  263.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  264.                 DIM AS INTEGER memo
  265.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 2, 0)
  266.                 EXIT WHILE
  267.             END IF
  268.         WEND
  269.     END IF
  270.     DIM AS INTEGER closeh
  271.     closeh = CloseHandle(hProcessSnap)
  272.     closeh = CloseHandle(hProcess)
  273.     PokeUnsignedInt = memo
  274.  
  275. FUNCTION PeekLong& (process AS STRING, address AS _UNSIGNED _OFFSET)
  276.     DIM AS _OFFSET hProcessSnap, hProcess
  277.     DIM AS PROCESSENTRY32 pe32
  278.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  279.     pe32.dwSize = LEN(pe32)
  280.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  281.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  282.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  283.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  284.                 DIM AS INTEGER memo
  285.                 DIM AS LONG result
  286.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 4, 0)
  287.                 EXIT WHILE
  288.             END IF
  289.         WEND
  290.     END IF
  291.     DIM AS INTEGER closeh
  292.     closeh = CloseHandle(hProcessSnap)
  293.     closeh = CloseHandle(hProcess)
  294.     PeekLong = result
  295.  
  296. FUNCTION PokeLong% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS LONG)
  297.     DIM AS _OFFSET hProcessSnap, hProcess
  298.     DIM AS PROCESSENTRY32 pe32
  299.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  300.     pe32.dwSize = LEN(pe32)
  301.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  302.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  303.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  304.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  305.                 DIM AS INTEGER memo
  306.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 4, 0)
  307.                 EXIT WHILE
  308.             END IF
  309.         WEND
  310.     END IF
  311.     DIM AS INTEGER closeh
  312.     closeh = CloseHandle(hProcessSnap)
  313.     closeh = CloseHandle(hProcess)
  314.     PokeLong = memo
  315.  
  316. FUNCTION PeekUnsignedLong~& (process AS STRING, address AS _UNSIGNED _OFFSET)
  317.     DIM AS _OFFSET hProcessSnap, hProcess
  318.     DIM AS PROCESSENTRY32 pe32
  319.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  320.     pe32.dwSize = LEN(pe32)
  321.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  322.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  323.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  324.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  325.                 DIM AS INTEGER memo
  326.                 DIM AS _UNSIGNED LONG result
  327.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 4, 0)
  328.                 EXIT WHILE
  329.             END IF
  330.         WEND
  331.     END IF
  332.     DIM AS INTEGER closeh
  333.     closeh = CloseHandle(hProcessSnap)
  334.     closeh = CloseHandle(hProcess)
  335.     PeekUnsignedLong = result
  336.  
  337. FUNCTION PokeUnsignedLong% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS _UNSIGNED LONG)
  338.     DIM AS _OFFSET hProcessSnap, hProcess
  339.     DIM AS PROCESSENTRY32 pe32
  340.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  341.     pe32.dwSize = LEN(pe32)
  342.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  343.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  344.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  345.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  346.                 DIM AS INTEGER memo
  347.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 4, 0)
  348.                 EXIT WHILE
  349.             END IF
  350.         WEND
  351.     END IF
  352.     DIM AS INTEGER closeh
  353.     closeh = CloseHandle(hProcessSnap)
  354.     closeh = CloseHandle(hProcess)
  355.     PokeUnsignedLong = memo
  356.  
  357. FUNCTION PeekInt64&& (process AS STRING, address AS _UNSIGNED _OFFSET)
  358.     DIM AS _OFFSET hProcessSnap, hProcess
  359.     DIM AS PROCESSENTRY32 pe32
  360.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  361.     pe32.dwSize = LEN(pe32)
  362.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  363.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  364.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  365.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  366.                 DIM AS INTEGER memo
  367.                 DIM AS _INTEGER64 result
  368.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 8, 0)
  369.                 EXIT WHILE
  370.             END IF
  371.         WEND
  372.     END IF
  373.     DIM AS INTEGER closeh
  374.     closeh = CloseHandle(hProcessSnap)
  375.     closeh = CloseHandle(hProcess)
  376.     PeekInt64 = result
  377.  
  378. FUNCTION PokeInt64% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS _INTEGER64)
  379.     DIM AS _OFFSET hProcessSnap, hProcess
  380.     DIM AS PROCESSENTRY32 pe32
  381.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  382.     pe32.dwSize = LEN(pe32)
  383.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  384.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  385.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  386.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  387.                 DIM AS INTEGER memo
  388.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 8, 0)
  389.                 EXIT WHILE
  390.             END IF
  391.         WEND
  392.     END IF
  393.     DIM AS INTEGER closeh
  394.     closeh = CloseHandle(hProcessSnap)
  395.     closeh = CloseHandle(hProcess)
  396.     PokeInt64 = memo
  397.  
  398. FUNCTION PeekUnsignedInt64~&& (process AS STRING, address AS _UNSIGNED _OFFSET)
  399.     DIM AS _OFFSET hProcessSnap, hProcess
  400.     DIM AS PROCESSENTRY32 pe32
  401.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  402.     pe32.dwSize = LEN(pe32)
  403.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  404.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  405.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  406.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  407.                 DIM AS INTEGER memo
  408.                 DIM AS _UNSIGNED _INTEGER64 result
  409.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 8, 0)
  410.                 EXIT WHILE
  411.             END IF
  412.         WEND
  413.     END IF
  414.     DIM AS INTEGER closeh
  415.     closeh = CloseHandle(hProcessSnap)
  416.     closeh = CloseHandle(hProcess)
  417.     PeekUnsignedInt64 = result
  418.  
  419. FUNCTION PokeUnsignedInt64% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS _UNSIGNED _INTEGER64)
  420.     DIM AS _OFFSET hProcessSnap, hProcess
  421.     DIM AS PROCESSENTRY32 pe32
  422.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  423.     pe32.dwSize = LEN(pe32)
  424.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  425.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  426.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  427.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  428.                 DIM AS INTEGER memo
  429.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 8, 0)
  430.                 EXIT WHILE
  431.             END IF
  432.         WEND
  433.     END IF
  434.     DIM AS INTEGER closeh
  435.     closeh = CloseHandle(hProcessSnap)
  436.     closeh = CloseHandle(hProcess)
  437.     PokeUnsignedInt64 = memo
  438.  
  439. FUNCTION PeekString$ (process AS STRING, address AS _UNSIGNED _OFFSET)
  440.     DIM AS _OFFSET hProcessSnap, hProcess
  441.     DIM AS PROCESSENTRY32 pe32
  442.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  443.     pe32.dwSize = LEN(pe32)
  444.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  445.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  446.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  447.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  448.                 DIM AS INTEGER memo
  449.                 DIM AS STRING result
  450.                 result = SPACE$(strlen(address))
  451.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), LEN(result), 0)
  452.                 EXIT WHILE
  453.             END IF
  454.         WEND
  455.     END IF
  456.     DIM AS INTEGER closeh
  457.     closeh = CloseHandle(hProcessSnap)
  458.     closeh = CloseHandle(hProcess)
  459.     PeekString = result
  460.  
  461. FUNCTION PokeString% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS STRING)
  462.     DIM AS _OFFSET hProcessSnap, hProcess
  463.     DIM AS PROCESSENTRY32 pe32
  464.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  465.     pe32.dwSize = LEN(pe32)
  466.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  467.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  468.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  469.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, TOM_FALSE, pe32.th32ProcessID)
  470.                 DIM AS INTEGER memo
  471.                 DIM AS LONG lenaddress
  472.                 lenaddress = strlen(address)
  473.                 IF RIGHT$(value, 1) <> CHR$(0) THEN
  474.                     value = value + CHR$(0)
  475.                 END IF
  476.                 IF lenaddress > LEN(value) THEN
  477.                     DIM AS LONG i
  478.                     FOR i = 1 TO lenaddress
  479.                         value = value + CHR$(0)
  480.                     NEXT
  481.                 END IF
  482.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), LEN(value), 0)
  483.                 EXIT WHILE
  484.             END IF
  485.         WEND
  486.     END IF
  487.     DIM AS INTEGER closeh
  488.     closeh = CloseHandle(hProcessSnap)
  489.     closeh = CloseHandle(hProcess)
  490.     PokeString = memo
  491. 'End $INCLUDE
« Last Edit: February 18, 2021, 09:43:38 AM by SpriggsySpriggs »

Offline Pete

  • Forum Resident
  • Posts: 2574
  • Cuz I sez so, varmint!
Re: Rewrite of PeepingTom library (Peek/Poke replacement)
« Reply #1 on: February 18, 2021, 12:32:21 AM »
So exactly how will that pop my CD try open?

Actually, I do miss the Atari days, where you could peek/poke to redefine characters in any 8x8 pixel form you wanted. Also, it would be nice to poke in the key-presses that _SENDKEY doesn't support. QB64 does still support a limited use of these old memory addresses, like 1047, which I use to detect Shift, and Alt key combinations.

Interesting stuff, but I'll have to wait until v1.5 comes out to take it for a spin.

Pete

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1057
  • If you're API and you know it clap your hands
    • My GitHub
Re: Rewrite of PeepingTom library (Peek/Poke replacement)
« Reply #2 on: February 18, 2021, 12:41:42 AM »
@Pete This is designed to read/write memory from any process in Windows. I have that first argument of "process As String" so that the correct process is grabbed. I used the file I'm running because I didn't make a different exe to run at the same time but I know the code works because I used it myself for a game trainer I made a while back. As for the CD tray, I have no clue. In this case, you'd need to know the a process name that is capable of opening the tray and then set the value in memory to cause the action. As far as waiting for 1.5, you can actually grab the dev build from the site and run it that way if you want. That, or the DIM statements can just be rearranged to match the 1.4 standard. That's really the only thing keeping you from using it in 1.4
« Last Edit: February 18, 2021, 12:43:03 AM by SpriggsySpriggs »

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1057
  • If you're API and you know it clap your hands
    • My GitHub
Re: Rewrite of PeepingTom library (Peek/Poke replacement)
« Reply #3 on: February 18, 2021, 10:01:45 AM »
I suppose it should be mentioned that if you are running multiple instances of the same program that they'd have the same process name. That being said, it isn't normal that you would try writing to a process that may be running multiple instances. All that can be done as a proactive measure is to be careful and use this sparingly. If you start changing memory all willy-nilly then you could have some issues. Also, it's possible that you might require admin rights to read/write to a process that isn't the EXE containing this code. This is expected and normal. If you find that you are unable to change data in another application then you will need to launch the executable with this code as administrator. I made an update to the original post with some new lines in the PokeString% function because of needing to null-terminate the string that the address is being changed to. Without that, you will end up grabbing data from elsewhere on your machine.