Skip to content

Commit 6e9d4be

Browse files
authored
Merge pull request #1293 from elicn/dev-maintain
Periodic maintenance PR
2 parents 05093ad + 1a731a8 commit 6e9d4be

File tree

12 files changed

+623
-331
lines changed

12 files changed

+623
-331
lines changed

examples/shellcode_run.py

Lines changed: 79 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,107 @@
11
#!/usr/bin/env python3
2-
#
2+
#
33
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
44
#
55

6-
from binascii import unhexlify
76
import sys
87

98
sys.path.append("..")
109
from qiling import Qiling
11-
from qiling.const import QL_VERBOSE
12-
13-
X86_LIN = unhexlify('31c050682f2f7368682f62696e89e3505389e1b00bcd80')
14-
X8664_LIN = unhexlify('31c048bbd19d9691d08c97ff48f7db53545f995257545eb03b0f05')
15-
MIPS32EL_LIN = unhexlify('ffff0628ffffd004ffff05280110e4270ff08424ab0f02240c0101012f62696e2f7368')
16-
X86_WIN = unhexlify('fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6a01eb2668318b6f87ffd5bbf0b5a25668a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd5e8d5ffffff63616c6300')
17-
X8664_WIN = unhexlify('fc4881e4f0ffffffe8d0000000415141505251564831d265488b52603e488b52183e488b52203e488b72503e480fb74a4a4d31c94831c0ac3c617c022c2041c1c90d4101c1e2ed5241513e488b52203e8b423c4801d03e8b80880000004885c0746f4801d0503e8b48183e448b40204901d0e35c48ffc93e418b34884801d64d31c94831c0ac41c1c90d4101c138e075f13e4c034c24084539d175d6583e448b40244901d0663e418b0c483e448b401c4901d03e418b04884801d0415841585e595a41584159415a4883ec204152ffe05841595a3e488b12e949ffffff5d49c7c1000000003e488d95fe0000003e4c8d850f0100004831c941ba45835607ffd54831c941baf0b5a256ffd548656c6c6f2c2066726f6d204d534621004d657373616765426f7800')
18-
ARM_LIN = unhexlify('01108fe211ff2fe102200121921a0f02193701df061c08a11022023701df3f270221301c01df0139fbd505a0921a05b469460b2701dfc046020012340a0002022f73797374656d2f62696e2f736800')
19-
ARM64_LIN = unhexlify('420002ca210080d2400080d2c81880d2010000d4e60300aa01020010020280d2681980d2010000d4410080d2420002cae00306aa080380d2010000d4210400f165ffff54e0000010420002ca210001caa81b80d2010000d4020004d27f0000012f62696e2f736800')
20-
X8664_FBSD = unhexlify('6a61586a025f6a015e990f054897baff02aaaa80f2ff524889e699046680c2100f05046a0f05041e4831f6990f0548976a035852488d7424f080c2100f0548b8523243427730637257488d3e48af74084831c048ffc00f055f4889d04889fe48ffceb05a0f0575f799043b48bb2f62696e2f2f73685253545f5257545e0f05')
21-
X8664_MACOS = unhexlify('4831f65648bf2f2f62696e2f7368574889e74831d24831c0b00248c1c828b03b0f05')
10+
from qiling.const import QL_ARCH, QL_OS, QL_VERBOSE
11+
12+
X86_LIN = bytes.fromhex('31c050682f2f7368682f62696e89e3505389e1b00bcd80')
13+
X8664_LIN = bytes.fromhex('31c048bbd19d9691d08c97ff48f7db53545f995257545eb03b0f05')
14+
15+
MIPS32EL_LIN = bytes.fromhex('''
16+
ffff0628ffffd004ffff05280110e4270ff08424ab0f02240c0101012f62696e
17+
2f7368
18+
''')
19+
20+
X86_WIN = bytes.fromhex('''
21+
fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c
22+
617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b5920
23+
01d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475
24+
e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ff
25+
e05f5f5a8b12eb8d5d6a01eb2668318b6f87ffd5bbf0b5a25668a695bd9dffd5
26+
3c067c0a80fbe07505bb4713726f6a0053ffd5e8d5ffffff63616c6300
27+
''')
28+
29+
X8664_WIN = bytes.fromhex('''
30+
fc4881e4f0ffffffe8d0000000415141505251564831d265488b52603e488b52
31+
183e488b52203e488b72503e480fb74a4a4d31c94831c0ac3c617c022c2041c1
32+
c90d4101c1e2ed5241513e488b52203e8b423c4801d03e8b80880000004885c0
33+
746f4801d0503e8b48183e448b40204901d0e35c48ffc93e418b34884801d64d
34+
31c94831c0ac41c1c90d4101c138e075f13e4c034c24084539d175d6583e448b
35+
40244901d0663e418b0c483e448b401c4901d03e418b04884801d0415841585e
36+
595a41584159415a4883ec204152ffe05841595a3e488b12e949ffffff5d49c7
37+
c1000000003e488d95fe0000003e4c8d850f0100004831c941ba45835607ffd5
38+
4831c941baf0b5a256ffd548656c6c6f2c2066726f6d204d534621004d657373
39+
616765426f7800
40+
''')
41+
42+
ARM_LIN = bytes.fromhex('''
43+
01108fe211ff2fe102200121921a0f02193701df061c08a11022023701df3f27
44+
0221301c01df0139fbd505a0921a05b469460b2701dfc046020012340a000202
45+
2f73797374656d2f62696e2f736800
46+
''')
47+
48+
ARM64_LIN = bytes.fromhex('''
49+
420002ca210080d2400080d2c81880d2010000d4e60300aa01020010020280d2
50+
681980d2010000d4410080d2420002cae00306aa080380d2010000d4210400f1
51+
65ffff54e0000010420002ca210001caa81b80d2010000d4020004d27f000001
52+
2f62696e2f736800
53+
''')
54+
55+
X8664_FBSD = bytes.fromhex('''
56+
6a61586a025f6a015e990f054897baff02aaaa80f2ff524889e699046680c210
57+
0f05046a0f05041e4831f6990f0548976a035852488d7424f080c2100f0548b8
58+
523243427730637257488d3e48af74084831c048ffc00f055f4889d04889fe48
59+
ffceb05a0f0575f799043b48bb2f62696e2f2f73685253545f5257545e0f05
60+
''')
61+
62+
X8664_MACOS = bytes.fromhex('''
63+
4831f65648bf2f2f62696e2f7368574889e74831d24831c0b00248c1c828b03b
64+
0f05
65+
''')
66+
2267

