Created
May 18, 2020 07:23
-
-
Save SakiiR/f13392989713fef53a140e982fcafd19 to your computer and use it in GitHub Desktop.
Defcon Quals 2020 - Babymaze hook.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <time.h> | |
#include <string.h> | |
#include <dlfcn.h> | |
#include <sys/ptrace.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
# define PLAYER_BASE (0x00dc05f8) | |
# define COORD_BASE (0x00dc0588) | |
// # define COORD_BASE (0x00dc0588) | |
typedef struct s_player | |
{ | |
double pitch; | |
double yaw; | |
unsigned char key; | |
unsigned char stopped; | |
}__attribute__((packed)) t_player; | |
typedef struct s_matrix | |
{ | |
double a; | |
double b; | |
double c; | |
double d; | |
double e; | |
double f; | |
double g; | |
double h; | |
double i; | |
double j; | |
double k; | |
double l; | |
}__attribute__((packed)) t_matrix; | |
void DumpHex(const void* data, size_t size) { | |
char ascii[17]; | |
size_t i; | |
size_t j; | |
ascii[16] = '\0'; | |
for (i = 0; i < size; ++i) { | |
printf("%02X ", ((unsigned char*)data)[i]); | |
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') { | |
ascii[i % 16] = ((unsigned char*)data)[i]; | |
} else { | |
ascii[i % 16] = '.'; | |
} | |
if ((i+1) % 8 == 0 || i+1 == size) { | |
printf(" "); | |
if ((i+1) % 16 == 0) { | |
printf("| %s \n", ascii); | |
} else if (i+1 == size) { | |
ascii[(i+1) % 16] = '\0'; | |
if ((i+1) % 16 <= 8) { | |
printf(" "); | |
} | |
for (j = (i+1) % 16; j < 16; ++j) { | |
printf(" "); | |
} | |
printf("| %s \n", ascii); | |
} | |
} | |
} | |
} | |
typedef void (*GLUTSWAP)(void); | |
int read_memory(unsigned long addr, void *data, size_t size) | |
{ | |
int fd = open("/proc/self/mem", O_RDONLY); | |
lseek(fd, addr, SEEK_SET); | |
int n = read(fd, data, size); | |
close(fd); | |
return n; | |
} | |
int write_memory(unsigned long addr, void *data, size_t size) | |
{ | |
int fd = open("/proc/self/mem", O_RDONLY | O_WRONLY ); | |
lseek(fd, addr, SEEK_SET); | |
int n = write(fd, data, size); | |
close(fd); | |
return n; | |
} | |
unsigned long get_player_base() | |
{ | |
unsigned long player_base = 0; | |
read_memory(PLAYER_BASE, &player_base, sizeof(unsigned long)); | |
return player_base; | |
} | |
void change_velocity(double velocity) | |
{ | |
double b = velocity; | |
write_memory(0x00dc05d0, &b, sizeof(double)); | |
printf("Changed velocity\n"); | |
} | |
void fly() | |
{ | |
unsigned long long a = 3; | |
write_memory(0x00dc05c8, &a, sizeof(unsigned long long)); | |
printf("Let's fly !\n"); | |
} | |
void walk() | |
{ | |
unsigned long long a = 1; | |
write_memory(0x00dc05c8, &a, sizeof(unsigned long long)); | |
printf("Let's walk !"); | |
} | |
unsigned char read_char(unsigned long addr) | |
{ | |
unsigned char value = 0; | |
read_memory(addr, &value, sizeof(unsigned char)); | |
return value; | |
} | |
int write_char(unsigned long addr, unsigned char value) | |
{ | |
return write_memory(addr, &value, sizeof(value)); | |
} | |
int read_int(unsigned long addr) | |
{ | |
int value = 0; | |
read_memory(addr, &value, sizeof(int)); | |
return value; | |
} | |
int write_int(unsigned long addr, int value) | |
{ | |
return write_memory(addr, &value, sizeof(value)); | |
} | |
double read_double(unsigned long addr) | |
{ | |
double value = 0; | |
read_memory(addr, &value, sizeof(double)); | |
return value; | |
} | |
double write_double(unsigned long addr, double value) | |
{ | |
return write_memory(addr, &value, sizeof(value)); | |
} | |
void get_matrix_at(unsigned long addr, t_matrix *matrix) | |
{ | |
unsigned long base = read_int(addr); | |
read_memory(base + 22, matrix, sizeof(*matrix)); | |
} | |
int set_matrix_at(unsigned long addr, t_matrix *matrix) | |
{ | |
unsigned long base = read_int(addr); | |
return write_memory(base + 16, matrix, sizeof(*matrix)); | |
} | |
void get_player(t_player *player) | |
{ | |
unsigned long player_base = get_player_base(); | |
player->pitch = read_double(player_base + 0x10); | |
player->yaw = read_double(player_base + 0x18); | |
player->key = read_char(player_base + 8); | |
player->stopped = read_char(player_base + 10); | |
} | |
unsigned int set_player(t_player *player) | |
{ | |
unsigned long player_base = get_player_base(); | |
unsigned int n = 0; | |
n += write_double(player_base + 0x10, player->pitch); | |
n += write_double(player_base + 0x18, player->yaw); | |
n += write_char(player_base + 8, player->key); | |
n += write_char(player_base + 10, player->stopped); | |
return n; | |
} | |
void print_player(t_player *player) | |
{ | |
printf("# Player '%p'\n", player); | |
printf("Key: 0x%02x\n", player->key); | |
printf("Stopped: 0x%02x\n", player->stopped); | |
printf("Pitch: %f\n", player->pitch); | |
printf("Yaw: %f\n", player->yaw); | |
} | |
void print_matrix(t_matrix *matrix) | |
{ | |
printf("# Matrix '%p'\n", matrix); | |
printf("%f %f %f\n", matrix->a, matrix->b, matrix->c); | |
printf("%f %f %f\n", matrix->d, matrix->e, matrix->f); | |
printf("%f %f %f\n", matrix->g, matrix->h, matrix->i); | |
printf("%f %f %f\n", matrix->j, matrix->k, matrix->l); | |
} | |
void dump_at(unsigned long addr, size_t count) | |
{ | |
char *memory = malloc(count); | |
read_memory(addr, memory, count); | |
DumpHex(memory, count); | |
free(memory); | |
} | |
void write_pos(double x, double y, double z) | |
{ | |
unsigned long position = read_int(COORD_BASE); | |
write_memory(position+(22 * 8) + (8 * 0), &x, 8); | |
write_memory(position+(22 * 8) + (8 * 1), &y, 8); | |
write_memory(position+(22 * 8) + (8 * 2), &z, 8); | |
} | |
void read_pos(double *x, double *y, double *z) | |
{ | |
unsigned long position = read_int(COORD_BASE); | |
read_memory(position+(22 * 8) + (8 * 0), x, 8); | |
read_memory(position+(22 * 8) + (8 * 1), y, 8); | |
read_memory(position+(22 * 8) + (8 * 2), z, 8); | |
} | |
void glutSwapBuffers(void) | |
{ | |
static void *handle = NULL; | |
static GLUTSWAP old_swap = NULL; | |
t_player player; | |
double x, y, z; | |
t_matrix m1; | |
printf("-----------------------------------\n"); | |
get_player(&player); | |
get_matrix_at(COORD_BASE, &m1); | |
// print_matrix(&m1); | |
read_pos(&x, &y, &z); | |
printf("x = %f; y = %f; z = %f;\n", x, y, z); | |
if (player.key == 0x61) { | |
walk(); | |
} | |
if (player.key == 0x64) { | |
change_velocity(2.0); | |
fly(); | |
} | |
if (player.key == 0x66) { // f | |
x = -48.002144; y = 3.189641; z = 88.500946; | |
} | |
if (player.key == 0x76) { // v | |
x = 144.077972; y = 1.670742; z = 142.010620; | |
} | |
write_pos(x, y, z); | |
set_player(&player); | |
// Call the good old one :) | |
handle = dlopen("/usr/local/lib/libglut.so.3.9.0", RTLD_LAZY); | |
old_swap = dlsym(handle, "glutSwapBuffers"); | |
old_swap(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment