Beispiel #1
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 #2
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 #3
0
    def readDefinition(self, ea):
        # Read all the fields from the stream.
        self.type = MakeAndGetWord(ea)
        idc.MakeWord(ea + 2)
        self.name_address = MakeAndGetDword(ea + 4)
        self.definition_address = MakeAndGetDword(ea + 8, "definition address")
        self.group_tag = MakeAndGetString(ea + 12, 4, "group tag")

        # Read strings.
        self.name_str = ReadString(self.name_address)

        # Comment the field type.
        idc.MakeComm(ea, field_type.field_types[self.type])

        # Check if we should comment the name string.
        if self.name_address < g_BaseAddress:
            idc.MakeComm(ea + 4, self.name_str)

        # Check the field type and read the definition accordingly.
        if self.type == field_type._field_block:
            # Read the tag block definition.
            tagBlock = tag_block_definition()
            tagBlock.readDefinition(self.definition_address)
        elif self.type == field_type._field_struct:
            # Ghetto hack to read the struct definition struct.
            MakeAndGetDword(self.definition_address)
            MakeAndGetDword(self.definition_address + 4, "group tag")
            MakeAndGetDword(self.definition_address + 8)
            blockAddress = MakeAndGetDword(self.definition_address + 12,
                                           "block definition address")

            # Read the tag block definition.
            tagBlock = tag_block_definition()
            tagBlock.readDefinition(blockAddress)
Beispiel #4
0
def MakeReg(name, offset, size, count=0):
    idc.MakeNameEx(offset, name, idc.SN_NOCHECK | idc.SN_NOWARN)
    if (size == 1):
        idc.MakeByte(offset)
    elif size == 2:
        idc.MakeWord(offset)
    elif size == 4:
        idc.MakeDword(offset)
    else:
        raise NotImplementedError("Register size invalid! Name: " + name)

    if (count != 0):
        idc.make_array(offset, count)
Beispiel #5
0
def MakeN(addr, size):
    '''
    Make a integer with the given size at the given address.

    Args:
      addr (int): effective address.
      size (int): the size of the integer, one of 1, 2, 4, or 8.
    '''
    if size == 1:
        idc.MakeByte(addr)
    elif size == 2:
        idc.MakeWord(addr)
    elif size == 4:
        idc.MakeDword(addr)
    elif size == 8:
        idc.MakeQword(addr)
Beispiel #6
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)
    def locateLocalConstants(self, scs, sds):
        """Locate and define all of the local strings / numeric constants, that match our observed pattern.

        Args:
            scs (list): List of (sark) code segments.
            sds (list): List of (sark) data segments.
        """
        self._analyzer.logger.info(
            "Locating local strings / constants in the code sections")
        for sc in scs:
            cur_ea = pad(sc.startEA, self._local_alignment)
            while cur_ea < sc.endEA:
                # check for a data constant
                if self.isDataConstant(cur_ea):
                    # check for a string (refs already checked)
                    if self._analyzer.str_identifier.isLocalAsciiString(
                            cur_ea, check_refs=False):
                        length = self._analyzer.str_identifier.defineAsciiString(
                            cur_ea)
                        padded_length = pad(length, self._local_alignment)
                        if padded_length != length:
                            idc.MakeUnknown(cur_ea + length,
                                            padded_length - length, 0)
                            idc.MakeData(cur_ea + length, 0,
                                         padded_length - length, 0)
                        cur_ea += padded_length
                    # This means it is a constant
                    else:
                        if self._local_pad is None:
                            idc.MakeData(cur_ea, 0, self._local_alignment, 0)
                        else:
                            # check the size of the constant using the byte padding
                            for offset in xrange(self._local_alignment - 1, -1,
                                                 -1):
                                if idc.Byte(cur_ea +
                                            offset) != self._local_pad:
                                    break
                            # prepare the bytes
                            idc.MakeUnknown(cur_ea, self._local_alignment, 0)
                            # the data constant - try to make it pretty
                            if offset + 1 == 2:
                                idc.MakeWord(cur_ea)
                            elif offset + 1 == 4:
                                idc.MakeDword(cur_ea)
                            elif offset + 1 == 8:
                                idc.MakeQword(cur_ea)
                            else:
                                idc.MakeData(cur_ea, 0, offset + 1, 0)
                            # the padding
                            idc.MakeData(cur_ea + offset + 1, 0,
                                         self._local_alignment - offset + 1, 0)
                            # Now check for a pointer (only supports code pointers for now)
                            if offset + 1 == self._analyzer.addressSize():
                                value = self._analyzer.parseAdderss(cur_ea)
                                # only support pointers inside our local segment (more probable)
                                if sc.startEA <= value and value < sc.endEA:
                                    self._analyzer.markCodePtr(
                                        cur_ea, value, aggressive=False)
                                # try a pointer to a declared string
                                else:
                                    for sd in sds:
                                        if sd.startEA <= value and value <= sd.endEA:
                                            line = sark.Line(value)
                                            if line.is_string and line.startEA == value:
                                                self._analyzer.markDataPtr(
                                                    cur_ea,
                                                    value,
                                                    aggressive=False)
                                            break
                        # now move onward
                        cur_ea += self._local_alignment
                # found nothing, move on
                else:
                    cur_ea += self._local_alignment