Пример #1
0
    def get_ch_str(self, startea):
        """
        Attempt to grab a full string (currently \x00 terminated) and return a
        tuple of the ending address and the string encoded as UTF-8.

        Decoding occurs here and may need to be adjusted, but we default to
        GB2312.

        Returning an ending address of -1 signifies that the 
        """
        CHUNKSIZE = 2048 # hopefully your string fits in here...
        STRTERM = "\x00" # and ends with this...
        ENCODING = "gb2312" # and is encoded this way...
        ch_str = ""
        endea = -1
        chunk = None

        while chunk is None:
            CHUNKSIZE = CHUNKSIZE >> 1
            chunk = GetManyBytes(startea, CHUNKSIZE)
            if CHUNKSIZE == 0:
                print("[!] Failed to grab any bytes.")
                return (endea, ch_str)

        end_idx = chunk.find(STRTERM)
        if end_idx != -1:
            ch_str = chunk[:end_idx]
            endea = startea + end_idx
        try:
            ch_str = ch_str.decode(ENCODING).encode("utf8")
        except UnicodeDecodeError:
            print("[!] String does not appear to be %s encoded." % ENCODING)
            endea = -1
        return (endea, ch_str)
def read_unicode_string(startea):
    CHUNKSIZE = 2048  # hopefully your string fits in here...
    STRTERM = "\x00\x00"
    ch_str = ""
    endea = -1
    chunk = None

    while chunk is None:
        CHUNKSIZE = CHUNKSIZE >> 1
        chunk = GetManyBytes(startea, CHUNKSIZE)
        if CHUNKSIZE == 0:
            print("[!] Failed to grab any bytes.")
            return (endea, ch_str)

    end_idx = chunk.find(STRTERM)
    if end_idx != -1:
        ch_str = chunk[:end_idx]
        endea = startea + end_idx
    if len(ch_str) % 2 != 0:
        ch_str += '\x00'
    ch_str += '\x00\x00'

    try:
        ch_str.decode('ascii')
        return None
    except UnicodeDecodeError:
        pass

    return ch_str
Пример #3
0
    def run(self, args):
        file_path = idaapi.get_input_file_path()

        if not file_path:
            print('Input file path was not found')
            return

        try:
            fd = open(file_path, "rb")
            elf = ELFFile(fd)
        except Exception as x:
            print(x)
            return

        eh_frame_phdr = next(
            (segment for segment in elf.iter_segments() if describe_p_type(segment['p_type']) == 'GNU_EH_FRAME'),
            None)

        if not eh_frame_phdr:
            print("[-] Executable was not compiled with exception unwinding information")
            return

        eh_frame_hdr_data = EhFrameHdr(eh_frame_phdr, elf)
        fde_count = eh_frame_hdr_data.decode_pointer(eh_frame_hdr_data.fde_count_enc, eh_frame_hdr_data.fde_count, pc=eh_frame_phdr['p_vaddr'] + 8)
        block_map = []

        for i in range(0, fde_count):
            (initial_loc, fde_entry_offset) = unpack("2I", GetManyBytes(eh_frame_hdr_data.fde_table_vaddr + 8 * i, 8))
            (function_vaddr, function_size) = eh_frame_hdr_data.decode_pointer(eh_frame_hdr_data.table_enc, initial_loc, fde_entry_offset)
            block_map.append({'function_address': function_vaddr, 'function_size': function_size})
        block_form = BlockForm0(block_map)
        block_form.Show('GNU_EH_FRAME functions')
