remove [+] and [!]

This commit is contained in:
xwings
2021-01-25 22:37:41 +08:00
parent b0a33d26cc
commit 7b3e3bf2ad
68 changed files with 391 additions and 391 deletions
@@ -58,7 +58,7 @@ def patcher(ql):
def check_pc(ql):
print("=" * 50)
print("[!] Hit fuzz point, stop at PC = 0x%x" % ql.reg.arch_pc)
print("Hit fuzz point, stop at PC = 0x%x" % ql.reg.arch_pc)
print("=" * 50)
ql.emu_stop()
+1 -1
View File
@@ -174,7 +174,7 @@ if __name__ == "__main__":
ql.os.set_function_args([0])
ql.hook_address(hook_stop_address, 0x4055FA)
ql.run(0x4053B2)
ql.log.info("[+] test kill thread")
ql.log.info("test kill thread")
if ql.amsint32_driver:
ql.amsint32_driver.os.io_Write(ql.pack32(0xdeadbeef))
ql.amsint32_driver.hook_address(hook_stop_address, 0x10423)
+2 -2
View File
@@ -78,7 +78,7 @@ class QlArchARM(QlArch):
#self.ql.reg.fpexc = 0x00000040
else:
self.ql.reg.fpexc = 0x40000000
self.ql.log.debug("[+] Enable ARM VFP")
self.ql.log.debug("Enable ARM VFP")
def check_thumb(self):
@@ -92,5 +92,5 @@ class QlArchARM(QlArch):
mode = UC_MODE_ARM
if (reg_cpsr & reg_cpsr_v) != 0:
mode = UC_MODE_THUMB
self.ql.log.debug("[+] Enable ARM THUMB")
self.ql.log.debug("Enable ARM THUMB")
return mode
+2 -2
View File
@@ -56,7 +56,7 @@ def ql_create_disassembler(archtype, archendian, reg_cpsr=None):
md = Cs(CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_LITTLE_ENDIAN)
else:
raise QlErrorArch("[!] Unknown arch defined in utils.py (debug output mode)")
raise QlErrorArch("Unknown arch defined in utils.py (debug output mode)")
return md
@@ -101,6 +101,6 @@ def ql_create_assembler(archtype, archendian, reg_cpsr=None):
ks = Ks(KS_ARCH_MIPS, KS_MODE_MIPS32 + KS_MODE_LITTLE_ENDIAN)
else:
raise QlErrorArch("[!] Unknown arch defined in utils.py (debug output mode)")
raise QlErrorArch("Unknown arch defined in utils.py (debug output mode)")
return ks
+1 -1
View File
@@ -146,7 +146,7 @@ class GDTManager:
self.ql.mem.map(SEGMENT_ADDR, SEGMENT_ADDR, info="[FS/GS]")
if index < 0 or index >= self.gdt_number:
raise QlGDTError("[!] Ql GDT register index error!")
raise QlGDTError("Ql GDT register index error!")
# create GDT entry, then write GDT entry into GDT table
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)
+4 -4
View File
@@ -122,9 +122,9 @@ class Qiling(QlCoreHooks, QlCoreStructs):
# file check
if self._shellcoder is None:
if not os.path.exists(str(self._argv[0])):
raise QlErrorFileNotFound("[!] Target binary not found")
raise QlErrorFileNotFound("Target binary not found")
if not os.path.exists(self._rootfs):
raise QlErrorFileNotFound("[!] Target rootfs not found")
raise QlErrorFileNotFound("Target rootfs not found")
self._path = (str(self._argv[0]))
self._targetname = ntpath.basename(self._argv[0])
@@ -142,10 +142,10 @@ class Qiling(QlCoreHooks, QlCoreStructs):
self._archendian = guessed_archendian
if not ql_is_valid_ostype(self._ostype):
raise QlErrorOsType("[!] Invalid OSType")
raise QlErrorOsType("Invalid OSType")
if not ql_is_valid_arch(self._archtype):
raise QlErrorArch("[!] Invalid Arch %s" % self._archtype)
raise QlErrorArch("Invalid Arch %s" % self._archtype)
self._loader = loader_setup(self._ostype, self)
+1 -1
View File
@@ -54,7 +54,7 @@ class HookIntr(Hook):
def check(self, ql, intno):
ql.log.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
+1 -1
View File
@@ -35,7 +35,7 @@ class QlCoreStructs:
}
if bit not in handlers:
raise QlErrorStructConversion("[!] Unsupported Qiling struct conversion")
raise QlErrorStructConversion("Unsupported Qiling struct conversion")
p, ps, up, ups = handlers[bit]
+2 -2
View File
@@ -34,8 +34,8 @@ class QlQdb(cmd.Cmd, QlDebugger):
@classmethod
def attach(cls, ql, *args, **kwargs):
print(color.RED, "[+] Qdb attached", color.END, sep="")
print(color.RED, "[!] All hooks of qiling instance will be disabled in Qdb", color.END, sep="")
print(color.RED, "Qdb attached", color.END, sep="")
print(color.RED, "All hooks of qiling instance will be disabled in Qdb", color.END, sep="")
# clear all hooks
for i in ql._addr_hook_fuc.keys():
+16 -16
View File
@@ -67,7 +67,7 @@ class ELFParse():
self.elfdata = elfdata.ljust(52, b'\x00')
if self.elffile.e_ident_raw[: 4] != b'\x7fELF':
raise QlErrorELFFormat("[!] ERROR: NOT a ELF")
raise QlErrorELFFormat("ERROR: NOT a ELF")
self.elfhead = self.parse_header()
if self.elfhead['e_type'] == "ET_REL": # kernel driver
@@ -179,7 +179,7 @@ class QlLoaderELF(QlLoader, ELFParse):
if elfhead['e_type'] == 'ET_EXEC':
load_address = 0
elif elfhead['e_type'] != 'ET_DYN':
self.ql.log.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
@@ -241,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
self.ql.log.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:
self.ql.log.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
@@ -254,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:
self.ql.log.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)
self.ql.log.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
self.ql.log.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
@@ -276,7 +276,7 @@ class QlLoaderELF(QlLoader, ELFParse):
interp = ELFParse(self.ql.rootfs + interp_path, self.ql)
interphead = interp.parse_header()
self.ql.log.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():
@@ -286,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
self.ql.log.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)
self.ql.log.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))
@@ -310,7 +310,7 @@ class QlLoaderELF(QlLoader, ELFParse):
else:
self.mmap_address = int(self.ql.os.profile.get("OS32", "mmap_address"), 16)
self.ql.log.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''
@@ -428,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']
ql.log.info("[+] init_module = 0x%x" % addr)
ql.log.info("init_module = 0x%x" % addr)
return addr
# not found. FIXME: report error on invalid module??
ql.log.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):
@@ -586,7 +586,7 @@ class QlLoaderELF(QlLoader, ELFParse):
ql.mem.write(loc + 2, ql.pack16(val & 0xFFFF))
else:
raise QlErrorNotImplemented("[!] Relocation type %s not implemented" % describe_reloc_type(rel['r_info_type'], elffile))
raise QlErrorNotImplemented("Relocation type %s not implemented" % describe_reloc_type(rel['r_info_type'], elffile))
return rev_reloc_symbols
@@ -615,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]")
ql.log.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)
@@ -628,7 +628,7 @@ class QlLoaderELF(QlLoader, ELFParse):
else:
self.mmap_address = int(self.ql.os.profile.get("OS32", "mmap_address"), 16)
ql.log.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)
+29 -29
View File
@@ -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")
self.ql.log.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
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.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)
self.ql.log.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))
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.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:
self.ql.log.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)))
# ql.log.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:
# ql.log.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:
# ql.log.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:
self.ql.log.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]
self.ql.log.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))
self.ql.log.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:
self.ql.log.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))
self.ql.log.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:
self.ql.log.info("[!] Exit point not found")
self.ql.log.info("Exit point not found")
self.kext_stop = None
self.slide = loadbase
@@ -398,7 +398,7 @@ class QlLoaderMACHO(QlLoader):
self.using_dyld = True
if not isdyld:
if not self.dyld_path:
raise QlErrorMACHOFormat("[!] Error No Dyld path")
raise QlErrorMACHOFormat("Error No Dyld path")
self.dyld_path = os.path.join(self.ql.rootfs + self.dyld_path)
self.dyld_file = MachoParser(self.ql, self.dyld_path)
self.loading_file = self.dyld_file
@@ -410,12 +410,12 @@ class QlLoaderMACHO(QlLoader):
self.mmap_address = mmap_address
self.stack_sp = self.loadStack()
if self.using_dyld:
self.ql.log.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
self.ql.log.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
self.ql.log.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":
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.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')
self.ql.log.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
self.ql.log.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
self.ql.log.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)
self.ql.log.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)
self.ql.log.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)
self.ql.log.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
self.ql.log.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
#ql.log.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)
self.ql.log.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:
self.ql.log.info('[!] stack align error')
self.ql.log.info('stack align error')
return
self.stack_sp -= align
+5 -5
View File
@@ -27,7 +27,7 @@ class MachoParser:
for seg in self.segments:
# find page zero
if seg.vm_address == 0 and seg.file_size == 0:
ql.log.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,17 +54,17 @@ class MachoParser:
self.magic = self.getMagic(self.binary_file)
if self.magic in MAGIC_64:
self.ql.log.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
# ql.log.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
self.ql.log.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]
@@ -80,7 +80,7 @@ class MachoParser:
return True
def parseLoadCommand(self):
self.ql.log.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
+23 -23
View File
@@ -67,7 +67,7 @@ class Process():
path = os.path.join(self.ql.rootfs, self.ql.dlls, dll_name)
if not os.path.exists(path):
raise QlErrorFileNotFound("[!] Cannot find dll in %s" % path)
raise QlErrorFileNotFound("Cannot find dll in %s" % path)
# If the dll is already loaded
if dll_name in self.dlls:
@@ -75,7 +75,7 @@ class Process():
else:
self.dlls[dll_name] = self.dll_last_address
self.ql.log.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)
@@ -313,7 +313,7 @@ class Process():
def init_driver_object(self):
# PDRIVER_OBJECT DriverObject
driver_object_addr = self.structure_last_addr
self.ql.log.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)
@@ -329,7 +329,7 @@ class Process():
def init_registry_path(self):
# PUNICODE_STRING RegistryPath
regitry_path_addr = self.structure_last_addr
self.ql.log.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)
@@ -344,7 +344,7 @@ class Process():
def init_eprocess(self):
addr = self.structure_last_addr
self.ql.log.info("[+] EPROCESS is is 0x%x" %addr)
self.ql.log.info("EPROCESS is is 0x%x" %addr)
if self.ql.archtype == QL_ARCH.X86:
@@ -370,7 +370,7 @@ class Process():
elif self.ql.archtype == QL_ARCH.X8664:
KI_USER_SHARED_DATA = 0xFFFFF78000000000
self.ql.log.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()
@@ -456,7 +456,7 @@ class QlLoaderPE(QlLoader, Process):
def load(self):
# set stack pointer
self.ql.log.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:
@@ -471,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
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.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
@@ -483,13 +483,13 @@ class QlLoaderPE(QlLoader, Process):
self.ql.reg.ebp = sp
if self.pe.is_dll():
self.ql.log.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')
self.ql.log.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)
self.ql.log.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:
@@ -497,15 +497,15 @@ class QlLoaderPE(QlLoader, Process):
self.ql.reg.rbp = sp
if self.pe.is_dll():
self.ql.log.debug('[+] Setting up DllMain args')
self.ql.log.debug('Setting up DllMain args')
self.ql.log.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
self.ql.log.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")
raise QlErrorArch("Unknown ql.arch")
# if this is NOT a driver, init tib/peb/ldr
if not self.is_driver: # userland program
@@ -522,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)
self.ql.log.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
@@ -531,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'))
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))
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'))
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))
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))
@@ -588,7 +588,7 @@ class QlLoaderPE(QlLoader, Process):
try:
addr = self.import_address_table[dll_name][imp.name]
except KeyError:
self.ql.log.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]
@@ -598,7 +598,7 @@ class QlLoaderPE(QlLoader, Process):
address = self.ql.pack64(addr)
self.ql.mem.write(imp.address, address)
self.ql.log.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
+8 -8
View File
@@ -111,10 +111,10 @@ class QlLoaderPE_UEFI(QlLoader):
ql.mem.map(image_base, image_size, info="[module]")
ql.mem.write(image_base, data)
ql.log.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
ql.log.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
@@ -207,11 +207,11 @@ class QlLoaderPE_UEFI(QlLoader):
def run(self):
# intel architecture uefi implementaion only
if self.ql.archtype not in (QL_ARCH.X86, QL_ARCH.X8664):
raise QlErrorArch("[!] Unsupported architecture")
raise QlErrorArch("Unsupported architecture")
# x86-64 arch only
if self.ql.archtype != QL_ARCH.X8664:
raise QlErrorArch("[!] Only 64 bit arch is supported at the moment")
raise QlErrorArch("Only 64 bit arch is supported at the moment")
self.loaded_image_protocol_guid = self.ql.os.profile["LOADED_IMAGE_PROTOCOL"]["guid"]
self.loaded_image_protocol_modules = []
@@ -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
self.ql.log.info(f"[+] Located heap at {heap_base:#010x}")
self.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
self.ql.log.info(f"[+] Located stack at {sp:#010x}")
self.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)
self.ql.log.info(f"[+] Located SMM heap at {heap_base:#010x}")
self.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
@@ -312,7 +312,7 @@ class QlLoaderPE_UEFI(QlLoader):
except QlMemoryMappedError:
self.ql.log.critical("Couldn't map dependency")
self.ql.log.info(f"[+] Done with loading {self.ql.path}")
self.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
+11 -11
View File
@@ -318,13 +318,13 @@ class QlOsDos(QlOs):
# read on the next call to getch.
ch = self._get_ch_non_blocking()
if ch == curses.KEY_RESIZE:
self.ql.log.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():
self.ql.log.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?
@@ -365,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:
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})]")
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
@@ -444,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.ql.log.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
@@ -458,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):
self.ql.log.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
@@ -497,7 +497,7 @@ class QlOsDos(QlOs):
_, _, cnt, offset, segment, lba = self._parse_dap(dapbs)
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):
self.ql.log.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
@@ -512,7 +512,7 @@ class QlOsDos(QlOs):
_, _, cnt, offset, segment, lba = self._parse_dap(dapbs)
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):
self.ql.log.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
@@ -540,7 +540,7 @@ class QlOsDos(QlOs):
self.clear_cf()
elif ax == 0x5307:
if self.ql.reg.bx == 1 and self.ql.reg.cx == 3:
self.ql.log.info("[+] Emulation Stop")
self.ql.log.info("Emulation Stop")
self.ql.uc.emu_stop()
elif ah == 0x86:
dx = self.ql.reg.dx
@@ -568,7 +568,7 @@ class QlOsDos(QlOs):
if ch in SCANCODES:
return SCANCODES[ch]
else:
self.ql.log.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):
@@ -673,7 +673,7 @@ class QlOsDos(QlOs):
# exit
if ah == 0x4C:
self.ql.log.info("[+] Emulation Stop")
self.ql.log.info("Emulation Stop")
self.ql.uc.emu_stop()
# character output
elif ah == 0x2 or ah == 0x6:
+1 -1
View File
@@ -270,7 +270,7 @@ def linux_kernel_api(param_num=None, params=None):
elif ql.archtype == QL_ARCH.MIPS:
return mips_call(ql, param_num, params, func, args, kwargs)
else:
raise QlErrorArch("[!] Unknown ql.archtype")
raise QlErrorArch("Unknown ql.archtype")
return wrapper
return decorator
+2 -2
View File
@@ -997,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]
self.ql.log.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]
self.ql.log.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
+4 -4
View File
@@ -30,10 +30,10 @@ def hook_kernel_api(ql, address, size):
api_func(ql, address, {})
except Exception:
ql.log.exception("")
ql.log.debug("[!] %s Exception Found" % api_name)
raise QlErrorSyscallError("[!] Linux kernel API Implementation Error")
ql.log.debug("%s Exception Found" % api_name)
raise QlErrorSyscallError("Linux kernel API Implementation Error")
else:
ql.log.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")
raise QlErrorSyscallNotFound("Linux kernel API Implementation Not Found")
+1 -1
View File
@@ -23,7 +23,7 @@ def ql_syscall_set_thread_area(ql, u_info_addr, *args, **kw):
base = ql.unpack32(u_info[4 : 8])
limit = ql.unpack32(u_info[8 : 12])
ql.log.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)
+1 -1
View File
@@ -22,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)
ql.log.debug("[+] Set init_kernel_get_tls")
ql.log.debug("Set init_kernel_get_tls")
+2 -2
View File
@@ -114,7 +114,7 @@ class QlMacOSEvManager:
def add_process(self, pid, name):
for p in self.my_procs:
if p.p_pid == pid:
self.ql.log.info("[!] Duplicated process")
self.ql.log.info("Duplicated process")
return
cur_proc_addr = self.ql.os.heap.alloc(ctypes.sizeof(proc_t))
@@ -208,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:
self.ql.log.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)
+1 -1
View File
@@ -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:
ql.log.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)
+4 -4
View File
@@ -33,11 +33,11 @@ def hook_kernel_api(ql, address, size):
raise
except Exception:
ql.log.exception("")
ql.log.debug("[!] %s Exception Found" % api_name)
raise QlErrorSyscallError("[!] MacOS kernel API Implementation Error")
ql.log.debug("%s Exception Found" % api_name)
raise QlErrorSyscallError("MacOS kernel API Implementation Error")
else:
ql.log.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")
raise QlErrorSyscallNotFound("MacOS kernel API Implementation Not Found")
+13 -13
View File
@@ -950,7 +950,7 @@ def hook__sock_getsockname(ql, address, params):
"cmd": STRING,
})
def hook__KUNCExecute(ql, address, params):
# ql.log.debug("[+] Starting userspace process: %s" % params["cmd"])
# ql.log.debug("Starting userspace process: %s" % params["cmd"])
return 0
######################## Custom events / callbacks ########################
@@ -994,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:
ql.log.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
@@ -1016,7 +1016,7 @@ def hook__sysctl_unregister_oid(ql, address, params):
break
true_name = oid_parent.lstrip(b"_") + b"." + oid_name.encode() + b"\x00"
ql.log.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={
@@ -1037,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:
ql.log.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={
@@ -1075,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)
ql.log.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,
@@ -1096,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()
ql.log.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={
@@ -1170,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"])
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)" % (
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,
@@ -1202,7 +1202,7 @@ def hook__sflt_unregister(ql, address, params):
break
ql.os.ev_manager.deregister(b"", keyword=handle)
ql.log.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={
@@ -1221,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])
ql.log.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
@@ -1281,7 +1281,7 @@ def hook__mac_policy_unregister(ql, address, params):
else:
ql.mac_policy_list.entries = POINTER64(0)
ql.log.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={
@@ -1292,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])
ql.log.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={
@@ -1319,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)
ql.log.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,
@@ -1394,7 +1394,7 @@ def hook__getattrlistbulk(ql, address, params):
vap.updateToMem()
code = gen_stub_code(ql, [0, uio.base, getattrlistbulk_args.alist, getattrlistbulk_args.options, vap.base, 0, params["p"]], vfs_attr_pack)
print("[+] Trampoline created at 0x%x for %s (0x%x) and 0x%x" % (code, truename, vap.va_name.value, vap.base))
print("Trampoline created at 0x%x for %s (0x%x) and 0x%x" % (code, truename, vap.va_name.value, vap.base))
ql.stack_push(code)
return
+12 -12
View File
@@ -59,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
self.ql.log.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:
self.ql.log.debug("[!] Failed to initialize kext object")
self.ql.log.debug("Failed to initialize kext object")
return
self.ql.log.debug("[+] Initialized kext object")
self.ql.log.debug("Initialized kext object")
self.ql.reg.rdi = self.kext_object
# FIXME Determine provider for kext
@@ -76,9 +76,9 @@ class QlOsMacos(QlOsPosix):
self.savedrip=0xffffff8000a16102
self.ql.run(begin=self.ql.loader.kext_attach)
if self.ql.reg.rax == 0:
self.ql.log.debug("[!] Failed to attach kext object")
self.ql.log.debug("Failed to attach kext object")
return
self.ql.log.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
@@ -89,14 +89,14 @@ class QlOsMacos(QlOsPosix):
self.savedrip=0xffffff8000a16184
self.ql.run(begin=self.ql.loader.kext_probe)
self.heap.free(tmp)
self.ql.log.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)
self.ql.log.debug("[+] Detached kext object")
self.ql.log.debug("Detached kext object")
self.ql.reg.rdi = self.kext_object
# FIXME Determine provider for kext
@@ -104,9 +104,9 @@ class QlOsMacos(QlOsPosix):
self.savedrip=0xffffff8000a168a3
self.ql.run(begin=self.ql.loader.kext_attach)
if self.ql.reg.rax == 0:
self.ql.log.debug("[!] Failed to attach kext object")
self.ql.log.debug("Failed to attach kext object")
return
self.ql.log.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
@@ -116,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))
self.ql.log.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
@@ -134,7 +134,7 @@ class QlOsMacos(QlOsPosix):
kmod_info.stop = POINTER64(self.ql.loader.kext_stop)
kmod_info.updateToMem()
self.ql.log.debug("[+] Initialized kmod_info")
self.ql.log.debug("Initialized kmod_info")
self.ql.reg.rdi = kmod_info_addr
self.ql.reg.rsi = 0
@@ -163,7 +163,7 @@ class QlOsMacos(QlOsPosix):
def hook_sigtrap(self, intno= None, int = None):
self.ql.log.info("[!] Trap Found")
self.ql.log.info("Trap Found")
self.emu_error()
exit(1)
+43 -43
View File
@@ -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]
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" % (
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"]
))
@@ -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):
ql.log.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
ql.log.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):
ql.log.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):
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)" % (
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):
ql.log.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):
ql.log.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):
ql.log.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):
ql.log.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)
ql.log.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):
ql.log.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
ql.log.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):
ql.log.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)
ql.log.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
@@ -176,7 +176,7 @@ def ql_syscall_mach_msg_trap(ql, args, opt, ssize, rsize, rname, timeout):
def ql_syscall_access_macos(ql, path, flags, *args, **kw):
path_str = macho_read_string(ql, path, MAX_PATH_SIZE)
ql.log.info("access(%s, 0x%x)" % (path_str, flags))
ql.log.debug("[+] access(path: %s, flags: 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:
@@ -246,10 +246,10 @@ 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)
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" % (
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"]
))
ql.log.debug("[+] path str: %s\n" % (path_str))
ql.log.debug("path str: %s\n" % (path_str))
attr = b''
if attrlist["commonattr"] != 0:
@@ -277,7 +277,7 @@ def ql_syscall_getattrlist(ql, path, alist, attributeBuffer, bufferSize, options
# };
def ql_syscall_getrlimit(ql, which, rlp, *args, **kw):
ql.log.info("getrlimit(0x%x, 0x%x)" % (which, rlp))
ql.log.debug("[+] getrlimit(which:0x%x, rlp: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
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))
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:
ql.log.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,8 +332,8 @@ 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)
ql.log.debug("[+] log mem wirte : " + hex(len(data)))
ql.log.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
@@ -341,7 +341,7 @@ def ql_syscall_mmap2_macos(ql, mmap2_addr, mmap2_length, mmap2_prot, mmap2_flags
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
ql.log.debug("[+] mmap_base is 0x%x" % regreturn)
ql.log.debug("mmap_base is 0x%x" % regreturn)
return regreturn
@@ -357,7 +357,7 @@ def ql_syscall_sysctlbyname(ql, name, namelen, old, oldlenp, new_arg, newlen):
ql.log.info("sysctlbyname(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
name, namelen, old, oldlenp, new_arg, newlen
))
ql.log.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
@@ -366,7 +366,7 @@ def ql_syscall_sysctlbyname(ql, name, namelen, old, oldlenp, new_arg, newlen):
# check shared region if avalible , return not ready every time
def ql_syscall_shared_region_check_np(ql, p, uap, retvalp, *args, **kw):
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))
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
@@ -375,7 +375,7 @@ def ql_syscall_proc_info(ql, callnum, pid, flavor, arg, buff, buffer_size):
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
))
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)" % (
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:
@@ -433,9 +433,9 @@ def ql_syscall_stat64_macos(ql, stat64_pathname, stat64_buf_ptr, *args, **kw):
ql.log.info("stat64(%s, 0x%x) = %d" % (stat64_file, stat64_buf_ptr, regreturn))
if regreturn == 0:
set_eflags_cf(ql, 0x0)
ql.log.debug("[+] stat64 write completed")
ql.log.debug("stat64 write completed")
else:
ql.log.debug("[!] stat64 read/write fail")
ql.log.debug("stat64 read/write fail")
return regreturn
# 0x153
@@ -490,7 +490,7 @@ def ql_syscall_fstat64_macos(ql, fstat64_fd, fstat64_add, *args, **kw):
fstat64_buf += ql.pack32(0x0) # __int32_t st_lspare
fstat64_buf += ql.pack32(0x0) # __int64_t st_qspare[2]
else :
raise QlErrorArch("[!] Arch not support in syscall fstat64")
raise QlErrorArch("Arch not support in syscall fstat64")
ql.mem.write(fstat64_add, fstat64_buf)
regreturn = 0
@@ -499,9 +499,9 @@ def ql_syscall_fstat64_macos(ql, fstat64_fd, fstat64_add, *args, **kw):
ql.log.info("fstat64(%d, 0x%x) = %d" % (fstat64_fd, fstat64_add, regreturn))
if regreturn == 0:
ql.log.debug("[+] fstat64 write completed")
ql.log.debug("fstat64 write completed")
else:
ql.log.debug("[!] fstat64 read/write fail")
ql.log.debug("fstat64 read/write fail")
return regreturn
# 0x16e
@@ -524,14 +524,14 @@ 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:
ql.log.debug("[+] write() CONTENT:")
ql.log.debug("write() CONTENT:")
ql.log.debug("%s" % buf)
if hasattr(ql.os.fd[write_fd], "write"):
ql.log.info("write(%d,%x,%i) = %d" % (write_fd, write_buf, write_count, regreturn))
ql.os.fd[write_fd].write(buf)
else:
ql.log.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:
@@ -571,9 +571,9 @@ def ql_syscall_open_nocancel(ql, filename, flags, mode, *args, **kw):
ql.log.info("open(%s, 0x%s, 0x%x) = %d" % (relative_path, flags, mode, regreturn))
if regreturn >= 0 and regreturn != 2:
ql.log.debug("[+] File Found: %s" % relative_path)
ql.log.debug("File Found: %s" % relative_path)
else:
ql.log.debug("[!] File Not Found %s" % relative_path)
ql.log.debug("File Not Found %s" % relative_path)
return regreturn
# 0x1b6
@@ -581,7 +581,7 @@ def ql_syscall_shared_region_map_and_slide_np(ql, fd, count, mappings_addr, slid
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
))
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)" % (
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 = []
@@ -604,7 +604,7 @@ def ql_syscall_csrctl(ql, op, useraddr, usersize, *args, **kw):
# 0x1f4
def ql_syscall_getentropy(ql, buffer, size, *args, **kw):
ql.log.info("getentropy(0x%x, 0x%x)" % (buffer, size))
ql.log.debug("[+] getentropy(buffer: 0x%x, size: 0x%x)" % (buffer, size))
ql.log.debug("getentropy(buffer: 0x%x, size: 0x%x)" % (buffer, size))
return KERN_SUCCESS
# 0x208
@@ -612,11 +612,11 @@ def ql_syscall_terminate_with_payload(ql, pid, reason_namespace, reason_code, pa
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))
ql.log.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()
raise QlErrorSyscallError("[!] Exit with Error")
raise QlErrorSyscallError("Exit with Error")
return KERN_SUCCESS
# 0x209
@@ -624,7 +624,7 @@ def ql_syscall_abort_with_payload(ql, reason_namespace, reason_code, payload, pa
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))
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,\
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):
ql.log.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
+11 -11
View File
@@ -17,43 +17,43 @@ def IOConnectCallMethod(ql, selector,
output_array, output_cnt, output_struct, output_struct_size):
if ql.os.IOKit is not True:
ql.log.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))
ql.log.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))
ql.log.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))
ql.log.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))
ql.log.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))
ql.log.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))
ql.log.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()
ql.log.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
ql.log.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)
ql.log.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
ql.log.debug("[+] Finish IOConnectCallMethod")
ql.log.debug("Finish IOConnectCallMethod")
return args_obj.scalarOutput, type(output_struct).from_buffer(args_obj.structureOutput)
+4 -4
View File
@@ -131,13 +131,13 @@ class QlMemoryManager:
perms_sym.append("-")
return "".join(perms_sym)
ql.log.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})"
ql.log.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):
@@ -324,7 +324,7 @@ class QlMemoryManager:
# address is free
if addr + size < max_gap_addr and self.is_mapped(addr, size) == False:
return addr
raise QlOutOfMemory("[!] Out Of Memory")
raise QlOutOfMemory("Out Of Memory")
def map_anywhere(
@@ -395,7 +395,7 @@ class QlMemoryManager:
self.ql.uc.mem_map(addr, size, perms)
self.add_mapinfo(addr, addr + size, perms, info if info else "[mapped]")
else:
raise QlMemoryMappedError("[!] Memory Mapped")
raise QlMemoryMappedError("Memory Mapped")
else:
self.ql.uc.mem_map_ptr(addr, size, perms, ptr)
+3 -3
View File
@@ -180,13 +180,13 @@ class QlOsPosix(QlOs):
raise
except Exception as e:
self.ql.log.exception("")
self.ql.log.info("[!] Syscall ERROR: %s DEBUG: %s" % (self.syscall_name, e))
self.ql.log.info("Syscall ERROR: %s DEBUG: %s" % (self.syscall_name, e))
raise e
else:
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))
"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")
raise QlErrorSyscallNotFound("Syscall Not Found")
# get syscall
def get_syscall(self):
+6 -6
View File
@@ -42,12 +42,12 @@ def ql_syscall_open(ql, filename, flags, mode, *args, **kw):
regreturn = - e.errno
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))
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:
ql.log.debug("[+] File Found: %s" % real_path)
ql.log.debug("File Found: %s" % real_path)
else:
ql.log.debug("[!] File Not Found %s" % real_path)
ql.log.debug("File Not Found %s" % real_path)
return regreturn
@@ -82,13 +82,13 @@ def ql_syscall_openat(ql, openat_fd, openat_path, openat_flags, openat_mode, *ar
regreturn = -1
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" % (
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:
ql.log.debug("[+] File Found: %s" % real_path)
ql.log.debug("File Found: %s" % real_path)
else:
ql.log.debug("[!] File Not Found %s" % real_path)
ql.log.debug("File Not Found %s" % real_path)
return regreturn
+1 -1
View File
@@ -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)
ql.log.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
+27 -27
View File
@@ -52,7 +52,7 @@ def ql_syscall_madvise(ql, *args, **kw):
def ql_syscall_mprotect(ql, mprotect_start, mprotect_len, mprotect_prot, *args, **kw):
regreturn = 0
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" % (
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
ql.log.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))
ql.log.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
ql.log.debug("[+] log old_mmap - return addr : " + hex(mmap_base))
ql.log.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:
ql.log.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
ql.log.debug("[+] log mem wirte : " + hex(len(data)))
ql.log.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)
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
ql.log.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):
ql.log.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))
ql.log.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
ql.log.debug("[+] log mmap - return addr : " + hex(mmap_base))
ql.log.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:
ql.log.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")
raise QlMemoryMappedError("mapping needed but fail")
ql.log.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,8 +191,8 @@ 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
ql.log.debug("[+] log mem wirte : " + hex(len(data)))
ql.log.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)
@@ -200,7 +200,7 @@ def ql_syscall_mmap(ql, mmap_addr, mmap_length, mmap_prot, mmap_flags, mmap_fd,
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
ql.log.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
ql.log.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))
ql.log.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))
ql.log.debug("[+] log mmap2 - return addr : " + hex(mmap_base))
ql.log.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:
ql.log.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
ql.log.debug("[+] log mem write : " + hex(len(data)))
ql.log.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)
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
ql.log.debug("[+] mmap2_base is 0x%x" % regreturn)
ql.log.debug("mmap2_base is 0x%x" % regreturn)
return regreturn
+1 -1
View File
@@ -103,6 +103,6 @@ def ql_syscall_socketcall(ql, socketcall_call, socketcall_args, *args, **kw):
return ql_syscall_setsockopt(ql)
else:
ql.log.debug("[!] error call %d" % socketcall_call)
ql.log.debug("error call %d" % socketcall_call)
ql.os.stop(stop_event=THREAD_EVENT_UNEXECPT_EVENT)
raise
+1 -1
View File
@@ -22,6 +22,6 @@ def ql_syscall_getrandom(ql, buf, buflen, flags,*args, **kw):
(buf, buflen, flags, regreturn))
if data:
ql.log.debug("[+] getrandom() CONTENT:")
ql.log.debug("getrandom() CONTENT:")
ql.log.debug(str(data))
return regreturn
+2 -2
View File
@@ -124,7 +124,7 @@ def ql_syscall_clone(ql, clone_flags, clone_child_stack, clone_parent_tidptr, cl
th.save()
if th is None or f_th is None:
raise Exception()
ql.log.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))
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))
@@ -138,7 +138,7 @@ 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
ql.log.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))
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))
+20 -20
View File
@@ -47,7 +47,7 @@ def ql_syscall_socket(ql, socket_domain, socket_type, socket_protocol, *args, **
socket_type = socket_type_mapping(socket_type, ql.archtype)
socket_domain = socket_domain_mapping(socket_domain, ql.archtype)
ql.log.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
@@ -150,7 +150,7 @@ def ql_syscall_bind(ql, bind_fd, bind_addr, bind_addrlen, *args, **kw):
ql.log.info("bind(%d, %s, %d) = %d" % (bind_fd, path, bind_addrlen, regreturn))
else:
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))
ql.log.debug("syscall bind host: %s and port: %i sin_family: %i" % (ql_bin_to_ip(host), port, sin_family))
return regreturn
@@ -252,7 +252,7 @@ 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:
ql.log.debug("[+] recv() CONTENT:")
ql.log.debug("recv() CONTENT:")
ql.log.debug("%s" % tmp_buf)
ql.mem.write(recv_buf, tmp_buf)
regreturn = len(tmp_buf)
@@ -267,15 +267,15 @@ 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:
ql.log.debug("[+] debug send() start")
ql.log.debug("debug send() start")
tmp_buf = ql.mem.read(send_buf, send_len)
ql.log.debug("[+] fd is " + str(send_sockfd))
ql.log.debug("[+] send() CONTENT:")
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))
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)
ql.log.debug("[+] debug send end")
ql.log.debug("debug send end")
except:
ql.log.info(sys.exc_info()[0])
if ql.output in (QL_OUTPUT.DEBUG, QL_OUTPUT.DUMP):
@@ -296,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:
ql.log.debug("[+] recvfrom() CONTENT:")
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:
ql.log.debug("[+] recvfrom() path is " + tmp_addr)
ql.log.debug("recvfrom() path is " + tmp_addr)
data += tmp_addr.encode()
else:
ql.log.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))
@@ -330,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:
ql.log.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:
@@ -346,18 +346,18 @@ 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())
ql.log.debug("[+] fd is " + str(sendto_sockfd))
ql.log.debug("[+] sendto() CONTENT:")
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))
ql.log.debug("sendto() flag is " + str(sendto_flags))
ql.log.debug("sendto() len is " + str(sendto_len))
if sin_family == 1:
ql.log.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:
ql.log.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))
ql.log.debug("[+] debug sendto end")
ql.log.debug("debug sendto end")
except:
ql.log.info(sys.exc_info()[0])
if ql.output in (QL_OUTPUT.DEBUG, QL_OUTPUT.DUMP):
+12 -12
View File
@@ -69,9 +69,9 @@ def ql_syscall_fstatat64(ql, fstatat64_fd, fstatat64_fname, fstatat64_buf, fstat
ql.log.info("fstatat64(0x%x, %s) = %d" % (fstatat64_fd, relative_path, regreturn))
if regreturn == 0:
ql.log.debug("[+] Directory Found: %s" % relative_path)
ql.log.debug("Directory Found: %s" % relative_path)
else:
ql.log.debug("[!] Directory Not Found: %s" % relative_path)
ql.log.debug("Directory Not Found: %s" % relative_path)
return regreturn
@@ -206,9 +206,9 @@ def ql_syscall_fstat64(ql, fstat64_fd, fstat64_add, *args, **kw):
ql.log.info("fstat64(%d, 0x%x) = %d" % (fstat64_fd, fstat64_add, regreturn))
if regreturn == 0:
ql.log.debug("[+] fstat64 write completed")
ql.log.debug("fstat64 write completed")
else:
ql.log.debug("[!] fstat64 read/write fail")
ql.log.debug("fstat64 read/write fail")
return regreturn
@@ -321,9 +321,9 @@ def ql_syscall_fstat(ql, fstat_fd, fstat_add, *args, **kw):
ql.log.info("fstat(%d, 0x%x) = %d" % (fstat_fd, fstat_add, regreturn))
if regreturn == 0:
ql.log.debug("[+] fstat write completed")
ql.log.debug("fstat write completed")
else:
ql.log.debug("[!] fstat read/write fail")
ql.log.debug("fstat read/write fail")
return regreturn
@@ -394,9 +394,9 @@ def ql_syscall_stat64(ql, stat64_pathname, stat64_buf_ptr, *args, **kw):
ql.log.info("stat64(%s, 0x%x) = %d" % (relative_path, stat64_buf_ptr, regreturn))
if regreturn == 0:
ql.log.debug("[+] stat64 write completed")
ql.log.debug("stat64 write completed")
else:
ql.log.debug("[!] stat64 read/write fail")
ql.log.debug("stat64 read/write fail")
return regreturn
@@ -455,9 +455,9 @@ def ql_syscall_stat(ql, stat_path, stat_buf_ptr, *args, **kw):
ql.log.info("stat(%s, 0x%x) = %d" % (relative_path, stat_buf_ptr, regreturn))
if regreturn == 0:
ql.log.debug("[+] stat() write completed")
ql.log.debug("stat() write completed")
else:
ql.log.debug("[!] stat() read/write fail")
ql.log.debug("stat() read/write fail")
return regreturn
@@ -515,9 +515,9 @@ def ql_syscall_lstat(ql, lstat_path, lstat_buf_ptr, *args, **kw):
ql.log.info("lstat(%s, 0x%x) = %d" % (relative_path, lstat_buf_ptr, regreturn))
if regreturn == 0:
ql.log.debug("[+] lstat() write completed")
ql.log.debug("lstat() write completed")
else:
ql.log.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):
+1 -1
View File
@@ -17,7 +17,7 @@ def ql_syscall_writev(ql, writev_fd, writev_vec, writev_vien, *args, **kw):
size_t_len = ql.archbit // 8
iov = ql.mem.read(writev_vec, writev_vien * size_t_len * 2)
ql.log.info("writev(0x%x, 0x%x, 0x%x)" % (writev_fd, writev_vec, writev_vien))
ql.log.debug("[+] writev() CONTENT:")
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])
+12 -12
View File
@@ -147,9 +147,9 @@ def ql_syscall_faccessat(ql, faccessat_dfd, faccessat_filename, faccessat_mode,
ql.log.info("facccessat (%d, 0x%x, 0x%x) = %d" %(faccessat_dfd, faccessat_filename, faccessat_mode, regreturn))
if regreturn == -1:
ql.log.debug("[!] File Not Found or Skipped: %s" % access_path)
ql.log.debug("File Not Found or Skipped: %s" % access_path)
else:
ql.log.debug("[+] File Found: %s" % access_path)
ql.log.debug("File Found: %s" % access_path)
return regreturn
@@ -201,7 +201,7 @@ def ql_syscall_brk(ql, brk_input, *args, **kw):
regreturn = ql.loader.brk_address
ql.log.debug("[+] brk return(0x%x)" % regreturn)
ql.log.debug("brk return(0x%x)" % regreturn)
return regreturn
@@ -218,9 +218,9 @@ def ql_syscall_access(ql, access_path, access_mode, *args, **kw):
ql.log.info("access(%s, 0x%x) = %d " % (relative_path, access_mode, regreturn))
if regreturn == 0:
ql.log.debug("[+] File found: %s" % relative_path)
ql.log.debug("File found: %s" % relative_path)
else:
ql.log.debug("[!] No such file or directory")
ql.log.debug("No such file or directory")
return regreturn
@@ -267,7 +267,7 @@ def ql_syscall_read(ql, read_fd, read_buf, read_len, *args, **kw):
ql.log.info("read(%d, 0x%x, 0x%x) = %d" % (read_fd, read_buf, read_len, regreturn))
if data:
ql.log.debug("[+] read() CONTENT:")
ql.log.debug("read() CONTENT:")
ql.log.debug("%s" % data)
return regreturn
@@ -279,14 +279,14 @@ def ql_syscall_write(ql, write_fd, write_buf, write_count, *args, **kw):
try:
buf = ql.mem.read(write_buf, write_count)
if buf:
ql.log.debug("[+] write() CONTENT:")
ql.log.debug("write() CONTENT:")
ql.log.debug("%s" % buf)
if hasattr(ql.os.fd[write_fd], "write"):
ql.log.info("write(%d,%x,%i) = %d" % (write_fd, write_buf, write_count, regreturn))
ql.os.fd[write_fd].write(buf)
else:
ql.log.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:
@@ -399,7 +399,7 @@ def ql_syscall_vfork(ql, *args, **kw):
if pid == 0:
ql.os.child_processes = True
ql.log.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
else:
regreturn = pid
@@ -609,7 +609,7 @@ def ql_syscall_unlink(ql, unlink_pathname, *args, **kw):
os.unlink(real_path)
regreturn = 0
except FileNotFoundError:
ql.log.debug('[!] No such file or directory')
ql.log.debug('No such file or directory')
regreturn = -1
except:
regreturn = -1
@@ -629,7 +629,7 @@ def ql_syscall_unlinkat(ql, dirfd, pathname, flag, *args, **kw):
os.unlink(real_path)
return 0
except FileNotFoundError:
ql.log.debug("[!] No such file or directory")
ql.log.debug("No such file or directory")
return -1
except:
return -1
@@ -682,6 +682,6 @@ def ql_syscall_getdents(ql, fd, dirp, count, *args, **kw):
regreturn = 0
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))
ql.log.debug("getdents(%d, /* %d entries */, 0x%x) = %d" % (fd, _ent_count, count, regreturn))
return regreturn
+1 -1
View File
@@ -19,7 +19,7 @@ def hook_EndOfExecution(ql):
if ql.loader.unload_modules():
return
ql.log.info(f'[+] No more modules to run')
ql.log.info(f'No more modules to run')
ql.emu_stop()
else:
ql.loader.execute_next_module()
+7 -7
View File
@@ -157,7 +157,7 @@ class QlOsUtils:
# Sanity check.
if cur_path[0] != '/':
self.ql.log.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)
@@ -174,7 +174,7 @@ class QlOsUtils:
# Sanity check.
if cur_path[0] != '/':
self.ql.log.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)
@@ -196,17 +196,17 @@ class QlOsUtils:
return str(Path(cur_path) / path)
def post_report(self):
self.ql.log.debug("[+] Syscalls called")
self.ql.log.debug("Syscalls called")
for key, values in self.ql.os.syscalls.items():
self.ql.log.debug("[-] %s:" % key)
for value in values:
self.ql.log.debug("[-] %s " % str(dumps(value)))
self.ql.log.debug("[+] Registries accessed")
self.ql.log.debug("Registries accessed")
for key, values in self.ql.os.registry_manager.accessed.items():
self.ql.log.debug("[-] %s:" % key)
for value in values:
self.ql.log.debug("[-] %s " % str(dumps(value)))
self.ql.log.debug("[+] Strings")
self.ql.log.debug("Strings")
for key, values in self.ql.os.appeared_strings.items():
val = " ".join([str(word) for word in values])
self.ql.log.debug("[-] %s: %s" % (key, val))
@@ -219,7 +219,7 @@ class QlOsUtils:
ret = self.ql.stack_read(0)
def restore(ql):
self.ql.log.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)
@@ -274,7 +274,7 @@ class QlOsUtils:
def setup_output(self):
def ql_hook_block_disasm(ql, address, size):
self.ql.log.info("\n[+] Tracing basic block at 0x%x" % (address))
self.ql.log.info("\nTracing basic block at 0x%x" % (address))
if self._disasm_hook:
self._disasm_hook.remove()
+7 -7
View File
@@ -17,10 +17,10 @@ def _RegOpenKey(ql, address, params):
hKey = params["hKey"]
s_lpSubKey = params["lpSubKey"]
phkResult = params["phkResult"]
ql.log.debug("[+] Key %s %s" % (hKey, s_lpSubKey))
ql.log.debug("Key %s %s" % (hKey, s_lpSubKey))
if hKey not in REG_KEYS:
ql.log.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]
@@ -29,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:
ql.log.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):
ql.log.debug("[!] Value key %s not present" % key)
ql.log.debug("Value key %s not present" % key)
return ERROR_FILE_NOT_FOUND
# new handle
@@ -62,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]
ql.log.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
@@ -76,7 +76,7 @@ def RegQueryValue(ql, address, params):
# error key
if reg_type is None or value is None:
ql.log.debug("[!] Key value not found")
ql.log.debug("Key value not found")
return ERROR_FILE_NOT_FOUND
else:
# set lpData
@@ -416,7 +416,7 @@ def hook_GetTokenInformation(ql, address, params):
ql.mem.write(dst, information_value)
return 1
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
# PUCHAR GetSidSubAuthorityCount(
+2 -2
View File
@@ -34,7 +34,7 @@ def hook_CryptStringToBinaryA(ql, address, params):
size_dst = int.from_bytes(ql.mem.read(size_dst_pointer, 4), byteorder="little")
if size_dst != 0 and size_dst < size_src:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
if flag_src == CRYPT_STRING_BASE64:
# Had a padding error, hope this always works
add_pad = 4 - (len(string_src) % 4)
@@ -44,7 +44,7 @@ def hook_CryptStringToBinaryA(ql, address, params):
else:
ql.log.debug("Flag")
ql.log.debug(flag_src)
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
if string_dst == 0:
# Only wants the length
+4 -4
View File
@@ -33,7 +33,7 @@ def hook_GetFileType(ql, address, params):
else:
obj = ql.os.handle_manager.get(hFile)
if obj is None:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
else:
# technically is not always a type_char but.. almost
ret = FILE_TYPE_CHAR
@@ -365,7 +365,7 @@ def hook_GetVolumeInformationW(ql, address, params):
system_type = (ql.os.profile["VOLUME"]["type"] + "\x00").encode("utf-16le")
ql.mem.write(pt_system_type, system_type)
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
return 1
@@ -380,7 +380,7 @@ def hook_GetDriveTypeW(ql, address, params):
return DRIVE_FIXED
# TODO add configuration for drives
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
return DRIVE_NO_ROOT_DIR
@@ -408,7 +408,7 @@ def hook_GetDiskFreeSpaceW(ql, address, params):
ql.mem.write(pt_free_clust, free_clust)
ql.mem.write(pt_total_clust, total_clust)
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
return 0
@@ -29,7 +29,7 @@ def _GetModuleHandle(ql, address, params):
if lpModuleName in ql.loader.dlls:
ret = ql.loader.dlls[lpModuleName]
else:
ql.log.debug("[!] Library %s not imported" % lpModuleName)
ql.log.debug("Library %s not imported" % lpModuleName)
ret = 0
return ret
@@ -88,7 +88,7 @@ def hook_GetModuleFileNameA(ql, address, params):
ql.mem.write(lpFilename, filename + b"\x00")
else:
ql.log.debug("hModule %x" % hModule)
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
return ret
@@ -115,7 +115,7 @@ def hook_GetModuleFileNameW(ql, address, params):
ret = filename_len
ql.mem.write(lpFilename, filename + b"\x00")
else:
raise QlErrorNotImplemented("[!] API not implemented")
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:
ql.log.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
@@ -257,4 +257,4 @@ def hook_SetDefaultDllDirectories(ql, address, params):
if value == LOAD_LIBRARY_SEARCH_USER_DIRS:
# TODO we have to probably set an handler for this, since it can be a not default value.
# And we have to change the default path of load
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
@@ -81,7 +81,7 @@ def hook_ExpandEnvironmentStringsW(ql, address, params):
result = ql.os.profile["PATH"].get(substring, None)
if result is None:
ql.log.debug(substring)
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
result = (string[:start] + result + string[end + 1:] + "\x00").encode("utf-16le")
dst = params["lpDst"]
max_size = params["nSize"]
+2 -2
View File
@@ -163,14 +163,14 @@ def hook_OpenMutexW(ql, address, params):
if mutex.isFree():
mutex.lock()
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
else:
if handle is None:
# If a named mutex does not exist, the function fails and GetLastError returns ERROR_FILE_NOT_FOUND.
ql.os.last_error = ERROR_FILE_NOT_FOUND
return 0
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
# HANDLE OpenMutexA(
+1 -1
View File
@@ -28,7 +28,7 @@ def hook_CreateToolhelp32Snapshot(ql, address, params):
if flag == TH32CS_SNAPPROCESS:
ql.log.debug("[=] The target is checking every process!")
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
return 0xD10C
+4 -4
View File
@@ -301,7 +301,7 @@ def compare(p1, operator, p2):
elif operator == "<=":
return p1 <= p2
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
# typedef struct _OSVERSIONINFOEXA {
@@ -344,7 +344,7 @@ def hook_VerifyVersionInfoW(ql, address, params):
elif value == VER_LESS_EQUAL:
operator = "<="
else:
raise QlErrorNotImplemented("[!] API not implemented with operator %d" % value)
raise QlErrorNotImplemented("API not implemented with operator %d" % value)
# Versions should be compared together
if key == VER_MAJORVERSION or key == VER_MINORVERSION or key == VER_PRODUCT_TYPE:
major_version_asked = os_asked.major[0]
@@ -357,7 +357,7 @@ def hook_VerifyVersionInfoW(ql, address, params):
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)
raise QlErrorNotImplemented("API not implemented for version %s" % concat)
else:
ql.log.debug("[=] The target asks for version %s %s" % (operator, version_asked))
# We can finally compare
@@ -368,7 +368,7 @@ def hook_VerifyVersionInfoW(ql, address, params):
elif key == VER_SERVICEPACKMAJOR:
res = compare(ql.os.profile.getint("SYSTEM", "VER_SERVICEPACKMAJOR"), operator, os_asked.service_major[0])
else:
raise QlErrorNotImplemented("[!] API not implemented for key %s" % key)
raise QlErrorNotImplemented("API not implemented for key %s" % key)
# The result is a AND between every value, so if we find a False we just exit from the loop
if not res:
ql.os.last_error = ERROR_OLD_WIN_VERSION
+1 -1
View File
@@ -62,7 +62,7 @@ def hook_GetLocaleInfoA(ql, address, params):
local_dict = LOCALE.get(locale_value, None)
if local_dict is None:
# raise QlErrorNotImplemented("[!] API not implemented")
# raise QlErrorNotImplemented("API not implemented")
ql.os.last_error = ERROR_INVALID_PARAMETER
return 0
@@ -29,5 +29,5 @@ def hook_IsWow64Process(ql, address, params):
if ql.archbit == 32:
ql.mem.write(pointer, false)
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
return 1
+1 -1
View File
@@ -448,7 +448,7 @@ def hook__ismbblead(ql, address, params):
if loc[0x1004] == "utf-8":
return 0
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
# errno_t _wfopen_s(
+5 -5
View File
@@ -53,7 +53,7 @@ def _QueryInformationProcess(ql, address, params):
value = addr.to_bytes(ql.pointersize, "little")
else:
ql.log.debug(str(flag))
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
ql.log.debug("[=] The target is checking the debugger via QueryInformationProcess ")
ql.mem.write(dst, value)
if pt_res != 0:
@@ -132,7 +132,7 @@ def _QuerySystemInformation(ql, address, params):
return STATUS_INFO_LENGTH_MISMATCH
else:
ql.log.debug(str(siClass))
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
return STATUS_SUCCESS
@@ -211,7 +211,7 @@ def hook_ZwQueryObject(ql, address, params):
# res = qiling.os.windows.structs.ObjectAllTypesInformation(ql, 2, oti)
return 1
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
if dest != 0 and params["Handle"] != 0:
res.write(dest)
if size_dest != 0:
@@ -268,7 +268,7 @@ def _SetInformationProcess(ql, address, params):
value = addr.to_bytes(ql.pointersize, "little")
else:
ql.log.debug(str(flag))
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
return STATUS_SUCCESS
@@ -299,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:
ql.log.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]:
+1 -1
View File
@@ -63,7 +63,7 @@ def hook_ZwSetInformationThread(ql, address, params):
if dst != 0:
ql.mem.write(dst, 0x0.to_bytes(1, byteorder="little"))
else:
raise QlErrorNotImplemented("[!] API not implemented %d " %
raise QlErrorNotImplemented("API not implemented %d " %
information)
else:
+6 -6
View File
@@ -44,7 +44,7 @@ def hook_SHGetFileInfoW(ql, address, params):
return 1
else:
ql.log.debug(flags)
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
def _ShellExecute(ql, obj: ShellExecuteInfoA):
@@ -116,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("\\", "/")
ql.log.debug("[+] dir path: %s" % path)
ql.log.debug("dir path: %s" % path)
path_emulated = os.path.join(ql.rootfs, appdata_dir)
ql.log.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)
ql.log.debug("[!] os.makedirs completed")
ql.log.debug("os.makedirs completed")
except OSError:
ql.log.debug("[!] os.makedirs fail")
ql.log.debug("os.makedirs fail")
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
return 1
+8 -8
View File
@@ -170,10 +170,10 @@ def hook_MapVirtualKeyW(ql, address, params):
return code
else:
ql.log.debug("Code value %x" % code_value)
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
else:
ql.log.debug("Map value %x" % map_value)
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
# SHORT GetKeyState(
@@ -244,7 +244,7 @@ def hook_GetSystemMetrics(ql, address, params):
return 300
else:
ql.log.debug("Info value %x" % info)
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
# HDC GetDC(
@@ -548,7 +548,7 @@ def hook_wsprintfW(ql, address, params):
if ql.archtype == QL_ARCH.X8664:
# We must pop the stack correctly
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
ql.mem.write(dst, (string + "\x00").encode("utf-16le"))
return size
@@ -569,7 +569,7 @@ def hook_sprintf(ql, address, params):
if ql.archtype == QL_ARCH.X8664:
# We must pop the stack correctly
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
ql.mem.write(dst, (string + "\x00").encode("utf-16le"))
return size
@@ -639,7 +639,7 @@ def hook_wsprintfA(ql, address, params):
if ql.archtype== QL_ARCH.X8664:
# We must pop the stack correctly
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
ql.mem.write(dst, (string + "\x00").encode("utf-8"))
return size
@@ -660,7 +660,7 @@ def hook_MessageBoxW(ql, address, params):
return IDYES
else:
ql.log.debug(type_box)
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
# int MessageBoxA(
@@ -708,7 +708,7 @@ def hook_GetWindowThreadProcessId(ql, address, params):
if target == ql.os.profile.getint("KERNEL", "pid") or target == ql.os.profile.getint("KERNEL", "shell_pid"):
pid = ql.os.profile.getint("KERNEL", "parent_pid")
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
dst = params["lpdwProcessId"]
if dst != 0:
ql.mem.write(dst, pid.to_bytes(4, "little"))
+1 -1
View File
@@ -57,7 +57,7 @@ def hook_connect(ql, address, params):
[str(octet) for octet in ql.mem.read(params["name"] + 4, 4)]
)
else:
ql.log.debug("[!] sockaddr sin_family unhandled variant")
ql.log.debug("sockaddr sin_family unhandled variant")
return 0
ql.log.debug(f"0x{params['name']:08x}: sockaddr_in{6 if sin_family == 0x17 else ''}",
+2 -2
View File
@@ -54,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:
ql.log.info('[!] %s not found', winsdk_path)
ql.log.info('%s not found', winsdk_path)
if funcname not in funclist:
params = replace_params
else:
@@ -94,7 +94,7 @@ def winsdkapi(cc, param_num=None, dllname=None, replace_params_type=None, replac
elif ql.archtype == QL_ARCH.X8664:
return ql.os.x8664_fastcall(param_num, params, func, args, kwargs, passthru)
else:
raise QlErrorArch("[!] Unknown self.ql.arch")
raise QlErrorArch("Unknown self.ql.arch")
return wrapper
return decorator
+7 -7
View File
@@ -39,7 +39,7 @@ class RegistryManager:
self.hive = hive
else:
self.hive = os.path.join(ql.rootfs, "Windows", "registry")
ql.log.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}'!")
@@ -61,7 +61,7 @@ class RegistryManager:
try:
self.registry_config = json.loads(data)
except json.decoder.JSONDecodeError:
raise QlErrorJsonDecode("[!] Windows Registry JSON decode error")
raise QlErrorJsonDecode("Windows Registry JSON decode error")
finally:
self.f_config.close()
@@ -98,7 +98,7 @@ class RegistryManager:
sub = "\\".join(keys[1:])
data = reg.open(sub)
else:
raise QlErrorNotImplemented("[!] Windows Registry %s not implemented" % (keys[0]))
raise QlErrorNotImplemented("Windows Registry %s not implemented" % (keys[0]))
except Exception:
return False
@@ -113,7 +113,7 @@ class RegistryManager:
return REG_TYPES[self.regdiff[key][subkey].type], self.regdiff[key][subkey].value
else:
raise QlErrorNotImplemented(
"[!] Windows Registry Type %s not implemented" % self.regdiff[key][subkey].type)
"Windows Registry Type %s not implemented" % self.regdiff[key][subkey].type)
# read hive
reg = None
@@ -129,7 +129,7 @@ class RegistryManager:
sub = "\\".join(keys[1:])
data = reg.open(sub)
else:
raise QlErrorNotImplemented("[!] Windows Registry %s not implemented" % (keys[0]))
raise QlErrorNotImplemented("Windows Registry %s not implemented" % (keys[0]))
for value in data.values():
if value.name() == subkey and (reg_type == Registry.RegNone or
@@ -191,7 +191,7 @@ class RegistryManager:
self.ql.mem.write(address, bytes(reg_value))
length = len(reg_value)
else:
raise QlErrorNotImplemented("[!] Windows Registry Type not implemented")
raise QlErrorNotImplemented("Windows Registry Type not implemented")
elif reg_type == Registry.RegDWord:
data = self.ql.pack32(reg_value)
self.ql.mem.write(address, data)
@@ -202,7 +202,7 @@ class RegistryManager:
length = len(data)
else:
raise QlErrorNotImplemented(
"[!] Windows Registry Type write to memory %s not implemented" % (REG_TYPES[reg_type]))
"Windows Registry Type write to memory %s not implemented" % (REG_TYPES[reg_type]))
return length
+8 -8
View File
@@ -1652,37 +1652,37 @@ class WindowsStruct:
raise NotImplementedError
def generic_write(self, addr: int, attributes: list):
self.ql.log.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)
self.ql.log.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
self.ql.log.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):
val.write(addr)
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
already_written += size
self.addr = addr
def generic_read(self, addr: int, attributes: list):
self.ql.log.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)
self.ql.log.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:
@@ -1692,7 +1692,7 @@ class WindowsStruct:
obj.read(addr)
elem[0] = obj
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
already_read += size
self.addr = addr
@@ -1770,7 +1770,7 @@ class Token:
def get(self, value):
res = self.struct[value]
if res is None:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
else:
return res
+1 -1
View File
@@ -19,7 +19,7 @@ from .structs import UNICODE_STRING32, UNICODE_STRING64
def ql_x86_windows_hook_mem_error(ql, access, addr, size, value):
ql.log.debug("[+] ERROR: unmapped memory access at 0x%x" % addr)
ql.log.debug("ERROR: unmapped memory access at 0x%x" % addr)
return False
+4 -4
View File
@@ -114,13 +114,13 @@ class QlOsWindows(QlOs):
except Exception:
self.ql.log.exception("")
self.ql.log.info("[!] %s Exception Found" % winapi_name)
self.ql.log.info("%s Exception Found" % winapi_name)
self.emu_error()
raise QlErrorSyscallError("[!] Windows API Implementation Error")
raise QlErrorSyscallError("Windows API Implementation Error")
else:
self.ql.log.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")
raise QlErrorSyscallNotFound("Windows API Implementation Not Found")
def run(self):
+10 -10
View File
@@ -168,7 +168,7 @@ def ql_get_arch_bits(arch):
return 32
if arch in QL_ARCH_64BIT:
return 64
raise QlErrorArch("[!] Invalid Arch")
raise QlErrorArch("Invalid Arch")
def ql_is_valid_ostype(ostype):
if ostype not in QL_OS_ALL:
@@ -259,12 +259,12 @@ def ql_get_module_function(module_name, function_name = None):
try:
imp_module = importlib.import_module(module_name)
except Exception as ex:
raise QlErrorModuleNotFound("[!] Unable to import module %s (%s)" % (module_name, ex))
raise QlErrorModuleNotFound("Unable to import module %s (%s)" % (module_name, ex))
try:
module_function = getattr(imp_module, function_name)
except:
raise QlErrorModuleFunctionNotFound("[!] Unable to import %s from %s" % (function_name, imp_module))
raise QlErrorModuleFunctionNotFound("Unable to import %s from %s" % (function_name, imp_module))
return module_function
@@ -416,7 +416,7 @@ def ql_guess_emu_env(path):
arch, ostype, archendian = ql_pe_parse_emu_env(path)
if ostype not in (QL_OS_ALL):
raise QlErrorOsType("[!] File does not belong to either 'linux', 'windows', 'freebsd', 'macos', 'ios', 'dos'")
raise QlErrorOsType("File does not belong to either 'linux', 'windows', 'freebsd', 'macos', 'ios', 'dos'")
return arch, ostype, archendian
@@ -447,7 +447,7 @@ def debugger_setup(debugger, ql):
if debugger_convert(remotedebugsrv) not in (QL_DEBUGGER):
raise QlErrorOutput("[!] Error: Debugger not supported")
raise QlErrorOutput("Error: Debugger not supported")
debugsession = ql_get_module_function(f"qiling.debugger.{remotedebugsrv}.{remotedebugsrv}", f"Ql{str.capitalize(remotedebugsrv)}")
@@ -455,7 +455,7 @@ def debugger_setup(debugger, ql):
def arch_setup(archtype, ql):
if not ql_is_valid_arch(archtype):
raise QlErrorArch("[!] Invalid Arch")
raise QlErrorArch("Invalid Arch")
if archtype == QL_ARCH.ARM_THUMB:
archtype = QL_ARCH.ARM
@@ -479,10 +479,10 @@ def ql_syscall_mapping_function(ostype):
def os_setup(archtype, ostype, ql):
if not ql_is_valid_ostype(ostype):
raise QlErrorOsType("[!] Invalid OSType")
raise QlErrorOsType("Invalid OSType")
if not ql_is_valid_arch(archtype):
raise QlErrorArch("[!] Invalid Arch %s" % archtype)
raise QlErrorArch("Invalid Arch %s" % archtype)
ostype_str = ostype_convert_str(ostype)
ostype_str = ostype_str.capitalize()
@@ -580,14 +580,14 @@ def verify_ret(ql, err):
if ql.archtype == QL_ARCH.X8664: # Win64
if ql.os.init_sp == ql.reg.arch_sp or ql.os.init_sp + 8 == ql.reg.arch_sp or ql.os.init_sp + 0x10 == ql.reg.arch_sp: # FIXME
# [+] 0x11626 c3 ret
# 0x11626 c3 ret
# print("OK, stack balanced!")
pass
else:
raise
else: # Win32
if ql.os.init_sp + 12 == ql.reg.arch_sp: # 12 = 8 + 4
# [+] 0x114dd c2 08 00 ret 8
# 0x114dd c2 08 00 ret 8
pass
else:
raise
+4 -4
View File
@@ -59,12 +59,12 @@ def run_shellcode(options):
elif options.hex == True:
if options.input is not None:
print ("[+] Load HEX from ARGV")
print ("Load HEX from ARGV")
shellcoder = str(options.input).strip("\\\\x").split("x")
shellcoder = "".join(shellcoder).strip()
shellcoder = bytes.fromhex(shellcoder)
elif options.filename is not None:
print ("[+] Load HEX from FILE")
print ("Load HEX from FILE")
shellcoder = str(read_file(options.filename)).strip('b\'').strip('\\n')
shellcoder = shellcoder.strip('x').split("\\\\x")
shellcoder = "".join(shellcoder).strip()
@@ -74,7 +74,7 @@ def run_shellcode(options):
exit(1)
elif options.asm == True:
print ("[+] Load ASM from FILE")
print ("Load ASM from FILE")
assembly = read_file(options.filename)
archtype = arch_convert(options.arch)
archendian = QL_ENDIAN.EL
@@ -86,7 +86,7 @@ def run_shellcode(options):
shellcoder = bytes(shellcoder)
else:
print ("[+] Load BIN from FILE")
print ("Load BIN from FILE")
if options.filename is None:
print("ERROR: File not found")
exit(1)
+2 -2
View File
@@ -25,7 +25,7 @@ def syscall_getrandom(ql, buf, buflen, flags, *args, **kw):
(buf, buflen, flags, regreturn))
if data:
ql.log.debug("[+] getrandom() CONTENT:")
ql.log.debug("getrandom() CONTENT:")
ql.log.debug(str(data))
return regreturn
@@ -46,7 +46,7 @@ def syscall_fstatfs(ql, fd, buf, *args, **kw):
ql.log.info("fstatfs(0x%x, 0x%x) = %d" % (fd, buf, regreturn))
if data:
ql.log.debug("[+] fstatfs() CONTENT:")
ql.log.debug("fstatfs() CONTENT:")
ql.log.debug(str(data))
return regreturn
+1 -1
View File
@@ -63,7 +63,7 @@ class MACHOTest(unittest.TestCase):
try:
ql.os.load_kext()
except UcError as e:
print("[!] Load driver error: %s" % e)
print("Load driver error: %s" % e)
sys.exit(-1)
ql.os.ev_manager.add_process(1337, "agent")
+1 -1
View File
@@ -113,7 +113,7 @@ class PETest(unittest.TestCase):
new_name += random.choice(st.ascii_lowercase + st.ascii_uppercase)
ql.os.profile[key][subkey] = new_name
else:
raise QlErrorNotImplemented("[!] API not implemented")
raise QlErrorNotImplemented("API not implemented")
ql = Qiling(["../examples/rootfs/x86_windows/bin/GandCrab502.bin"], "../examples/rootfs/x86_windows",
output="debug", profile="profiles/windows_gandcrab_admin.ql")
+1 -1
View File
@@ -193,7 +193,7 @@ class PETest(unittest.TestCase):
ql.os.set_function_args([0])
ql.hook_address(hook_second_stop_address, 0x4055FA)
ql.run(begin=0x4053B2)
print("[+] test kill thread")
print("test kill thread")
if ql.amsint32_driver:
ql.amsint32_driver.os.io_Write(ql.pack32(0xdeadbeef))