Exemplo n.º 1
0
 def _eval_load(self, ins: minsn_t,
                environment: MicroCodeEnvironment) -> Union[None, int]:
     res_mask = AND_TABLE[ins.d.size]
     if ins.opcode == m_ldx:
         load_address = self.eval(ins.r, environment)
         formatted_seg_register = format_mop_t(ins.l)
         if formatted_seg_register == "ss.2":
             stack_mop = mop_t()
             stack_mop.erase()
             stack_mop._make_stkvar(environment.cur_blk.mba, load_address)
             emulator_log.debug("Searching for stack mop {0}".format(
                 format_mop_t(stack_mop)))
             stack_mop_value = environment.lookup(stack_mop)
             emulator_log.debug("  stack mop {0} value : {1}".format(
                 format_mop_t(stack_mop), stack_mop_value))
             return stack_mop_value & res_mask
         else:
             mem_seg = getseg(load_address)
             seg_perm = mem_seg.perm
             if (seg_perm & SEGPERM_WRITE) != 0:
                 raise WritableMemoryReadException(
                     "ldx {0:x} (writable -> return None)".format(
                         load_address))
             else:
                 memory_value = get_qword(load_address)
                 emulator_log.debug(
                     "ldx {0:x} (non writable -> return {1:x})".format(
                         load_address, memory_value & res_mask))
                 return memory_value & res_mask
Exemplo n.º 2
0
 def eval(self, mop: mop_t,
          environment: MicroCodeEnvironment) -> Union[None, int]:
     if mop.t == mop_n:
         return mop.nnn.value
     elif mop.t in [mop_r, mop_S]:
         return environment.lookup(mop)
     elif mop.t == mop_d:
         return self._eval_instruction(mop.d, environment)
     elif mop.t == mop_a:
         if mop.a.t == mop_v:
             emulator_log.debug("Reading a mop_a '{0}' -> {1:x}".format(
                 format_mop_t(mop), mop.a.g))
             return mop.a.g
         elif mop.a.t == mop_S:
             emulator_log.debug("Reading a mop_a '{0}' -> {1:x}".format(
                 format_mop_t(mop), mop.a.s.off))
             return mop.a.s.off
         raise UnresolvedMopException(
             "Calling get_cst with unsupported mop type {0} - {1}: '{2}'".
             format(mop.t, mop.a.t, format_mop_t(mop)))
     elif mop.t == mop_v:
         mem_seg = getseg(mop.g)
         seg_perm = mem_seg.perm
         if (seg_perm & SEGPERM_WRITE) != 0:
             emulator_log.debug("Reading a (writable) mop_v {0}".format(
                 format_mop_t(mop)))
             return environment.lookup(mop)
         else:
             memory_value = get_qword(mop.g)
             emulator_log.debug(
                 "Reading a mop_v {0:x} (non writable -> return {1:x})".
                 format(mop.g, memory_value))
             return mop.g
     raise EmulationException("Unsupported mop type '{0}': '{1}'".format(
         mop_type_to_string(mop.t), format_mop_t(mop)))
