Beispiel #1
0
 def guidAtAddr(self, addr):
     val = [idc.Dword(addr), idc.Word(addr + 4), idc.Word(addr + 6), []]
     addr += 8
     val[3] = [idc.Byte(addr + i) for i in range(8)]
     h = GuidHelper()
     guid = h.guidOfVals(val)
     val = h.findGuid(guid)
     return (val or guid)
Beispiel #2
0
def get_guid(address):
    CurrentGUID = []
    CurrentGUID.append(idc.Dword(address))
    CurrentGUID.append(idc.Word(address + 4))
    CurrentGUID.append(idc.Word(address + 6))
    for addr in range(address + 8, address + 16, 1):
        CurrentGUID.append(idc.Byte(addr))
    return CurrentGUID
Beispiel #3
0
 def parseFuncType(self, offset):
     return
     sid = ida_struct.get_struc_id("funcType")
     in_size = idc.Word(offset + idc.get_member_offset(sid, "incount"))
     out_size = idc.Word(offset + idc.get_member_offset(sid, "outcount"))
     sz = ida_struct.get_struc_size(sid)
     for i in xrange(in_size + out_size):
         idc.SetType(offset + sz + i * self.stepper.size, "type *")
Beispiel #4
0
 def parseFuncType(self, offset):
     return
     sid = idc.GetStrucIdByName("funcType")
     in_size = idc.Word(offset + idc.GetMemberOffset(sid, "incount"))
     out_size = idc.Word(offset + idc.GetMemberOffset(sid, "outcount"))
     sz = idc.GetStrucSize(sid)
     for i in xrange(in_size + out_size):
         idc.SetType(offset + sz + i * self.stepper.size, "type *")
Beispiel #5
0
 def GetDyn():
     phoff = idc.Dword(idc.MinEA() + 0x1c) + idc.MinEA()
     phnum = idc.Word(idc.MinEA() + 0x2c)
     phentsize = idc.Word(idc.MinEA() + 0x2a)
     for i in range(phnum):
         p_type = idc.Dword(phoff + phentsize * i)
         if p_type == 2:  # PY_DYNAMIC
             dyn_addr = idc.Dword(phoff + phentsize * i + 8)
             return dyn_addr
Beispiel #6
0
 def __init__(self, addr, deepness=0):
     super(InventoryInterface.Entry, self).__init__(addr, deepness)
     self.handleId = idc.Dword(
         self.addr + InventoryInterface.Entry.Offset.HandleId.value)
     self.ownerHandle = idc.Dword(
         self.addr + InventoryInterface.Entry.Offset.OwnerHandle.value)
     self.itemPosition = idc.Word(
         self.addr + InventoryInterface.Entry.Offset.ItemPosition.value)
     self.count = idc.Word(self.addr +
                           InventoryInterface.Entry.Offset.Count.value)
Beispiel #7
0
def get_guid(address):
    """
    get GUID located by address
    """
    guid = []
    guid.append(idc.Dword(address))
    guid.append(idc.Word(address + 4))
    guid.append(idc.Word(address + 6))
    for addr in range(address + 8, address + 16, 1):
        guid.append(idc.Byte(addr))
    return guid
    def readValue(self):
        if self.value != None:
            return self.value

        operandType = self.parser.getOperandType()
        regName = self.parser.getRegName()
        regValue = idc.GetRegValue(regName) if regName != None else None
        if operandType == OperandType.Value64OfRegisterPlusOffset:
            self.value = idc.Qword(regValue + self.opValue)
        elif operandType == OperandType.Value32OfRegisterPlusOffset:
            self.value = idc.Dword(regValue + self.opValue)
        elif operandType == OperandType.Value16OfRegisterPlusOffset:
            self.value = idc.Word(regValue + self.opValue)
        elif operandType == OperandType.Value8OfRegisterPlusOffset:
            self.value = idc.Byte(regValue + self.opValue)
        elif (operandType
              == OperandType.Register64) or (operandType
                                             == OperandType.Register32):
            self.value = regValue
        elif (operandType
              == OperandType.Register16) or (operandType
                                             == OperandType.Register8):
            self.value = regValue
        elif operandType == OperandType.ImmediateUnkown:
            self.value = self.opValue
        else:
            raise Exception("Unknown operand type")

        return self.value
