def test_findbytes(): payload = b" " * 0x1000 + pad.null( b"\xffoo\x00bar thisis0test\n hAAAA\xc3\xc0\xc2\xc4\n\n\x10\x2f\x1f\x1a\x1b\x1f\x1d\xbb\xcc\xdd\xff", 0x10000) buf = procmem(payload, base=0x400000) assert list(buf.findbytesv("c? c? c? 0A")) == [0x40101B] assert list(buf.findbytesv(b"1f ?? ?b")) == [0x401022, 0x401025] assert list(buf.findbytesv("?f ?? ?? 00")) == [0x401000, 0x40102A] assert not list(buf.findbytesv(enhex(b"test hAAAA"))) assert list(buf.findbytesv(enhex(b"test\n hAAAA"))) assert list(buf.findbytesv(enhex(b"is"), length=0x100b)) == [0x40100a] assert list(buf.findbytesv(enhex(b"is"), length=0x100d)) == [0x40100a, 0x40100c] assert list(buf.findbytesv(enhex(b"is"), addr=0x40100b, length=0x100d)) == [0x40100c] payload = b"".join( [b"a" * 0x1000, b"b" * 0x1000, b"c" * 0x1000, b"d" * 0x1000]) regions = [ Region(0x400000, 0x1000, 0, 0, 0, 0), Region(0x401000, 0x1000, 0, 0, 0, 0x1000), Region(0x402000, 0x1000, 0, 0, 0, 0x2000), Region(0x410000, 0x1000, 0, 0, 0, 0x3000), ] p = procmem(payload, regions=regions) assert next(p.findbytesv(enhex(b"dddd"))) == 0x410000
def test_weaky(): modules = ExtractorModules("tests/files/modules") weaky = procmem(b"weakyx") strongy = procmem(b"strongy") strongyweaky = procmem(b"strongyweakyx") assert not weaky.extract(modules) assert strongy.extract(modules) == [{"family": "weaky"}] assert strongyweaky.extract(modules) == [{ "family": "weaky", "weak": True, "weaky": True }]
def test_findv(): payload = b"".join([ pad.null( pad.null(b"a" * 0x200 + b"pattern", 0x500) + b"pattern2", 0x1000), pad.null( pad.null(b"b" * 0x200 + b"pattern", 0x500) + b"pattern2", 0x1000), b"c" * 0x1000, pad.null( pad.null(b"d" * 0x200 + b"pattern", 0x500) + b"pattern2", 0x1000) ]) regions = [ Region(0x400000, 0x1000, 0, 0, 0, 0), Region(0x401000, 0x1000, 0, 0, 0, 0x1000), Region(0x402000, 0x1000, 0, 0, 0, 0x2000), Region(0x410000, 0x1000, 0, 0, 0, 0x3000), ] p = procmem(payload, regions=regions) assert list(p.findv(b"pattern")) == [ 0x400200, 0x400500, 0x401200, 0x401500, 0x410200, 0x410500 ] assert list(p.findv(b"pattern", 0x401100, 0x405)) == [0x401200] assert list(p.findv(b"pattern", length=0x10300)) == [ 0x400200, 0x400500, 0x401200, 0x401500, 0x410200 ] assert list(p.findv(b"pattern", 0x401508)) == [0x410200, 0x410500] assert list(p.findv(b"pattern", 0x403508)) == [0x410200, 0x410500]
def test_single_region(): payload = b"0123456789" regions = [Region(0x10000, 8, 0, 0, 0, 1)] mem = procmem(payload, regions=regions) assert list(mem.iter_regions()) == mem.regions assert list(mem.iter_regions(addr=0xffff)) == mem.regions assert list(mem.iter_regions(addr=0x10000)) == mem.regions assert list(mem.iter_regions(addr=0x10007)) == mem.regions assert list(mem.iter_regions(addr=0x10008)) == [] assert list(mem.iter_regions(offset=0)) == mem.regions assert list(mem.iter_regions(offset=1)) == mem.regions assert list(mem.iter_regions(offset=8)) == mem.regions assert list(mem.iter_regions(offset=9)) == [] assert list(mem.iter_regions(length=0)) == [] assert list(mem.iter_regions(length=1)) == mem.regions assert list(mem.iter_regions(addr=0xffff, length=1)) == [] assert list(mem.iter_regions(addr=0xffff, length=2)) == mem.regions assert list(mem.iter_regions(addr=0xffff, length=0x10)) == mem.regions assert list(mem.iter_regions(addr=0x10007, length=0x10)) == mem.regions assert list(mem.iter_regions(addr=0x10008, length=0x10)) == [] with pytest.raises(ValueError): # ValueError("Don't know how to retrieve length-limited regions with offset from unmapped area") list(mem.iter_regions(offset=0, length=1)) assert list(mem.iter_regions(offset=1, length=1)) == mem.regions
def test_patchv(): payload = b"".join( [b"a" * 0x1000, b"b" * 0x1000, b"c" * 0x1000, b"d" * 0x1000]) regions = [ Region(0x400000, 0x1000, 0, 0, 0, 0), Region(0x401000, 0x1000, 0, 0, 0, 0x1000), Region(0x402000, 0x1000, 0, 0, 0, 0x2000), Region(0x410000, 0x1000, 0, 0, 0, 0x3000), ] p = procmem(payload, regions=regions) with pytest.raises( ValueError, match= "Patched bytes range must be contained within single, existing region" ): p.patchv(0x3fffff, b"p" * 16) p.patchv(0x400000, b"p" * 16) assert p.readv(0x400000, 17) == b"p" * 16 + b"a" with pytest.raises( ValueError, match= "Patched bytes range must be contained within single, existing region" ): p.patchv(0x401fff, b"p" * 2)
def test_readv(): payload = b"".join([ b"a" * 0x1000, b"b" * 0x1000, b"c" * 0x1000, b"d" * 0x1000 ]) regions = [ Region(0x400000, 0x1000, 0, 0, 0, 0), Region(0x401000, 0x1000, 0, 0, 0, 0x1000), Region(0x402000, 0x1000, 0, 0, 0, 0x2000), Region(0x410000, 0x1000, 0, 0, 0, 0x3000), ] p = procmem(payload, regions=regions) assert p.readv(0x3fffff, 16) == b"" assert p.readv(0x400000, 16) == b"a" * 16 assert isinstance(p.readv(0x400000, 16), binary_type) assert p.readv(0x400fff, 16) == b"a" + b"b" * 15 assert p.readv(0x400ffe, 0x1100) == b"aa" + (b"b" * 0x1000) + (b"c" * 0xfe) assert p.readv(0x402ffe, 0x1000) == b"cc" assert p.readv(0x402ffe) == b"cc" assert p.readv(0x403000) == b"" assert p.readv(0x401000) == b"b" * 0x1000 + b"c" * 0x1000 assert p.readv(0x40ffff) == b"" assert p.readv(0x410000) == b"d" * 0x1000 assert p.readv(0x410ffe) == b"dd"
def test_multirules(): modules = ExtractorModules("tests/files/modules") multistring = procmem(b"FiRsT string fIrSt string" b"SeCoNd string sEcOnD string" b"ThIrD string tHiRd string") assert multistring.extract(modules) == [{ 'family': 'multistring', 'first': ['FiRsT string', 'fIrSt string', 'SeCoNd string', 'sEcOnD string'], 'third': ['ThIrD string'] }] multistring_v2 = procmem(b"ThIrD stringa0a1b2b3c4c5d6d7e8e9FoUrTh string") assert multistring_v2.extract(modules) == [{ 'family': 'multistring_v2', 'matched': ['v2'], 'third': ['ThIrD string'] }]
def entrypoint(self, p, hit): hit = align_down(hit, 0x200) payload = aPLib().decompress(p.readv(hit, p.imgend)) embed_pe = procmem(payload, base=0) # Fix headers embed_pe.patchp(0, b"MZ") embed_pe.patchp(embed_pe.uint32p(0x3C), b"PE") # Load patched image into procmempe embed_pe = procmempe.from_memory(embed_pe, image=True) self.push_procmem(embed_pe)
def mem(): # aaaaaaa bbbbbbccccccccdddd eeee payload = b"0123456789abcdefghijklmnopqrstuvwxyz" regions = [ Region(0x10000, 7, 0, 0, 0, 1), Region(0x10007, 6, 0, 0, 0, 10), Region(0x10100, 8, 0, 0, 0, 16), Region(0x10108, 4, 0, 0, 0, 24), Region(0x10200, 4, 0, 0, 0, 31) ] # v---0x10000 v---- 0x10100 v-- 0x10200 # VM: .....1234567abcdef..........ghijklmnopqr ..........vwxy....... return procmem(payload, base=0x10000, regions=regions)
def test_mal1(): with open("tests/files/mal1.b64") as f: mal1 = base64.b64decode(f.read()) # Load dumped image ppe = procmempe(mal1) assert not ppe.is_image_loaded_as_memdump() # Decompress payload payload = aPLib().decompress(ppe.readv(ppe.imgbase + 0x8400, ppe.imgend)) embed_pe = procmem(payload, base=0) # Fix headers embed_pe.patchp(0, b"MZ") embed_pe.patchp(embed_pe.uint32p(0x3C), b"PE") # Load patched image into procmempe embed_pe = procmempe.from_memory(embed_pe, image=True) assert embed_pe.asciiz(0x1000a410) == b"StrToIntExA"
def test_simple_findv(): payload = b"12ab34cd45ef" regions = [ Region(0x10000, 2, 0, 0, 0, 2), Region(0x10002, 2, 0, 0, 0, 6), Region(0x10010, 2, 0, 0, 0, 10) ] p = procmem(payload, regions=regions) assert list(p.findv(b"12")) == [] assert list(p.findv(b"ab")) == [0x10000] assert list(p.findv(b"ab", addr=0x10002)) == [] assert list(p.findv(b"ab34")) == [] assert list(p.findv(b"abcd")) == [0x10000] assert list(p.findv(b"abcdef")) == [] assert list(p.findv(b"cdef")) == [] assert list(p.findv(b"ef")) == [0x10010]
def test_patchv(): payload = b"".join( [b"a" * 0x1000, b"b" * 0x1000, b"c" * 0x1000, b"d" * 0x1000]) regions = [ Region(0x400000, 0x1000, 0, 0, 0, 0), Region(0x401000, 0x1000, 0, 0, 0, 0x1000), Region(0x402000, 0x1000, 0, 0, 0, 0x2000), Region(0x410000, 0x1000, 0, 0, 0, 0x3000), ] p = procmem(payload, regions=regions) with pytest.raises(ValueError, match="Cross-region patching is not supported"): p.patchv(0x3fffff, b"p" * 16) p.patchv(0x400000, b"p" * 16) assert p.readv(0x400000, 17) == b"p" * 16 + b"a" with pytest.raises(ValueError, match="Cross-region patching is not supported"): p.patchv(0x401fff, b"p" * 2)
def test_single_region_trim(): payload = b"0123456789" regions = [Region(0x10000, 8, 0, 0, 0, 1)] mem = procmem(payload, regions=regions) assert list(mem.iter_regions(trim=True)) == mem.regions assert list(mem.iter_regions(addr=0xffff, trim=True)) == mem.regions assert list(mem.iter_regions(addr=0x10000, trim=True)) == mem.regions assert list(mem.iter_regions( addr=0x10007, trim=True)) == [Region(0x10007, 1, 0, 0, 0, 8)] assert list(mem.iter_regions(addr=0x10008, trim=True)) == [] assert list(mem.iter_regions(offset=0, trim=True)) == mem.regions assert list(mem.iter_regions(offset=1, trim=True)) == mem.regions assert list(mem.iter_regions( offset=8, trim=True)) == [Region(0x10007, 1, 0, 0, 0, 8)] assert list(mem.iter_regions(offset=9, trim=True)) == [] assert list(mem.iter_regions(length=0, trim=True)) == [] assert list(mem.iter_regions( length=1, trim=True)) == [Region(0x10000, 1, 0, 0, 0, 1)] assert list(mem.iter_regions(addr=0xffff, length=1, trim=True)) == [] assert list(mem.iter_regions( addr=0xffff, length=2, trim=True)) == [Region(0x10000, 1, 0, 0, 0, 1)] assert list(mem.iter_regions( addr=0xffff, length=8, trim=True)) == [Region(0x10000, 7, 0, 0, 0, 1)] assert list( mem.iter_regions(addr=0x10001, length=4, trim=True)) == [Region(0x10001, 4, 0, 0, 0, 2)] assert list( mem.iter_regions(addr=0x10007, length=0x10, trim=True)) == [Region(0x10007, 1, 0, 0, 0, 8)] assert list(mem.iter_regions(addr=0x10008, length=0x10, trim=True)) == [] with pytest.raises(ValueError): # ValueError("Don't know how to retrieve length-limited regions with offset from unmapped area") list(mem.iter_regions(offset=0, length=1, trim=True)) assert list(mem.iter_regions( offset=1, length=1, trim=True)) == [Region(0x10000, 1, 0, 0, 0, 1)] assert list(mem.iter_regions( offset=4, length=2, trim=True)) == [Region(0x10003, 2, 0, 0, 0, 4)]
def test_utf16z(): payload = b"\x00\x00a\x00b\x00c\x00\x00\x00" p = procmem(payload, base=0x400000) assert p.utf16z(0x400000) == b"" assert p.utf16z(0x400002) == b"abc"