Machine Programming Advanced Topics

References

Outline

x86-64 Linux Memory Layout

x86-64 Linux Memory Layout

Linux Memory Layout
Linux Memory Layout

Memory Allocation Example

char big_array[1L<<24];  // 16 MB
char huge_array[1L<<31]; // 2 GB

int global = 0;

int useless() { return 0; }

int main() {
    void *phuge1, *psmall2, *phuge3, *psmall4;
    int local = 0;
    phuge1 = malloc(1L << 28);  // 256 MB
    psmall2 = malloc(1L << 8);  // 256 B
    phuge3 = malloc(1L << 32);  // 4 GB
    psmall4 = malloc(1L << 8);  // 256 B
    // some print statements
}

x86-64 Example Addresses

Symbol Example Address Location
local 0x00007ffe4d3be87c stack
phuge1 0x00007f7262a1e010 heap
phuge3 0x00007f7162a1d010 heap
psmall4 0x000000008359d120 heap
psmall2 0x000000008359d010 heap
big_array 0x0000000080601060 data
huge_array 0x0000000000601060 data
main() 0x000000000040060c text
useless() 0x0000000000400590 text

Runaway Stack Example

int recurse(int x) {
    int a[1<<15];  // 128 KiB
    printf("x = %d.    a at %p\n", x, a);
    a[0] = (1<<14)-1;
    a[a[0]] = x-1;
    if (a[a[0]] == 0) {
        return -1;
    }
    return recurse(a[a[0]]) - 1;
}

Memory Referencing Bug Example

typedef struct {
    int a[2];
    double d;
} struct_t;

double fun(int i) {
    volatile struct_t s;
    s.d = 3.14;
    s.a[i] = 1073741824; // possibly out of bounds
    return s.d;
}

Memory Referencing Bug Example

Such Problems are a BIG deal

String Library Code

Vulnerable Buffer Code

/* Echo Line */
void echo() {
    char buf[8]; // way too small
    gets(buf);
    puts(buf);
}

void call_echo() {
    echo();
}

Buffer Overflow Disassembly

echo:
  subq  $24, %rsp   # allocate 24 bytes on stack
  movq  %rsp, %rdi  # compute buf as %rsp
  call  gets        # call gets
  movq  %rsp, %rdi  # compute buf as %rsp
  call  puts        # call puts
  addq  $24, %rsp   # deallocate stack space
  ret

Buffer Overflow Stack Example

Characters typed Additional Corrupted State
0 - 7 None
9 - 23 Unused stack space
24 - 31 Return address
32+ Saved state in caller

Stack Smashing Attacks

Crafting Smashing String

Performing Stack Smash

Code Injection Attacks

Preventing Buffer Overflow Attacks

1. Avoid Overflow Vulnerabilities in Code

void echo() {
    char buf[4];
    fgets(buf, 4, stdin);
    puts(buf);
}

System-Level Protections Can Help

Stack Canaries Can Help

Return-Oriented Programming Attacks

Gadget Example #1

Gadget Example #2

Return-Oriented Programming Execution

Union Allocation

struct S1 {
    char c;   // 1 byte + 3 bytes padding
    int i[2]; // 8 bytes + 4 bytes padding
    double v; // 8 bytes
} *up;

Using Union to Access Bit Patterns

typedef union {
    float f;
    unsigned u;
} bit_float_t;

float bit2float(unsigned u) {
    bit_float_t arg;
    arg.u = u;
    return arg.f;
}

unsigned float2bit(float f) {
    bit_float_t arg;
    arg.f = f;
    return arg.u;
}

Byte Ordering Revisited

Summary of Compound Types in C

Summary