Esempio n. 1
0
    def callbackProcessing(self,inputLoggingList):
        """
        This function is a callback from the API monitoring functions
        When the API monitoring functions is ready to start tracing, it calls this function from the debugger to start tracing
        The list of input values is written to a file or memory, then PauseProcess is called to force the debugger to suspend
        Suspending the debugger will then trigger the debugger to go into single stepping mode
        In single stepping mode, each instruction will be written to either memory or a file
        @param inputLoggingList: A list of input values to log
        @return: None        
        """
        data_addr = inputLoggingList.pop(0)
        data_size = inputLoggingList.pop(0)
        data = inputLoggingList.pop(0)
        handle = inputLoggingList.pop(0)
        caller_addr = inputLoggingList.pop(0)
        caller_name = inputLoggingList.pop(0)
        thread_id = inputLoggingList.pop(0)
        
        global instSeq

        self.logger.info( "Taking a memory snapshot then saving to the current idb file.")

        self.logger.info("CallbackProcessing called.  Logging input... I %x %d %s 0x%x 0x%x %s 0x%x 0x%x" % \
             (data_addr,data_size,toHex(data),thread_id,instSeq,caller_name,caller_addr,handle) )
        self.memoryWriter.writeToFile("I %x %d %s 0x%x 0x%x %s 0x%x 0x%x\n" % \
             (data_addr,data_size,toHex(data),thread_id,instSeq,caller_name,caller_addr,handle) )
        
        #update the instruction sequence counter
        instSeq = instSeq+1
        
        self.startTracing = True
        PauseProcess()
Esempio n. 2
0
    def callbackProcessing(self,inputLoggingList):
        """
        This function is a callback from the API monitoring functions
        When the API monitoring functions is ready to start tracing, it calls this function from the debugger to start tracing
        The list of input values is written to a file or memory, then PauseProcess is called to force the debugger to suspend
        Suspending the debugger will then trigger the debugger to go into single stepping mode
        In single stepping mode, each instruction will be written to either memory or a file
        @param inputLoggingList: A list of input values to log
        @return: None        
        """
        data_addr = inputLoggingList.pop(0)
        data_size = inputLoggingList.pop(0)
        data = inputLoggingList.pop(0)
        handle = inputLoggingList.pop(0)
        caller_addr = inputLoggingList.pop(0)
        caller_name = inputLoggingList.pop(0)
        thread_id = inputLoggingList.pop(0)
        
        global instSeq

        self.logger.info( "Taking a memory snapshot then saving to the current idb file.")

        self.logger.info("CallbackProcessing called.  Logging input... I %x %d %s 0x%x 0x%x %s 0x%x 0x%x" % \
             (data_addr,data_size,toHex(data),thread_id,instSeq,caller_name,caller_addr,handle) )
        self.memoryWriter.writeToFile("I %x %d %s 0x%x 0x%x %s 0x%x 0x%x\n" % \
             (data_addr,data_size,toHex(data),thread_id,instSeq,caller_name,caller_addr,handle) )
        
        #update the instruction sequence counter
        instSeq = instSeq+1
        
        self.startTracing = True
        PauseProcess()
