def _parse(self, row): """Parse log row. @param row: row data. @return: parsed information dict. """ call = {} arguments = [] try: timestamp = row[0] # Timestamp of current API call invocation. thread_id = row[1] # Thread ID. caller = row[2] # non-system DLL return address parentcaller = row[3] # non-system DLL parent of non-system-DLL return address category = row[4] # Win32 function category. api_name = row[5] # Name of the Windows API. repeated = row[6] # Times log repeated status_value = row[7] # Success or Failure? return_value = row[8] # Value returned by the function. except IndexError as e: log.debug("Unable to parse process log row: %s", e) return None # Now walk through the remaining columns, which will contain API # arguments. for index in range(9, len(row)): argument = {} # Split the argument name with its value based on the separator. try: arg_name, arg_value = row[index] except ValueError as e: log.debug("Unable to parse analysis row argument (row=%s): %s", row[index], e) continue argument["name"] = arg_name argument["value"] = convert_to_printable(str(arg_value), self.conversion_cache) if not self.reporting_mode: argument["raw_value"] = arg_value pretty = pretty_print_arg(category, api_name, arg_name, argument["value"]) if pretty: argument["pretty_value"] = pretty arguments.append(argument) call["timestamp"] = timestamp call["thread_id"] = str(thread_id) call["caller"] = "0x%.08x" % caller call["parentcaller"] = "0x%.08x" % parentcaller call["category"] = category call["api"] = api_name call["status"] = bool(int(status_value)) if isinstance(return_value, int) or isinstance(return_value, long): call["return"] = "0x%.08x" % return_value else: call["return"] = convert_to_printable(str(return_value), self.conversion_cache) prettyret = pretty_print_retval(category, api_name, call["status"], call["return"]) if prettyret: call["pretty_return"] = prettyret call["arguments"] = arguments call["repeated"] = repeated # add the thread id to our thread set if call["thread_id"] not in self.threads: self.threads.append(call["thread_id"]) return call
def _parse(self, row): """Parse log row. @param row: row data. @return: parsed information dict. """ arguments = [] try: timestamp = row[0] # Timestamp of current API call invocation. thread_id = row[1] # Thread ID. caller = row[2] # non-system DLL return address parentcaller = row[3] # non-system DLL parent of non-system-DLL return address category = row[4] # Win32 function category. api_name = row[5] # Name of the Windows API. repeated = row[6] # Times log repeated status_value = row[7] # Success or Failure? return_value = row[8] # Value returned by the function. except IndexError as e: log.debug("Unable to parse process log row: %s", e) return None # Now walk through the remaining columns, which will contain API # arguments. for api_arg in row[9:]: # Split the argument name with its value based on the separator. try: arg_name, arg_value = api_arg except ValueError as e: log.debug("Unable to parse analysis row argument (row=%s): %s", api_arg, e) continue argument = {"name": arg_name} if isinstance(arg_value, bytes): arg_value = bytes2str(arg_value) if arg_value and isinstance(arg_value, list) and len(arg_value) >= 1 and isinstance(arg_value[0], bytes): arg_value = " ".join(bytes2str(arg_value)) try: argument["value"] = convert_to_printable(arg_value, self.conversion_cache) except Exception as e: log.error(arg_value, exc_info=True) continue if not self.reporting_mode: argument["raw_value"] = arg_value pretty = pretty_print_arg(category, api_name, arg_name, argument["value"]) if pretty: argument["pretty_value"] = pretty arguments.append(argument) call = { "timestamp": timestamp, "thread_id": str(thread_id), "caller": f"0x{default_converter(caller):08x}", "parentcaller": f"0x{default_converter(parentcaller):08x}", "category": category, "api": api_name, "status": bool(int(status_value)), } if isinstance(return_value, int): call["return"] = f"0x{default_converter(return_value):08x}" else: call["return"] = convert_to_printable(str(return_value), self.conversion_cache) prettyret = pretty_print_retval(call["status"], call["return"]) if prettyret: call["pretty_return"] = prettyret call["arguments"] = arguments call["repeated"] = repeated # add the thread id to our thread set if call["thread_id"] not in self.threads: self.threads.append(call["thread_id"]) return call
def _parse(self, row): """Parse log row. @param row: row data. @return: parsed information dict. """ call = {} arguments = [] try: timestamp = row[0] # Timestamp of current API call invocation. thread_id = row[1] # Thread ID. caller = row[2] # non-system DLL return address parentcaller = row[ 3] # non-system DLL parent of non-system-DLL return address category = row[4] # Win32 function category. api_name = row[5] # Name of the Windows API. repeated = row[6] # Times log repeated status_value = row[7] # Success or Failure? return_value = row[8] # Value returned by the function. except IndexError as e: log.debug("Unable to parse process log row: %s", e) return None # Now walk through the remaining columns, which will contain API # arguments. for index in range(9, len(row)): argument = {} # Split the argument name with its value based on the separator. try: arg_name, arg_value = row[index] except ValueError as e: log.debug("Unable to parse analysis row argument (row=%s): %s", row[index], e) continue argument["name"] = arg_name if isinstance(arg_value, bytes): arg_value = bytes2str(arg_value) argument["value"] = convert_to_printable(str(arg_value), self.conversion_cache) if not self.reporting_mode: argument["raw_value"] = arg_value pretty = pretty_print_arg(category, api_name, arg_name, argument["value"]) if pretty: argument["pretty_value"] = pretty arguments.append(argument) call["timestamp"] = timestamp call["thread_id"] = str(thread_id) call["caller"] = "0x%.08x" % default_converter(caller) call["parentcaller"] = "0x%.08x" % default_converter(parentcaller) call["category"] = category call["api"] = api_name call["status"] = bool(int(status_value)) if isinstance(return_value, int) or isinstance(return_value, int): call["return"] = "0x%.08x" % default_converter(return_value) else: call["return"] = convert_to_printable(str(return_value), self.conversion_cache) prettyret = pretty_print_retval(category, api_name, call["status"], call["return"]) if prettyret: call["pretty_return"] = prettyret call["arguments"] = arguments call["repeated"] = repeated # add the thread id to our thread set if call["thread_id"] not in self.threads: self.threads.append(call["thread_id"]) return call
def test_pretty_print_retval_true_status(self): assert utils.pretty_print_retval(status=True, retval="0") is None
def test_pretty_print_retval_err(self): assert utils.pretty_print_retval(status=False, retval="-") is None
def test_pretty_print_retval(self): assert utils.pretty_print_retval( status=False, retval="0xc0000139") == "ENTRYPOINT_NOT_FOUND"
def test_pretty_print_retval_no_lookup(self): assert utils.pretty_print_retval(status=False, retval="0") is None