from sys import * from struct import * import struct import utils import time from pydbg import * from pydbg.defines import * ## --------------------------------------------------------------------------- # Reads a null terminated ascii string from a given address def readsz(dbg, addr): i=0 s="" while(1): c = dbg.read(addr + i, 1) if c == "\000": break s += c i += 1 return s ## --------------------------------------------------------------------------- class DbgLoop: def __init__(self, dbg): self.dbg = dbg self.evs = {} self.first = True self.dbg.set_callback(EXCEPTION_BREAKPOINT, self.on_bp) def add(self, c): for eip in c.eip: try: self.dbg.bp_set(eip) except: pass if eip in self.evs: self.evs[eip].append(c) else: self.evs[eip] = [c] def on_bp(self, *args): if self.first: for e in self.evs.get(0,[]): e.go(self.dbg, self.dbg.context, self.dbg.context.Eip, self) self.first = False if self.dbg.context.Eip in self.evs: for e in self.evs[self.dbg.context.Eip]: e.go(self.dbg, self.dbg.context, self.dbg.context.Eip, self) return DBG_CONTINUE def go(self): self.dbg.debug_event_loop() ## --------------------------------------------------------------------------- class ModuleEntryPoint: eip = [0xabadcafe] ## The address of WinMain() aka ModuleEntryPoint() def go(self, dbg, ctx, eip, loop): print " Hit ModuleEntryPoint" loop.add(GetCode()) class GetCode: addr = 0xdeadbeef ## The address where we'll snag code in memory eip = [ addr ] def go(self, dbg, ctx, eip, loop): stdout.write(readsz(dbg, ctx.Eax)) ## --------------------------------------------------------------------------- def main(argv): if(len(argv) < 2 ): print "supply path to encrypted perl script" exit(1) try: dbg = pydbg() dbg.load("c:\\perl\\bin\\perl.exe", "-c " + argv[1]) d = DbgLoop(dbg) d.add(ModuleEntryPoint()) d.go() finally: dbg.detach() if __name__ == '__main__': main(argv)