Пример #4
0
    def decode_pointer(self, encoding_byte, target_entry, pc=None):
        encoding_byte = EncodedByte(encoding_byte)
        value_size = fmt = result = None
        elf_class = self._elf.header['e_ident']['EI_CLASS']

        if encoding_byte.value == DW_EH_PE_omit or encoding_byte.encoding == DW_EH_PE_omit:
            return
        elif encoding_byte.value == DW_EH_PE_uleb128:
            return get_uleb128(target_entry)
        elif encoding_byte.value == DW_EH_PE_sleb128:
            return get_sleb128(target_entry)
        else:
            if encoding_byte.value == DW_EH_PE_absptr:
                value_size = 8 if elf_class == EI_CLASS64 else 4
                fmt = "<q" if elf_class == EI_CLASS64 else "<i"
            elif encoding_byte.value == DW_EH_PE_udata2 or encoding_byte.value == DW_EH_PE_sdata2:
                value_size = 2
                fmt = "<b"
            elif encoding_byte.value == DW_EH_PE_udata4 or encoding_byte.value == DW_EH_PE_sdata4:
                value_size = 4
                fmt = "<i"
            elif encoding_byte.value == DW_EH_PE_udata8 or encoding_byte.value == DW_EH_PE_sdata8:
                value_size = 8
                fmt = "<q"

            if not value_size and not fmt:
                return

            if encoding_byte.encoding == DW_EH_PE_pcrel:
                result = unpack(fmt, GetManyBytes(pc + target_entry, value_size))[0]
            elif encoding_byte.encoding == DW_EH_PE_absptr:
                result = target_entry
            elif encoding_byte.encoding == DW_EH_PE_datarel:
                if target_entry > 0x7fffffff:
                    target_entry -= 0x100000000
                function_vaddr = self._phdr['p_vaddr'] + target_entry
                function_size = \
                    unpack(fmt, GetManyBytes(self.fde_table_vaddr + pc, value_size))[0]
                result = (function_vaddr, function_size)
            elif encoding_byte.encoding == DW_EH_PE_textrel or encoding_byte.encoding == DW_EH_PE_funcrel:
                # These encoding schemes are not implemented. I have read they are not longer supported
                return
        if encoding_byte.encoding & DW_EH_PE_indirect:
            result = unpack(fmt, GetManyBYtes(result, value_size))[0]

        return result
Пример #5
0
def get_hex_bytes_from_ea(ea, length):
    """
    returns a list of hex bytes from an address
    :param ea:
    :param length:
    :return:
    """
    return ['{:02x}'.format(ord(x)) for x in GetManyBytes(ea, length)]
Пример #6
0
 def _getOriginData(self, address, size):
     res = []
     for offset in xrange(0, size, 64):
         tmp = GetManyBytes(address + offset, 64)
         if tmp == None:
             res.extend([pack("<Q", Qword(address + offset + i)) for i in range(0, 64, 8)])
         else:
             res.append(tmp)
     res = "".join(res)
     return res[:size]
Пример #7
0
    def __init__(self, ea, info, cs):
        """Initialization function."""
        # Init the node structure
        node_t.__init__(self)

        # Check if it's a code instruction
        try:
            is_c = is_code(get_flags(ea))
        except:
            is_c = isCode(GetFlags(ea))
        if not is_c:
            raise CodeException

        #
        # fill node_t struct
        #

        # NodeInfo
        self.info = NodeInfo()
        inst_elements = []

        try:
            size = create_insn(ea)
            bytes = get_bytes(ea, size)
        except:
            size = MakeCode(ea)
            bytes = GetManyBytes(ea, size)

        (address, size, mnemonic, op_str) = cs.disasm_lite(bytes, ea, count=1).next()
        self.info.opcode = mnemonic.encode("ascii", "ignore")

        op_str_ascci = op_str.encode("ascii", "ignore")
        self.info.inst_str = self.info.opcode + " " + op_str_ascci

        splitted = op_str_ascci.split(", ")
        self.info.nargs = 0

        if len(splitted) >= 1:
            self.info.arg1 = splitted[0]
            self.info.nargs += 1
            if len(splitted) >= 2:
                self.info.arg2 = splitted[1]
                self.info.nargs += 1
                if len(splitted) >= 3:
                    self.info.arg3 = splitted[2]
                    self.info.nargs += 1

        # No node will be root but this is acceptable for CFGs
        self.info.is_root = False

        self.info.address = ea
        self.info.has_address = True

        # node_t
        self.node_id = self._genid()
