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]')
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
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)
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