Add more registers to ISA, required for exploit.

This commit is contained in:
Johannes Maier
2024-01-16 09:12:57 +01:00
parent ab724721c0
commit f244d69127
2 changed files with 34 additions and 17 deletions

View File

@@ -21,6 +21,12 @@ class Register(IntEnum):
F = 5 F = 5
G = 6 G = 6
H = 7 H = 7
I = 8
J = 9
K = 10
L = 11
M = 12
N = 13
INSTR_LEN = 8 INSTR_LEN = 8

45
vuln.c
View File

@@ -11,7 +11,23 @@
typedef enum Opcode { ADD = 0, ADDI = 1, SUB = 2, COPY = 3, LOADI = 4, COUNT_OPCODES } Opcode; typedef enum Opcode { ADD = 0, ADDI = 1, SUB = 2, COPY = 3, LOADI = 4, COUNT_OPCODES } Opcode;
typedef enum Register { Adelheid = 0, Berthold = 1, Cornelia = 2, Dora = 3, Engelbert = 4, Friedrich = 5, Giesela = 6, Heinrich = 7, COUNT_REGISTERS } Register; typedef enum Register {
Adelheid = 0,
Berthold = 1,
Cornelia = 2,
Dora = 3,
Engelbert = 4,
Friedrich = 5,
Giesela = 6,
Heinrich = 7,
I = 8,
J = 9,
K = 10,
L = 11,
M = 12,
N = 13,
COUNT_REGISTERS
} Register;
typedef struct Instruction { typedef struct Instruction {
Opcode opcode; Opcode opcode;
@@ -37,11 +53,17 @@ static uint8_t register_id_lookup[COUNT_REGISTERS] = {
0b0111, // F to rdi 0b0111, // F to rdi
0b1000, // G to r8 0b1000, // G to r8
0b1001, // H to r9 0b1001, // H to r9
0b1010, // I to r10
0b1011, // J to r11
0b1100, // K to r12
0b1101, // L to r13
0b1110, // M to r14
0b1111, // N to r15
}; };
#define EXTRACT_REX_BIT(x) ((x >> 3) & 1) #define EXTRACT_REX_BIT(x) ((x >> 3) & 1)
size_t get_size_t(size_t limit) { size_t get_size_t(size_t min, size_t limit) {
size_t val; size_t val;
char buf[0x10] = {0}; char buf[0x10] = {0};
char *end_ptr; char *end_ptr;
@@ -56,7 +78,7 @@ size_t get_size_t(size_t limit) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (val <= limit) if (val <= limit && val >= min)
break; break;
puts("Nah, that's too long. Let's try again."); puts("Nah, that's too long. Let's try again.");
@@ -66,7 +88,7 @@ size_t get_size_t(size_t limit) {
Instruction *get_program(size_t *program_len) { Instruction *get_program(size_t *program_len) {
printf("Now to your next program: How long should it bee?"); printf("Now to your next program: How long should it bee?");
size_t len = get_size_t(MAX_PROGRAM_LEN); size_t len = get_size_t(1, MAX_PROGRAM_LEN);
Instruction *program = malloc(len * sizeof(Instruction)); Instruction *program = malloc(len * sizeof(Instruction));
@@ -115,14 +137,6 @@ void exec_code(uint8_t *code) {
_exit(res); _exit(res);
} }
void write_instr(uint8_t *code, size_t *offset, const uint8_t *instr, size_t instr_len) {
for (size_t i = 0; i < instr_len; ++i) {
code[*offset + i] = instr[i];
}
*offset += instr_len;
}
void gen_3B_native_instr(uint8_t opcode, uint8_t reg1_id, uint8_t reg2_id, uint8_t *code, size_t *offset) { void gen_3B_native_instr(uint8_t opcode, uint8_t reg1_id, uint8_t reg2_id, uint8_t *code, size_t *offset) {
// REW.X prefix (we use 64bit registers) + upper bit of the second register id + upper bit of the first register id // REW.X prefix (we use 64bit registers) + upper bit of the second register id + upper bit of the first register id
code[*offset] = 0b01001000 + (EXTRACT_REX_BIT(reg2_id) << 2) + EXTRACT_REX_BIT(reg1_id); code[*offset] = 0b01001000 + (EXTRACT_REX_BIT(reg2_id) << 2) + EXTRACT_REX_BIT(reg1_id);
@@ -208,14 +222,11 @@ void gen_code(uint8_t *code, Instruction *program, size_t program_len) {
} }
uint8_t run_jit(Instruction *program, size_t len) { uint8_t run_jit(Instruction *program, size_t len) {
// an instruction takes up at most 7B + prolog + epilog // an instruction takes up to 7B + prolog + epilog
size_t expected_code_len = 7 * len + 3 * COUNT_REGISTERS + 4; size_t expected_code_len = 7 * len + 3 * COUNT_REGISTERS + 4;
// page alignment // page alignment
size_t allocated_code_len = (expected_code_len + 0xFFF) & ~0xFFF; size_t allocated_code_len = (expected_code_len + 0xFFF) & ~0xFFF;
// TODO: remove this!!
printf("Allocating %ld B for your code!\n", allocated_code_len);
// TODO: maybe randomly choose address to make exploitation harder // TODO: maybe randomly choose address to make exploitation harder
// allocate memory for context and code // allocate memory for context and code
uint8_t *code = (uint8_t *)mmap(NULL, allocated_code_len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); uint8_t *code = (uint8_t *)mmap(NULL, allocated_code_len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
@@ -270,7 +281,7 @@ uint8_t run_jit(Instruction *program, size_t len) {
int main() { int main() {
// TODO: signal handlers? SIGCHILD? seccomp? // TODO: signal handlers? SIGCHILD? seccomp?
// TODO: colors in message, just so that every is pissed :D // TODO: colors in message, just so that everyone is pissed :D
setbuf(stdout, NULL); setbuf(stdout, NULL);
setbuf(stdin, NULL); setbuf(stdin, NULL);