Skip to content

Commit b485fd6

Browse files
committed
tests: Add x86 and x86_64 archs
1 parent ac5d11f commit b485fd6

3 files changed

Lines changed: 69 additions & 1 deletion

File tree

shellblocks/compiler_archs/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
from enum import Enum
22
from shellblocks.compiler_archs.mips import CompilerArchMIPSBE, CompilerArchMIPSLE
33
from shellblocks.compiler_archs.arm import CompilerArchARMLE
4+
from shellblocks.compiler_archs.x86 import CompilerArchX86
5+
from shellblocks.compiler_archs.x86_64 import CompilerArchX86_64
46
from shellblocks.compiler_arch import CompilerArch
57

68

79
class CompilerArchOption(Enum):
810
MIPSBE = "mipsbe"
911
MIPSLE = "mipsle"
1012
ARMLE = "armle"
13+
X86 = "x86"
14+
X86_64 = "x86_64"
1115

1216

1317
def compiler_arch_to_object(arch: CompilerArchOption) -> CompilerArch:
@@ -17,6 +21,10 @@ def compiler_arch_to_object(arch: CompilerArchOption) -> CompilerArch:
1721
return CompilerArchMIPSLE()
1822
elif arch == CompilerArchOption.ARMLE:
1923
return CompilerArchARMLE()
24+
elif arch == CompilerArchOption.X86:
25+
return CompilerArchX86()
26+
elif arch == CompilerArchOption.X86_64:
27+
return CompilerArchX86_64()
2028

2129
raise NotImplementedError()
2230

shellblocks/test_arch_helper.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from unicorn.mips_const import UC_MIPS_REG_PC, UC_MIPS_REG_29, UC_MIPS_REG_4
22
from unicorn.arm_const import UC_ARM_REG_PC, UC_ARM_REG_SP, UC_ARM_REG_R0
3+
from unicorn.x86_const import UC_X86_REG_EIP, UC_X86_REG_ESP, UC_X86_REG_RDI
34

45
from shellblocks.compiler_archs import CompilerArchOption
56

@@ -9,6 +10,57 @@ def __init__(self, compiler_arch_option):
910
self.compiler_arch_option = compiler_arch_option
1011

1112

13+
class X86Helper(ArchHelper):
14+
def __init__(self, compiler_arch_option):
15+
super().__init__(compiler_arch_option)
16+
17+
assert compiler_arch_option in [
18+
CompilerArchOption.X86,
19+
CompilerArchOption.X86_64,
20+
]
21+
22+
self.word_size = 4
23+
24+
if CompilerArchOption.X86_64 == self.compiler_arch_option:
25+
self.word_size = 8
26+
27+
def get_jump_hook_bytes(self, jump_hook_goto):
28+
raise NotImplementedError()
29+
30+
def get_ret_bytes(self):
31+
return b"\xc3" # "ret" in x86
32+
33+
def get_curr_pc(self, mu):
34+
return mu.reg_read(UC_X86_REG_EIP)
35+
36+
def set_curr_sp(self, mu, new_stack):
37+
mu.reg_write(UC_X86_REG_ESP, new_stack)
38+
39+
def get_curr_sp(self, mu):
40+
return mu.reg_read(UC_X86_REG_ESP)
41+
42+
def get_curr_func_arg(self, mu, func_arg):
43+
if CompilerArchOption.X86_64 == self.compiler_arch_option:
44+
if func_arg == 0:
45+
return mu.reg_read(UC_X86_REG_RDI)
46+
47+
raise NotImplementedError(f"Getting {func_arg} func arg")
48+
49+
if CompilerArchOption.X86 == self.compiler_arch_option:
50+
# cdecl
51+
52+
val = mu.mem_read(
53+
(mu.reg_read(UC_X86_REG_ESP)
54+
+ (func_arg + 1) * self.word_size), self.word_size
55+
)
56+
57+
return int.from_bytes(val, 'little')
58+
59+
raise NotImplementedError(
60+
"Only x86 or x86-64 calling conventions are implemented"
61+
)
62+
63+
1264
class ARMHelper(ArchHelper):
1365
def __init__(self, compiler_arch_option):
1466
super().__init__(compiler_arch_option)

tests/conftest.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@
88
Uc,
99
UC_ARCH_MIPS,
1010
UC_ARCH_ARM,
11+
UC_ARCH_X86,
1112
UC_MODE_ARM,
1213
UC_MODE_32,
14+
UC_MODE_64,
1315
UC_MODE_BIG_ENDIAN,
1416
UC_MODE_LITTLE_ENDIAN,
1517
)
1618

1719

18-
from shellblocks.test_arch_helper import MIPSHelper, ARMHelper
20+
from shellblocks.test_arch_helper import MIPSHelper, ARMHelper, X86Helper
1921

2022
from shellblocks.compiler_archs import CompilerArchOption, compiler_arch_to_object
2123

@@ -48,6 +50,8 @@ def arch_helper(compiler_arch_option):
4850
return MIPSHelper(compiler_arch_option)
4951
if compiler_arch_option in [CompilerArchOption.ARMLE]:
5052
return ARMHelper(compiler_arch_option)
53+
if compiler_arch_option in [CompilerArchOption.X86, CompilerArchOption.X86_64]:
54+
return X86Helper(compiler_arch_option)
5155
else:
5256
raise NotImplementedError("Arch unimplemented error!")
5357

@@ -61,6 +65,10 @@ def get_mu_instance():
6165
return Uc(UC_ARCH_MIPS, UC_MODE_32 | UC_MODE_LITTLE_ENDIAN)
6266
elif CompilerArchOption.ARMLE == compiler_arch_option:
6367
return Uc(UC_ARCH_ARM, UC_MODE_ARM | UC_MODE_LITTLE_ENDIAN)
68+
elif CompilerArchOption.X86 == compiler_arch_option:
69+
return Uc(UC_ARCH_X86, UC_MODE_32)
70+
elif CompilerArchOption.X86_64 == compiler_arch_option:
71+
return Uc(UC_ARCH_X86, UC_MODE_64)
6472
else:
6573
raise NotImplementedError("Arch unimplemented error!")
6674

0 commit comments

Comments
 (0)