Esempio n. 3
0
    def dbg_step_into(self):
        """
        Notified when the debugger is single stepping thru a process
        This is the main function for tracing, we analyze each instruction being executed
        The instruction along with its metadata is written to either memory or out to a file
        This is a standard IDA Debug Hook callback
        """
        
        global instSeq
        
        eip = GetRegValue("EIP")

        DecodeInstruction(eip)
        
        inslen = cmd.size
        
        if cmd.size > 0:
            bytes = get_many_bytes(cmd.ea,cmd.size)

            self.memoryWriter.writeToFile("E 0x%x %x %s " % (cmd.ea,cmd.size,toHex(bytes)))
    
            instcode = c_byte*inslen
            instBytes = instcode()
            for i in range(inslen):
                instBytes[i]=get_byte(cmd.ea+i)
    
            curid = idc.GetCurrentThreadId()
            self.memoryWriter.writeToFile("0x%x 0x%x" % (curid, instSeq)) # current_thread_id
            instSeq = instSeq+1
    
            instInfo = instDecode()
            
            if inslen > 0:
                self.xDecoder32.decode_inst(inslen, pointer(instBytes),ctypes.byref((instInfo)))
            else:
                self.logger.error( "Cannot decode instruction at 0x%x %x %s" % (cmd.ea,cmd.size,toHex(bytes)) )
                

            self.logger.debug("source_operands_number=%d" % (instInfo.n_src_operand))
    
            lReadEA = 0
            lReadSize = 0
            lWriteEA = 0
            lWriteSize = 0
            bSegFS = 0
            
            regs = {}
            for i in range(instInfo.n_src_operand):

                self.logger.debug("%d: width=%d, rw=%d, type=%d, ea_string=%s" %(i, instInfo.src_operands[i]._width_bits,instInfo.src_operands[i]._rw,instInfo.src_operands[i]._type,instInfo.src_operands[i]._ea))
                
                if(instInfo.src_operands[i]._type == REGISTER):
                    if(instInfo.src_operands[i]._ea == "STACKPOP"):
                        regs["ESP"] = GetRegValue("ESP")
                    elif((instInfo.src_operands[i]._ea.find("EFLAGS"))!=-1):
                        regs["eflags"] = GetRegValue("EFL")
                    else:
                        regs[instInfo.src_operands[i]._ea]= GetRegValue(instInfo.src_operands[i]._ea)
                elif(instInfo.src_operands[i]._type == MEMORY): #collect registers used to calculate memory address
                    lBase = 0
                    lIndex = 0
                    lScale =0
                    lDisp = 0
                    parts = (instInfo.src_operands[i]._ea).split(":")
                    for part in parts:
                        comps = part.split("=")

                        if(len(comps)==2):
                            self.logger.debug("%s is %s"%(comps[0], comps[1]))                    
                    
                        if comps[0] =="SEG":
                            if(comps[1]=="FS"):
                                bSegFS = 1
                                self.logger.debug("SRC SEG==FS")
                            continue
                        elif comps[0] =="BASE":
                            lBase = GetRegValue(comps[1])
                            regs[comps[1]] = GetRegValue(comps[1])
                        elif comps[0] =="INDEX":
                            lIndex = GetRegValue(comps[1])
                            regs[comps[1]] = GetRegValue(comps[1])
                        elif comps[0] =="SCALE":
                            lScale = int(comps[1])
                        elif comps[0] =="DISP":
                            lDisp = int(comps[1])
                        else:
                            break
                    lReadEA = lBase + lIndex*lScale + lDisp
                    if (instInfo.attDisa.find("lea")!=-1): # lea doesn't actually read
                        lReadSize = 0
                        self.logger.debug("Encounter instruction lea:%s" %(instInfo.attDisa))
                    elif (bSegFS==1):
                        lReadSize = 0
                        self.logger.debug("FS segement register ignored for NOW:%s" %(instInfo.attDisa))                    
                    else:
                        lReadSize = instInfo.src_operands[i]._width_bits/8
                    
                    self.logger.debug("lEA = 0x%x" %(lReadEA))                    
              
            self.logger.debug("dest_operands_number=%d" % (instInfo.n_dest_operand))
            
            for i in range(instInfo.n_dest_operand):
                
                self.logger.debug("%d: width=%d, rw=%d, type=%d, ea_string=%s" %(i, instInfo.dest_operands[i]._width_bits,instInfo.dest_operands[i]._rw,instInfo.dest_operands[i]._type,instInfo.dest_operands[i]._ea))
                
                if(instInfo.dest_operands[i]._type == REGISTER):
                    if(instInfo.dest_operands[i]._ea == "STACKPUSH"): #push ino stack
                        regs["ESP"] = GetRegValue("ESP")
                    elif((instInfo.dest_operands[i]._ea.find("EFLAGS"))!=-1):
                        regs["eflags"] = GetRegValue("EFL")
                    else:
                        regs[instInfo.dest_operands[i]._ea]= GetRegValue(instInfo.dest_operands[i]._ea)
                elif(instInfo.dest_operands[i]._type == MEMORY): #collect registers used to calculate memory address
                    lBase = 0
                    lIndex = 0
                    lScale =0
                    lDisp = 0
                    parts = (instInfo.dest_operands[i]._ea).split(":")
                    for part in parts:
                        comps = part.split("=")

                        if(len(comps)==2):
                            self.logger.debug("%s is %s" %(comps[0], comps[1]))             
                    
                        if comps[0] =="SEG":
                            if(comps[1]=="FS"):
                                bSegFS = 1
                                self.logger.debug("DEST: SEG==FS")
                            continue
                        elif comps[0] =="BASE":
                            lBase = GetRegValue(comps[1])
                            regs[comps[1]] = lBase

                            self.logger.debug("BASE %s equals 0x%x" %(comps[1],lBase))
                        
                        elif comps[0] =="INDEX":
                            lIndex = GetRegValue(comps[1])
                            regs[comps[1]] = lIndex
                            
                            self.logger.debug("lIndex %s equals 0x%x" %(comps[1],lIndex))                        
                        elif comps[0] =="SCALE":
                            lScale = int(comps[1])
                            self.logger.debug("lScale equals 0x%x" %(lScale))                                                
                        elif comps[0] =="DISP":
                            lDisp = int(comps[1])
                            self.logger.debug("lDisp equals 0x%x" %(lDisp))                                                                        
                        else:
                            break
                    lWriteEA = lBase + lIndex*lScale + lDisp
                    if (bSegFS==1):
                        lWriteSize = 0
                        self.logger.debug("FS segement register ignored for NOW:%s" %(instInfo.attDisa))                    
                    else:
                        lWriteSize = instInfo.dest_operands[i]._width_bits/8
                    
                    self.logger.debug("lEA = 0x%x" %(lWriteEA))                    
    
            self.memoryWriter.writeToFile(" Reg( ")
            for reg in regs:
                self.memoryWriter.writeToFile("%s=0x%x " %(reg,regs[reg]))
            self.memoryWriter.writeToFile(") ")
    
            if lReadEA!=0 and lReadSize!=0:
                self.memoryWriter.writeToFile("R %d %x " % (lReadSize,lReadEA))
                for j in range(lReadSize):
                    value = DbgByte(lReadEA+j)
                    if(value is not None):
                        if(j==0):
                            self.memoryWriter.writeToFile("%x" %(value))
                        else:
                            self.memoryWriter.writeToFile("_%x" %(value))
                    else:
                        self.memoryWriter.writeToFile("X")    
            if lWriteEA!=0 and lWriteSize!=0: # no need to get contents from the write address
                self.memoryWriter.writeToFile(" W %d %x " % (lWriteSize,lWriteEA))
                
            self.memoryWriter.writeToFile("\n")

            request_step_into()
        else:
            self.logger.error("The instruction at 0x%x has 0 size." % cmd.ea)
