Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions examples/hello_arm_uboot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
#
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#

import sys
sys.path.append("..")

from qiling.core import Qiling
from qiling.const import QL_VERBOSE
from qiling.os.const import STRING

def get_kaimendaji_password():
def my_getenv(ql, *args, **kwargs):
env = {"ID": b"000000000000000", "ethaddr": b"11:22:33:44:55:66"}
params = ql.os.resolve_fcall_params({'key': STRING})
value = env.get(params["key"], b"")

value_addr = ql.os.heap.alloc(len(value))
ql.mem.write(value_addr, value)

ql.reg.r0 = value_addr
ql.reg.arch_pc = ql.reg.lr

def get_password(ql, *args, **kwargs):
password_raw = ql.mem.read(ql.reg.r0, ql.reg.r2)

password = ''
for item in password_raw:
if 0 <= item <= 9:
password += chr(item + 48)
else:
password += chr(item + 87)

print("The password is: %s" % password)

def partial_run_init(ql):
# argv prepare
ql.reg.arch_sp -= 0x30
arg0_ptr = ql.reg.arch_sp
ql.mem.write(arg0_ptr, b"kaimendaji")

ql.reg.arch_sp -= 0x10
arg1_ptr = ql.reg.arch_sp
ql.mem.write(arg1_ptr, b"000000") # arbitrary password

ql.reg.arch_sp -= 0x20
argv_ptr = ql.reg.arch_sp
ql.mem.write(argv_ptr, ql.pack(arg0_ptr))
ql.mem.write(argv_ptr + ql.pointersize, ql.pack(arg1_ptr))

ql.reg.r2 = 2
ql.reg.r3 = argv_ptr


with open("../examples/rootfs/blob/u-boot.bin.img", "rb") as f:
uboot_code = f.read()

ql = Qiling(code=uboot_code[0x40:], archtype="arm", ostype="blob", profile="uboot_bin.ql", verbose=QL_VERBOSE.OFF)

image_base_addr = ql.loader.load_address
ql.hook_address(my_getenv, image_base_addr + 0x13AC0)
ql.hook_address(get_password, image_base_addr + 0x48634)

partial_run_init(ql)

ql.run(image_base_addr + 0x486B4, image_base_addr + 0x48718)

if __name__ == "__main__":
get_kaimendaji_password()
20 changes: 20 additions & 0 deletions examples/uboot_bin.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[CODE]
ram_size = 0xa00000
entry_point = 0x80800000
heap_size = 0x300000


[LOG]
# log directory output
# usage: dir = qlog
dir =
# split log file, use with multithread
split = False


[MISC]
# append string into different logs
# maily for multiple times Ql run with one file
# usage: append = test1
append =
current_path = /
2 changes: 2 additions & 0 deletions qiling/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class QL_OS(IntEnum):
EVM = 207
QNX = 208
MCU = 209
BLOB = 210

class QL_VERBOSE(IntEnum):
OFF = 0
Expand Down Expand Up @@ -89,6 +90,7 @@ def __reverse_enum(e: Type[Enum]) -> Mapping[str, Any]:
QL_OS.DOS : "DOS",
QL_OS.EVM : "EVM",
QL_OS.MCU : "MCU",
QL_OS.BLOB : "BLOB"
}