Exemplo n.º 3
0
    def resolve_symbols(self, dll):
        tmpdir = tempfile.gettempdir().replace('\\', '/') + '/'
        # File who will first contain ordinals then symbols
        tmpfile = tmpdir + "dotNIETsymbols.txt"
        tmplog = tmpdir + "dotNIETlogs.txt"
        # Destination path for a copy of SharedLibrary.dll
        tmpdll = tmpdir + os.path.basename(dll)
        # Path to the idat binary, needed to parse a remote idb
        idat = idc.idadir().replace('\\','/') + '/' + 'idat' + \
               ['64' if utils.is_x64(dll) else ''][0]

        if os.getenv("windir") is not None:
            idat += '.exe'
        # script called along with idat in order to parse SharedLibrary.idb
        parsing_script_path = '"' + os.path.dirname(os.path.realpath(__file__)).replace('\\','/')\
                              + '/dotNIET/resolve.py"'

        # we first copy SharedLibrary.dll to tmp to be sure we are in a
        # writable location
        shutil.copyfile(dll, tmpdll)

        # we have to use temporary files because of the ida headless stuff...
        # pretty dirty
        ordinals = []
        with open(tmpfile, 'w') as f:
            for i in range(self.nb_symbols):
                ordinals.append((idaapi.get_qword(self.ordinals + i * 8)
                                 & ~0x8000000000000000) * 4)
            f.write(",".join([str(x) for x in ordinals]))

        # be prepared to wait as this will load the binary + pdb
        idaapi.msg("Starting parsing of %d symbols...\n" % self.nb_symbols)
        subprocess.run([idat, "-L" + tmplog, "-c", "-A", "-S" + \
                        parsing_script_path + " " + tmpfile, tmpdll],
                        creationflags=subprocess.CREATE_NO_WINDOW,
                        check=True)

        # we read back tmpfile which now contains symbols
        symbols = []
        with open(tmpfile, 'r') as f:
            symbolsArray = f.read()
            symbols = symbolsArray.split(',')

        # we first have to undef structure as it is an array and ida will
        # refuse to set names within it
        idc.del_items(self.ordinals)
        idc.set_cmt(self.ordinals - 8, "Custom imports from SharedLibrary.dll",
                    0)
        # we then apply the symbols at this very same location (start of .idata)
        for i in range(self.nb_symbols):
            idc.set_name(self.ordinals + i * 8, symbols[i],
                         SN_NOCHECK | SN_FORCE | SN_NODUMMY)

        # finally we remove our temp files
        os.remove(tmpfile)
        os.remove(tmpdll)
        # ida generate a db
        os.remove(tmpdll + '.i64')
        # if everything went smoothly, we should not need this anymore
        os.remove(tmplog)
Exemplo n.º 4
0
def znullptr(address, end, search, struct):

    magic = idaapi.find_binary(address, end, search, 0x10, idc.SEARCH_DOWN)
    pattern = '%02X %02X %02X %02X FF FF FF FF' % (magic & 0xFF,
                                                   ((magic >> 0x8) & 0xFF),
                                                   ((magic >> 0x10) & 0xFF),
                                                   ((magic >> 0x18) & 0xFF))

    sysvec = idaapi.find_binary(address, cvar.inf.maxEA, pattern, 0x10,
                                idc.SEARCH_UP) - 0x60
    idaapi.set_name(sysvec, 'sysentvec', SN_NOCHECK | SN_NOWARN | SN_FORCE)

    sysent = idaapi.get_qword(sysvec + 0x8)
    idaapi.set_name(sysent, 'sv_table', SN_NOCHECK | SN_NOWARN | SN_FORCE)

    sysnames = idaapi.get_qword(sysvec + 0xD0)
    idaapi.set_name(sysnames, 'sv_syscallnames',
                    SN_NOCHECK | SN_NOWARN | SN_FORCE)

    # Get the list of syscalls
    offset = idaapi.find_binary(address, cvar.inf.maxEA,
                                '73 79 73 63 61 6C 6C 00 65 78 69 74 00', 0x10,
                                SEARCH_DOWN)

    numsyscalls = idaapi.get_qword(sysvec)
    for entry in xrange(numsyscalls):
        initial = sysnames + (entry * 0x8)
        idc.create_data(initial, FF_QWORD, 0x8, BADNODE)
        offset = idaapi.get_qword(initial)

        length = idaapi.get_max_strlit_length(offset, STRTYPE_C)
        name = idaapi.get_strlit_contents(offset, length, STRTYPE_C)

        sysentoffset = sysent + 0x8 + (entry * 0x30)
        idaapi.do_unknown_range(sysentoffset - 0x8, 0x30, 0)
        idaapi.create_struct(sysentoffset - 0x8, 0x30, struct)
        idc.set_cmt(sysentoffset - 0x8, '#%i' % entry, False)

        if '{' in name:
            continue

        # Rename the functions
        function = idaapi.get_qword(sysentoffset)
        idaapi.set_name(function, name.replace('#', 'sys_'),
                        SN_NOCHECK | SN_NOWARN | SN_FORCE)
Exemplo n.º 5
0
 def update_mop_tracker(self, mba: mbl_array_t, mop_tracker: MopTracker):
     stack_array_base_address = mba.stkoff_ida2vd(self.sp_offset)
     # print("stack_array_base_address: {0:x}".format(stack_array_base_address))
     for i in range(self.nb_elt):
         tmp_mop = mop_t()
         tmp_mop.erase()
         tmp_mop._make_stkvar(mba, stack_array_base_address + 8 * i)
         tmp_mop.size = 8
         mem_val = idaapi.get_qword(self.mem_offset + 8 * i) & AND_TABLE[8]
         mop_tracker.add_mop_definition(tmp_mop, mem_val)
def fix_relocs(base_address, relocs_address, relocs_size):
	cursor = relocs_address
	end = relocs_address+relocs_size

	multiplier = 4 * (idaapi.get_dword(cursor) & 1) + 4
	cursor += 4
	
	print 'starting to fix relocs...'
	nb_relocs = 0

	delta = idaapi.get_dword(cursor)
	while delta != 0xFFFFFFFF and cursor < end:
		current_reloc = base_address + delta
		while True:
			decorated_addr = idaapi.get_qword(current_reloc)
			if decorated_addr & 0x4000000000000000 == 0:
				if decorated_addr & 0x8000000000000000:
					#tagged ptr
					sign_type = (decorated_addr >> 49) & 3
					real_addr = base_address + (decorated_addr & 0xFFFFFFFF)
					modifier = ((decorated_addr >> 32) & 0xFFFF)
					if decorated_addr & 0x1000000000000:
						if modifier == 0:
							modifier = current_reloc
							modifier_type = 'ptr_addr'
						else:
							modifier_type = '0x%X << 48 | ptr_addr & 0xFFFFFFFFFFFF'%(modifier)
							modifier = (current_reloc & 0xFFFFFFFFFFFF) | (modifier << 48)
					else:
						modifier_type = '0x%X'%modifier
					if sign_type == 0:
						decorator = 'PACIA %s'%modifier_type if modifier else 'PACIZA'
					elif sign_type == 1:
						decorator = 'PACIB %s'%modifier_type if modifier else 'PACIZB'
					elif sign_type == 2:
						decorator = 'PACDA %s'%modifier_type if modifier else 'PACDZA'
					elif sign_type == 3:
						decorator = 'PACDB %s'%modifier_type if modifier else 'PACDZB'
					idaapi.set_cmt(current_reloc , decorator, 1)
				else:
					real_addr = ((decorated_addr << 13) & 0xFF00000000000000) | (decorated_addr & 0x7ffffffffff)
					if decorated_addr & 0x40000000000:
						real_addr |= 0xfffc0000000000
				idaapi.patch_qword(current_reloc, real_addr)
				idaapi.op_offset(current_reloc, 0, idaapi.REF_OFF64)
				nb_relocs += 1
			delta_next_reloc = ((decorated_addr >> 51) & 0x7ff) * multiplier
			if delta_next_reloc == 0:
				break
			current_reloc += delta_next_reloc
		cursor += 4
		delta = idaapi.get_dword(cursor)
	print '%d relocs fixed!'%nb_relocs
Exemplo n.º 7
0
def Pablo(address, end):

    while address < end:
        offset = idaapi.find_binary(address, end, '?? FF FF FF FF', 0x10,
                                    SEARCH_DOWN)
        offset -= 0x3

        if idaapi.is_unknown(idaapi.get_flags(offset)):
            if text.start_ea <= idaapi.get_qword(offset) <= abs.end_ea:
                idaapi.create_data(offset, FF_QWORD, 0x8, BADNODE)

        address = offset + 0x4
