예제 #1
0
    def build_content(self):
        c = StrPatchwork()
        c[self.NThdr.sizeofheaders - 1] = pe.data_null
        c[0] = self.DOShdr.pack()

        # fix image size
        if len(self.SHList):
            s_last = self.SHList.shlist[-1]
            size = s_last.vaddr + s_last.rsize + (self.NThdr.sectionalignment -
                                                  1)
            size &= ~(self.NThdr.sectionalignment - 1)
            self.NThdr.sizeofimage = size

        # headers
        self.build_headers(c)

        # section headers
        off = self.DOShdr.lfanew \
            + self.NTsig.bytelen \
            + self.COFFhdr.bytelen \
            + self.COFFhdr.sizeofoptionalheader
        c[off] = self.SHList.pack()
        off += self.SHList.bytelen
        end_of_headers = off

        # section data
        # note that the content of directories should have been already
        # included section data, which is possible because position and
        # size of sections are known at this point
        for s in sorted(self.SHList, key=lambda _: _.scnptr):
            if s.rawsize == 0:
                continue
            if end_of_headers > s.scnptr:
                log.warning("section %s offset %#x overlap pe hdr %#x", s.name,
                            s.scnptr, off)
            elif off > s.scnptr:
                log.warning("section %s offset %#x overlap previous section",
                            s.name, s.scnptr)
            off = s.scnptr + s.rawsize
            c[s.scnptr:off] = s.section_data.data.pack()

        # symbols and strings
        if self.COFFhdr.numberofsymbols:
            self.COFFhdr.pointertosymboltable = off
            c[off] = self.Symbols.pack()
            assert self.Symbols.bytelen == 18 * self.COFFhdr.numberofsymbols
            off += self.Symbols.bytelen
            c[off] = self.SymbolStrings.pack()

        # some headers may have been updated when building sections or symbols
        self.build_headers(c)

        # final verifications
        l = self.DOShdr.lfanew + self.NTsig.bytelen + self.COFFhdr.bytelen
        if l % 4:
            log.warning("non aligned coffhdr, bad crc calculation")
        crcs = self.patch_crc(c.pack(), self.NThdr.CheckSum)
        c[l + 64] = struct.pack('I', crcs)
        return c.pack()
예제 #2
0
 def pack(self):
     c = StrPatchwork()
     c[0] = self.hdr.pack()
     of = self.hdr.bytelen
     for s in self.sections:
         c[of] = s.pack()
         of += s.bytelen
     return c.pack()
예제 #3
0
 def build_content(self):
     if self.Ehdr.shoff == 0:
         elf_set_offsets(self)
     c = StrPatchwork()
     c[0] = self.Ehdr.pack()
     c[self.Ehdr.phoff] = self.ph.pack()
     for s in self.sh:
         c[s.sh.offset] = s.pack()
     c[self.Ehdr.shoff] = self.sh.pack()
     return c.pack()
예제 #4
0
 def build_content(self):
     if self.Ehdr.shoff == 0:
         elf_set_offsets(self)
     c = StrPatchwork()
     c[0] = self.Ehdr.pack()
     c[self.Ehdr.phoff] = self.ph.pack()
     for s in self.sh:
         c[s.sh.offset] = s.pack()
     sh = self.sh.pack()
     if len(sh):
         # When 'shoff' is invalid, 'sh' is empty, but the line below
         # is very slow because strpatchwork extends the file.
         c[self.Ehdr.shoff] = sh
     return c.pack()