2368
if __name__ == "__main__":
2469
print("\nLinux ARM 64bit Shellcode")
25-
ql = Qiling(code=ARM64_LIN, archtype="arm64", ostype="linux", verbose=QL_VERBOSE.DEBUG)
70+
ql = Qiling(code=ARM64_LIN, archtype=QL_ARCH.ARM64, ostype=QL_OS.LINUX, verbose=QL_VERBOSE.DEBUG)
2671
ql.run()
2772

2873
print("\nLinux ARM 32bit Shellcode")
29-
ql = Qiling(code=ARM_LIN, archtype="arm", ostype="linux", verbose=QL_VERBOSE.DEBUG)
74+
ql = Qiling(code=ARM_LIN, archtype=QL_ARCH.ARM, ostype=QL_OS.LINUX, verbose=QL_VERBOSE.DEBUG)
3075
ql.run()
3176

32-
print("\nLinux X86 32bit Shellcode")
33-
ql = Qiling(code=X86_LIN, archtype="x86", ostype="linux", verbose=QL_VERBOSE.DEBUG)
77+
print("\nLinux x86 32bit Shellcode")
78+
ql = Qiling(code=X86_LIN, archtype=QL_ARCH.X86, ostype=QL_OS.LINUX, verbose=QL_VERBOSE.DEBUG)
3479
ql.run()
3580

3681
print("\nLinux MIPS 32bit EL Shellcode")
37-
ql = Qiling(code=MIPS32EL_LIN, archtype="mips", ostype="linux", verbose=QL_VERBOSE.DEBUG)
82+
ql = Qiling(code=MIPS32EL_LIN, archtype=QL_ARCH.MIPS, ostype=QL_OS.LINUX, verbose=QL_VERBOSE.DEBUG)
3883
ql.run()
3984

40-
print("\nLinux X86 64bit Shellcode")
41-
ql = Qiling(code=X8664_LIN, archtype="x8664", ostype="linux", verbose=QL_VERBOSE.DEBUG)
85+
print("\nLinux x86-64 Shellcode")
86+
ql = Qiling(code=X8664_LIN, archtype=QL_ARCH.X8664, ostype=QL_OS.LINUX, verbose=QL_VERBOSE.DEBUG)
4287
ql.run()
4388

