# author: ww9210
import angr
from angr import concretization_strategies
import claripy
from pwn import *
import statebroker
import _concrete_state
import _explore_routine
import _explore_impl
import _stats_explore
import _instrumentations
import _debugging_util
import _bp_handler
import _smep_bypass
import _payload_packer
import _houses_on_the_heap
import _exploit_knowledge_graph
import neo4j_interace
import neo4j
import pickle

# context.log_level = 'debug'
kernel_io_funcs = ['__put_user_4']


class ConcolicExecutor(object, _concrete_state.ConcreteStateMixin
                       , _explore_routine.ExploreRoutineMixin
                       , _explore_impl.ExploreImplMixin
                       , _stats_explore.StatsExploreMixin
                       , _instrumentations.InstrumentationMixin
                       , _bp_handler.BPHandlerMixin
                       , _debugging_util.DebuggingUtilMixin
                       , _smep_bypass.SMEPBypassMixin
                       , _payload_packer.PayloadPackerMixin
                       , _houses_on_the_heap.HousesOnTheHeapMixin
                       , _exploit_knowledge_graph.ExploitKnowledgeGraphMixin
                       ):
    def __init__(self, kernel_path=None, dbcred=\
            '/home/ww9210/develop/concolic_execution/concolicexecutor/dbcredentials.bin'):
        self.kernel_path = kernel_path
        self.k = ELF(kernel_path)
        self.b = angr.Project(kernel_path)
        self.sol = claripy.Solver()
        self.claripy = claripy
        self.typebv = claripy.ast.bv.BV
        self.r = None
        self.statebroker = statebroker.StateBroker()
        self.krop = None
        self.interested_funcs = {}
        self.memory_leak_funcs = {}

        # build connection to knowledge graph
        tmpf = open(dbcred, 'r')
        url, username, password = pickle.load(tmpf)
        print url, username, password
        try:
            self.neo4j_inst = neo4j_interace.MyNeo4jInterface(url, username, password)
        except neo4j.exceptions.ServiceUnavailable:
            print '[-] could not connect database'
        tmpf.close()

        # primitives
        self.control_flow_hijack_primitive = []  # control flow hijack primitive
        self.write_to_uaf_object_primitive = []  # write to uaf object primitive
        self.write_to_symbolic_address_primitive = []  # write to symbolic address primitive
        self.double_free_primitive = []  # double free primitive
        self.memory_leak_primitive = []  # memory leak primitive

        self.seen_symbolic_write_primitive_addr = []
        self.seen_write_to_uaf_object_primitive_addr = []

        # attributes
        self.start_addr = None
        self.use_custom_concretization_strategy_first = None
        self.qemu_port = None
        self.debug_qemu_backend = None
        self.debug_irsb = None
        self.debug_after_address_concretization = None
        self.resolve_uninit = None
        self.pause_on_finish_memory_loading = None
        self.pause_on_write_to_symbolic_address = None
        self.pause_on_uninit_write = None
        self.pause_on_each_step = None
        self.pause_on_read_from_symbolic_address = None
        self.pause_on_write_to_uaf_object_primitive = None
        self.dump_uaf_buffer = None
        self.dump_userspace_buffer = None
        self.pause_on_failed_memory_resolving = None
        self.pause_on_control_flow_hijack = None
        self.pause_on_memory_leak = None
        self.remove_range_concretize = None
        self.userspace_base = None
        self.kuafffp_concretizer = None

        self.seen_control_flow_hijack_primitive = []
        self.seen_memory_leak_primitive = []

        self.concretization_range = None
        self.extra_bp = None
        self.execution_time_limit = None
        self.expected_start_rip = None
        self.limit_loop = None
        self.detect_rcu_free = None
        self.detect_memory_leak = None
        self.assigned_start_time = None
        self.start_time_of_symbolic_execution = None
        self.function_call_to_disable = None
        self.stack_pivot_address = None
        self.additional_symbolic_registers = None
        self.name_concretization_strategy = None
        self.num_user_pages = None
        self.spray_method = None
        self.pause_on_strange_state = None
        self.target_allocator = None
        self.vulnerability_type = None
        self.look_for_second_control_flow_hijack = None
        return

    def setup(self, start_addr=None
              , vulnerability_type='uaf'
              , use_custom_concretization_strategy_first=True
              , qemu_port=9210
              , debug_irsb=False
              , debug_qemu_backend=True
              , debug_after_address_concretization=False
              , resolve_uninit=True
              , pause_on_finish_memory_loading=False
              , pause_on_write_to_symbolic_address=True
              , pause_on_uninit_write=True
              , pause_on_each_step=False
              , pause_on_read_from_symbolic_address=False
              , dump_uaf_buffer=True
              , dump_userspace_buffer=True
              , pause_on_failed_memory_resolving=False
              , concretization_range=1024
              , pause_on_write_to_uaf_object_primitive=True
              , pause_on_control_flow_hijack=True
              , pause_on_memory_leak=True
              , extra_bp=[]
              , execution_time_limit=60*30
              , expected_start_rip=None
              , limit_loop=True
              , detect_rcu_free=False
              , detect_memory_leak=True
              , callback_functions_to_monitor=None
              , assigned_start_time=None
              , function_call_to_disable=None
              , additional_symbolic_registers=[]
              , userspace_base=0xfacea000
              , name_concretization_strategy='kuafffp'
              , num_user_pages=1
              , spray_method='add_key'
              , pause_on_strange_state=True
              , target_allocator='slub'
              , look_for_second_control_flow_hijack=True
              ):
        self.start_addr = start_addr
        self.use_custom_concretization_strategy_first = use_custom_concretization_strategy_first
        self.qemu_port = qemu_port
        self.debug_qemu_backend = debug_qemu_backend
        self.debug_irsb = debug_irsb
        self.debug_after_address_concretization = debug_after_address_concretization
        self.resolve_uninit = resolve_uninit
        self.pause_on_finish_memory_loading = pause_on_finish_memory_loading
        self.pause_on_write_to_symbolic_address = pause_on_write_to_symbolic_address
        self.pause_on_uninit_write = pause_on_uninit_write
        self.pause_on_each_step = pause_on_each_step
        self.pause_on_read_from_symbolic_address = pause_on_read_from_symbolic_address
        self.pause_on_write_to_uaf_object_primitive = pause_on_write_to_uaf_object_primitive
        self.dump_uaf_buffer = dump_uaf_buffer
        self.dump_userspace_buffer = dump_userspace_buffer
        self.pause_on_failed_memory_resolving = pause_on_failed_memory_resolving
        self.pause_on_control_flow_hijack = pause_on_control_flow_hijack
        self.pause_on_memory_leak = pause_on_memory_leak
        self.remove_range_concretize = False
        self.userspace_base = userspace_base
        self.kuafffp_concretizer=concretization_strategies.SimConcretizationStrategyKuafffp(userspace_base, 4096)
        self.name_concretization_strategy = name_concretization_strategy

        self.seen_control_flow_hijack_primitive = []
        self.seen_memory_leak_primitive = []
        
        self.concretization_range = concretization_range
        self.extra_bp = extra_bp
        self.execution_time_limit = execution_time_limit
        self.expected_start_rip = expected_start_rip
        self.limit_loop=limit_loop
        self.detect_rcu_free = detect_rcu_free
        self.detect_memory_leak = detect_memory_leak
        self.assigned_start_time = assigned_start_time
        self.start_time_of_symbolic_execution = 0
        self.function_call_to_disable = function_call_to_disable
        self.additional_symbolic_registers = additional_symbolic_registers
        self.num_user_pages = num_user_pages
        self.spray_method = spray_method
        self.target_allocator = target_allocator
        self.vulnerability_type = vulnerability_type
        self.look_for_second_control_flow_hijack = look_for_second_control_flow_hijack

        self.pause_on_strange_state = pause_on_strange_state

        if callback_functions_to_monitor is not None:
            for name in callback_functions_to_monitor:
                print '[+] need to monitor:', name, 'for primitive'
                self.interested_funcs[name] = self.k.symbols[name]

        if self.detect_memory_leak:  # detect memory disclosure primitive
            for name in kernel_io_funcs:
                self.memory_leak_funcs[name] = self.k.symbols[name]
        return




from .restoreandse import RestoreAndSE

# author: ww9210
import angr
from angr import concretization_strategies
import claripy
from pwn import *
import statebroker
import _concrete_state
import _explore_routine
import _explore_impl
import _stats_explore
import _instrumentations
import _debugging_util
import _bp_handler
import _smep_bypass
import _payload_packer
import _houses_on_the_heap
import _exploit_knowledge_graph
import neo4j_interace
import neo4j
import pickle

# context.log_level = 'debug'
kernel_io_funcs = ['__put_user_4']


class ConcolicExecutor(object, _concrete_state.ConcreteStateMixin
                       , _explore_routine.ExploreRoutineMixin
                       , _explore_impl.ExploreImplMixin
                       , _stats_explore.StatsExploreMixin
                       , _instrumentations.InstrumentationMixin
                       , _bp_handler.BPHandlerMixin
                       , _debugging_util.DebuggingUtilMixin
                       , _smep_bypass.SMEPBypassMixin
                       , _payload_packer.PayloadPackerMixin
                       , _houses_on_the_heap.HousesOnTheHeapMixin
                       , _exploit_knowledge_graph.ExploitKnowledgeGraphMixin
                       ):
    def __init__(self, kernel_path=None, dbcred=\
            '/home/ww9210/develop/concolic_execution/concolicexecutor/dbcredentials.bin'):
        self.kernel_path = kernel_path
        self.k = ELF(kernel_path)
        self.b = angr.Project(kernel_path)
        self.sol = claripy.Solver()
        self.claripy = claripy
        self.typebv = claripy.ast.bv.BV
        self.r = None
        self.statebroker = statebroker.StateBroker()
        self.krop = None
        self.interested_funcs = {}
        self.memory_leak_funcs = {}

        # build connection to knowledge graph
        tmpf = open(dbcred, 'r')
        url, username, password = pickle.load(tmpf)
        print url, username, password
        try:
            self.neo4j_inst = neo4j_interace.MyNeo4jInterface(url, username, password)
        except neo4j.exceptions.ServiceUnavailable:
            print '[-] could not connect database'
        tmpf.close()

        # primitives
        self.control_flow_hijack_primitive = []  # control flow hijack primitive
        self.write_to_uaf_object_primitive = []  # write to uaf object primitive
        self.write_to_symbolic_address_primitive = []  # write to symbolic address primitive
        self.double_free_primitive = []  # double free primitive
        self.memory_leak_primitive = []  # memory leak primitive

        self.seen_symbolic_write_primitive_addr = []
        self.seen_write_to_uaf_object_primitive_addr = []

        # attributes
        self.start_addr = None
        self.use_custom_concretization_strategy_first = None
        self.qemu_port = None
        self.debug_qemu_backend = None
        self.debug_irsb = None
        self.debug_after_address_concretization = None
        self.resolve_uninit = None
        self.pause_on_finish_memory_loading = None
        self.pause_on_write_to_symbolic_address = None
        self.pause_on_uninit_write = None
        self.pause_on_each_step = None
        self.pause_on_read_from_symbolic_address = None
        self.pause_on_write_to_uaf_object_primitive = None
        self.dump_uaf_buffer = None
        self.dump_userspace_buffer = None
        self.pause_on_failed_memory_resolving = None
        self.pause_on_control_flow_hijack = None
        self.pause_on_memory_leak = None
        self.remove_range_concretize = None
        self.userspace_base = None
        self.kuafffp_concretizer = None

        self.seen_control_flow_hijack_primitive = []
        self.seen_memory_leak_primitive = []

        self.concretization_range = None
        self.extra_bp = None
        self.execution_time_limit = None
        self.expected_start_rip = None
        self.limit_loop = None
        self.detect_rcu_free = None
        self.detect_memory_leak = None
        self.assigned_start_time = None
        self.start_time_of_symbolic_execution = None
        self.function_call_to_disable = None
        self.stack_pivot_address = None
        self.additional_symbolic_registers = None
        self.name_concretization_strategy = None
        self.num_user_pages = None
        self.spray_method = None
        self.pause_on_strange_state = None
        self.target_allocator = None
        self.vulnerability_type = None
        self.look_for_second_control_flow_hijack = None
        return

    def setup(self, start_addr=None
              , vulnerability_type='uaf'
              , use_custom_concretization_strategy_first=True
              , qemu_port=9210
              , debug_irsb=False
              , debug_qemu_backend=True
              , debug_after_address_concretization=False
              , resolve_uninit=True
              , pause_on_finish_memory_loading=False
              , pause_on_write_to_symbolic_address=True
              , pause_on_uninit_write=True
              , pause_on_each_step=False
              , pause_on_read_from_symbolic_address=False
              , dump_uaf_buffer=True
              , dump_userspace_buffer=True
              , pause_on_failed_memory_resolving=False
              , concretization_range=1024
              , pause_on_write_to_uaf_object_primitive=True
              , pause_on_control_flow_hijack=True
              , pause_on_memory_leak=True
              , extra_bp=[]
              , execution_time_limit=60*30
              , expected_start_rip=None
              , limit_loop=True
              , detect_rcu_free=False
              , detect_memory_leak=True
              , callback_functions_to_monitor=None
              , assigned_start_time=None
              , function_call_to_disable=None
              , additional_symbolic_registers=[]
              , userspace_base=0xfacea000
              , name_concretization_strategy='kuafffp'
              , num_user_pages=1
              , spray_method='add_key'
              , pause_on_strange_state=True
              , target_allocator='slub'
              , look_for_second_control_flow_hijack=True
              ):
        self.start_addr = start_addr
        self.use_custom_concretization_strategy_first = use_custom_concretization_strategy_first
        self.qemu_port = qemu_port
        self.debug_qemu_backend = debug_qemu_backend
        self.debug_irsb = debug_irsb
        self.debug_after_address_concretization = debug_after_address_concretization
        self.resolve_uninit = resolve_uninit
        self.pause_on_finish_memory_loading = pause_on_finish_memory_loading
        self.pause_on_write_to_symbolic_address = pause_on_write_to_symbolic_address
        self.pause_on_uninit_write = pause_on_uninit_write
        self.pause_on_each_step = pause_on_each_step
        self.pause_on_read_from_symbolic_address = pause_on_read_from_symbolic_address
        self.pause_on_write_to_uaf_object_primitive = pause_on_write_to_uaf_object_primitive
        self.dump_uaf_buffer = dump_uaf_buffer
        self.dump_userspace_buffer = dump_userspace_buffer
        self.pause_on_failed_memory_resolving = pause_on_failed_memory_resolving
        self.pause_on_control_flow_hijack = pause_on_control_flow_hijack
        self.pause_on_memory_leak = pause_on_memory_leak
        self.remove_range_concretize = False
        self.userspace_base = userspace_base
        self.kuafffp_concretizer=concretization_strategies.SimConcretizationStrategyKuafffp(userspace_base, 4096)
        self.name_concretization_strategy = name_concretization_strategy

        self.seen_control_flow_hijack_primitive = []
        self.seen_memory_leak_primitive = []
        
        self.concretization_range = concretization_range
        self.extra_bp = extra_bp
        self.execution_time_limit = execution_time_limit
        self.expected_start_rip = expected_start_rip
        self.limit_loop=limit_loop
        self.detect_rcu_free = detect_rcu_free
        self.detect_memory_leak = detect_memory_leak
        self.assigned_start_time = assigned_start_time
        self.start_time_of_symbolic_execution = 0
        self.function_call_to_disable = function_call_to_disable
        self.additional_symbolic_registers = additional_symbolic_registers
        self.num_user_pages = num_user_pages
        self.spray_method = spray_method
        self.target_allocator = target_allocator
        self.vulnerability_type = vulnerability_type
        self.look_for_second_control_flow_hijack = look_for_second_control_flow_hijack

        self.pause_on_strange_state = pause_on_strange_state

        if callback_functions_to_monitor is not None:
            for name in callback_functions_to_monitor:
                print '[+] need to monitor:', name, 'for primitive'
                self.interested_funcs[name] = self.k.symbols[name]

        if self.detect_memory_leak:  # detect memory disclosure primitive
            for name in kernel_io_funcs:
                self.memory_leak_funcs[name] = self.k.symbols[name]
        return




from .restoreandse import RestoreAndSE

# author: ww9210 # context.log_level = 'debug' # build connection to knowledge graph # primitives # control flow hijack primitive # write to uaf object primitive # write to symbolic address primitive # double free primitive # memory leak primitive # attributes # detect memory disclosure primitive