예제 #5
0
    def __init__(self, parent, **kargs):
        self.parent = parent
        inheritsexwsize(self, parent, kargs)
        self.shlist = []
        ehdr = self.parent.Ehdr
        of1 = ehdr.shoff
        if not of1:  # No SH table
            return
        filesize = len(parent.content)
        if of1 > filesize:
            log.error("Offset to section headers after end of file")
            return
        if of1 + ehdr.shnum * ehdr.shentsize > filesize:
            log.error("Offset to end of section headers after end of file")
            return
        for i in range(ehdr.shnum):
            of2 = of1 + ehdr.shentsize
            shstr = parent[of1:of2]
            self.shlist.append(Section.create(self, shstr=shstr))
            of1 = of2
        assert len(self.shlist) == ehdr.shnum
        # The shstrtab section is not always valid :-(
        if 0 <= ehdr.shstrndx < ehdr.shnum:
            self._shstrtab = self.shlist[ehdr.shstrndx]
        else:
            self._shstrtab = None
        if not isinstance(self._shstrtab, StrTable):

            class NoStrTab(object):
                def get_name(self, idx):
                    return "<no-name>"

            self._shstrtab = NoStrTab()

        if ehdr.shnum == 0: return

        for s in self.shlist:
            if not isinstance(s, NoBitsSection):
                if s.sh.offset > filesize:
                    log.error("Offset to section %d after end of file",
                              self.shlist.index(s))
                    continue
                if s.sh.offset + s.sh.size > filesize:
                    log.error("Offset to end of section %d after end of file",
                              self.shlist.index(s))
                    continue
                s.content = StrPatchwork(parent[s.sh.offset:s.sh.offset +
                                                s.sh.size])
        # Follow dependencies when initializing sections
        zero = self.shlist[0]
        todo = self.shlist[1:]
        done = []
        while todo:
            s = todo.pop(0)
            if ((s.linksection in done + [zero, NoLinkSection])
                    and (s.infosection in done + [zero, None])):
                done.append(s)
                s.parse_content()
            else:
                todo.append(s)
예제 #6
0
def test_ELF_offset_to_sections(assertion):
    global log_history
    data = StrPatchwork(ELF().pack())
    data[88+20] = struct.pack("<I", 0x1000)
    e = ELF(data)
    assertion([('error', ('Offset to end of section %d after end of file', 0), {})],
              log_history,
              'Section offset+size too far away (logs)')
    log_history = []
    data[88+16] = struct.pack("<I", 0x1000)
    e = ELF(data)
    assertion([('error', ('Offset to section %d after end of file', 0), {})],
              log_history,
              'Section offset very far away (logs)')
    log_history = []
    data[32] = struct.pack("<I", 100) # e.Ehdr.shoff
    e = ELF(data)
    assertion([('error', ('Offset to end of section headers after end of file',), {}),
               ('error', ('No section of index shstrndx=2',), {})],
              log_history,
              'SH offset too far away (logs)')
    log_history = []
    data[32] = struct.pack("<I", 0x2000) # e.Ehdr.shoff
    e = ELF(data)
    assertion([('error', ('Offset to section headers after end of file',), {}),
               ('error', ('No section of index shstrndx=2',), {})],
              log_history,
              'SH offset very far away (logs)')
    log_history = []
예제 #7
0
def test_ELF_wordsize_endianess(assertion):
    global log_history
    data = StrPatchwork(ELF().pack())
    data[4] = struct.pack("B", 4)
    e = ELF(data)
    assertion([('error', ('Invalid ELF, wordsize defined to %d', 128), {})],
              log_history,
              'Invalid ELF word size (logs)')
    log_history = []
    data = StrPatchwork(ELF().pack())
    data[5] = struct.pack("B", 0)
    e = ELF(data)
    assertion([('error', ('Invalid ELF, endianess defined to %d', 0), {})],
              log_history,
              'Invalid ELF endianess (logs)')
    log_history = []
예제 #8
0
 def __init__(self, parent, sh=None, **kargs):
     self.parent = parent
     self.phparent = None
     inheritsexwsize(self, parent, {})
     if sh is None:
         sh = elf.Shdr(parent=self, type=self.sht, name_idx=0, **kargs)
     self.sh = sh
     self.content = StrPatchwork()
예제 #9
0
 def __init__(self, data = None, **kargs):
     self.sections = []
     if data is not None:
         self.content = StrPatchwork(data)
         self.parse_content()
         return
     # Create a RPRC file with no section
     self.hdr = RPRChdr(parent=self)
예제 #10
0
파일: rprc.py 프로젝트: yd0b0N/elfesteem
 def __init__(self, data=None, **kargs):
     self.sections = []
     if data is not None:
         self.content = StrPatchwork(data)
         self.parse_content()
     else:
         # Create a RPRC file with no section
         self.hdr = Header(parent=self)
     self._virt = Virtual(self)
예제 #11
0
    def asm(self):
        blocs, symbol_pool = parse_asm.parse_txt(mn_aarch64, 'l', self.TXT,
                                                 symbol_pool = self.myjit.ir_arch.symbol_pool)
        # fix shellcode addr
        symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0)
        s = StrPatchwork()
        patches = asmbloc.asm_resolve_final(mn_aarch64, blocs, symbol_pool)
        for offset, raw in patches.items():
            s[offset] = raw

        self.assembly = str(s)
