Author Topic: Peeping Tom: A Powerful PEEK/POKE library written using WinAPI  (Read 4474 times)

0 Members and 1 Guest are viewing this topic.

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Peeping Tom: A Powerful PEEK/POKE library written using WinAPI
« on: October 16, 2020, 04:36:39 pm »
In regular QBasic, we had PEEK and POKE. In QB64, those functions are kept mostly for legacy and will overflow on modern variables. On the Wiki, there was code written in 2011 by Michael Calkins to give PEEK and POKE functionality back to QB64 without such issues (here:https://www.qb64.org/wiki/PEEK_and_POKE_Library). It works ok but not great. It crashes quite often when trying to POKE the memory of a different process. So, in my endeavor to make trainers in QB64, I decided it was high-time someone made a good alternative to PEEK and POKE that allows you to change the memory of a different process/application. So, we have Peeping Tom. A library made using WinAPI's OpenProcess, ReadProcessMemory, and WriteProcessMemory functions. With this you can peekbyte, peekint, peeklong, peekint64, peekstring, pokebyte, pokeint, pokelong, pokeint64, and pokestring for ANY process that has read/writeable memory in the locations you are attempting to access.

A screenshot showing the library editing values in the exe compiled from the source:
 
Screenshot 2020-10-16 154218.png


And the source code (tested in 32 and 64 bit):

Code: QB64: [Select]
  1.  
  2. $IF 64BIT THEN
  3.     TYPE PROCESSENTRY32
  4.         dwSize AS LONG
  5.         cntUsage AS LONG
  6.         th32ProcessID AS _INTEGER64
  7.         th32DefaultHeapID AS _UNSIGNED _INTEGER64
  8.         th32ModuleID AS LONG
  9.         cntThreads AS LONG
  10.         th32ParentProcessID AS LONG
  11.         pcPriClassBase AS LONG
  12.         dwFlags AS LONG
  13.         szExeFile AS STRING * 260
  14.     END TYPE
  15.     TYPE PROCESSENTRY32
  16.     dwSize AS LONG
  17.     cntUsage AS LONG
  18.     th32ProcessID AS LONG
  19.     th32DefaultHeapID AS _UNSIGNED LONG
  20.     th32ModuleID AS LONG
  21.     cntThreads AS LONG
  22.     th32ParentProcessID AS LONG
  23.     pcPriClassBase AS LONG
  24.     dwFlags AS LONG
  25.     szExeFile AS STRING * 260
  26.     END TYPE
  27.  
  28. CONST PROCESS_VM_READ = &H0010
  29. CONST PROCESS_QUERY_INFORMATION = &H0400
  30. CONST PROCESS_VM_WRITE = &H0020
  31. CONST PROCESS_VM_OPERATION = &H0008
  32. CONST STANDARD_RIGHTS_REQUIRED = &H000F0000
  33. CONST SYNCHRONIZE = &H00100000
  34. CONST PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED OR SYNCHRONIZE OR &HFFFF
  35.  
  36. CONST TH32CS_INHERIT = &H80000000
  37. CONST TH32CS_SNAPHEAPLIST = &H00000001
  38. CONST TH32CS_SNAPMODULE = &H00000008
  39. CONST TH32CS_SNAPMODULE32 = &H00000010
  40. CONST TH32CS_SNAPPROCESS = &H00000002
  41. CONST TH32CS_SNAPTHREAD = &H00000004
  42. CONST TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST OR TH32CS_SNAPMODULE OR TH32CS_SNAPPROCESS OR TH32CS_SNAPTHREAD
  43.  
  44. CONST TRUE = -1
  45. CONST FALSE = 0
  46.  
  47.     FUNCTION CreateToolhelp32Snapshot& (BYVAL dwFlags AS LONG, BYVAL th32ProcessID AS LONG)
  48.     FUNCTION Process32First%% (BYVAL hSnapshot AS LONG, BYVAL lppe AS _OFFSET)
  49.     FUNCTION Process32Next%% (BYVAL hSnapshot AS LONG, BYVAL lppe AS _OFFSET)
  50.     FUNCTION OpenProcess& (BYVAL dwDesiredAccess AS LONG, BYVAL bInheritHandle AS _BYTE, BYVAL dwProcessId AS LONG)
  51.     FUNCTION ReadProcessMemory%% (BYVAL hProcess AS LONG, BYVAL lpBaseAddress AS _OFFSET, BYVAL lpBuffer AS _OFFSET, BYVAL nSize AS LONG, BYVAL lpNumberOfBytesRead AS _OFFSET)
  52.     FUNCTION WriteProcessMemory%% (BYVAL hProcess AS LONG, BYVAL lpBaseAddress AS _OFFSET, BYVAL lpBuffer AS _OFFSET, BYVAL nSize AS LONG, BYVAL lpNumberOfBytesWritten AS _OFFSET)
  53.     FUNCTION CloseHandle%% (BYVAL hObject AS LONG)
  54.  
  55.     FUNCTION strlen& (BYVAL ptr AS _UNSIGNED _OFFSET)
  56.  
  57. _TITLE "Peeping Tom: A Powerful PEEK/POKE"
  58.  
  59. test = "This is a test" + CHR$(0)
  60. exe = MID$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\") + 1)
  61. PRINT CHR$(peekbyte(exe, _OFFSET(test)))
  62. PRINT peekstring(exe, _OFFSET(test))
  63.  
  64. DIM testint AS INTEGER
  65. testint = 320
  66. PRINT peekint(exe, _OFFSET(testint))
  67.  
  68. DIM testlong AS LONG
  69. testlong = &HFF
  70. PRINT peeklong(exe, _OFFSET(testlong))
  71.  
  72. DIM testint64 AS _INTEGER64
  73. testint64 = 922337
  74. PRINT peekint64(exe, _OFFSET(testint64))
  75.  
  76. a = pokebyte(exe, _OFFSET(test), ASC("S"))
  77. PRINT peekstring(exe, _OFFSET(test))
  78.  
  79. a = pokeint(exe, _OFFSET(testint), 312)
  80. PRINT peekint(exe, _OFFSET(testint))
  81.  
  82. a = pokelong(exe, _OFFSET(testlong), &HFE)
  83. PRINT peeklong(exe, _OFFSET(testlong))
  84.  
  85. a = pokeint64(exe, _OFFSET(testint64), 922345)
  86. PRINT peekint64(exe, _OFFSET(testint64))
  87.  
  88. a = pokestring(exe, _OFFSET(test), "This is NOT a test" + CHR$(0))
  89. PRINT peekstring(exe, _OFFSET(test))
  90.  
  91. FUNCTION peekbyte%% (process AS STRING, address AS _UNSIGNED _OFFSET)
  92.     DIM hProcessSnap AS LONG
  93.     DIM hProcess AS LONG
  94.     DIM pe32 AS PROCESSENTRY32
  95.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  96.     pe32.dwSize = LEN(pe32)
  97.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  98.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  99.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  100.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  101.                 DIM memo AS _BYTE
  102.                 DIM result AS _BYTE
  103.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 1, 0)
  104.                 EXIT WHILE
  105.             END IF
  106.         WEND
  107.     END IF
  108.     DIM closeh AS LONG
  109.     closeh = CloseHandle(hProcessSnap)
  110.     closeh = CloseHandle(hProcess)
  111.     peekbyte = result
  112.  
  113. FUNCTION peekint% (process AS STRING, address AS _UNSIGNED _OFFSET)
  114.     DIM hProcessSnap AS LONG
  115.     DIM hProcess AS LONG
  116.     DIM pe32 AS PROCESSENTRY32
  117.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  118.     pe32.dwSize = LEN(pe32)
  119.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  120.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  121.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  122.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  123.                 DIM memo AS _BYTE
  124.                 DIM result AS INTEGER
  125.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 2, 0)
  126.                 EXIT WHILE
  127.             END IF
  128.         WEND
  129.     END IF
  130.     DIM closeh AS LONG
  131.     closeh = CloseHandle(hProcessSnap)
  132.     closeh = CloseHandle(hProcess)
  133.     peekint = result
  134.  
  135. FUNCTION peeklong& (process AS STRING, address AS _UNSIGNED _OFFSET)
  136.     DIM hProcessSnap AS LONG
  137.     DIM hProcess AS LONG
  138.     DIM pe32 AS PROCESSENTRY32
  139.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  140.     pe32.dwSize = LEN(pe32)
  141.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  142.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  143.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  144.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  145.                 DIM memo AS _BYTE
  146.                 DIM result AS LONG
  147.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 4, 0)
  148.                 EXIT WHILE
  149.             END IF
  150.         WEND
  151.     END IF
  152.     DIM closeh AS LONG
  153.     closeh = CloseHandle(hProcessSnap)
  154.     closeh = CloseHandle(hProcess)
  155.     peeklong = result
  156.  
  157. FUNCTION peekint64&& (process AS STRING, address AS _UNSIGNED _OFFSET)
  158.     DIM hProcessSnap AS LONG
  159.     DIM hProcess AS LONG
  160.     DIM pe32 AS PROCESSENTRY32
  161.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  162.     pe32.dwSize = LEN(pe32)
  163.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  164.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  165.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  166.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  167.                 DIM memo AS _BYTE
  168.                 DIM result AS _INTEGER64
  169.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), 8, 0)
  170.                 EXIT WHILE
  171.             END IF
  172.         WEND
  173.     END IF
  174.     DIM closeh AS LONG
  175.     closeh = CloseHandle(hProcessSnap)
  176.     closeh = CloseHandle(hProcess)
  177.     peekint64 = result
  178.  
  179. FUNCTION peekstring$ (process AS STRING, address AS _UNSIGNED _OFFSET)
  180.     DIM hProcessSnap AS LONG
  181.     DIM hProcess AS LONG
  182.     DIM pe32 AS PROCESSENTRY32
  183.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  184.     pe32.dwSize = LEN(pe32)
  185.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  186.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  187.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  188.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  189.                 DIM memo AS _BYTE
  190.                 DIM result AS STRING
  191.                 result = SPACE$(PointerLen(address))
  192.                 memo = ReadProcessMemory(hProcess, address, _OFFSET(result), LEN(result), 0)
  193.                 EXIT WHILE
  194.             END IF
  195.         WEND
  196.     END IF
  197.     DIM closeh AS LONG
  198.     closeh = CloseHandle(hProcessSnap)
  199.     closeh = CloseHandle(hProcess)
  200.     peekstring = result
  201.  
  202. FUNCTION pokebyte%% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS _BYTE)
  203.     DIM hProcessSnap AS LONG
  204.     DIM hProcess AS LONG
  205.     DIM pe32 AS PROCESSENTRY32
  206.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  207.     pe32.dwSize = LEN(pe32)
  208.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  209.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  210.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  211.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  212.                 DIM memo AS _BYTE
  213.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 1, 0)
  214.                 EXIT WHILE
  215.             END IF
  216.         WEND
  217.     END IF
  218.     DIM closeh AS LONG
  219.     closeh = CloseHandle(hProcessSnap)
  220.     closeh = CloseHandle(hProcess)
  221.     pokebyte = memo
  222.  
  223. FUNCTION pokeint%% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS INTEGER)
  224.     DIM hProcessSnap AS LONG
  225.     DIM hProcess AS LONG
  226.     DIM pe32 AS PROCESSENTRY32
  227.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  228.     pe32.dwSize = LEN(pe32)
  229.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  230.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  231.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  232.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  233.                 DIM memo AS _BYTE
  234.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 2, 0)
  235.                 EXIT WHILE
  236.             END IF
  237.         WEND
  238.     END IF
  239.     DIM closeh AS LONG
  240.     closeh = CloseHandle(hProcessSnap)
  241.     closeh = CloseHandle(hProcess)
  242.     pokeint = memo
  243.  
  244. FUNCTION pokelong%% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS LONG)
  245.     DIM hProcessSnap AS LONG
  246.     DIM hProcess AS LONG
  247.     DIM pe32 AS PROCESSENTRY32
  248.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  249.     pe32.dwSize = LEN(pe32)
  250.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  251.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  252.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  253.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  254.                 DIM memo AS _BYTE
  255.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 4, 0)
  256.                 EXIT WHILE
  257.             END IF
  258.         WEND
  259.     END IF
  260.     DIM closeh AS LONG
  261.     closeh = CloseHandle(hProcessSnap)
  262.     closeh = CloseHandle(hProcess)
  263.     pokelong = memo
  264.  
  265. FUNCTION pokeint64%% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS _INTEGER64)
  266.     DIM hProcessSnap AS LONG
  267.     DIM hProcess AS LONG
  268.     DIM pe32 AS PROCESSENTRY32
  269.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  270.     pe32.dwSize = LEN(pe32)
  271.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  272.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  273.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  274.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  275.                 DIM memo AS _BYTE
  276.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), 8, 0)
  277.                 EXIT WHILE
  278.             END IF
  279.         WEND
  280.     END IF
  281.     DIM closeh AS LONG
  282.     closeh = CloseHandle(hProcessSnap)
  283.     closeh = CloseHandle(hProcess)
  284.     pokeint64 = memo
  285.  
  286. FUNCTION pokestring%% (process AS STRING, address AS _UNSIGNED _OFFSET, value AS STRING)
  287.     DIM hProcessSnap AS LONG
  288.     DIM hProcess AS LONG
  289.     DIM pe32 AS PROCESSENTRY32
  290.     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
  291.     pe32.dwSize = LEN(pe32)
  292.     IF Process32First(hProcessSnap, _OFFSET(pe32)) THEN
  293.         WHILE Process32Next(hProcessSnap, _OFFSET(pe32))
  294.             IF _STRCMP(LEFT$(pe32.szExeFile, INSTR(pe32.szExeFile, ".exe" + CHR$(0)) + 3), process) = 0 THEN
  295.                 hProcess = OpenProcess(PROCESS_VM_READ OR PROCESS_QUERY_INFORMATION OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION, FALSE, pe32.th32ProcessID)
  296.                 DIM memo AS _BYTE
  297.                 memo = WriteProcessMemory(hProcess, address, _OFFSET(value), LEN(value), 0)
  298.                 EXIT WHILE
  299.             END IF
  300.         WEND
  301.     END IF
  302.     DIM closeh AS LONG
  303.     closeh = CloseHandle(hProcessSnap)
  304.     closeh = CloseHandle(hProcess)
  305.     pokestring = memo
  306.  
  307. FUNCTION PointerLen& (value AS _OFFSET)
  308.     PointerLen = strlen(value)