Esempio n. 4
0
    def dbg_step_into(self):
        """
        Notified when the debugger is single stepping thru a process
        This is the main function for tracing, we analyze each instruction being executed
        The instruction along with its metadata is written to either memory or out to a file
        This is a standard IDA Debug Hook callback
        """
        
        global instSeq
        
        eip = GetRegValue("EIP")

        DecodeInstruction(eip)
        
        inslen = cmd.size
        
        if cmd.size > 0:
            bytes = get_many_bytes(cmd.ea,cmd.size)

            self.memoryWriter.writeToFile("E 0x%x %x %s " % (cmd.ea,cmd.size,toHex(bytes)))
    
            instcode = c_byte*inslen
            instBytes = instcode()
            for i in range(inslen):
                instBytes[i]=get_byte(cmd.ea+i)
    
            curid = idc.GetCurrentThreadId()
            self.memoryWriter.writeToFile("0x%x 0x%x" % (curid, instSeq)) # current_thread_id
            instSeq = instSeq+1
    
            instInfo = instDecode()
            
            if inslen > 0:
                self.xDecoder32.decode_inst(inslen, pointer(instBytes),ctypes.byref((instInfo)))
            else:
                self.logger.error( "Cannot decode instruction at 0x%x %x %s" % (cmd.ea,cmd.size,toHex(bytes)) )
                

            self.logger.debug("source_operands_number=%d" % (instInfo.n_src_operand))
    
            lReadEA = 0
            lReadSize = 0
            lWriteEA = 0
            lWriteSize = 0
            bSegFS = 0
            
            regs = {}
            for i in range(instInfo.n_src_operand):

                self.logger.debug("%d: width=%d, rw=%d, type=%d, ea_string=%s" %(i, instInfo.src_operands[i]._width_bits,instInfo.src_operands[i]._rw,instInfo.src_operands[i]._type,instInfo.src_operands[i]._ea))
                
                if(instInfo.src_operands[i]._type == REGISTER):
                    if(instInfo.src_operands[i]._ea == "STACKPOP"):
                        regs["ESP"] = GetRegValue("ESP")
                    elif((instInfo.src_operands[i]._ea.find("EFLAGS"))!=-1):
                        regs["eflags"] = GetRegValue("EFL")
                    else:
                        regs[instInfo.src_operands[i]._ea]= GetRegValue(instInfo.src_operands[i]._ea)
                elif(instInfo.src_operands[i]._type == MEMORY): #collect registers used to calculate memory address
                    lBase = 0
                    lIndex = 0
                    lScale =0
                    lDisp = 0
                    parts = (instInfo.src_operands[i]._ea).split(":")
                    for part in parts:
                        comps = part.split("=")

                        if(len(comps)==2):
                            self.logger.debug("%s is %s"%(comps[0], comps[1]))                    
                    
                        if comps[0] =="SEG":
                            if(comps[1]=="FS"):
                                bSegFS = 1
                                self.logger.debug("SRC SEG==FS")
                            continue
                        elif comps[0] =="BASE":
                            lBase = GetRegValue(comps[1])
                            regs[comps[1]] = GetRegValue(comps[1])
                        elif comps[0] =="INDEX":
                            lIndex = GetRegValue(comps[1])
                            regs[comps[1]] = GetRegValue(comps[1])
                        elif comps[0] =="SCALE":
                            lScale = int(comps[1])
                        elif comps[0] =="DISP":
                            lDisp = int(comps[1])
                        else:
                            break
                    lReadEA = lBase + lIndex*lScale + lDisp
                    if (instInfo.attDisa.find("lea")!=-1): # lea doesn't actually read
                        lReadSize = 0
                        self.logger.debug("Encounter instruction lea:%s" %(instInfo.attDisa))
                    elif (bSegFS==1):
                        lReadSize = 0
                        self.logger.debug("FS segement register ignored for NOW:%s" %(instInfo.attDisa))                    
                    else:
                        lReadSize = instInfo.src_operands[i]._width_bits/8
                    
                    self.logger.debug("lEA = 0x%x" %(lReadEA))                    
              
            self.logger.debug("dest_operands_number=%d" % (instInfo.n_dest_operand))
            
            for i in range(instInfo.n_dest_operand):
                
                self.logger.debug("%d: width=%d, rw=%d, type=%d, ea_string=%s" %(i, instInfo.dest_operands[i]._width_bits,instInfo.dest_operands[i]._rw,instInfo.dest_operands[i]._type,instInfo.dest_operands[i]._ea))
                
                if(instInfo.dest_operands[i]._type == REGISTER):
                    if(instInfo.dest_operands[i]._ea == "STACKPUSH"): #push ino stack
                        regs["ESP"] = GetRegValue("ESP")
                    elif((instInfo.dest_operands[i]._ea.find("EFLAGS"))!=-1):
                        regs["eflags"] = GetRegValue("EFL")
                    else:
                        regs[instInfo.dest_operands[i]._ea]= GetRegValue(instInfo.dest_operands[i]._ea)
                elif(instInfo.dest_operands[i]._type == MEMORY): #collect registers used to calculate memory address
                    lBase = 0
                    lIndex = 0
                    lScale =0
                    lDisp = 0
                    parts = (instInfo.dest_operands[i]._ea).split(":")
                    for part in parts:
                        comps = part.split("=")

                        if(len(comps)==2):
                            self.logger.debug("%s is %s" %(comps[0], comps[1]))             
                    
                        if comps[0] =="SEG":
                            if(comps[1]=="FS"):
                                bSegFS = 1
                                self.logger.debug("DEST: SEG==FS")
                            continue
                        elif comps[0] =="BASE":
                            lBase = GetRegValue(comps[1])
                            regs[comps[1]] = lBase

                            self.logger.debug("BASE %s equals 0x%x" %(comps[1],lBase))
                        
                        elif comps[0] =="INDEX":
                            lIndex = GetRegValue(comps[1])
                            regs[comps[1]] = lIndex
                            
                            self.logger.debug("lIndex %s equals 0x%x" %(comps[1],lIndex))                        
                        elif comps[0] =="SCALE":
                            lScale = int(comps[1])
                            self.logger.debug("lScale equals 0x%x" %(lScale))                                                
                        elif comps[0] =="DISP":
                            lDisp = int(comps[1])
                            self.logger.debug("lDisp equals 0x%x" %(lDisp))                                                                        
                        else:
                            break
                    lWriteEA = lBase + lIndex*lScale + lDisp
                    if (bSegFS==1):
                        lWriteSize = 0
                        self.logger.debug("FS segement register ignored for NOW:%s" %(instInfo.attDisa))                    
                    else:
                        lWriteSize = instInfo.dest_operands[i]._width_bits/8
                    
                    self.logger.debug("lEA = 0x%x" %(lWriteEA))                    
    
            self.memoryWriter.writeToFile(" Reg( ")
            for reg in regs:
                self.memoryWriter.writeToFile("%s=0x%x " %(reg,regs[reg]))
            self.memoryWriter.writeToFile(") ")
    
            if lReadEA!=0 and lReadSize!=0:
                self.memoryWriter.writeToFile("R %d %x " % (lReadSize,lReadEA))
                for j in range(lReadSize):
                    value = DbgByte(lReadEA+j)
                    if(value is not None):
                        if(j==0):
                            self.memoryWriter.writeToFile("%x" %(value))
                        else:
                            self.memoryWriter.writeToFile("_%x" %(value))
                    else:
                        self.memoryWriter.writeToFile("X")    
            if lWriteEA!=0 and lWriteSize!=0: # no need to get contents from the write address
                self.memoryWriter.writeToFile(" W %d %x " % (lWriteSize,lWriteEA))
                
            self.memoryWriter.writeToFile("\n")

            request_step_into()
        else:
            self.logger.error("The instruction at 0x%x has 0 size." % cmd.ea)