mirror of
https://github.com/qilingframework/qiling.git
synced 2026-10-12 02:21:40 +00:00
remove [+] and [!]
This commit is contained in:
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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]:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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 ''}",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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")
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user