Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # small universal game trainer proof of concept
- # - search byte location in memory by value
- # - modify byte location in memory
- # Copyright (C) 2010 Matthias -apoc- Hecker <apoc@sixserv.org>
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- # http://bitbucket.org/haypo/python-ptrace/overview
- from ptrace.debugger.debugger import PtraceDebugger
- from ptrace.debugger.memory_mapping import readProcessMappings
- import sys
- import logging
- import os
- import pickle
- #logging.basicConfig(level=logging.DEBUG)
- if len(sys.argv) != 2:
- print "Usage: %s <PID>" % sys.argv[0]
- sys.exit()
- pid = int(sys.argv[1])
- max_memory = 0x00FFFFFF
- locations_file = "pycheat_locations.tmp"
- open(locations_file, "w").close() # truncate file
- print "pycheat: universal game trainer v0.1"
- print "process id: %d" % pid
- print "highest address: %#x" % max_memory
- def write_locations(locations):
- global locations_file
- tmpfile = open(locations_file, "w")
- pickle.dump(locations, tmpfile)
- tmpfile.close()
- def read_locations():
- global locations_file
- try:
- tmpfile = open(locations_file, "r")
- locations = pickle.load(tmpfile)
- return locations
- except:
- return None
- else:
- tmpfile.close()
- def search_memory_locations(pid, max_memory, search_value):
- child_pid = os.fork()
- if child_pid == 0: # search within forked process:
- locations = list()
- prev_locations = read_locations()
- dbg = PtraceDebugger()
- process = dbg.addProcess(pid, False)
- memory_mappings = readProcessMappings(process)
- print "\x1B[?25l", # deactivate cursor (^_^)
- for memory_mapping in memory_mappings:
- # only search in read/writable memory areas within range...
- if "rw" in memory_mapping.permissions and memory_mapping.end <= max_memory:
- for loc in range(memory_mapping.start, memory_mapping.end):
- value = process.readBytes(loc, 1)
- if value[0] == search_value:
- print "search memory area[0x%08X-0x%08X] address[0x%08X] value[0x%02X (%03d)] \r" % (memory_mapping.start, memory_mapping.end, loc, ord(value), ord(value)),
- if prev_locations and len(prev_locations) > 0 and not loc in prev_locations:
- continue # skip prev not found locations
- locations.append(loc)
- print "\x1B[?25h", # activate cursor
- dbg.quit()
- write_locations(locations)
- sys.exit()
- return child_pid # don't really need this
- def change_memory(pid, location, value):
- dbg = PtraceDebugger()
- process = dbg.addProcess(pid, False)
- process.writeBytes(location, value)
- dbg.quit()
- locations = None # loop until the correct (uniqe) location is found
- while not locations or len(locations) != 1:
- print
- if locations and len(locations) != 1:
- print "found %d occurrences, change value to:" % len(locations),
- else:
- print "searching for address by byte value:",
- search_value = "%c" % int(raw_input())
- # this forks the process and search within memory...
- search_memory_locations(pid, max_memory, search_value)
- # wait until the forked process returns/quits
- os.wait()
- # for communication with forked process a pickle tmp file is used
- locations = read_locations()
- found_location = locations[0]
- print
- print "found 1 occurrence! correct address for this value is 0x%08X" % (found_location)
- print "change value in memory at 0x%08X to:" % (found_location),
- change_value = "%c" % int(raw_input())
- change_memory(pid, found_location, change_value)
- print "done."
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement