risen napisał(a)
problem w tym, że mam problemy ze znalezieniem pointerów lub adresów do nie znanej mi wartości.
Przed pójściem spać dla przypomnienia sobie ctypes napisałem mały skrypt w Pythonie:
from ctypes import *
from sys import stdout, stderr, argv
MEM_COMMIT = 0x1000
PAGE_NOACCESS = 0x0001
PAGE_GUARD = 0x0100
PROCESS_VM_READ = 0x0010
PROCESS_QUERY_INFORMATION = 0x0400
class MEMORY_BASIC_INFORMATION(Structure):
_fields_ = [
('BaseAddress', c_ulong),
('AllocationBase', c_ulong),
('AllocationProtect', c_ulong),
('RegionSize', c_ulong),
('State', c_ulong),
('Protect', c_ulong),
('Type', c_ulong) ]
class SYSTEM_INFO(Structure):
_fields_ = [
('unused1', c_ulong * 2),
('lpMinimumApplicationAddress', c_ulong),
('lpMaximumApplicationAddress', c_ulong),
('unused2', c_ulong * 5) ]
K32 = windll.kernel32
CRT = cdll.msvcrt
def enumMemoryBlocks(hProcess):
blocks = []
systemInfo = SYSTEM_INFO()
K32.GetSystemInfo(byref(systemInfo))
currentPtr = systemInfo.lpMinimumApplicationAddress
while currentPtr < systemInfo.lpMaximumApplicationAddress:
memoryInfo = MEMORY_BASIC_INFORMATION()
if not K32.VirtualQueryEx(hProcess, currentPtr, byref(memoryInfo), sizeof(memoryInfo)):
raise RuntimeError('VirtualQueryEx failed!')
if memoryInfo.State == MEM_COMMIT:
if memoryInfo.Protect & (PAGE_GUARD | PAGE_NOACCESS) == 0:
blocks.append(memoryInfo)
currentPtr += memoryInfo.RegionSize
return blocks
def isValidPtr(ptr, blocks):
return any(b.AllocationBase <= ptr < b.BaseAddress + b.RegionSize for b in blocks)
def findPtrs(hProcess, blocks):
ptrsTab = []
for n, b in enumerate(blocks):
buff = CRT.malloc(b.RegionSize)
stderr.write('\rscanning [%d/%d]... ' % (n + 1, len(blocks)))
stderr.flush()
if not buff:
raise RuntimeError('Malloc failed!')
if not K32.ReadProcessMemory(hProcess, b.BaseAddress, buff, b.RegionSize, None):
raise RuntimeError('ReadProcessMemory failed!')
for o in range(b.RegionSize + 1 - sizeof(c_ulong)):
if isValidPtr(cast(buff + o, POINTER(c_ulong))[0], blocks):
ptrsTab.append(buff + o)
CRT.free(buff)
stderr.write('\rscanning compleated!\n')
stderr.flush()
return ptrsTab
if __name__ == '__main__':
import psyco; psyco.full()
hProc = None
if len(argv) > 1:
hProc = K32.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, int(argv[1]))
if hProc == -1:
raise RuntimeError('OpenProcess failed!')
else:
hProc = K32.GetCurrentProcess()
blocks = enumMemoryBlocks(hProc)
ptrs = findPtrs(hProc, blocks)
for p in ptrs:
stdout.write('potential pointer detected: %08lx\n' % p)
stdout.write('\nsummary: %d pointers detected.\n' % len(ptrs))
stdout.flush()
K32.CloseHandle(hProc)
Wersja bez Psyco jakieś 4 godziny mieliła suspendnięty Notatnik na VM, ile skompilowana to jeszcze nie wiem. Przegląda tylko dostępne bloki pamięci, bez ochrony, wyszukuje coś, co można za wskaźnik uznać, jeżeli wskazuje pod jeden z takich obszarów. O ile się nie machnąłem to znalazł prawie 900000 rzeczy mogących być 'pointerami do nieznanych wartości'.
risen napisał(a)
No ale np. chcę sobie czołg stworzyć lub podobnych tego typu rzeczy, w których nie widać wartości wizualnie.. O to mi się ciągle rozchodzi..
No to teraz już wiemy, że nawet normalnej gry 'z czołgami' napisać nie potrafisz. Jest jakiś uniwersalny sposób opisu czołgów? Znasz strukturę obiektu reprezentującego czołg? Menadżera obiektów? Nie. Obiekt może nawet nie być przez nic wskazywany (może być częścią czegoś większego lub np. siedzieć w tablicy). Tutaj nie ma durnego wyszukiwania wartości na pałę, jest analiza danych gry lub binarki. W pierwszym wypadku to nic wielkiego, dowiedz się jak wygląda tworzenie modów do gier. W drugim - dowiedz się co to reverse engineering i zapomnij, najpiew naucz się normalnego programowania.