Feel free to change it up as you see fit. Note: You will have to know where the address of the data you want to change is located. I do have a function that searches out strings and can be modified to search for numbers (and is not included here) BUT you DO NOT want to try it that way as you will MOST CERTAINLY WRITE TO THE WRONG ADDRESS since there are multiple places where a value could be the same as the one you are searching for. After I make my tutorial on creating game trainers you will see that you should use Cheat Engine https://www.cheatengine.org/ to locate the BASE addresses you are wanting to change. Base addresses remain constant between launches of a program with several offsets in place to arrive at the variable address that does change between launches. Be VERY CAREFUL modifying memory in programs. Don't go all will-nilly changing things for the heck of it. Take care in what you do.
« Last Edit: October 17, 2020, 11:30:14 am by SpriggsySpriggs »
Shuwatch!

Offline Dav

  • Forum Resident
  • Posts: 792
    • View Profile
Re: Peeping Tom: A Powerful PEEK/POKE library written using WinAPI
« Reply #1 on: October 16, 2020, 05:55:38 pm »
Cool. I'll be giving this a try.  I've played around with mcaulkins code quite a bit and did have some crashing issues now and then.  Thanks for sharing.

- Dav

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Peeping Tom: A Powerful PEEK/POKE library written using WinAPI
« Reply #2 on: October 16, 2020, 05:57:33 pm »
Cool. I'll be giving this a try.  I've played around with mcaulkins code quite a bit and did have some crashing issues now and then.  Thanks for sharing.

