Created
January 1, 2015 15:54
-
-
Save hhc0null/756952caad7e7fd19ac0 to your computer and use it in GitHub Desktop.
a dirty decompiled code of ezhp(Plaid CTF 2014 Pwnbale 200pts)
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
/* I might me making some mistakes... */ | |
#define NONUSE 0xfffffffe | |
#define INUSE 1 | |
typedef struct _chunk { | |
int size; | |
chunk_t *next; | |
chunk_t *back; | |
} chunk_t; | |
chunk_t *chained_chunks; | |
char *note_list; | |
int current_note_num; | |
// don't be called.. | |
void initialize() | |
{ | |
int limit_content_size; // -0x10(%ebp) | |
chunk_t *loc_0ch; // -0xc(%ebp) | |
limit_content_size = 1048; | |
chained_chunks = sbrk(limit_content_size); | |
chained_chunks->back = NULL; | |
chained_chunks->next = chained_chunks->back; | |
chained_chunks->size = 12; | |
loc_0ch = chained_chunks+12; | |
chained_chunks->next = loc_0ch; | |
loc_0ch->back = chained_chunks; | |
loc_0ch->next = NULL; | |
loc_0ch->size = 1024; | |
} | |
// heap allocator | |
chunk_t *chunk_allocate(int expectation) | |
{ | |
chunk_t *new_chunk;// -0x20(%ebp) | |
chunk_t *chunk_end;// -0x1c(%ebp) | |
chunk_t *limit_size;// -0x18(%ebp) | |
chunk_t *dangling_chunk;// -0x14(%ebp) | |
chunk_t *afternext_chunk;// -0x10(%ebp) | |
chunk_t *next_chunk;// -0xc(%ebp) | |
expectation += 12; | |
expectation = CORDINATE(expectation); // ??? | |
// search non-using chaind_chunks | |
for(new_chunk = chained_chunks; new_chunk != NULL && new_chunk->size < expectation || new_chunk->size & 1; new_chunk = new_chunk->next); | |
if(new_chunk == NULL) { | |
limit_size = 1036; | |
if(expectation < limit_size) { | |
expectation = limit_size; | |
} | |
new_chunk = sbrk(expectation); | |
new_chunk->next = NULL; | |
new_chunk->size = expectation; | |
// add to list | |
for(chunk_end = chained_chunks; chunk_end->next != NULL; chunk_end = chunk_end->next); | |
chunk_end->next = new_chunk; | |
new_chunk->back = chunk_end; | |
new_chunk->size |= IN_USE; | |
} else { | |
if(expectation+48 < new_chunk->size) { | |
dangling_chunk = new_chunk->back; // XXX: kininaru | |
afternext_chunk = new_chunk->next; | |
next_chunk = new_chunk+expectation; | |
next_chunk->back = new_chunk; | |
next_chunk->next = afternext_chunk; | |
next_chunk->size = new_chunk->size - expectation; | |
if(afternext_chunk != NULL) { | |
afternext_chunk->back = next_chunk; | |
} | |
new_chunk->next = next_chunk; | |
new_chunk->size = expectation; | |
new_chunk->size |= IN_USE; | |
} else { | |
new_chunk->size |= IN_USE; | |
} | |
} | |
return new_chunk+12; | |
} | |
void remove_chunk(chunk_t *target) | |
{ | |
chunk_t *delete_chunk; | |
chunk_t *prev_chunk; | |
chunk_t *next_chunk; | |
if(target != NULL) { | |
delete_chunk = target+12; | |
prev_chunk = delete_chunk->back; | |
next_chunk = delete_chunk->next; | |
if(prev_chunk != NULL) { | |
prev_chunk->next = next_chunk; | |
} | |
if(next_chunk != NULL) { | |
next_chunk->back = prev_chunk; | |
} | |
delete_chunk->next = chained_chunks->next; | |
if(chained_chunks->next != NULL) { | |
chained_chunks->next->back = delete_chunk; | |
} | |
chained_chunks->next = delete_chunk; | |
delete_chunk->size &= NON_USE; | |
} | |
} | |
// 1 add note | |
void add_note() | |
{ | |
int expectation; | |
chunk_t *new_note; | |
if(current_note_num > 1022) { | |
puts("The emperor says there are too many notes!"); | |
fflush(stdout); | |
} else { | |
puts("Please give me a size."); | |
fflush(stdout); | |
scanf("%d%*c", &expectation); | |
new_note = chunk_allocate(expectation); | |
note_list[current_note_num] = new_note; | |
current_note_num++; | |
} | |
} | |
// 2: remove note | |
void remove_note() | |
{ | |
int id; | |
puts("Please give me an id."); | |
fflush(stdout); | |
scanf("%d%*c", &id); | |
if(0 <= id && id <= current_note_num) { | |
if(note_list[id] != NULL) { | |
remove_chunk(note_list[id]); | |
} | |
note_list[id] == NULL; | |
} | |
} | |
// 3: change a note | |
void change_note() | |
{ | |
int id; | |
int size; | |
puts("Please give me an id."); | |
fflush(stdout); | |
scanf("%d%*c", &id); | |
if(0 <= id && id <= current_note_num) { | |
if(note_list[id] != NULL) { | |
puts("Please give me a size."); | |
fflush(stdout); | |
scanf("%d%*c", &size); | |
puts("Please input your data."); | |
fflush(stdout); | |
read(STDIN_FILENO, note_list[id], size); | |
} | |
} | |
} | |
// 4: print a note | |
void print_note() | |
{ | |
int id; // -0xc(%ebp) | |
puts("Please give me an id."); | |
fflush(stdout); | |
scanf("%d%*c", &id); | |
if(0 <= id && id <= current_note_num) { | |
puts(note_list[id]); | |
} | |
} | |
int select_option() | |
{ | |
int option; | |
puts("Please choose an option."); | |
fflush(stdout); | |
scanf("%d%*c", &option); | |
return option; | |
} | |
void controll_menu() | |
{ | |
puts("Please enter one of the following:"); | |
puts("1 to add a note."); | |
puts("2 to remove a note."); | |
puts("3 to change a note."); | |
puts("4 to print a note."); | |
puts("5 to quit."); | |
fflush(stdout); | |
} | |
int main() | |
{ | |
int i; | |
int option = 0; | |
while(option != 5) { | |
controll_menu(); | |
option = select_option(); | |
if(option > 5) { | |
switch(option) { | |
case 0: | |
exit(EXIT_SUCCESS); | |
case 1: | |
add_note(); | |
break; | |
case 2: | |
remove_note(); | |
break; | |
case 3: | |
change_note(); | |
break; | |
case 4: | |
print_note(); | |
break; | |
case 5: | |
} | |
continue; | |
} | |
exit(EXIT_SUCCESS); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment