Example #1
0
    def _go_to_instruction(self,
                           instruction_search,
                           offset,
                           history=[],
                           indent=1):
        """

        """
        if offset == 0:
            self.next()
            eip = self.register.eip
            offset = eip
        for d in Decode(offset, self.data_code[offset:offset + 0x1000]):
            instruction = d[2]
            offset = d[0]
            history.append(offset)
            if instruction_search in instruction:
                self.backhistory = history
                self.set_position(offset)
                return True

            if 'RET' in instruction:
                return False

            if "CALL" in instruction:
                address_expression = self._get_function_name(instruction)

                if "0x" in address_expression:
                    if '[' in address_expression:
                        continue
                    if ':' in address_expression:
                        continue

                    try:
                        address = compute_operation(address_expression,
                                                    self.register)

                        if address in history:
                            continue

                        if address not in self.map_call:
                            self.map_call[address] = "CALL_%x" % address
                            self.map_call_by_name["CALL_%x" %
                                                  address] = address

                        if self._go_to_instruction(instruction_search, address,
                                                   history, indent + 1):
                            return True

                    except Exception as e:
                        print >> sys.stderr, "".join([
                            bcolors.FAIL,
                            "\tError: Can't eval instruction'%s'" %
                            instruction, bcolors.ENDC
                        ])

        return False
 def test_compute_instructrion(self, o):
     """
     Test
     """
     register = Register32()
     value = compute_operation(o[0], register)
     if value != o[1]:
         assert False
     else:
         assert True
    def test_compute_operation_register(self, o):
        """
        Test de l'initialisation du moteur disass 32
        """

        register = Register32()
        register.eax = 5
        register.edx = 1
        r = compute_operation(o[0], register)
        if r == o[1]:
            assert True
        else:
            print o[0], o[1], r
            assert False
        return
    def test_compute_operation_basic(self, o):
        """
        Test de l'initialisation du moteur disass 32
        """
        register = Register32()
        r = compute_operation(o[0], register)

        if r == o[1]:
            print o[1], "=", str(r)
            assert True
        else:
            print "%s !!! %s != %s " % (o[0], str(r), str(o[1]))
            assert False

        return
Example #5
0
    def _make_xref(self, name, offset, depth=1):
        if offset in self.map_call:
            return

        self.map_call[offset] = name
        self.map_call_by_name[name] = offset

        for d in Decode(offset, self.data_code[offset:offset + 0x1000]):
            instruction = d[2]
            offset = d[0]

            if "CALL" in instruction:
                address_expression = self._get_function_name(instruction)

                if "0x" in address_expression:
                    if '[' in address_expression:
                        continue
                    if ':' in address_expression:
                        continue

                    try:
                        address = compute_operation(address_expression,
                                                    self.register)
                    except Exception as e:
                        print >> sys.stderr, str(e), address_expression
                        print >> sys.stderr, "".join([
                            bcolors.FAIL,
                            "\tError: Can't eval CALL instruction'%s'" %
                            instruction, bcolors.ENDC
                        ])
                        continue

                    if address not in self.map_call:
                        self._make_xref("CALL_%x" % address, address,
                                        depth + 1)

                    continue

                if self.is_register(instruction):
                    continue

                if address_expression not in self.xref:
                    self.xref[address_expression] = set()
                self.xref[address_expression].add(offset)
