mirror of
https://github.com/qilingframework/qiling.git
synced 2026-10-12 02:21:40 +00:00
Use ql.log instread of logging
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -1,2 +1,2 @@
|
||||
from .core import Qiling
|
||||
from .__version__ import __version__
|
||||
from .__version__ import __version__
|
||||
+3
-4
@@ -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
@@ -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
@@ -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!')
|
||||
|
||||
|
||||
###############
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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,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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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")
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
|
||||
#
|
||||
|
||||
import logging
|
||||
|
||||
from qiling.const import *
|
||||
from qiling.arch.x86 import *
|
||||
|
||||
@@ -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
@@ -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,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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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")
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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,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,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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="",
|
||||
)
|
||||
|
||||
@@ -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,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:
|
||||
|
||||
@@ -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}'!")
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
@@ -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
Reference in New Issue
Block a user