Skip to content

Commit c59e234

Browse files
committed
compiler_archs: Add PowerPC
1 parent 80f8bce commit c59e234

7 files changed

Lines changed: 87 additions & 1 deletion

File tree

shellblocks/compiler_arch_option.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class CompilerArchOption(Enum):
88
ARMLE = "armle"
99
X86 = "x86"
1010
X86_64 = "x86_64"
11+
POWERPCLE = "powerpcle"
1112

1213

1314
def get_current_platform():
@@ -28,5 +29,7 @@ def get_current_platform():
2829
return CompilerArchOption.ARMLE
2930
if "x86_64-" in machine:
3031
return CompilerArchOption.X86_64
32+
if "powerpc64le-" in machine:
33+
return CompilerArchOption.POWERPCLE
3134

3235
return None

shellblocks/compiler_archs/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from shellblocks.compiler_archs.arm import CompilerArchARMLE
44
from shellblocks.compiler_archs.x86 import CompilerArchX86
55
from shellblocks.compiler_archs.x86_64 import CompilerArchX86_64
6+
from shellblocks.compiler_archs.powerpc import CompilerArchPowerPC
67
from shellblocks.compiler_arch import CompilerArch
78

89

@@ -17,6 +18,8 @@ def compiler_arch_to_object(arch: CompilerArchOption) -> CompilerArch:
1718
return CompilerArchX86()
1819
elif arch == CompilerArchOption.X86_64:
1920
return CompilerArchX86_64()
21+
elif arch == CompilerArchOption.POWERPC:
22+
return CompilerArchPowerPC()
2023

2124
raise NotImplementedError()
2225

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from typing import List
2+
3+
from shellblocks.compiler_arch_option import CompilerArchOption
4+
from shellblocks.compiler_archs.gcc import CompilerArchGCC
5+
from shellblocks.utils import sources_location
6+
7+
8+
class CompilerArchPowerPC(CompilerArchGCC):
9+
def __init__(self, use_main_gcc: bool):
10+
super().__init__(use_main_gcc)
11+
12+
def get_gcc_flags(self):
13+
return super().get_gcc_flags() + [
14+
"-m32",
15+
"-mbig",
16+
]
17+
18+
def get_headers(self) -> List[str]:
19+
return ["arch/powerpc/utils.h"]
20+
21+
def get_ldscript_path(self):
22+
return (sources_location / "shellcode_ldscript.ld").as_posix()
23+
24+
def get_compiler_path(self):
25+
return "powerpc64le-linux-gnu-gcc-10"
26+
27+
def compiler_arch_option(self) -> [CompilerArchOption]:
28+
return [CompilerArchOption.POWERPCLE]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef SHELLCODE_BLOCKS_ARCH_POWERPC_UTILS_H
2+
#define SHELLCODE_BLOCKS_ARCH_POWERPC_UTILS_H
3+
4+
#define NOP_OPCODE (0x60000000)
5+
6+
#define GET_REL_ADDRESS(OUTPUT, LABEL) \
7+
__asm__ volatile ( \
8+
"bl " GET_REL_LABEL(LABEL) "\n\t" \
9+
"nop\n\t" \
10+
GET_REL_LABEL(LABEL) ": mr %0, 8\n\t" \
11+
"addis %0, %0, (" #LABEL " - " GET_REL_LABEL(LABEL) ")\n\t" \
12+
: "=r" (OUTPUT) : : "8" \
13+
)
14+
15+
#endif // !SHELLCODE_BLOCKS_ARCH_POWERPC_UTILS_H

shellblocks/src/arch/utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "x86/utils.h"
88
#elif defined(__arm__)
99
#include "arm/utils.h"
10+
#elif defined(__powerpc__)
11+
#include "powerpc/utils.h"
1012
#endif
1113

1214
#define REL_ACCESS_STRING __attribute__((section(".text")))

shellblocks/test_arch_helper.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
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
33
from unicorn.x86_const import UC_X86_REG_EIP, UC_X86_REG_ESP, UC_X86_REG_RDI
4+
from unicorn.ppc_const import UC_PPC_REG_PC, UC_PPC_REG_1, UC_PPC_REG_3
45

56
from shellblocks.compiler_archs import CompilerArchOption
67

@@ -58,6 +59,34 @@ def get_curr_func_arg(self, mu, func_arg):
5859
)
5960

6061

62+
class PowerPCHelper(ArchHelper):
63+
def __init__(self, compiler_arch_option):
64+
super().__init__(compiler_arch_option)
65+
66+
assert compiler_arch_option in [
67+
CompilerArchOption.POWERPC,
68+
]
69+
70+
def get_ret_bytes(self):
71+
val = 0x4E800020
72+
return val.to_bytes(4, 'little')
73+
74+
def get_curr_pc(self, mu):
75+
return mu.reg_read(UC_PPC_REG_PC)
76+
77+
def set_curr_sp(self, mu, new_stack):
78+
mu.reg_write(UC_PPC_REG_1, new_stack)
79+
80+
def get_curr_sp(self, mu):
81+
return mu.reg_read(UC_PPC_REG_1)
82+
83+
def get_curr_func_arg(self, mu, func_arg):
84+
if func_arg == 0:
85+
return mu.reg_read(UC_PPC_REG_3)
86+
87+
raise NotImplementedError(f"Getting {func_arg} func arg")
88+
89+
6190
class ARMHelper(ArchHelper):
6291
def __init__(self, compiler_arch_option):
6392
super().__init__(compiler_arch_option)

tests/conftest.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@
1010
UC_ARCH_ARM,
1111
UC_ARCH_X86,
1212
UC_MODE_ARM,
13+
UC_ARCH_PPC,
1314
UC_MODE_32,
1415
UC_MODE_64,
1516
UC_MODE_BIG_ENDIAN,
1617
UC_MODE_LITTLE_ENDIAN,
18+
UC_MODE_PPC32,
1719
)
1820

1921

20-
from shellblocks.test_arch_helper import MIPSHelper, ARMHelper, X86Helper
22+
from shellblocks.test_arch_helper import MIPSHelper, ARMHelper, X86Helper, PowerPCHelper
2123

2224
from shellblocks.compiler_archs import CompilerArchOption, compiler_arch_to_object
2325

@@ -52,6 +54,8 @@ def arch_helper(compiler_arch_option):
5254
return ARMHelper(compiler_arch_option)
5355
if compiler_arch_option in [CompilerArchOption.X86, CompilerArchOption.X86_64]:
5456
return X86Helper(compiler_arch_option)
57+
if compiler_arch_option in [CompilerArchOption.POWERPC]:
58+
return PowerPCHelper(compiler_arch_option)
5559
else:
5660
raise NotImplementedError("Arch unimplemented error!")
5761

@@ -69,6 +73,8 @@ def get_mu_instance():
6973
return Uc(UC_ARCH_X86, UC_MODE_32)
7074
elif CompilerArchOption.X86_64 == compiler_arch_option:
7175
return Uc(UC_ARCH_X86, UC_MODE_64)
76+
elif CompilerArchOption.POWERPC == compiler_arch_option:
77+
return Uc(UC_ARCH_PPC, UC_MODE_PPC32 | UC_MODE_BIG_ENDIAN)
7278
else:
7379
raise NotImplementedError("Arch unimplemented error!")
7480

0 commit comments

Comments
 (0)