Пример #8
0
 def __init__(self, phdr,  elf):
     self._elf = elf
     self._phdr = phdr
     self.vaddr = self._phdr['p_vaddr']
     self.fde_table_vaddr = self.vaddr + 12
     self.file_bytes = GetManyBytes(self._phdr['p_vaddr'], self._phdr['p_filesz'])
     (self.version,
      self.eh_frame_ptr_enc,
      self.fde_count_enc,
      self.table_enc,
      self.eh_frame_ptr,
      self.fde_count) = unpack_from('4c2I', self.file_bytes, 0)
    def get_ch_str(self, startea):
        CHUNKSIZE = 2048  # hopefully your string fits in here...
        STRTERM = "\x00\x00"
        ch_str = ""
        endea = -1
        chunk = None

        while chunk is None:
            CHUNKSIZE = CHUNKSIZE >> 1
            chunk = GetManyBytes(startea, CHUNKSIZE)
            if CHUNKSIZE == 0:
                print("[!] Failed to grab any bytes.")
                return (endea, ch_str)

        end_idx = chunk.find(STRTERM)
        if end_idx != -1:
            ch_str = chunk[:end_idx]
            endea = startea + end_idx
        if len(ch_str) % 2 != 0:
            ch_str += '\x00'
            endea += 1

        foundEncodingFlag = False
        for encoding in ENCODING_LIST:
            try:
                test_str1 = ch_str.decode(encoding)
                test_str2 = test_str1.encode('euc-kr')
                foundEncodingFlag = True
                print '[ ' + encoding + ' string ] '
                self.korean_strings_view.set_encoding(encoding)
                break
            except:
                #print("[!] String does not appear to be %s encoded." % encoding)
                continue

        if foundEncodingFlag == False:
            endea = -1

        return (endea, ch_str.decode(encoding))
Пример #10
0
def findPatchString(config):
    patchStringByteArray = []
    for funcAddr in Functions():
        if GetFunctionName(funcAddr) == config['srcFnName']:
            print('found ea for ' + config['name'])
            break
    for byteIndex in xrange(0, config['patchLength']):
        func_byte_char = GetManyBytes(funcAddr + config['offset'] + byteIndex, 1)
        if func_byte_char is not None:
            patchStringByteArray.append('{:02x}'.format(ord(func_byte_char)))
    PATCH_STRING = ' '.join(patchStringByteArray)
    print('patch found for ' + config['name'] + ' >> ' + PATCH_STRING)
    return PATCH_STRING
Пример #11
0
      int('10', 16),
      'Redirect from UnitUiCtrl$$updatePlayerSkill',
      '01 20 A0 E3 ' +  # MOV R2, #1  flag this jump as player's
      # NOTE: Always check if this code moves.
      #       BL UnitCtrl$$JudgeSkillReadyAndIsMyTurn might move
      getARMBLHexString(call_fb_start_ea + 4,
                        update_player_ea + int('14', 16)) + ' ' +
      '')

