diff --git a/ChangeLog b/ChangeLog index 0035e7cb..cc1b7c3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ BREAK CHANGE - ql.filename is renamed to ql.argv. - ql.output and ql.verbose now has slightly different meanings and can be adjusted runtime. See their docstring for details. - ql.filter now accepts a regular expression. +- Remove ql.log_dir, ql.log_split, ql.append but add ql.log_file instead. ------------------------------------ [Version 1.3]: January [SOMETHING], 2021 diff --git a/examples/doogie_8086_crack.py b/examples/doogie_8086_crack.py index cffb92d3..c76bd6f2 100644 --- a/examples/doogie_8086_crack.py +++ b/examples/doogie_8086_crack.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import sys, curses, math, struct, string, time, logging +import sys, curses, math, struct, string, time sys.path.append("..") from qiling import * from qiling.const import * @@ -131,8 +131,7 @@ def third_stage(keys): # To setup terminal again, we have to restart the whole program. ql = Qiling(["rootfs/8086/doogie/doogie.DOS_MBR"], "rootfs/8086", - console=False, - log_dir=".") + console=False) ql.add_fs_mapper(0x80, QlDisk("rootfs/8086/doogie/doogie.DOS_MBR", 0x80)) ql.set_api((0x1a, 4), set_required_datetime, QL_INTERCEPT.EXIT) hk = ql.hook_code(stop, begin=0x8018, end=0x8018) @@ -172,7 +171,7 @@ def read_until_zero(ql: Qiling, addr): return buf def set_required_datetime(ql: Qiling): - logging.info("Setting Feburary 06, 1990") + ql.log.info("Setting Feburary 06, 1990") ql.reg.ch = BIN2BCD(19) ql.reg.cl = BIN2BCD(1990%100) ql.reg.dh = BIN2BCD(2) @@ -185,8 +184,7 @@ def stop(ql, addr, data): def first_stage(): ql = Qiling(["rootfs/8086/doogie/doogie.DOS_MBR"], "rootfs/8086", - console=False, - log_dir=".") + console=False) ql.add_fs_mapper(0x80, QlDisk("rootfs/8086/doogie/doogie.DOS_MBR", 0x80)) # Doogie suggests that the datetime should be 1990-02-06. ql.set_api((0x1a, 4), set_required_datetime, QL_INTERCEPT.EXIT) diff --git a/examples/hello_arm_linux_custom_syscall.py b/examples/hello_arm_linux_custom_syscall.py index 889860de..a90bc39f 100644 --- a/examples/hello_arm_linux_custom_syscall.py +++ b/examples/hello_arm_linux_custom_syscall.py @@ -14,12 +14,12 @@ def my_syscall_write(ql, write_fd, write_buf, write_count, *args, **kw): try: buf = ql.mem.read(write_buf, write_count) - logging.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn)) + ql.log.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn)) ql.os.fd[write_fd].write(buf) regreturn = write_count except: regreturn = -1 - logging.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn)) + ql.log.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn)) if ql.output in (QL_OUTPUT.DEBUG, QL_OUTPUT.DUMP): raise diff --git a/examples/hello_arm_set_filter.py b/examples/hello_arm_set_filter.py index f17f350a..93be5536 100644 --- a/examples/hello_arm_set_filter.py +++ b/examples/hello_arm_set_filter.py @@ -8,6 +8,6 @@ from qiling import * if __name__ == "__main__": - ql = Qiling(["rootfs/arm_linux/bin/arm_hello"], "rootfs/arm_linux", log_dir="qlog") + ql = Qiling(["rootfs/arm_linux/bin/arm_hello"], "rootfs/arm_linux") ql.filter = ["open"] ql.run() diff --git a/examples/hello_x8664_windows_customapi.py b/examples/hello_x8664_windows_customapi.py index 3bd1d3f2..1fb2a632 100644 --- a/examples/hello_x8664_windows_customapi.py +++ b/examples/hello_x8664_windows_customapi.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import sys, logging +import sys sys.path.append("..") from qiling import * @@ -16,7 +16,7 @@ from qiling.os.windows.const import * @winsdkapi(cc=CDECL, replace_params={"str": STRING}) def my_puts(ql, address, params): ret = 0 - logging.info("\n+++++++++\nmy random Windows API\n+++++++++\n") + ql.log.info("\n+++++++++\nmy random Windows API\n+++++++++\n") string = params["str"] ret = len(string) return ret diff --git a/examples/petya_8086_crack.py b/examples/petya_8086_crack.py index b9e0a9ec..6a16f598 100644 --- a/examples/petya_8086_crack.py +++ b/examples/petya_8086_crack.py @@ -46,8 +46,7 @@ def third_stage(key): ql = Qiling(["rootfs/8086/petya/petya.DOS_MBR"], "rootfs/8086", console=False, - output="debug", - log_dir=".") + output="debug") ql.add_fs_mapper(0x80, QlDisk("rootfs/8086/petya/out_1M.raw", 0x80)) ql.hook_code(pass_red, begin=0x886d, end=0x886d) ql.hook_code(input_key, begin=0x85f0, end=0x85f0) @@ -90,8 +89,7 @@ def first_stage(): ql = Qiling(["rootfs/8086/petya/petya.DOS_MBR"], "rootfs/8086", console=False, - output="debug", - log_dir=".") + output="debug") ql.add_fs_mapper(0x80, QlDisk("rootfs/8086/petya/out_1M.raw", 0x80)) # Workaround for `until` in uc_emu_start not working with dynamic loaded code. ql.hook_code(stop, begin=petya_2nd_stage_start, end=petya_2nd_stage_start) diff --git a/examples/sality.py b/examples/sality.py index a2f9bb1e..abf9fb35 100644 --- a/examples/sality.py +++ b/examples/sality.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import sys, logging +import sys from unicorn import UcError @@ -108,7 +108,7 @@ def hook_WriteFile(ql, address, params): r, nNumberOfBytesToWrite = ql.amsint32_driver.os.io_Write(buffer) ql.mem.write(lpNumberOfBytesWritten, ql.pack32(nNumberOfBytesToWrite)) except Exception as e: - logging.exception("") + ql.log.exception("") print("Exception = %s" % str(e)) r = 1 if r: @@ -147,7 +147,7 @@ def hook_StartServiceA(ql, address, params): else: return 1 except Exception as e: - logging.exception("") + ql.log.exception("") print (e) @@ -174,7 +174,7 @@ if __name__ == "__main__": ql.os.set_function_args([0]) ql.hook_address(hook_stop_address, 0x4055FA) ql.run(0x4053B2) - logging.info("[+] test kill thread") + ql.log.info("[+] test kill thread") if ql.amsint32_driver: ql.amsint32_driver.os.io_Write(ql.pack32(0xdeadbeef)) ql.amsint32_driver.hook_address(hook_stop_address, 0x10423) diff --git a/examples/tendaac1518_httpd.py b/examples/tendaac1518_httpd.py index afa69c09..70e704d3 100644 --- a/examples/tendaac1518_httpd.py +++ b/examples/tendaac1518_httpd.py @@ -13,7 +13,7 @@ # notes: we are using rootfs in this example, so rootfs = squashfs-root # -import os, socket, sys, threading, logging +import os, socket, sys, threading sys.path.append("..") from qiling import * @@ -54,7 +54,7 @@ def nvram_listener(): def myvfork(ql): regreturn = 0 - logging.info("vfork() = %d" % regreturn) + ql.log.info("vfork() = %d" % regreturn) return regreturn diff --git a/qiling/__init__.py b/qiling/__init__.py index 7a9200d1..5a5ddbac 100644 --- a/qiling/__init__.py +++ b/qiling/__init__.py @@ -1,2 +1,2 @@ from .core import Qiling -from .__version__ import __version__ +from .__version__ import __version__ \ No newline at end of file diff --git a/qiling/arch/arm.py b/qiling/arch/arm.py index 292c5ff1..be99d44a 100644 --- a/qiling/arch/arm.py +++ b/qiling/arch/arm.py @@ -3,8 +3,6 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging - from unicorn import * from unicorn.arm_const import * @@ -12,6 +10,7 @@ from qiling.const import * from .arch import QlArch from .arm_const import * + class QlArchARM(QlArch): def __init__(self, ql): super(QlArchARM, self).__init__(ql) @@ -79,7 +78,7 @@ class QlArchARM(QlArch): #self.ql.reg.fpexc = 0x00000040 else: self.ql.reg.fpexc = 0x40000000 - logging.debug("[+] Enable ARM VFP") + self.ql.log.debug("[+] Enable ARM VFP") def check_thumb(self): @@ -93,5 +92,5 @@ class QlArchARM(QlArch): mode = UC_MODE_ARM if (reg_cpsr & reg_cpsr_v) != 0: mode = UC_MODE_THUMB - logging.debug("[+] Enable ARM THUMB") + self.ql.log.debug("[+] Enable ARM THUMB") return mode diff --git a/qiling/arch/x86.py b/qiling/arch/x86.py index 6a91c9f2..00dd1bae 100644 --- a/qiling/arch/x86.py +++ b/qiling/arch/x86.py @@ -3,8 +3,6 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging - from unicorn import * from unicorn.x86_const import * @@ -15,6 +13,7 @@ from .x86_const import * from qiling.const import * from qiling.exception import * + class QlArchX86(QlArch): def __init__(self, ql): super(QlArchX86, self).__init__(ql) @@ -150,7 +149,7 @@ class GDTManager: gdt_entry = self._create_gdt_entry(SEGMENT_ADDR, SEGMENT_SIZE, SPORT, QL_X86_F_PROT_32) self.ql.mem.write(self.gdt_addr + (index << 3), gdt_entry) # self.gdt_used[index] = True - logging.debug(f"Write to {hex(self.gdt_addr + (index << 3))} for new entry {gdt_entry}") + self.ql.log.debug(f"Write to {hex(self.gdt_addr + (index << 3))} for new entry {gdt_entry}") def get_gdt_buf(self, start, end): diff --git a/qiling/core.py b/qiling/core.py index 4e7335db..6074c9c3 100644 --- a/qiling/core.py +++ b/qiling/core.py @@ -4,7 +4,7 @@ # from configparser import ConfigParser -import ctypes, logging, ntpath, os, pickle, platform +import ctypes, ntpath, os, pickle, platform import io from sys import stdin, stdout # See https://stackoverflow.com/questions/39740632/python-type-hinting-without-cyclic-imports @@ -39,9 +39,7 @@ class Qiling(QlCoreHooks, QlCoreStructs): verbose=1, profile=None, console=True, - log_dir=None, - log_split=None, - append=None, + log_file=None, libcache = False, multithread = False, stop_on_stackpointer = False, @@ -71,9 +69,7 @@ class Qiling(QlCoreHooks, QlCoreStructs): self._pointersize = None self._profile = profile self._console = console - self._log_dir = log_dir - self._log_split = log_split - self._append = append + self._log_file = log_file self._multithread = multithread self._log_file_fd = None self._platform = ostype_convert(platform.system().lower()) @@ -155,12 +151,6 @@ class Qiling(QlCoreHooks, QlCoreStructs): # Profile & Logging # ##################### self._profile, debugmsg = profile_setup(self.ostype, self.profile, self) - if self._append == None: - self._append = self._profile["MISC"]["append"] - if self._log_dir == None: - self._log_dir = self._profile["LOG"]["dir"] - if self._log_split == None: - self._log_split = self._profile.getboolean('LOG', 'split') # Log's configuration @@ -168,19 +158,16 @@ class Qiling(QlCoreHooks, QlCoreStructs): self._output = output_convert(self._output) # We only use the root logger now. - ql_setup_logger(self, - self._log_dir, - self._targetname + self._append + ".qlog", - self._log_split, self._console, - self._filter, - self._multithread) - # For compatibility. - self._log_file_fd = logging.getLogger() - - ql_resolve_logger_level(self._output, self._verbose) + self._log_file_fd = ql_setup_logger(self, + self._log_file, + self._console, + self._filter, + self._multithread) + + self.log.setLevel(ql_resolve_logger_level(self._output, self._verbose)) # Now that the logger is configured, we can log profile debug msg: - logging.debug(debugmsg) + self.log.debug(debugmsg) ######################## # Archbit & Endianness # @@ -264,42 +251,20 @@ class Qiling(QlCoreHooks, QlCoreStructs): """ return self._os + @property + def log(self) -> logging.Logger: + """ Returns the logger this Qiling instance uses. + + Type: logging.Logger + Example: ql.ql.log.info("This goes to terminal") + """ + return self._log_file_fd + ################## # Qiling Options # ################## # If an option doesn't have a setter, it means that it can be only set during Qiling.__init__ - # TODO: Rename to suffix? - @property - def append(self) -> str: - """ Suffix appended to the filename. - Used when writing to file (e.g. logging). - - Type: str - Example: Qiling(append="dbg") - """ - return self._append - - @property - def log_dir(self) -> str: - """ Specify the logging directory. - Use with ql.log_split. - - Type: str - Example: Qiling(log_dir=".") - """ - return self._log_dir - - @property - def log_split(self) -> bool: - """ Specify whether spliting logs within multiprocess/multithread context. - Use with ql.log_dir. - - Type: bool - Example: Qiling(log_split=True) - """ - return self._log_split - @property def console(self) -> bool: """ Specify whether enabling console output. @@ -309,6 +274,15 @@ class Qiling(QlCoreHooks, QlCoreStructs): """ return self._console + @property + def log_file(self) -> str: + """ Log to a file. + + Type: str + Example: Qiling(log_file="./ql.log") + """ + return self._log_file + @property def multithread(self) -> bool: """ Specify whether multithread has been enabled. @@ -565,7 +539,7 @@ class Qiling(QlCoreHooks, QlCoreStructs): self._output = output_convert(op) else: self._output = op - ql_resolve_logger_level(self._output, self._verbose) + self.log.setLevel(ql_resolve_logger_level(self._output, self._verbose)) self.os.setup_output() @property @@ -588,7 +562,7 @@ class Qiling(QlCoreHooks, QlCoreStructs): @verbose.setter def verbose(self, v): self._verbose = v - ql_resolve_logger_level(self._output, self._verbose) + self.log.setLevel(ql_resolve_logger_level(self._output, self._verbose)) self.os.setup_output() @property @@ -720,7 +694,7 @@ class Qiling(QlCoreHooks, QlCoreStructs): if not ql.loader.skip_exit_check: sp = ql._initial_sp - ql.reg.arch_sp if sp < 0: - logging.info('Process returned from entrypoint (stackpointer)!') + self.log.info('Process returned from entrypoint (stackpointer)!') ql.emu_stop() self.hook_code(_check_sp) @@ -728,7 +702,7 @@ class Qiling(QlCoreHooks, QlCoreStructs): # Stop when running to exit trap address if self.stop_options.exit_trap: def _exit_trap(ql): - logging.info('Process returned from entrypoint (exit_trap)!') + self.log.info('Process returned from entrypoint (exit_trap)!') ql.emu_stop() self.hook_address(_exit_trap, self._exit_trap_addr) @@ -737,10 +711,10 @@ class Qiling(QlCoreHooks, QlCoreStructs): self._initial_sp = self.reg.arch_sp if self.stop_options.any: if not self.loader.skip_exit_check: - logging.debug(f'Setting up exit trap at 0x{hex(self._exit_trap_addr)}') + self.log.debug(f'Setting up exit trap at 0x{hex(self._exit_trap_addr)}') self.stack_write(0, self._exit_trap_addr) elif self.stop_options.exit_trap: - logging.debug(f'Loader {self.loader} requested to skip exit_trap!') + self.log.debug(f'Loader {self.loader} requested to skip exit_trap!') ############### diff --git a/qiling/core_hooks.py b/qiling/core_hooks.py index 1b6c5fd6..a733f2ef 100644 --- a/qiling/core_hooks.py +++ b/qiling/core_hooks.py @@ -8,7 +8,6 @@ # handling hooks # ############################################## -import logging from unicorn import * from .utils import catch_KeyboardInterrupt @@ -55,7 +54,7 @@ class HookIntr(Hook): def check(self, ql, intno): - logging.debug("[+] Received Interupt: %i Hooked Interupt: %i" % (intno, self.intno)) + ql.log.debug("[+] Received Interupt: %i Hooked Interupt: %i" % (intno, self.intno)) if intno < 0 or self.intno == intno: return True return False diff --git a/qiling/debugger/gdb/gdb.py b/qiling/debugger/gdb/gdb.py index a4e74c91..d491c942 100644 --- a/qiling/debugger/gdb/gdb.py +++ b/qiling/debugger/gdb/gdb.py @@ -8,7 +8,7 @@ from unicorn import * -import struct, os, re, socket, logging +import struct, os, re, socket from binascii import unhexlify from .utils import QlGdbUtils @@ -122,7 +122,7 @@ class QlGdb(QlDebugger, object): return unhexlify(rawbin_escape) def setup_server(self): - logging.info("gdb> Listening on %s:%u" % (self.ip, self.port)) + self.ql.log.info("gdb> Listening on %s:%u" % (self.ip, self.port)) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -444,7 +444,7 @@ class QlGdb(QlDebugger, object): if reg_name == self.ql.reg.arch_pc_name: self.gdb.current_address = reg_data - logging.info("gdb> Write to register %s with %x\n" % (self.tables[self.ql.archtype][reg_index], reg_data)) + self.ql.log.info("gdb> Write to register %s with %x\n" % (self.tables[self.ql.archtype][reg_index], reg_data)) self.send('OK') @@ -488,7 +488,7 @@ class QlGdb(QlDebugger, object): file_contents = f.read() self.send("l%s" % file_contents) else: - logging.info("gdb> Platform is not supported by xml or xml file not found: %s\n" % (xfercmd_file)) + self.ql.log.info("gdb> Platform is not supported by xml or xml file not found: %s\n" % (xfercmd_file)) self.send("l") @@ -680,7 +680,7 @@ class QlGdb(QlDebugger, object): else: file_abspath = self.ql.os.transform_to_real_path(file_path) - logging.debug("gdb> target file: %s" % (file_abspath)) + self.ql.log.debug("gdb> target file: %s" % (file_abspath)) if os.path.exists(file_abspath) and not (file_path).startswith("/proc"): fd = os.open(file_abspath, flags, mode) self.send("F%x" % fd) @@ -713,7 +713,7 @@ class QlGdb(QlDebugger, object): self.send('OK') elif subcmd.startswith('Cont'): - logging.debug("gdb> Cont command received: %s" % subcmd) + self.ql.log.debug("gdb> Cont command received: %s" % subcmd) if subcmd == 'Cont?': self.send('vCont;c;C;t;s;S;r') elif subcmd.startswith ("Cont;"): @@ -804,9 +804,9 @@ class QlGdb(QlDebugger, object): if cmd not in commands: self.send('') - logging.info("gdb> Command not supported: %s\n" %(cmd)) + self.ql.log.info("gdb> Command not supported: %s\n" %(cmd)) continue - logging.debug("gdb> received: %s%s" % (cmd, subcmd)) + self.ql.log.debug("gdb> received: %s%s" % (cmd, subcmd)) commands[cmd](subcmd) self.close() @@ -861,7 +861,7 @@ class QlGdb(QlDebugger, object): self.clientsocket.send(b'$%s#%.2x' % (msg, self.checksum(msg))) self.netout.flush() - logging.debug("gdb> send: $%s#%.2x" % (msg, self.checksum(msg))) + self.ql.log.debug("gdb> send: $%s#%.2x" % (msg, self.checksum(msg))) def send_raw(self, r): self.netout.write(r) diff --git a/qiling/debugger/gdb/utils.py b/qiling/debugger/gdb/utils.py index da23d2f5..fed8dd84 100644 --- a/qiling/debugger/gdb/utils.py +++ b/qiling/debugger/gdb/utils.py @@ -3,10 +3,10 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging from unicorn import * from qiling.const import * + class QlGdbUtils(object): def __init__(self): self.current_address = 0x0 @@ -56,7 +56,7 @@ class QlGdbUtils(object): self.breakpoint_count += 1 self.ql.os.stop() self.last_bp = address - logging.info("gdb> Breakpoint found, stop at address: 0x%x" % address) + ql.log.info("gdb> Breakpoint found, stop at address: 0x%x" % address) elif address == self.last_bp: self.last_bp = 0x0 @@ -64,11 +64,11 @@ class QlGdbUtils(object): self.has_soft_bp = hit_soft_bp if self.current_address + size == self.exit_point: - logging.debug("gdb> emulation entrypoint at 0x%x" % (self.entry_point)) - logging.debug("gdb> emulation exitpoint at 0x%x" % (self.exit_point)) + ql.log.debug("gdb> emulation entrypoint at 0x%x" % (self.entry_point)) + ql.log.debug("gdb> emulation exitpoint at 0x%x" % (self.exit_point)) except KeyboardInterrupt as ex: - logging.info("gdb> Paused at 0x%x, instruction size = %u" % (address, size)) + ql.log.info("gdb> Paused at 0x%x, instruction size = %u" % (address, size)) self.ql.os.stop() except: raise @@ -77,12 +77,12 @@ class QlGdbUtils(object): def bp_insert(self, addr): if addr not in self.bp_list: self.bp_list.append(addr) - logging.info('gdb> Breakpoint added at: 0x%x' % addr) + self.ql.log.info('gdb> Breakpoint added at: 0x%x' % addr) def bp_remove(self, addr, type = None, len = None): self.bp_list.remove(addr) - logging.info('gdb> Breakpoint removed at: 0x%x' % addr) + self.ql.log.info('gdb> Breakpoint removed at: 0x%x' % addr) def resume_emu(self, address=None, skip_bp=0): @@ -99,6 +99,6 @@ class QlGdbUtils(object): self.skip_bp_count = skip_bp if self.exit_point is not None: - logging.info('gdb> Resume at: 0x%x' % self.current_address) + self.ql.log.info('gdb> Resume at: 0x%x' % self.current_address) self.ql.emu_start(self.current_address, self.exit_point) \ No newline at end of file diff --git a/qiling/loader/dos.py b/qiling/loader/dos.py index 37ca73ad..7d899c3b 100644 --- a/qiling/loader/dos.py +++ b/qiling/loader/dos.py @@ -3,9 +3,10 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging, math, sys, traceback +import math, sys, traceback from .loader import QlLoader + from qiling.os.disk import QlDisk @@ -19,7 +20,7 @@ class QlLoaderDOS(QlLoader): def excepthook(self, tp, value, tb): if self.ql.os.stdscr is not None: tbmsg = "".join(traceback.format_exception(tp, value, tb)) - logging.info(f"{tbmsg}") + self.ql.log.info(f"{tbmsg}") self.old_excepthook(tp, value, tb) def _round_to_4k(self, addr): diff --git a/qiling/loader/elf.py b/qiling/loader/elf.py index 235f2abc..ff501313 100644 --- a/qiling/loader/elf.py +++ b/qiling/loader/elf.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging, os, string, sys +import os, string, sys from heapq import heappush, heappop @@ -13,6 +13,7 @@ from elftools.elf.sections import SymbolTableSection from elftools.elf.descriptions import describe_reloc_type from qiling.const import * + from qiling.exception import * from .loader import QlLoader from qiling.os.linux.function_hook import FunctionHook @@ -178,7 +179,7 @@ class QlLoaderELF(QlLoader, ELFParse): if elfhead['e_type'] == 'ET_EXEC': load_address = 0 elif elfhead['e_type'] != 'ET_DYN': - logging.debug("[+] Some error in head e_type: %i!", elfhead['e_type']) + self.ql.log.debug("[+] Some error in head e_type: %i!", elfhead['e_type']) return -1 # We need to sort the memory segments first, sometimes they are unordered @@ -240,9 +241,9 @@ class QlLoaderELF(QlLoader, ELFParse): self.ql.mem.map(_mem_s, _mem_e - _mem_s, perms=_perms, info=self.path) if _mem_e > _highestmapped_e: _highestmapped_e = _mem_e - logging.debug("[+] load 0x%x - 0x%x" % (_mem_s, _mem_e)) + self.ql.log.debug("[+] load 0x%x - 0x%x" % (_mem_s, _mem_e)) except Exception as e: - logging.debug("[!] load 0x%x - 0x%x => %s" % (_mem_s, _mem_e, str(e))) + self.ql.log.debug("[!] load 0x%x - 0x%x => %s" % (_mem_s, _mem_e, str(e))) continue # Now we write the segment data to the memory @@ -253,18 +254,18 @@ class QlLoaderELF(QlLoader, ELFParse): data = super().getelfdata(entry['p_offset'], entry['p_filesz']) self.ql.mem.write(_mem_s, data) except Exception as e: - logging.debug("[!] segment data 0x%x - Length 0x%x => %s" % (_mem_s, len(data), str(e))) + self.ql.log.debug("[!] segment data 0x%x - Length 0x%x => %s" % (_mem_s, len(data), str(e))) continue loaded_mem_end = load_address + mem_end if loaded_mem_end > _mem_e: self.ql.mem.map(_mem_e, loaded_mem_end - _mem_e, info=self.path) - logging.debug("[+] load 0x%x - 0x%x" % ( + self.ql.log.debug("[+] load 0x%x - 0x%x" % ( _mem_e, loaded_mem_end)) # make sure we map all PT_LOAD tagged area entry_point = elfhead['e_entry'] + load_address self.ql.os.elf_mem_start = mem_start - logging.debug("[+] mem_start: 0x%x mem_end: 0x%x" % (mem_start, mem_end)) + self.ql.log.debug("[+] mem_start: 0x%x mem_end: 0x%x" % (mem_start, mem_end)) self.brk_address = mem_end + load_address + 0x2000 @@ -275,7 +276,7 @@ class QlLoaderELF(QlLoader, ELFParse): interp = ELFParse(self.ql.rootfs + interp_path, self.ql) interphead = interp.parse_header() - logging.debug("[+] interp is : %s" % (self.ql.rootfs + interp_path)) + self.ql.log.debug("[+] interp is : %s" % (self.ql.rootfs + interp_path)) interp_mem_size = -1 for i in interp.parse_segments(): @@ -285,14 +286,14 @@ class QlLoaderELF(QlLoader, ELFParse): interp_mem_size = i['p_vaddr'] + i['p_memsz'] interp_mem_size = (interp_mem_size // 0x1000 + 1) * 0x1000 - logging.debug("[+] interp_mem_size is : 0x%x" % int(interp_mem_size)) + self.ql.log.debug("[+] interp_mem_size is : 0x%x" % int(interp_mem_size)) if self.ql.archbit == 64: self.interp_address = int(self.ql.os.profile.get("OS64", "interp_address"), 16) elif self.ql.archbit == 32: self.interp_address = int(self.ql.os.profile.get("OS32", "interp_address"), 16) - logging.debug("[+] interp_address is : 0x%x" % (self.interp_address)) + self.ql.log.debug("[+] interp_address is : 0x%x" % (self.interp_address)) self.ql.mem.map(self.interp_address, int(interp_mem_size), info=os.path.abspath(self.ql.rootfs + interp_path)) @@ -309,7 +310,7 @@ class QlLoaderELF(QlLoader, ELFParse): else: self.mmap_address = int(self.ql.os.profile.get("OS32", "mmap_address"), 16) - logging.debug("[+] mmap_address is : 0x%x" % (self.mmap_address)) + self.ql.log.debug("[+] mmap_address is : 0x%x" % (self.mmap_address)) # Set elf table elf_table = b'' @@ -381,7 +382,7 @@ class QlLoaderELF(QlLoader, ELFParse): # for i in range(120): # buf = self.ql.mem.read(new_stack + i * 0x8, 8) - # logging.info("0x%08x : 0x%08x " % (new_stack + i * 0x4, self.ql.unpack64(buf)) + ' '.join(['%02x' % i for i in buf]) + ' ' + ''.join([chr(i) if i in string.printable[ : -5].encode('ascii') else '.' for i in buf])) + # self.ql.log.info("0x%08x : 0x%08x " % (new_stack + i * 0x4, self.ql.unpack64(buf)) + ' '.join(['%02x' % i for i in buf]) + ' ' + ''.join([chr(i) if i in string.printable[ : -5].encode('ascii') else '.' for i in buf])) self.ql.os.entry_point = self.entry_point = entry_point self.ql.os.elf_entry = self.elf_entry = load_address + elfhead['e_entry'] @@ -427,11 +428,11 @@ class QlLoaderELF(QlLoader, ELFParse): for nsym, symbol in enumerate(section.iter_symbols()): if symbol.name == 'init_module': addr = symbol.entry.st_value + elffile.get_section(symbol['st_shndx'])['sh_offset'] - logging.info("[+] init_module = 0x%x" % addr) + ql.log.info("[+] init_module = 0x%x" % addr) return addr # not found. FIXME: report error on invalid module?? - logging.warning("[!] invalid module? symbol init_module not found") + ql.log.warning("[!] invalid module? symbol init_module not found") return -1 def lkm_dynlinker(self, ql, mem_start): @@ -505,7 +506,7 @@ class QlLoaderELF(QlLoader, ELFParse): self.ql.os.hook_addr / self.ql.pointersize) + 1) * self.ql.pointersize # print("hook_addr = %x" %self.ql.os.hook_addr) ql.import_symbols[self.ql.os.hook_addr] = symbol_name - # logging.info(":: Demigod is hooking %s(), at slot %x" %(symbol_name, self.ql.os.hook_addr)) + # ql.log.info(":: Demigod is hooking %s(), at slot %x" %(symbol_name, self.ql.os.hook_addr)) if symbol_name == "page_offset_base": # FIXME: this is for rootkit to scan for syscall table from page_offset_base @@ -522,12 +523,12 @@ class QlLoaderELF(QlLoader, ELFParse): all_symbols.append(symbol_name) _section = elffile.get_section(_symbol['st_shndx']) rev_reloc_symbols[symbol_name] = _section['sh_offset'] + _symbol['st_value'] + mem_start - # logging.info(":: Add reverse lookup for %s to %x (%x, %x)" %(symbol_name, rev_reloc_symbols[symbol_name], _section['sh_offset'], _symbol['st_value'])) - # logging.info(":: Add reverse lookup for %s to %x" %(symbol_name, rev_reloc_symbols[symbol_name])) + # ql.log.info(":: Add reverse lookup for %s to %x (%x, %x)" %(symbol_name, rev_reloc_symbols[symbol_name], _section['sh_offset'], _symbol['st_value'])) + # ql.log.info(":: Add reverse lookup for %s to %x" %(symbol_name, rev_reloc_symbols[symbol_name])) else: sym_offset = rev_reloc_symbols[symbol_name] - mem_start - # logging.info("Relocating symbol %s -> 0x%x" %(symbol_name, rev_reloc_symbols[symbol_name])) + # ql.log.info("Relocating symbol %s -> 0x%x" %(symbol_name, rev_reloc_symbols[symbol_name])) loc = elffile.get_section(section['sh_info'])['sh_offset'] + rel['r_offset'] loc += mem_start @@ -537,11 +538,11 @@ class QlLoaderELF(QlLoader, ELFParse): if rel['r_addend']: val = sym_offset + rel['r_addend'] val += mem_start - # logging.info('R_X86_64_32S %s: [0x%x] = 0x%x' %(symbol_name, loc, val & 0xFFFFFFFF)) + # ql.log.info('R_X86_64_32S %s: [0x%x] = 0x%x' %(symbol_name, loc, val & 0xFFFFFFFF)) ql.mem.write(loc, ql.pack32(val & 0xFFFFFFFF)) else: # print("sym_offset = %x, rel = %x" %(sym_offset, rel['r_addend'])) - # logging.info('R_X86_64_32S %s: [0x%x] = 0x%x' %(symbol_name, loc, rev_reloc_symbols[symbol_name] & 0xFFFFFFFF)) + # ql.log.info('R_X86_64_32S %s: [0x%x] = 0x%x' %(symbol_name, loc, rev_reloc_symbols[symbol_name] & 0xFFFFFFFF)) ql.mem.write(loc, ql.pack32(rev_reloc_symbols[symbol_name] & 0xFFFFFFFF)) elif describe_reloc_type(rel['r_info_type'], elffile) == 'R_X86_64_64': @@ -549,7 +550,7 @@ class QlLoaderELF(QlLoader, ELFParse): val = sym_offset + rel['r_addend'] val += 0x2000000 # init_module position: FIXME # finally patch this reloc - # logging.info('R_X86_64_64 %s: [0x%x] = 0x%x' %(symbol_name, loc, val)) + # ql.log.info('R_X86_64_64 %s: [0x%x] = 0x%x' %(symbol_name, loc, val)) ql.mem.write(loc, ql.pack64(val)) elif describe_reloc_type(rel['r_info_type'], elffile) == 'R_X86_64_PC32': @@ -557,7 +558,7 @@ class QlLoaderELF(QlLoader, ELFParse): val = rel['r_addend'] - loc val += rev_reloc_symbols[symbol_name] # finally patch this reloc - # logging.info('R_X86_64_PC32 %s: [0x%x] = 0x%x' %(symbol_name, loc, val & 0xFFFFFFFF)) + # ql.log.info('R_X86_64_PC32 %s: [0x%x] = 0x%x' %(symbol_name, loc, val & 0xFFFFFFFF)) ql.mem.write(loc, ql.pack32(val & 0xFFFFFFFF)) elif describe_reloc_type(rel['r_info_type'], elffile) == 'R_386_PC32': @@ -614,7 +615,7 @@ class QlLoaderELF(QlLoader, ELFParse): # map some memory to intercept external functions of Linux kernel ql.mem.map(API_HOOK_MEM, 0x1000, info="[api_mem]") - logging.info("[+] loadbase: %x, mem_start: %x, mem_end: %x" % (loadbase, mem_start, mem_end)) + ql.log.info("[+] loadbase: %x, mem_start: %x, mem_end: %x" % (loadbase, mem_start, mem_end)) ql.mem.map(loadbase + mem_start, mem_end - mem_start, info=ql.path) ql.mem.write(loadbase + mem_start, elfdata_mapping) @@ -627,7 +628,7 @@ class QlLoaderELF(QlLoader, ELFParse): else: self.mmap_address = int(self.ql.os.profile.get("OS32", "mmap_address"), 16) - logging.debug("[+] mmap_address is : 0x%x" % (self.mmap_address)) + ql.log.debug("[+] mmap_address is : 0x%x" % (self.mmap_address)) new_stack = stack_addr new_stack = self.alignment(new_stack) @@ -655,7 +656,7 @@ class QlLoaderELF(QlLoader, ELFParse): tmp_sc = sc.replace("sys_", "NR_") if tmp_sc in globals(): syscall_id = globals()[tmp_sc] - logging.debug("Writing syscall %s to [0x%x]" % (sc, SYSCALL_MEM + ql.pointersize * syscall_id)) + ql.log.debug("Writing syscall %s to [0x%x]" % (sc, SYSCALL_MEM + ql.pointersize * syscall_id)) ql.mem.write(SYSCALL_MEM + ql.pointersize * syscall_id, ql.pack(rev_reloc_symbols[sc])) # write syscall addresses into syscall table diff --git a/qiling/loader/macho.py b/qiling/loader/macho.py index a8837e9e..53c2dd7e 100644 --- a/qiling/loader/macho.py +++ b/qiling/loader/macho.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import os, plistlib, struct, logging +import os, plistlib, struct from .loader import QlLoader @@ -168,7 +168,7 @@ class QlLoaderMACHO(QlLoader): self.kext_size = self.vm_end_addr - loadbase kernel_path = os.path.join(self.ql.rootfs, "System/Library/Kernels/kernel.development") - logging.info("[+] Parsing kernel:") + self.ql.log.info("[+] Parsing kernel:") self.kernel = MachoParser(self.ql, kernel_path) # Create memory for external static symbol jmp code @@ -176,7 +176,7 @@ class QlLoaderMACHO(QlLoader): self.static_size = PAGE_SIZE self.ql.mem.map(self.static_addr, self.static_size, info="[STATIC]") self.vm_end_addr += PAGE_SIZE - logging.info("[+] Memory for external static symbol is created at 0x%x with size 0x%x" % (self.static_addr, self.static_size)) + self.ql.log.info("[+] Memory for external static symbol is created at 0x%x with size 0x%x" % (self.static_addr, self.static_size)) self.static_symbols = {} # Load kernel @@ -190,7 +190,7 @@ class QlLoaderMACHO(QlLoader): self.kernel_base = cmd.vm_address self.loadSegment64(cmd, False) - logging.info("[+] Kernel loaded at 0x%x" % self.kernel_base) + self.ql.log.info("[+] Kernel loaded at 0x%x" % self.kernel_base) # Resolve local relocation for relocation in self.macho_file.dysymbol_table.locreloc: @@ -200,7 +200,7 @@ class QlLoaderMACHO(QlLoader): seg = segment break current_value, = struct.unpack("= 8: lc = LoadCommand(self.lc_raw[offset:]) else: - logging.info("[-] cmd size overflow") + self.ql.log.info("[-] cmd size overflow") return False if self.header.lc_size >= offset + lc.cmd_size: complete_cmd = lc.get_complete() pass else: - logging.info("[-] cmd size overflow") + self.ql.log.info("[-] cmd size overflow") return False self.commands.append(complete_cmd) diff --git a/qiling/loader/pe.py b/qiling/loader/pe.py index bbd76eb8..0599dde7 100644 --- a/qiling/loader/pe.py +++ b/qiling/loader/pe.py @@ -3,10 +3,11 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging, os, pefile, pickle, secrets, string, sys, traceback +import os, pefile, pickle, secrets, string, sys, traceback from unicorn.x86_const import * + from qiling.os.windows.utils import * from qiling.os.windows.structs import * from qiling.exception import * @@ -74,7 +75,7 @@ class Process(): else: self.dlls[dll_name] = self.dll_last_address - logging.info("[+] Loading %s to 0x%x" % (path, self.dll_last_address)) + self.ql.log.info("[+] Loading %s to 0x%x" % (path, self.dll_last_address)) if self.libcache: cached = self.libcache.restore(path, self.dll_last_address) @@ -87,15 +88,15 @@ class Process(): import_table = cached.import_table for entry in cached.cmdlines: self.set_cmdline(entry['name'], entry['address'], data) - logging.info("Loaded %s from cache" % path) + self.ql.log.info("Loaded %s from cache" % path) else: dll = pefile.PE(path, fast_load=True) dll.parse_data_directories() warnings = dll.get_warnings() if warnings: - logging.warning(f'Warnings while loading {path}:') + self.ql.log.warning(f'Warnings while loading {path}:') for warning in warnings: - logging.warning(f' - {warning}') + self.ql.log.warning(f' - {warning}') data = bytearray(dll.get_memory_mapped_image()) cmdlines = [] @@ -116,18 +117,18 @@ class Process(): if self.libcache: cached = QlPeCacheEntry(data, cmdlines, import_symbols, import_table) self.libcache.save(path, self.dll_last_address, cached) - logging.info("Cached %s" % path) + self.ql.log.info("Cached %s" % path) # Add dll to IAT try: self.import_address_table[dll_name] = import_table except Exception as ex: - logging.exception(f'Unable to add {dll_name} to IAT') + self.ql.log.exception(f'Unable to add {dll_name} to IAT') try: self.import_symbols.update(import_symbols) except Exception as ex: - logging.exception(f'Unable to add {dll_name} import symbols') + self.ql.log.exception(f'Unable to add {dll_name} import symbols') dll_base = self.dll_last_address dll_len = self.ql.mem.align(len(bytes(data)), 0x1000) @@ -143,7 +144,7 @@ class Process(): # add DLL to coverage images self.images.append(self.coverage_image(dll_base, dll_base+dll_len, path)) - logging.info("Done with loading %s" % path) + self.ql.log.info("Done with loading %s" % path) return dll_base @@ -177,7 +178,7 @@ class Process(): self.structure_last_addr += 0x30 teb_addr = self.structure_last_addr - logging.info("TEB addr is 0x%x" %teb_addr) + self.ql.log.info("TEB addr is 0x%x" %teb_addr) teb_size = len(TEB(self.ql).bytes()) teb_data = TEB( @@ -202,7 +203,7 @@ class Process(): def init_peb(self): peb_addr = self.structure_last_addr - logging.info("PEB addr is 0x%x" % peb_addr) + self.ql.log.info("PEB addr is 0x%x" % peb_addr) # we must set an heap, will try to retrieve this value. Is ok to be all \x00 process_heap = self.ql.os.heap.alloc(0x100) @@ -307,12 +308,12 @@ class Process(): self.import_address_table[dll_name][entry.name] = self.pe_image_address + entry.address self.import_address_table[dll_name][entry.ordinal] = self.pe_image_address + entry.address except: - logging.info('Failed to load exports for %s:\n%s' % (self.ql.argv, traceback.format_exc())) + self.ql.log.info('Failed to load exports for %s:\n%s' % (self.ql.argv, traceback.format_exc())) def init_driver_object(self): # PDRIVER_OBJECT DriverObject driver_object_addr = self.structure_last_addr - logging.info("[+] Driver object addr is 0x%x" %driver_object_addr) + self.ql.log.info("[+] Driver object addr is 0x%x" %driver_object_addr) if self.ql.archtype == QL_ARCH.X86: self.driver_object = DRIVER_OBJECT32(self.ql, driver_object_addr) @@ -328,7 +329,7 @@ class Process(): def init_registry_path(self): # PUNICODE_STRING RegistryPath regitry_path_addr = self.structure_last_addr - logging.info("[+] Registry path addr is 0x%x" %regitry_path_addr) + self.ql.log.info("[+] Registry path addr is 0x%x" %regitry_path_addr) if self.ql.archtype == QL_ARCH.X86: regitry_path_data = UNICODE_STRING32(0, 0, regitry_path_addr) @@ -343,7 +344,7 @@ class Process(): def init_eprocess(self): addr = self.structure_last_addr - logging.info("[+] EPROCESS is is 0x%x" %addr) + self.ql.log.info("[+] EPROCESS is is 0x%x" %addr) if self.ql.archtype == QL_ARCH.X86: @@ -369,7 +370,7 @@ class Process(): elif self.ql.archtype == QL_ARCH.X8664: KI_USER_SHARED_DATA = 0xFFFFF78000000000 - logging.info("[+] KI_USER_SHARED_DATA is 0x%x" %KI_USER_SHARED_DATA) + self.ql.log.info("[+] KI_USER_SHARED_DATA is 0x%x" %KI_USER_SHARED_DATA) shared_user_data = KUSER_SHARED_DATA() @@ -455,7 +456,7 @@ class QlLoaderPE(QlLoader, Process): def load(self): # set stack pointer - logging.info("[+] Initiate stack address at 0x%x " % self.stack_address) + self.ql.log.info("[+] Initiate stack address at 0x%x " % self.stack_address) self.ql.mem.map(self.stack_address, self.stack_size, info="[stack]") if self.path and not self.ql.shellcoder: @@ -470,8 +471,8 @@ class QlLoaderPE(QlLoader, Process): self.entry_point = self.pe_entry_point = self.pe_image_address + self.pe.OPTIONAL_HEADER.AddressOfEntryPoint self.sizeOfStackReserve = self.pe.OPTIONAL_HEADER.SizeOfStackReserve - logging.info("[+] Loading %s to 0x%x" % (self.path, self.pe_image_address)) - logging.info("[+] PE entry point at 0x%x" % self.entry_point) + self.ql.log.info("[+] Loading %s to 0x%x" % (self.path, self.pe_image_address)) + self.ql.log.info("[+] PE entry point at 0x%x" % self.entry_point) self.images.append(self.coverage_image(self.pe_image_address, self.pe_image_address + self.pe.NT_HEADERS.OPTIONAL_HEADER.SizeOfImage, self.path)) # Stack should not init at the very bottom. Will cause errors with Dlls @@ -482,13 +483,13 @@ class QlLoaderPE(QlLoader, Process): self.ql.reg.ebp = sp if self.pe.is_dll(): - logging.debug('[+] Setting up DllMain args') + self.ql.log.debug('[+] Setting up DllMain args') load_addr_bytes = self.pe_image_address.to_bytes(length=4, byteorder='little') - logging.debug('[+] Writing 0x%08X (IMAGE_BASE) to [ESP+4](0x%08X)' % (self.pe_image_address, sp + 0x4)) + self.ql.log.debug('[+] Writing 0x%08X (IMAGE_BASE) to [ESP+4](0x%08X)' % (self.pe_image_address, sp + 0x4)) self.ql.mem.write(sp + 0x4, load_addr_bytes) - logging.debug('[+] Writing 0x01 (DLL_PROCESS_ATTACH) to [ESP+8](0x%08X)' % (sp + 0x8)) + self.ql.log.debug('[+] Writing 0x01 (DLL_PROCESS_ATTACH) to [ESP+8](0x%08X)' % (sp + 0x8)) self.ql.mem.write(sp + 0x8, int(1).to_bytes(length=4, byteorder='little')) elif self.ql.archtype == QL_ARCH.X8664: @@ -496,12 +497,12 @@ class QlLoaderPE(QlLoader, Process): self.ql.reg.rbp = sp if self.pe.is_dll(): - logging.debug('[+] Setting up DllMain args') + self.ql.log.debug('[+] Setting up DllMain args') - logging.debug('[+] Setting RCX (arg1) to %16X (IMAGE_BASE)' % (self.pe_image_address)) + self.ql.log.debug('[+] Setting RCX (arg1) to %16X (IMAGE_BASE)' % (self.pe_image_address)) self.ql.reg.rcx = self.pe_image_address - logging.debug('[+] Setting RDX (arg2) to 1 (DLL_PROCESS_ATTACH)') + self.ql.log.debug('[+] Setting RDX (arg2) to 1 (DLL_PROCESS_ATTACH)') self.ql.reg.rdx = 1 else: raise QlErrorArch("[!] Unknown ql.arch") @@ -521,7 +522,7 @@ class QlLoaderPE(QlLoader, Process): # setup CR4, some drivers may check this at initialized time self.ql.uc.reg_write(UC_X86_REG_CR4, 0x6f8) - logging.debug('[+] Setting up DriverEntry args') + self.ql.log.debug('[+] Setting up DriverEntry args') self.ql.stop_execution_pattern = 0xDEADC0DE if self.ql.archtype == QL_ARCH.X86: # Win32 @@ -530,16 +531,16 @@ class QlLoaderPE(QlLoader, Process): # so if the user did not configure stop options, write a sentinel return value self.ql.mem.write(sp, self.ql.stop_execution_pattern.to_bytes(length=4, byteorder='little')) - logging.debug('[+] Writing 0x%08X (PDRIVER_OBJECT) to [ESP+4](0x%08X)' % (self.ql.driver_object_address, sp+0x4)) - logging.debug('[+] Writing 0x%08X (RegistryPath) to [ESP+8](0x%08X)' % (self.ql.regitry_path_address, sp+0x8)) + self.ql.log.debug('[+] Writing 0x%08X (PDRIVER_OBJECT) to [ESP+4](0x%08X)' % (self.ql.driver_object_address, sp+0x4)) + self.ql.log.debug('[+] Writing 0x%08X (RegistryPath) to [ESP+8](0x%08X)' % (self.ql.regitry_path_address, sp+0x8)) elif self.ql.archtype == QL_ARCH.X8664: # Win64 if not self.ql.stop_options.any: # We know that a driver will return, # so if the user did not configure stop options, write a sentinel return value self.ql.mem.write(sp, self.ql.stop_execution_pattern.to_bytes(length=8, byteorder='little')) - logging.debug('[+] Setting RCX (arg1) to %16X (PDRIVER_OBJECT)' % (self.ql.driver_object_address)) - logging.debug('[+] Setting RDX (arg2) to %16X (PUNICODE_STRING)' % (self.ql.regitry_path_address)) + self.ql.log.debug('[+] Setting RCX (arg1) to %16X (PDRIVER_OBJECT)' % (self.ql.driver_object_address)) + self.ql.log.debug('[+] Setting RDX (arg2) to %16X (PUNICODE_STRING)' % (self.ql.regitry_path_address)) # setup args for DriverEntry() self.ql.os.set_function_args((self.ql.driver_object_address, self.ql.regitry_path_address)) @@ -581,13 +582,13 @@ class QlLoaderPE(QlLoader, Process): super().load_dll(entry.dll, self.is_driver) for imp in entry.imports: # fix IAT - # logging.info(imp.name) - # logging.info(self.import_address_table[imp.name]) + # ql.log.info(imp.name) + # ql.log.info(self.import_address_table[imp.name]) if imp.name: try: addr = self.import_address_table[dll_name][imp.name] except KeyError: - logging.debug("[!] Error in loading function %s" % imp.name.decode()) + self.ql.log.debug("[!] Error in loading function %s" % imp.name.decode()) else: addr = self.import_address_table[dll_name][imp.ordinal] @@ -597,7 +598,7 @@ class QlLoaderPE(QlLoader, Process): address = self.ql.pack64(addr) self.ql.mem.write(imp.address, address) - logging.debug("[+] Done with loading %s" % self.path) + self.ql.log.debug("[+] Done with loading %s" % self.path) self.ql.os.entry_point = self.entry_point self.ql.os.pid = 101 diff --git a/qiling/loader/pe_uefi.py b/qiling/loader/pe_uefi.py index 5fafdc83..cd157308 100644 --- a/qiling/loader/pe_uefi.py +++ b/qiling/loader/pe_uefi.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from typing import Sequence from pefile import PE @@ -111,10 +111,10 @@ class QlLoaderPE_UEFI(QlLoader): ql.mem.map(image_base, image_size, info="[module]") ql.mem.write(image_base, data) - logging.info(f'[+] Module {path} loaded to {image_base:#x}') + ql.log.info(f'[+] Module {path} loaded to {image_base:#x}') entry_point = image_base + pe.OPTIONAL_HEADER.AddressOfEntryPoint - logging.info(f'[+] Module entry point at {entry_point:#x}') + ql.log.info(f'[+] Module entry point at {entry_point:#x}') # the 'entry_point' member is used by the debugger. if not set, set it # to the first loaded module entry point so the debugger can break @@ -173,7 +173,7 @@ class QlLoaderPE_UEFI(QlLoader): self.call_function(unload_ptr, [handle], self.end_of_execution_ptr) self.loaded_image_protocol_modules.remove(handle) - logging.info(f'Unloading module {handle:#x}, calling {unload_ptr:#x}') + ql.log.info(f'Unloading module {handle:#x}, calling {unload_ptr:#x}') return True @@ -195,7 +195,7 @@ class QlLoaderPE_UEFI(QlLoader): self.call_function(entry_point, [ImageHandle, SystemTable], eoe_trap) self.ql.os.entry_point = entry_point - logging.info(f'Running from {entry_point:#010x} of {path}') + ql.log.info(f'Running from {entry_point:#010x} of {path}') def execute_next_module(self): if not self.modules or self.ql.os.notify_before_module_execution(self.ql, self.modules[0][0]): @@ -236,14 +236,14 @@ class QlLoaderPE_UEFI(QlLoader): heap_size = int(os_profile["heap_size"], 0) self.dxe_context.init_heap(heap_base, heap_size) self.heap_base_address = heap_base - logging.info(f"[+] Located heap at {heap_base:#010x}") + ql.log.info(f"[+] Located heap at {heap_base:#010x}") # initialize and locate stack stack_base = int(os_profile["stack_address"], 0) stack_size = int(os_profile["stack_size"], 0) self.dxe_context.init_stack(stack_base, stack_size) sp = stack_base + stack_size - CPU_STACK_ALIGNMENT - logging.info(f"[+] Located stack at {sp:#010x}") + ql.log.info(f"[+] Located stack at {sp:#010x}") # TODO: statically allocating 256 KiB for ST, RT, BS, DS and Configuration Tables. # however, this amount of memory is rather arbitrary @@ -271,7 +271,7 @@ class QlLoaderPE_UEFI(QlLoader): heap_base = int(smm_profile["heap_address"], 0) heap_size = int(smm_profile["heap_size"], 0) self.smm_context.init_heap(heap_base, heap_size) - logging.info(f"[+] Located SMM heap at {heap_base:#010x}") + ql.log.info(f"[+] Located SMM heap at {heap_base:#010x}") # TODO: statically allocating 256 KiB for SMM ST. # however, this amount of memory is rather arbitrary @@ -310,9 +310,9 @@ class QlLoaderPE_UEFI(QlLoader): for dependency in self.ql.argv: self.map_and_load(dependency) except QlMemoryMappedError: - logging.critical("Couldn't map dependency") + ql.log.critical("Couldn't map dependency") - logging.info(f"[+] Done with loading {self.ql.path}") + ql.log.info(f"[+] Done with loading {self.ql.path}") # set up an end-of-execution hook to regain control when module is done # executing (i.e. when the entry point function returns). that should be diff --git a/qiling/os/dos/dos.py b/qiling/os/dos/dos.py index 8bdeff82..c8cf81a8 100644 --- a/qiling/os/dos/dos.py +++ b/qiling/os/dos/dos.py @@ -3,9 +3,10 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import types, os, struct, time, logging +import types, os, struct, time from unicorn import * + from qiling.const import QL_INTERCEPT from qiling.os.os import QlOs from qiling.os.utils import PathUtils @@ -308,7 +309,7 @@ class QlOsDos(QlOs): elif al == 0x11 or al == 0x12: curses.resizeterm(480, 640) else: - logging.info("Exception: int 10h syscall Not Found, al: %s" % hex(al)) + self.ql.log.info("Exception: int 10h syscall Not Found, al: %s" % hex(al)) raise NotImplementedError() # Quoted from https://linux.die.net/man/3/resizeterm # @@ -317,13 +318,13 @@ class QlOsDos(QlOs): # read on the next call to getch. ch = self._get_ch_non_blocking() if ch == curses.KEY_RESIZE: - logging.info(f"[!] You term has been resized!") + self.ql.log.info(f"[!] You term has been resized!") elif ch != -1: curses.ungetch(ch) self.stdscr.scrollok(True) if not curses.has_colors(): - logging.info(f"[!] Warning: your terminal doesn't support colors, content might not be displayed correctly.") + self.ql.log.info(f"[!] Warning: your terminal doesn't support colors, content might not be displayed correctly.") # https://en.wikipedia.org/wiki/BIOS_color_attributes # blink support? @@ -364,8 +365,8 @@ class QlOsDos(QlOs): cy, cx = self.stdscr.getyx() attr = self._get_attr(fg, bg) if ch != 0 or cl != 0 or dh != y - 1 or dl != x - 1: - logging.info(f"[!] Warning: Partial scroll is unsupported. Will scroll the whole page.") - logging.info(f"[!] Resolution: {y}x{x} but asked to scroll [({ch},{cl}),({dh}, {dl})]") + self.ql.log.info(f"[!] Warning: Partial scroll is unsupported. Will scroll the whole page.") + self.ql.log.info(f"[!] Resolution: {y}x{x} but asked to scroll [({ch},{cl}),({dh}, {dl})]") if al != 0: self.stdscr.scroll(al) ny = 0 @@ -402,7 +403,7 @@ class QlOsDos(QlOs): orig_bg |= 0b1000 self.ql.reg.ah = ((orig_bg << 4) & orig_fg) elif ah == 0xE: - logging.debug(f"Echo: {hex(al)} -> {curses.ascii.unctrl(al)}") + self.ql.log.debug(f"Echo: {hex(al)} -> {curses.ascii.unctrl(al)}") y, x = self.stdscr.getmaxyx() cy, cx = self.stdscr.getyx() fg = self.ql.reg.bl @@ -413,7 +414,7 @@ class QlOsDos(QlOs): attr = self.stdscr.inch(cy, cx) & curses.A_COLOR if al == 0xa: # \n will erase current line with echochar, so we have to handle it carefully. - logging.info(f"Resolution: {x}x{y}, Cursor position: {cx},{cy}, Going to get a new line.") + self.ql.log.info(f"Resolution: {x}x{y}, Cursor position: {cx},{cy}, Going to get a new line.") if y-1 == cy: # scroll doesn't affect our cursor self.stdscr.scroll(1) @@ -423,7 +424,7 @@ class QlOsDos(QlOs): else: self.stdscr.echochar(al, attr) else: - logging.info("Exception: int 10h syscall Not Found, ah: %s" % hex(ah)) + self.ql.log.info("Exception: int 10h syscall Not Found, ah: %s" % hex(ah)) raise NotImplementedError() if self.stdscr is not None: self.stdscr.refresh() @@ -443,7 +444,7 @@ class QlOsDos(QlOs): sector = self.ql.reg.cx & 63 head = self.ql.reg.dh if not self.ql.os.fs_mapper.has_mapping(idx): - self.logging.info(f"[!] Warning: No such disk: {hex(idx)}") + self.ql.log.info(f"[!] Warning: No such disk: {hex(idx)}") self.ql.reg.ah = INT13DiskError.BadCommand.value self.set_cf() return @@ -457,7 +458,7 @@ class QlOsDos(QlOs): # https://stanislavs.org/helppc/int_13-8.html idx = self.ql.reg.dl if not self.ql.os.fs_mapper.has_mapping(idx): - logging.info(f"[!] Warning: No such disk: {hex(idx)}") + self.ql.log.info(f"[!] Warning: No such disk: {hex(idx)}") self.ql.reg.ah = INT13DiskError.BadCommand.value self.set_cf() return @@ -494,9 +495,9 @@ class QlOsDos(QlOs): idx = self.ql.reg.dl dapbs = self.ql.mem.read(self.calculate_address(ds, si), 0x10) _, _, cnt, offset, segment, lba = self._parse_dap(dapbs) - logging.info(f"Reading {cnt} sectors from disk {hex(idx)} with LBA {lba}") + self.ql.log.info(f"Reading {cnt} sectors from disk {hex(idx)} with LBA {lba}") if not self.ql.os.fs_mapper.has_mapping(idx): - logging.info(f"[!] Warning: No such disk: {hex(idx)}") + self.ql.log.info(f"[!] Warning: No such disk: {hex(idx)}") self.ql.reg.ah = INT13DiskError.BadCommand.value self.set_cf() return @@ -509,9 +510,9 @@ class QlOsDos(QlOs): idx = self.ql.reg.dl dapbs = self.ql.mem.read(self.calculate_address(ds, si), 0x10) _, _, cnt, offset, segment, lba = self._parse_dap(dapbs) - logging.info(f"Write {cnt} sectors to disk {hex(idx)} with LBA {lba}") + self.ql.log.info(f"Write {cnt} sectors to disk {hex(idx)} with LBA {lba}") if not self.ql.os.fs_mapper.has_mapping(idx): - logging.info(f"[!] Warning: No such disk: {hex(idx)}") + self.ql.log.info(f"[!] Warning: No such disk: {hex(idx)}") self.ql.reg.ah = INT13DiskError.BadCommand.value self.set_cf() return @@ -521,7 +522,7 @@ class QlOsDos(QlOs): self.clear_cf() self.ql.reg.ah = 0 else: - logging.info("Exception: int 13h syscall Not Found, ah: %s" % hex(ah)) + self.ql.log.info("Exception: int 13h syscall Not Found, ah: %s" % hex(ah)) raise NotImplementedError() def int15(self): @@ -539,13 +540,13 @@ class QlOsDos(QlOs): self.clear_cf() elif ax == 0x5307: if self.ql.reg.bx == 1 and self.ql.reg.cx == 3: - self.logging.info("[+] Emulation Stop") + self.ql.log.info("[+] Emulation Stop") self.ql.uc.emu_stop() elif ah == 0x86: dx = self.ql.reg.dx cx = self.ql.reg.cx full_secs = ((cx << 16) + dx) / 1000000 - logging.info(f"Goint to sleep {full_secs} seconds") + self.ql.log.info(f"Goint to sleep {full_secs} seconds") time.sleep(full_secs) # Note: Since we are in a single thread environment, we assume @@ -567,7 +568,7 @@ class QlOsDos(QlOs): if ch in SCANCODES: return SCANCODES[ch] else: - logging.info(f"[!] Warning: scan code for {hex(ch)} doesn't exist!") + self.ql.log.info(f"[!] Warning: scan code for {hex(ch)} doesn't exist!") return 0 def int16(self): @@ -575,7 +576,7 @@ class QlOsDos(QlOs): if ah == 0x0: curses.nonl() key = self._parse_key(self.stdscr.getch()) - logging.debug(f"Get key: {hex(key)}") + self.ql.log.debug(f"Get key: {hex(key)}") if curses.ascii.isascii(key): self.ql.reg.al = key else: @@ -591,7 +592,7 @@ class QlOsDos(QlOs): self.set_flag(0x40) self.ql.reg.ax = 0 else: - logging.debug(f"Has key: {hex(key)} ({curses.ascii.unctrl(key)})") + self.ql.log.debug(f"Has key: {hex(key)} ({curses.ascii.unctrl(key)})") self.ql.reg.al = key self.ql.reg.ah = self._get_scan_code(key) self.clear_flag(0x40) @@ -664,7 +665,7 @@ class QlOsDos(QlOs): pass else: - logging.info("Exception: int 20h syscall Not Found, ah: %s" % hex(ah)) + self.ql.log.info("Exception: int 20h syscall Not Found, ah: %s" % hex(ah)) raise NotImplementedError() def int21(self): @@ -672,17 +673,17 @@ class QlOsDos(QlOs): # exit if ah == 0x4C: - logging.info("[+] Emulation Stop") + self.ql.log.info("[+] Emulation Stop") self.ql.uc.emu_stop() # character output elif ah == 0x2 or ah == 0x6: ch = chr(self.ql.reg.dl) self.ql.reg.al = self.ql.reg.dl - logging.info(ch) + self.ql.log.info(ch) # write to screen elif ah == 0x9: s = self.read_dos_string_from_ds_dx() - logging.info(s) + self.ql.log.info(s) elif ah == 0xC: # Clear input buffer pass @@ -772,13 +773,13 @@ class QlOsDos(QlOs): self.ql.reg.cx = 0xFFFF self.clear_cf() else: - logging.info("Exception: int 21h syscall Not Found, ah: %s" % hex(ah)) + self.ql.log.info("Exception: int 21h syscall Not Found, ah: %s" % hex(ah)) raise NotImplementedError() def hook_syscall(self): def cb(ql, intno, user_data=None): ah = self.ql.reg.ah - logging.debug(f"INT {intno:x} with ah={hex(ah)}") + self.ql.log.debug(f"INT {intno:x} with ah={hex(ah)}") interrupt_tuple = (intno, ah) before = self.before_interrupt.get(interrupt_tuple, None) after = self.after_interrupt.get(interrupt_tuple, None) diff --git a/qiling/os/freebsd/syscall.py b/qiling/os/freebsd/syscall.py index 37ce4265..6e6b9be6 100644 --- a/qiling/os/freebsd/syscall.py +++ b/qiling/os/freebsd/syscall.py @@ -3,12 +3,11 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging from qiling.arch.x86_const import * def ql_syscall_clock_gettime(ql, clock_gettime_clock_id, clock_gettime_timespec, *args, **kw): - logging.info("clock_gettime()") + ql.log.info("clock_gettime()") return 0 @@ -28,5 +27,5 @@ def ql_syscall_sysarch(ql, op, parms, *args, **kw): #op_buf = ql.pack32(op) #ql.mem.write(parms, op_buf) - logging.info("sysarch(0x%x,0x%x) = %i" % (op, parms, regreturn)) + ql.log.info("sysarch(0x%x,0x%x) = %i" % (op, parms, regreturn)) return regreturn diff --git a/qiling/os/linux/fncc.py b/qiling/os/linux/fncc.py index 8fc981df..5cf05669 100644 --- a/qiling/os/linux/fncc.py +++ b/qiling/os/linux/fncc.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import struct, logging +import struct from unicorn.x86_const import * from unicorn.mips_const import * @@ -196,9 +196,9 @@ def print_function(ql, passthru, address, function_name, params, ret): log = log.replace("\n", "\\n") if ql.output != QL_OUTPUT.DEBUG: log = log.partition(" ")[-1] - logging.info(log) + ql.log.info(log) else: - logging.debug(log) + ql.log.debug(log) def __x86_cc(ql, param_num, params, func, args, kwargs): diff --git a/qiling/os/linux/function_hook.py b/qiling/os/linux/function_hook.py index 0d667e49..47b1c696 100644 --- a/qiling/os/linux/function_hook.py +++ b/qiling/os/linux/function_hook.py @@ -3,7 +3,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import struct, logging +import struct + from qiling.const import * @@ -996,12 +997,12 @@ class FunctionHook: for r in rel: if (r.r_type == self.JMP_SLOT or r.r_type == self.GLOB_DAT) and r.r_sym != 0: rel_name = self.strtab[self.symtab[r.r_sym].st_name] - logging.debug('[+] rel name ' + str(rel_name)) + self.ql.log.debug('[+] rel name ' + str(rel_name)) def show_dynsym_name(self, s, e): for symidx in range(s, e): rel_name = self.strtab[self.symtab[symidx].st_name] - logging.debug('[+] dynsym name ' + str(rel_name)) + self.ql.log.debug('[+] dynsym name ' + str(rel_name)) def _hook_int(self, ql, intno): idx = (self.ql.reg.arch_pc - self.hook_mem) // 0x10 diff --git a/qiling/os/linux/futex.py b/qiling/os/linux/futex.py index 9bd7b1c0..1f17b9b2 100644 --- a/qiling/os/linux/futex.py +++ b/qiling/os/linux/futex.py @@ -3,9 +3,9 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import gevent, logging +import gevent + -from logging import getLevelName from gevent.event import Event from queue import Queue @@ -22,11 +22,11 @@ class QlLinuxFutexManagement: def futex_wait(self, ql, uaddr, t, val, bitset=FUTEX_BITSET_MATCH_ANY): def _sched_wait_event(cur_thread): - logging.debug(f"[Thread {cur_thread.get_id()}] Wait for notifications.") + ql.log.debug(f"Wait for notifications.") event.wait() uaddr_value = ql.unpack32(ql.mem.read(uaddr, 4)) if uaddr_value != val: - logging.debug(f"uaddr: {hex(uaddr_value)} != {hex(val)}") + ql.log.debug(f"uaddr: {hex(uaddr_value)} != {hex(val)}") return -1 ql.emu_stop() if uaddr not in self.wait_list.keys(): @@ -39,7 +39,7 @@ class QlLinuxFutexManagement: def get_futex_wake_list(self, ql, addr, number, bitset=FUTEX_BITSET_MATCH_ANY): wakes = [] if addr not in self.wait_list or number == 0: - logging.debug(f"No thread at {hex(addr)}") + ql.log.debug(f"No thread at {hex(addr)}") return wakes thread_queue = self.wait_list[addr] if thread_queue.qsize() < number: @@ -55,7 +55,7 @@ class QlLinuxFutexManagement: def futex_wake(self, ql, uaddr, t, number, bitset=FUTEX_BITSET_MATCH_ANY): def _sched_set_event(cur_thread): for t, e in wakes: - logging.debug(f"[Thread {cur_thread.get_id()}] Notify [Thread {t.get_id()}].") + ql.log.debug(f"Notify [Thread {t.get_id()}.") e.set() # Give up control. gevent.sleep(0) diff --git a/qiling/os/linux/kernel_api/hook.py b/qiling/os/linux/kernel_api/hook.py index 63bc0c4f..ad98ed1f 100644 --- a/qiling/os/linux/kernel_api/hook.py +++ b/qiling/os/linux/kernel_api/hook.py @@ -4,7 +4,7 @@ # from qiling.os.linux.kernel_api import * -import logging + # hook Linux kernel API def hook_kernel_api(ql, address, size): @@ -29,11 +29,11 @@ def hook_kernel_api(ql, address, size): try: api_func(ql, address, {}) except Exception: - logging.exception("") - logging.debug("[!] %s Exception Found" % api_name) + ql.log.exception("") + ql.log.debug("[!] %s Exception Found" % api_name) raise QlErrorSyscallError("[!] Linux kernel API Implementation Error") else: - logging.warning("[!] %s is not implemented\n" % api_name) + ql.log.warning("[!] %s is not implemented\n" % api_name) if ql.debug_stop: raise QlErrorSyscallNotFound("[!] Linux kernel API Implementation Not Found") diff --git a/qiling/os/linux/linux.py b/qiling/os/linux/linux.py index 12eb31e1..7dc10f99 100644 --- a/qiling/os/linux/linux.py +++ b/qiling/os/linux/linux.py @@ -3,7 +3,6 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging from qiling.const import * from qiling.arch.x86 import * diff --git a/qiling/os/linux/syscall.py b/qiling/os/linux/syscall.py index ad469ed3..894d6b24 100644 --- a/qiling/os/linux/syscall.py +++ b/qiling/os/linux/syscall.py @@ -3,7 +3,6 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging from unicorn.arm_const import * from unicorn.x86_const import * @@ -17,20 +16,20 @@ def ql_syscall_set_thread_area(ql, u_info_addr, *args, **kw): GDT_ENTRY_TLS_MIN = 12 GDT_ENTRY_TLS_MAX = 14 - logging.info("set_thread_area(u_info_addr= 0x%x)" % u_info_addr) + ql.log.info("set_thread_area(u_info_addr= 0x%x)" % u_info_addr) u_info = ql.mem.read(u_info_addr, 4 * 4) index = ql.unpack32s(u_info[0 : 4]) base = ql.unpack32(u_info[4 : 8]) limit = ql.unpack32(u_info[8 : 12]) - logging.debug("[+] set_thread_area base : 0x%x limit is : 0x%x" % (base, limit)) + ql.log.debug("[+] set_thread_area base : 0x%x limit is : 0x%x" % (base, limit)) if index == -1: index = ql.os.gdtm.get_free_idx(12) if index == -1 or index < 12 or index > 14: - logging.warning(f"Wrong index {index} from address {hex(u_info_addr)}") + ql.log.warning(f"Wrong index {index} from address {hex(u_info_addr)}") return -1 else: ql.os.gdtm.register_gdt_segment(index, base, limit, QL_X86_A_PRESENT | QL_X86_A_DATA | QL_X86_A_DATA_WRITABLE | QL_X86_A_PRIV_3 | QL_X86_A_DIR_CON_BIT, QL_X86_S_GDT | QL_X86_S_PRIV_3) @@ -43,7 +42,7 @@ def ql_syscall_set_thread_area(ql, u_info_addr, *args, **kw): ql.reg.cp0_userlocal = u_info_addr ql.reg.v0 = 0 ql.reg.a3 = 0 - logging.info ("set_thread_area(0x%x)" % u_info_addr) + ql.log.info ("set_thread_area(0x%x)" % u_info_addr) return 0 @@ -53,4 +52,4 @@ def ql_syscall_set_tls(ql, address, *args, **kw): ql.reg.c13_c0_3 = address ql.mem.write(ql.arch.arm_get_tls_addr + 12, ql.pack32(address)) ql.reg.r0 = address - logging.info("settls(0x%x)" % address) + ql.log.info("settls(0x%x)" % address) diff --git a/qiling/os/linux/thread.py b/qiling/os/linux/thread.py index 763781b8..5681519e 100644 --- a/qiling/os/linux/thread.py +++ b/qiling/os/linux/thread.py @@ -3,8 +3,9 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import gevent, os, time, logging +import gevent, os, time +from typing import Callable from abc import ABC, abstractmethod from pathlib import Path from gevent import Greenlet @@ -45,17 +46,8 @@ class QlLinuxThread(QlThread): self._log_file_fd = None self._sched_cb = None - if self.ql.log_split: - _logger = logging.getLogger(f"thread{self.id}") - _logger.propagate = False - if self.ql.log_dir is not None and self.ql.log_dir != "": - handler = logging.FileHandler(Path(self.ql.log_dir) / f"{self.ql.targetname + self.ql.append}_{self.id}.qlog") - handler.setFormatter(logging.Formatter(FMT_STR)) - _logger.addHandler(handler) - - self._log_file_fd = _logger - else: - self._log_file_fd = logging.getLogger() + # Compatibility + self._log_file_fd = ql.log # For each thread, the kernel maintains two attributes (addresses) # called set_child_tid and clear_child_tid. These two attributes @@ -206,7 +198,7 @@ class QlLinuxThread(QlThread): self._robust_list_head_len = l @property - def sched_cb(self): + def sched_cb(self) -> Callable: return self._sched_cb @sched_cb.setter @@ -249,21 +241,21 @@ class QlLinuxThread(QlThread): # Sanity check if self.ql.reg.arch_pc == self.exit_point: - logging.warning("Nothing to do but still get scheduled!") + self.ql.log.warning(f"Nothing to do but still get scheduled!") # Run and log the run event start_address = self.ql.arch.get_pc() # For arm thumb. self.sched_cb = QlLinuxThread._default_sched_cb - logging.debug(f"Scheduled from {hex(start_address)}.") + self.ql.log.debug(f"Scheduled from {hex(start_address)}.") try: # Known issue for timeout: https://github.com/unicorn-engine/unicorn/issues/1355 self.ql.emu_start(start_address, self.exit_point, count=30000) except UcError as e: self.ql.os.emu_error() - logging.exception("") + self.ql.log.exception("") raise e - logging.debug(f"Suspended at {hex(self.ql.reg.arch_pc)}") + self.ql.log.debug(f"Suspended at {hex(self.ql.reg.arch_pc)}") self.save() # Note that this callback may be set by UC callbacks. @@ -271,7 +263,7 @@ class QlLinuxThread(QlThread): # 1. Never give up control during a UC callback. # 2. emu_stop only sends a signal to unicorn which won't stop it immediately. # 3. According to 1, never call gevent functions in UC callbacks. - logging.debug(f"Call sched_cb: {self.sched_cb}") + self.ql.log.debug(f"Call sched_cb: {self.sched_cb}") self.sched_cb(self) if self.status == THREAD_STATUS_TERMINATED or self.ql.reg.arch_pc == self.exit_point: @@ -344,14 +336,14 @@ class QlLinuxThread(QlThread): # Source: Linux Man Page if self.clear_child_tid_address is not None: - logging.debug(f"[Thread {self.get_id()}] Perform CLONE_CHILD_CLEARTID at {hex(self.clear_child_tid_address)}") + self.ql.log.debug(f"Perform CLONE_CHILD_CLEARTID at {hex(self.clear_child_tid_address)}") self.ql.mem.write(self.clear_child_tid_address, self.ql.pack32(0)) wakes = self.ql.os.futexm.get_futex_wake_list(self.ql, self.clear_child_tid_address, 1) self.clear_child_tid_address = None # When the thread is to stop, we don't have chance for next sched_cb, so # we notify the thread directly. for t, e in wakes: - logging.debug(f"[Thread {self.get_id()}] Notify [Thread {t.get_id()}].") + self.ql.log.debug(f"Notify {t}.") e.set() # This function should called outside unicorn callback. @@ -399,17 +391,17 @@ class QlLinuxX86Thread(QlLinuxThread): self.tls = bytes(self.ql.os.gdtm.get_gdt_buf(12, 14 + 1)) self.ql.os.gdtm.set_gdt_buf(12, 14 + 1, old_tls) - logging.debug(f"Set tls to index={hex(index)} base={hex(base)} limit={hex(limit)} fs={hex(self.ql.reg.fs)} gs={hex(self.ql.reg.gs)} gdt_buf={self.tls}") + self.ql.log.debug(f"Set tls to index={hex(index)} base={hex(base)} limit={hex(limit)} fs={hex(self.ql.reg.fs)} gs={hex(self.ql.reg.gs)} gdt_buf={self.tls}") def save(self): self.save_context() self.tls = bytes(self.ql.os.gdtm.get_gdt_buf(12, 14 + 1)) - logging.debug(f"Saved context. fs={hex(self.ql.reg.fs)} gs={hex(self.ql.reg.gs)} gdt_buf={self.tls}") + self.ql.log.debug(f"Saved context. fs={hex(self.ql.reg.fs)} gs={hex(self.ql.reg.gs)} gdt_buf={self.tls}") def restore(self): self.restore_context() self.ql.os.gdtm.set_gdt_buf(12, 14 + 1, self.tls) - logging.debug(f"Restored context. fs={hex(self.ql.reg.fs)} gs={hex(self.ql.reg.gs)} gdt_buf={self.tls}") + self.ql.log.debug(f"Restored context. fs={hex(self.ql.reg.fs)} gs={hex(self.ql.reg.gs)} gdt_buf={self.tls}") def clone(self): new_thread = super(QlLinuxX86Thread, self).clone() @@ -425,7 +417,7 @@ class QlLinuxX8664Thread(QlLinuxThread): def set_thread_tls(self, tls_addr): self.tls = tls_addr self.ql.reg.msr(FSMSR, self.tls) - logging.debug(f"Set fsbase to {hex(tls_addr)} for {str(self)}") + self.ql.log.debug(f"Set fsbase to {hex(tls_addr)} for {str(self)}") # Some notes: # - https://wiki.osdev.org/SWAPGS @@ -433,12 +425,12 @@ class QlLinuxX8664Thread(QlLinuxThread): def save(self): self.save_context() self.tls = self.ql.reg.msr(FSMSR) - logging.debug(f"Saved context: fs={hex(self.ql.reg.fsbase)} tls={hex(self.tls)}") + self.ql.log.debug(f"Saved context: fs={hex(self.ql.reg.fsbase)} tls={hex(self.tls)}") def restore(self): self.restore_context() self.set_thread_tls(self.tls) - logging.debug(f"Restored context: fs={hex(self.ql.reg.fsbase)} tls={hex(self.tls)}") + self.ql.log.debug(f"Restored context: fs={hex(self.ql.reg.fsbase)} tls={hex(self.tls)}") def clone(self): new_thread = super(QlLinuxX8664Thread, self).clone() @@ -457,17 +449,17 @@ class QlLinuxMIPS32Thread(QlLinuxThread): CONFIG3_ULR = (1 << 13) self.ql.reg.cp0_config3 = CONFIG3_ULR self.ql.reg.cp0_userlocal = self.tls - logging.debug(f"Set cp0 to {hex(self.ql.reg.cp0_userlocal)}") + self.ql.log.debug(f"Set cp0 to {hex(self.ql.reg.cp0_userlocal)}") def save(self): self.save_context() self.tls = self.ql.reg.cp0_userlocal - logging.debug(f"Saved context. cp0={hex(self.ql.reg.cp0_userlocal)}") + self.ql.log.debug(f"Saved context. cp0={hex(self.ql.reg.cp0_userlocal)}") def restore(self): self.restore_context() self.set_thread_tls(self.tls) - logging.debug(f"Restored context. cp0={hex(self.ql.reg.cp0_userlocal)}") + self.ql.log.debug(f"Restored context. cp0={hex(self.ql.reg.cp0_userlocal)}") def clone(self): new_thread = super(QlLinuxMIPS32Thread, self).clone() @@ -484,18 +476,18 @@ class QlLinuxARMThread(QlLinuxThread): def set_thread_tls(self, tls_addr): self.tls = tls_addr self.ql.reg.c13_c0_3 = self.tls - logging.debug(f"Set c13_c0_3 to {hex(self.ql.reg.c13_c0_3)}") + self.ql.log.debug(f"Set c13_c0_3 to {hex(self.ql.reg.c13_c0_3)}") def save(self): self.save_context() self.tls = self.ql.reg.c13_c0_3 - logging.debug(f"Saved context. c13_c0_3={hex(self.ql.reg.c13_c0_3)}") + self.ql.log.debug(f"Saved context. c13_c0_3={hex(self.ql.reg.c13_c0_3)}") def restore(self): self.restore_context() self.set_thread_tls(self.tls) - logging.debug(f"Restored context. c13_c0_3={hex(self.ql.reg.c13_c0_3)}") + self.ql.log.debug(f"Restored context. c13_c0_3={hex(self.ql.reg.c13_c0_3)}") def clone(self): new_thread = super(QlLinuxARMThread, self).clone() @@ -512,17 +504,17 @@ class QlLinuxARM64Thread(QlLinuxThread): def set_thread_tls(self, tls_addr): self.tls = tls_addr self.ql.reg.tpidr_el0 = self.tls - logging.debug(f"Set tpidr_el0 to {hex(self.ql.reg.tpidr_el0)}") + self.ql.log.debug(f"Set tpidr_el0 to {hex(self.ql.reg.tpidr_el0)}") def save(self): self.save_context() self.tls = self.ql.reg.tpidr_el0 - logging.debug(f"Saved context. tpidr_el0={hex(self.ql.reg.tpidr_el0)}") + self.ql.log.debug(f"Saved context. tpidr_el0={hex(self.ql.reg.tpidr_el0)}") def restore(self): self.restore_context() self.set_thread_tls(self.tls) - logging.debug(f"Restored context. tpidr_el0={hex(self.ql.reg.tpidr_el0)}") + self.ql.log.debug(f"Restored context. tpidr_el0={hex(self.ql.reg.tpidr_el0)}") def clone(self): new_thread = super(QlLinuxARM64Thread, self).clone() @@ -577,7 +569,7 @@ class QlLinuxThreadManagement: self._clear_queued_msg() gevent.joinall([self.main_thread], raise_error=True) if self.ql.reg.arch_pc != self.ql.loader.elf_entry: - logging.error(f"Expect {hex(self.ql.loader.elf_entry)} but get {hex(self.ql.reg.arch_pc)} when running loader.") + self.ql.log.error(f"{self.cur_thread} Expect {hex(self.ql.loader.elf_entry)} but get {hex(self.ql.reg.arch_pc)} when running loader.") raise QlErrorExecutionStop('Dynamic library .init() failed!') self.ql.enable_lib_patch() self.ql.os.run_function_after_load() @@ -588,7 +580,7 @@ class QlLinuxThreadManagement: # Stop the world, urge all threads to stop immediately. def stop(self): - logging.debug("[Thread Manager] Stop the world.") + self.ql.log.debug("[Thread Manager] Stop the world.") self.ql.emu_stop() for t in self.threads: gevent.kill(t) diff --git a/qiling/os/linux/utils.py b/qiling/os/linux/utils.py index a4dba38f..92719c08 100644 --- a/qiling/os/linux/utils.py +++ b/qiling/os/linux/utils.py @@ -3,7 +3,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + + from .const import * from qiling.const import * @@ -21,5 +22,5 @@ def ql_arm_init_get_tls(ql): # sc = ql.os.lsbmsb_convert(ql, sc) ql.mem.write(ql.arch.arm_get_tls_addr, sc) - logging.debug("[+] Set init_kernel_get_tls") + ql.log.debug("[+] Set init_kernel_get_tls") \ No newline at end of file diff --git a/qiling/os/macos/events/macos.py b/qiling/os/macos/events/macos.py index fa8a4526..7ffeea23 100644 --- a/qiling/os/macos/events/macos.py +++ b/qiling/os/macos/events/macos.py @@ -4,7 +4,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import ctypes, logging, socket, struct +import ctypes, socket, struct + from functools import wraps from unicorn.x86_const import * @@ -33,14 +34,14 @@ class QlMacOSEv: self.params = params[:] def dump(self): - logging.info("[*] Dumping object: %s with type %d" % (self.name, self.type.value)) + self.ql.log.info("[*] Dumping object: %s with type %d" % (self.name, self.type.value)) for field in self.event._fields_: if isinstance(getattr(self.event, field[0]), POINTER64): - logging.info("%s: 0x%x" % (field[0], getattr(self.event, field[0]).value)) + self.ql.log.info("%s: 0x%x" % (field[0], getattr(self.event, field[0]).value)) elif isinstance(getattr(self.event, field[0]), int): - logging.info("%s: %d" % (field[0], getattr(self.event, field[0]))) + self.ql.log.info("%s: %d" % (field[0], getattr(self.event, field[0]))) elif isinstance(getattr(self.event, field[0]), bytes): - logging.info("%s: %s" % (field[0], getattr(self.event, field[0]).decode())) + self.ql.log.info("%s: %s" % (field[0], getattr(self.event, field[0]).decode())) def init_ev_ctx(f): @wraps(f) @@ -113,7 +114,7 @@ class QlMacOSEvManager: def add_process(self, pid, name): for p in self.my_procs: if p.p_pid == pid: - logging.info("[!] Duplicated process") + self.ql.log.info("[!] Duplicated process") return cur_proc_addr = self.ql.os.heap.alloc(ctypes.sizeof(proc_t)) @@ -207,7 +208,7 @@ class QlMacOSEvManager: def emit(self, ev_name, ev_type, params): found = self.get_event_by_name_and_type(ev_name, ev_type) if found is None: - logging.info("[!] No callbacks found for (%s, %s)" % (ev_name, ev_type)) + self.ql.log.info("[!] No callbacks found for (%s, %s)" % (ev_name, ev_type)) return found.set_params(params) diff --git a/qiling/os/macos/events/macos_policy.py b/qiling/os/macos/events/macos_policy.py index aaa92152..12d49112 100644 --- a/qiling/os/macos/events/macos_policy.py +++ b/qiling/os/macos/events/macos_policy.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import ctypes, enum, logging +import ctypes, enum from functools import wraps @@ -57,7 +57,7 @@ class QlMacOSPolicy(): @init_ctx def mpo_file_check_mmap(self, prot, flags, file_pos): if self.manager.vnode is None or self.manager.cred is None: - logging.info("[!] Invalid vnode or credential") + ql.log.info("[!] Invalid vnode or credential") return fg_addr = self.ql.os.heap.alloc(ctypes.sizeof(fileglob_t)) fg = fileglob_t(self.ql, fg_addr) diff --git a/qiling/os/macos/events/macos_structs.py b/qiling/os/macos/events/macos_structs.py index edbd07e9..718d3c2f 100644 --- a/qiling/os/macos/events/macos_structs.py +++ b/qiling/os/macos/events/macos_structs.py @@ -3,10 +3,11 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import ctypes, enum, logging +import ctypes, enum from qiling.os.macos.structs import POINTER64 + base_event_normal = 0 class AutoNumberNormalEvent(enum.Enum): def __new__(cls): @@ -1006,14 +1007,14 @@ class sflt_filter_t(ctypes.Structure): return newObj def dump(self): - logging.info("[*] Dumping object: %s" % (self.sf_name)) + self.ql.log.info("[*] Dumping object: %s" % (self.sf_name)) for field in self._fields_: if isinstance(getattr(self, field[0]), POINTER64): - logging.info("%s: 0x%x" % (field[0], getattr(self, field[0]).value)) + self.ql.log.info("%s: 0x%x" % (field[0], getattr(self, field[0]).value)) elif isinstance(getattr(self, field[0]), int): - logging.info("%s: %d" % (field[0], getattr(self, field[0]))) + self.ql.log.info("%s: %d" % (field[0], getattr(self, field[0]))) elif isinstance(getattr(self, field[0]), bytes): - logging.info("%s: %s" % (field[0], getattr(self, field[0]).decode())) + self.ql.log.info("%s: %s" % (field[0], getattr(self, field[0]).decode())) # struct sockaddr_in { # __uint8_t sin_len; @@ -1123,11 +1124,11 @@ class mac_policy_conf_t(ctypes.Structure): def dump(self): for field in self._fields_: if isinstance(getattr(self, field[0]), POINTER64): - logging.info("%s: 0x%x" % (field[0], getattr(self, field[0]).value)) + self.ql.log.info("%s: 0x%x" % (field[0], getattr(self, field[0]).value)) elif isinstance(getattr(self, field[0]), int): - logging.info("%s: %d" % (field[0], getattr(self, field[0]))) + self.ql.log.info("%s: %d" % (field[0], getattr(self, field[0]))) elif isinstance(getattr(self, field[0]), bytes): - logging.info("%s: %s" % (field[0], getattr(self, field[0]).decode())) + self.ql.log.info("%s: %s" % (field[0], getattr(self, field[0]).decode())) # struct ucred { # TAILQ_ENTRY(ucred) cr_link; /* never modify this without KAUTH_CRED_HASH_LOCK */ diff --git a/qiling/os/macos/kernel_api/hook.py b/qiling/os/macos/kernel_api/hook.py index d9b904f7..07bb4954 100644 --- a/qiling/os/macos/kernel_api/hook.py +++ b/qiling/os/macos/kernel_api/hook.py @@ -3,7 +3,6 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging from unicorn import * @@ -33,11 +32,11 @@ def hook_kernel_api(ql, address, size): except UcError: raise except Exception: - logging.exception("") - logging.debug("[!] %s Exception Found" % api_name) + ql.log.exception("") + ql.log.debug("[!] %s Exception Found" % api_name) raise QlErrorSyscallError("[!] MacOS kernel API Implementation Error") else: - logging.info("[!] %s is not implemented\n" % api_name) + ql.log.info("[!] %s is not implemented\n" % api_name) if ql.debug_stop: raise QlErrorSyscallNotFound("[!] MacOS kernel API Implementation Not Found") diff --git a/qiling/os/macos/kernel_api/kernel_api.py b/qiling/os/macos/kernel_api/kernel_api.py index 82ba3096..c7469873 100644 --- a/qiling/os/macos/kernel_api/kernel_api.py +++ b/qiling/os/macos/kernel_api/kernel_api.py @@ -3,10 +3,11 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import ctypes, logging, os, struct +import ctypes, os, struct from time import time + from qiling.os.macos.fncc import * from qiling.os.macos.structs import * from qiling.os.macos.utils import gen_stub_code @@ -949,7 +950,7 @@ def hook__sock_getsockname(ql, address, params): "cmd": STRING, }) def hook__KUNCExecute(ql, address, params): - # logging.debug("[+] Starting userspace process: %s" % params["cmd"]) + # ql.log.debug("[+] Starting userspace process: %s" % params["cmd"]) return 0 ######################## Custom events / callbacks ######################## @@ -993,7 +994,7 @@ def hook__sysctl_register_oid(ql, address, params): true_name = oid_parent.lstrip(b"_") + b"." + oid_name.encode() + b"\x00" if oidp.oid_handler.value != 0: - logging.debug("[+] New sysctl callback has been registered: %s" % true_name) + ql.log.debug("[+] New sysctl callback has been registered: %s" % true_name) ql.os.ev_manager.register(oidp.oid_handler.value, true_name, MacOSEventType.EV_SYSCTL, ev_obj=oidp, idx=0) return @@ -1015,7 +1016,7 @@ def hook__sysctl_unregister_oid(ql, address, params): break true_name = oid_parent.lstrip(b"_") + b"." + oid_name.encode() + b"\x00" - logging.debug("[+] A sysctl event has been deregistered: %s" % true_name) + ql.log.debug("[+] A sysctl event has been deregistered: %s" % true_name) ql.os.ev_manager.deregister(true_name) @macos_kernel_api(params={ @@ -1036,7 +1037,7 @@ def hook__sysctl_root(ql, address, params): obj = event.event ql.os.ev_manager.emit(ev_name, ev_type, [obj.oid_arg1.value, obj.oid_arg2, params["req"]]) else: - logging.debug("[!] Event not found (%s, %s)" % (ev_name, ev_type.name)) + ql.log.debug("[!] Event not found (%s, %s)" % (ev_name, ev_type.name)) return 0 @macos_kernel_api(params={ @@ -1074,7 +1075,7 @@ def hook__ctl_register(ql, address, params): ql.os.ev_manager.register(userctl.ctl_bind.value, ctl_name, MacOSEventType.EV_CTL_BIND_FUNC, ev_obj=userctl, idx=0) - logging.debug("[+] New ctl callbacks has been registered: %s (%d/%d/%d/%d/%d/%d/%d/%d)" % ( + ql.log.debug("[+] New ctl callbacks has been registered: %s (%d/%d/%d/%d/%d/%d/%d/%d)" % ( ctl_name, (flag & (1 << 0)) != 0, (flag & (1 << 1)) != 0, @@ -1095,7 +1096,7 @@ def hook__ctl_deregister(ql, address, params): userctl = kern_ctl_reg_t(ql, params["userctl"]) userctl = userctl.loadFromMem() ctl_name = ql.mem.string(params["userctl"]).encode() - logging.debug("[+] A ctl event has been deregistered: %s" % ctl_name) + ql.log.debug("[+] A ctl event has been deregistered: %s" % ctl_name) ql.os.ev_manager.deregister(ctl_name) @macos_kernel_api(params={ @@ -1169,7 +1170,7 @@ def hook__sflt_register(ql, address, params): flag |= 1 << 14 ql.os.ev_manager.register(sf.sf_ioctl.value, true_name, MacOSEventType.EV_SFLT_IOCTL, protocol=params["protocol"]) - logging.debug("[+] New sflt callbacks has been registered: %s (%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d)" % ( + ql.log.debug("[+] New sflt callbacks has been registered: %s (%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d)" % ( true_name, (flag & (1 << 0)) != 0, (flag & (1 << 1)) != 0, @@ -1201,7 +1202,7 @@ def hook__sflt_unregister(ql, address, params): break ql.os.ev_manager.deregister(b"", keyword=handle) - logging.debug("[+] A sflt event has been deregistered: %s" % (handle)) + ql.log.debug("[+] A sflt event has been deregistered: %s" % (handle)) return 0 @macos_kernel_api(params={ @@ -1220,7 +1221,7 @@ def hook__mac_policy_register(ql, address, params): func, = struct.unpack(" -import logging from struct import pack, unpack @@ -84,7 +83,7 @@ class MachMsg(): return header def read_msg_content(self, addr, size): - logging.debug("0x{:X}, {}".format(addr, size)) + self.ql.log.debug("0x{:X}, {}".format(addr, size)) return self.ql.mem.read(addr, size) @@ -127,10 +126,10 @@ class MachPortManager(): out_msg = self.ql.os.macho_task_server.get_special_port(msg.header, msg.content) out_msg.write_msg_to_mem(addr) else: - logging.info("Error Mach Msgid {} can not handled".format(msg.header.msgh_id)) + self.ql.log.info("Error Mach Msgid {} can not handled".format(msg.header.msgh_id)) raise Exception("Mach Msgid Not Found") - logging.debug("Reply-> Header: {}, Content: {}".format(out_msg.header, out_msg.content)) + self.ql.log.debug("Reply-> Header: {}, Content: {}".format(out_msg.header, out_msg.content)) def get_thread_port(self, MachoThread): return MachoThread.port.name diff --git a/qiling/os/macos/macos.py b/qiling/os/macos/macos.py index d84b9018..407d9af5 100644 --- a/qiling/os/macos/macos.py +++ b/qiling/os/macos/macos.py @@ -3,12 +3,13 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging, traceback +import traceback from unicorn import * from unicorn.x86_const import * from unicorn.arm64_const import * + from qiling.arch.x86 import * from qiling.const import * from qiling.os.const import * @@ -58,16 +59,16 @@ class QlOsMacos(QlOsPosix): self.savedrip=0xffffff8000a163bd self.ql.run(begin=self.ql.loader.kext_alloc) self.kext_object = self.ql.reg.rax - logging.debug("[+] Created kext object at 0x%x" % self.kext_object) + self.ql.log.debug("[+] Created kext object at 0x%x" % self.kext_object) self.ql.reg.rdi = self.kext_object self.ql.reg.rsi = 0 # NULL option self.savedrip=0xffffff8000a16020 self.ql.run(begin=self.ql.loader.kext_init) if self.ql.reg.rax == 0: - logging.debug("[!] Failed to initialize kext object") + self.ql.log.debug("[!] Failed to initialize kext object") return - logging.debug("[+] Initialized kext object") + self.ql.log.debug("[+] Initialized kext object") self.ql.reg.rdi = self.kext_object # FIXME Determine provider for kext @@ -75,9 +76,9 @@ class QlOsMacos(QlOsPosix): self.savedrip=0xffffff8000a16102 self.ql.run(begin=self.ql.loader.kext_attach) if self.ql.reg.rax == 0: - logging.debug("[!] Failed to attach kext object") + self.ql.log.debug("[!] Failed to attach kext object") return - logging.debug("[+] Attached kext object 1st time") + self.ql.log.debug("[+] Attached kext object 1st time") self.ql.reg.rdi = self.kext_object self.ql.reg.rdi = 0 @@ -88,14 +89,14 @@ class QlOsMacos(QlOsPosix): self.savedrip=0xffffff8000a16184 self.ql.run(begin=self.ql.loader.kext_probe) self.heap.free(tmp) - logging.debug("[+] Probed kext object") + self.ql.log.debug("[+] Probed kext object") self.ql.reg.rdi = self.kext_object # FIXME Determine provider for kext self.ql.reg.rsi = 0 # ? self.savedrip=0xffffff8000a16198 self.ql.run(begin=self.ql.loader.kext_detach) - logging.debug("[+] Detached kext object") + self.ql.log.debug("[+] Detached kext object") self.ql.reg.rdi = self.kext_object # FIXME Determine provider for kext @@ -103,9 +104,9 @@ class QlOsMacos(QlOsPosix): self.savedrip=0xffffff8000a168a3 self.ql.run(begin=self.ql.loader.kext_attach) if self.ql.reg.rax == 0: - logging.debug("[!] Failed to attach kext object") + self.ql.log.debug("[!] Failed to attach kext object") return - logging.debug("[+] Attached kext object 2nd time") + self.ql.log.debug("[+] Attached kext object 2nd time") self.ql.reg.rdi = self.kext_object # FIXME Determine provider for kext @@ -115,7 +116,7 @@ class QlOsMacos(QlOsPosix): else: from qiling.os.macos.structs import kmod_info_t, POINTER64 kmod_info_addr = self.heap.alloc(ctypes.sizeof(kmod_info_t)) - logging.debug("[+] Created fake kmod_info at 0x%x" % kmod_info_addr) + self.ql.log.debug("[+] Created fake kmod_info at 0x%x" % kmod_info_addr) kmod_info = kmod_info_t(self.ql, kmod_info_addr) # OSKext.cpp:562 @@ -133,7 +134,7 @@ class QlOsMacos(QlOsPosix): kmod_info.stop = POINTER64(self.ql.loader.kext_stop) kmod_info.updateToMem() - logging.debug("[+] Initialized kmod_info") + self.ql.log.debug("[+] Initialized kmod_info") self.ql.reg.rdi = kmod_info_addr self.ql.reg.rsi = 0 @@ -162,7 +163,7 @@ class QlOsMacos(QlOsPosix): def hook_sigtrap(self, intno= None, int = None): - logging.info("[!] Trap Found") + self.ql.log.info("[!] Trap Found") self.emu_error() exit(1) diff --git a/qiling/os/macos/subsystems.py b/qiling/os/macos/subsystems.py index 95cf0458..e7969c2c 100644 --- a/qiling/os/macos/subsystems.py +++ b/qiling/os/macos/subsystems.py @@ -10,8 +10,6 @@ # TODO: finish the servers # find Release source code in https://github.com/doadam/xnu-4570.1.46/master/BUILD/obj/RELEASE_X86_64/osfmk/RELEASE/mach/mach_host_server.c -import logging - from struct import pack, unpack from qiling.const import * @@ -32,7 +30,7 @@ class MachHostServer(): # parse request out_msg = MachMsg(self.ql) if len(in_content) < 16: - logging.debug("Error in Host info SubSystem -hostinfo()") + self.ql.log.debug("Error in Host info SubSystem -hostinfo()") raise ndr = unpack(" bufferSize: - logging.debug("Length error") + ql.log.debug("Length error") return 1 else: @@ -72,7 +72,7 @@ def ql_syscall_fgetattrlist(ql, fd, alist, attributeBuffer, bufferSize, options, def ql_syscall_poll(ql, target, address, size, *args, **kw): - logging.info("pool()") + ql.log.info("pool()") return KERN_SUCCESS @@ -82,24 +82,24 @@ def ql_syscall_poll(ql, target, address, size, *args, **kw): # 0xa def ql_syscall_kernelrpc_mach_vm_allocate_trap(ql, port, addr, size, flags, *args, **kw): - logging.debug("[+] [mach] mach vm allocate trap(port: 0x%x, addr: 0x%x, size: 0x%x, flags: 0x%x" % (port, addr, size, flags)) + ql.log.debug("[+] [mach] mach vm allocate trap(port: 0x%x, addr: 0x%x, size: 0x%x, flags: 0x%x" % (port, addr, size, flags)) mmap_address = ql.os.macho_task.min_offset mmap_end = page_align_end(mmap_address + size, PAGE_SIZE) ql.mem.map(mmap_address, mmap_end - mmap_address) ql.mem.write(mmap_address, b'\x00'*(mmap_end - mmap_address)) ql.os.macho_task.min_offset = mmap_end - logging.debug("[+] vm alloc form 0x%x to 0x%0x" % (mmap_address, mmap_end)) + ql.log.debug("[+] vm alloc form 0x%x to 0x%0x" % (mmap_address, mmap_end)) ql.mem.write(addr, struct.pack(" Header: %s, Content: %s" % (mach_msg.header, mach_msg.content)) + ql.log.debug("[+] Recv-> Header: %s, Content: %s" % (mach_msg.header, mach_msg.content)) ql.os.macho_port_manager.deal_with_msg(mach_msg, args) return 0 @@ -175,8 +175,8 @@ def ql_syscall_mach_msg_trap(ql, args, opt, ssize, rsize, rname, timeout): # 0x21 def ql_syscall_access_macos(ql, path, flags, *args, **kw): path_str = macho_read_string(ql, path, MAX_PATH_SIZE) - logging.info("access(%s, 0x%x)" % (path_str, flags)) - logging.debug("[+] access(path: %s, flags: 0x%x)" % (path_str, flags)) + ql.log.info("access(%s, 0x%x)" % (path_str, flags)) + ql.log.debug("[+] access(path: %s, flags: 0x%x)" % (path_str, flags)) if not ql.os.macho_fs.isexists(path_str): return ENOENT else: @@ -184,7 +184,7 @@ def ql_syscall_access_macos(ql, path, flags, *args, **kw): # 0x30 def ql_syscall_sigprocmask(ql, how, mask, omask, *args, **kw): - logging.info("sigprocmask(how: 0x%x, mask: 0x%x, omask: 0x%x)" % (how, mask, omask)) + ql.log.info("sigprocmask(how: 0x%x, mask: 0x%x, omask: 0x%x)" % (how, mask, omask)) # 0x5c def ql_syscall_fcntl64_macos(ql, fcntl_fd, fcntl_cmd, fcntl_arg, *args, **kw): @@ -203,12 +203,12 @@ def ql_syscall_fcntl64_macos(ql, fcntl_fd, fcntl_cmd, fcntl_arg, *args, **kw): else: regreturn = 0 - logging.info("fcntl64(fd: %d, cmd: %d, arg: 0x%x) = %d" % (fcntl_fd, fcntl_cmd, fcntl_arg, regreturn)) + ql.log.info("fcntl64(fd: %d, cmd: %d, arg: 0x%x) = %d" % (fcntl_fd, fcntl_cmd, fcntl_arg, regreturn)) return regreturn # 0x99 def ql_syscall_pread(ql, fd, buf, nbyte, offset, *args, **kw): - logging.info("pread(fd: 0x%x, buf: 0x%x, nbyte: 0x%x, offset: 0x%x)" % ( + ql.log.info("pread(fd: 0x%x, buf: 0x%x, nbyte: 0x%x, offset: 0x%x)" % ( fd, buf, nbyte, offset )) if fd >= 0 and fd <= MAX_FD_SIZE: @@ -222,18 +222,18 @@ def ql_syscall_pread(ql, fd, buf, nbyte, offset, *args, **kw): def ql_syscall_csops(ql, pid, ops, useraddr, usersize, *args, **kw): flag = struct.pack(" bufferSize: - logging.debug("Length error") + ql.log.debug("Length error") return 1 else: ql.mem.write(attributeBuffer, attr) @@ -276,8 +276,8 @@ def ql_syscall_getattrlist(ql, path, alist, attributeBuffer, bufferSize, options # rlim_t rlim_max; /* maximum value for rlim_cur */ uint64 # }; def ql_syscall_getrlimit(ql, which, rlp, *args, **kw): - logging.info("getrlimit(0x%x, 0x%x)" % (which, rlp)) - logging.debug("[+] getrlimit(which:0x%x, rlp:0x%x)" % (which, rlp)) + ql.log.info("getrlimit(0x%x, 0x%x)" % (which, rlp)) + ql.log.debug("[+] getrlimit(which:0x%x, rlp:0x%x)" % (which, rlp)) _RLIMIT_POSIX_FLAG = 0x1000 RLIM_NLIMITS = 9 which = which & _RLIMIT_POSIX_FLAG @@ -315,12 +315,12 @@ def ql_syscall_mmap2_macos(ql, mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags mmap_base = ql.loader.mmap_address ql.loader.mmap_address = mmap_base + ((mmap2_length + 0x1000 - 1) // 0x1000) * 0x1000 - logging.debug("[+] log mmap - mmap2(0x%x, %d, 0x%x, 0x%x, %d, %d)" % (mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags, mmap2_fd, mmap2_pgoffset)) - logging.debug("[+] log mmap - return addr : " + hex(mmap_base)) - logging.debug("[+] log mmap - addr range : " + hex(mmap_base) + ' - ' + hex(mmap_base + ((mmap2_length + 0x1000 - 1) // 0x1000) * 0x1000)) + ql.log.debug("[+] log mmap - mmap2(0x%x, %d, 0x%x, 0x%x, %d, %d)" % (mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags, mmap2_fd, mmap2_pgoffset)) + ql.log.debug("[+] log mmap - return addr : " + hex(mmap_base)) + ql.log.debug("[+] log mmap - addr range : " + hex(mmap_base) + ' - ' + hex(mmap_base + ((mmap2_length + 0x1000 - 1) // 0x1000) * 0x1000)) if need_mmap: - logging.debug("[+] log mmap - mapping needed") + ql.log.debug("[+] log mmap - mapping needed") try: ql.mem.map(mmap_base, ((mmap2_length + 0x1000 - 1) // 0x1000) * 0x1000) except: @@ -332,32 +332,32 @@ def ql_syscall_mmap2_macos(ql, mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags ql.os.fd[mmap2_fd].lseek(mmap2_pgoffset) data = ql.os.fd[mmap2_fd].read(mmap2_length) - logging.debug("[+] log mem wirte : " + hex(len(data))) - logging.debug("[+] log mem mmap : " + str(ql.os.fd[mmap2_fd].name)) + ql.log.debug("[+] log mem wirte : " + hex(len(data))) + ql.log.debug("[+] log mem mmap : " + str(ql.os.fd[mmap2_fd].name)) ql.mem.write(mmap_base, data) mem_info = ql.os.fd[mmap2_fd].name - logging.info("mmap2(0x%x, %d, 0x%x, 0x%x, %d, %d) = 0x%x" % (mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags, mmap2_fd, mmap2_pgoffset, mmap_base)) + ql.log.info("mmap2(0x%x, %d, 0x%x, 0x%x, %d, %d) = 0x%x" % (mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags, mmap2_fd, mmap2_pgoffset, mmap_base)) regreturn = mmap_base - logging.debug("[+] mmap_base is 0x%x" % regreturn) + ql.log.debug("[+] mmap_base is 0x%x" % regreturn) return regreturn # 0xca def ql_syscall_sysctl(ql, name, namelen, old, oldlenp, new_arg, newlen): - logging.info("sysctl(name: 0x%x, namelen: 0x%x, old: 0x%x, oldlenp: 0x%x, new: 0x%x, newlen: 0x%x)" % ( + ql.log.info("sysctl(name: 0x%x, namelen: 0x%x, old: 0x%x, oldlenp: 0x%x, new: 0x%x, newlen: 0x%x)" % ( name, namelen, old, oldlenp, new_arg, newlen )) return KERN_SUCCESS # 0x112 def ql_syscall_sysctlbyname(ql, name, namelen, old, oldlenp, new_arg, newlen): - logging.info("sysctlbyname(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % ( + ql.log.info("sysctlbyname(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % ( name, namelen, old, oldlenp, new_arg, newlen )) - logging.debug("[+] sysctlbyname(name: 0x%x, namelen: 0x%x, old: 0x%x, oldlenp: 0x%x, new: 0x%x, newlen: 0x%x)" % ( + ql.log.debug("[+] sysctlbyname(name: 0x%x, namelen: 0x%x, old: 0x%x, oldlenp: 0x%x, new: 0x%x, newlen: 0x%x)" % ( name, namelen, old, oldlenp, new_arg, newlen )) return KERN_SUCCESS @@ -365,17 +365,17 @@ def ql_syscall_sysctlbyname(ql, name, namelen, old, oldlenp, new_arg, newlen): # 0x126 # check shared region if avalible , return not ready every time def ql_syscall_shared_region_check_np(ql, p, uap, retvalp, *args, **kw): - logging.info("shared_region_check_np(0x%x, 0x%x, 0x%x) = 0x%x" % (p, uap, retvalp, EINVAL)) - logging.debug("[+] shared_region_check_np(p: 0x%x, uap: 0x%x, retvalp: 0x%x) = 0x%x" % (p, uap, retvalp, EINVAL)) + ql.log.info("shared_region_check_np(0x%x, 0x%x, 0x%x) = 0x%x" % (p, uap, retvalp, EINVAL)) + ql.log.debug("[+] shared_region_check_np(p: 0x%x, uap: 0x%x, retvalp: 0x%x) = 0x%x" % (p, uap, retvalp, EINVAL)) return EINVAL # 0x150 def ql_syscall_proc_info(ql, callnum, pid, flavor, arg, buff, buffer_size): retval = struct.unpack("= 0 and regreturn != 2: - logging.debug("[+] File Found: %s" % relative_path) + ql.log.debug("[+] File Found: %s" % relative_path) else: - logging.debug("[!] File Not Found %s" % relative_path) + ql.log.debug("[!] File Not Found %s" % relative_path) return regreturn # 0x1b6 def ql_syscall_shared_region_map_and_slide_np(ql, fd, count, mappings_addr, slide, slide_start, slide_size): - logging.info("shared_region_map_and_slide_np(%d, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % ( + ql.log.info("shared_region_map_and_slide_np(%d, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % ( fd, count ,mappings_addr, slide, slide_start, slide_size )) - logging.debug("[+] shared_region_map_and_slide_np(fd: %d, count: 0x%x, mappings: 0x%x, slide: 0x%x, slide_start: 0x%x, slide_size: 0x%x)" % ( + ql.log.debug("[+] shared_region_map_and_slide_np(fd: %d, count: 0x%x, mappings: 0x%x, slide: 0x%x, slide_start: 0x%x, slide_size: 0x%x)" % ( fd, count ,mappings_addr, slide, slide_start, slide_size )) mapping_list = [] @@ -597,22 +597,22 @@ def ql_syscall_shared_region_map_and_slide_np(ql, fd, count, mappings_addr, slid # 0x1e3 def ql_syscall_csrctl(ql, op, useraddr, usersize, *args, **kw): - logging.info("csrctl(0x%x, 0x%x, 0x%x)" % (op, useraddr, usersize)) - logging.debug("csrctl(op: 0x%x, useraddr :0x%x, usersize: 0x%x)" % (op, useraddr, usersize)) + ql.log.info("csrctl(0x%x, 0x%x, 0x%x)" % (op, useraddr, usersize)) + ql.log.debug("csrctl(op: 0x%x, useraddr :0x%x, usersize: 0x%x)" % (op, useraddr, usersize)) return 1 # 0x1f4 def ql_syscall_getentropy(ql, buffer, size, *args, **kw): - logging.info("getentropy(0x%x, 0x%x)" % (buffer, size)) - logging.debug("[+] getentropy(buffer: 0x%x, size: 0x%x)" % (buffer, size)) + ql.log.info("getentropy(0x%x, 0x%x)" % (buffer, size)) + ql.log.debug("[+] getentropy(buffer: 0x%x, size: 0x%x)" % (buffer, size)) return KERN_SUCCESS # 0x208 def ql_syscall_terminate_with_payload(ql, pid, reason_namespace, reason_code, payload, payload_size, reason_string): - logging.info("terminate_with_payload(%d, 0x%x, 0x%x, 0x%x 0x%x, 0x%x)" % ( + ql.log.info("terminate_with_payload(%d, 0x%x, 0x%x, 0x%x 0x%x, 0x%x)" % ( pid, reason_namespace, reason_code,payload, payload_size, reason_string)) - logging.debug("[+] terminate_with_payload(pid: %d, reason_namespace: 0x%x, reason_code: 0x%x, payload: 0x%x \ + ql.log.debug("[+] terminate_with_payload(pid: %d, reason_namespace: 0x%x, reason_code: 0x%x, payload: 0x%x \ payload_size: 0x%x, reason_string: 0x%x)" % (pid, reason_namespace, reason_code, payload, payload_size, reason_string)) ql.emu_stop() @@ -621,10 +621,10 @@ def ql_syscall_terminate_with_payload(ql, pid, reason_namespace, reason_code, pa # 0x209 def ql_syscall_abort_with_payload(ql, reason_namespace, reason_code, payload, payload_size, reason_string, reason_flags): - logging.info("abort_with_payload(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % ( + ql.log.info("abort_with_payload(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % ( reason_namespace, reason_code, payload, payload_size, reason_string, reason_flags)) - logging.debug("[+] abort_with_payload(reason_namespace: 0x%x, reason_code: 0x%x, payload: 0x%x, payload_size: 0x%x, reason_string: 0x%x,\ + ql.log.debug("[+] abort_with_payload(reason_namespace: 0x%x, reason_code: 0x%x, payload: 0x%x, payload_size: 0x%x, reason_string: 0x%x,\ reason_flags: 0x%x)" % (reason_namespace, reason_code, payload, payload_size, reason_string, reason_flags)) return KERN_SUCCESS @@ -637,6 +637,6 @@ def ql_syscall_abort_with_payload(ql, reason_namespace, reason_code, payload, pa # 0x3d # thread_set_tsd_base def ql_syscall_thread_fast_set_cthread_self64(ql, u_info_addr, *args, **kw): - logging.debug("[+] [mdep] thread fast set cthread self64(tsd_base:0x%x)" % (u_info_addr)) + ql.log.debug("[+] [mdep] thread fast set cthread self64(tsd_base:0x%x)" % (u_info_addr)) ql.reg.msr(GSMSR, u_info_addr) return KERN_SUCCESS diff --git a/qiling/os/macos/utils.py b/qiling/os/macos/utils.py index 052d013b..083cf76d 100644 --- a/qiling/os/macos/utils.py +++ b/qiling/os/macos/utils.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import ctypes, os, struct, logging +import ctypes, os, struct from unicorn.x86_const import * from unicorn.arm_const import * @@ -17,43 +17,43 @@ def IOConnectCallMethod(ql, selector, output_array, output_cnt, output_struct, output_struct_size): if ql.os.IOKit is not True: - logging.info("[!] Must have a IOKit driver") + ql.log.info("[!] Must have a IOKit driver") return output_array, output_struct args_addr = ql.os.heap.alloc(ctypes.sizeof(IOExternalMethodArguments)) - logging.debug("[+] Created IOExternalMethodArguments object at 0x%x" % args_addr) + ql.log.debug("[+] Created IOExternalMethodArguments object at 0x%x" % args_addr) args_obj = IOExternalMethodArguments(ql, args_addr) if input_array is not None and input_cnt != 0: input_array_addr = ql.os.heap.alloc(input_cnt) ql.mem.write(input_array_addr, b''.join(struct.pack(" bytearray: @@ -187,8 +188,8 @@ class QlMemoryManager: self.ql.uc.mem_write(addr, data) except: self.show_mapinfo() - logging.debug("addresss write length: " + str(len(data))) - logging.error("addresss write error: " + hex(addr)) + self.ql.log.debug("addresss write length: " + str(len(data))) + self.ql.log.error("addresss write error: " + hex(addr)) raise def search(self, needle: bytes, begin= None, end= None): @@ -400,7 +401,7 @@ class QlMemoryManager: def get_mapped(self): for idx, val in enumerate(self.ql.uc.mem_regions()): - logging.info(idx, list(map(hex, val))) + self.ql.log.info(idx, list(map(hex, val))) # A Simple Heap Implementation class Chunk(): @@ -475,7 +476,7 @@ class QlMemoryHeap: self.chunks.append(chunk) chunk.inuse = True - #logging.debug("heap.alloc addresss: " + hex(chunk.address)) + #ql.log.debug("heap.alloc addresss: " + hex(chunk.address)) return chunk.address def size(self, addr): diff --git a/qiling/os/os.py b/qiling/os/os.py index 03132973..09e91dc9 100644 --- a/qiling/os/os.py +++ b/qiling/os/os.py @@ -3,9 +3,10 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import sys, logging +import sys from typing import Callable, Sequence, Mapping, MutableMapping, Any + from .const import * from .filestruct import ql_file from .mapper import QlFsMapper @@ -161,32 +162,32 @@ class QlOs(QlOsUtils): return image def emu_error(self): - logging.error("\n") + self.ql.log.error("\n") for reg in self.ql.reg.register_mapping: if isinstance(reg, str): REG_NAME = reg REG_VAL = self.ql.reg.read(reg) - logging.error("%s\t:\t 0x%x" % (REG_NAME, REG_VAL)) + self.ql.log.error("%s\t:\t 0x%x" % (REG_NAME, REG_VAL)) - logging.error("\n") - logging.error("PC = 0x%x" % (self.ql.reg.arch_pc)) + self.ql.log.error("\n") + self.ql.log.error("PC = 0x%x" % (self.ql.reg.arch_pc)) containing_image = self.find_containing_image(self.ql.reg.arch_pc) if containing_image: offset = self.ql.reg.arch_pc - containing_image.base - logging.error(" (%s+0x%x)" % (containing_image.path, offset)) + self.ql.log.error(" (%s+0x%x)" % (containing_image.path, offset)) else: - logging.info("\n") + self.ql.log.info("\n") self.ql.mem.show_mapinfo() try: buf = self.ql.mem.read(self.ql.reg.arch_pc, 8) - logging.error("%r" % ([hex(_) for _ in buf])) + self.ql.log.error("%r" % ([hex(_) for _ in buf])) - logging.info("\n") + self.ql.log.info("\n") self.disassembler(self.ql, self.ql.reg.arch_pc, 64) except: - logging.error("Error: PC(0x%x) Unreachable" % self.ql.reg.arch_pc) + self.ql.log.error("Error: PC(0x%x) Unreachable" % self.ql.reg.arch_pc) def set_function_args(self, args: Sequence[int]) -> None: """Set function call arguments. diff --git a/qiling/os/posix/posix.py b/qiling/os/posix/posix.py index 8c9d81d4..dcfcf222 100644 --- a/qiling/os/posix/posix.py +++ b/qiling/os/posix/posix.py @@ -3,8 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -# For syscall_num -import logging + from unicorn.arm64_const import * from unicorn.arm_const import * @@ -180,11 +179,11 @@ class QlOsPosix(QlOs): except KeyboardInterrupt: raise except Exception as e: - logging.exception("") - logging.info("[!] Syscall ERROR: %s DEBUG: %s" % (self.syscall_name, e)) + self.ql.log.exception("") + self.ql.log.info("[!] Syscall ERROR: %s DEBUG: %s" % (self.syscall_name, e)) raise e else: - logging.warning( + self.ql.log.warning( "[!] 0x%x: syscall %s number = 0x%x(%d) not implemented" % (self.ql.reg.arch_pc, syscall_name_str, self.syscall, self.syscall)) if self.ql.debug_stop: raise QlErrorSyscallNotFound("[!] Syscall Not Found") diff --git a/qiling/os/posix/syscall/fcntl.py b/qiling/os/posix/syscall/fcntl.py index 665a47a3..bb175843 100644 --- a/qiling/os/posix/syscall/fcntl.py +++ b/qiling/os/posix/syscall/fcntl.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -41,13 +41,13 @@ def ql_syscall_open(ql, filename, flags, mode, *args, **kw): except QlSyscallError as e: regreturn = - e.errno - logging.info("open(%s, 0x%x, 0o%o) = %d" % (relative_path, flags, mode, regreturn)) - logging.debug("[+] open(%s, %s, 0o%o) = %d" % (relative_path, open_flags_mapping(flags, ql.archtype), mode, regreturn)) + ql.log.info("open(%s, 0x%x, 0o%o) = %d" % (relative_path, flags, mode, regreturn)) + ql.log.debug("[+] open(%s, %s, 0o%o) = %d" % (relative_path, open_flags_mapping(flags, ql.archtype), mode, regreturn)) if regreturn >= 0 and regreturn != 2: - logging.debug("[+] File Found: %s" % real_path) + ql.log.debug("[+] File Found: %s" % real_path) else: - logging.debug("[!] File Not Found %s" % real_path) + ql.log.debug("[!] File Not Found %s" % real_path) return regreturn @@ -81,14 +81,14 @@ def ql_syscall_openat(ql, openat_fd, openat_path, openat_flags, openat_mode, *ar except QlSyscallError: regreturn = -1 - logging.info("openat(%d, %s, 0x%x, 0o%o) = %d" % (openat_fd, relative_path, openat_flags, openat_mode, regreturn)) - logging.debug("[+] openat(%d, %s, %s, 0o%o) = %d" % ( + ql.log.info("openat(%d, %s, 0x%x, 0o%o) = %d" % (openat_fd, relative_path, openat_flags, openat_mode, regreturn)) + ql.log.debug("[+] openat(%d, %s, %s, 0o%o) = %d" % ( openat_fd, relative_path, open_flags_mapping(openat_flags, ql.archtype), openat_mode, regreturn)) if regreturn >= 0 and regreturn != 2: - logging.debug("[+] File Found: %s" % real_path) + ql.log.debug("[+] File Found: %s" % real_path) else: - logging.debug("[!] File Not Found %s" % real_path) + ql.log.debug("[!] File Not Found %s" % real_path) return regreturn @@ -104,7 +104,7 @@ def ql_syscall_fcntl(ql, fcntl_fd, fcntl_cmd, *args, **kw): elif fcntl_cmd == F_SETFL: regreturn = 0 - logging.info("fcntl(%d, %d) = %d" % (fcntl_fd, fcntl_cmd, regreturn)) + ql.log.info("fcntl(%d, %d) = %d" % (fcntl_fd, fcntl_cmd, regreturn)) return regreturn @@ -128,12 +128,12 @@ def ql_syscall_fcntl64(ql, fcntl_fd, fcntl_cmd, fcntl_arg, *args, **kw): else: regreturn = 0 - logging.info("fcntl64(%d, %d, %d) = %d" % (fcntl_fd, fcntl_cmd, fcntl_arg, regreturn)) + ql.log.info("fcntl64(%d, %d, %d) = %d" % (fcntl_fd, fcntl_cmd, fcntl_arg, regreturn)) return regreturn def ql_syscall_flock(ql, flock_fd, flock_operation, *args, **kw): # Should always return 0, we don't need a actual file lock regreturn = 0 - logging.info("flock(%d) = %d" % (flock_operation, regreturn)) + ql.log.info("flock(%d) = %d" % (flock_operation, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/futex.py b/qiling/os/posix/syscall/futex.py index cd7da3f7..688fa358 100644 --- a/qiling/os/posix/syscall/futex.py +++ b/qiling/os/posix/syscall/futex.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -17,7 +17,7 @@ def ql_syscall_set_robust_list(ql, set_robust_list_head_ptr, set_robust_list_hea ql.os.thread_management.cur_thread.robust_list_head_ptr = set_robust_list_head_ptr ql.os.thread_management.cur_thread.robust_list_head_len = set_robust_list_head_len regreturn = 0 - logging.info("set_robust_list(%x, %x) = %d"%(set_robust_list_head_ptr, set_robust_list_head_len, regreturn)) + ql.log.info("set_robust_list(%x, %x) = %d"%(set_robust_list_head_ptr, set_robust_list_head_len, regreturn)) return regreturn @@ -47,13 +47,13 @@ def ql_syscall_futex(ql, futex_uaddr, futex_op, futex_val, futex_timeout, futex_ regreturn = ql.os.futexm.futex_wait(ql, futex_uaddr, ql.os.thread_management.cur_thread, futex_val) - logging.info("futex(%x, %d, %d, %x) = %d" % (futex_uaddr, futex_op, futex_val, futex_timeout, regreturn)) + ql.log.info("futex(%x, %d, %d, %x) = %d" % (futex_uaddr, futex_op, futex_val, futex_timeout, regreturn)) elif futex_op & (FUTEX_PRIVATE_FLAG - 1) == FUTEX_WAIT_BITSET: regreturn = ql.os.futexm.futex_wait(ql, futex_uaddr, ql.os.thread_management.cur_thread, futex_val, futex_val3) - logging.info("futex(%x, %d, %d, %x, %x, %x) = %d" % (futex_uaddr, + ql.log.info("futex(%x, %d, %d, %x, %x, %x) = %d" % (futex_uaddr, futex_op, futex_val, futex_timeout, futex_uaddr2, @@ -61,12 +61,12 @@ def ql_syscall_futex(ql, futex_uaddr, futex_op, futex_val, futex_timeout, futex_ regreturn)) elif futex_op & (FUTEX_PRIVATE_FLAG - 1) == FUTEX_WAKE: regreturn = ql.os.futexm.futex_wake(ql, futex_uaddr,ql.os.thread_management.cur_thread, futex_val) - logging.info("futex(%x, %d, %d) = %d" % (futex_uaddr, futex_op, futex_val, regreturn)) + ql.log.info("futex(%x, %d, %d) = %d" % (futex_uaddr, futex_op, futex_val, regreturn)) elif futex_op & (FUTEX_PRIVATE_FLAG - 1) == FUTEX_WAKE_BITSET: regreturn = ql.os.futexm.futex_wake(ql, futex_uaddr,ql.os.thread_management.cur_thread, futex_val, futex_val3) - logging.info("futex(%x, %d, %d) = %d" % (futex_uaddr, futex_op, futex_val, regreturn)) + ql.log.info("futex(%x, %d, %d) = %d" % (futex_uaddr, futex_op, futex_val, regreturn)) else: - logging.info("futex(%x, %d, %d) = ?" % (futex_uaddr, futex_op, futex_val)) + ql.log.info("futex(%x, %d, %d) = ?" % (futex_uaddr, futex_op, futex_val)) ql.emu_stop() #ql.os.thread_management.cur_thread.stop() #ql.os.thread_management.cur_thread.stop_event = THREAD_EVENT_EXIT_GROUP_EVENT diff --git a/qiling/os/posix/syscall/ioctl.py b/qiling/os/posix/syscall/ioctl.py index 29ba2554..20c93b42 100644 --- a/qiling/os/posix/syscall/ioctl.py +++ b/qiling/os/posix/syscall/ioctl.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -81,7 +81,7 @@ def ql_syscall_ioctl(ql, ioctl_fd, ioctl_cmd, ioctl_arg, *args, **kw): if isinstance(ql.os.fd[ioctl_fd], ql_socket) and (ioctl_cmd == SIOCGIFADDR or ioctl_cmd == SIOCGIFNETMASK): try: tmp_arg = ql.mem.read(ioctl_arg, 64) - logging.debug("[+] query network card : %s" % tmp_arg) + ql.log.debug("[+] query network card : %s" % tmp_arg) data = ql.os.fd[ioctl_fd].ioctl(ioctl_cmd, bytes(tmp_arg)) ql.mem.write(ioctl_arg, data) regreturn = 0 @@ -102,5 +102,5 @@ def ql_syscall_ioctl(ql, ioctl_fd, ioctl_cmd, ioctl_arg, *args, **kw): except : regreturn = -1 - logging.info("ioctl(0x%x, 0x%x, 0x%x) = %d" % (ioctl_fd, ioctl_cmd, ioctl_arg, regreturn)) + ql.log.info("ioctl(0x%x, 0x%x, 0x%x) = %d" % (ioctl_fd, ioctl_cmd, ioctl_arg, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/mman.py b/qiling/os/posix/syscall/mman.py index 18536e77..e6ede8ec 100644 --- a/qiling/os/posix/syscall/mman.py +++ b/qiling/os/posix/syscall/mman.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from unicorn import ( UC_PROT_ALL, UC_PROT_EXEC, @@ -39,20 +39,20 @@ def ql_syscall_munmap(ql, munmap_addr , munmap_len, *args, **kw): ql.mem.unmap(munmap_addr, munmap_len) regreturn = 0 - logging.info("munmap(0x%x, 0x%x) = %d" % (munmap_addr , munmap_len, regreturn)) + ql.log.info("munmap(0x%x, 0x%x) = %d" % (munmap_addr , munmap_len, regreturn)) return regreturn def ql_syscall_madvise(ql, *args, **kw): regreturn = 0 - logging.info("madvise() = %d" % regreturn) + ql.log.info("madvise() = %d" % regreturn) return regreturn def ql_syscall_mprotect(ql, mprotect_start, mprotect_len, mprotect_prot, *args, **kw): regreturn = 0 - logging.info("mprotect(0x%x, 0x%x, 0x%x) = %d" % (mprotect_start, mprotect_len, mprotect_prot, regreturn)) - logging.debug("[+] mprotect(0x%x, 0x%x, %s) = %d" % ( + ql.log.info("mprotect(0x%x, 0x%x, 0x%x) = %d" % (mprotect_start, mprotect_len, mprotect_prot, regreturn)) + ql.log.debug("[+] mprotect(0x%x, 0x%x, %s) = %d" % ( mprotect_start, mprotect_len, mmap_prot_mapping(mprotect_prot), regreturn)) return regreturn @@ -66,9 +66,9 @@ def ql_syscall_old_mmap(ql, struct_mmap_args, *args, **kw): _struct.append(int.from_bytes(data, 'little')) mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd, mmap_offset = _struct - logging.debug("[+] log old_mmap - old_mmap(0x%x, 0x%x, 0x%x, 0x%x, %d, %d)" % ( + ql.log.debug("[+] log old_mmap - old_mmap(0x%x, 0x%x, 0x%x, 0x%x, %d, %d)" % ( mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd, mmap_offset)) - logging.debug("[+] log old_mmap - old_mmap(0x%x, 0x%x, %s, %s, %d, %d)" % ( + ql.log.debug("[+] log old_mmap - old_mmap(0x%x, 0x%x, %s, %s, %d, %d)" % ( mmap_addr, mmap_length, mmap_prot_mapping(mmap_prot), mmap_flag_mapping(mmap_flags), mmap_fd, mmap_offset)) # FIXME @@ -97,13 +97,13 @@ def ql_syscall_old_mmap(ql, struct_mmap_args, *args, **kw): elif ql.mem.is_mapped(mmap_addr, mmap_length): need_mmap = False - logging.debug("[+] log old_mmap - return addr : " + hex(mmap_base)) - logging.debug("[+] log old_mmap - addr range : " + hex(mmap_base) + ' - ' + hex( + ql.log.debug("[+] log old_mmap - return addr : " + hex(mmap_base)) + ql.log.debug("[+] log old_mmap - addr range : " + hex(mmap_base) + ' - ' + hex( mmap_base + ((mmap_length + 0x1000 - 1) // 0x1000) * 0x1000)) # initialized mapping if need_mmap: - logging.debug("[+] log old_mmap - mapping needed") + ql.log.debug("[+] log old_mmap - mapping needed") try: ql.mem.map(mmap_base, ((mmap_length + 0x1000 - 1) // 0x1000) * 0x1000, info="[syscall_old_mmap]") except: @@ -119,23 +119,23 @@ def ql_syscall_old_mmap(ql, struct_mmap_args, *args, **kw): ql.os.fd[mmap_fd]._is_map_shared = True ql.os.fd[mmap_fd]._mapped_offset = mmap_offset - logging.debug("[+] log mem wirte : " + hex(len(data))) - logging.debug("[+] log mem mmap : " + mem_info) + ql.log.debug("[+] log mem wirte : " + hex(len(data))) + ql.log.debug("[+] log mem mmap : " + mem_info) ql.mem.add_mapinfo(mmap_base, mmap_base + (((mmap_length + 0x1000 - 1) // 0x1000) * 0x1000), mem_p = UC_PROT_ALL, mem_info = "[old_mmap] " + mem_info) ql.mem.write(mmap_base, data) - logging.info("old_mmap(0x%x, 0x%x, 0x%x, 0x%x, %d, %d) = 0x%x" % (mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd, mmap_offset, mmap_base)) + ql.log.info("old_mmap(0x%x, 0x%x, 0x%x, 0x%x, %d, %d) = 0x%x" % (mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd, mmap_offset, mmap_base)) regreturn = mmap_base - logging.debug("[+] mmap_base is 0x%x" % regreturn) + ql.log.debug("[+] mmap_base is 0x%x" % regreturn) return regreturn def ql_syscall_mmap(ql, mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd, mmap_pgoffset): - logging.debug("[+] log mmap - mmap(0x%x, 0x%x, 0x%x, 0x%x, %d, %d)" % ( + ql.log.debug("[+] log mmap - mmap(0x%x, 0x%x, 0x%x, 0x%x, %d, %d)" % ( mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd, mmap_pgoffset)) - logging.debug("[+] log mmap - mmap(0x%x, 0x%x, %s, %s, %d, %d)" % ( + ql.log.debug("[+] log mmap - mmap(0x%x, 0x%x, %s, %s, %d, %d)" % ( mmap_addr, mmap_length, mmap_prot_mapping(mmap_prot), mmap_flag_mapping(mmap_flags), mmap_fd, mmap_pgoffset)) # FIXME @@ -164,19 +164,19 @@ def ql_syscall_mmap(ql, mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd, elif ql.mem.is_mapped(mmap_addr, mmap_length): need_mmap = False - logging.debug("[+] log mmap - return addr : " + hex(mmap_base)) - logging.debug("[+] log mmap - addr range : " + hex(mmap_base) + ' - ' + hex( + ql.log.debug("[+] log mmap - return addr : " + hex(mmap_base)) + ql.log.debug("[+] log mmap - addr range : " + hex(mmap_base) + ' - ' + hex( mmap_base + ((mmap_length + 0x1000 - 1) // 0x1000) * 0x1000)) # initialized mapping if need_mmap: - logging.debug("[+] log mmap - mapping needed") + ql.log.debug("[+] log mmap - mapping needed") try: ql.mem.map(mmap_base, ((mmap_length + 0x1000 - 1) // 0x1000) * 0x1000, info="[syscall_mmap]") except: raise QlMemoryMappedError("[!] mapping needed but fail") - logging.debug("[+] mmap_base 0x%x length 0x%x" %(mmap_base, (((mmap_length + 0x1000 - 1) // 0x1000) * 0x1000))) + ql.log.debug("[+] mmap_base 0x%x length 0x%x" %(mmap_base, (((mmap_length + 0x1000 - 1) // 0x1000) * 0x1000))) # FIXME: MIPS32 Big Endian try: @@ -191,16 +191,16 @@ def ql_syscall_mmap(ql, mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd, ql.os.fd[mmap_fd]._is_map_shared = True ql.os.fd[mmap_fd]._mapped_offset = mmap_pgoffset - logging.debug("[+] log mem wirte : " + hex(len(data))) - logging.debug("[+] log mem mmap : " + mem_info) + ql.log.debug("[+] log mem wirte : " + hex(len(data))) + ql.log.debug("[+] log mem mmap : " + mem_info) ql.mem.add_mapinfo(mmap_base, mmap_base + (((mmap_length + 0x1000 - 1) // 0x1000) * 0x1000), mem_p = UC_PROT_ALL, mem_info = "[mmap] " + mem_info) ql.mem.write(mmap_base, data) - logging.info("mmap(0x%x, 0x%x, 0x%x, 0x%x, %d, %d) = 0x%x" % (mmap_addr, mmap_length, mmap_prot, mmap_flags, + ql.log.info("mmap(0x%x, 0x%x, 0x%x, 0x%x, %d, %d) = 0x%x" % (mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd, mmap_pgoffset, mmap_base)) regreturn = mmap_base - logging.debug("[+] mmap_base is 0x%x" % regreturn) + ql.log.debug("[+] mmap_base is 0x%x" % regreturn) return regreturn @@ -231,16 +231,16 @@ def ql_syscall_mmap2(ql, mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags, mmap elif mmap2_addr !=0 and ql.mem.is_mapped(mmap2_addr, mmap2_length): need_mmap = False - logging.debug("[+] log mmap2 - mmap2(0x%x, 0x%x, 0x%x, 0x%x, %d, %d)" % ( + ql.log.debug("[+] log mmap2 - mmap2(0x%x, 0x%x, 0x%x, 0x%x, %d, %d)" % ( mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags, mmap2_fd, mmap2_pgoffset)) - logging.debug("[+] log mmap2 - mmap2(0x%x, 0x%x, %s, %s, %d, %d)" % ( + ql.log.debug("[+] log mmap2 - mmap2(0x%x, 0x%x, %s, %s, %d, %d)" % ( mmap2_addr, mmap2_length, mmap_prot_mapping(mmap2_prot), mmap_flag_mapping(mmap2_flags), mmap2_fd, mmap2_pgoffset)) - logging.debug("[+] log mmap2 - return addr : " + hex(mmap_base)) - logging.debug("[+] log mmap2 - addr range : " + hex(mmap_base) + ' - ' + hex( + ql.log.debug("[+] log mmap2 - return addr : " + hex(mmap_base)) + ql.log.debug("[+] log mmap2 - addr range : " + hex(mmap_base) + ' - ' + hex( mmap_base + ((mmap2_length + 0x1000 - 1) // 0x1000) * 0x1000)) if need_mmap: - logging.debug("[+] log mmap2 - mapping needed") + ql.log.debug("[+] log mmap2 - mapping needed") try: ql.mem.map(mmap_base, ((mmap2_length + 0x1000 - 1) // 0x1000) * 0x1000, info="[syscall_mmap2]") except: @@ -256,14 +256,14 @@ def ql_syscall_mmap2(ql, mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags, mmap ql.os.fd[mmap2_fd]._is_map_shared = True ql.os.fd[mmap2_fd]._mapped_offset = mmap2_pgoffset - logging.debug("[+] log mem write : " + hex(len(data))) - logging.debug("[+] log mem mmap2 : " + mem_info) + ql.log.debug("[+] log mem write : " + hex(len(data))) + ql.log.debug("[+] log mem mmap2 : " + mem_info) ql.mem.add_mapinfo(mmap_base, mmap_base + (((mmap2_length + 0x1000 - 1) // 0x1000) * 0x1000), mem_p = UC_PROT_ALL, mem_info = "[mmap2] " + mem_info) ql.mem.write(mmap_base, data) - logging.info("mmap2(0x%x, 0x%x, 0x%x, 0x%x, %d, %d) = 0x%x" % (mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags, mmap2_fd, mmap2_pgoffset, mmap_base)) + ql.log.info("mmap2(0x%x, 0x%x, 0x%x, 0x%x, %d, %d) = 0x%x" % (mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags, mmap2_fd, mmap2_pgoffset, mmap_base)) regreturn = mmap_base - logging.debug("[+] mmap2_base is 0x%x" % regreturn) + ql.log.debug("[+] mmap2_base is 0x%x" % regreturn) return regreturn diff --git a/qiling/os/posix/syscall/net.py b/qiling/os/posix/syscall/net.py index a6c46635..30c78a3a 100644 --- a/qiling/os/posix/syscall/net.py +++ b/qiling/os/posix/syscall/net.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -36,7 +36,7 @@ def ql_syscall_socketcall(ql, socketcall_call, socketcall_args, *args, **kw): SOCKETCALL_SYS_RECVMMSG = 19 SOCKETCALL_SYS_SENDMMSG = 20 - logging.info("socketcall(%d, %x)" % (socketcall_call, socketcall_args)) + ql.log.info("socketcall(%d, %x)" % (socketcall_call, socketcall_args)) if socketcall_call == SOCKETCALL_SYS_SOCKET: socketcall_domain = ql.unpack(ql.mem.read(socketcall_args, ql.pointersize)) @@ -103,6 +103,6 @@ def ql_syscall_socketcall(ql, socketcall_call, socketcall_args, *args, **kw): return ql_syscall_setsockopt(ql) else: - logging.debug("[!] error call %d" % socketcall_call) + ql.log.debug("[!] error call %d" % socketcall_call) ql.os.stop(stop_event=THREAD_EVENT_UNEXECPT_EVENT) raise diff --git a/qiling/os/posix/syscall/prctl.py b/qiling/os/posix/syscall/prctl.py index 9e31794f..d7ddbd46 100644 --- a/qiling/os/posix/syscall/prctl.py +++ b/qiling/os/posix/syscall/prctl.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -16,11 +16,11 @@ def ql_syscall_arch_prctl(ql, ARCHX, ARCH_SET_FS, *args, **kw): FSMSR = 0xC0000100 ql.reg.msr(FSMSR, ARCH_SET_FS) regreturn = 0 - logging.info("arch_prctl(0x%x) = %d" % (ARCH_SET_FS, regreturn)) + ql.log.info("arch_prctl(0x%x) = %d" % (ARCH_SET_FS, regreturn)) return regreturn def ql_syscall_prctl(ql, *args, **kw): regreturn = 0 - logging.info("prctl() = %d" % (regreturn)) + ql.log.info("prctl() = %d" % (regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/ptrace.py b/qiling/os/posix/syscall/ptrace.py index 5da6da65..44f3def6 100644 --- a/qiling/os/posix/syscall/ptrace.py +++ b/qiling/os/posix/syscall/ptrace.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -14,5 +14,5 @@ from qiling.exception import * def ql_syscall_ptrace(ql, request, pid, addr, data, *args, **kw): regreturn = 0 - logging.info("ptrace(0x%x, 0x%x, 0x%x, 0x%x) = %d" % (request, pid, addr, data, regreturn)) + ql.log.info("ptrace(0x%x, 0x%x, 0x%x, 0x%x) = %d" % (request, pid, addr, data, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/random.py b/qiling/os/posix/syscall/random.py index 2622ddda..17669a92 100644 --- a/qiling/os/posix/syscall/random.py +++ b/qiling/os/posix/syscall/random.py @@ -3,7 +3,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import os, logging +import os + from qiling.const import * @@ -17,10 +18,10 @@ def ql_syscall_getrandom(ql, buf, buflen, flags,*args, **kw): except: regreturn = -1 - logging.info("getrandom(0x%x, 0x%x, 0x%x) = %d" % + ql.log.info("getrandom(0x%x, 0x%x, 0x%x) = %d" % (buf, buflen, flags, regreturn)) if data: - logging.debug("[+] getrandom() CONTENT:") - logging.debug(str(data)) + ql.log.debug("[+] getrandom() CONTENT:") + ql.log.debug(str(data)) return regreturn diff --git a/qiling/os/posix/syscall/resource.py b/qiling/os/posix/syscall/resource.py index 0bb3d0f2..e32650e5 100644 --- a/qiling/os/posix/syscall/resource.py +++ b/qiling/os/posix/syscall/resource.py @@ -14,7 +14,7 @@ except ImportError: pass resource = DummyResource() -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -27,7 +27,7 @@ def ql_syscall_ugetrlimit(ql, ugetrlimit_resource, ugetrlimit_rlim, *args, **kw) rlim = resource.getrlimit(ugetrlimit_resource) ql.mem.write(ugetrlimit_rlim, ql.pack32s(rlim[0]) + ql.pack32s(rlim[1])) regreturn = 0 - logging.info("ugetrlimit(%d, 0x%x) = %d" % (ugetrlimit_resource, ugetrlimit_rlim, regreturn)) + ql.log.info("ugetrlimit(%d, 0x%x) = %d" % (ugetrlimit_resource, ugetrlimit_rlim, regreturn)) return regreturn @@ -37,7 +37,7 @@ def ql_syscall_setrlimit(ql, setrlimit_resource, setrlimit_rlim, *args, **kw): resource.setrlimit(setrlimit_resource, tmp_rlim) regreturn = 0 - logging.info("setrlimit(%d, 0x%x) = %d" % (setrlimit_resource, setrlimit_rlim, regreturn)) + ql.log.info("setrlimit(%d, 0x%x) = %d" % (setrlimit_resource, setrlimit_rlim, regreturn)) return regreturn @@ -50,11 +50,11 @@ def ql_syscall_prlimit64(ql, prlimit64_pid, prlimit64_resource, prlimit64_new_li else: # set other process which pid != 0 regreturn = -1 - logging.info("prlimit64(%d, %d, 0x%x, 0x%x) = %d" % (prlimit64_pid, prlimit64_resource, prlimit64_new_limit, prlimit64_old_limit, regreturn)) + ql.log.info("prlimit64(%d, %d, 0x%x, 0x%x) = %d" % (prlimit64_pid, prlimit64_resource, prlimit64_new_limit, prlimit64_old_limit, regreturn)) return regreturn def ql_syscall_getpriority(ql, getpriority_which, getpriority_who, null1, null2, null3, null4): base = os.getpriority(getpriority_which, getpriority_who) - logging.info("getpriority(0x%x, 0x%x) = %d" % (getpriority_which, getpriority_who, base)) + ql.log.info("getpriority(0x%x, 0x%x) = %d" % (getpriority_which, getpriority_who, base)) return base diff --git a/qiling/os/posix/syscall/sched.py b/qiling/os/posix/syscall/sched.py index c1332f78..b13b7f99 100644 --- a/qiling/os/posix/syscall/sched.py +++ b/qiling/os/posix/syscall/sched.py @@ -3,9 +3,10 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import types, logging +import types from multiprocessing import Process + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -72,7 +73,6 @@ def ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, cl f_th.update_global_thread_id() f_th.new_thread_id() - f_th.set_thread_log_file(ql.log_dir) if clone_flags & CLONE_SETTLS == CLONE_SETTLS: f_th.set_thread_tls(clone_newtls) @@ -83,10 +83,10 @@ def ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, cl if clone_child_stack != 0: ql.arch.set_sp(clone_child_stack) regreturn = 0 - logging.info("clone(new_stack = %x, flags = %x, tls = %x, ptidptr = %x, ctidptr = %x) = %d" % (clone_child_stack, clone_flags, clone_newtls, clone_parent_tidptr, clone_child_tidptr, regreturn)) + ql.log.info("clone(new_stack = %x, flags = %x, tls = %x, ptidptr = %x, ctidptr = %x) = %d" % (clone_child_stack, clone_flags, clone_newtls, clone_parent_tidptr, clone_child_tidptr, regreturn)) else: regreturn = pid - logging.info("clone(new_stack = %x, flags = %x, tls = %x, ptidptr = %x, ctidptr = %x) = %d" % (clone_child_stack, clone_flags, clone_newtls, clone_parent_tidptr, clone_child_tidptr, regreturn)) + ql.log.info("clone(new_stack = %x, flags = %x, tls = %x, ptidptr = %x, ctidptr = %x) = %d" % (clone_child_stack, clone_flags, clone_newtls, clone_parent_tidptr, clone_child_tidptr, regreturn)) ql.emu_stop() return regreturn @@ -96,7 +96,7 @@ def ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, cl th = ql.os.thread_class.spawn(ql, ql.reg.arch_pc + 2, ql.os.exit_point, set_child_tid_addr = set_child_tid_addr) th.current_path = f_th.current_path - logging.debug(f"{str(th)} created.") + ql.log.debug(f"{str(th)} created.") if clone_flags & CLONE_PARENT_SETTID == CLONE_PARENT_SETTID: ql.mem.write(clone_parent_tidptr, ql.pack32(th.id)) @@ -104,7 +104,7 @@ def ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, cl ctx = ql.save(reg=True, mem=False) # Whether to set a new tls if clone_flags & CLONE_SETTLS == CLONE_SETTLS: - logging.debug(f"new_tls={hex(clone_newtls)}") + ql.log.debug(f"new_tls={hex(clone_newtls)}") th.set_thread_tls(clone_newtls) if clone_flags & CLONE_CHILD_CLEARTID == CLONE_CHILD_CLEARTID: @@ -119,14 +119,14 @@ def ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, cl # We have to find next pc manually for some archs since the pc is current instruction (like `syscall`). if ql.archtype in (QL_ARCH.X8664, ): ql.reg.arch_pc += list(ql.disassembler.disasm_lite(bytes(ql.mem.read(ql.reg.arch_pc, 4)), ql.reg.arch_pc))[0][1] - logging.debug(f"Fix pc for child thread to {hex(ql.reg.arch_pc)}") + ql.log.debug(f"Fix pc for child thread to {hex(ql.reg.arch_pc)}") ql.os.set_syscall_return(0) th.save() if th is None or f_th is None: raise Exception() - logging.debug("[+] Currently running pid is: %d; tid is: %d " % ( + ql.log.debug("[+] Currently running pid is: %d; tid is: %d " % ( os.getpid(), ql.os.thread_management.cur_thread.id)) - logging.info("clone(new_stack = %x, flags = %x, tls = %x, ptidptr = %x, ctidptr = %x) = %d" % ( + ql.log.info("clone(new_stack = %x, flags = %x, tls = %x, ptidptr = %x, ctidptr = %x) = %d" % ( clone_child_stack, clone_flags, clone_newtls, clone_parent_tidptr, clone_child_tidptr, regreturn)) # Restore the stack and return value of the parent process @@ -138,9 +138,9 @@ def ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, cl f_th.stop_event = THREAD_EVENT_CREATE_THREAD f_th.stop_return_val = th - logging.debug("[+] Currently running pid is: %d; tid is: %d " % ( + ql.log.debug("[+] Currently running pid is: %d; tid is: %d " % ( os.getpid(), ql.os.thread_management.cur_thread.id)) - logging.info("clone(new_stack = %x, flags = %x, tls = %x, ptidptr = %x, ctidptr = %x) = %d" % ( + ql.log.info("clone(new_stack = %x, flags = %x, tls = %x, ptidptr = %x, ctidptr = %x) = %d" % ( clone_child_stack, clone_flags, clone_newtls, clone_parent_tidptr, clone_child_tidptr, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/select.py b/qiling/os/posix/syscall/select.py index ada1ee78..12db4035 100644 --- a/qiling/os/posix/syscall/select.py +++ b/qiling/os/posix/syscall/select.py @@ -3,7 +3,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import select, logging +import select + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -61,7 +62,7 @@ def ql_syscall__newselect(ql, _newselect_nfds, _newselect_readfds, _newselect_wr if _newselect_readfds != 0: tmp_buf = b'\x00' * (_newselect_nfds // 8 + 1) for i in ans[0]: - logging.debug("debug : " + str(tmp_r_map[i])) + ql.log.debug("debug : " + str(tmp_r_map[i])) tmp_buf = set_fd_set(tmp_buf, tmp_r_map[i]) ql.mem.write(_newselect_readfds, tmp_buf) @@ -81,5 +82,5 @@ def ql_syscall__newselect(ql, _newselect_nfds, _newselect_readfds, _newselect_wr except: if ql.output in (QL_OUTPUT.DEBUG, QL_OUTPUT.DUMP): raise - logging.info("_newselect(%d, %x, %x, %x, %x) = %d" % (_newselect_nfds, _newselect_readfds, _newselect_writefds, _newselect_exceptfds, _newselect_timeout, regreturn)) + ql.log.info("_newselect(%d, %x, %x, %x, %x) = %d" % (_newselect_nfds, _newselect_readfds, _newselect_writefds, _newselect_exceptfds, _newselect_timeout, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/sendfile.py b/qiling/os/posix/syscall/sendfile.py index 23d368f5..987af66f 100644 --- a/qiling/os/posix/syscall/sendfile.py +++ b/qiling/os/posix/syscall/sendfile.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -20,5 +20,5 @@ def ql_syscall_sendfile64(ql, sendfile64_out_fd, sendfile64_in_fd, sendfile64_of else: regreturn = -1 - logging.info("sendfile64(%d, %d, %x, %d) = %d" % (sendfile64_out_fd, sendfile64_in_fd, sendfile64_offest, sendfile64_count, regreturn)) + ql.log.info("sendfile64(%d, %d, %x, %d) = %d" % (sendfile64_out_fd, sendfile64_in_fd, sendfile64_offest, sendfile64_count, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/signal.py b/qiling/os/posix/syscall/signal.py index c00c63c1..f75e81f3 100644 --- a/qiling/os/posix/syscall/signal.py +++ b/qiling/os/posix/syscall/signal.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -29,7 +29,7 @@ def ql_syscall_rt_sigaction(ql, rt_sigaction_signum, rt_sigaction_act, rt_sigact ql.os.sigaction_act[rt_sigaction_signum] = data regreturn = 0 - logging.info("rt_sigaction(0x%x, 0x%x, = 0x%x) = %d" % (rt_sigaction_signum, rt_sigaction_act, rt_sigaction_oldact, regreturn)) + ql.log.info("rt_sigaction(0x%x, 0x%x, = 0x%x) = %d" % (rt_sigaction_signum, rt_sigaction_act, rt_sigaction_oldact, regreturn)) return regreturn @@ -41,11 +41,11 @@ def ql_syscall_rt_sigprocmask(ql, rt_sigprocmask_how, rt_sigprocmask_nset, rt_si pass regreturn = 0 - logging.info("rt_sigprocmask(0x%x, 0x%x, 0x%x, 0x%x) = %d" % (rt_sigprocmask_how, rt_sigprocmask_nset, rt_sigprocmask_oset, rt_sigprocmask_sigsetsize, regreturn)) + ql.log.info("rt_sigprocmask(0x%x, 0x%x, 0x%x, 0x%x) = %d" % (rt_sigprocmask_how, rt_sigprocmask_nset, rt_sigprocmask_oset, rt_sigprocmask_sigsetsize, regreturn)) return regreturn def ql_syscall_signal(ql, sig, __sighandler_t, *args, **kw): regreturn = 0 - logging.info("signal(%d, 0x%x) = %d" % (sig, __sighandler_t,regreturn)) + ql.log.info("signal(%d, 0x%x) = %d" % (sig, __sighandler_t,regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/socket.py b/qiling/os/posix/syscall/socket.py index 13df73fa..1a481f27 100644 --- a/qiling/os/posix/syscall/socket.py +++ b/qiling/os/posix/syscall/socket.py @@ -3,7 +3,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import struct, ipaddress, logging +import struct, ipaddress + from qiling.const import * from qiling.os.linux.thread import * @@ -42,11 +43,11 @@ def ql_syscall_socket(ql, socket_domain, socket_type, socket_protocol, *args, ** except: regreturn = -1 - logging.info("socket(%d, %d, %d) = %d" % (socket_domain, socket_type, socket_protocol, regreturn)) + ql.log.info("socket(%d, %d, %d) = %d" % (socket_domain, socket_type, socket_protocol, regreturn)) socket_type = socket_type_mapping(socket_type, ql.archtype) socket_domain = socket_domain_mapping(socket_domain, ql.archtype) - logging.debug("[+] socket(%s, %s, %s) = %d" % (socket_domain, socket_type, socket_protocol, regreturn)) + ql.log.debug("[+] socket(%s, %s, %s) = %d" % (socket_domain, socket_type, socket_protocol, regreturn)) return regreturn @@ -80,17 +81,17 @@ def ql_syscall_connect(ql, connect_sockfd, connect_addr, connect_addrlen, *args, regreturn = -1 if s.family == AF_UNIX: - logging.info("connect(%s) = %d" % (sun_path, regreturn)) + ql.log.info("connect(%s) = %d" % (sun_path, regreturn)) elif s.family == AF_INET: - logging.info("connect(%s, %d) = %d" % (ip, port, regreturn)) + ql.log.info("connect(%s, %d) = %d" % (ip, port, regreturn)) else: - logging.info("connect() = %d" % (regreturn)) + ql.log.info("connect() = %d" % (regreturn)) return regreturn def ql_syscall_setsockopt(ql, *args, **kw): regreturn = 0 - logging.info("setsockopt() = %d" % (regreturn)) + ql.log.info("setsockopt() = %d" % (regreturn)) return regreturn @@ -101,7 +102,7 @@ def ql_syscall_shutdown(ql, shutdown_fd, shutdown_how, *args, **kw): regreturn = 0 except: regreturn = -1 - logging.info("shutdown(%d, %d) = %d" % (shutdown_fd, shutdown_how, regreturn)) + ql.log.info("shutdown(%d, %d) = %d" % (shutdown_fd, shutdown_how, regreturn)) return regreturn @@ -123,7 +124,7 @@ def ql_syscall_bind(ql, bind_fd, bind_addr, bind_addrlen, *args, **kw): if sin_family == 1: path = data[2 : ].split(b'\x00')[0] path = ql.os.transform_to_real_path(path.decode()) - logging.info(path) + ql.log.info(path) ql.os.fd[bind_fd].bind(path) # need a proper fix, for now ipv4 comes first @@ -146,10 +147,10 @@ def ql_syscall_bind(ql, bind_fd, bind_addr, bind_addrlen, *args, **kw): regreturn = 0 if sin_family == 1: - logging.info("bind(%d, %s, %d) = %d" % (bind_fd, path, bind_addrlen, regreturn)) + ql.log.info("bind(%d, %s, %d) = %d" % (bind_fd, path, bind_addrlen, regreturn)) else: - logging.info("bind(%d,%s:%d,%d) = %d" % (bind_fd, host, port, bind_addrlen,regreturn)) - logging.debug("[+] syscall bind host: %s and port: %i sin_family: %i" % (ql_bin_to_ip(host), port, sin_family)) + ql.log.info("bind(%d,%s:%d,%d) = %d" % (bind_fd, host, port, bind_addrlen,regreturn)) + ql.log.debug("[+] syscall bind host: %s and port: %i sin_family: %i" % (ql_bin_to_ip(host), port, sin_family)) return regreturn @@ -168,7 +169,7 @@ def ql_syscall_getsockname(ql, sockfd, addr, addrlenptr, *args, **kw): else: regreturn = -1 - logging.info("getsockname(%d, 0x%x, 0x%x) = %d" % (sockfd, addr, addrlenptr, regreturn)) + ql.log.info("getsockname(%d, 0x%x, 0x%x) = %d" % (sockfd, addr, addrlenptr, regreturn)) return regreturn @@ -186,7 +187,7 @@ def ql_syscall_getpeername(ql, sockfd, addr, addrlenptr, *args, **kw): else: regreturn = -1 - logging.info("getpeername(%d, 0x%x, 0x%x) = %d" % (sockfd, addr, addrlenptr, regreturn)) + ql.log.info("getpeername(%d, 0x%x, 0x%x) = %d" % (sockfd, addr, addrlenptr, regreturn)) return regreturn @@ -202,7 +203,7 @@ def ql_syscall_listen(ql, listen_sockfd, listen_backlog, *args, **kw): else: regreturn = -1 - logging.info("listen(%d, %d) = %d" % (listen_sockfd, listen_backlog, regreturn)) + ql.log.info("listen(%d, %d) = %d" % (listen_sockfd, listen_backlog, regreturn)) return regreturn @@ -243,7 +244,7 @@ def ql_syscall_accept(ql, accept_sockfd, accept_addr, accept_addrlen, *args, **k raise regreturn = -1 - logging.info("accept(%d, %x, %x) = %d" %(accept_sockfd, accept_addr, accept_addrlen, regreturn)) + ql.log.info("accept(%d, %x, %x) = %d" %(accept_sockfd, accept_addr, accept_addrlen, regreturn)) return regreturn @@ -251,14 +252,14 @@ def ql_syscall_recv(ql, recv_sockfd, recv_buf, recv_len, recv_flags, *args, **kw if recv_sockfd < 256 and ql.os.fd[recv_sockfd] != 0: tmp_buf = ql.os.fd[recv_sockfd].recv(recv_len, recv_flags) if tmp_buf: - logging.debug("[+] recv() CONTENT:") - logging.debug("%s" % tmp_buf) + ql.log.debug("[+] recv() CONTENT:") + ql.log.debug("%s" % tmp_buf) ql.mem.write(recv_buf, tmp_buf) regreturn = len(tmp_buf) else: regreturn = -1 - logging.info("recv(%d, %x, %d, %x) = %d" % (recv_sockfd, recv_buf, recv_len, recv_flags, regreturn)) + ql.log.info("recv(%d, %x, %d, %x) = %d" % (recv_sockfd, recv_buf, recv_len, recv_flags, regreturn)) return regreturn @@ -266,23 +267,23 @@ def ql_syscall_send(ql, send_sockfd, send_buf, send_len, send_flags, *args, **kw regreturn = 0 if send_sockfd < 256 and ql.os.fd[send_sockfd] != 0: try: - logging.debug("[+] debug send() start") + ql.log.debug("[+] debug send() start") tmp_buf = ql.mem.read(send_buf, send_len) - logging.debug("[+] fd is " + str(send_sockfd)) - logging.debug("[+] send() CONTENT:") - logging.debug("%s" % str(tmp_buf)) - logging.debug("[+] send() flag is " + str(send_flags)) - logging.debug("[+] send() len is " + str(send_len)) + ql.log.debug("[+] fd is " + str(send_sockfd)) + ql.log.debug("[+] send() CONTENT:") + ql.log.debug("%s" % str(tmp_buf)) + ql.log.debug("[+] send() flag is " + str(send_flags)) + ql.log.debug("[+] send() len is " + str(send_len)) regreturn = ql.os.fd[send_sockfd].send(bytes(tmp_buf), send_flags) - logging.debug("[+] debug send end") + ql.log.debug("[+] debug send end") except: - logging.info(sys.exc_info()[0]) + ql.log.info(sys.exc_info()[0]) if ql.output in (QL_OUTPUT.DEBUG, QL_OUTPUT.DUMP): raise else: regreturn = -1 - logging.info("send(%d, %x, %d, %x) = %d" % (send_sockfd, send_buf, send_len, send_flags, regreturn)) + ql.log.info("send(%d, %x, %d, %x) = %d" % (send_sockfd, send_buf, send_len, send_flags, regreturn)) return regreturn @@ -295,16 +296,16 @@ def ql_syscall_recvfrom(ql, recvfrom_sockfd, recvfrom_buf, recvfrom_len, recvfro if recvfrom_sockfd < 256 and ql.os.fd[recvfrom_sockfd] != 0: tmp_buf, tmp_addr = ql.os.fd[recvfrom_sockfd].recvfrom(recvfrom_len, recvfrom_flags) if tmp_buf: - logging.debug("[+] recvfrom() CONTENT:") - logging.debug("%s" % tmp_buf) + ql.log.debug("[+] recvfrom() CONTENT:") + ql.log.debug("%s" % tmp_buf) sin_family = int(ql.os.fd[recvfrom_sockfd].family) data = struct.pack("H", tmp_addr[1]) data += ipaddress.ip_address(tmp_addr[0]).packed addrlen = ql.unpack(ql.mem.read(recvfrom_addrlen, ql.pointersize)) @@ -316,7 +317,7 @@ def ql_syscall_recvfrom(ql, recvfrom_sockfd, recvfrom_buf, recvfrom_len, recvfro else: regreturn = -1 - logging.info("recvfrom(%d, %#x, %d, %#x, %#x, %#x) = %d" % (recvfrom_sockfd, recvfrom_buf, recvfrom_len, recvfrom_flags, recvfrom_addr, recvfrom_addrlen, regreturn)) + ql.log.info("recvfrom(%d, %#x, %d, %#x, %#x, %#x) = %d" % (recvfrom_sockfd, recvfrom_buf, recvfrom_len, recvfrom_flags, recvfrom_addr, recvfrom_addrlen, regreturn)) return regreturn @@ -329,7 +330,7 @@ def ql_syscall_sendto(ql, sendto_sockfd, sendto_buf, sendto_len, sendto_flags, s regreturn = 0 if sendto_sockfd < 256 and ql.os.fd[sendto_sockfd] != 0: try: - logging.debug("[+] debug sendto() start") + ql.log.debug("[+] debug sendto() start") tmp_buf = ql.mem.read(sendto_buf, sendto_len) if ql.archtype== QL_ARCH.X8664: @@ -345,24 +346,24 @@ def ql_syscall_sendto(ql, sendto_sockfd, sendto_buf, sendto_len, sendto_flags, s path = data[2 : ].split(b'\x00')[0] path = ql.os.transform_to_real_path(path.decode()) - logging.debug("[+] fd is " + str(sendto_sockfd)) - logging.debug("[+] sendto() CONTENT:") - logging.debug("%s" % tmp_buf) - logging.debug("[+] sendto() flag is " + str(sendto_flags)) - logging.debug("[+] sendto() len is " + str(sendto_len)) + ql.log.debug("[+] fd is " + str(sendto_sockfd)) + ql.log.debug("[+] sendto() CONTENT:") + ql.log.debug("%s" % tmp_buf) + ql.log.debug("[+] sendto() flag is " + str(sendto_flags)) + ql.log.debug("[+] sendto() len is " + str(sendto_len)) if sin_family == 1: - logging.debug("[+] sendto() path is " + str(path)) + ql.log.debug("[+] sendto() path is " + str(path)) regreturn = ql.os.fd[sendto_sockfd].sendto(bytes(tmp_buf), sendto_flags, path) else: - logging.debug("[+] sendto() addr is %s:%d" % (host, port)) + ql.log.debug("[+] sendto() addr is %s:%d" % (host, port)) regreturn = ql.os.fd[sendto_sockfd].sendto(bytes(tmp_buf), sendto_flags, (host, port)) - logging.debug("[+] debug sendto end") + ql.log.debug("[+] debug sendto end") except: - logging.info(sys.exc_info()[0]) + ql.log.info(sys.exc_info()[0]) if ql.output in (QL_OUTPUT.DEBUG, QL_OUTPUT.DUMP): raise else: regreturn = -1 - logging.info("sendto(%d, %#x, %d, %#x, %#x, %#x) = %d" % (sendto_sockfd, sendto_buf, sendto_len, sendto_flags, sendto_addr, sendto_addrlen, regreturn)) + ql.log.info("sendto(%d, %#x, %d, %#x, %#x, %#x) = %d" % (sendto_sockfd, sendto_buf, sendto_len, sendto_flags, sendto_addr, sendto_addrlen, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/stat.py b/qiling/os/posix/syscall/stat.py index bf7e1e66..e015815e 100644 --- a/qiling/os/posix/syscall/stat.py +++ b/qiling/os/posix/syscall/stat.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -16,7 +16,7 @@ from qiling.os.stat import * def ql_syscall_chmod(ql, filename, mode, null1, null2, null3, null4): regreturn = 0 filename = ql.mem.string(filename) - logging.info("chmod(%s,%d) = %d" % (filename, mode, regreturn)) + ql.log.info("chmod(%s,%d) = %d" % (filename, mode, regreturn)) return regreturn @@ -66,12 +66,12 @@ def ql_syscall_fstatat64(ql, fstatat64_fd, fstatat64_fname, fstatat64_buf, fstat ql.mem.write(fstatat64_buf,fstat64_buf) regreturn = 0 - logging.info("fstatat64(0x%x, %s) = %d" % (fstatat64_fd, relative_path, regreturn)) + ql.log.info("fstatat64(0x%x, %s) = %d" % (fstatat64_fd, relative_path, regreturn)) if regreturn == 0: - logging.debug("[+] Directory Found: %s" % relative_path) + ql.log.debug("[+] Directory Found: %s" % relative_path) else: - logging.debug("[!] Directory Not Found: %s" % relative_path) + ql.log.debug("[!] Directory Not Found: %s" % relative_path) return regreturn @@ -204,11 +204,11 @@ def ql_syscall_fstat64(ql, fstat64_fd, fstat64_add, *args, **kw): else: regreturn = -1 - logging.info("fstat64(%d, 0x%x) = %d" % (fstat64_fd, fstat64_add, regreturn)) + ql.log.info("fstat64(%d, 0x%x) = %d" % (fstat64_fd, fstat64_add, regreturn)) if regreturn == 0: - logging.debug("[+] fstat64 write completed") + ql.log.debug("[+] fstat64 write completed") else: - logging.debug("[!] fstat64 read/write fail") + ql.log.debug("[!] fstat64 read/write fail") return regreturn @@ -319,11 +319,11 @@ def ql_syscall_fstat(ql, fstat_fd, fstat_add, *args, **kw): else: regreturn = -1 - logging.info("fstat(%d, 0x%x) = %d" % (fstat_fd, fstat_add, regreturn)) + ql.log.info("fstat(%d, 0x%x) = %d" % (fstat_fd, fstat_add, regreturn)) if regreturn == 0: - logging.debug("[+] fstat write completed") + ql.log.debug("[+] fstat write completed") else: - logging.debug("[!] fstat read/write fail") + ql.log.debug("[!] fstat read/write fail") return regreturn @@ -392,11 +392,11 @@ def ql_syscall_stat64(ql, stat64_pathname, stat64_buf_ptr, *args, **kw): ql.mem.write(stat64_buf_ptr, stat64_buf) regreturn = 0 - logging.info("stat64(%s, 0x%x) = %d" % (relative_path, stat64_buf_ptr, regreturn)) + ql.log.info("stat64(%s, 0x%x) = %d" % (relative_path, stat64_buf_ptr, regreturn)) if regreturn == 0: - logging.debug("[+] stat64 write completed") + ql.log.debug("[+] stat64 write completed") else: - logging.debug("[!] stat64 read/write fail") + ql.log.debug("[!] stat64 read/write fail") return regreturn @@ -453,11 +453,11 @@ def ql_syscall_stat(ql, stat_path, stat_buf_ptr, *args, **kw): regreturn = 0 ql.mem.write(stat_buf_ptr, stat_buf) - logging.info("stat(%s, 0x%x) = %d" % (relative_path, stat_buf_ptr, regreturn)) + ql.log.info("stat(%s, 0x%x) = %d" % (relative_path, stat_buf_ptr, regreturn)) if regreturn == 0: - logging.debug("[+] stat() write completed") + ql.log.debug("[+] stat() write completed") else: - logging.debug("[!] stat() read/write fail") + ql.log.debug("[!] stat() read/write fail") return regreturn @@ -513,18 +513,18 @@ def ql_syscall_lstat(ql, lstat_path, lstat_buf_ptr, *args, **kw): regreturn = 0 ql.mem.write(lstat_buf_ptr, lstat_buf) - logging.info("lstat(%s, 0x%x) = %d" % (relative_path, lstat_buf_ptr, regreturn)) + ql.log.info("lstat(%s, 0x%x) = %d" % (relative_path, lstat_buf_ptr, regreturn)) if regreturn == 0: - logging.debug("[+] lstat() write completed") + ql.log.debug("[+] lstat() write completed") else: - logging.debug("[!] lstat() read/write fail") + ql.log.debug("[!] lstat() read/write fail") return regreturn def ql_syscall_mknodat(ql, dirfd, pathname, mode, dev, *args, **kw): # fix me. dirfd(relative path) not implement. file_path = ql.mem.string(pathname) real_path = ql.os.transform_to_real_path(file_path) - logging.info("mknodat(%d, %s, 0%o, %d)" % (dirfd, real_path, mode, dev)) + ql.log.info("mknodat(%d, %s, 0%o, %d)" % (dirfd, real_path, mode, dev)) try: os.mknod(real_path, mode, dev) regreturn = 0 @@ -536,7 +536,7 @@ def ql_syscall_mknodat(ql, dirfd, pathname, mode, dev, *args, **kw): def ql_syscall_mkdir(ql, pathname, mode, *args, **kw): file_path = ql.mem.string(pathname) real_path = ql.os.transform_to_real_path(file_path) - logging.info("mkdir(%s, 0%o)" % (real_path, mode)) + ql.log.info("mkdir(%s, 0%o)" % (real_path, mode)) try: if not os.path.exists(real_path): os.mkdir(real_path, mode) @@ -548,6 +548,6 @@ def ql_syscall_mkdir(ql, pathname, mode, *args, **kw): def ql_syscall_umask(ql, mode, *args, **kw): oldmask = os.umask(mode) - logging.info("umask(0%o) return oldmask 0%o" % (mode, oldmask)) + ql.log.info("umask(0%o) return oldmask 0%o" % (mode, oldmask)) regreturn = oldmask return regreturn diff --git a/qiling/os/posix/syscall/sysctl.py b/qiling/os/posix/syscall/sysctl.py index 64c0d645..d6eb5468 100644 --- a/qiling/os/posix/syscall/sysctl.py +++ b/qiling/os/posix/syscall/sysctl.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -15,5 +15,5 @@ from qiling.exception import * def ql_syscall__sysctl(ql, sysctl_name, sysctl_namelen, sysctl_bytes_oldlenp, sysctl_size_oldlenp, sysctl_bytes_newlen, sysctl_size_newlen): # sysctl (name=0x7fffffffe3d8, namelen=2, oldp=0x7fffffffe3d4, oldlenp=0x7fffffffe3e0, newp=0x0, newlen=) regreturn = 0 - logging.info("_sysctl(0x%x) = %i" % (sysctl_name, regreturn)) + ql.log.info("_sysctl(0x%x) = %i" % (sysctl_name, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/sysinfo.py b/qiling/os/posix/syscall/sysinfo.py index 4ec23b03..7e83fa0e 100644 --- a/qiling/os/posix/syscall/sysinfo.py +++ b/qiling/os/posix/syscall/sysinfo.py @@ -3,7 +3,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import struct, logging +import struct + from qiling.const import * from qiling.os.linux.thread import * @@ -34,6 +35,6 @@ def ql_syscall_sysinfo(ql, sysinfo_info, *args, **kw): ) regreturn = 0 - logging.info("sysinfo(0x%x) = %d" % (sysinfo_info, regreturn)) + ql.log.info("sysinfo(0x%x) = %d" % (sysinfo_info, regreturn)) #ql.mem.write(sysinfo_info, data) return regreturn diff --git a/qiling/os/posix/syscall/time.py b/qiling/os/posix/syscall/time.py index ca708655..d054d47a 100644 --- a/qiling/os/posix/syscall/time.py +++ b/qiling/os/posix/syscall/time.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -14,7 +14,7 @@ from qiling.exception import * def ql_syscall_time(ql, *args, **kw): regreturn = int(time.time()) - logging.info("time() = %d" % regreturn) + ql.log.info("time() = %d" % regreturn) return regreturn @@ -35,7 +35,7 @@ def ql_syscall_nanosleep(ql, nanosleep_req, nanosleep_rem, *args, **kw): th = ql.os.thread_management.cur_thread regreturn = 0 - logging.info("nanosleep(0x%x, 0x%x) = %d" % (nanosleep_req, nanosleep_rem, regreturn)) + ql.log.info("nanosleep(0x%x, 0x%x) = %d" % (nanosleep_req, nanosleep_rem, regreturn)) return regreturn @@ -44,7 +44,7 @@ def ql_syscall_setitimer(ql, setitimer_which, setitimer_new_value, setitimer_old # When any timer expires, a signal is sent to the process, and the timer (potentially) restarts. # But I haven’t figured out how to send a signal yet. regreturn = 0 - logging.info("setitimer(%d, %x, %x) = %d" % (setitimer_which, setitimer_new_value, setitimer_old_value, regreturn)) + ql.log.info("setitimer(%d, %x, %x) = %d" % (setitimer_which, setitimer_new_value, setitimer_old_value, regreturn)) return regreturn @@ -58,7 +58,7 @@ def ql_syscall_times(ql, times_tbuf, *args, **kw): tmp_buf += ql.pack32(int(tmp_times.children_system * 1000)) ql.mem.write(times_tbuf, tmp_buf) regreturn = int(tmp_times.elapsed * 100) - logging.info('times(%x) = %d' % (times_tbuf, regreturn)) + ql.log.info('times(%x) = %d' % (times_tbuf, regreturn)) return regreturn @@ -72,5 +72,5 @@ def ql_syscall_gettimeofday(ql, gettimeofday_tv, gettimeofday_tz, *args, **kw): if gettimeofday_tz != 0: ql.mem.write(gettimeofday_tz, b'\x00' * 8) regreturn = 0 - logging.info("gettimeofday(%x, %x) = %d" % (gettimeofday_tv, gettimeofday_tz, regreturn)) + ql.log.info("gettimeofday(%x, %x) = %d" % (gettimeofday_tv, gettimeofday_tz, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/types.py b/qiling/os/posix/syscall/types.py index 3b7e3ade..520affd4 100644 --- a/qiling/os/posix/syscall/types.py +++ b/qiling/os/posix/syscall/types.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -21,5 +21,5 @@ def ql_syscall_gettid(ql, *args, **kw): # In single-threaded process, the thread ID is equal to the process ID # per Posix documentation. regreturn = ql.os.pid - logging.info("gettid() = %d" % regreturn) + ql.log.info("gettid() = %d" % regreturn) return regreturn diff --git a/qiling/os/posix/syscall/uio.py b/qiling/os/posix/syscall/uio.py index 696f33fb..28007baf 100644 --- a/qiling/os/posix/syscall/uio.py +++ b/qiling/os/posix/syscall/uio.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -16,11 +16,11 @@ def ql_syscall_writev(ql, writev_fd, writev_vec, writev_vien, *args, **kw): regreturn = 0 size_t_len = ql.archbit // 8 iov = ql.mem.read(writev_vec, writev_vien * size_t_len * 2) - logging.info("writev(0x%x, 0x%x, 0x%x)" % (writev_fd, writev_vec, writev_vien)) - logging.debug("[+] writev() CONTENT:") + ql.log.info("writev(0x%x, 0x%x, 0x%x)" % (writev_fd, writev_vec, writev_vien)) + ql.log.debug("[+] writev() CONTENT:") for i in range(writev_vien): addr = ql.unpack(iov[i * size_t_len * 2 : i * size_t_len * 2 + size_t_len]) l = ql.unpack(iov[i * size_t_len * 2 + size_t_len : i * size_t_len * 2 + size_t_len * 2]) regreturn += l - logging.debug("%s" % str(ql.mem.read(addr, l))) + ql.log.debug("%s" % str(ql.mem.read(addr, l))) return regreturn diff --git a/qiling/os/posix/syscall/unistd.py b/qiling/os/posix/syscall/unistd.py index 6884bfdb..3b08c1ed 100644 --- a/qiling/os/posix/syscall/unistd.py +++ b/qiling/os/posix/syscall/unistd.py @@ -3,10 +3,11 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import stat, logging, itertools, pathlib +import stat, itertools, pathlib from multiprocessing import Process + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -17,14 +18,14 @@ from qiling.exception import * from qiling.os.stat import * def ql_syscall_exit(ql, exit_code, *args, **kw): - logging.info("exit(%u) = %u" % (exit_code, exit_code)) + ql.log.info("exit(%u) = %u" % (exit_code, exit_code)) if ql.os.child_processes == True: os._exit(0) if ql.multithread: def _sched_cb_exit(cur_thread): - logging.debug(f"[Thread {cur_thread.get_id()}] Terminated.") + ql.log.debug(f"[Thread {cur_thread.get_id()}] Terminated.") cur_thread.stop() cur_thread.exit_code = exit_code td = ql.os.thread_management.cur_thread @@ -38,7 +39,7 @@ def ql_syscall_exit(ql, exit_code, *args, **kw): def ql_syscall_exit_group(ql, exit_code, *args, **kw): ql.os.exit_code = exit_code - logging.info("exit_group(%u)" % ql.os.exit_code) + ql.log.info("exit_group(%u)" % ql.os.exit_code) if ql.os.child_processes == True: os._exit(0) @@ -48,55 +49,55 @@ def ql_syscall_exit_group(ql, exit_code, *args, **kw): def ql_syscall_alarm(ql, alarm_seconds, *args, **kw): regreturn = 0 - logging.info("alarm(%d) = %d" % (alarm_seconds, regreturn)) + ql.log.info("alarm(%d) = %d" % (alarm_seconds, regreturn)) return regreturn def ql_syscall_issetugid(ql, *args, **kw): UGID = ql.os.uid - logging.info("issetugid(%i)" % UGID) + ql.log.info("issetugid(%i)" % UGID) regreturn = UGID return regreturn def ql_syscall_getuid(ql, *args, **kw): UID = ql.os.uid - logging.info("getuid(%i)" % UID) + ql.log.info("getuid(%i)" % UID) regreturn = UID return regreturn def ql_syscall_getuid32(ql, *args, **kw): UID = ql.os.uid - logging.info("getuid32(%i)" % UID) + ql.log.info("getuid32(%i)" % UID) regreturn = UID return regreturn def ql_syscall_getgid32(ql, *args, **kw): GID = ql.os.gid - logging.info("getgid32(%i)" % GID) + ql.log.info("getgid32(%i)" % GID) regreturn = GID return regreturn def ql_syscall_geteuid(ql, *args, **kw): EUID = ql.os.uid - logging.info("geteuid(%i)" % EUID) + ql.log.info("geteuid(%i)" % EUID) regreturn = EUID return regreturn def ql_syscall_getegid(ql, *args, **kw): EGID = ql.os.gid - logging.info("getegid(%i)" % EGID) + ql.log.info("getegid(%i)" % EGID) regreturn = EGID return regreturn def ql_syscall_getgid(ql, *args, **kw): GID = ql.os.gid - logging.info("getgid(%i)" % GID) + ql.log.info("getgid(%i)" % GID) regreturn = GID return regreturn @@ -104,27 +105,27 @@ def ql_syscall_getgid(ql, *args, **kw): def ql_syscall_setgroups(ql, gidsetsize, grouplist, *args, **kw): GID = ql.os.gid regreturn = GID - logging.info("setgroups(0x%x, 0x%x) = %d" % (gidsetsize, grouplist, regreturn)) + ql.log.info("setgroups(0x%x, 0x%x) = %d" % (gidsetsize, grouplist, regreturn)) return regreturn def ql_syscall_setgid(ql, *args, **kw): GID = ql.os.gid - logging.info("setgid(%i)" % GID) + ql.log.info("setgid(%i)" % GID) regreturn = GID return regreturn def ql_syscall_setgid32(ql, *args, **kw): GID = ql.os.gid - logging.info("setgid32(%i)" % GID) + ql.log.info("setgid32(%i)" % GID) regreturn = GID return regreturn def ql_syscall_setuid(ql, *args, **kw): UID = ql.os.uid - logging.info("setuid(%i)" % UID) + ql.log.info("setuid(%i)" % UID) regreturn = UID return regreturn @@ -143,24 +144,24 @@ def ql_syscall_faccessat(ql, faccessat_dfd, faccessat_filename, faccessat_mode, else: regreturn = -1 - logging.info("facccessat (%d, 0x%x, 0x%x) = %d" %(faccessat_dfd, faccessat_filename, faccessat_mode, regreturn)) + ql.log.info("facccessat (%d, 0x%x, 0x%x) = %d" %(faccessat_dfd, faccessat_filename, faccessat_mode, regreturn)) if regreturn == -1: - logging.debug("[!] File Not Found or Skipped: %s" % access_path) + ql.log.debug("[!] File Not Found or Skipped: %s" % access_path) else: - logging.debug("[+] File Found: %s" % access_path) + ql.log.debug("[+] File Found: %s" % access_path) return regreturn def ql_syscall_lseek(ql, lseek_fd, lseek_ofset, lseek_origin, *args, **kw): lseek_ofset = ql.unpacks(ql.pack(lseek_ofset)) regreturn = 0 - logging.debug("lseek(%d, 0x%x, 0x%x) = %d" % (lseek_fd, lseek_ofset, lseek_origin, regreturn)) + ql.log.debug("lseek(%d, 0x%x, 0x%x) = %d" % (lseek_fd, lseek_ofset, lseek_origin, regreturn)) try: regreturn = ql.os.fd[lseek_fd].lseek(lseek_ofset, lseek_origin) except OSError: regreturn = -1 - logging.info("lseek(%d, 0x%x, 0x%x) = %d" % (lseek_fd, lseek_ofset, lseek_origin, regreturn)) + ql.log.info("lseek(%d, 0x%x, 0x%x) = %d" % (lseek_fd, lseek_ofset, lseek_origin, regreturn)) return regreturn @@ -168,7 +169,7 @@ def ql_syscall__llseek(ql, fd, offset_high, offset_low, result, whence, *args, * offset = offset_high << 32 | offset_low origin = whence regreturn = 0 - logging.info("_llseek(%d, 0x%x, 0x%x, 0x%x) = %d" % (fd, offset_high, offset_low, origin, regreturn)) + ql.log.info("_llseek(%d, 0x%x, 0x%x, 0x%x) = %d" % (fd, offset_high, offset_low, origin, regreturn)) try: ret = ql.os.fd[fd].lseek(offset, origin) except OSError: @@ -177,7 +178,7 @@ def ql_syscall__llseek(ql, fd, offset_high, offset_low, result, whence, *args, * if regreturn == 0: ql.mem.write(result, ql.pack64(ret)) - logging.info("_llseek(%d, 0x%x, 0x%x, 0x%x) = %d" % (fd, offset_high, offset_low, origin, regreturn)) + ql.log.info("_llseek(%d, 0x%x, 0x%x, 0x%x) = %d" % (fd, offset_high, offset_low, origin, regreturn)) return regreturn @@ -185,7 +186,7 @@ def ql_syscall_brk(ql, brk_input, *args, **kw): # current brk_address will be modified if brk_input is not NULL(zero) # otherwise, just return current brk_address - logging.info("brk(0x%x)" % brk_input) + ql.log.info("brk(0x%x)" % brk_input) if brk_input != 0: new_brk_addr = ((brk_input + 0xfff) // 0x1000) * 0x1000 @@ -200,7 +201,7 @@ def ql_syscall_brk(ql, brk_input, *args, **kw): regreturn = ql.loader.brk_address - logging.debug("[+] brk return(0x%x)" % regreturn) + ql.log.debug("[+] brk return(0x%x)" % regreturn) return regreturn @@ -215,11 +216,11 @@ def ql_syscall_access(ql, access_path, access_mode, *args, **kw): else: regreturn = 0 - logging.info("access(%s, 0x%x) = %d " % (relative_path, access_mode, regreturn)) + ql.log.info("access(%s, 0x%x) = %d " % (relative_path, access_mode, regreturn)) if regreturn == 0: - logging.debug("[+] File found: %s" % relative_path) + ql.log.debug("[+] File found: %s" % relative_path) else: - logging.debug("[!] No such file or directory") + ql.log.debug("[!] No such file or directory") return regreturn @@ -230,7 +231,7 @@ def ql_syscall_close(ql, close_fd, *args, **kw): ql.os.fd[close_fd].close() ql.os.fd[close_fd] = 0 regreturn = 0 - logging.info("close(%d) = %d" % (close_fd, regreturn)) + ql.log.info("close(%d) = %d" % (close_fd, regreturn)) return regreturn @@ -248,7 +249,7 @@ def ql_syscall_pread64(ql, read_fd, read_buf, read_len, read_offt, *args, **kw): regreturn = -1 else: regreturn = -1 - logging.info("pread(%d, 0x%x, 0x%x, 0x%x) = 0x%x" % (read_fd, read_buf, read_len, read_offt, regreturn)) + ql.log.info("pread(%d, 0x%x, 0x%x, 0x%x) = 0x%x" % (read_fd, read_buf, read_len, read_offt, regreturn)) return regreturn @@ -263,11 +264,11 @@ def ql_syscall_read(ql, read_fd, read_buf, read_len, *args, **kw): regreturn = -1 else: regreturn = -1 - logging.info("read(%d, 0x%x, 0x%x) = %d" % (read_fd, read_buf, read_len, regreturn)) + ql.log.info("read(%d, 0x%x, 0x%x) = %d" % (read_fd, read_buf, read_len, regreturn)) if data: - logging.debug("[+] read() CONTENT:") - logging.debug("%s" % data) + ql.log.debug("[+] read() CONTENT:") + ql.log.debug("%s" % data) return regreturn @@ -278,23 +279,23 @@ def ql_syscall_write(ql, write_fd, write_buf, write_count, *args, **kw): try: buf = ql.mem.read(write_buf, write_count) if buf: - logging.debug("[+] write() CONTENT:") - logging.debug("%s" % buf) + ql.log.debug("[+] write() CONTENT:") + ql.log.debug("%s" % buf) if hasattr(ql.os.fd[write_fd], "write"): - logging.info("write(%d,%x,%i) = %d" % (write_fd, write_buf, write_count, regreturn)) + ql.log.info("write(%d,%x,%i) = %d" % (write_fd, write_buf, write_count, regreturn)) ql.os.fd[write_fd].write(buf) else: - logging.info("[!] write(%d,%x,%i) failed due to write_fd" % (write_fd, write_buf, write_count, regreturn)) + ql.log.info("[!] write(%d,%x,%i) failed due to write_fd" % (write_fd, write_buf, write_count, regreturn)) regreturn = write_count except: regreturn = -1 - logging.info("write(%d,%x,%i) = %d" % (write_fd, write_buf, write_count, regreturn)) + ql.log.info("write(%d,%x,%i) = %d" % (write_fd, write_buf, write_count, regreturn)) if ql.output in (QL_OUTPUT.DEBUG, QL_OUTPUT.DUMP): raise #if buf: - # logging.info(buf.decode(errors='ignore')) + # ql.log.info(buf.decode(errors='ignore')) return regreturn @@ -316,7 +317,7 @@ def ql_syscall_readlink(ql, path_name, path_buff, path_buffsize, *args, **kw): else: regreturn = 0x0 - logging.info("readlink(%s, 0x%x, 0x%x) = %d" % (relative_path, path_buff, path_buffsize, regreturn)) + ql.log.info("readlink(%s, 0x%x, 0x%x) = %d" % (relative_path, path_buff, path_buffsize, regreturn)) return regreturn @@ -329,7 +330,7 @@ def ql_syscall_getcwd(ql, path_buff, path_buffsize, *args, **kw): pathname = (ql.mem.read(path_buff, 0x100).split(b'\x00'))[0] pathname = str(pathname, 'utf-8', errors="ignore") - logging.info("getcwd(%s, 0x%x) = %d" % (pathname, path_buffsize, regreturn)) + ql.log.info("getcwd(%s, 0x%x) = %d" % (pathname, path_buffsize, regreturn)) return regreturn @@ -345,10 +346,10 @@ def ql_syscall_chdir(ql, path_name, *args, **kw): pass else: ql.os.current_path = relative_path - logging.info("chdir(%s) = %d"% (relative_path, regreturn)) + ql.log.info("chdir(%s) = %d"% (relative_path, regreturn)) else: regreturn = -1 - logging.info("chdir(%s) = %d : Not Found" % (relative_path, regreturn)) + ql.log.info("chdir(%s) = %d : Not Found" % (relative_path, regreturn)) return regreturn @@ -370,19 +371,19 @@ def ql_syscall_readlinkat(ql, readlinkat_dfd, readlinkat_path, readlinkat_buf, r else: regreturn = 0x0 - logging.info("readlinkat(0x%x, 0x%x, 0x%x, 0x%x) = %d" % (readlinkat_dfd, readlinkat_path, readlinkat_buf, readlinkat_bufsiz, regreturn)) + ql.log.info("readlinkat(0x%x, 0x%x, 0x%x, 0x%x) = %d" % (readlinkat_dfd, readlinkat_path, readlinkat_buf, readlinkat_bufsiz, regreturn)) return regreturn def ql_syscall_getpid(ql, *args, **kw): regreturn= 0x512 - logging.info("getpid() = %d" % (regreturn)) + ql.log.info("getpid() = %d" % (regreturn)) return regreturn def ql_syscall_getppid(ql, *args, **kw): regreturn= 0x1024 - logging.info("getpid() = %d" % (regreturn)) + ql.log.info("getpid() = %d" % (regreturn)) return regreturn @@ -398,30 +399,21 @@ def ql_syscall_vfork(ql, *args, **kw): if pid == 0: ql.os.child_processes = True - logging.debug("[+] vfork(): is this a child process: %r" % (ql.os.child_processes)) + ql.log.debug("[+] vfork(): is this a child process: %r" % (ql.os.child_processes)) regreturn = 0 - if ql.os.thread_management != None: - ql.os.thread_management.cur_thread.set_thread_log_file(ql.log_dir) - else: - if ql.log_split: - _logger = ql.log_file_fd - _logger = ql_setup_logging_file(ql.output, ql.log_file , _logger) - _logger_name = str(len(logging.root.manager.loggerDict)) - _logger = ql_setup_logging_file(ql.output, '_'.join((ql.log_file, _logger_name))) - ql.log_file_fd = _logger else: regreturn = pid if ql.os.thread_management != None: ql.emu_stop() - logging.info("vfork() = %d" % regreturn) + ql.log.info("vfork() = %d" % regreturn) return regreturn def ql_syscall_setsid(ql, *args, **kw): regreturn = os.getpid() - logging.info("setsid() = %d" % regreturn) + ql.log.info("setsid() = %d" % regreturn) return regreturn @@ -457,7 +449,7 @@ def ql_syscall_execve(ql, execve_pathname, execve_argv, execve_envp, *args, **kw ql.emu_stop() - logging.info("execve(%s, [%s], [%s])"% (pathname, ', '.join(argv), ', '.join([key + '=' + value for key, value in env.items()]))) + ql.log.info("execve(%s, [%s], [%s])"% (pathname, ', '.join(argv), ', '.join([key + '=' + value for key, value in env.items()]))) ql.loader.argv = argv ql.loader.env = env @@ -486,7 +478,7 @@ def ql_syscall_dup(ql, dup_oldfd, *args, **kw): regreturn = idx break - logging.info("dup(%d) = %d" % (dup_oldfd, regreturn)) + ql.log.info("dup(%d) = %d" % (dup_oldfd, regreturn)) return regreturn @@ -499,7 +491,7 @@ def ql_syscall_dup2(ql, dup2_oldfd, dup2_newfd, *args, **kw): regreturn = -1 else: regreturn = -1 - logging.info("dup2(%d, %d) = %d" % (dup2_oldfd, dup2_newfd, regreturn)) + ql.log.info("dup2(%d, %d) = %d" % (dup2_oldfd, dup2_newfd, regreturn)) return regreturn @@ -512,7 +504,7 @@ def ql_syscall_dup3(ql, dup3_oldfd, dup3_newfd, dup3_flags, null2, null3, null4) regreturn = -1 else: regreturn = -1 - logging.info("dup3(%d, %d, %d) = %d" % (dup3_oldfd, dup3_newfd, dup3_flags, regreturn)) + ql.log.info("dup3(%d, %d, %d) = %d" % (dup3_oldfd, dup3_newfd, dup3_flags, regreturn)) return regreturn def ql_syscall_set_tid_address(ql, set_tid_address_tidptr, *args, **kw): @@ -521,7 +513,7 @@ def ql_syscall_set_tid_address(ql, set_tid_address_tidptr, *args, **kw): else: ql.os.thread_management.cur_thread.set_clear_child_tid_addr(set_tid_address_tidptr) regreturn = ql.os.thread_management.cur_thread.id - logging.info("set_tid_address(%x) = %d" % (set_tid_address_tidptr, regreturn)) + ql.log.info("set_tid_address(%x) = %d" % (set_tid_address_tidptr, regreturn)) return regreturn @@ -553,13 +545,13 @@ def ql_syscall_pipe(ql, pipe_pipefd, *args, **kw): ql.mem.write(pipe_pipefd, ql.pack32(idx1) + ql.pack32(idx2)) regreturn = 0 - logging.info("pipe(%x, [%d, %d]) = %d" % (pipe_pipefd, idx1, idx2, regreturn)) + ql.log.info("pipe(%x, [%d, %d]) = %d" % (pipe_pipefd, idx1, idx2, regreturn)) return regreturn def ql_syscall_nice(ql, nice_inc, *args, **kw): regreturn = 0 - logging.info("nice(%d) = %d" % (nice_inc, regreturn)) + ql.log.info("nice(%d) = %d" % (nice_inc, regreturn)) return regreturn @@ -581,7 +573,7 @@ def ql_syscall_truncate(ql, path, length, *args, **kw): except: regreturn = -1 - logging.info('truncate(%s, 0x%x) = %d' % (path, length, regreturn)) + ql.log.info('truncate(%s, 0x%x) = %d' % (path, length, regreturn)) return regreturn @@ -602,7 +594,7 @@ def ql_syscall_ftruncate(ql, ftrunc_fd, ftrunc_length, *args, **kw): except: regreturn = -1 - logging.info('ftruncate(%d, 0x%x) = %d' % (ftrunc_fd, ftrunc_length, regreturn)) + ql.log.info('ftruncate(%d, 0x%x) = %d' % (ftrunc_fd, ftrunc_length, regreturn)) return regreturn @@ -617,14 +609,14 @@ def ql_syscall_unlink(ql, unlink_pathname, *args, **kw): os.unlink(real_path) regreturn = 0 except FileNotFoundError: - logging.debug('[!] No such file or directory') + ql.log.debug('[!] No such file or directory') regreturn = -1 except: regreturn = -1 else: regreturn = -1 - logging.info('unlink(%s) = %d' % (pathname, regreturn)) + ql.log.info('unlink(%s) = %d' % (pathname, regreturn)) return regreturn @@ -632,12 +624,12 @@ def ql_syscall_unlinkat(ql, dirfd, pathname, flag, *args, **kw): #FIXME dirfd(relative path) not implement. file_path = ql.mem.string(pathname) real_path = ql.os.transform_to_real_path(file_path) - logging.info("unlinkat(%d, %s, 0%o)" % (dirfd, real_path, flag)) + ql.log.info("unlinkat(%d, %s, 0%o)" % (dirfd, real_path, flag)) try: os.unlink(real_path) return 0 except FileNotFoundError: - logging.debug("[!] No such file or directory") + ql.log.debug("[!] No such file or directory") return -1 except: return -1 @@ -689,7 +681,7 @@ def ql_syscall_getdents(ql, fd, dirp, count, *args, **kw): _ent_count = 0 regreturn = 0 - logging.info("getdents(%d, 0x%x, 0x%x) = %d" % (fd, dirp, count, regreturn)) - logging.debug("[+] getdents(%d, /* %d entries */, 0x%x) = %d" % (fd, _ent_count, count, regreturn)) + ql.log.info("getdents(%d, 0x%x, 0x%x) = %d" % (fd, dirp, count, regreturn)) + ql.log.debug("[+] getdents(%d, /* %d entries */, 0x%x) = %d" % (fd, _ent_count, count, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/utsname.py b/qiling/os/posix/syscall/utsname.py index 8b6c2ff4..4bb1b858 100644 --- a/qiling/os/posix/syscall/utsname.py +++ b/qiling/os/posix/syscall/utsname.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -22,5 +22,5 @@ def ql_syscall_uname(ql, address, *args, **kw): buf += b''.ljust(65, b'\x00') ql.mem.write(address, buf) regreturn = 0 - logging.info("uname(0x%x) = %d" % (address, regreturn)) + ql.log.info("uname(0x%x) = %d" % (address, regreturn)) return regreturn diff --git a/qiling/os/posix/syscall/wait.py b/qiling/os/posix/syscall/wait.py index a2882d80..4cd36378 100644 --- a/qiling/os/posix/syscall/wait.py +++ b/qiling/os/posix/syscall/wait.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.linux.thread import * from qiling.const import * @@ -24,6 +24,6 @@ def ql_syscall_wait4(ql, wait4_pid, wait4_wstatus, wait4_options, wait4_rusage, regreturn = spid except ChildProcessError: regreturn = -ECHILD - logging.info("wait4(%d, %d) = %d"% (wait4_pid, wait4_options, regreturn)) + ql.log.info("wait4(%d, %d) = %d"% (wait4_pid, wait4_options, regreturn)) return regreturn diff --git a/qiling/os/uefi/bs.py b/qiling/os/uefi/bs.py index 07f9b129..f341ca3f 100644 --- a/qiling/os/uefi/bs.py +++ b/qiling/os/uefi/bs.py @@ -481,7 +481,7 @@ def hook_InstallMultipleProtocolInterfaces(ql, address, params): GUID_ptr = ql.os.get_param_by_index(index) protocol_ptr = ql.os.get_param_by_index(index+1) GUID = str(ql.os.read_guid(GUID_ptr)) - logging.info(f' | {GUID} {protocol_ptr:x}') + ql.log.info(f' | {GUID} {protocol_ptr:x}') dic[GUID] = protocol_ptr index +=2 @@ -509,7 +509,7 @@ def hook_UninstallMultipleProtocolInterfaces(ql, address, params): GUID_ptr = ql.os.get_param_by_index(index) protocol_ptr = ql.os.get_param_by_index(index+1) GUID = str(ql.os.read_guid(GUID_ptr)) - logging.info(f' | {GUID}, {protocol_ptr:x}') + ql.log.info(f' | {GUID}, {protocol_ptr:x}') if GUID not in dic: return EFI_INVALID_PARAMETER diff --git a/qiling/os/uefi/context.py b/qiling/os/uefi/context.py index c52737e1..48c6fd4e 100644 --- a/qiling/os/uefi/context.py +++ b/qiling/os/uefi/context.py @@ -1,4 +1,4 @@ -import logging + from qiling.os.memory import QlMemoryHeap from qiling.os.uefi.utils import init_struct @@ -21,7 +21,7 @@ class UefiContext: self.protocols[handle] = {} if guid in self.protocols[handle]: - logging.warning(f'a protocol with guid {guid} is already installed') + self.ql.log.warning(f'a protocol with guid {guid} is already installed') if address is None: struct_class = proto_desc['struct'] diff --git a/qiling/os/uefi/protocols/EfiSmmBase2Protocol.py b/qiling/os/uefi/protocols/EfiSmmBase2Protocol.py index 1f42b042..88d4114a 100644 --- a/qiling/os/uefi/protocols/EfiSmmBase2Protocol.py +++ b/qiling/os/uefi/protocols/EfiSmmBase2Protocol.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.const import * from qiling.os.const import * from ..fncc import * @@ -26,7 +26,7 @@ class EFI_SMM_BASE2_PROTOCOL(STRUCT): "InSmram" : POINTER }) def hook_InSmm(ql, address, params): - logging.info(f'InSmram = {ql.loader.in_smm}') + ql.log.info(f'InSmram = {ql.loader.in_smm}') write_int8(ql, params["InSmram"], int(ql.loader.in_smm)) diff --git a/qiling/os/uefi/shutdown.py b/qiling/os/uefi/shutdown.py index f36d553c..6aca810e 100644 --- a/qiling/os/uefi/shutdown.py +++ b/qiling/os/uefi/shutdown.py @@ -3,7 +3,6 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging from .utils import check_and_notify_protocols @@ -20,7 +19,7 @@ def hook_EndOfExecution(ql): if ql.loader.unload_modules(): return - logging.info(f'[+] No more modules to run') + ql.log.info(f'[+] No more modules to run') ql.emu_stop() else: ql.loader.execute_next_module() diff --git a/qiling/os/uefi/st.py b/qiling/os/uefi/st.py index 935ca658..a0498702 100644 --- a/qiling/os/uefi/st.py +++ b/qiling/os/uefi/st.py @@ -3,9 +3,9 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging import binascii + from qiling.os.uefi import bs, rt, ds from qiling.os.uefi.utils import CoreInstallConfigurationTable from qiling.os.uefi.UefiSpec import EFI_SYSTEM_TABLE, EFI_BOOT_SERVICES, EFI_RUNTIME_SERVICES, EFI_CONFIGURATION_TABLE @@ -79,12 +79,12 @@ def initialize(ql, gST : int): gDS = gRT + EFI_RUNTIME_SERVICES.sizeof() # dxe services cfg = gDS + ds.EFI_DXE_SERVICES.sizeof() # configuration tables array - logging.info(f'Global tables:') - logging.info(f' | gST {gST:#010x}') - logging.info(f' | gBS {gBS:#010x}') - logging.info(f' | gRT {gRT:#010x}') - logging.info(f' | gDS {gDS:#010x}') - logging.info(f'') + ql.log.info(f'Global tables:') + ql.log.info(f' | gST {gST:#010x}') + ql.log.info(f' | gBS {gBS:#010x}') + ql.log.info(f' | gRT {gRT:#010x}') + ql.log.info(f' | gDS {gDS:#010x}') + ql.log.info(f'') bs.initialize(ql, gBS) rt.initialize(ql, gRT) diff --git a/qiling/os/uefi/uefi.py b/qiling/os/uefi/uefi.py index 74194d30..63dbe49b 100644 --- a/qiling/os/uefi/uefi.py +++ b/qiling/os/uefi/uefi.py @@ -3,7 +3,6 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging from unicorn import UcError @@ -77,16 +76,16 @@ class QlOsUefi(QlOs): sizes = (64, 32, 16, 8, 8) - logging.error(f'CPU Context:') + self.ql.log.error(f'CPU Context:') for grp in rgroups: - logging.error(', '.join((f'{reg:4s} = {self.ql.reg.read(reg):0{bits // 4}x}') for reg, bits in zip(grp, sizes) if reg)) + self.ql.log.error(', '.join((f'{reg:4s} = {self.ql.reg.read(reg):0{bits // 4}x}') for reg, bits in zip(grp, sizes) if reg)) - logging.error(f'') + self.ql.log.error(f'') def emit_hexdump(self, address : int, data : str, num_cols=16): - logging.error('Hexdump:') + self.ql.log.error('Hexdump:') # align hexdump to numbers of columns pre_padding = [None] * (address % num_cols) @@ -96,15 +95,15 @@ class QlOsUefi(QlOs): for i in range(0, len(chars), num_cols): hexdump = ' '.join(f' ' if ch is None else f'{ch:02x}' for ch in chars[i: i + num_cols]) - logging.error(f'{address + i:08x} : {hexdump}') + self.ql.log.error(f'{address + i:08x} : {hexdump}') - logging.error(f'') + self.ql.log.error(f'') def emit_disasm(self, address : int, data : str, num_insns=8): md = self.ql.create_disassembler() - logging.error('Disassembly:') + self.ql.log.error('Disassembly:') for insn in tuple(md.disasm(data, address))[:num_insns]: opcodes = ''.join(f'{ch:02x}' for ch in insn.bytes[:10]) @@ -112,9 +111,9 @@ class QlOsUefi(QlOs): if len(insn.bytes) > 10: opcodes += '.' - logging.error(f'{insn.address:08x} {opcodes:<20s} {insn.mnemonic:<10s} {insn.op_str:s}') + self.ql.log.error(f'{insn.address:08x} {opcodes:<20s} {insn.mnemonic:<10s} {insn.op_str:s}') - logging.error(f'') + self.ql.log.error(f'') def emu_error(self): @@ -130,12 +129,12 @@ class QlOsUefi(QlOs): containing_image = self.find_containing_image(pc) img_info = f' ({containing_image.path} + {pc - containing_image.base:#x})' if containing_image else '' - logging.error(f'PC = {pc:#010x}{img_info}') + self.ql.log.error(f'PC = {pc:#010x}{img_info}') - logging.error(f'Memory map:') + self.ql.log.error(f'Memory map:') self.ql.mem.show_mapinfo() except UcError: - logging.error(f'Error: PC({pc:#x}) is unreachable') + self.ql.log.error(f'Error: PC({pc:#x}) is unreachable') def run(self): @@ -150,7 +149,7 @@ class QlOsUefi(QlOs): try: self.ql.emu_start(self.ql.loader.entry_point, self.exit_point, self.ql.timeout, self.ql.count) except KeyboardInterrupt as ex: - logging.critical(f'Execution interrupted by user') + self.ql.log.critical(f'Execution interrupted by user') if self.ql._internal_exception is ex: self.ql._internal_exception = None diff --git a/qiling/os/uefi/utils.py b/qiling/os/uefi/utils.py index 147ebd43..24bbbace 100644 --- a/qiling/os/uefi/utils.py +++ b/qiling/os/uefi/utils.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging, struct +import struct from uuid import UUID @@ -14,7 +14,7 @@ from qiling.os.uefi.UefiBaseType import EFI_GUID def check_and_notify_protocols(ql): if len(ql.loader.notify_list) > 0: event_id, notify_func, notify_context = ql.loader.notify_list.pop(0) - logging.info(f'Notify event:{event_id} calling:{notify_func:x} context:{notify_context:x}') + ql.log.info(f'Notify event:{event_id} calling:{notify_func:x} context:{notify_context:x}') ql.stack_push(ql.loader.end_of_execution_ptr) ql.reg.rcx = notify_context @@ -79,7 +79,7 @@ def init_struct(ql, base : int, descriptor : dict): struct_fields = descriptor.get('fields', []) isntance = struct_class() - logging.info(f'Initializing {struct_class.__name__}') + ql.log.info(f'Initializing {struct_class.__name__}') for name, value in struct_fields: if value is not None: @@ -90,13 +90,13 @@ def init_struct(ql, base : int, descriptor : dict): isntance.__setattr__(name, p) ql.hook_address(value, p) - logging.info(f' | {name:36s} {p:#010x}') + ql.log.info(f' | {name:36s} {p:#010x}') # a value: set it else: isntance.__setattr__(name, value) - logging.info(f'') + ql.log.info(f'') return isntance @@ -125,7 +125,8 @@ def LocateProtocol(context, params): write_int64(context.ql, params['Interface'], guid_dic[protocol]) return EFI_SUCCESS - logging.warning(f'protocol with guid {protocol} not found') + # (@wtdcode): please use ql.log.warning instead. + #ql.log.warning(f'protocol with guid {protocol} not found') return EFI_NOT_FOUND diff --git a/qiling/os/utils.py b/qiling/os/utils.py index 3132806d..b5352a68 100644 --- a/qiling/os/utils.py +++ b/qiling/os/utils.py @@ -7,7 +7,7 @@ This module is intended for general purpose functions that are only used in qiling.os """ -import ctypes, inspect, os, struct, uuid, logging +import ctypes, inspect, os, struct, uuid from json import dumps from pathlib import Path, PurePosixPath, PureWindowsPath, PosixPath, WindowsPath @@ -23,6 +23,7 @@ from capstone.arm64_const import * from capstone.mips_const import * from keystone import * + from qiling.const import * from qiling.exception import * from .const import * @@ -156,7 +157,7 @@ class QlOsUtils: # Sanity check. if cur_path[0] != '/': - logging.info(f"[!] Warning: cur_path doesn't start with a /") + self.ql.log.info(f"[!] Warning: cur_path doesn't start with a /") rootfs = self.ql.rootfs real_path = self.convert_path(rootfs, cur_path, path) @@ -173,7 +174,7 @@ class QlOsUtils: # Sanity check. if cur_path[0] != '/': - logging.info(f"[!] Warning: cur_path must start with /") + self.ql.log.info(f"[!] Warning: cur_path must start with /") rootfs = self.ql.rootfs real_path = self.convert_path(rootfs, cur_path, path) @@ -195,20 +196,20 @@ class QlOsUtils: return str(Path(cur_path) / path) def post_report(self): - logging.debug("[+] Syscalls called") + self.ql.log.debug("[+] Syscalls called") for key, values in self.ql.os.syscalls.items(): - logging.debug("[-] %s:" % key) + self.ql.log.debug("[-] %s:" % key) for value in values: - logging.debug("[-] %s " % str(dumps(value))) - logging.debug("[+] Registries accessed") + self.ql.log.debug("[-] %s " % str(dumps(value))) + self.ql.log.debug("[+] Registries accessed") for key, values in self.ql.os.registry_manager.accessed.items(): - logging.debug("[-] %s:" % key) + self.ql.log.debug("[-] %s:" % key) for value in values: - logging.debug("[-] %s " % str(dumps(value))) - logging.debug("[+] Strings") + self.ql.log.debug("[-] %s " % str(dumps(value))) + self.ql.log.debug("[+] Strings") for key, values in self.ql.os.appeared_strings.items(): val = " ".join([str(word) for word in values]) - logging.debug("[-] %s: %s" % (key, val)) + self.ql.log.debug("[-] %s: %s" % (key, val)) def exec_arbitrary(self, start, end): @@ -218,7 +219,7 @@ class QlOsUtils: ret = self.ql.stack_read(0) def restore(ql): - logging.debug(f"[+] Executed code from 0x{start:x} to 0x{end:x}") + self.ql.log.debug(f"[+] Executed code from 0x{start:x} to 0x{end:x}") # now we can restore the register to be where we were supposed to old_hook_addr = ql.reg.arch_pc ql.reg.arch_sp = old_sp + (ql.archbit // 8) @@ -262,18 +263,18 @@ class QlOsUtils: log_data += '\n> ' first = False log_data += "%s %s" % (i.mnemonic, i.op_str) - logging.info(log_data) + self.ql.log.info(log_data) if self.ql.output == QL_OUTPUT.DUMP: for reg in self.ql.reg.register_mapping: if isinstance(reg, str): REG_NAME = reg REG_VAL = self.ql.reg.read(reg) - logging.debug("%s\t:\t 0x%x" % (REG_NAME, REG_VAL)) + self.ql.log.debug("%s\t:\t 0x%x" % (REG_NAME, REG_VAL)) def setup_output(self): def ql_hook_block_disasm(ql, address, size): - logging.info("\n[+] Tracing basic block at 0x%x" % (address)) + self.ql.log.info("\n[+] Tracing basic block at 0x%x" % (address)) if self._disasm_hook: self._disasm_hook.remove() @@ -361,10 +362,10 @@ class QlOsUtils: log = f'{address:02x}: {function_name:s}({", ".join(fargs)}){fret}{fpass}' if self.ql.output == QL_OUTPUT.DEBUG: - logging.debug(log) + self.ql.log.debug(log) else: log = log.partition(" ")[-1] - logging.info(log) + self.ql.log.info(log) def vprintf(self, address, fmt, params_addr, name, wstring=False): count = fmt.count("%") @@ -402,7 +403,7 @@ class QlOsUtils: else: output = '%s(format = %s) = 0x%x' % (name, repr(fmt), len(fmt)) stdout = fmt - logging.info(output) + self.ql.log.info(output) self.ql.os.stdout.write(bytes(stdout, 'utf-8')) return len(stdout), stdout @@ -603,7 +604,7 @@ class QlOsUtils: #print("32 irpstack offset = 0x%x" %IRP32.irpstack.offset) #print("irp at %x, irpstack at %x" %(irp_addr, irpstack_addr)) - logging.info("IRP is at 0x%x, IO_STACK_LOCATION is at 0x%x" %(irp_addr, irpstack_addr)) + self.ql.log.info("IRP is at 0x%x, IO_STACK_LOCATION is at 0x%x" %(irp_addr, irpstack_addr)) irpstack.Parameters.DeviceIoControl.IoControlCode = ioctl_code(devicetype, function, ctl_method, access) irpstack.Parameters.DeviceIoControl.OutputBufferLength = output_buffer_size @@ -642,7 +643,7 @@ class QlOsUtils: self.ql.mem.write(irp_addr, bytes(irp)) # set function args - logging.info("Executing IOCTL with DeviceObject = 0x%x, IRP = 0x%x" %(self.ql.loader.driver_object.DeviceObject, irp_addr)) + self.ql.log.info("Executing IOCTL with DeviceObject = 0x%x, IRP = 0x%x" %(self.ql.loader.driver_object.DeviceObject, irp_addr)) self.set_function_args((self.ql.loader.driver_object.DeviceObject, irp_addr)) try: diff --git a/qiling/os/windows/dlls/advapi32.py b/qiling/os/windows/dlls/advapi32.py index a8884695..902e1958 100644 --- a/qiling/os/windows/dlls/advapi32.py +++ b/qiling/os/windows/dlls/advapi32.py @@ -2,7 +2,8 @@ # # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import struct, logging +import struct + from qiling.os.windows.fncc import * from qiling.os.const import * from qiling.os.windows.utils import * @@ -16,10 +17,10 @@ def _RegOpenKey(ql, address, params): hKey = params["hKey"] s_lpSubKey = params["lpSubKey"] phkResult = params["phkResult"] - logging.debug("[+] Key %s %s" % (hKey, s_lpSubKey)) + ql.log.debug("[+] Key %s %s" % (hKey, s_lpSubKey)) if hKey not in REG_KEYS: - logging.debug("[!] Key %s %s not present" % (hKey, s_lpSubKey)) + ql.log.debug("[!] Key %s %s not present" % (hKey, s_lpSubKey)) return ERROR_FILE_NOT_FOUND else: s_hKey = REG_KEYS[hKey] @@ -28,11 +29,11 @@ def _RegOpenKey(ql, address, params): # Keys in the profile are saved as KEY\PARAM = VALUE, so i just want to check that the key is the same keys_profile = [key.rsplit("\\", 1)[0] for key in ql.os.profile["REGISTRY"].keys()] if key.lower() in keys_profile: - logging.debug("[+] Using profile for key of %s" % key) + ql.log.debug("[+] Using profile for key of %s" % key) ql.os.registry_manager.access(key) else: if not ql.os.registry_manager.exists(key): - logging.debug("[!] Value key %s not present" % key) + ql.log.debug("[!] Value key %s not present" % key) return ERROR_FILE_NOT_FOUND # new handle @@ -61,7 +62,7 @@ def RegQueryValue(ql, address, params): try: # Keys in the profile are saved as KEY\PARAM = VALUE, so i just want to check that the key is the same value = ql.os.profile["REGISTRY"][s_hKey + "\\" + s_lpValueName] - logging.debug("[+] Using profile for value of key %s" % (s_hKey + "\\" + s_lpValueName,)) + ql.log.debug("[+] Using profile for value of key %s" % (s_hKey + "\\" + s_lpValueName,)) # TODO i have no fucking idea on how to set a None value, fucking configparser if value == "None": return ERROR_FILE_NOT_FOUND @@ -75,7 +76,7 @@ def RegQueryValue(ql, address, params): # error key if reg_type is None or value is None: - logging.debug("[!] Key value not found") + ql.log.debug("[!] Key value not found") return ERROR_FILE_NOT_FOUND else: # set lpData @@ -407,7 +408,7 @@ def hook_GetTokenInformation(ql, address, params): information_value = token.get(information) ql.mem.write(return_point, len(information_value).to_bytes(4, byteorder="little")) return_size = int.from_bytes(ql.mem.read(return_point, 4), byteorder="little") - logging.debug("[=] The target is checking for its permissions") + ql.log.debug("[=] The target is checking for its permissions") if return_size > max_size: ql.os.last_error = ERROR_INSUFFICIENT_BUFFER return 0 diff --git a/qiling/os/windows/dlls/cng.py b/qiling/os/windows/dlls/cng.py index aa514ea0..c28686f8 100644 --- a/qiling/os/windows/dlls/cng.py +++ b/qiling/os/windows/dlls/cng.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.os.windows.const import * from qiling.os.windows.fncc import * from qiling.os.const import * @@ -52,5 +52,5 @@ def hook_RtlGetVersion(ql, address, params): ql.os.profile.getint("SYSTEM", "minorVersion").to_bytes(4, byteorder="little")) - logging.debug("[=] The sample is checking the windows Version!") + ql.log.debug("[=] The sample is checking the windows Version!") return STATUS_SUCCESS diff --git a/qiling/os/windows/dlls/crypt32.py b/qiling/os/windows/dlls/crypt32.py index 7a208876..ab7cbec6 100644 --- a/qiling/os/windows/dlls/crypt32.py +++ b/qiling/os/windows/dlls/crypt32.py @@ -4,7 +4,7 @@ # import struct import base64 -import logging + from qiling.os.windows.fncc import * from qiling.os.const import * from qiling.os.windows.utils import * @@ -42,8 +42,8 @@ def hook_CryptStringToBinaryA(ql, address, params): string_src += "=" * add_pad output = base64.b64decode(string_src).decode("utf-16le") + "\x00" else: - logging.debug("Flag") - logging.debug(flag_src) + ql.log.debug("Flag") + ql.log.debug(flag_src) raise QlErrorNotImplemented("[!] API not implemented") if string_dst == 0: diff --git a/qiling/os/windows/dlls/kernel32/debugapi.py b/qiling/os/windows/dlls/kernel32/debugapi.py index 1cd642f6..f02aa124 100644 --- a/qiling/os/windows/dlls/kernel32/debugapi.py +++ b/qiling/os/windows/dlls/kernel32/debugapi.py @@ -5,7 +5,8 @@ import struct import time -import logging + + from qiling.os.windows.const import * from qiling.os.const import * from qiling.os.windows.fncc import * @@ -40,7 +41,7 @@ def hook_CheckRemoteDebuggerPresent(ql, address, params): @winsdkapi(cc=STDCALL, dllname=dllname) def hook_OutputDebugStringW(ql, address, params): string = params["lpOutputString"] - logging.info('OutputDebugStringW: "%s"' % (string.encode())) + ql.log.info('OutputDebugStringW: "%s"' % (string.encode())) return 0 @@ -49,5 +50,5 @@ def hook_OutputDebugStringW(ql, address, params): # ); @winsdkapi(cc=STDCALL, dllname=dllname) def hook_OutputDebugStringA(ql, address, params): - logging.info('OutputDebugStringA: "%s"' % (params['lpOutputString'])) + ql.log.info('OutputDebugStringA: "%s"' % (params['lpOutputString'])) return 0 diff --git a/qiling/os/windows/dlls/kernel32/fileapi.py b/qiling/os/windows/dlls/kernel32/fileapi.py index 82402968..fa7b0eca 100644 --- a/qiling/os/windows/dlls/kernel32/fileapi.py +++ b/qiling/os/windows/dlls/kernel32/fileapi.py @@ -3,11 +3,12 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import struct, time, os, logging +import struct, time, os from shutil import copyfile from datetime import datetime + from qiling.exception import * from qiling.os.windows.const import * @@ -143,7 +144,7 @@ def hook_ReadFile(ql, address, params): # TODO maybe insert a good random generation input s = (b"A" * (nNumberOfBytesToRead - 1)) + b"\x00" else: - logging.debug("Insert input") + ql.log.debug("Insert input") s = ql.os.stdin.read(nNumberOfBytesToRead) slen = len(s) read_len = slen diff --git a/qiling/os/windows/dlls/kernel32/libloaderapi.py b/qiling/os/windows/dlls/kernel32/libloaderapi.py index ddd10153..278e7cbc 100644 --- a/qiling/os/windows/dlls/kernel32/libloaderapi.py +++ b/qiling/os/windows/dlls/kernel32/libloaderapi.py @@ -4,7 +4,7 @@ # import os -import logging + from qiling.exception import * from qiling.os.windows.const import * @@ -29,7 +29,7 @@ def _GetModuleHandle(ql, address, params): if lpModuleName in ql.loader.dlls: ret = ql.loader.dlls[lpModuleName] else: - logging.debug("[!] Library %s not imported" % lpModuleName) + ql.log.debug("[!] Library %s not imported" % lpModuleName) ret = 0 return ret @@ -87,7 +87,7 @@ def hook_GetModuleFileNameA(ql, address, params): ret = filename_len ql.mem.write(lpFilename, filename + b"\x00") else: - logging.debug("hModule %x" % hModule) + ql.log.debug("hModule %x" % hModule) raise QlErrorNotImplemented("[!] API not implemented") return ret @@ -140,7 +140,7 @@ def hook_GetProcAddress(ql, address, params): try: dll_name = [key for key, value in ql.loader.dlls.items() if value == params['hModule']][0] except IndexError as ie: - logging.info('[!] Failed to import function "%s" with handle 0x%X' % (lpProcName, params['hModule'])) + ql.log.info('[!] Failed to import function "%s" with handle 0x%X' % (lpProcName, params['hModule'])) return 0 # Handle case where module is self diff --git a/qiling/os/windows/dlls/kernel32/memoryapi.py b/qiling/os/windows/dlls/kernel32/memoryapi.py index ae33277c..48721caf 100644 --- a/qiling/os/windows/dlls/kernel32/memoryapi.py +++ b/qiling/os/windows/dlls/kernel32/memoryapi.py @@ -5,7 +5,7 @@ import struct import time -import logging + from qiling.os.windows.const import * from qiling.os.const import * from qiling.os.windows.fncc import * @@ -81,7 +81,7 @@ def hook_VirtualQuery(ql, address, params): if not base and not size: # Page not found # printable = sorted(['0x%x-0x%x' % (chunk.address, chunk.address+chunk.size) for chunk in ql.os.heap.chunks]) - # logging.debug('Could not find memory chunk containing address 0x%x in %s' % (params['lpAddress'], + # ql.log.debug('Could not find memory chunk containing address 0x%x in %s' % (params['lpAddress'], # printable)) ql.os.last_error = ERROR_INVALID_PARAMETER return 0 diff --git a/qiling/os/windows/dlls/kernel32/processenv.py b/qiling/os/windows/dlls/kernel32/processenv.py index 75d97c90..3cc744bd 100644 --- a/qiling/os/windows/dlls/kernel32/processenv.py +++ b/qiling/os/windows/dlls/kernel32/processenv.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.os.windows.fncc import * from qiling.exception import * @@ -80,7 +80,7 @@ def hook_ExpandEnvironmentStringsW(ql, address, params): substring = string[start + 1:end] result = ql.os.profile["PATH"].get(substring, None) if result is None: - logging.debug(substring) + ql.log.debug(substring) raise QlErrorNotImplemented("[!] API not implemented") result = (string[:start] + result + string[end + 1:] + "\x00").encode("utf-16le") dst = params["lpDst"] diff --git a/qiling/os/windows/dlls/kernel32/tlhelp32.py b/qiling/os/windows/dlls/kernel32/tlhelp32.py index 4dbc426b..acbcd8c6 100644 --- a/qiling/os/windows/dlls/kernel32/tlhelp32.py +++ b/qiling/os/windows/dlls/kernel32/tlhelp32.py @@ -5,7 +5,6 @@ import struct import time -import logging from qiling.os.windows.const import * from qiling.os.const import * from qiling.os.windows.fncc import * @@ -27,7 +26,7 @@ def hook_CreateToolhelp32Snapshot(ql, address, params): # TODO thinking about implementing an handler, gonna see if is really necessary flag = params["dwFlags"] if flag == TH32CS_SNAPPROCESS: - logging.debug("[=] The target is checking every process!") + ql.log.debug("[=] The target is checking every process!") else: raise QlErrorNotImplemented("[!] API not implemented") return 0xD10C diff --git a/qiling/os/windows/dlls/kernel32/winbase.py b/qiling/os/windows/dlls/kernel32/winbase.py index cf7dc537..d4ea4818 100644 --- a/qiling/os/windows/dlls/kernel32/winbase.py +++ b/qiling/os/windows/dlls/kernel32/winbase.py @@ -7,9 +7,10 @@ from qiling.os.windows.const import * from qiling.os.windows.fncc import * from qiling.os.windows.thread import * from qiling.exception import * -import configparser, logging +import configparser from qiling.os.windows.structs import * + dllname = 'kernel32_dll' # __analysis_noreturn VOID FatalExit( @@ -353,12 +354,12 @@ def hook_VerifyVersionInfoW(ql, address, params): # Just a print for analysts, will remove it from here in the future if key == VER_MAJORVERSION: - logging.debug("[=] The Target is checking the windows Version!") + ql.log.debug("[=] The Target is checking the windows Version!") version_asked = SYSTEMS_VERSION.get(concat, None) if version_asked is None: raise QlErrorNotImplemented("[!] API not implemented for version %s" % concat) else: - logging.debug("[=] The target asks for version %s %s" % (operator, version_asked)) + ql.log.debug("[=] The target asks for version %s %s" % (operator, version_asked)) # We can finally compare qiling_os = str(ql.os.profile.get("SYSTEM", "majorVersion")) + str( ql.os.profile.get("SYSTEM", "minorVersion")) + str( diff --git a/qiling/os/windows/dlls/msvcrt.py b/qiling/os/windows/dlls/msvcrt.py index 2769f6a4..7587e568 100644 --- a/qiling/os/windows/dlls/msvcrt.py +++ b/qiling/os/windows/dlls/msvcrt.py @@ -5,7 +5,7 @@ import os import time -import logging + from qiling.os.windows.fncc import * from qiling.os.const import * from qiling.os.windows.const import * @@ -162,7 +162,7 @@ def hook___p___argv(ql, address, params): # int* __p___argc(void) @winsdkapi(cc=CDECL) def hook___p___argc(ql, address, params): - logging.debug("_p___argc") + ql.log.debug("_p___argc") ret = ql.os.heap.alloc(ql.pointersize) ql.mem.write(ret, ql.pack(len(ql.argv))) return ret @@ -188,7 +188,7 @@ def hook_sprintf(ql, address, _): str_ptr, format_ptr = ql.os.get_function_param(2) if not format_ptr: - logging.info('printf(format = 0x0) = 0x%x' % ret) + ql.log.info('printf(format = 0x0) = 0x%x' % ret) return ret sp = ql.reg.esp if ql.archtype == QL_ARCH.X86 else ql.reg.rsp @@ -196,7 +196,7 @@ def hook_sprintf(ql, address, _): format_string = ql.os.read_cstring(format_ptr) str_size, str_data = ql.os.vprintf(address, format_string, p_args, "sprintf") - logging.info() + ql.log.info() count = format_string.count('%') if ql.archtype == QL_ARCH.X8664: @@ -216,7 +216,7 @@ def hook_printf(ql, address, _): format_string = ql.os.get_function_param(1) if format_string == 0: - logging.info('printf(format = 0x0) = 0x%x' % ret) + ql.log.info('printf(format = 0x0) = 0x%x' % ret) return ret format_string = ql.os.read_cstring(format_string) @@ -243,7 +243,7 @@ def hook_wprintf(ql, address, _): format_string = ql.os.get_function_param(1) if format_string == 0: - logging.info('wprintf(format = 0x0) = 0x%x' % ret) + ql.log.info('wprintf(format = 0x0) = 0x%x' % ret) return ret format_string = ql.os.read_wstring(format_string) diff --git a/qiling/os/windows/dlls/ntdll.py b/qiling/os/windows/dlls/ntdll.py index f1e9f47e..91e79477 100644 --- a/qiling/os/windows/dlls/ntdll.py +++ b/qiling/os/windows/dlls/ntdll.py @@ -3,7 +3,9 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import struct, logging +import struct + + from qiling.os.windows.const import * from qiling.os.windows.fncc import * from qiling.os.const import * @@ -26,7 +28,7 @@ def hook_memcpy(ql, address, params): data = bytes(ql.mem.read(params['src'], params['count'])) ql.mem.write(params['dest'], data) except Exception as e: - logging.exception("") + ql.log.exception("") return params['dest'] @@ -50,9 +52,9 @@ def _QueryInformationProcess(ql, address, params): pbi.write(addr) value = addr.to_bytes(ql.pointersize, "little") else: - logging.debug(str(flag)) + ql.log.debug(str(flag)) raise QlErrorNotImplemented("[!] API not implemented") - logging.debug("[=] The target is checking the debugger via QueryInformationProcess ") + ql.log.debug("[=] The target is checking the debugger via QueryInformationProcess ") ql.mem.write(dst, value) if pt_res != 0: ql.mem.write(pt_res, 0x8.to_bytes(1, byteorder="little")) @@ -129,7 +131,7 @@ def _QuerySystemInformation(ql, address, params): ql.mem.write(pt_res, sbi.size.to_bytes(1, byteorder="little")) return STATUS_INFO_LENGTH_MISMATCH else: - logging.debug(str(siClass)) + ql.log.debug(str(siClass)) raise QlErrorNotImplemented("[!] API not implemented") @@ -194,8 +196,8 @@ def hook_ZwQueryObject(ql, address, params): size_dest = params["ReturnLength"] string = "DebugObject".encode("utf-16le") string_addr = ql.os.heap.alloc(len(string)) - logging.debug(str(string_addr)) - logging.debug(str(string)) + ql.log.debug(str(string_addr)) + ql.log.debug(str(string)) ql.mem.write(string_addr, string) us = qiling.os.windows.structs.UnicodeString(ql, length=len(string), maxLength=len(string), buffer=string_addr) @@ -246,9 +248,9 @@ def _SetInformationProcess(ql, address, params): elif flag == ProcessDebugObjectHandle: return STATUS_PORT_NOT_SET elif flag == ProcessBreakOnTermination: - logging.debug("[=] The target may be attempting modify a the 'critical' flag of the process") + ql.log.debug("[=] The target may be attempting modify a the 'critical' flag of the process") elif flag == ProcessExecuteFlags: - logging.debug("[=] The target may be attempting to modify DEP for the process") + ql.log.debug("[=] The target may be attempting to modify DEP for the process") if dst != 0: ql.mem.write(dst, 0x0.to_bytes(1, byteorder="little")) @@ -260,12 +262,12 @@ def _SetInformationProcess(ql, address, params): uniqueId=ql.os.profile.getint("KERNEL", "pid"), parentPid=ql.os.profile.geting("KERNEL", "parent_pid") ) - logging.debug("[=] The target may be attempting to modify the PEB debug flag") + ql.log.debug("[=] The target may be attempting to modify the PEB debug flag") addr = ql.os.heap.alloc(pbi.size) pbi.write(addr) value = addr.to_bytes(ql.pointersize, "little") else: - logging.debug(str(flag)) + ql.log.debug(str(flag)) raise QlErrorNotImplemented("[!] API not implemented") return STATUS_SUCCESS @@ -297,7 +299,7 @@ def hook_LdrGetProcedureAddress(ql, address, params): try: dll_name = [key for key, value in ql.loader.dlls.items() if value == params['ModuleHandle']][0] except IndexError as ie: - logging.info('[!] Failed to import function "%s" with handle 0x%X' % (lpProcName, params['ModuleHandle'])) + ql.log.info('[!] Failed to import function "%s" with handle 0x%X' % (lpProcName, params['ModuleHandle'])) return 0 if identifier in ql.loader.import_address_table[dll_name]: diff --git a/qiling/os/windows/dlls/ntoskrnl.py b/qiling/os/windows/dlls/ntoskrnl.py index 69e3dc70..8c646e6f 100644 --- a/qiling/os/windows/dlls/ntoskrnl.py +++ b/qiling/os/windows/dlls/ntoskrnl.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging + from qiling.os.windows.const import * from qiling.os.windows.fncc import * from qiling.os.const import * @@ -37,7 +37,7 @@ def hook_RtlGetVersion(ql, address, params): os.major[0] = ql.os.profile.getint("SYSTEM", "majorVersion") os.minor[0] = ql.os.profile.getint("SYSTEM", "minorVersion") os.write(pointer) - logging.debug("[=] The target is checking the windows Version!") + ql.log.debug("[=] The target is checking the windows Version!") return STATUS_SUCCESS @@ -59,7 +59,7 @@ def hook_ZwSetInformationThread(ql, address, params): if size >= 100: return STATUS_INFO_LENGTH_MISMATCH if information == ThreadHideFromDebugger: - logging.debug("[=] The target is checking debugger via SetInformationThread") + ql.log.debug("[=] The target is checking debugger via SetInformationThread") if dst != 0: ql.mem.write(dst, 0x0.to_bytes(1, byteorder="little")) else: @@ -1097,7 +1097,7 @@ def hook_PsLookupProcessByProcessId(ql, address, params): else: addr = ql.os.heap.alloc(ctypes.sizeof(EPROCESS32)) ql.mem.write(Process, ql.pack(addr)) - logging.info("PID = 0x%x, addrof(EPROCESS) == 0x%x" % (ProcessId, addr)) + ql.log.info("PID = 0x%x, addrof(EPROCESS) == 0x%x" % (ProcessId, addr)) return STATUS_SUCCESS # NTSYSAPI NTSTATUS ZwOpenKey( @@ -1287,7 +1287,7 @@ def hook_ObOpenObjectByPointer(ql, address, params): new_handle = Handle(name="p=%x" % Object) ql.os.handle_manager.append(new_handle) ql.mem.write(point_to_new_handle, ql.pack(new_handle.id)) - logging.info("New handle of 0x%x is 0x%x" % (Object, new_handle.id)) + ql.log.info("New handle of 0x%x is 0x%x" % (Object, new_handle.id)) return STATUS_SUCCESS @winsdkapi(cc=CDECL, dllname=dllname) diff --git a/qiling/os/windows/dlls/shell32.py b/qiling/os/windows/dlls/shell32.py index 01ca5605..8d6432b0 100644 --- a/qiling/os/windows/dlls/shell32.py +++ b/qiling/os/windows/dlls/shell32.py @@ -3,7 +3,8 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import struct, time, os, logging +import struct, time, os + from qiling.os.windows.const import * from qiling.os.const import * @@ -42,7 +43,7 @@ def hook_SHGetFileInfoW(ql, address, params): if flags == SHGFI_LARGEICON: return 1 else: - logging.debug(flags) + ql.log.debug(flags) raise QlErrorNotImplemented("[!] API not implemented") @@ -53,13 +54,13 @@ def _ShellExecute(ql, obj: ShellExecuteInfoA): file = ql.os.read_wstring(obj.file[0]) if obj.file[0] != 0 else "" directory = ql.os.read_wstring(obj.dir[0]) if obj.dir[0] != 0 else "" - logging.debug("[=] Target executed a shell command!") - logging.debug("[-] Operation: %s " % operation) - logging.debug("[-] Parameters: %s " % params) - logging.debug("[-] File: %s " % file) - logging.debug("[-] Directory: %s " % directory) + ql.log.debug("[=] Target executed a shell command!") + ql.log.debug("[-] Operation: %s " % operation) + ql.log.debug("[-] Parameters: %s " % params) + ql.log.debug("[-] File: %s " % file) + ql.log.debug("[-] Directory: %s " % directory) if obj.show[0] == SW_HIDE: - logging.debug("[=] With an hidden window") + ql.log.debug("[=] With an hidden window") process = QlWindowsThread(ql, status=0, isFake=True) handle = Handle(obj=process) ql.os.handle_manager.append(handle) @@ -115,17 +116,17 @@ def hook_SHGetSpecialFolderPathW(ql, address, params): path = str(ql.os.userprofile + "AppData\\") # We always create the directory appdata_dir = path.split("C:\\")[1].replace("\\", "/") - logging.debug("[+] dir path: %s" % path) + ql.log.debug("[+] dir path: %s" % path) path_emulated = os.path.join(ql.rootfs, appdata_dir) - logging.debug("[!] emulated path: %s" % path_emulated) + ql.log.debug("[!] emulated path: %s" % path_emulated) ql.mem.write(dst, (path + "\x00").encode("utf-16le")) # FIXME: Somehow winodws path is wrong if not os.path.exists(path_emulated): try: os.makedirs(path_emulated, 0o755) - logging.debug("[!] os.makedirs completed") + ql.log.debug("[!] os.makedirs completed") except OSError: - logging.debug("[!] os.makedirs fail") + ql.log.debug("[!] os.makedirs fail") else: raise QlErrorNotImplemented("[!] API not implemented") return 1 diff --git a/qiling/os/windows/dlls/user32.py b/qiling/os/windows/dlls/user32.py index b60ee4db..8247a448 100644 --- a/qiling/os/windows/dlls/user32.py +++ b/qiling/os/windows/dlls/user32.py @@ -4,7 +4,7 @@ # import struct -import logging + from qiling.os.windows.fncc import * from qiling.os.const import * @@ -142,7 +142,7 @@ def hook_GetClipboardData(ql, address, params): ql.mem.write(addr, data) return addr else: - logging.debug('Failed to get clipboard data') + ql.log.debug('Failed to get clipboard data') return 0 @@ -169,10 +169,10 @@ def hook_MapVirtualKeyW(ql, address, params): if code is not None: return code else: - logging.debug("Code value %x" % code_value) + ql.log.debug("Code value %x" % code_value) raise QlErrorNotImplemented("[!] API not implemented") else: - logging.debug("Map value %x" % map_value) + ql.log.debug("Map value %x" % map_value) raise QlErrorNotImplemented("[!] API not implemented") @@ -182,7 +182,7 @@ def hook_MapVirtualKeyW(ql, address, params): @winsdkapi(cc=STDCALL, dllname=dllname, replace_params_type={'int': 'UINT'}) def hook_GetKeyState(ql, address, params): let = chr(params["nVirtKey"]) - logging.debug(let) + ql.log.debug(let) UP = 2 DOWN = 0 return UP @@ -243,7 +243,7 @@ def hook_GetSystemMetrics(ql, address, params): elif info == SM_CYHSCROLL: return 300 else: - logging.debug("Info value %x" % info) + ql.log.debug("Info value %x" % info) raise QlErrorNotImplemented("[!] API not implemented") @@ -659,7 +659,7 @@ def hook_MessageBoxW(ql, address, params): if type_box == MB_YESNO or type_box == MB_YESNOCANCEL: return IDYES else: - logging.debug(type_box) + ql.log.debug(type_box) raise QlErrorNotImplemented("[!] API not implemented") diff --git a/qiling/os/windows/dlls/wsock32.py b/qiling/os/windows/dlls/wsock32.py index cc0dbc46..89388cc9 100644 --- a/qiling/os/windows/dlls/wsock32.py +++ b/qiling/os/windows/dlls/wsock32.py @@ -4,7 +4,8 @@ # import struct -import logging + + from qiling.os.windows.const import * from qiling.os.windows.fncc import * from qiling.os.const import * @@ -56,10 +57,10 @@ def hook_connect(ql, address, params): [str(octet) for octet in ql.mem.read(params["name"] + 4, 4)] ) else: - logging.debug("[!] sockaddr sin_family unhandled variant") + ql.log.debug("[!] sockaddr sin_family unhandled variant") return 0 - logging.debug(f"0x{params['name']:08x}: sockaddr_in{6 if sin_family == 0x17 else ''}", + ql.log.debug(f"0x{params['name']:08x}: sockaddr_in{6 if sin_family == 0x17 else ''}", f"{{sin_family=0x{sin_family:02x}, sin_port={sin_port}, sin_addr={sin_addr}}}", sep="", ) diff --git a/qiling/os/windows/fiber.py b/qiling/os/windows/fiber.py index 7febc9f2..0a420a36 100644 --- a/qiling/os/windows/fiber.py +++ b/qiling/os/windows/fiber.py @@ -4,7 +4,6 @@ # # A Simple Windows Clipboard Simulation -import logging from unicorn import * from unicorn.x86_const import * @@ -37,7 +36,7 @@ class FiberManager: else: fiber = self.fibers[idx] if fiber.cb: - logging.debug("Skipping emulation of callback function 0x%X for fiber 0x%X" % (fiber.cb, fiber.idx)) + self.ql.log.debug("Skipping emulation of callback function 0x%X for fiber 0x%X" % (fiber.cb, fiber.idx)) """ ret_addr = self.ql.reg.read(UC_X86_REG_RIP + 6 ) #FIXME, use capstone to get addr of next instr? @@ -52,7 +51,7 @@ class FiberManager: else: self.ql.stack_push(ret_addr) self.ql.stack_push(ret_addr) - logging.debug("Jumping to callback @ 0x%X" % fiber.cb) + self.ql.log.debug("Jumping to callback @ 0x%X" % fiber.cb) self.ql.reg.write(UC_X86_REG_RIP, fiber.cb) # All of this gets overwritten by the rest of the code in fncc.py # Not sure how to actually make unicorn emulate the callback function due to that diff --git a/qiling/os/windows/fncc.py b/qiling/os/windows/fncc.py index 406ddc8f..7cca2530 100644 --- a/qiling/os/windows/fncc.py +++ b/qiling/os/windows/fncc.py @@ -3,10 +3,11 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import json, logging, os, struct +import json, os, struct from functools import wraps + from qiling.os.const import * from qiling.os.windows.utils import * from qiling.const import * @@ -53,7 +54,7 @@ def winsdkapi(cc, param_num=None, dllname=None, replace_params_type=None, replac with open(winsdk_path, 'r') as f: funclist = json.load(f) else: - logging.info('[!] %s not found', winsdk_path) + ql.log.info('[!] %s not found', winsdk_path) if funcname not in funclist: params = replace_params else: diff --git a/qiling/os/windows/registry.py b/qiling/os/windows/registry.py index 65dba361..d9e366cb 100644 --- a/qiling/os/windows/registry.py +++ b/qiling/os/windows/registry.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import json, logging, os, sys +import json, os, sys from Registry import Registry @@ -11,6 +11,7 @@ from qiling.os.windows.const import * from qiling.exception import * from qiling.const import * + # Registry Manager reads data from two places # 1. config.json # if you want to modify the registry key/value, you can modify config.json @@ -25,12 +26,12 @@ from qiling.const import * class RegistryManager: def __init__(self, ql, hive=None): self.ql = ql - self.log_registry_dir = self.ql.log_dir + self.log_registry_dir = self.ql.rootfs if self.log_registry_dir == None: self.log_registry_dir = "qlog" - self.registry_diff = self.ql.targetname + "_" + self.ql.append + ".json" + self.registry_diff = self.ql.targetname + "_diff.json" self.regdiff = os.path.join(self.log_registry_dir, "registry", self.registry_diff) # hive dir @@ -38,7 +39,7 @@ class RegistryManager: self.hive = hive else: self.hive = os.path.join(ql.rootfs, "Windows", "registry") - logging.debug("[+] Windows Registry PATH: %s" % self.hive) + ql.log.debug("[+] Windows Registry PATH: %s" % self.hive) if not os.path.exists(self.hive) and not self.ql.shellcoder: raise QlErrorFileNotFound(f"Error: Registry files not found in '{self.hive}'!") diff --git a/qiling/os/windows/structs.py b/qiling/os/windows/structs.py index 8ba9b2ab..482c9469 100644 --- a/qiling/os/windows/structs.py +++ b/qiling/os/windows/structs.py @@ -3,12 +3,13 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import ctypes, logging, struct +import ctypes, struct from enum import IntEnum from unicorn.x86_const import * + from qiling.const import * from qiling.os.windows.handle import * from qiling.exception import * @@ -1651,20 +1652,20 @@ class WindowsStruct: raise NotImplementedError def generic_write(self, addr: int, attributes: list): - logging.debug("[+] Writing Windows object " + self.__class__.__name__) + self.ql.log.debug("[+] Writing Windows object " + self.__class__.__name__) already_written = 0 for elem in attributes: (val, size, endianness, typ) = elem if typ == int: value = val.to_bytes(size, endianness) - logging.debug("[+] Writing to %d with value %s" % (addr + already_written, value)) + self.ql.log.debug("[+] Writing to %d with value %s" % (addr + already_written, value)) self.ql.mem.write(addr + already_written, value) elif typ == bytes: if isinstance(val, bytearray): value = bytes(val) else: value = val - logging.debug("[+] Writing at addr %d value %s" % (addr + already_written, value)) + self.ql.log.debug("[+] Writing at addr %d value %s" % (addr + already_written, value)) self.ql.mem.write(addr + already_written, value) elif issubclass(typ, WindowsStruct): @@ -1676,12 +1677,12 @@ class WindowsStruct: self.addr = addr def generic_read(self, addr: int, attributes: list): - logging.debug("[+] Reading Windows object " + self.__class__.__name__) + self.ql.log.debug("[+] Reading Windows object " + self.__class__.__name__) already_read = 0 for elem in attributes: (val, size, endianness, type) = elem value = self.ql.mem.read(addr + already_read, size) - logging.debug("[+] Reading from %d value %s" % (addr + already_read, value)) + self.ql.log.debug("[+] Reading from %d value %s" % (addr + already_read, value)) if type == int: elem[0] = int.from_bytes(value, endianness) elif type == bytes: diff --git a/qiling/os/windows/utils.py b/qiling/os/windows/utils.py index 350df68d..e4f01000 100644 --- a/qiling/os/windows/utils.py +++ b/qiling/os/windows/utils.py @@ -3,11 +3,12 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging, ntpath, os, uuid +import ntpath, os, uuid from sys import getsizeof from qiling.const import * + from qiling.os.const import * from .registry import RegistryManager from .clipboard import Clipboard @@ -18,7 +19,7 @@ from .structs import UNICODE_STRING32, UNICODE_STRING64 def ql_x86_windows_hook_mem_error(ql, access, addr, size, value): - logging.debug("[+] ERROR: unmapped memory access at 0x%x" % addr) + ql.log.debug("[+] ERROR: unmapped memory access at 0x%x" % addr) return False @@ -56,9 +57,9 @@ def print_function(ql, passthru, address, function_name, params, ret): if ql.output != QL_OUTPUT.DEBUG: log = log.partition(" ")[-1] - logging.info(log) + ql.log.info(log) else: - logging.debug(log) + ql.log.debug(log) def read_wstring(ql, address): @@ -111,9 +112,9 @@ def env_dict_to_array(env_dict): def debug_print_stack(ql, num, message=None): if message: - logging.debug("========== %s ==========" % message) + ql.log.debug("========== %s ==========" % message) sp = ql.reg.arch_sp - logging.debug(hex(sp + ql.pointersize * num) + ": " + hex(ql.stack_read(num * ql.pointersize))) + ql.log.debug(hex(sp + ql.pointersize * num) + ": " + hex(ql.stack_read(num * ql.pointersize))) def is_file_library(string): diff --git a/qiling/os/windows/windows.py b/qiling/os/windows/windows.py index 3f324597..975bb08e 100644 --- a/qiling/os/windows/windows.py +++ b/qiling/os/windows/windows.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import types, logging +import types from unicorn import * @@ -11,6 +11,7 @@ from qiling.arch.x86_const import * from qiling.arch.x86 import * from qiling.const import * from qiling.os.os import QlOs + from .dlls import * from .const import * from .utils import * @@ -112,12 +113,12 @@ class QlOsWindows(QlOs): winapi_func(self.ql, address, {}) except Exception: - logging.exception("") - logging.info("[!] %s Exception Found" % winapi_name) + self.ql.log.exception("") + self.ql.log.info("[!] %s Exception Found" % winapi_name) self.emu_error() raise QlErrorSyscallError("[!] Windows API Implementation Error") else: - logging.warning("[!] %s is not implemented" % winapi_name) + self.ql.log.warning("[!] %s is not implemented" % winapi_name) if self.ql.debug_stop: raise QlErrorSyscallNotFound("[!] Windows API Implementation Not Found") diff --git a/qiling/utils.py b/qiling/utils.py index b0eb62e8..7afa5dfd 100644 --- a/qiling/utils.py +++ b/qiling/utils.py @@ -7,7 +7,7 @@ This module is intended for general purpose functions that can be used thoughout the qiling framework """ -import importlib, logging, os, logging, copy, re, pefile, configparser +import importlib, os, copy, re, pefile, configparser, logging from logging import LogRecord from pathlib import Path @@ -19,8 +19,8 @@ from .exception import * from .const import QL_ARCH, QL_ARCH_ALL, QL_ENDIAN, QL_OS, QL_OS_ALL, QL_OUTPUT, QL_DEBUGGER, QL_ARCH_32BIT, QL_ARCH_64BIT, QL_ARCH_16BIT from .const import debugger_map, arch_map, os_map -FMT_STR = "[%(levelname)s] [%(filename)s:%(lineno)d]\t%(message)s" - +FMT_STR = "%(levelname)s\t%(message)s" + # \033 -> ESC # ESC [ -> CSI # CSI %d;%d;... m -> SGR @@ -42,43 +42,55 @@ LEVEL_COLORS = { 'CRITICAL': COLOR_CODE.CRIMSON, 'ERROR': COLOR_CODE.RED } - -LEVEL_NAME = { - 'WARNING': f"{COLOR_CODE.YELLOW}!{COLOR_CODE.ENDC}", - 'INFO': f"{COLOR_CODE.BLUE}={COLOR_CODE.ENDC}", - 'DEBUG': f"{COLOR_CODE.MAGENTA}+{COLOR_CODE.ENDC}", - 'CRITICAL': f"{COLOR_CODE.CRIMSON}!{COLOR_CODE.ENDC}", - 'ERROR': f"{COLOR_CODE.RED}x{COLOR_CODE.ENDC}" -} - -class ColoredFormatter(logging.Formatter): - def __init__(self, *args, **kwargs): - super(ColoredFormatter, self).__init__(*args, **kwargs) - - def get_colored_level(self, record: LogRecord): - levelname = record.levelname - return LEVEL_NAME[levelname] - - def format(self, record: LogRecord): - _record = copy.copy(record) - _record.levelname = self.get_colored_level(_record) - return super(ColoredFormatter, self).format(_record) - -class MultithreadColoredFormatter(ColoredFormatter): +class QilingColoredFormatter(logging.Formatter): def __init__(self, ql, *args, **kwargs): - super(MultithreadColoredFormatter, self).__init__(*args, **kwargs) + super(QilingColoredFormatter, self).__init__(*args, **kwargs) self._ql = ql + def get_colored_level(self, record: LogRecord): + LEVEL_NAME = { + 'WARNING': f"{COLOR_CODE.YELLOW}[!]{COLOR_CODE.ENDC}", + 'INFO': f"{COLOR_CODE.BLUE}[=]{COLOR_CODE.ENDC}", + 'DEBUG': f"{COLOR_CODE.MAGENTA}[+]{COLOR_CODE.ENDC}", + 'CRITICAL': f"{COLOR_CODE.CRIMSON}[x]{COLOR_CODE.ENDC}", + 'ERROR': f"{COLOR_CODE.RED}[x]{COLOR_CODE.ENDC}" + } + return LEVEL_NAME[record.levelname] + def format(self, record: LogRecord): + record.levelname = self.get_colored_level(record) try: cur_thread = self._ql.os.thread_management.cur_thread + if cur_thread is not None: + record.levelname = f"{record.levelname} {COLOR_CODE.GREEN}{str(cur_thread)}{COLOR_CODE.ENDC}" except AttributeError: - return super(MultithreadColoredFormatter, self).format(record) - _record = copy.copy(record) - levelname = self.get_colored_level(_record) - _record.levelname = f"{levelname}] [{COLOR_CODE.GREEN}Thread {cur_thread.id}{COLOR_CODE.ENDC}" - msg = super(ColoredFormatter, self).format(_record) - return msg + pass + return super(QilingColoredFormatter, self).format(record) + +class QilingPlainFormatter(logging.Formatter): + def __init__(self, ql, *args, **kwargs): + super(QilingPlainFormatter, self).__init__(*args, **kwargs) + self._ql = ql + + def get_level(self, record: LogRecord): + LEVEL_NAME = { + 'WARNING': "[!]", + 'INFO': "[=]", + 'DEBUG': "[+]", + 'CRITICAL': "[x]", + 'ERROR': "[x]" + } + return LEVEL_NAME[record.levelname] + + def format(self, record: LogRecord): + record.levelname = self.get_level(record) + try: + cur_thread = self._ql.os.thread_management.cur_thread + if cur_thread is not None: + record.levelname = f"{record.levelname} {str(cur_thread)}" + except AttributeError: + pass + return super(QilingPlainFormatter, self).format(record) class RegexFilter(logging.Filter): def __init__(self, filters): @@ -92,21 +104,6 @@ class RegexFilter(logging.Filter): return True return False -class MultithreadSplitHandler(logging.Handler): - def __init__(self, ql): - super(MultithreadSplitHandler, self).__init__() - self._ql = ql - - def emit(self, record: LogRecord): - msg = self.format(record) - try: - cur_thread = self._ql.os.thread_management.cur_thread - except AttributeError: - self._ql._msg_before_main_thread.append((record.levelno, msg)) - return - cur_thread.log_file_fd.log(record.levelno, msg) - - class QlFileDes: def __init__(self, init): self.__fds = init @@ -515,67 +512,51 @@ def ql_resolve_logger_level(output, verbose): level = logging.DEBUG elif verbose >= 1: level = logging.INFO - - logging.getLogger().setLevel(level) + + return level +QL_INSTANCE_ID = 114514 # TODO: qltool compatibility -def ql_setup_logger(ql, log_dir, log_filename, log_split, console, filter, multithread): - # Covered use cases: - # - Normal console output. - # - Write to a single file. - # - Write to splitted log files. - +def ql_setup_logger(ql, log_file, console, filter, multithread): + global QL_INSTANCE_ID + + # We should leave the root logger untouched. + log = logging.getLogger(f"qiling{QL_INSTANCE_ID}") + QL_INSTANCE_ID += 1 + # Clear all handlers and filters. - lger = logging.getLogger() - lger.handlers = [] - lger.filters = [] + log.handlers = [] + log.filters = [] # Do we have console output? if console: handler = logging.StreamHandler() - if multithread: - formatter = MultithreadColoredFormatter(ql, FMT_STR) - else: - formatter = ColoredFormatter(FMT_STR) - + formatter = QilingColoredFormatter(ql, FMT_STR) handler.setFormatter(formatter) - lger.addHandler(handler) + log.addHandler(handler) else: - logging.disable(level=logging.CRITICAL) - - # If log_dir isn't specified, return. - if log_dir is None or log_dir == "": - if log_split: - raise QlErrorOutput("log_split should be used with log_dir") - return + log.setLevel(logging.CRITICAL) - os.makedirs(log_dir, 0o755, exist_ok=True) - - # If we don't have to split logs, that's the most simple case. - if not log_split: - handler = logging.FileHandler(Path(log_dir) / log_filename) - handler.setFormatter(logging.Formatter(FMT_STR)) - lger.addHandler(handler) - else: - if multithread: - # A placeholder for messages before the first(main) thread is created. - ql._msg_before_main_thread = [] - handler = MultithreadSplitHandler(ql) - handler.setFormatter(logging.Formatter(FMT_STR)) - lger.addHandler(handler) - # For spliting logs with child process, we do that during fork. + # Do we have to write log to a file? + if log_file is not None: + handler = logging.FileHandler(log_file) + formatter = QilingPlainFormatter(ql, FMT_STR) + handler.setFormatter(formatter) + log.addHandler(handler) # Remeber to add filters. if filter is not None and type(filter) == list and len(filter) != 0: - lger.addFilter(RegexFilter(filter)) + log.addFilter(RegexFilter(filter)) - lger.setLevel(logging.INFO) + log.setLevel(logging.INFO) + + return log # verify if emulator returns properly def verify_ret(ql, err): - logging.debug("Got exception %u: init SP = %x, current SP = %x, PC = %x" %(err.errno, ql.os.init_sp, ql.reg.arch_sp, ql.reg.arch_pc)) + ql.log.debug("Got exception %u: init SP = %x, current SP = %x, PC = %x" %(err.errno, ql.os.init_sp, ql.reg.arch_sp, ql.reg.arch_pc)) # print("Got exception %u: init SP = %x, current SP = %x, PC = %x" %(err.errno, ql.os.init_sp, self.reg.arch_sp, self.reg.arch_pc)) ql.os.RUN = False diff --git a/tests/test_android.py b/tests/test_android.py index d130e973..373bf08e 100644 --- a/tests/test_android.py +++ b/tests/test_android.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import logging, os, sys, unittest +import os, sys, unittest sys.path.append("..") from qiling import * @@ -21,12 +21,12 @@ def syscall_getrandom(ql, buf, buflen, flags, *args, **kw): except: regreturn = -1 - logging.info("getrandom(0x%x, 0x%x, 0x%x) = %d" % + ql.log.info("getrandom(0x%x, 0x%x, 0x%x) = %d" % (buf, buflen, flags, regreturn)) if data: - logging.debug("[+] getrandom() CONTENT:") - logging.debug(str(data)) + ql.log.debug("[+] getrandom() CONTENT:") + ql.log.debug(str(data)) return regreturn @@ -43,11 +43,11 @@ def syscall_fstatfs(ql, fd, buf, *args, **kw): except: regreturn = -1 - logging.info("fstatfs(0x%x, 0x%x) = %d" % (fd, buf, regreturn)) + ql.log.info("fstatfs(0x%x, 0x%x) = %d" % (fd, buf, regreturn)) if data: - logging.debug("[+] fstatfs() CONTENT:") - logging.debug(str(data)) + ql.log.debug("[+] fstatfs() CONTENT:") + ql.log.debug(str(data)) return regreturn diff --git a/tests/test_elf.py b/tests/test_elf.py index 253ca237..be60a362 100644 --- a/tests/test_elf.py +++ b/tests/test_elf.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import sys, unittest, subprocess, string, random, os, logging +import sys, unittest, subprocess, string, random, os from unicorn import UcError, UC_ERR_READ_UNMAPPED, UC_ERR_FETCH_UNMAPPED @@ -268,7 +268,7 @@ class ELFTest(unittest.TestCase): all_mem = ql.mem.save() ql.mem.restore(all_mem) - ql = Qiling(["../examples/rootfs/arm_linux/bin/arm_hello"], "../examples/rootfs/arm_linux", output = "debug", profile='profiles/append_test.ql', log_split=True) + ql = Qiling(["../examples/rootfs/arm_linux/bin/arm_hello"], "../examples/rootfs/arm_linux", output = "debug", profile='profiles/append_test.ql') ql.set_api('puts', my_puts) ql.run() del ql @@ -706,7 +706,7 @@ class ELFTest(unittest.TestCase): regreturn = 0 buf = None mapaddr = ql.mem.map_anywhere(0x100000) - logging.info("0x%x" % mapaddr) + ql.log.info("0x%x" % mapaddr) reg = ql.reg.read("r0") print("reg : 0x%x" % reg) @@ -715,12 +715,12 @@ class ELFTest(unittest.TestCase): try: buf = ql.mem.read(write_buf, write_count) - logging.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn)) + ql.log.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn)) ql.os.fd[write_fd].write(buf) regreturn = write_count except: regreturn = -1 - logging.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn)) + ql.log.info("\n+++++++++\nmy write(%d,%x,%i) = %d\n+++++++++" % (write_fd, write_buf, write_count, regreturn)) if ql.output in (QL_OUTPUT.DEBUG, QL_OUTPUT.DUMP): raise self.set_syscall = reg @@ -821,7 +821,7 @@ class ELFTest(unittest.TestCase): self.id = fake_id fake_id += 1 ids.append(self.id) - logging.info(f"Creating Fake_urandom with id {self.id}") + ql.log.info(f"Creating Fake_urandom with id {self.id}") def read(self, size): return b'\x01' diff --git a/tests/test_elf_ko.py b/tests/test_elf_ko.py index f2d7c422..4e712e9e 100644 --- a/tests/test_elf_ko.py +++ b/tests/test_elf_ko.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import sys, unittest, subprocess, string, random, os, logging +import sys, unittest, subprocess, string, random, os from unicorn import UcError, UC_ERR_READ_UNMAPPED, UC_ERR_FETCH_UNMAPPED diff --git a/tests/test_elf_multithread.py b/tests/test_elf_multithread.py index 324f3d41..70f209a9 100644 --- a/tests/test_elf_multithread.py +++ b/tests/test_elf_multithread.py @@ -3,7 +3,7 @@ # Cross Platform and Multi Architecture Advanced Binary Emulation Framework # -import sys, unittest, subprocess, string, random, os, logging +import sys, unittest, subprocess, string, random, os from unicorn import UcError, UC_ERR_READ_UNMAPPED, UC_ERR_FETCH_UNMAPPED @@ -78,7 +78,7 @@ class ELFTest(unittest.TestCase): except: pass buf_out = None - ql = Qiling(["../examples/rootfs/x8664_linux/bin/x8664_multithreading"], "../examples/rootfs/x8664_linux", multithread=True, profile= "profiles/append_test.ql", log_split=True) + ql = Qiling(["../examples/rootfs/x8664_linux/bin/x8664_multithreading"], "../examples/rootfs/x8664_linux", multithread=True, profile= "profiles/append_test.ql") ql.set_syscall("write", check_write, QL_INTERCEPT.ENTER) ql.run() diff --git a/tests/test_pe.py b/tests/test_pe.py index 7080571d..7b635657 100644 --- a/tests/test_pe.py +++ b/tests/test_pe.py @@ -40,7 +40,7 @@ class PETest(unittest.TestCase): def test_pe_win_x86_hello(self): ql = Qiling(["../examples/rootfs/x86_windows/bin/x86_hello.exe"], "../examples/rootfs/x86_windows", - output="default", profile="profiles/append_test.ql", log_split=True) + output="default", profile="profiles/append_test.ql") ql.run() del ql @@ -220,9 +220,9 @@ class PETest(unittest.TestCase): if 'QL_FAST_TEST' in os.environ: return def stop(ql): - logging.info("killerswtichfound") - logging.disable(level=logging.CRITICAL) - logging.info("No Print") + ql.log.info("killerswtichfound") + log.setLevel(logging.CRITICAL) + ql.log.info("No Print") ql.emu_stop() ql = Qiling(["../examples/rootfs/x86_windows/bin/wannacry.bin"], "../examples/rootfs/x86_windows") diff --git a/tests/view_perf_results.py b/tests/view_perf_results.py index 57e81be1..2312114b 100644 --- a/tests/view_perf_results.py +++ b/tests/view_perf_results.py @@ -44,7 +44,6 @@ class QLGuiPerfApp(): self.scrollData.insert(INSERT, output_stream.getvalue()) self.highlight_pattern("qiling_highlight", "qiling") except Exception as e: - logging.exception("") msgbox.showerror("Error...", "Unable to load selected file") def highlight_pattern(self, tag, keyword):