예제 #12
0
파일: sign.py 프로젝트: achow101/signapple
    def make_signature(self):
        """
        Attaches the signature
        """
        # Get the CodeSignature section. It should be the last in the binary
        cs_sec = self.macho.sect[-1]
        assert cs_sec == self.get_linkedit_segment().sect[-1]
        assert isinstance(cs_sec, CodeSignature)
        sig_cmd = self.get_sig_command()

        # Set the section's content to be the signature
        cs_sec.content = StrPatchwork(self.sig_data)
예제 #13
0
파일: sign.py 프로젝트: achow101/signapple
    def make_signature(self):
        assert self.sig.code_dir_blob

        # Redo the code hashes
        self._set_code_hashes()

        # Make the signature
        signed_attrs: CMSAttributes = make_signed_attrs(
            self.sig.code_dir_blob.get_hash(self.hash_type), self.hash_type)
        actual_privkey = load_private_key(self.privkey)
        signature = rsa_pkcs1v15_sign(actual_privkey, signed_attrs.dump(),
                                      self.hash_type_str)

        # Get the timestamp from Apple
        digest = get_hash(signature, self.hash_type)
        tst = CMSAttribute({
            "type":
            CMSAttributeType("signature_time_stamp_token"),
            "values": [get_timestamp_token(digest, self.hash_type)],
        })

        # Make the CMS
        self.sig.sig_blob = SignatureBlob()
        self.sig.sig_blob.cms = make_cms(self.cert, self.hash_type,
                                         signed_attrs, signature,
                                         CMSAttributes([tst]))

        # Get the CodeSignature section. It should be the last in the binary
        cs_sec = self.macho.sect[-1]
        assert cs_sec == self.get_linkedit_segment().sect[-1]
        assert isinstance(cs_sec, CodeSignature)
        sig_cmd = self.get_sig_command()

        # Serialize the signature
        f = BytesIO()
        self.sig.serialize(f)
        f.write((sig_cmd.datasize - f.tell()) * b"\x00")

        if self.detach_target:
            target_dir = os.path.join(self.detach_target, "Contents", "MacOS")
            os.makedirs(target_dir, exist_ok=True)
            target_file = os.path.join(
                target_dir,
                os.path.basename(self.filename) +
                f".{CPU_NAMES[self.macho.Mhdr.cputype]}sign",
            )
            with open(target_file, "wb") as tf:
                tf.write(f.getvalue())
                self.files_modified.append(target_file)
        else:
            # Set the section's content to be the signature
            cs_sec.content = StrPatchwork(f.getvalue())
예제 #14
0
    def asm(self):
        blocks, loc_db = parse_asm.parse_txt(mn_aarch64,
                                             'l',
                                             self.TXT,
                                             loc_db=self.myjit.ir_arch.loc_db)
        # fix shellcode addr
        loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0)
        s = StrPatchwork()
        patches = asmblock.asm_resolve_final(mn_aarch64, blocks, loc_db)
        for offset, raw in patches.items():
            s[offset] = raw

        self.assembly = str(s)
예제 #15
0
 class CDataInstance(CBase):
     def _initialize(self, f=f):
         self._size = f(self.parent)
         self._data = StrPatchwork()
     def unpack(self, c, o):
         self._data[0] = c[o:o+self._size]
     def pack(self):
         return self._data.pack()
     def __str__(self):
         return self.pack().decode('latin1')
     def __getitem__(self, item):
         return self._data[item]
     def __setitem__(self, item, value):
         self._data[item] = value