44-
print("\nWindows X86 32bit Shellcode")
45-
ql = Qiling(code=X86_WIN, archtype="x86", ostype="windows", rootfs="rootfs/x86_windows")
89+
print("\nWindows x86 Shellcode")
90+
ql = Qiling(code=X86_WIN, archtype=QL_ARCH.X86, ostype=QL_OS.WINDOWS, rootfs=r'rootfs/x86_windows')
4691
ql.run()
4792

48-
print("\nWindows X8664 64bit Shellcode")
49-
ql = Qiling(code=X8664_WIN, archtype="x8664", ostype="windows", rootfs="rootfs/x8664_windows")
93+
print("\nWindows x86-64 Shellcode")
94+
ql = Qiling(code=X8664_WIN, archtype=QL_ARCH.X8664, ostype=QL_OS.WINDOWS, rootfs=r'rootfs/x8664_windows')
5095
ql.run()
5196

52-
print("\nFreeBSD X86 64bit Shellcode")
53-
ql = Qiling(code=X8664_FBSD, archtype="x8664", ostype="freebsd", verbose=QL_VERBOSE.DEBUG)
54-
ql.run()
97+
# FIXME: freebsd sockets are currently broken.
98+
#
99+
# print("\nFreeBSD x86-64 Shellcode")
100+
# ql = Qiling(code=X8664_FBSD, archtype=QL_ARCH.X8664, ostype=QL_OS.FREEBSD, verbose=QL_VERBOSE.DEBUG)
101+
# ql.run()
55102

56-
print("\nmacos X86 64bit Shellcode")
57-
ql = Qiling(code=X8664_MACOS, archtype="x8664", ostype="macos", verbose=QL_VERBOSE.DEBUG)
58-
ql.run()
103+
# FIXME: macos shellcode loader is currently broken
104+
#
105+
# print("\nMacOS x86-64 Shellcode")
106+
# ql = Qiling(code=X8664_MACOS, archtype=QL_ARCH.X8664, ostype=QL_OS.MACOS, verbose=QL_VERBOSE.DEBUG)
107+
# ql.run()

qiling/loader/elf.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env python3
2-
#
2+
#
33
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
44
#
55

@@ -26,6 +26,7 @@
2626
from qiling.os.linux.kernel_api.hook import *
2727
from qiling.os.linux.kernel_api.kernel_api import hook_sys_open, hook_sys_read, hook_sys_write
2828

29+
2930
# auxiliary vector types
3031
# see: https://man7.org/linux/man-pages/man3/getauxval.3.html
3132
class AUXV(IntEnum):
@@ -53,13 +54,15 @@ class AUXV(IntEnum):
5354
AT_HWCAP2 = 26
5455
AT_EXECFN = 31
5556

57+
5658
# start area memory for API hooking
5759
# we will reserve 0x1000 bytes for this (which contains multiple slots of 4/8 bytes, each for one api)
5860
API_HOOK_MEM = 0x1000000
5961

6062
# memory for syscall table
6163
SYSCALL_MEM = API_HOOK_MEM + 0x1000
6264

65+
6366
class QlLoaderELF(QlLoader):
6467
def __init__(self, ql: Qiling):
6568
super().__init__(ql)
@@ -77,16 +80,11 @@ def run(self):
7780

7881
return
7982

80-
section = {
81-
32 : 'OS32',
82-
64 : 'OS64'
83-
}[self.ql.arch.bits]
84-
85-
self.profile = self.ql.os.profile[section]
83+
self.profile = self.ql.os.profile[f'OS{self.ql.arch.bits}']
8684

8785
# setup program stack
88-
stack_address = int(self.profile.get('stack_address'), 0)
89-
stack_size = int(self.profile.get('stack_size'), 0)
86+
stack_address = self.profile.getint('stack_address')
87+
stack_size = self.profile.getint('stack_size')
9088
self.ql.mem.map(stack_address, stack_size, info='[stack]')
9189

9290
self.path = self.ql.path
@@ -110,7 +108,7 @@ def run(self):
110108

111109
# is it a shared object?
112110
elif elftype == 'ET_DYN':
113-
load_address = int(self.profile.get('load_address'), 0)
111+
load_address = self.profile.getint('load_address')
114112

115113
self.load_with_ld(elffile, stack_address + stack_size, load_address, self.argv, self.env)
116114

@@ -242,7 +240,7 @@ def load_elf_segments(elffile: ELFFile, load_address: int, info: str):
242240
# determine interpreter base address
243241
# some old interpreters may not be PIE: p_vaddr of the first LOAD segment is not zero
244242
# we should load interpreter at the address p_vaddr specified in such situation
245-
interp_address = int(self.profile.get('interp_address'), 0) if min_vaddr == 0 else 0
243+
interp_address = self.profile.getint('interp_address') if min_vaddr == 0 else 0
246244
self.ql.log.debug(f'Interpreter addr: {interp_address:#x}')
247245