Beispiel #9
0
def read_mem(addr, forced_addr_sz=None, read_only=False):
    global ADDR_SZ

    if not read_only:
        if forced_addr_sz:
            idc.MakeUnknown(addr, forced_addr_sz, idc.DOUNK_SIMPLE)
        else:
            idc.MakeUnknown(addr, ADDR_SZ, idc.DOUNK_SIMPLE)
        idaapi.autoWait()

    if forced_addr_sz == 2:
        if not read_only:
            idc.MakeWord(addr)
            idaapi.autoWait()
        return idc.Word(addr)
    if forced_addr_sz == 4 or ADDR_SZ == 4:
        if not read_only:
            idc.MakeDword(addr)
            idaapi.autoWait()
        return idc.Dword(addr)
    if forced_addr_sz == 8 or ADDR_SZ == 8:
        if not read_only:
            idc.MakeQword(addr)
            idaapi.autoWait()
        return idc.Qword(addr)
Beispiel #10
0
    def parse_hdr(self):
        '''
        Refer: function [go12Init()] in https://golang.org/src/debug/gosym/pclntab.go
        '''
        magic = idc.Dword(self.start_addr) & 0xFFFFFFFF
        if magic != Pclntbl.MAGIC:
            print magic, Pclntbl.MAGIC
            common._error("Invalid pclntbl header magic number!")
            idc.Exit(1)
            #raise Exception("Invalid pclntbl header magic number!")
        idc.MakeDword(self.start_addr)
        idc.MakeComm(self.start_addr, "Magic Number")
        idc.MakeNameEx(self.start_addr,
                       "runtime_symtab",
                       flags=idaapi.SN_FORCE)
        idaapi.autoWait()

        if idc.Word(self.start_addr + 4) & 0xFFFF != 0:
            raise Exception("Invalid pclntbl header")
        idc.MakeWord(self.start_addr + 4)

        self.min_lc = idc.Byte(self.start_addr + 6) & 0xFF
        if (self.min_lc != 1) and (self.min_lc != 2) and (self.min_lc != 4):
            raise Exception("Invalid pclntbl minimum LC!")
        idc.MakeComm(self.start_addr + 6, "instruction size quantum")
        idaapi.autoWait()

        self.ptr_sz = idc.Byte(self.start_addr + 7) & 0xFF
        if (self.ptr_sz != 4) and (self.ptr_sz != 8):
            raise Exception("Invalid pclntbl pointer size!")
        idc.MakeComm(self.start_addr + 7, "ptr size")
        idaapi.autoWait()
Beispiel #11
0
 def stval(self, addr, ofs, sz=8):
     if addr < 20:
         """ argument """
         if addr < 4:
             regs = ["rcx", "rdx", "r8", "r9"]
             addr = idc.GetRegValue(regs[addr])
         else:
             rsp = idc.GetRegValue('rsp')
             addr = idc.Qword(rsp + addr * 8 + 8)
     if isinstance(ofs, basestring):
         sf = ofs.split('.')
         st = struct.Struct(sf[0])
         res = st.readInst(addr)
         while len(sf) > 2:
             res = st.subInst(res, sf[1])
             sf = sf[1:]
         if len(sf) > 1:
             res = res[sf[1]]
         return str(res)
     if sz == 8:
         return idc.Qword(addr + ofs)
     if sz == 4:
         return idc.Dword(addr + ofs)
     if sz == 2:
         return idc.Word(addr + ofs)
     return idc.Byte(addr + ofs)