예제 #16
0
 def __init__(self, elfstr=None, **kargs):
     self._virt = virt(self)
     if elfstr is None:
         # Create an ELF file, with default header values
         # kargs can supersede these default values
         self.wsize = kargs.get('wsize', 32)
         self.sex = kargs.get('sex', '<')
         self.Ehdr = elf.Ehdr(parent=self)
         self.Ehdr.ident = struct.pack(
             "16B",
             0x7f,
             0x45,
             0x4c,
             0x46,  # magic number, \x7fELF
             {
                 32: 1,
                 64: 2
             }[self.wsize],  # EI_CLASS
             {
                 '<': 1,
                 '>': 2
             }[self.sex],  # EI_DATA
             1,  # EI_VERSION
             0,  # EI_OSABI
             0,  # EI_ABIVERSION
             0,
             0,
             0,
             0,
             0,
             0,
             0)
         self.Ehdr.version = 1
         self.Ehdr.type = kargs.get('e_type', elf.ET_REL)
         self.Ehdr.machine = kargs.get('e_machine', elf.EM_386)
         self.Ehdr.ehsize = self.Ehdr.bytelen
         self.sh = SHList(self)
         self.ph = PHList(self)
         elf_default_content(self, **kargs)
         return
     self.content = StrPatchwork(elfstr)
     self.parse_content()
     try:
         self.check_coherency()
     except ValueError:
         # Report the exception message in a way compatible with most
         # versions of python.
         import sys
         log.error(str(sys.exc_info()[1]))
예제 #17
0
파일: dse.py 프로젝트: xxtxiaofeng/miasm
    def asm(self):
        mn_x86 = self.machine.mn
        blocks, loc_db = parse_asm.parse_txt(mn_x86,
                                             self.arch_attrib,
                                             self.TXT,
                                             loc_db=self.myjit.ir_arch.loc_db)

        # fix shellcode addr
        loc_db.set_location_offset(loc_db.get_name_location("main"), 0x0)
        output = StrPatchwork()
        patches = asm_resolve_final(mn_x86, blocks, loc_db)
        for offset, raw in patches.items():
            output[offset] = raw

        self.assembly = str(output)
예제 #18
0
def assemble_text(src_text, symbols=[], mach_name="x86_64", mach_attr=64):
    # 指定アーキテクチャのニーモニックを取得
    mnemo = Machine(mach_name).mn
    # セクションとシンボルの取得
    sections, symbol_pool = parse_asm.parse_txt(mnemo, mach_attr, src_text)
    # シンボル毎のアドレスを設定
    for name, addr in symbols:
        symbol_pool.set_offset(symbol_pool.getby_name(name), addr)
    # アセンブル
    patches = asmbloc.asm_resolve_final(mnemo, sections[0], symbol_pool)
    # アセンブル結果の構築
    patch_worker = StrPatchwork()
    for offset, raw in patches.items():
        patch_worker[offset] = raw

    return str(patch_worker)
예제 #19
0
파일: dse.py 프로젝트: damnya/miasm
    def asm(self):
        mn_x86 = self.machine.mn
        blocks, symbol_pool = parse_asm.parse_txt(
            mn_x86,
            self.arch_attrib,
            self.TXT,
            symbol_pool=self.myjit.ir_arch.symbol_pool
        )

        # fix shellcode addr
        symbol_pool.set_offset(symbol_pool.getby_name("main"), 0x0)
        output = StrPatchwork()
        patches = asm_resolve_final(mn_x86, blocks, symbol_pool)
        for offset, raw in patches.items():
            output[offset] = raw

        self.assembly = str(output)
예제 #20
0
def test_PE_invalids(assertion):
    # Some various ways for a PE to be detected as invalid
    e = PE()
    data = StrPatchwork(e.pack())
    try:
        e.NTsig.signature = 0x2000
        e = PE(e.pack())
        assertion(0,1, 'Not a PE, invalid NTsig')
    except ValueError:
        pass
    try:
        e.DOShdr.lfanew = 0x200000
        data[60] = struct.pack("<I", e.DOShdr.lfanew)
        e = PE(data)
        assertion(0,1, 'Not a PE, NTsig offset after eof')
    except ValueError:
        pass
