Last active
December 3, 2015 20:30
-
-
Save mniip/233195c59c6aeede3c5c to your computer and use it in GitHub Desktop.
This file contains 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 <stdint.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <sys/mman.h> | |
char var_1; | |
char var_2; | |
asm ( | |
".section .text\n" | |
"aentry:\n" | |
#ifdef __amd64__ | |
"movl $var_2, (%rdi)\n" | |
#else | |
"movl 4(%esp), %eax\n" | |
"movl $var_2, (%eax)\n" | |
#endif | |
"aentry_end:\n" | |
"aexit:\n" | |
"movb $1, %al\n" | |
"aexit_key:\n" | |
"movb %al, var_1\n" | |
"ret\n" | |
"aexit_end:\n" | |
); | |
extern char aentry; | |
extern char aentry_end; | |
extern char aexit; | |
extern char aexit_key; | |
extern char aexit_end; | |
void *base = (void*)0x80000000LL; | |
size_t page = 4096; | |
int main() | |
{ | |
size_t write_offset = -1; | |
size_t i; | |
for(i = 0; i < &aexit_end - &aexit; i++) | |
if(*(unsigned int *)(i + (void *)&aexit) == (uint32_t)(intptr_t)&var_1) | |
{ | |
printf("Found pointer at offset 0x%x\n", (unsigned int)i); | |
write_offset = i; | |
break; | |
} | |
if(write_offset == -1) { printf("Couldn't find pointer\n"); return 1; } | |
const char *name = "test " __DATE__ " " __TIME__; | |
int desc = open(name, O_RDWR | O_CREAT, 0777); | |
if(desc == -1) { perror("open"); return 1; } | |
if(unlink(name) == -1) { perror("unlink"); return 1; } | |
if(ftruncate(desc, 4096) == -1) { perror("ftruncate"); return 1; } | |
void *block1 = mmap(base, page, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_SHARED | MAP_FIXED, desc, 0); | |
if(block1 == (void *)-1LL) { perror("mmap[1]"); return 1; } | |
void *block2 = mmap(base + page, page, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_SHARED | MAP_FIXED, desc, 0); | |
if(block2 == (void *)-1LL) { perror("mmap[2]"); return 1; } | |
printf("block[1]: %p, block[2]: %p\n", block1, block2); | |
size_t min_aentry_offset = &aexit_end - &aexit - 1; | |
size_t max_aentry_offset = page - (&aentry_end - &aentry) - (&aexit_key - &aexit) + 1; | |
size_t aexit_offset = page - (&aexit_key - &aexit); | |
while(max_aentry_offset - min_aentry_offset > 1) | |
{ | |
size_t aentry_offset = (min_aentry_offset + max_aentry_offset) / 2; | |
printf("Trying distance of %d bytes: ", (unsigned int)(aexit_offset - aentry_offset - (&aentry_end - &aentry) + (&aexit_key - &aexit))); | |
fflush(stdout); | |
memset(base, 0x90, page); | |
memcpy(base + aentry_offset, &aentry, &aentry_end - &aentry); | |
memcpy(base + aexit_offset, &aexit, &aexit_end - &aexit); | |
var_1 = 0; | |
var_2 = 0; | |
((void (*)(void *))(base + aentry_offset))(base + (aexit_offset + write_offset) - page); | |
if(var_1 && !var_2) | |
{ | |
max_aentry_offset = aentry_offset; | |
printf("instruction cached\n"); | |
} | |
else if(!var_1 && var_2) | |
{ | |
min_aentry_offset = aentry_offset; | |
printf("instruction updated\n"); | |
} | |
else | |
{ | |
printf("confused, var[1]: %d, var[2]: %d\n", var_1, var_2); | |
return 1; | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment