Example #1
0
    def setupGDT(self):
        gdtm = GDTManager(self.ql)

        segm_class: Type[SegmentManager] = {
            32: SegmentManager86,
            64: SegmentManager64
        }[self.ql.arch.bits]

        # setup gdt and segments selectors
        segm = segm_class(self.ql.arch, gdtm)
        segm.setup_cs_ds_ss_es(0, 4 << 30)
        segm.setup_fs(FS_SEGMENT_ADDR, FS_SEGMENT_SIZE)
        segm.setup_gs(GS_SEGMENT_ADDR, GS_SEGMENT_SIZE)

        if not self.ql.mem.is_available(FS_SEGMENT_ADDR, FS_SEGMENT_SIZE):
            raise QlMemoryMappedError(
                'cannot map FS segment, memory location is taken')

        self.ql.mem.map(FS_SEGMENT_ADDR, FS_SEGMENT_SIZE, info='[FS]')

        if not self.ql.mem.is_available(GS_SEGMENT_ADDR, GS_SEGMENT_SIZE):
            raise QlMemoryMappedError(
                'cannot map GS segment, memory location is taken')

        self.ql.mem.map(GS_SEGMENT_ADDR, GS_SEGMENT_SIZE, info='[GS]')
Example #2
0
def ql_syscall_mprotect(ql: Qiling, start: int, mlen: int, prot: int):
    try:
        ql.mem.protect(start, mlen, prot)
    except Exception as e:
        ql.log.exception(e)

        raise QlMemoryMappedError(
            f'Error: change protection at: {start:#x} - {start + mlen - 1:#x}')

    return 0
Example #3
0
    def __init__(self,
                 ql: Qiling,
                 base=QL_X86_GDT_ADDR,
                 limit=QL_X86_GDT_LIMIT,
                 num_entries=16):
        ql.log.debug(f'Mapping GDT at {base:#x} with limit {limit:#x}')

        if not ql.mem.is_available(base, limit):
            raise QlMemoryMappedError(
                'cannot map GDT, memory location is taken')

        ql.mem.map(base, limit, info="[GDT]")

        # setup GDT by writing to GDTR
        ql.arch.regs.write(UC_X86_REG_GDTR, (0, base, limit, 0x0))

        self.array = GDTArray(ql.mem, base, num_entries)
Example #4
0
def syscall_mmap_impl(ql: Qiling, addr: int, mlen: int, prot: int, flags: int,
                      fd: int, pgoffset: int, ver: int):
    MAP_FAILED = -1
    MAP_SHARED = 0x01
    MAP_FIXED = 0x10
    MAP_ANONYMOUS = 0x20

    pagesize = ql.mem.pagesize
    api_name = {0: 'old_mmap', 1: 'mmap', 2: 'mmap2'}[ver]

    if ql.arch.bits == 64:
        fd = ql.unpack64(ql.pack64(fd))

    elif ql.arch.type == QL_ARCH.MIPS:
        MAP_ANONYMOUS = 2048
        if ver == 2:
            pgoffset = pgoffset * pagesize

    elif ql.arch.type == QL_ARCH.ARM and ql.os.type == QL_OS.QNX:
        MAP_ANONYMOUS = 0x00080000
        fd = ql.unpack32s(ql.pack32s(fd))

    else:
        fd = ql.unpack32s(ql.pack32(fd))
        if ver == 2:
            pgoffset = pgoffset * pagesize

    need_mmap = True
    mmap_base = addr
    mmap_size = ql.mem.align_up(mlen - (addr & (pagesize - 1)))

    if ql.os.type != QL_OS.QNX:
        mmap_base = ql.mem.align(mmap_base)

        if (flags & MAP_FIXED) and mmap_base != addr:
            return MAP_FAILED

    # initial ql.loader.mmap_address
    if mmap_base != 0 and ql.mem.is_mapped(mmap_base, mmap_size):
        if (flags & MAP_FIXED) > 0:
            ql.log.debug("%s - MAP_FIXED, mapping not needed" % api_name)
            try:
                ql.mem.protect(mmap_base, mmap_size, prot)
            except Exception as e:
                ql.log.debug(e)
                raise QlMemoryMappedError(
                    "Error: change protection at: 0x%x - 0x%x" %
                    (mmap_base, mmap_base + mmap_size - 1))
            need_mmap = False
        else:
            mmap_base = 0

    # initialized mapping
    if need_mmap:
        if mmap_base == 0:
            mmap_base = ql.loader.mmap_address
            ql.loader.mmap_address = mmap_base + mmap_size
        ql.log.debug("%s - mapping needed for 0x%x" % (api_name, mmap_base))
        try:
            ql.mem.map(mmap_base, mmap_size, prot, "[syscall_%s]" % api_name)
        except Exception as e:
            raise QlMemoryMappedError("Error: mapping needed but failed")
        ql.log.debug("%s - addr range  0x%x - 0x%x: " %
                     (api_name, mmap_base, mmap_base + mmap_size - 1))

    # FIXME: MIPS32 Big Endian
    try:
        ql.mem.write(mmap_base, b'\x00' * mmap_size)
    except Exception as e:
        raise QlMemoryMappedError("Error: trying to zero memory")

    if ((flags & MAP_ANONYMOUS) == 0) and fd in range(NR_OPEN):
        f = ql.os.fd[fd]

        if f is not None:
            f.seek(pgoffset)
            data = f.read(mlen)
            mem_info = str(f.name)
            f._is_map_shared = flags & MAP_SHARED
            f._mapped_offset = pgoffset
            ql.log.debug("mem write : " + hex(len(data)))
            ql.log.debug("mem mmap  : " + mem_info)

            ql.mem.change_mapinfo(
                mmap_base,
                mmap_base + mmap_size,
                mem_info=f'[{api_name}] {os.path.basename(mem_info)}')
            try:
                ql.mem.write(mmap_base, data)
            except Exception as e:
                ql.log.debug(e)
                raise QlMemoryMappedError("Error: trying to write memory: ")

    return mmap_base