Exemplo n.º 8
0
    def dbg_process_start(self, pid, tid, ea, name, base, size):

        self.mem_for_inline_hooks = 0
        self.virtualalloc = 0

        ntdll = DllHook('ntdll.dll')
        ntdll.add_func(
            FuncHook('ntdll_NtClose', NtClose_inline_hook_code_32,
                     NtClose_bpt_cond_hook_code_32))
        ntdll.add_func(
            FuncHook('ntdll_NtQueryInformationProcess',
                     NtQueryInformationProcess_inline_hook_code_32,
                     NtQueryInformationProcess_bpt_cond_hook_code_32))

        self.dlls = [ntdll]

        # IDA creates a segment named "TIB[XXXXXXXX]", which points to
        # wow_peb64 antually. We can get peb from wow_peb64 with 0x1000 offset.
        #               peb_addr = wow_peb64_addr + 0x1000
        # Note: IDA has not created segment "TIB[XXXXXXXX]" at this point.

        # tid = get_current_thread()
        # tib_segm_name = "TIB[%08X]" % tid
        # print tib_segm_name
        # tib_segm = get_segm_by_name(tib_segm_name)
        # wow_peb64 = tib_segm.start_ea
        # peb = tib_segm.start_ea + 0x1000

        # on debugging start, ebx points to peb
        # get addrs of peb and wow_peb64
        ebx = idc.get_reg_value("ebx")
        peb = ebx
        wow_peb64 = peb - 0x1000

        # patch peb->BeingDebugged
        # solving peb->NtGlobalFlag and "Heap Magic" anti-debug method
        # at the same time.
        idc.patch_byte(peb + 2, 0)
        idc.patch_byte(wow_peb64 + 2, 0)

        # patching peb process paramters
        peb_process_parameters = idaapi.get_dword(peb + 0x10)
        flag = idaapi.get_dword(peb_process_parameters + 0x8)
        idc.patch_dword(peb_process_parameters + 0x8, flag | 0x4000)

        # patching peb64 process paramters
        peb64_process_parameters = idaapi.get_qword(wow_peb64 + 0x20)
        flag = idaapi.get_dword(peb64_process_parameters + 0x8)
        idc.patch_dword(peb64_process_parameters + 0x8, flag | 0x4000)
Exemplo n.º 9
0
def pablo(address, end, search):
    
    while address < end:
        address = idaapi.find_binary(address, end, search, 0x10, SEARCH_DOWN)
        
        if address > idaapi.get_segm_by_name('CODE').end_ea:
            offset = address - 0x3
            
            if idaapi.isUnknown(idaapi.getFlags(offset)):
                if idaapi.get_qword(offset) <= end:
                    idaapi.create_data(offset, FF_QWORD, 0x8, BADNODE)
            
            address = offset + 4
        
        else:
            idaapi.do_unknown(address, 0)
            idaapi.create_insn(address)
            idaapi.add_func(address, BADADDR)
            address += 4
Exemplo n.º 10
0
    def __get_ptr_val(cls, ea):
        if idaapi.cvar.inf.is_64bit():
            return idaapi.get_qword(ea)

        return (idaapi.get_dword if idaapi.IDA_SDK_VERSION >= 700 else idaapi.get_long)(ea)
Exemplo n.º 11
0
def read_ptr(ea):
    if EA64:
        return idaapi.get_qword(ea)
    return idaapi.get_dword(ea)
Exemplo n.º 12
0
 def get_qword(self, addr):
     return idaapi.get_qword(addr)
segX_start = 0
segX_end = 0
for ea in idautils.Segments():
    seg = idaapi.getseg(ea)
    if seg and (seg.perm & idaapi.SEGPERM_EXEC):
        SigmName = idc.SegName(ea)
        print '[+] Segments with +X permission: ' + SigmName
        segX_start = seg.startEA
        segX_end = seg.endEA

# Loop through hypercall table
hypercalls = []
valid_hypercall = True
addr = hypercall_dispatch_table
while valid_hypercall:
    func_ptr = idaapi.get_qword(addr)
    # Set struct field sizes in IDA in the HypercallDispatchFormat format
    if APPLY_TO_IDB:
        MakeQword(addr)
    addr += 8

    call_code = idaapi.get_word(addr)
    if APPLY_TO_IDB:
        MakeWord(addr)
    addr += 2

    is_rep_call = idaapi.get_word(addr)
    if APPLY_TO_IDB:
        MakeWord(addr)
    addr += 2
Exemplo n.º 14
0
def get_pointer(address):
    if arch_size == 32:
        return idaapi.get_dword(address)
    else:
        return idaapi.get_qword(address)