arch_os_map = {
Expand Down
28 changes: 28 additions & 0 deletions qiling/loader/blob.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
#
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be part of mcu?

# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#

from qiling import Qiling
from qiling.loader.loader import QlLoader
from qiling.os.memory import QlMemoryHeap

class QlLoaderBLOB(QlLoader):
def __init__(self, ql: Qiling):
super().__init__(ql)

self.load_address = 0

def run(self):
self.load_address = self.ql.os.entry_point # for consistency

self.ql.mem.map(self.ql.os.entry_point, self.ql.os.code_ram_size, info="[code]")
self.ql.mem.write(self.ql.os.entry_point, self.ql.code)

heap_address = self.ql.os.entry_point + self.ql.os.code_ram_size
heap_size = int(self.ql.os.profile.get("CODE", "heap_size"), 16)
self.ql.os.heap = QlMemoryHeap(self.ql, heap_address, heap_address + heap_size)

self.ql.reg.arch_sp = heap_address - 0x1000

return
43 changes: 43 additions & 0 deletions qiling/os/blob/blob.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
#
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#

from qiling import Qiling
from qiling.cc import QlCC, intel, arm, mips
from qiling.const import QL_ARCH
from qiling.os.fcall import QlFunctionCall
from qiling.os.os import QlOs

class QlOsBlob(QlOs):
""" QlOsBlob for bare barines.

For bare binary such as u-boot, it's ready to be mapped and executed directly,
where there is(may be) no concept of os? Currently, some functionalities such as
resolve_fcall_params(), heap or add_fs_mapper() are based on os. To keep the
consistence of api usage, QlOsBlob is introduced and placed at its loader temporarily.
"""
def __init__(self, ql: Qiling):
super(QlOsBlob, self).__init__(ql)

self.ql = ql

cc: QlCC = {
QL_ARCH.X86 : intel.cdecl,
QL_ARCH.X8664 : intel.amd64,
QL_ARCH.ARM : arm.aarch32,
QL_ARCH.ARM64 : arm.aarch64,
QL_ARCH.MIPS : mips.mipso32
}[ql.archtype](ql)

self.fcall = QlFunctionCall(ql, cc)

def run(self):
if self.ql.entry_point:
self.entry_point = self.ql.entry_point

self.exit_point = self.ql.loader.load_address + len(self.ql.code)
if self.ql.exit_point:
self.exit_point = self.ql.exit_point

self.ql.emu_start(self.entry_point, self.exit_point, self.ql.timeout, self.ql.count)
20 changes: 20 additions & 0 deletions tests/profiles/uboot_bin.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[CODE]
ram_size = 0xa00000
entry_point = 0x80800000
heap_size = 0x300000


[LOG]
# log directory output
# usage: dir = qlog
dir =
# split log file, use with multithread
split = False


[MISC]
# append string into different logs
# maily for multiple times Ql run with one file
# usage: append = test1
append =
current_path = /
68 changes: 68 additions & 0 deletions tests/test_blob.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python3
#
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
#

import sys, unittest
sys.path.append("..")

from qiling.core import Qiling
from qiling.const import QL_VERBOSE
from qiling.os.const import STRING

class BlobTest(unittest.TestCase):
def test_uboot_arm(self):
def my_getenv(ql, *args, **kwargs):
env = {"ID": b"000000000000000", "ethaddr": b"11:22:33:44:55:66"}
params = ql.os.resolve_fcall_params({'key': STRING})
value = env.get(params["key"], b"")

value_addr = ql.os.heap.alloc(len(value))
ql.mem.write(value_addr, value)

ql.reg.r0 = value_addr
ql.reg.arch_pc = ql.reg.lr

def check_password(ql, *args, **kwargs):
passwd_output = ql.mem.read(ql.reg.r0, ql.reg.r2)
passwd_input = ql.mem.read(ql.reg.r1, ql.reg.r2)
self.assertEqual(passwd_output, passwd_input)

def partial_run_init(ql):
# argv prepare
ql.reg.arch_sp -= 0x30
arg0_ptr = ql.reg.arch_sp
ql.mem.write(arg0_ptr, b"kaimendaji")

ql.reg.arch_sp -= 0x10
arg1_ptr = ql.reg.arch_sp
ql.mem.write(arg1_ptr, b"013f1f")

ql.reg.arch_sp -= 0x20
argv_ptr = ql.reg.arch_sp
ql.mem.write(argv_ptr, ql.pack(arg0_ptr))
ql.mem.write(argv_ptr + ql.pointersize, ql.pack(arg1_ptr))

ql.reg.r2 = 2
ql.reg.r3 = argv_ptr

print("ARM uboot bin")

with open("../examples/rootfs/blob/u-boot.bin.img", "rb") as f:
uboot_code = f.read()

ql = Qiling(code=uboot_code[0x40:], archtype="arm", ostype="blob", profile="profiles/uboot_bin.ql", verbose=QL_VERBOSE.DEBUG)

image_base_addr = ql.loader.load_address
ql.hook_address(my_getenv, image_base_addr + 0x13AC0)
ql.hook_address(check_password, image_base_addr + 0x48634)

partial_run_init(ql)

ql.run(image_base_addr + 0x486B4, image_base_addr + 0x48718)

del ql


if __name__ == "__main__":
unittest.main()
1 change: 1 addition & 0 deletions tests/test_onlinux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ python3 ./test_qnx.py &&
python3 ./test_android.py &&
python3 ./test_mcu.py &&
python3 ./test_evm.py &&
python3 ./test_blob.py &&
echo "Done Test"