Beispiel #12
0
 def activate(self, ctx):
     arch = idc.Word(idc.MinEA() + 0x12)
     if arch == 0x3E:  # EM_X86_64
         PltResolver64()
     elif arch == 0x3:  # EM_386
         PltResolver32()
     else:
         print '[-] Only support EM_X86_64 and EM_386'
     return 1
Beispiel #13
0
def mem_read_integer(addr, read_size=4):
    if read_size == 2:
        return idc.Word(addr) % 0xFFFF

    elif read_size == 4:  # 32bit Default
        return idc.Dword(addr) & 0xFFFFFFFF

    else:  # Read Size is 8 Byte (for 64bit)
        return idc.Qword(addr) & 0xFFFFFFFFFFFFFFFF
Beispiel #14
0
 def as_x0(self):
     """
     The receiver(X0) of instance methods is always the object.
     :return:
     """
     if idc.SegName(
             idc.Qword(self.class_ref)
     ) == 'UNDEF':  # IMPORTED CLASS, has no method implementations.
         return
     class_data = idc.Qword(self.class_ref)
     class_data_ro = idc.Qword(class_data + 0x20)
     meths = idc.Qword(class_data_ro + 0x20)
     entrysize = idc.Word(meths)
     count = idc.Word(meths)
     for meth in range(meths + 8, meths + 8 + entrysize * count, entrysize):
         name = idc.Name(idc.Qword(meth)).replace('sel_', '')
         type = idc.GetDisasm(idc.Qword(meth + 8))
         imp = idc.Qword(meth + 0x10)
         self.add_occurrences(imp, 'x0')
Beispiel #15
0
def decrypts_all_strings(offsets):
    result = []

    for offset in offsets:
        if offset != 0:
            key = idc.Dword(offset)
            size = idc.Word(offset) ^ idc.Word(offset + 4)
            plaintext = ''

            for index in range(size):
                key = ((key << 29) | (key >> 3)) + index
                key = key & 0xFFFFFFFF
                ciphersymbol = idc.Byte(offset + index + 6)
                plainsymbol = (key ^ ciphersymbol) & 0xFF
                plaintext += chr(plainsymbol)

            result.append([offset, plaintext])

    return result
Beispiel #16
0
 def peek(self, size):
     ea = self.vaddr + self.offset
     if size == 1:
         raw = idc.Byte(ea)
     elif size == 2:
         raw = idc.Word(ea)
     elif size == 4:
         raw = idc.Dword(ea)
     else:
         print "bad size:", size
         assert (False)
     return raw
Beispiel #17
0
 def rename_supposed_guids(self):
     EFI_GUID = "EFI_GUID *"
     for seg in idautils.Segments():
         if idc.SegName(seg) == ".data":
             seg_start = idc.SegStart(seg)
             seg_end = idc.SegEnd(seg)
             break
     ea = seg_start
     while (ea <= seg_end - 15):
         prot_name = ""
         if idc.Name(ea).find("unk_") != -1:
             find = False
             CurrentGuid = []
             CurrentGuid.append(idc.Dword(ea))
             CurrentGuid.append(idc.Word(ea + 4))
             CurrentGuid.append(idc.Word(ea + 6))
             for addr in range(ea + 8, ea + 16, 1):
                 CurrentGuid.append(idc.Byte(addr))
             for name in self.Protocols["Edk2Guids"]:
                 if self.Protocols["Edk2Guids"][name] == CurrentGuid:
                     prot_name = name + "_" + hex(ea)
                     find = True
                     break
             for name in self.Protocols["EdkGuids"]:
                 if self.Protocols["EdkGuids"][name] == CurrentGuid:
                     prot_name = name + "_" + hex(ea)
                     find = True
                     break
             for name in self.Protocols["AmiGuids"]:
                 if self.Protocols["AmiGuids"][name] == CurrentGuid:
                     prot_name = name + "_" + hex(ea)
                     find = True
                     break
             if (find and \
                 idc.Name(ea) != prot_name and \
                 CurrentGuid[0] != 0
                 ):
                 idc.SetType(ea, EFI_GUID)
                 idc.MakeName(ea, prot_name)
         ea += 1
Beispiel #18
0
def IsInstrumentIns(ea):
    '''
    is ea instrument instruction?
    '''
    if idc.__EA64__:  # 64bit
        '''
.text:0000000000412450 48 8D 64 24 80    lea     rsp, [rsp-80h]
.text:0000000000412455 53                push    rbx
.text:0000000000412456 51                push    rcx
.text:0000000000412457 68 30 E2 00 00    push    0E230h                 // z
.text:000000000041245C 48 C7 C1 00 00 00+mov     rcx, 0                 // x
.text:0000000000412463 48 C7 C3 19 D6 00+mov     rbx, 0D619h
.text:000000000041246A E8 51 44 00 00    call    __afl_maybe_log_fun_3
.text:000000000041246F 59                pop     rcx
.text:0000000000412470 59                pop     rcx
.text:0000000000412471 5B                pop     rbx
.text:0000000000412472 48 8D A4 24 80 00+lea     rsp, [rsp+80h] 
        '''
        if 0x6851538024648D48 == idc.Qword(ea) and 0xC748 == idc.Word(
                ea + 0xc) and 0xC748 == idc.Word(
                    ea + 0x13) and 0x0000008024A48D48 == idc.Qword(ea + 0x22):
            return True
    else:  # 32bit
        '''
        52                push    edx
        51                push    ecx
        50                push    eax
        B9 8A 7D 00 00    mov     ecx, 7D8Ah
        E8 53 10 00 00    call    __afl_maybe_log
        58                pop     eax
        59                pop     ecx
        5A                pop     edx
        '''
        if 0xB9505152 == idc.Dword(ea) and 0x5A595800 == idc.Dword(ea + 12):
            return True

    return False
Beispiel #19
0
def MakeAndGetWord(ea, comment=None):
    """
    Creates a word at the specified address and returns the word value.
    :param ea: address to make word at
    :param comment: optional comment to place at the specified address
    :return: the value of the word at the specified address
    """

    # Make the word value.
    idc.MakeWord(ea)

    # Check if the comment is valid and if so place it at the address.
    if comment is not None:
        idc.MakeComm(ea, comment)

    # Get the word value.
    return idc.Word(ea)
Beispiel #20
0
def read_word(ea, wordsize=WORD_SIZE):
    """Get the word at the given address.

    Words are read using Byte(), Word(), Dword(), or Qword(), as appropriate. Addresses are checked
    using is_mapped(). If the address isn't mapped, then None is returned.
    """
    if not is_mapped(ea, wordsize):
        return None
    if wordsize == 1:
        return idc.Byte(ea)
    if wordsize == 2:
        return idc.Word(ea)
    if wordsize == 4:
        return idc.Dword(ea)
    if wordsize == 8:
        return idc.Qword(ea)
    raise ValueError('Invalid argument: wordsize={}'.format(wordsize))
Beispiel #21
0
    def parse_hdr(self):
        '''
        Refer: function [go12Init()] in https://golang.org/src/debug/gosym/pclntab.go
        '''
        magic = idc.Dword(self.start_addr) & 0xFFFFFFFF
        if magic != Pclntbl.MAGIC:
            print magic, Pclntbl.MAGIC
            common._error("Invalid pclntbl header magic number!")
            idc.Exit(1)
            #raise Exception("Invalid pclntbl header magic number!")

        if idc.Word(self.start_addr + 4) & 0xFFFF != 0:
            raise Exception("Invalid pclntbl header")

        self.min_lc = idc.Byte(self.start_addr + 6) & 0xFF
        if (self.min_lc != 1) and (self.min_lc != 2) and (self.min_lc != 4):
            raise Exception("Invalid pclntbl minimum LC!")

        self.ptr_sz = idc.Byte(self.start_addr + 7) & 0xFF
        if (self.ptr_sz != 4) and (self.ptr_sz != 8):
            raise Exception("Invalid pclntbl pointer size!")
