예제 #1
0
    def __init__(self, configFile):
        self.tree = ET.parse(configFile)
        self.root = self.tree.getroot()

        self.processTable = dict()
        self.getProcessData(self.root)

        self.outputPath = self.root.find("output/path").text
        self.Debug = self.root.find('Debug').text
        self.Logging = self.root.find('Logging').text
        self.configFile = configFile
        Print("Creating a new config object")
    def ReadFile(self):
        """
        Monitors the the beginning of ReadFile function
        ReadFile arguments are read from the stack
        This is the function that will trigger the trace
        inputLoggingList holds arguments for 
        """
        """  
        BOOL WINAPI ReadFile(
          _In_         HANDLE hFile,
          _Out_        LPVOID lpBuffer,
          _In_         DWORD nNumberOfBytesToRead,
          _Out_opt_    LPDWORD lpNumberOfBytesRead,
          _Inout_opt_  LPOVERLAPPED lpOverlapped
        ); 
        """

        hFile = Util.GetData(0x0)
        self.logger.info("hFile is 0x%x" % (hFile))

        lpBuffer = Util.GetData(0x4)
        self.logger.info("lpBuffer is 0x%x" % (lpBuffer))

        nNumberOfBytesToRead = Util.GetData(0x8)
        self.logger.info("nNumberOfBytesToRead value is 0x%x" %
                         (nNumberOfBytesToRead))

        lpNumberOfBytesRead = Util.GetData(0xC)
        self.logger.info("lpNumberOfBytesRead value is 0x%x" %
                         (lpNumberOfBytesRead))

        lpOverlapped = Util.GetData(0x10)
        self.logger.info("lpOverlapped is 0x%x" % (lpOverlapped))

        ea = idc.GetRegValue("EIP")

        retAddr = ea + idc.ItemSize(ea)

        Print("The return address is 0x%x" % retAddr)

        self.tempStack = []
        self.tempStack.append(lpBuffer)
        self.tempStack.append(lpNumberOfBytesRead)
        self.tempStack.append(hFile)
        self.tempStack.append(ea)

        self.tempStack.append("ReadFile")
        self.tempStack.append(idc.GetCurrentThreadId())

        idc.AddBpt(retAddr)
        idc.SetBptCnd(retAddr, "interactivemodeCallback.ReadFileEnd()")

        return 0
예제 #3
0
    def initLogging(self, logfile, bLog, bDbg):

        self.logger = logging.getLogger('IDATrace')

        logging.basicConfig(
            filename=logfile,
            filemode='w',
            format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
            datefmt='%H:%M:%S',
            level=logging.INFO)

        if bLog:
            Print("Logging is turned on.")
            self.logger.disabled = False
        else:
            Print("Logging is turned off.")
            self.logger.disabled = True

        if bDbg:
            Print("Log Debug mode is turned on.")
            self.logger.setLevel(logging.DEBUG)
예제 #4
0
 def init(self):
     Print("tracer_plugin_t installed")
     ExTraces = None
     ExTraces = idaapi.netnode("$ ExTraces", 0,
                               False)  #Get the execution trace id
     data = ExTraces.getblob(0, 'A')
     if data is None:
         print "This IDB has no TREE Trace. Turn ON TREE Tracer"
         return idaapi.PLUGIN_OK
     else:
         print "This IDB has TREE Trace. Turn OFF TREE Trace"
         return idaapi.PLUGIN_SKIP
예제 #5
0
    def MyCreateFileWEnd(self):
        """
        Monitors the end of CreateFileW function
        The return value (handle to the file) for CreateFileW is stored in a set
        """

        Print("Returning from CreateFileW...")
        handle = idc.GetRegValue("EAX")

        self.handleSet.add(handle)
        self.logger.info("HANDLE is 0x%x" % handle)

        return 0
예제 #6
0
    def taintStart(self):

        Print("Taint Start pressed!")
        #Remove the starting breakpoint
        if self.taintStart is not None:
            idc.DelBpt(self.taintStart)
        
        #Add a new starting breakpoint
        self.taintStart = idc.here()
        instruction =  idc.GetDisasm(self.taintStart)
        Print( instruction )
        idc.AddBpt(self.taintStart)
        idc.SetBptAttr(self.taintStart, idc.BPT_BRK, 0)
        
        callbackAddr = "interactivemodeCallback.startTrace()"
        customCallbackFuncs = ['ReadFile','recv']
        
        for callbackFunc in customCallbackFuncs:
            if callbackFunc in instruction:
                callbackAddr = "interactivemodeCallback." + callbackFunc + "()"
                Print("Found callback function %s for interactive mode" % callbackAddr)
                break
        
        idc.SetBptCnd(self.taintStart, callbackAddr)
예제 #7
0
    def My_fread(self):
        """  
        old - size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
        
        size_t _IO_fread (void * ptr, size_t size, size_t count, FILE * stream )
        
        """

        ptr = Util.GetData(0x4)
        self.logger.info("fp is 0x%x" % (ptr))

        _size = Util.GetData(0x8)
        self.logger.info("size is %d" % (_size))

        _count = Util.GetData(0xc)
        self.logger.info("count is %d" % (_count))

        stream = Util.GetData(0x10)
        self.logger.info("stream is 0x%x" % (stream))

        self.pSize = _size * _count
        self.pBuffer = ptr

        retAddr = Util.GetData(0x0)

        callerAddr = retAddr - idc.ItemSize(retAddr)

        self.tempStack = []
        self.tempStack.append(self.pBuffer)
        self.tempStack.append(self.pSize)
        self.tempStack.append(stream)
        self.tempStack.append(callerAddr)

        self.tempStack.append("fread")
        self.tempStack.append(idc.GetCurrentThreadId())

        if stream in self.handleSet:
            self.logger.info("Found stream 0x%x" % stream)

            idc.AddBpt(retAddr)
            idc.SetBptAttr(retAddr, idc.BPT_BRK, 0)
            idc.SetBptCnd(retAddr, "linuxFileIO.My_freadEnd()")
        else:
            self.logger.info("Cannot find handle 0x%x" % stream)
            Print("Removing un-needed fread breakpoint.")
            idc.DelBpt(retAddr)

        return 0
예제 #8
0
    def populateConfig(self):
        """
        Populate the GUI with configuration parameters from config.xml
        """

        from ..core.DebugPrint import dbgPrint, Print

        self.processConfig = self.idaTracer.getProcessConfig()
        if self.processConfig is None:
            Print("Error, we need to add a new config")
            Print("Should not get here!!!")
        else:
            self.application_edit.setText(self.processConfig.getApplication())
            self.path_edit.setText(self.processConfig.getPath())
            self.name_label_d.setText(self.processConfig.getName())
            self.os_label_d.setText(self.processConfig.getOsType() + " " +
                                    self.processConfig.getOsArch() + " Bit")
            self.arguments_edit.setText(self.processConfig.getArgs())
            #sdir  = self.processConfig.getSdir()
            self.host_label_edit.setText(self.processConfig.getHost())
            self.password_label_edit.setText(self.processConfig.getPass())
            #_debugger = self.processConfig.getDebugger()

            #port  = int(self.processConfig.getPort())
            self.port_label_edit.setText(self.processConfig.getPort())
            if self.processConfig.getRemote() == "True":
                self.remote_cb.setCheckState(self.QtCore.Qt.Checked)
                self.host_label_edit.setEnabled(1)
                self.password_label_edit.setEnabled(1)
                self.port_label_edit.setEnabled(1)
            else:
                self.remote_cb.setCheckState(self.QtCore.Qt.Unchecked)
                self.host_label_edit.setDisabled(1)
                self.password_label_edit.setDisabled(1)
                self.port_label_edit.setDisabled(1)

            self.filters = dict()

            fileFilter = self.processConfig.getFileFilter()
            if fileFilter is not None:

                Print("Found %d file filters" % len(fileFilter))
                self.populateFiltersTable(fileFilter,
                                          self.filters_filename_table)
            else:
                Print("No file filters found")

            networkFilter = self.processConfig.getNetworkFilter()
            if networkFilter is not None:

                Print("Found %d network filters" % len(networkFilter))
                self.populateFiltersTable(networkFilter,
                                          self.filters_network_port_table)
            else:
                Print("No network filters found")
