Re: [python-win32] Quest for memory scanner

2017-10-21 Thread Tim Roberts
On Oct 20, 2017, at 12:54 PM, Michael C  wrote:
> 
> Hello Tim, everyone:
> 
> I actually have a semi-working scanner, but I can't figure out why it doesn't 
> return
> nearly as many addresses as Cheat Engine does.(for scan run #1)  Let's say I 
> am scanning the Calculator that comes with Windows.

The Windows calculator uses an arbitrary-precision math library to store its 
numbers.  It does not store them as double-precision floats.

You are only looking at PAGE_READWRITE memory.  Processes also have read-only 
memory that you can scan, but not change.

When I suggested using a buffer, what I meant is that you should allocate a 
buffer of about a megabyte, then read a megabyte at a time from the other 
process, and scan through that memory in your code.  That's much faster than 
making millions and millions of kernel calls.  You may not be aware of what 
goes on behind the scenes when you do ReadProcessMemory.  At any given time, 
only one process at a time (per CPU) can have its memory space in the page 
tables, and if it's not in the page tables, it can't be accessed.  Thus, when 
you call ReadProcessMemory, the kernel has to switch to that other process as 
if it were going to start running, load its page tables, copy the memory into 
kernel space, switch back to your process and load its page tables, copy the 
data back to you, then start you running again.  That's a lot of overhead.
— 
Tim Roberts, t...@probo.com
Providenza & Boekelheide, Inc.

___
python-win32 mailing list
python-win32@python.org
https://mail.python.org/mailman/listinfo/python-win32


Re: [python-win32] Quest for memory scanner

2017-10-20 Thread Michael C
Oh I forgot to mention what sort of advise/help I am looking for.

First, my target value to scan for is the amount gold/money in Fallout 2.
Ok, the first_scan
function caught plenty of the right values, but once I run second_scan to
compare the addresses
of those correct values, none of the addresses survived even one pass.

I think this could be a reason:
1) somehow when I ran VirtualQueryEx, not all qualifying region were
returned. I can prove
that my code has this problem:  I run Calculator from Window Accessory and
then type 400,
and '='  My code actually returns *zero* regions to be scanned. So I am
definitely not getting
all of them with my fallout 2, and *ANY* with the calculator.


P.S.
Tim, I tried to use
buffer = ctypes.c_buffer

 to create my buffer, and it hasn't returned a problem. but I don't know
what the difference
is, perhaps you could point me to something? Thanks



On Fri, Oct 20, 2017 at 12:54 PM, Michael C 
wrote:

> Hello Tim, everyone:
>
> I actually have a semi-working scanner, but I can't figure out why it
> doesn't return
> nearly as many addresses as Cheat Engine does.(for scan run #1)  Let's say
> I am scanning the Calculator that comes with Windows.
>
> Please have a look!
>
___
python-win32 mailing list
python-win32@python.org
https://mail.python.org/mailman/listinfo/python-win32


[python-win32] Quest for memory scanner

2017-10-20 Thread Michael C
Hello Tim, everyone:

I actually have a semi-working scanner, but I can't figure out why it
doesn't return
nearly as many addresses as Cheat Engine does.(for scan run #1)  Let's say
I am scanning the Calculator that comes with Windows.

Please have a look!
import ctypes
from ctypes.wintypes import WORD, DWORD, LPVOID
import psutil
import sys

def main():

PID = int(input('enter PID'))
target_value = int(input('new scan value'))

# a simple list to contain all the addresses the code finds.
hit_pool = list()

# calls the function to scan the application's memory, and then returns
# the addresses found to contain the target value, back into the list.
hit_pool = First_scan(hit_pool, target_value, PID)

# prints all the addresses to take a look.
print(hit_pool)

# calls the second scan function by passing it the hit_pool, and then
# scan for the value present in the address, compare it with the new
# target value, if they are differnt, the address is removed.
while target_value != -999:
target_value = int(input('new scan value'))
hit_pool = Second_scan(hit_pool, target_value, PID)

print('done.')

##print(hit_pool)






def First_scan(hit_pool, target_value, PID):


###
###
###
## I think this part works properly!
###
###


PVOID = LPVOID
SIZE_T = ctypes.c_size_t

# https://msdn.microsoft.com/en-us/library/aa383751#DWORD_PTR
if ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulonglong):
DWORD_PTR = ctypes.c_ulonglong
elif ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulong):
DWORD_PTR = ctypes.c_ulong

class SYSTEM_INFO(ctypes.Structure):
"""https://msdn.microsoft.com/en-us/library/ms724958""";
class _U(ctypes.Union):
class _S(ctypes.Structure):
_fields_ = (('wProcessorArchitecture', WORD),
('wReserved', WORD))
_fields_ = (('dwOemId', DWORD), # obsolete
('_s', _S))
_anonymous_ = ('_s',)
_fields_ = (('_u', _U),
('dwPageSize', DWORD),
('lpMinimumApplicationAddress', LPVOID),
('lpMaximumApplicationAddress', LPVOID),
('dwActiveProcessorMask',   DWORD_PTR),
('dwNumberOfProcessors',DWORD),
('dwProcessorType', DWORD),
('dwAllocationGranularity', DWORD),
('wProcessorLevel',WORD),
('wProcessorRevision', WORD))
_anonymous_ = ('_u',)

LPSYSTEM_INFO = ctypes.POINTER(SYSTEM_INFO)



Kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
Kernel32.GetSystemInfo.restype = None
Kernel32.GetSystemInfo.argtypes = (LPSYSTEM_INFO,)

sysinfo = SYSTEM_INFO()
Kernel32.GetSystemInfo(ctypes.byref(sysinfo))


PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010

Process = Kernel32.OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, 
False, PID)
print('process:', Process)




class MEMORY_BASIC_INFORMATION(ctypes.Structure):
"""https://msdn.microsoft.com/en-us/library/aa366775""";
_fields_ = (('BaseAddress', PVOID),
('AllocationBase',PVOID),
('AllocationProtect', DWORD),
('RegionSize', SIZE_T),
('State',   DWORD),
('Protect', DWORD),
('Type',DWORD))

mbi = MEMORY_BASIC_INFORMATION()

print('VirtualQueryEx ran properly?',Kernel32.VirtualQueryEx(Process, \
sysinfo.lpMinimumApplicationAddress, 
ctypes.byref(mbi),ctypes.sizeof(mbi)))






###
###
###
## I think the following part has a bug
###
###


ReadProcessMemory = Kernel32.ReadProcessMemory

##
MEM_COMMIT = 0x1000;
PAGE_READWRITE = 0x04;

###
###
###
###IMPORTANT!I know I am supposed to initiate buffer
###  with something, but I can't work out what to put
###  down!
buffer = ctypes.c_double()
nread = SIZE_T()
###
###
###
###

##start = ctypes.c_void_p(mbi.BaseAddress)

current_a