Skip to content

Commit 80f8bce

Browse files
authored
Merge pull request #23 from shaymargolis/make-base-address-optional
shellcode_step: Make base_address optional
2 parents c26012d + 5af6d53 commit 80f8bce

9 files changed

Lines changed: 72 additions & 25 deletions

File tree

README.md

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,52 @@
44

55
## What is this repo?
66

7-
This repo allows you to concatenate shellcodes, running from different address spaces and links between them.
8-
Each shellcode will ensure the next will run, and will constitute from various primitives.
7+
Allows you to write PIC and fast shellcodes in C! keeping your logic simple, easy to expand, test and maintain.
8+
Shellcodes are seperated to "primitives", each one provides a behavior, and to create a full grown shellcode you can concatenate multiple primitives, or to create one primtives doing all of your logic.
99

10-
For starters, we will only support MIPS (le/be).
10+
Supported architectures:
11+
12+
- X86 and X64
13+
- Mips (LE and BE)
14+
- Arm 32bit
15+
16+
Adding another architecture is very simple!
17+
18+
## What does this mean?
19+
20+
For example, see our implementation of goto:
21+
22+
```c
23+
void start(void) {
24+
void (*goto_address)() = (void (*)())(GOTO_ADDRESS);
25+
26+
goto_address();
27+
}
28+
```
29+
30+
Our implementation of memcpy:
31+
32+
```c
33+
void __attribute__((noreturn)) start(void) {
34+
u8 *src = (u8 *)MEMCPY_SOURCE_ADDRESS;
35+
u8 *dst = (u8 *)MEMCPY_DEST_ADDRESS;
36+
u32 len = (u32)MEMCPY_LEN;
37+
38+
u8 *end = src + len;
39+
40+
while (src < end - 1) {
41+
*dst = *src;
42+
src++;
43+
dst++;
44+
}
45+
46+
*dst = *src;
47+
48+
__builtin_unreachable();
49+
}
50+
```
51+
52+
Super easy and to write even more complex code!
1153

1254
## Shellcode primitives
1355

@@ -23,7 +65,6 @@ A final "Shellcode Structure" example:
2365
```python
2466
first_step = ShellcodeStep(
2567
"first_step",
26-
0xbfc00000,
2768
[
2869
ShellcodePrimitiveMemcpy("copy_next_stage", 0x80abcdef, 0x8f0ed0b0, 0x100),
2970
ShellcodePrimitivePrint("print_debug", 0x80901234, "This is a print!\n"),

shellblocks/primitives/jump_hook.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ def __init__(self, nickname: str, hook_address: int, goto_address: int):
2424
def generate(self, path: Path, compiler: CompilerArch):
2525
step = ShellcodeStep(
2626
self.nickname,
27-
0x0, # This should be PIC
2827
[
2928
ShellcodePrimitiveGoto(
3029
self.nickname,
3130
self.goto_address
3231
),
3332
],
34-
0x1000
33+
0x1000,
34+
base_address=0x0, # This should be PIC
3535
)
3636

3737
out_file = step.generate(path / self.nickname / "goto_temp", compiler)

shellblocks/shellcode_step.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@
88

99

1010
class ShellcodeStep:
11-
def __init__(self, nickname: str, base_address: int, primitives: [ShellcodePrimitive], max_len: int):
11+
def __init__(
12+
self,
13+
nickname: str,
14+
primitives: [ShellcodePrimitive],
15+
max_len: int,
16+
base_address: int = 0
17+
):
1218
self.nickname = nickname
1319
self.base_address = base_address
1420
self.primitives = primitives

tests/test_goto.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ def test_goto_sanity(get_mu, temp_dir_path, arch_helper, compiler_arch, goto_pag
2424

2525
step = ShellcodeStep(
2626
"first_step",
27-
shellcode_address,
2827
[
2928
ShellcodePrimitiveGoto("copy_next_stage", goto_address),
3029
],
31-
0x1000
30+
0x1000,
31+
base_address=shellcode_address,
3232
)
3333

3434
out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
@@ -64,11 +64,11 @@ def test_goto_is_pic(get_mu, temp_dir_path, arch_helper, compiler_arch, shellcod
6464

6565
step = ShellcodeStep(
6666
"first_step",
67-
shellcode_address,
6867
[
6968
ShellcodePrimitiveGoto("copy_next_stage", goto_address),
7069
],
71-
0x1000
70+
0x1000,
71+
base_address=shellcode_address,
7272
)
7373

7474
out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)

tests/test_jump_hook.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ def generate_memset_to_goto(temp_dir_path,
2121

2222
step = ShellcodeStep(
2323
"first_step",
24-
shellcode_address,
2524
[
2625
expected_goto_primitive,
2726
],
28-
0x1000
27+
0x1000,
28+
base_address=shellcode_address,
2929
)
3030

3131
out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
@@ -39,11 +39,11 @@ def generate_memset_to_goto(temp_dir_path,
3939

4040
step = ShellcodeStep(
4141
"first_step",
42-
shellcode_address,
4342
[
4443
expected_memset_primitive,
4544
],
46-
0x1000
45+
0x1000,
46+
base_address=shellcode_address,
4747
)
4848

4949
out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
@@ -95,11 +95,11 @@ def test_jump_hook_sanity(
9595

9696
step = ShellcodeStep(
9797
"first_step",
98-
shellcode_address,
9998
[
10099
jump_hook_pritimive,
101100
],
102-
0x1000
101+
0x1000,
102+
base_address=shellcode_address
103103
)
104104

105105
out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)

tests/test_memcpy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ def memcpy_get_shellcode(temp_dir_path, compiler_arch, memcpy_helper, copy_len):
4545

4646
step = ShellcodeStep(
4747
"first_step",
48-
helper.shellcode_address,
4948
[
5049
ShellcodePrimitiveMemcpy(
5150
"copy_next_stage",
@@ -54,7 +53,8 @@ def memcpy_get_shellcode(temp_dir_path, compiler_arch, memcpy_helper, copy_len):
5453
copy_len
5554
),
5655
],
57-
0x1000
56+
0x1000,
57+
base_address=helper.shellcode_address,
5858
)
5959

6060
out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)

tests/test_memset.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ def memset_get_shellcode(temp_dir_path, compiler_arch, memset_helper, copy_bytes
5353

5454
step = ShellcodeStep(
5555
"first_step",
56-
helper.shellcode_address,
5756
[
5857
ShellcodePrimitiveMemset(
5958
"copy_next_stage",
6059
helper.copy_addr,
6160
copy_bytes
6261
),
6362
],
64-
0x1000 * len(copy_bytes)
63+
0x1000 * len(copy_bytes),
64+
base_address=helper.shellcode_address
6565
)
6666

6767
out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)

tests/test_print.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ def print_shellcode(compiler_arch, temp_dir_path, print_function_addr, string_to
4444

4545
step = ShellcodeStep(
4646
"first_step",
47-
shellcode_address,
4847
[
4948
ShellcodePrimitivePrint("print_stuff", print_function_addr, string_to_print),
5049
],
51-
0x1000
50+
0x1000,
51+
base_address=shellcode_address,
5252
)
5353

5454
out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)

tests/test_step.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
def test_step_too_large_fails(temp_dir_path):
88
step = ShellcodeStep(
99
"first_step",
10-
0x1000,
1110
[
1211
ShellcodePrimitiveMemcpy(
1312
f"copy_next_stage{i}",
@@ -17,7 +16,8 @@ def test_step_too_large_fails(temp_dir_path):
1716
)
1817
for i in range(6)
1918
],
20-
0x10
19+
0x10,
20+
base_address=0x1000,
2121
)
2222

2323
with pytest.raises(Exception):

0 commit comments

Comments
 (0)