예제 #9
0
    def getConfigFromGUI(self):
        """
        Grabs the current configuration parameters from the GUI
        """
        from ..core.DebugPrint import dbgPrint, Print

        #Get all the process config data from the GUI
        self.processConfig.application = str(self.application_edit.text())
        self.processConfig.path = str(self.path_edit.text())
        self.processConfig.args = str(self.arguments_edit.text())
        self.processConfig.host = str(self.host_label_edit.text())
        self.processConfig._pass = str(self.password_label_edit.text())
        self.processConfig.port = str(self.port_label_edit.text())
        #Hardcoded debugger until we integrate kernel trace
        #self.processConfig.debugger =
        if self.remote_cb.isChecked():
            self.processConfig.remote = "True"
        else:
            self.processConfig.remote = "False"

        tempFileFilter = []
        for row in range(self.filters_filename_table.rowCount()):
            data = self.filters_filename_table.item(row, 0).text()
            #Print( "Adding file %s" % data )
            tempFileFilter.append(data)

        if len(tempFileFilter) > 0:
            self.processConfig.fileFilter = tempFileFilter
        else:
            self.processConfig.fileFilter = None

        tempNetworkFilter = []

        for row in range(self.filters_network_port_table.rowCount()):
            data = self.filters_network_port_table.item(row, 0).text()
            Print("Adding port %s" % data)
            tempNetworkFilter.append(data)

        if len(tempNetworkFilter) > 0:
            self.processConfig.networkFilter = tempNetworkFilter
        else:
            self.processConfig.networkFilter = None
예제 #10
0
    def onAttachProcessButtonClicked(self):
        """
        Attaching to an exsiting process - This is disabled for this version
        """

        #start debugging
        self.getConfigFromGUI()
        if not self.pin_cb.isChecked():
            if self.checkInteractiveMode():
                self.idaTracer.attach(self.processConfig)
        else:
            if self.remote_cb.isChecked():
                if len(self.processConfig.host) > 0:
                    port = int(self.processConfig.port, 10)
                    self.pinCommunication(self.processConfig.host, port, True)
                else:
                    #IDA alert box
                    Print("Please enter a host address to debug")
            else:
                self.pinCommunication()
예제 #11
0
    def recv(self):
        """
        int recv(
        _In_   SOCKET s,
        _Out_  char *buf,
        _In_   int len,
        _In_   int flags
         );
        """

        s = Util.GetData(0x0)
        self.logger.info("checkRecv: Socket is 0x%x" % (s))

        buf = Util.GetData(0x4)
        self.logger.info("checkRecv: *buf is 0x%x" % (buf))

        _len = Util.GetData(0x8)
        self.logger.info("checkRecv: len value is %d" % (_len))

        flag = Util.GetData(0xC)
        self.logger.info("checkRecv: flag value is %d" % (flag))

        ea = idc.GetRegValue("EIP")

        retAddr = ea + idc.ItemSize(ea)

        Print("The return address is 0x%x" % retAddr)

        self.tempStack = []
        self.tempStack.append(s)
        self.tempStack.append(buf)
        self.tempStack.append(_len)
        self.tempStack.append(ea)
        self.tempStack.append("recv")
        self.tempStack.append(idc.GetCurrentThreadId())

        idc.AddBpt(retAddr)
        idc.SetBptAttr(retAddr, idc.BPT_BRK, 0)
        idc.SetBptCnd(retAddr, "interactivemodeCallback.recvEnd()")

        return 0