###
# Remove FB Graph API lol v2
###
speed_offset = '{:02x}'.format(
    ord(
        GetManyBytes(
            get_ea_from_binary(SET_RECAST_TIME_SIGNATURE) +
            ATK_RECAST_TIME_OFFSET, 1
        )
    )
)
patch(call_fb_start_ea,
      int('0', 16),
      'Remove FB Graph API lol v2',
      #  Original FB code patched to exit early
      '1e ff 2f e1 ' +  # BX lr
      #
      #  UnitUiCtrl$$updatePlayerSkill redirects here
      #  Init phase to set objects we need
      'F0 4D 2D E9 ' +  # STMFD sp!, {r4-r8, r10, r11, lr}
      '04 60 A0 E1 ' +  # MOV r6, r4 (set UnitUICtrl to r6)
      '00 40 A0 E1 ' +  # MOV R4, R0 (set the unitCtrl to r4)
      '00 f0 20 e3 ' +  # NOP for now until we know how to get move rate
Пример #12
0
Файл: Node.py Проект: yaps8/grap
    def __init__(self, ea, cs, IDA_inst, IDA_inst_size, IDA_inst_string):
        """Initialization function, to disassemble with Capstone"""
        # Init the node structure
        node_t.__init__(self)

        # Check if it's a code instruction
        try:
            is_c = is_code(get_flags(ea))
        except:
            is_c = isCode(GetFlags(ea))
        if not is_c:
            raise CodeException

        #
        # fill node_t struct
        #

        # NodeInfo
        self.info = NodeInfo()
        inst_elements = []

        if cs is not None:
            try:
                size = create_insn(ea)
                bytes = get_bytes(ea, size)
            except:
                size = MakeCode(ea)
                bytes = GetManyBytes(ea, size)

            (address, size, mnemonic,
             op_str) = next(cs.disasm_lite(bytes, ea, count=1))
        else:
            address = ea
            size = IDA_inst_size
            splitted = IDA_inst_string.split(" ")
            mnemonic = splitted[0]
            op_str = " ".join(splitted[1:])

        self.info.opcode = mnemonic
        self.info.inst_str = self.info.opcode + " " + op_str

        splitted = op_str.split(", ")
        self.info.nargs = 0

        if len(splitted) >= 1:
            self.info.arg1 = splitted[0]
            self.info.nargs += 1
            if len(splitted) >= 2:
                self.info.arg2 = splitted[1]
                self.info.nargs += 1
                if len(splitted) >= 3:
                    self.info.arg3 = splitted[2]
                    self.info.nargs += 1

        # No node will be root but this is acceptable for CFGs
        self.info.is_root = False

        self.info.address = ea
        self.info.has_address = True

        # node_t
        self.node_id = self._genid()
Пример #13
0
from patchUtil import patchList, get_ea_from_binary, zero_ex, patch
from patchUtil import getARMBLHexString, getFuncEA
from idc import GetManyBytes

###
#  fix wait times
#  always make one of our players have the next turn
#  by making sure each enemy has a wait time of 100
#  and our units get a wait time of 1
###
# GET_UNIT_TYPES_SIGNATURE = 'A0 01 1E FF 2F E1 ? ? 90 E5'
GET_UNIT_TYPES_SIGNATURE = 'AC 00 90 E5 1E FF 2F E1 70 4C 2D E9'
GET_UNIT_TYPES_EA_OFFSET = 0
UNIT_TYPE_BYTES = [
    '{:02x}'.format(ord(char)) for char in GetManyBytes(
        get_ea_from_binary(GET_UNIT_TYPES_SIGNATURE) +
        GET_UNIT_TYPES_EA_OFFSET, 1)
]
# FIX_WAIT_TIMES_SIGNATURE = '10 4A 00 EE 00 60 A0 E1 00 00 56 E3 C0 8A B8 EE'
# 1.4.2 changes moved the target function as a separate name
# "BattleManager:calcWaitValue"
"""
FIX_WAIT_TIMES_SIGNATURE = '00 A0 A0 E3 00 00 A0 E3 07 10 A0 E1 05 20 A0 E1'
FIX_WAIT_TIMES_OFFSET = int('-84', 16)
patch(
    get_ea_from_binary(FIX_WAIT_TIMES_SIGNATURE),
    FIX_WAIT_TIMES_OFFSET,
    'fix wait times',
    '{} 50 90 e5 '.format(' '.join(UNIT_TYPE_BYTES)) +
    # example: 'a4 50 90 e5'
    # LDR r5, [r0, 0xa4]  (check battleUnit.getUnitType)