예제 #21
0
파일: sign.py 프로젝트: achow101/signapple
    def allocate(self):
        for cs in self.code_signers:
            # Get fresh calculations of offset and size
            sig_offset = cs.calculate_sig_offset()
            sig_size = cs.get_size_estimate()
            sig_end = sig_offset + sig_size

            # Get the linkedit segment
            linkedit_seg = cs.get_linkedit_segment()
            linkedit_end = linkedit_seg.fileoff + linkedit_seg.filesize

            cmd = cs.get_sig_command()
            if cmd is not None:
                # Existing sig command. Get the CodeSignature section. It should be last one in the binary.
                cs_sec = cs.macho.sect[-1]
                sig_size = sig_size if sig_size > cmd.datasize else cmd.datasize
            else:
                # No existing sig command, so add one.
                cmd = linkedit_data_command(cmd=LC_CODE_SIGNATURE,
                                            parent=cs.macho.load)

                # Add the load command
                cs.macho.load.append(cmd)

                # Create a CodeSignature section
                cs_sec = CodeSignature(parent=cmd)

                # Add it to the binary
                # Note, don't use linkedit_seg.addSH because linkedit doesn't actually have segments.
                linkedit_seg.sect.append(cs_sec)
                cs.macho.sect.add(cs_sec)

            # Set the size, offset, and empty content of the CodeSignature section
            cmd.dataoff = sig_offset
            cmd.datasize = sig_size
            cs_sec.size = sig_size
            cs_sec.offset = sig_offset
            cs_sec.content = StrPatchwork(sig_size * b"\x00")

            # increase linkedit size
            end_diff = sig_end - linkedit_end
            if end_diff > 0:
                linkedit_seg.filesize += end_diff
                linkedit_seg.vmsize = round_up(linkedit_seg.filesize,
                                               cs.page_size)
예제 #22
0
 def __init__(self, elfstr=None, **kargs):
     self._virt = virt(self)
     if elfstr is None:
         # Create an ELF file, with default header values
         # kargs can supersede these default values
         self.wsize = kargs.get('wsize', 32)
         self.sex = kargs.get('sex', '<')
         self.Ehdr = elf.Ehdr(parent=self)
         self.Ehdr.ident = struct.pack(
             "16B",
             0x7f,
             0x45,
             0x4c,
             0x46,  # magic number, \x7fELF
             {
                 32: 1,
                 64: 2
             }[self.wsize],  # EI_CLASS
             {
                 '<': 1,
                 '>': 2
             }[self.sex],  # EI_DATA
             1,  # EI_VERSION
             0,  # EI_OSABI
             0,  # EI_ABIVERSION
             0,
             0,
             0,
             0,
             0,
             0,
             0)
         self.Ehdr.version = 1
         self.Ehdr.type = kargs.get('e_type', elf.ET_REL)
         self.Ehdr.machine = kargs.get('e_machine', elf.EM_386)
         self.Ehdr.ehsize = self.Ehdr.bytelen
         self.sh = SHList(self)
         self.ph = PHList(self)
         elf_default_content(self, **kargs)
         return
     self.content = StrPatchwork(elfstr)
     self.parse_content()
     self.check_coherency()
예제 #23
0
    def __init__(self, minidump_str):
        self._content = StrPatchwork(minidump_str)

        # Specific streams
        self.modulelist = None
        self.memory64list = None
        self.memorylist = None
        self.memoryinfolist = None
        self.systeminfo = None

        # Get information
        self.streams = []
        self.threads = None
        self.parse_content()

        # Memory information
        self.memory = {}  # base address (virtual) -> Memory information
        self.build_memory()
        self.virt = ContentVirtual(self)
예제 #24
0
def test_COFF_invalidity(assertion):
    global log_history
    # Some various ways for a COFF to be detected as invalid
    obj_mingw = open(__dir__+'/binary_input/coff_mingw.obj', 'rb').read()
    obj_mingw = StrPatchwork(obj_mingw)
    e = COFF(obj_mingw)
    try:
        obj_mingw[2] = struct.pack("<H", 0)
        e = COFF(obj_mingw)
        assertion(0,1, 'COFF cannot have no section')
    except ValueError:
        pass
    try:
        obj_mingw[2] = struct.pack("<H", 0x2000)
        e = COFF(obj_mingw)
        assertion(0,1, 'Too many sections in COFF')
    except ValueError:
        pass
    try:
        obj_mingw[2] = struct.pack("<H", 0x100)
        e = COFF(obj_mingw)
        assertion(0,1, 'Too many sections in COFF, past end of file')
    except ValueError:
        pass
    try:
        obj_mingw[2] = struct.pack("<H", 3)
        obj_mingw[8] = struct.pack("<I", 0x100000)
        e = COFF(obj_mingw)
        assertion(0,1, 'COFF invalid ptr to symbol table')
    except ValueError:
        pass
    obj_mingw[8] = struct.pack("<I", 220)
    obj_mingw[436] = struct.pack("<I", 10000)
    e = COFF(obj_mingw)
    assertion([('warn', ('File too short for StrTable 0x4 != 0x2710',), {})],
              log_history,
              'File too short for StrTable (logs)')
    log_history = []
    assertion([],
              log_history,
              'No non-regression test created unwanted log messages')