예제 #12
0
    def __init__(self, parent, funcCallbacks):
        from ..core.DebugPrint import dbgPrint, Print

        from ..core.structures.Tracer import IDATrace
        from ..core.structures.Tracer.Config.config import ProcessConfig as ProcessConfig

        super(TraceGeneratorWidget, self).__init__()
        Print("[|] loading TraceGenerationWidget")

        self.idaTracer = IDATrace(funcCallbacks)
        self.processConfig = ProcessConfig()
        self.parent = parent
        self.name = "Trace Generation"

        tracer_icon_path = os.path.join(self.parent.iconPath, "trace.png")
        self.icon = QtGui.QIcon(tracer_icon_path)

        self.QtGui = QtGui
        self.QtCore = QtCore
        self.central_widget = self.QtGui.QWidget()
        self.setCentralWidget(self.central_widget)
        self._createGui()
        self.populateConfig()
예제 #13
0
    def MyCreateFileW(self):
        """
        Monitors the the beginning of CreateFileW function
        CreateFileW arguments are read from the stack
        """
        """
        HANDLE WINAPI CreateFileW(
        _In_      LPCTSTR lpFileName,
        _In_      DWORD dwDesiredAccess,
        _In_      DWORD dwShareMode,
        _In_opt_  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
        _In_      DWORD dwCreationDisposition,
        _In_      DWORD dwFlagsAndAttributes,
        _In_opt_  HANDLE hTemplateFile
        );
        """

        lpFileName = Util.GetData(0x4)
        self.logger.info("MyCreateFileW lpFileName is 0x%x" % lpFileName)

        filePath = "".join(Util.Read(lpFileName, 2))

        self.logger.info("filePath is %s" % filePath)

        dwDesiredAccess = Util.GetData(0x8)
        self.logger.info("dwDesiredAccess is 0x%x" % (dwDesiredAccess))

        dwShareMode = Util.GetData(0xC)
        self.logger.info("dwShareMode value is 0x%x" % (dwShareMode))

        lpSecurityAttributes = Util.GetData(0x10)
        self.logger.info("lpSecurityAttributes value is 0x%x" %
                         (lpSecurityAttributes))

        dwCreationDisposition = Util.GetData(0x14)
        self.logger.info("dwCreationDisposition value is 0x%x" %
                         (dwCreationDisposition))

        dwFlagsAndAttributes = Util.GetData(0x18)
        hTemplateFile = Util.GetData(0x1C)

        fileName = os.path.basename(filePath)

        self.logger.info("The filename is %s" % fileName)

        retAddr = Util.GetData(0x0)

        if fileName in self.filter['file']:
            idc.AddBpt(retAddr)
            idc.SetBptAttr(retAddr, idc.BPT_BRK, 0)
            idc.SetBptCnd(retAddr, "windowsFileIO.MyCreateFileWEnd()")
            self.logger.info(
                "Filter matched. Add handle to the handle's dictionary to start logging."
            )
            Print(
                "Filter matched. Add handle to the handle's dictionary to start logging."
            )

        else:
            if idc.CheckBpt(retAddr) >= 0:
                Print("Removing un-needed breakpoint.")
                self.logger.info("Removing un-needed breakpoint.")
                idc.DelBpt(retAddr)

            self.logger.info("Filter did not match.")

        return 0
예제 #14
0
 def SetDebuggerInstance(self, dbgHook):
     Print("Setting InteractivemodeFunctions debugging instances.")
     self.debuggerInstance = dbgHook
예제 #15
0
    def term(self):
        """
        Called when the plugsin terminates
        """

        Print("tracer_plugin_t uninstalled!")
예제 #16
0
def checkMacOSXLibs(name,ea):
    #TODO: Mac implementation
    Print( "Checking Mac OSX" )
    
