diff options
Diffstat (limited to '3/10_control_and_data')
| -rw-r--r-- | 3/10_control_and_data/00_prog.c | 0 | ||||
| -rw-r--r-- | 3/10_control_and_data/01_echo.c | 24 | ||||
| -rw-r--r-- | 3/10_control_and_data/46_get_line.c | 31 | ||||
| -rw-r--r-- | 3/10_control_and_data/47_address_range.c | 10 | ||||
| -rw-r--r-- | 3/10_control_and_data/48_stack_protection.c | 52 | ||||
| -rw-r--r-- | 3/10_control_and_data/49_variable_stack.c | 81 |
6 files changed, 198 insertions, 0 deletions
diff --git a/3/10_control_and_data/00_prog.c b/3/10_control_and_data/00_prog.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/3/10_control_and_data/00_prog.c diff --git a/3/10_control_and_data/01_echo.c b/3/10_control_and_data/01_echo.c new file mode 100644 index 0000000..8ef71e2 --- /dev/null +++ b/3/10_control_and_data/01_echo.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +char* gets(char *s) { + int c; + char *dest = s; + while ((c = getchar()) != '\n' && c != EOF) { + *dest++ = c; + } + if ( c == EOF && dest == s) { + return NULL; + } + *dest++ = '\0'; + return s; +} + +void echo() { + char buf[8]; + gets(buf); + puts(buf); +} + +int main(void) { + echo(); +} diff --git a/3/10_control_and_data/46_get_line.c b/3/10_control_and_data/46_get_line.c new file mode 100644 index 0000000..f1920e8 --- /dev/null +++ b/3/10_control_and_data/46_get_line.c @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +// char *get_line() +// 400720: 53 push %rbx +// 400721: 48 83 ec 10 sub $0x10,%rsp +// 400725: 48 89 e7 mov %rsp,%rdi +// 400728 e8 73 ff ff ff callq 4006a0 <gets> +char *get_line() { + char buf[4]; + char *result; + gets(buf); + result = malloc(strlen(buf)); + strcpy(result, buf); + return result; +} +int main(void) { + printf("%s\n", get_line()); +} +// A. B. (I mistakingly thought $0x10 was the same as $10...) +// 00 34 33 32 31 30 39 38 return address +// 37 36 35 34 33 32 31 30 callee saved %rbx +// 39 38 37 36 35 34 33 32< sub $rsp - 8 +// 31 30 00 00 00 00 00 40 sub $rsp -16 +// 07 32< return address gets +// +// C. 00 34 33 32 31 30 39 38 +// D. %rbx +// E. Malloc should consider the terminating null (strlen+1) and check for NULL pointer result diff --git a/3/10_control_and_data/47_address_range.c b/3/10_control_and_data/47_address_range.c new file mode 100644 index 0000000..57a3fcb --- /dev/null +++ b/3/10_control_and_data/47_address_range.c @@ -0,0 +1,10 @@ +// +// A. Using bc +// +ibase=16; FFFFB754 +ibase=16; FFFFD754 - FFFFB754 +8192 +2^13 +// B. +2^5 +32 diff --git a/3/10_control_and_data/48_stack_protection.c b/3/10_control_and_data/48_stack_protection.c new file mode 100644 index 0000000..08cb4e8 --- /dev/null +++ b/3/10_control_and_data/48_stack_protection.c @@ -0,0 +1,52 @@ +int len(char *s) { + return strlen(s); +} + +void iptoa(char *s, long *p) { + long val = *p; + sprintf(s, "%ld", val); +} + +// int inlen(long x) +// x in %rdi +// without canary +// +// intlen: +// subq $40, %rsp allocate 5*8 bytes +// movq %rdi, 24(%rsp) put x on the stack +// leaq 24(%rsp), %rsi set &v = &x to the second argument +// movq %rsp, %rdi set buf[12] to %rsp +// call iptoa +// +// 0<rsp+32 <-? +// 0<rsp+24 <-v +// 0<rsp+16 <-? +// 0<rsp+8 <-buf[12] +// 0<rsp <-buf[12] +// +// with canary +// +// intlen: +// subq $56, %rsp +// movq %fs:40, %rax +// movq %rax, 40(%rsp) +// xorl %eax, %eax +// movq %rdi, 8(%rsp) +// leaq 8(%rsp), %rsi +// leaq 16(%rsp), %rdi +// call iptoa +// +// 0<rsp+48 <- +// 0<rsp+40 <-canary +// 0<rsp+32 <- +// 0<rsp+24 <- +// 0<rsp+16 <-buf[12] +// 0<rsp+8 <-v +// 0<rsp <- +int intlen(long x) { + long v; + char buf[12]; + v = x; + iptoa(buf, &v); + return len(buf); +} diff --git a/3/10_control_and_data/49_variable_stack.c b/3/10_control_and_data/49_variable_stack.c new file mode 100644 index 0000000..d72c235 --- /dev/null +++ b/3/10_control_and_data/49_variable_stack.c @@ -0,0 +1,81 @@ +// A. +// vframe: +// pushq %rbp +// movq %rsp, %rbp +// subq $16, %rsp +// leaq 22(,%rdi,8), %rax +// andq $-16, %rax +// +// +// bitlevel representation of -16 +// 1111111111111111111111111111111111111111111111111111111111110000 +// +// rax +// 22 + n*8 +// n=0 0000000000000000000000000000000000000000000000000000000000010110 22 +// n=1 0000000000000000000000000000000000000000000000000000000000011110 30 +// n=2 0000000000000000000000000000000000000000000000000000000000100110 38 +// n=3 0000000000000000000000000000000000000000000000000000000000101110 46 +// n=4 0000000000000000000000000000000000000000000000000000000000110110 54 +// n=5 0000000000000000000000000000000000000000000000000000000000111110 62 +// +// (22 + n*8) & -16 +// n=0 0000000000000000000000000000000000000000000000000000000000010000 16 8n+16 +// n=1 0000000000000000000000000000000000000000000000000000000000010000 16 8n+8 +// n=2 0000000000000000000000000000000000000000000000000000000000100000 32 8n+16 +// n=3 0000000000000000000000000000000000000000000000000000000000100000 32 8n+8 +// n=4 0000000000000000000000000000000000000000000000000000000000110000 48 +// n=5 0000000000000000000000000000000000000000000000000000000000110000 48 +// +// print("{:064b}".format((0*8+22) & -16)) +// print("{:064b}".format((1*8+22) & -16)) +// print("{:064b}".format((2*8+22) & -16)) +// print("{:064b}".format((3*8+22) & -16)) +// print("{:064b}".format((4*8+22) & -16)) +// print("{:064b}".format((5*8+22) & -16)) +// +// B. +// vframe: +// pushq %rbp +// movq %rsp, %rbp +// subq $16, %rsp +// leaq 22(,%rdi,8), %rax +// andq $-16, %rax +// +// subq %rax, %rsp +// +// leaq 7(%rsp), %rax rax <- (rsp+7) = (rsp+(n-1)), n = 8 +// shrq $3, %rax rax <- (floor(rax/8)) +// leaq 0(,%rax,8), %r8 r8 <- ceil(rsp/8)*8 +// +// Important We are growing the stack downwards. +// But the array index grows upwards. +// +// See 2.3.7 for derivation. +// If x%(1<<k) == 0 then the bias has no effect, rounding down does not happen, there is no fraction. +// else +// Since the operation of adding the bias and then flooring happens, +// this results in rounding towards zero, or taking the ceiling. +// +// So if rsp was a multiple of 8 then nothing happens. +// Otherwise the start of the array is set to the first multiple of 8 towards the bottom of the stack (ceil goes towards greater addresses of the bottom). +// +// C. +// +// s_2 = (- s_1 +// (+ (if (odd? n) 8 16) (* n 8) ) +// ) +// +// p = ceil(s2/8)*8 +// e2 = (- p s2) +// e1 = (- s2 s1 e2 8n) +// +// 2065 - (8+5*8) +// +// n s_1 s_2 p e_1 e_2 +// 5 2065 2017 2024 1 7 +// 6 2064 2000 2000 16 0 +// +// D. +// p is 8byte aligned owing to the 8-10 instructions. +// s2 is not guaranteed to be aligned, so 1 byte. (But all we are doing is subtracting multiples of 16 from s1... not sure how this helps) |
