Add more registers to ISA, required for exploit.
This commit is contained in:
@@ -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
45
vuln.c
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user