Beispiel #22
0
    def search_rop_gadgets(self, segment, ret_preamble = 0xc3):
        """ Search for rop gadgets """

        # Nothing to do if the option is not set
        if not self.searchRop:
            return
            
        ea = segment.startEA
        while True:

            ea = idaapi.find_binary(ea + 1, segment.endEA, "%X" % ret_preamble, 16, idaapi.SEARCH_DOWN)
            if ea == idaapi.BADADDR: 
                break

            if ret_preamble in [ 0xc2, 0xca, 0xf2c2]:

                 # Read imm16 value and filter large values
                retn_imm16 = idc.Word(ea + 1)
                if retn_imm16 <= self.maxRetnImm:
                    self.retns.append((ea))
            else:
                self.retns.append( (ea))
def PatchCall(addr):
    '''
    To improve IDA's analysis, the patch converts call abuse
    into push and jmp instructions. The patched data is saved
    as a comment.
    '''

    if idc.Byte(addr) == 0xE8:
        logger = logging.getLogger(__name__)
        logger.info("Patching push as call @ %x" % addr)
        data_size = idc.Dword(addr + 1)
        if (data_size) >= 0xfe:
            logger.info("Can't patch: 0x%x" % addr)
            return
        fname = idc.GetFunctionName(addr)
        target = idc.GetOperandValue(addr, 0)
        data_addr = addr + idautils.DecodeInstruction(addr).size
        orig_data = idc.Word(data_addr)
        orig_asm = idc.GetDisasm(addr)
        idc.MakeUnknown(addr, target - addr,
                        idaapi.DOUNK_EXPAND | idaapi.DOUNK_DELNAMES)
        idc.PatchByte(addr, 0x68)
        idc.PatchDword(addr + 1, data_addr)
        idc.PatchByte(data_addr, 0xEB)
        idc.PatchByte(data_addr + 1, data_size - 2)
        # idaapi.analyze_area(addr, data_addr + 2)
        uksize = 0
        if fname != idc.GetFunctionName(target) and fname is not None:
            while uksize < 32:
                x = idautils.DecodeInstruction(target + uksize)
                if x is None:
                    break
                uksize += x.size
            idc.MakeUnknown(target, uksize,
                            idaapi.DOUNK_EXPAND | idaapi.DOUNK_DELNAMES)
            # idaapi.analyze_area(target, target + uksize + 1)
        idc.MakeComm(addr, "Original: " + orig_asm)
        idc.MakeComm(data_addr, "Original: %x" % orig_data)
Beispiel #24
0
def readData(ea, type, size):
    flag = type[1]
    if not flag:
        return ''
    t = flag & idc.DT_TYPE
    tsz = DATA['typeSize'][t]
    val = []
    for i in range(size / tsz):
        if t == idc.FF_BYTE:
            val += [idc.Byte(ea)]
        elif t == idc.FF_WORD:
            val += [idc.Word(ea)]
        elif t == idc.FF_DWRD:
            val += [idc.Dword(ea)]
        elif t == idc.FF_QWRD:
            val += [idc.Qword(ea)]
        elif t == idc.FF_FLOAT:
            val += [idc.GetFloat(ea)]
        ea += tsz
    if len(val) == 1:
        val = idc.GetString(val[0], -1, DATA['strtypes'][
            type[0]]) if type[0] in DATA['strtypes'] else val[0]
    return val
    def annotate_vector_table(self, vtoffset=0x0000000000):
        '''
        Name the vector table entries according to docs:
        http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABIFJFG.html
    
        Vector tables can appear in mulitple places in device flash
        Functions are not renamed because multiple vectors might point to a single function
        Append the address of the VT entry to the name from self.annotations to keep unique names
    
        '''

        for annotation_index in range(len(self.annotations)):
            entry_addr = vtoffset + 4 * annotation_index
            entry_name = "%s_%08x" % (self.annotations[annotation_index],
                                      entry_addr)

            idc.MakeDword(entry_addr)
            ida_name.set_name(entry_addr, entry_name, 0)

            # get the bytes of the vt entry
            dword = idc.Dword(entry_addr)

            if dword != 0:
                # print "ea %08x = 0x%08x" % (ea, dword)
                idc.MakeCode(dword - 1)
                idc.MakeFunction(dword - 1)
                # TODO fix the offsets created here
                # for thumb, they show to be off by a byte
                # one of the end args controls stuff about this
                idc.OpOffEx(entry_addr, 0, idaapi.REF_OFF32, -1, 0, 0)

                instruction = idc.Word(dword - 1)

                # functions like this are common
                if instruction == 0xe7fe:
                    idc.SetFunctionCmt(dword - 1, 'Infinite Loop', 1)