- Dav
Yeah, his code is pretty good for some things but I had times where just using his library at all in my code made it not even get to the point of loading the screen of the program. I've had plenty of good luck with this code so far.
Shuwatch!

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Peeping Tom: A Powerful PEEK/POKE library written using WinAPI
« Reply #3 on: October 16, 2020, 11:17:01 pm »
The next step would be to offer free cloud services to banks.
It works better if you plug it in.

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Peeping Tom: A Powerful PEEK/POKE library written using WinAPI
« Reply #4 on: October 16, 2020, 11:18:30 pm »
The next step would be to offer free cloud services to banks.
@Richard Frost Eh?
Shuwatch!

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Peeping Tom: A Powerful PEEK/POKE library written using WinAPI
« Reply #5 on: October 16, 2020, 11:23:56 pm »
If a bank runs a process on your computer, you can monkey with it,
vary the amount of bananas in accounts.
It works better if you plug it in.

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Peeping Tom: A Powerful PEEK/POKE library written using WinAPI
« Reply #6 on: October 16, 2020, 11:26:24 pm »
If a bank runs a process on your computer, you can monkey with it,
vary the amount of bananas in accounts.
@Richard Frost I don't know why they would do that but sure, I guess.....
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Peeping Tom: A Powerful PEEK/POKE library written using WinAPI
« Reply #7 on: October 17, 2020, 11:22:33 am »
Updated 10/17/2020

Fixed the peekstring function so it doesn't just call peekbyte but instead grabs the entire string in one go.
Shuwatch!

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: Peeping Tom: A Powerful PEEK/POKE library written using WinAPI
« Reply #8 on: October 17, 2020, 11:31:29 am »
Updated each function by placing an EXIT WHILE so on the off-chance that there is another process running of the same name that it doesn't change that as well.
Shuwatch!