예제 #25
0
    def __init__(self, parent, **kargs):
        self.parent = parent
        inheritsexwsize(self, parent, kargs)
        self.shlist = []
        ehdr = self.parent.Ehdr
        of1 = ehdr.shoff
        if not of1:  # No SH table
            return
        for i in range(ehdr.shnum):
            of2 = of1 + ehdr.shentsize
            shstr = parent[of1:of2]
            self.shlist.append(Section.create(self, shstr=shstr))
            of1 = of2
        # The shstrtab section is not always valid :-(
        self._shstrtab = self.shlist[ehdr.shstrndx]
        if not isinstance(self._shstrtab, StrTable):

            class NoStrTab(object):
                def get_name(self, idx):
                    return "<no-name>"

            self._shstrtab = NoStrTab()

        for s in self.shlist:
            if not isinstance(s, NoBitsSection):
                s._content = StrPatchwork(parent[s.sh.offset:s.sh.offset +
                                                 s.sh.size])
        # Follow dependencies when initializing sections
        zero = self.shlist[0]
        todo = self.shlist[1:]
        done = []
        while todo:
            s = todo.pop(0)
            if ((s.linksection in done + [zero, None]) and
                (s.infosection in [zero, None] or s.infosection in done)):
                done.append(s)
                s.parse_content()
            else:
                todo.append(s)
        for s in self.shlist:
            self.do_add_section(s)
예제 #26
0
class LinkEditSection(BaseSection):
    type = 'data'

    def unpack(self, c, o):
        if self.parent is not None: assert o == self.offset
        self.content = StrPatchwork(c[o:o + self.size])

    def get_size(self):
        return getattr(self.parent, self.type + 'size')

    def set_size(self, val):
        setattr(self.parent, self.type + 'size', val)

    size = property(get_size, set_size)
    addr = property(lambda _: 0)

    def pack(self):
        return self.content.pack()

    def __str__(self):
        return "%-30s %-10s %#010x %#010x" % (self.__class__.__name__, '',
                                              self.offset, self.size)
예제 #27
0
    new_dll = [({
        "name": "USER32.dll",
        "firstthunk": s_iat.addr
    }, ["MessageBoxA"])]
    pe.DirImport.add_dlldesc(new_dll)
    s_myimp = pe.SHList.add_section(name="myimp", rawsize=len(pe.DirImport))
    pe.DirImport.set_rva(s_myimp.addr)
    pe.Opthdr.AddressOfEntryPoint = s_text.addr

    addr_main = pe.rva2virt(s_text.addr)
    virt = pe.virt
    output = pe
    dst_interval = interval([(pe.rva2virt(s_text.addr),
                              pe.rva2virt(s_text.addr + s_text.size))])
else:
    st = StrPatchwork()

    addr_main = 0
    virt = st
    output = st

# Get and parse the source code
with open(args.source) as fstream:
    source = fstream.read()

blocks, symbol_pool = parse_asm.parse_txt(machine.mn, attrib, source)

# Fix shellcode addrs
symbol_pool.set_offset(symbol_pool.getby_name("main"), addr_main)

if args.PE:
예제 #28
0
 def set_content(self, val):
     self.__content = StrPatchwork(val)
예제 #29
0
 def unpack(self, c, o):
     if self.parent is not None: assert o == self.offset
     self.content = StrPatchwork(c[o:o + self.size])
예제 #30
0
parser.add_argument('-v', "--verbose",
                    help="verbose mode", action="store_true")

options = parser.parse_args()

if options.endianness == 'b':
    sandbox = Sandbox_Linux_armb_str
elif options.endianness == 'l':
    sandbox = Sandbox_Linux_arml_str
else:
    raise ValueError("Bad endianness!")

sb = sandbox(options.filename, options, globals())

if options.address is None:
    raise ValueError('invalid address')

sb.run()

# test correct de xor
start = sb.jitter.cpu.R0
stop = sb.jitter.cpu.R1
s = sb.jitter.vm.get_mem(start, stop-start)
s = StrPatchwork(s)
for i, c in enumerate(s):
    s[i] = chr(ord(c)^0x11)
s = str(s)
assert(s == "test string\x00")