Beispiel #26
0
def getUInt16(ea) :
    return idc.Word(ea)
Beispiel #27
0
 def get_data_guids(self):
     """
     rename GUIDs in idb
     """
     EFI_GUID = "EFI_GUID *"
     segments = [".text", ".data"]
     for segment in segments:
         seg_start, seg_end = 0, 0
         for seg in idautils.Segments():
             if idc.SegName(seg) == segment:
                 seg_start = idc.SegStart(seg)
                 seg_end = idc.SegEnd(seg)
                 break
         ea = seg_start
         while (ea <= seg_end - 15):
             prot_name = ""
             if idc.Name(ea).find("unk_") != -1:
                 find = False
                 cur_guid = []
                 cur_guid.append(idc.Dword(ea))
                 cur_guid.append(idc.Word(ea + 4))
                 cur_guid.append(idc.Word(ea + 6))
                 for addr in range(ea + 8, ea + 16, 1):
                     cur_guid.append(idc.Byte(addr))
                 if cur_guid == [0] * 11:
                     ea += 1
                     continue
                 for name in self.Protocols["Edk2Guids"]:
                     if self.Protocols["Edk2Guids"][name] == cur_guid:
                         prot_name = name + "_" + "{addr:#x}".format(
                             addr=ea)
                         record = {
                             "address": ea,
                             "service": "unknown",
                             "guid": cur_guid,
                             "protocol_name": name,
                             "protocol_place": "edk2_guids"
                         }
                         find = True
                         break
                 for name in self.Protocols["EdkGuids"]:
                     if self.Protocols["EdkGuids"][name] == cur_guid:
                         prot_name = name + "_" + "{addr:#x}".format(
                             addr=ea)
                         prot_name = name + "_" + "{addr:#x}".format(
                             addr=ea)
                         record = {
                             "address": ea,
                             "service": "unknown",
                             "guid": cur_guid,
                             "protocol_name": name,
                             "protocol_place": "edk_guids"
                         }
                         find = True
                         break
                 for name in self.Protocols["AmiGuids"]:
                     if self.Protocols["AmiGuids"][name] == cur_guid:
                         prot_name = name + "_" + "{addr:#x}".format(
                             addr=ea)
                         prot_name = name + "_" + "{addr:#x}".format(
                             addr=ea)
                         record = {
                             "address": ea,
                             "service": "unknown",
                             "guid": cur_guid,
                             "protocol_name": name,
                             "protocol_place": "ami_guids"
                         }
                         find = True
                         break
                 if (find and (idc.Name(ea) != prot_name)):
                     idc.SetType(ea, EFI_GUID)
                     idc.MakeName(ea, prot_name)
                     self.Protocols["Data"].append(record)
             ea += 1
Beispiel #28
0
 def getWord(self, ea):
     return idc.Word(ea)
Beispiel #29
0
def get_wide_dword(addr):
    if idaapi.IDA_SDK_VERSION <= 699:
        retval = idc.Word(addr)
    else:
        retval = idc.get_wide_dword(addr)
    return retval
Beispiel #30
0
def getInt16(ea) :
    return toSigned(idc.Word(ea), 16)