Use ql.log instread of logging

This commit is contained in:
mio
2021-01-25 20:12:58 +08:00
parent d8edce6e69
commit 89fa357fab
106 changed files with 965 additions and 1013 deletions
+1
View File
@@ -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
+4 -6
View File
@@ -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)
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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()
+2 -2
View File
@@ -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
+2 -4
View File
@@ -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)
+4 -4
View File
@@ -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)
+2 -2
View File
@@ -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
+1 -1
View File
@@ -1,2 +1,2 @@
from .core import Qiling
from .__version__ import __version__
from .__version__ import __version__
+3 -4
View File
@@ -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
+2 -3
View File
@@ -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):
+35 -61
View File
@@ -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!')
###############
+1 -2
View File
@@ -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
+9 -9
View File
@@ -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)
+8 -8
View File
@@ -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)
+3 -2
View File
@@ -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):
+26 -25
View File
@@ -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
+29 -29
View File
@@ -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("<Q", self.ql.mem.read(loadbase + relocation.address, 8))
logging.debug("[+] Patching relocation (0x%x): from 0x%x, update to segment %s at 0x%x" % (loadbase + relocation.address, current_value, seg.name, loadbase + seg.vm_address))
self.ql.log.debug("[+] Patching relocation (0x%x): from 0x%x, update to segment %s at 0x%x" % (loadbase + relocation.address, current_value, seg.name, loadbase + seg.vm_address))
self.ql.mem.write(loadbase + relocation.address, struct.pack("<Q", current_value + loadbase ))
# Resolve dynamic symbols
@@ -242,7 +242,7 @@ class QlLoaderMACHO(QlLoader):
elif symname in self.kernel_extrn_symbols_detail:
real_addr = self.kernel_extrn_symbols_detail[symname]["n_value"]
else:
logging.info("[!] Static symbol %s not found" % symname)
self.ql.log.info("[!] Static symbol %s not found" % symname)
continue
self.ql.import_symbols[real_addr] = symname
lo_addr = real_addr & 0xffffffff
@@ -257,19 +257,19 @@ class QlLoaderMACHO(QlLoader):
else:
self.ql.mem.write(loadbase + relocation.address, struct.pack("<I", self.static_symbols[symname] - (loadbase + relocation.address + 4)))
# logging.info("[+] Patching relocation (0x%x): %s at 0x%x" % (loadbase + relocation.address, symname, self.static_symbols[symname]))
# ql.log.info("[+] Patching relocation (0x%x): %s at 0x%x" % (loadbase + relocation.address, symname, self.static_symbols[symname]))
continue
if relocation.extern == 0 or relocation.length != 3:
continue
if symname in self.kernel_local_symbols_detail:
# logging.debug("[+] Patching relocation (0x%x): %s at 0x%x" % (loadbase + relocation.address, symname, self.kernel_local_symbols_detail[symname]["n_value"]))
# ql.log.debug("[+] Patching relocation (0x%x): %s at 0x%x" % (loadbase + relocation.address, symname, self.kernel_local_symbols_detail[symname]["n_value"]))
self.ql.mem.write(loadbase + relocation.address, struct.pack("<Q", self.kernel_local_symbols_detail[symname]["n_value"]))
elif symname in self.kernel_extrn_symbols_detail:
# logging.debug("[+] Patching relocation (0x%x): %s at 0x%x" % (loadbase + relocation.address, symname, self.kernel_extrn_symbols_detail[symname]["n_value"]))
# ql.log.debug("[+] Patching relocation (0x%x): %s at 0x%x" % (loadbase + relocation.address, symname, self.kernel_extrn_symbols_detail[symname]["n_value"]))
self.ql.mem.write(loadbase + relocation.address, struct.pack("<Q", self.kernel_extrn_symbols_detail[symname]["n_value"]))
else:
logging.info("[!] Symbol %s not found!" % symname)
self.ql.log.info("[!] Symbol %s not found!" % symname)
# Update resolved symbols in table
self.loadbase = loadbase
@@ -287,7 +287,7 @@ class QlLoaderMACHO(QlLoader):
for symbol in self.macho_file.symbol_table.symbols:
if symbol.n_type == 0xf and "__const".ljust(16, "\x00") == self.macho_file.sections[symbol.n_sect].name:
symname = self.macho_file.string_table[symbol.n_strx]
logging.info("[+] Found vtable of %s at 0x%x" % (symname, loadbase + symbol.n_value))
self.ql.log.info("[+] Found vtable of %s at 0x%x" % (symname, loadbase + symbol.n_value))
self.vtables[symname] = loadbase + symbol.n_value
kext = self.plist["IOKitPersonalities"][self.kext_name]["IOClass"]
@@ -336,19 +336,19 @@ class QlLoaderMACHO(QlLoader):
if b"__realmain" in self.kext_local_symbols:
realmain = loadbase + self.kext_local_symbols[b"__realmain"]["n_value"]
current_value, = struct.unpack("<Q", self.ql.mem.read(realmain, 8))
logging.info("[+] Found entry point: 0x%x" % (current_value))
self.ql.log.info("[+] Found entry point: 0x%x" % (current_value))
self.kext_start = current_value
else:
logging.info("[!] Entry point not found")
self.ql.log.info("[!] Entry point not found")
self.kext_start = None
if b"__antimain" in self.kext_local_symbols:
antimain = loadbase + self.kext_local_symbols[b"__antimain"]["n_value"]
current_value, = struct.unpack("<Q", self.ql.mem.read(antimain, 8))
logging.info("[+] Found exit point: 0x%x" % (current_value))
self.ql.log.info("[+] Found exit point: 0x%x" % (current_value))
self.kext_stop = current_value
else:
logging.info("[!] Exit point not found")
self.ql.log.info("[!] Exit point not found")
self.kext_stop = None
self.slide = loadbase
@@ -410,12 +410,12 @@ class QlLoaderMACHO(QlLoader):
self.mmap_address = mmap_address
self.stack_sp = self.loadStack()
if self.using_dyld:
logging.info("[+] ProcEntry: {}".format(hex(self.proc_entry)))
self.ql.log.info("[+] ProcEntry: {}".format(hex(self.proc_entry)))
self.entry_point = self.proc_entry + self.dyld_slide
logging.info("[+] Dyld entry point: {}".format(hex(self.entry_point)))
self.ql.log.info("[+] Dyld entry point: {}".format(hex(self.entry_point)))
else:
self.entry_point = self.proc_entry + self.slide
logging.info("[+] Binary Entry Point: 0x{:X}".format(self.binary_entry))
self.ql.log.info("[+] Binary Entry Point: 0x{:X}".format(self.binary_entry))
self.macho_entry = self.binary_entry + self.slide
self.load_address = self.macho_entry
@@ -441,7 +441,7 @@ class QlLoaderMACHO(QlLoader):
return -1
if seg_name[:10] == "__PAGEZERO":
logging.debug("[+] Now loading {}, VM[{}:{}] for pagezero actually it only got a page size".format(seg_name, hex(vaddr_start), hex(vaddr_end)))
self.ql.log.debug("[+] Now loading {}, VM[{}:{}] for pagezero actually it only got a page size".format(seg_name, hex(vaddr_start), hex(vaddr_end)))
self.ql.mem.map(vaddr_start, PAGE_SIZE, info="[__PAGEZERO]")
self.ql.mem.write(vaddr_start, b'\x00' * PAGE_SIZE)
if self.vm_end_addr < vaddr_end:
@@ -452,7 +452,7 @@ class QlLoaderMACHO(QlLoader):
seg_size = vaddr_end - vaddr_start
seg_data = seg_data.ljust(seg_size, b'\0')
logging.debug("[+] Now loading {}, VM[{}:{}]".format(seg_name, hex(vaddr_start), hex(vaddr_end)))
self.ql.log.debug("[+] Now loading {}, VM[{}:{}]".format(seg_name, hex(vaddr_start), hex(vaddr_end)))
self.ql.mem.map(vaddr_start, seg_size, info="[loadSegment64]")
self.ql.mem.write(vaddr_start, seg_data)
if self.vm_end_addr < vaddr_end:
@@ -465,7 +465,7 @@ class QlLoaderMACHO(QlLoader):
self.binary_entry = cmd.entry
self.proc_entry = cmd.entry
logging.debug("[+] Binary Thread Entry: {}".format(hex(cmd.entry)))
self.ql.log.debug("[+] Binary Thread Entry: {}".format(hex(cmd.entry)))
def loadUuid(self):
@@ -511,17 +511,17 @@ class QlLoaderMACHO(QlLoader):
for item in self.argvs[::-1]:
argvs_ptr.append(ptr) # need pack and tostring
logging.debug('[+] add argvs ptr {}'.format(hex(ptr)))
self.ql.log.debug('[+] add argvs ptr {}'.format(hex(ptr)))
ptr += len(item) + 1
for item in self.envs[::-1]:
envs_ptr.append(ptr)
logging.debug('[+] add envs ptr {}'.format(hex(ptr)))
self.ql.log.debug('[+] add envs ptr {}'.format(hex(ptr)))
ptr += len(item) + 1
for item in self.apples[::-1]:
apple_ptr.append(ptr)
logging.debug('[+] add apple ptr {}'.format(hex(ptr)))
self.ql.log.debug('[+] add apple ptr {}'.format(hex(ptr)))
ptr += len(item) + 1
ptr = self.stack_sp
@@ -545,16 +545,16 @@ class QlLoaderMACHO(QlLoader):
for item in argvs_ptr:
ptr -= 4
self.push_stack_addr(item)
logging.debug("[+] SP 0x%x, content 0x%x" % (self.stack_sp, item))
self.ql.log.debug("[+] SP 0x%x, content 0x%x" % (self.stack_sp, item))
argvs_ptr_ptr = ptr
self.push_stack_addr(self.argc)
ptr -= 4
logging.debug("[+] SP 0x%x, content 0x%x" % (self.stack_sp, self.argc))
self.ql.log.debug("[+] SP 0x%x, content 0x%x" % (self.stack_sp, self.argc))
if self.using_dyld:
ptr -= 4
#logging.info("[+] Binary Dynamic Entry Point: {:X}".format(self.binary_entry))
#ql.log.info("[+] Binary Dynamic Entry Point: {:X}".format(self.binary_entry))
self.push_stack_addr(self.macho_file.header_address)
# self.push_stack_addr(self.binary_entry)
@@ -571,7 +571,7 @@ class QlLoaderMACHO(QlLoader):
self.stack_sp -= length
self.ql.mem.write(self.stack_sp, data)
logging.debug("[+] SP {} write data len {}".format(hex(self.stack_sp), length))
self.ql.log.debug("[+] SP {} write data len {}".format(hex(self.stack_sp), length))
return self.stack_sp
@@ -584,7 +584,7 @@ class QlLoaderMACHO(QlLoader):
content = struct.pack('<Q', data)
if len(content) != align:
logging.info('[!] stack align error')
self.ql.log.info('[!] stack align error')
return
self.stack_sp -= align
+10 -10
View File
@@ -3,7 +3,6 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#
import logging
from .header import *
from .loadcommand import *
@@ -13,6 +12,7 @@ from .utils import *
from struct import unpack
from qiling.const import *
class MachoParser:
# arch = "x8664" or "x86"
@@ -27,7 +27,7 @@ class MachoParser:
for seg in self.segments:
# find page zero
if seg.vm_address == 0 and seg.file_size == 0:
logging.info("[+] PageZero Size: {:X}".format(seg.vm_size))
ql.log.info("[+] PageZero Size: {:X}".format(seg.vm_size))
self.page_zero_size = seg.vm_size
self.header_address = seg.vm_size
@@ -54,33 +54,33 @@ class MachoParser:
self.magic = self.getMagic(self.binary_file)
if self.magic in MAGIC_64:
logging.debug("[+] Got a 64bit Header ")
self.ql.log.debug("[+] Got a 64bit Header ")
self.header = BinaryHeader(self.binary_file)
#elif self.magic in MAGIC_X86:
# # x86
# logging.debug("[+] Got a x86 Header")
# ql.log.debug("[+] Got a x86 Header")
# self.header = BinaryHeader(self.binary_file)
elif self.magic in MAGIC_FAT:
# fat
logging.debug("[+] Got a fat header")
self.ql.log.debug("[+] Got a fat header")
fat = FatHeader(self.binary_file)
file_info = fat.getBinary(self.archtype)
self.binary_file = self.binary_file[file_info.offset : file_info.offset + file_info.size]
self.header = BinaryHeader(self.binary_file)
else:
logging.info("[-] unknow header!")
self.ql.log.info("[-] unknow header!")
return False
if not self.header:
logging.info("[-] parse header error")
self.ql.log.info("[-] parse header error")
return False
return True
def parseLoadCommand(self):
logging.debug("[+] Parse LoadCommand")
self.ql.log.debug("[+] Parse LoadCommand")
if not self.header.lc_num or not self.header.lc_size or not self.header.header_size:
return False
@@ -95,14 +95,14 @@ class MachoParser:
if self.header.lc_size >= 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)
+35 -34
View File
@@ -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
+10 -10
View File
@@ -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
+28 -27
View File
@@ -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)
+2 -3
View File
@@ -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
+3 -3
View File
@@ -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):
+4 -3
View File
@@ -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
+6 -6
View File
@@ -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)
+4 -4
View File
@@ -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")
-1
View File
@@ -3,7 +3,6 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#
import logging
from qiling.const import *
from qiling.arch.x86 import *
+5 -6
View File
@@ -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)
+29 -37
View File
@@ -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)
+3 -2
View File
@@ -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")
+8 -7
View File
@@ -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)
+2 -2
View File
@@ -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)
+9 -8
View File
@@ -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 */
+3 -4
View File
@@ -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")
+14 -13
View File
@@ -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("<Q", ql.mem.read(mac_ops_addr + i * 8, 8))
if func != 0:
ql.os.ev_manager.register(func, true_name, MACPolicy_EventType[MACPolicy_EventType(i + base_event_MAC).name])
logging.debug("[+] New mac policy callback has been registered: Name: %s --- Type: %s --- Addr: 0x%x " %
ql.log.debug("[+] New mac policy callback has been registered: Name: %s --- Type: %s --- Addr: 0x%x " %
(true_name, MACPolicy_EventType(i + base_event_MAC).name, func))
# Update mac_policy_list
@@ -1280,7 +1281,7 @@ def hook__mac_policy_unregister(ql, address, params):
else:
ql.mac_policy_list.entries = POINTER64(0)
logging.debug("[+] A MAC event has been deregistered: 0x%x" % handle)
ql.log.debug("[+] A MAC event has been deregistered: 0x%x" % handle)
return 0;
@macos_kernel_api(params={
@@ -1291,7 +1292,7 @@ def hook__mac_policy_unregister(ql, address, params):
def hook__kauth_listen_scope(ql, address, params):
ev_name = ql.mem.string(params["_identifier"]).replace("com.", "").replace("apple.", "").upper().replace(".", "_")
ql.os.ev_manager.register(params["_callback"], ev_name.encode(), MacOSEventType["EV_" + ev_name])
logging.debug("[+] New kauth callback has been registered: %s" % ev_name)
ql.log.debug("[+] New kauth callback has been registered: %s" % ev_name)
return params["_identifier"]
@macos_kernel_api(params={
@@ -1318,7 +1319,7 @@ def hook__ipf_addv4(ql, address, params):
flag |= (1 << 2)
ql.os.ev_manager.register(ip_filter_ipv4.ipf_detach.value, name, MacOSEventType.EV_IPF_DETACH)
logging.debug("[+] New ipf callbacks has been registered: %s (%d/%d/%d)" % (
ql.log.debug("[+] New ipf callbacks has been registered: %s (%d/%d/%d)" % (
name,
(flag & (1 << 0)) != 0,
(flag & (1 << 1)) != 0,
+9 -9
View File
@@ -3,7 +3,7 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#
import os, logging
import os
from struct import *
@@ -45,7 +45,7 @@ class SharedFileMappingNp:
self.sfm_max_prot = unpack("<L", self.ql.mem.read(addr + 24, 4))[0]
self.sfm_init_prot = unpack("<L", self.ql.mem.read(addr + 28, 4))[0]
logging.debug("[ShareFileMapping]: addr: 0x{:X}, size: 0x{:X}, fileOffset:0x{:X}, maxProt: {}, initProt: {}".format(
self.ql.log.debug("[ShareFileMapping]: addr: 0x{:X}, size: 0x{:X}, fileOffset:0x{:X}, maxProt: {}, initProt: {}".format(
self.sfm_address, self.sfm_size, self.sfm_file_offset, self.sfm_max_prot, self.sfm_init_prot
))
@@ -86,26 +86,26 @@ class FileSystem():
filename = path.split("/")[-1]
filename_len = len(filename) + 1 # add \0
attr += pack("<L", filename_len)
logging.debug("FileName :{}, len:{}".format(filename, filename_len))
self.ql.log.debug("FileName :{}, len:{}".format(filename, filename_len))
if cmn_flags & ATTR_CMN_DEVID != 0:
attr += pack("<L", file_stat.st_dev)
logging.debug("DevID: {}".format(file_stat.st_dev))
self.ql.log.debug("DevID: {}".format(file_stat.st_dev))
if cmn_flags & ATTR_CMN_OBJTYPE != 0:
if os.path.isdir(path):
attr += pack("<L", VDIR)
logging.debug("ObjType: DIR")
self.ql.log.debug("ObjType: DIR")
elif os.path.islink(path):
attr += pack("<L", VLINK)
logging.debug("ObjType: LINK")
self.ql.log.debug("ObjType: LINK")
else:
attr += pack("<L", VREG)
logging.debug("ObjType: REG")
self.ql.log.debug("ObjType: REG")
if cmn_flags & ATTR_CMN_OBJID != 0:
attr += pack("<Q", file_stat.st_ino)
logging.debug("VnodeID :{}".format(file_stat.st_ino))
self.ql.log.debug("VnodeID :{}".format(file_stat.st_ino))
# at last, add name
if cmn_flags & ATTR_CMN_NAME != 0:
@@ -114,7 +114,7 @@ class FileSystem():
attr += filename.encode("utf8")
attr += b'\x00'
logging.debug("Attr : {}".format(attr))
self.ql.log.debug("Attr : {}".format(attr))
return attr
+3 -4
View File
@@ -4,7 +4,6 @@
#
# reference to <Mac OS X and IOS Internals: To the Apple's Core>
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
+14 -13
View File
@@ -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)
+2 -4
View File
@@ -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("<Q", in_content[:8])[0]
flavor = unpack("<L", in_content[8:12])[0]
@@ -87,7 +85,7 @@ class MachHostServer():
out_msg.content += pack("<L", 0x0) # minimum_priority = MINPRI_USER;
out_msg.content += pack("<L", 0x4f) # maximum_priority = MAXPRI_RESERVED
else:
logging.debug("Host flavor not support")
self.ql.log.debug("Host flavor not support")
raise
return out_msg
+77 -77
View File
@@ -3,7 +3,7 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#
import struct, logging
import struct
from qiling.exception import *
from qiling.const import *
@@ -27,11 +27,11 @@ from .utils import *
################
def ql_syscall_fgetattrlist(ql, fd, alist, attributeBuffer, bufferSize, options, *args, **kw):
logging.info("fgetattrlist(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
ql.log.info("fgetattrlist(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
fd, alist, attributeBuffer, bufferSize, options
))
logging.debug("fgetattrlist(fd: 0x%x, alist: 0x%x, attributeBuffer: 0x%x, bufferSize: 0x%x, options: 0x%x)" % (
ql.log.debug("fgetattrlist(fd: 0x%x, alist: 0x%x, attributeBuffer: 0x%x, bufferSize: 0x%x, options: 0x%x)" % (
fd, alist, attributeBuffer, bufferSize, options
))
@@ -44,7 +44,7 @@ def ql_syscall_fgetattrlist(ql, fd, alist, attributeBuffer, bufferSize, options,
attrlist["fileattr"] = unpack("<L", ql.mem.read(alist + 16, 4))[0]
attrlist["forkattr"] = unpack("<L", ql.mem.read(alist + 20, 4))[0]
logging.debug("[+] bitmapcount: 0x%x, reserved: 0x%x, commonattr: 0x%x, volattr: 0x%x, dirattr: 0x%x, fileattr: 0x%x, forkattr: 0x%x\n" % (
ql.log.debug("[+] bitmapcount: 0x%x, reserved: 0x%x, commonattr: 0x%x, volattr: 0x%x, dirattr: 0x%x, fileattr: 0x%x, forkattr: 0x%x\n" % (
attrlist["bitmapcount"], attrlist["reserved"], attrlist["commonattr"], attrlist["volattr"], attrlist["dirattr"], attrlist["fileattr"], attrlist["forkattr"]
))
@@ -54,7 +54,7 @@ def ql_syscall_fgetattrlist(ql, fd, alist, attributeBuffer, bufferSize, options,
if attrlist["commonattr"] != 0:
commonattr = ql.os.macho_fs.get_common_attr(ql.path, attrlist["commonattr"])
if not commonattr:
logging.debug("Error File Not Exist: %s" % (path_str))
ql.log.debug("Error File Not Exist: %s" % (path_str))
raise QlErrorSyscallError("Error File Not Exist")
attr += commonattr
@@ -62,7 +62,7 @@ def ql_syscall_fgetattrlist(ql, fd, alist, attributeBuffer, bufferSize, options,
attr = struct.pack("<L", attr_len) + attr
if len(attr) > 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("<Q", mmap_address))
return 0
# 0xc
def ql_syscall_kernelrpc_mach_vm_deallocate_trap(ql, target, address, size, *args, **kw):
logging.debug("[+] [mach] mach vm deallocate trap")
ql.log.debug("[+] [mach] mach vm deallocate trap")
return KERN_SUCCESS
# 0xf
def ql_syscall_kernelrpc_mach_vm_map_trap(ql, target, address, size, mask, flags, cur_protection):
logging.debug("[+] [mach] mach vm map trap(target: 0x%x, address: 0x%x, size: 0x%x, mask: 0x%x, flag: 0x%x, cur_protect: 0x%x)" % (
ql.log.debug("[+] [mach] mach vm map trap(target: 0x%x, address: 0x%x, size: 0x%x, mask: 0x%x, flag: 0x%x, cur_protect: 0x%x)" % (
target, address, size, mask, flags, cur_protection
))
@@ -118,52 +118,52 @@ def ql_syscall_kernelrpc_mach_vm_map_trap(ql, target, address, size, mask, flags
# 0x12
def ql_syscall_kernelrpc_mach_port_deallocate_trap(ql, *args, **kw):
logging.debug("[+] [mach] mach port deallocate trap")
ql.log.debug("[+] [mach] mach port deallocate trap")
# 0x13
def ql_syscall_kernelrpc_mach_port_mod_refs_trap(ql, target, name, right, delta, *args, **kw):
logging.debug("[+] [mach] mach port mod refs trap(target: 0x%x, name: 0x%x, right: 0x%x, delta: 0x%x)" % (
ql.log.debug("[+] [mach] mach port mod refs trap(target: 0x%x, name: 0x%x, right: 0x%x, delta: 0x%x)" % (
target, name, right, delta
))
pass
# 0x18
def ql_syscall_kernelrpc_mach_port_construct_trap(ql, target, options, context, name, *args, **kw):
logging.debug("[+] [mach] mach port construct trap(target: 0x%x, options: 0x%x, context: 0x%x, name: 0x%x)" % (
ql.log.debug("[+] [mach] mach port construct trap(target: 0x%x, options: 0x%x, context: 0x%x, name: 0x%x)" % (
target, options, context, name
))
pass
# 0x1a
def ql_syscall_mach_reply_port(ql, *args, **kw):
logging.debug("[+] [mach] mach reply port , ret: %s" % (ql.os.macho_mach_port.name))
ql.log.debug("[+] [mach] mach reply port , ret: %s" % (ql.os.macho_mach_port.name))
return ql.os.macho_mach_port.name
# 0x1b
def ql_syscall_thread_self_trap(ql, *args, **kw):
port_manager = ql.os.macho_port_manager
thread_port = port_manager.get_thread_port(ql.os.macho_thread)
logging.debug("[+] [mach] thread_self_trap: ret: %s" % (thread_port))
ql.log.debug("[+] [mach] thread_self_trap: ret: %s" % (thread_port))
return thread_port
# 0x1c
def ql_syscall_task_self_trap(ql, *args, **kw):
logging.debug("[+] [mach] task self trap, ret: %d" % (ql.os.macho_task.id))
ql.log.debug("[+] [mach] task self trap, ret: %d" % (ql.os.macho_task.id))
return ql.os.macho_task.id
# 0x1d
def ql_syscall_host_self_trap(ql, *args, **kw):
port_manager = ql.os.macho_port_manager
logging.debug("[+] [mach] host_self_trap, ret: %s" % (ql.os.macho_port_manager.host_port.name))
ql.log.debug("[+] [mach] host_self_trap, ret: %s" % (ql.os.macho_port_manager.host_port.name))
return port_manager.host_port.name
# 0x1f
def ql_syscall_mach_msg_trap(ql, args, opt, ssize, rsize, rname, timeout):
logging.debug("[+] [mach] mach_msg_trap(args: 0x%x opt: 0x%x, ssize: 0x%x, rsize: 0x%x, rname: 0x%x, timeout: %d)" % (
ql.log.debug("[+] [mach] mach_msg_trap(args: 0x%x opt: 0x%x, ssize: 0x%x, rsize: 0x%x, rname: 0x%x, timeout: %d)" % (
args, opt, ssize, rsize, rname, timeout))
mach_msg = MachMsg(ql)
mach_msg.read_msg_from_mem(args, ssize)
logging.debug("[+] Recv-> 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("<L", (CS_ENFORCEMENT | CS_GET_TASK_ALLOW))
ql.mem.write(useraddr, flag)
logging.info("csops(pid: %d, ops: 0x%x, useraddr: 0x%x, usersize: 0x%x) flag: 0x%x" % (
ql.log.info("csops(pid: %d, ops: 0x%x, useraddr: 0x%x, usersize: 0x%x) flag: 0x%x" % (
pid, ops, useraddr, usersize, ((CS_ENFORCEMENT | CS_GET_TASK_ALLOW))
))
return KERN_SUCCESS
# 0xdc
def ql_syscall_getattrlist(ql, path, alist, attributeBuffer, bufferSize, options, *args, **kw):
logging.info("getattrlist(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
ql.log.info("getattrlist(0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
path, alist, attributeBuffer, bufferSize, options
))
logging.debug("getattrlist(path: 0x%x, alist: 0x%x, attributeBuffer: 0x%x, bufferSize: 0x%x, options: 0x%x)" % (
ql.log.debug("getattrlist(path: 0x%x, alist: 0x%x, attributeBuffer: 0x%x, bufferSize: 0x%x, options: 0x%x)" % (
path, alist, attributeBuffer, bufferSize, options
))
attrlist = {}
@@ -246,16 +246,16 @@ def ql_syscall_getattrlist(ql, path, alist, attributeBuffer, bufferSize, options
attrlist["forkattr"] = unpack("<L", ql.mem.read(alist + 20, 4))[0]
path_str = macho_read_string(ql, path, MAX_PATH_SIZE)
logging.debug("[+] bitmapcount: 0x%x, reserved: 0x%x, commonattr: 0x%x, volattr: 0x%x, dirattr: 0x%x, fileattr: 0x%x, forkattr: 0x%x\n" % (
ql.log.debug("[+] bitmapcount: 0x%x, reserved: 0x%x, commonattr: 0x%x, volattr: 0x%x, dirattr: 0x%x, fileattr: 0x%x, forkattr: 0x%x\n" % (
attrlist["bitmapcount"], attrlist["reserved"], attrlist["commonattr"], attrlist["volattr"], attrlist["dirattr"], attrlist["fileattr"], attrlist["forkattr"]
))
logging.debug("[+] path str: %s\n" % (path_str))
ql.log.debug("[+] path str: %s\n" % (path_str))
attr = b''
if attrlist["commonattr"] != 0:
commonattr = ql.os.macho_fs.get_common_attr(path_str, attrlist["commonattr"])
if not commonattr:
logging.debug("Error File Not Exist: %s" % (path_str))
ql.log.debug("Error File Not Exist: %s" % (path_str))
raise QlErrorSyscallError("Error File Not Exist")
attr += commonattr
@@ -263,7 +263,7 @@ def ql_syscall_getattrlist(ql, path, alist, attributeBuffer, bufferSize, options
attr = struct.pack("<L", attr_len) + attr
if len(attr) > 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("<Q", ql.mem.read(ql.reg.rsp, 8))[0]
logging.info("proc_info(0x%x, %d, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
ql.log.info("proc_info(0x%x, %d, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
callnum, pid, flavor, arg, buff, buffer_size, retval
))
logging.info("[+] proc_info(callnum: 0x%x, pid: %d, flavor:0x%x, arg: 0x%x, buffer: 0x%x, buffersize: 0x%x, retval: 0x%x)" % (
ql.log.info("[+] proc_info(callnum: 0x%x, pid: %d, flavor:0x%x, arg: 0x%x, buffer: 0x%x, buffersize: 0x%x, retval: 0x%x)" % (
callnum, pid, flavor, arg, buff, buffer_size, retval
))
if callnum == PROC_INFO_CALL_PIDINFO:
@@ -391,7 +391,7 @@ def ql_syscall_stat64_macos(ql, stat64_pathname, stat64_buf_ptr, *args, **kw):
stat64_file = (ql.mem.string(stat64_pathname))
real_path = ql.os.macho_fs.vm_to_real_path(stat64_file)
logging.debug("real_path: %s" % (real_path))
ql.log.debug("real_path: %s" % (real_path))
if os.path.exists(real_path) == False:
regreturn = -1
else:
@@ -430,12 +430,12 @@ def ql_syscall_stat64_macos(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" % (stat64_file, stat64_buf_ptr, regreturn))
ql.log.info("stat64(%s, 0x%x) = %d" % (stat64_file, stat64_buf_ptr, regreturn))
if regreturn == 0:
set_eflags_cf(ql, 0x0)
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
# 0x153
@@ -497,11 +497,11 @@ def ql_syscall_fstat64_macos(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
# 0x16e
@@ -512,7 +512,7 @@ def ql_syscall_bsdthread_register(ql, threadstart, wqthread, flags, stack_addr_h
# 0x174
def ql_syscall_thread_selfid(ql, *args, **kw):
thread_id = ql.os.macho_thread.id
logging.info("thread_selfid() = %d" % (thread_id))
ql.log.info("thread_selfid() = %d" % (thread_id))
return thread_id
@@ -524,23 +524,23 @@ def ql_syscall_write_nocancel(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 0
@@ -569,19 +569,19 @@ def ql_syscall_open_nocancel(ql, filename, flags, mode, *args, **kw):
except QlSyscallError:
regreturn = -1
logging.info("open(%s, 0x%s, 0x%x) = %d" % (relative_path, flags, mode, regreturn))
ql.log.info("open(%s, 0x%s, 0x%x) = %d" % (relative_path, flags, mode, regreturn))
if regreturn >= 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
+14 -14
View File
@@ -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("<Q", x) for x in input_array))
logging.debug("[+] Created input array at 0x%x" % input_array_addr)
ql.log.debug("[+] Created input array at 0x%x" % input_array_addr)
else:
input_array_addr = 0
if input_struct is not None and input_struct_size != 0:
input_struct_addr = ql.os.heap.alloc(input_struct_size)
ql.mem.write(input_struct_addr, bytes(input_struct))
logging.debug("[+] Created input struct at 0x%x" % input_struct_addr)
ql.log.debug("[+] Created input struct at 0x%x" % input_struct_addr)
else:
input_struct_addr = 0
if output_array is not None and output_cnt != 0:
output_array_addr = ql.os.heap.alloc(output_cnt)
ql.mem.write(output_array_addr, b''.join(struct.pack("<Q", x) for x in output_array))
logging.debug("[+] Created output array at 0x%x" % output_array_addr)
ql.log.debug("[+] Created output array at 0x%x" % output_array_addr)
else:
output_array_addr = 0
if output_struct is not None and output_struct_size != 0:
output_struct_addr = ql.os.heap.alloc(output_struct_size)
ql.mem.write(output_struct_addr, bytes(output_struct))
logging.debug("[+] Created output struct at 0x%x" % output_struct_size)
ql.log.debug("[+] Created output struct at 0x%x" % output_struct_size)
else:
output_struct_addr = 0
dispatch_addr = ql.os.heap.alloc(ctypes.sizeof(IOExternalMethodDispatch))
logging.debug("[+] Created IOExternalMethodDispatch object at 0x%x" % dispatch_addr)
ql.log.debug("[+] Created IOExternalMethodDispatch object at 0x%x" % dispatch_addr)
dispatch_obj = IOExternalMethodDispatch(ql, dispatch_addr)
args_obj.___reservedA = 0
@@ -79,11 +79,11 @@ def IOConnectCallMethod(ql, selector,
args_obj._structureOutputSize = output_struct_size
args_obj.updateToMem()
logging.debug("[+] Initialized IOExternalMethodArguments object")
ql.log.debug("[+] Initialized IOExternalMethodArguments object")
ql.os.savedrip=0xffffff8000a106ba
ql.run(begin=ql.loader.user_alloc)
ql.os.user_object = ql.reg.rax
logging.debug("[+] Created user object at 0x%x" % ql.os.user_object)
ql.log.debug("[+] Created user object at 0x%x" % ql.os.user_object)
ql.reg.rdi = ql.os.user_object
ql.reg.rsi = 0x1337 # owningTask
@@ -93,7 +93,7 @@ def IOConnectCallMethod(ql, selector,
ql.stack_push(0)
ql.os.savedrip=0xffffff8000a10728
ql.run(begin=ql.loader.user_initWithTask)
logging.debug("[+] Initialized user object")
ql.log.debug("[+] Initialized user object")
# TODO: Add some extra methods with correct order
@@ -108,7 +108,7 @@ def IOConnectCallMethod(ql, selector,
args_obj.loadFromMem()
output_array = args_obj.scalarOutput
logging.debug("[+] Finish IOConnectCallMethod")
ql.log.debug("[+] Finish IOConnectCallMethod")
return args_obj.scalarOutput, type(output_struct).from_buffer(args_obj.structureOutput)
@@ -235,6 +235,6 @@ 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)
+4 -3
View File
@@ -3,7 +3,8 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#
import inspect, logging
import inspect
from .filestruct import ql_file
from .utils import QlOsUtils
@@ -96,7 +97,7 @@ class QlFsMapper:
def open_ql_file(self, path, openflags, openmode):
if self.has_mapping(path):
logging.info(f"mapping {path}")
self.ql.log.info(f"mapping {path}")
return self._open_mapping_ql_file(path, openflags, openmode)
else:
real_path = self.ql.os.transform_to_real_path(path)
@@ -104,7 +105,7 @@ class QlFsMapper:
def open(self, path, openmode):
if self.has_mapping(path):
logging.info(f"mapping {path}")
self.ql.log.info(f"mapping {path}")
return self._open_mapping(path, openmode)
else:
real_path = self.ql.os.transform_to_real_path(path)
+11 -10
View File
@@ -3,11 +3,12 @@
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#
import logging, os, re
import os, re
from qiling.const import *
from qiling.exception import *
from unicorn import (
UC_PROT_ALL,
UC_PROT_EXEC,
@@ -130,13 +131,13 @@ class QlMemoryManager:
perms_sym.append("-")
return "".join(perms_sym)
logging.info("[+] Start End Perm. Path")
ql.log.info("[+] Start End Perm. Path")
for start, end, perm, info in self.map_info:
_perm = _perms_mapping(perm)
image = self.ql.os.find_containing_image(start)
if image:
info += f" ({image.path})"
logging.info("[+] %08x - %08x - %s %s" % (start, end, _perm, info))
ql.log.info("[+] %08x - %08x - %s %s" % (start, end, _perm, info))
def get_lib_base(self, filename):
@@ -170,12 +171,12 @@ class QlMemoryManager:
info = value[3]
mem_read = bytes(value[4])
logging.debug("restore key: %i 0x%x 0x%x %s" % (key, start, end, info))
self.ql.log.debug("restore key: %i 0x%x 0x%x %s" % (key, start, end, info))
if self.is_mapped(start, end-start) == False:
logging.debug("mapping 0x%x 0x%x mapsize 0x%x" % (start, end, end-start))
self.ql.log.debug("mapping 0x%x 0x%x mapsize 0x%x" % (start, end, end-start))
self.map(start, end-start, perms=perm, info=info)
logging.debug("writing 0x%x size 0x%x write_size 0x%x " % (start, end-start, len(mem_read)))
self.ql.log.debug("writing 0x%x size 0x%x write_size 0x%x " % (start, end-start, len(mem_read)))
self.write(start, mem_read)
def read(self, addr: int, size: int) -> 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):
+11 -10
View File
@@ -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.
+4 -5
View File
@@ -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")
+12 -12
View File
@@ -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
+7 -7
View File
@@ -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
+3 -3
View File
@@ -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
+33 -33
View File
@@ -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
+3 -3
View File
@@ -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
+3 -3
View File
@@ -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
+2 -2
View File
@@ -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
+5 -4
View File
@@ -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
+5 -5
View File
@@ -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
+11 -11
View File
@@ -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
+4 -3
View File
@@ -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
+2 -2
View File
@@ -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
+4 -4
View File
@@ -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
+45 -44
View File
@@ -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", sin_family)
if sin_family == 1:
logging.debug("[+] recvfrom() path is " + tmp_addr)
ql.log.debug("[+] recvfrom() path is " + tmp_addr)
data += tmp_addr.encode()
else:
logging.debug("[+] recvfrom() addr is %s:%d" % (tmp_addr[0], tmp_addr[1]))
ql.log.debug("[+] recvfrom() addr is %s:%d" % (tmp_addr[0], tmp_addr[1]))
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
+23 -23
View File
@@ -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
+2 -2
View File
@@ -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=<optimized out>)
regreturn = 0
logging.info("_sysctl(0x%x) = %i" % (sysctl_name, regreturn))
ql.log.info("_sysctl(0x%x) = %i" % (sysctl_name, regreturn))
return regreturn
+3 -2
View File
@@ -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
+6 -6
View File
@@ -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
+2 -2
View File
@@ -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
+4 -4
View File
@@ -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
+65 -73
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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']
@@ -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))
+1 -2
View File
@@ -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()
+7 -7
View File
@@ -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)
+13 -14
View File
@@ -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
+7 -6
View File
@@ -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
+21 -20
View File
@@ -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:
+9 -8
View File
@@ -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
+2 -2
View File
@@ -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
+3 -3
View File
@@ -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:
+4 -3
View File
@@ -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
+3 -2
View File
@@ -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
@@ -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
+2 -2
View File
@@ -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
@@ -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"]
+1 -2
View File
@@ -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
+4 -3
View File
@@ -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(
+6 -6
View File
@@ -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)
+14 -12
View File
@@ -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]:
+5 -5
View File
@@ -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)
+13 -12
View File
@@ -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
+7 -7
View File
@@ -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")
+4 -3
View File
@@ -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="",
)
+2 -3
View File
@@ -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
+3 -2
View File
@@ -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:
+5 -4
View File
@@ -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}'!")
+7 -6
View File
@@ -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:
+7 -6
View File
@@ -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):
+5 -4
View File
@@ -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")
+71 -90
View File
@@ -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

Some files were not shown because too many files have changed in this diff Show More