def test_procmem_dummy_dmp(): p = procmem("tests/files/dummy.dmp") assert len(p.regions) == 3 assert p.regions[0].to_json() == { "addr": "0x41410000", "end": "0x41411000", "offset": 24, "size": 0x1000, "state": 0, "type": 0, "protect": "rwx", } assert p.regions[1].to_json() == { "addr": "0x41411000", "end": "0x41413000", "offset": 4144, "protect": "r", "size": 0x2000, "state": 42, "type": 43, } assert p.regions[2].to_json() == { "addr": "0x42420000", "end": "0x42421000", "offset": 12360, "protect": "r", "size": 0x1000, "state": 0, "type": 0, } p = procmem("tests/files/dummy.dmp", False) assert len(p.regions) == 3 assert p.readv(0x41410f00, 0x200) == b"A" * 0xf4 + b"X" * 4 + b"A" * 8 + b"B" * 0x100 assert p.uint8p(p.v2p(0x41410fff)) == 0x41 assert p.uint8v(0x41410fff) == 0x41 assert p.uint16p(p.v2p(0x4141100f)) == 0x4242 assert p.uint16v(0x4141100f) == 0x4242 assert p.uint32p(p.v2p(0x42420000)) == 0x43434343 assert p.uint32v(0x42420000) == 0x43434343 assert p.uint64p(p.v2p(0x41410ff8)) == 0x4141414141414141 assert p.uint64v(0x41410ffe) == 0x4242424242424141 assert p.p2v(p.v2p(0x41411414)) == 0x41411414 assert p.uint8v(0x1000) is None assert p.uint16v(0x1000) is None assert p.uint32v(0x1000) is None assert p.uint64v(0x1000) is None
def test_calc_dmp(): p = procmem("tests/files/calc.dmp") assert p.regions == procmempe("tests/files/calc.dmp", 0xd0000).regions assert p.findmz(0x129abc) == 0xd0000 p = procmempe(p, 0xd0000) assert p[0] == b"M" and p[1] == b"Z" and p[:2] == b"MZ" # Old/regular method with PE header. assert pe(p.readv(p.imgbase, 0x1000)).dos_header.e_lfanew == 0xd8 assert p[0xd8:0xdc] == b"PE\x00\x00" assert pe(p).is32bit is True d = pe(p).optional_header.DATA_DIRECTORY[2] assert d.VirtualAddress == 0x59000 and d.Size == 0x62798 data = pe(p).resource(b"WEVT_TEMPLATE") assert data.startswith(b"CRIM") assert len(data) == 4750 # In this case imgbase + OptionalHeader.SizeOfImage adds up to 0x190000. # TODO Should we take the upper bound, lower bound, or depending on whether # in-between is completely filled with zeroes? p = procmempe.fromaddr("tests/files/calc.dmp", 0xe9999) assert p.imgbase == 0xd0000 assert p.imgend == 0x18fb3c p = procmempe.fromoffset("tests/files/calc.dmp", 0x12345) assert p.imgbase == 0xd0000 assert p.pe.is32bit is True
def test_pe2procmem(): a = pe(open("tests/files/calc.exe", "rb").read()) b = procmem( io.BytesIO(pe2procmem(open("tests/files/calc.exe", "rb").read()))) assert a.sections[2].SizeOfRawData == b.regions[3].size assert a.sections[3].get_data() == b.readv(b.regions[4].addr, b.regions[4].size)
def procmem_list(mempath): p = procmem(mempath) for region in p.regions: s = p.readv(region.addr, 16) if isinstance(s, str): print("0x%08x .. 0x%08x" % (region.addr, region.addr + region.size)), print(repr(s)) else: s = "'"+"".join([chr(c) for c in s])+"'" print("0x%08x .. 0x%08x" % (region.addr, region.addr + region.size), s)
def run(self): """Run analysis. @return: structured results. """ self.key = "procmemory" results = [] if os.path.exists(self.pmemory_path): for dmp in os.listdir(self.pmemory_path): if not dmp.endswith(".dmp"): continue dump_path = os.path.join(self.pmemory_path, dmp) dump_file = File(dump_path) pid, num = map(int, re.findall("(\\d+)", dmp)) regions = [] for region in roach.procmem(dump_path).regions: regions.append(region.to_json()) proc = dict( file=dump_path, pid=pid, num=num, yara=dump_file.get_yara("memory"), urls=list(dump_file.get_urls()), regions=regions, ) ExtractManager.for_task(self.task["id"]).peek_procmem(proc) if self.options.get("idapro"): self.create_idapy(proc) if self.options.get("extract_img"): proc["extracted"] = list( self.dump_images(proc, self.options.get("extract_dll"))) proc["extracted"] += list(self.dump_dex(proc)) if self.options.get("dump_delete"): try: os.remove(dump_path) except OSError: log.error( "Unable to delete memory dump file at path \"%s\"", dump_path) results.append(proc) results.sort(key=lambda x: (x["pid"], x["num"])) return results
def run(self): """Run analysis. @return: structured results. """ self.key = "procmemory" results = [] if os.path.exists(self.pmemory_path): for dmp in os.listdir(self.pmemory_path): if not dmp.endswith(".dmp"): continue dump_path = os.path.join(self.pmemory_path, dmp) dump_file = File(dump_path) pid, num = map(int, re.findall("(\\d+)", dmp)) regions = [] for region in roach.procmem(dump_path).regions: regions.append(region.to_json()) proc = dict( file=dump_path, pid=pid, num=num, yara=dump_file.get_yara("memory"), urls=list(dump_file.get_urls()), regions=regions, ) ExtractManager.for_task(self.task["id"]).peek_procmem(proc) if self.options.get("idapro"): self.create_idapy(proc) if self.options.get("extract_img"): proc["extracted"] = list(self.dump_images( proc, self.options.get("extract_dll") )) if self.options.get("dump_delete"): try: os.remove(dump_path) except OSError: log.error( "Unable to delete memory dump file at path \"%s\"", dump_path ) results.append(proc) results.sort(key=lambda x: (x["pid"], x["num"])) return results
def test_methods(): fd, filepath = tempfile.mkstemp() os.write(fd, "".join(( struct.pack("QIIII", 0x401000, 0x1000, 0, 0, PAGE_READWRITE), pad.null("foo\x00bar thisis0test\n hAAAA\xc3", 0x1000), ))) os.close(fd) buf = procmem(filepath) assert buf.readv(0x401000, 0x1000).endswith("\x00"*0x100) assert list(buf.regexv("thisis(.*)test")) == [0x401008] assert list(buf.regexv(" ")) == [0x401007, 0x401014] assert list(buf.regexv(" ", 0x401000, 0x10)) == [0x401007] assert list(buf.regexv("test..h")) == [0x40100f] assert buf.disasmv(0x401015, 6) == [ insn("push", 0x41414141, addr=0x401015), insn("ret", addr=0x40101a), ]
def test_mmap(): fd, filepath = tempfile.mkstemp() os.close(fd) assert procmem(filepath).regions == [] assert procmem(io.BytesIO(b"")).regions == []
def procmem_list(mempath): p = procmem(mempath) for region in p.regions: print "0x%08x .. 0x%08x" % (region.addr, region.addr + region.size), print repr(p.readv(region.addr, 16))