Skip to content

Commit 7e746aa

Browse files
committed
compiler_archs: Add PowerPC
1 parent a3dcec3 commit 7e746aa

6 files changed

Lines changed: 83 additions & 1 deletion

File tree

shellblocks/compiler_archs/__init__.py

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

910

@@ -13,6 +14,7 @@ class CompilerArchOption(Enum):
1314
ARMLE = "armle"
1415
X86 = "x86"
1516
X86_64 = "x86_64"
17+
POWERPC = "powerpc"
1618

1719

1820
def get_current_platform():
@@ -33,6 +35,8 @@ def get_current_platform():
3335
return CompilerArchOption.ARMLE
3436
if "x86_64-" in machine:
3537
return CompilerArchOption.X86_64
38+
if "powerpc64le-" in machine:
39+
return CompilerArchOption.POWERPC
3640

3741
return None
3842

@@ -51,6 +55,8 @@ def compiler_arch_to_object(arch: CompilerArchOption) -> CompilerArch:
5155
return CompilerArchX86(CompilerArchOption.X86_64 == current_platform)
5256
elif arch == CompilerArchOption.X86_64:
5357
return CompilerArchX86_64(use_main_gcc)
58+
elif arch == CompilerArchOption.POWERPC:
59+
return CompilerArchPowerPC(use_main_gcc)
5460

5561
raise NotImplementedError()
5662

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from typing import List
2+
3+
from shellblocks.compiler_archs.gcc import CompilerArchGCC
4+
from shellblocks.utils import sources_location
5+
6+
7+
class CompilerArchPowerPC(CompilerArchGCC):
8+
def __init__(self, use_main_gcc: bool):
9+
super().__init__(use_main_gcc)
10+
11+
def get_gcc_flags(self):
12+
return super().get_gcc_flags() + [
13+
"-m32",
14+
"-mbig",
15+
]
16+
17+
def get_headers(self) -> List[str]:
18+
return ["arch/powerpc/utils.h"]
19+
20+
def get_ldscript_path(self):
21+
return (sources_location / "shellcode_ldscript.ld").as_posix()
22+
23+
def get_compiler_path(self):
24+
return "powerpc64le-linux-gnu-gcc-10"
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)