248246
# load interpreter segments data to memory
@@ -255,7 +253,7 @@ def load_elf_segments(elffile: ELFFile, load_address: int, info: str):
255253
entry_point = interp_address + interp['e_entry']
256254

257255
# set mmap addr
258-
mmap_address = int(self.profile.get('mmap_address'), 0)
256+
mmap_address = self.profile.getint('mmap_address')
259257
self.ql.log.debug(f'mmap_address is : {mmap_address:#x}')
260258

261259
# set info to be used by gdb
@@ -658,7 +656,7 @@ def get_elfdata_mapping(self, elffile: ELFFile) -> bytes:
658656
# pick up loadable sections
659657
for sec in elffile.iter_sections():
660658
if sec['sh_flags'] & SH_FLAGS.SHF_ALLOC:
661-
# pad aggregated elf data to the offset of the current section
659+
# pad aggregated elf data to the offset of the current section
662660
elfdata_mapping.extend(b'\x00' * (sec['sh_offset'] - len(elfdata_mapping)))
663661

664662
# aggregate section data

qiling/os/linux/procfs.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99
from qiling.os.memory import QlMemoryManager
1010

1111

12+
class FsMappedStream(io.BytesIO):
13+
"""Wrap stream objects to make them look like a QlFsMappedObject.
14+
"""
15+
16+
def __init__(self, fname: str, *args) -> None:
17+
super().__init__(*args)
18+
19+
self.name = fname
20+
21+
1222
class QlProcFS:
1323

1424
@staticmethod
@@ -28,14 +38,14 @@ def self_auxv(os: 'QlOsLinux') -> QlFsMappedObject:
2838
auxv_data.extend(os.ql.mem.read(auxv_addr, nbytes))
2939
auxv_addr += nbytes
3040

31-
return io.BytesIO(bytes(auxv_data))
41+
return FsMappedStream(r'/proc/self/auxv', auxv_data)
3242

3343
@staticmethod
3444
def self_cmdline(os: 'QlOsLinux') -> QlFsMappedObject:
3545
entries = (arg.encode('utf-8') for arg in os.ql.argv)
3646
cmdline = b'\x00'.join(entries) + b'\x00'
3747

38-
return io.BytesIO(cmdline)
48+
return FsMappedStream(r'/proc/self/cmdline', cmdline)
3949

4050
@staticmethod
4151
def self_environ(os: 'QlOsLinux') -> QlFsMappedObject:
@@ -48,14 +58,14 @@ def __to_bytes(s: AnyStr) -> bytes:
4858
entries = (b'='.join((__to_bytes(k), __to_bytes(v))) for k, v in os.ql.env.items())
4959
environ = b'\x00'.join(entries) + b'\x00'
5060

51-
return io.BytesIO(environ)
61+
return FsMappedStream(r'/proc/self/environ', environ)
5262

5363
@staticmethod
5464
def self_exe(os: 'QlOsLinux') -> QlFsMappedObject:
5565
with open(os.ql.path, 'rb') as exefile:
5666
content = exefile.read()
5767

58-
return io.BytesIO(content)
68+
return FsMappedStream(r'/proc/self/exe', content)
5969

6070
@staticmethod
6171
def self_map(mem: 'QlMemoryManager') -> QlFsMappedObject:
@@ -65,4 +75,4 @@ def self_map(mem: 'QlMemoryManager') -> QlFsMappedObject:
6575
for lbound, ubound, perms, label, container in mapinfo:
6676
content += f"{lbound:x}-{ubound:x}\t{perms}p\t0\t00:00\t0\t{container if container else label}\n".encode("utf-8")
6777

68-
return io.BytesIO(bytes(content))
78+
return FsMappedStream(r'/proc/self/map', content)

qiling/os/linux/thread.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def _run(self):
239239
self.ql.log.debug(f"Scheduled from {hex(start_address)}.")
240240
try:
241241
# Known issue for timeout: https://github.com/unicorn-engine/unicorn/issues/1355
242-
self.ql.emu_start(start_address, self.exit_point, count=30000)
242+
self.ql.emu_start(start_address, self.exit_point, count=31337)
243243
except UcError as e:
244244
self.ql.os.emu_error()
245245
self.ql.log.exception("")

0 commit comments

Comments
 (0)