# Copyright 2005 Cody Brocious. Released under the terms of the GNU GPL import sys, getopt, time, struct import process def usage(): print ''' Usage: %s [options] Options: -p - PID of process (this or -n must be used) -n - Name of process (this or -p must be used) - Address to attach at - Data to watch '''.strip() % sys.argv[0] if len(sys.argv) < 5: usage() sys.exit() optlist, args = getopt.getopt(sys.argv[1:], '-p:n:', []) pid, name = None, None for o, a in optlist: if o == '-p': pid = int(a) elif o == '-n': name = a address = eval(args[0]) data = eval(args[1]) p = process.Process(name=name, pid=pid) if not p.handle: print 'Could not attach to process.' sys.exit() print 'Producing bytecode' bytecode = '\xC6\x05' + struct.pack('],90 bytecode += '\xEB\xF6' # jmp short
bytecode += '\xC6\x05' + struct.pack('],AB print 'Bytecode is:', ' '.join(['%02X' % ord(b) for b in bytecode]) print 'Reading in original code...' orig = p.read(address, len(bytecode)) print '\tDone.' print 'Reading original data...' origd = p.read(data, 1) print '\tDone.' print 'Bytecode will be written to %08X-%08X now...' % (address, address + len(bytecode)) p.write(address, bytecode) print '\tWritten.' print 'Writing data...' p.write(data, '\xCC') print '\tWritten.' print 'Waiting for flag to data change...' nop = '\x90' while True: d = p.read(data, 1) if not d: print 'Application disappeared' sys.exit() if d == nop: break time.sleep(0.1) print '\tChanged.' print 'Attach your debugger now. Set your EIP to %08X and execute the MOV that\'s there.' % (address + 9) print 'MAKE SURE YOU PAUSE AFTER THE MOV. DO _NOT_ EXECUTE ANY INSTRUCTIONS AFTER IT.\n' print 'Once you do this, the original code and data will be put back in place. You will be notified once this is done.' ab = '\xAB' while True: d = p.read(data, 1) if not d: print 'Application disappeared' sys.exit() if d == ab: break time.sleep(0.1) print 'Detected change. Writing back original code...' p.write(address, orig) print '\tDone.' print 'Writing back original data...' p.write(data, origd) print '\tDone.' print 'You can now set your EIP to %08X and debug from there.' % address print 'Enjoy.'