Example #6
0
    def update_stack_and_register(self, offset=None):
        """
        Update Stack and register
        """
        if offset is None:
            offset = self.register.eip
        bloc = ''
        # Am I on a function ?
        functionname = self.where_am_i(offset)

        addr = self.map_call_by_name[functionname]
        if addr < offset:
            s = addr
            e = offset
        else:
            s = self.where_start_my_bloc()
            e = offset

        self.stack = list()
        for d in Decode(addr, self.data_code[s:e]):
            if "PUSH" in d[2]:
                svalue = self._extract_value(d[2])

                if svalue == '':
                    continue

                if '[' in svalue:
                    svalue = svalue[1:-1]
                    svalue = compute_operation(svalue, self.register)
                    svalue = "[%s]" % svalue
                else:
                    svalue = compute_operation(svalue, self.register)
                self.stack.append(svalue)

            elif "POP" in d[2]:
                svalue = self._extract_value(d[2])

                if svalue == '':
                    continue

                svalue = compute_operation(svalue, self.register)
                self.stack.append(svalue)

            elif "CALL" in d[2]:
                continue

            elif "LEAVE" in d[2]:
                continue

            elif "MOVSD" in d[2]:
                continue

            elif "MOV" in d[2] or "LEA" in d[2]:
                bloc = d[2].split(' ')
                if "DWORD" in d[2]:
                    pass
                elif "BYTE" in d[2]:
                    pass
                else:
                    bloc = d[2].split(' ')

                    if 'REP' in bloc:
                        continue
                    if 'MOVSW' in bloc:
                        continue
                    if 'MOVSB' in bloc:
                        continue
                    if 'MOVZX' in bloc:
                        continue
                    if 'MOV WORD' in d[2]:
                        continue
                    try:

                        dst = bloc[1][:-1].lower()
                        src = bloc[2].lower()

                        if '[' in dst:
                            continue
                        if ':' in src or ':' in dst:
                            continue

                        if '[' in src:
                            value_src = compute_operation(
                                src[1:-1], self.register)
                            self.register.set_address(dst, value_src)
                        else:
                            value_src = compute_operation(src, self.register)
                            self.register.set(dst, value_src)

                    except Exception as e:
                        print >> sys.stderr, "".join([
                            bcolors.FAIL,
                            "\tError: '%s'" % bloc, bcolors.ENDC
                        ])
                        print >> sys.stderr, "".join([
                            bcolors.FAIL,
                            "\tError: Can't update stack and registry '%s' for %s"
                            % (str(e), d[2]), bcolors.ENDC
                        ])
                        pass

            elif "XOR" in d[2]:
                try:
                    bloc = d[2].split(' ')
                    dst = bloc[1][:-1].lower()
                    if '[' in d[2]:
                        continue
                    src = bloc[2].lower()
                    self.register.set(
                        dst,
                        self.register.get(dst) ^ self.register.get(src))
                except Exception as e:
                    print >> sys.stderr, "".join(
                        [bcolors.FAIL,
                         "\tError: '%s'" % bloc, bcolors.ENDC])
                    print >> sys.stderr, "".join([
                        bcolors.FAIL,
                        "\tError: Can't xor '%s' for %s" % (str(e), d[2]),
                        bcolors.ENDC
                    ])
                    pass
        self.stack.reverse()
Example #7
0
    def _go_to_next_call(self, name, offset, history=[], indent=1):
        """

        """
        if offset == 0:
            self.next()
            eip = self.register.eip
            offset = eip

        for d in Decode(offset, self.data_code[offset:offset + 0x1000]):
            instruction = d[2]
            offset = d[0]

            if offset in history:
                return False

            history.append(offset)

            if name in self.replace_function(instruction):
                self.backhistory = history
                self.set_position(offset)
                return True

            if 'RET' in instruction:
                return False

            if 'J' == instruction[0]:
                address_expression = self._get_function_name(instruction)

                if address_expression in self.symbols_imported_by_name:
                    #Trampoline Function
                    name_tampoline = "__jmp__%s" % address_expression
                    self.symbols_imported_by_name[name_tampoline] = offset
                    self.symbols_imported[offset] = name_tampoline

                    if name in name_tampoline:
                        self.set_position(history[-2])
                        self.backhistory = history[:-2]
                        return True

                    return False

                if address_expression is None:
                    continue

                if "0x" in address_expression:
                    if '[' in address_expression:
                        continue
                    if ':' in address_expression:
                        continue

                    try:
                        address = compute_operation(address_expression,
                                                    self.register)
                    except Exception as e:
                        print >> sys.stderr, str(e), address_expression
                        print >> sys.stderr, "".join([
                            bcolors.FAIL,
                            "\tError: Can't eval JMP instruction'%s'" %
                            instruction, bcolors.ENDC
                        ])
                        continue

                    if address in history:
                        continue
                    if self._go_to_next_call(name, address, history,
                                             indent + 1):
                        return True

            if "CALL" in instruction:
                address_expression = self._get_function_name(instruction)

                if "0x" in address_expression:
                    if '[' in address_expression:
                        continue
                    if ':' in address_expression:
                        continue

                    try:
                        address = compute_operation(address_expression,
                                                    self.register)
                    except Exception as e:
                        print >> sys.stderr, str(e), address_expression
                        print >> sys.stderr, "".join([
                            bcolors.FAIL,
                            "\tError: Can't eval CALL instruction'%s'" %
                            instruction, bcolors.ENDC
                        ])
                        continue

                    if address in history:
                        continue

                    if address not in self.map_call:
                        self.map_call[address] = "CALL_%x" % address
                        self.map_call_by_name["CALL_%x" % address] = address

                    if self._go_to_next_call(name, address, history,
                                             indent + 1):
                        return True

                if self.is_register(instruction):
                    self.backhistory = history
                    self.update_stack_and_register(offset)

                    value = self.register.get(address_expression.lower())
                    if value in self.symbols_imported:
                        if name == self.symbols_imported[value]:
                            self.backhistory = history
                            self.set_position(offset)
                            return True

        return False