예제 #17
0
def checkLinuxLibs(name,ea,bCheckFileIO,bCheckNetworkIO):
    """
    This function monitors loaded libaries for Linux
    If any of these libaries and functions are loaded
    a conditional breakpoint is set
    
    LIBC - _IO_file_fopen _IO_fread _IO_fclose
    
    @param name: The name of the loaded library
    @param ea: The address of the loaded library
    @param bCheckFileIO: Checks to see if FileIO filtering was turned on
    @param bCheckNetworkIO: Checks to see if NetworkIO filtering was turned on
    @return: None        
    """
    
    import idc
    import logging
    Print ("Found Libc at 0x%x" % ea)
    logger = logging.getLogger('IDATrace')
    
    logger.info( "Found Libc at 0x%x" % ea )
    idc.RefreshDebuggerMemory() 
    library_name = name.upper()
    
    Print( "Checking Linux for library " + library_name )
    
    if "LIBC" in library_name:

        if bCheckFileIO:
            
            fopen_func = idc.LocByName("_IO_file_fopen");
            
            if fopen_func == idc.BADADDR:
                logger.info( "Cannot find _IO_file_fopen" )
                # "Cannot find _IO_file_fopen."
            else:
                logger.info( "We found _IO_file_fopen at 0x%x." % fopen_func )
                Print( "We found _IO_file_fopen at 0x%x." % fopen_func )
                idc.AddBpt(fopen_func)
                idc.SetBptAttr(fopen_func, idc.BPT_BRK, 0)
                idc.SetBptCnd(fopen_func, "linuxFileIO.My_fopen()")
            
            fread_func = idc.LocByName("_IO_fread");
            
            if fread_func == idc.BADADDR:
                logger.info( "Cannot find _IO_fread" )
                Print( "Cannot find _IO_fread." )
            else:
                logger.info( "We found _IO_fread at 0x%x." % fread_func )
                Print( "We found _IO_fread at 0x%x." % fread_func  )
                idc.AddBpt(fread_func)
                idc.SetBptAttr(fread_func, idc.BPT_BRK, 0)
                idc.SetBptCnd(fread_func, "linuxFileIO.My_fread()")
    
            fclose_func = idc.LocByName("_IO_fclose");
            
            if fclose_func == idc.BADADDR:
                logger.info( "Cannot find _IO_fclose" )
                Print( "Cannot find _IO_fclose." )
            else:
                logger.info( "We found _IO_fclose at 0x%x." % fclose_func )
                Print( "We found _IO_fclose at 0x%x." % fclose_func  )
                idc.AddBpt(fclose_func)
                idc.SetBptAttr(fclose_func, idc.BPT_BRK, 0)
                idc.SetBptCnd(fclose_func, "linuxFileIO.My_fclose()")
예제 #18
0
    def write(self, processConfig):
        config = self.root

        newProcess = Element("process")
        #Before writing or updating the config.xml file, we need to refresh the internal process table
        self.getProcessData(self.root)

        if self.processTable.has_key(
                str(processConfig.getName()) + str(processConfig.getOsType()) +
                str(processConfig.getOsArch())):
            Print("updating an existing configuration")
            self.update(processConfig)
        else:
            Print("Adding a new configuration")
            #adding a new process config
            newProcess.attrib["name"] = processConfig.getName()
            newProcess.attrib["OS"] = processConfig.getOsType()
            newProcess.attrib["Arch"] = processConfig.getOsArch()

            newProcess_input = Element("input")

            application = Element("application")
            application.text = processConfig.getApplication()
            newProcess_input.append(application)

            path = Element("path")
            path.text = processConfig.getPath()
            newProcess_input.append(path)

            args = Element("args")
            args.text = processConfig.getArgs()
            newProcess_input.append(args)

            args = Element("sdir")
            args.text = "."
            newProcess_input.append(args)

            remote = Element("remote")
            remote.text = "False"
            newProcess_input.append(remote)

            pin = Element("pin")
            pin.text = "False"
            newProcess_input.append(pin)

            host = Element("host")
            host.text = ""
            newProcess_input.append(host)

            _pass = Element("pass")
            _pass.text = ""
            newProcess_input.append(_pass)

            port = Element("port")
            port.text = "0"
            newProcess_input.append(port)

            debugger = Element("debugger")
            debugger.text = processConfig.getDebugger()
            newProcess_input.append(debugger)
            """
            filter_file = Element("filter")
            filter_file.attrib["type"] = "fileIO"
            filter_file.text = ""
            
            filter_network = Element("filter")
            filter_network.attrib["type"] = "networkIO"
            filter_network.text = ""
            """
            newProcess.append(newProcess_input)
            #newProcess.append(filter_file)
            #newProcess.append(filter_network)

            config.append(newProcess)

        #self.tree.write("output.xml")
        self.tree.write(self.configFile, "UTF-8")