C Programming

General-purpose, imperative, low-level, memory management, compiled

"C was originally developed at Bell Labs by Dennis Ritchie between 1972 and 1973 to make utilities running on Unix" -Wiki

Control Statements

  • If-statements
  • While-loops
  • Do-whiles
  • For-loops
  • Switch-statements
  • Gotos
if ( 1 && !0 ){
    printf("Non-zero is true\n");
} else {
    printf("!0 is 1\n");
}
while ("Is this non-zero?") {
    printf("Who thinks yes?\n");
} 
int i; /* C99 */
for (; i < 10; i++) {
    print("What is wrong with this?\n");
}
/* What might this snipped be used for? */
switch(ast_node->type) {
    case INT:
        return atoi(ast_node->data);
    case PLUS:
        int a = process(ast_node->left);
        int b = process(ast_node->right);
        return a + b
    default:
        printf("There was an error\n");
        exit(1); /* What does exit 1 mean? */
}
C:
B:
    if (a) {
        goto A;
    }
A: 
    if (b) {
        goto B;
    }
    a = ~a;
    b = ~b;
    goto C;

Pointers & Dynamic Memory

What are pointers used for in C?

  • referencing memory on the stack or heap
  • referencing arrays
  • extra return values

What are pointers used for in Java?

  • Objects, Objects, Objects
//stack memory, how many bytes are used?
int a[10] = {42, 0}; 

//pointer to stack memory
int *pa = a;

//pointer to heap memory
int *b = malloc(sizeof(int)*10); 

//pointer to heap memory pointing to pointers,
// how many bytes are used?
int **c = malloc(sizeof(int*)*3);

c[0] = b;
c[1] = b;
c[2] = a+1;

**(c+2) = 72;

printf("What is c[2][0]? %d\n", c[2][0]);
printf("What is c[2][-1]? %d\n", c[2][-1]);

Referencing memory on the stack or heap

Arrays are contiguous blocks of memory. Static 2D Arrays are contiguous, but not Dynamic 2D Arrays

Pointers & Dynamic Memory

These data structures and how they are represented in memory are important! 

int foo(int x, int y, int *z) {
    if (x > 0 && y > 0){
        *z = x*y;
        return SUCCESS;
    }
    return FAILURE;
}

int main() {
    int a = -1;
    if (foo(1, 2, &a) == FAILURE) {
        return 1;
    }

    printf("%d\n", a);
    return a;
}

How do you return multiple items from a function?

Sometimes one return value is not enough, so pointer as arguments can help receive more data from a function. 

Pointers & Dynamic Memory

Stack and Heap

What is the Stack?

 

 

 

 

 

What is the Heap?

*if you know where to look

  • Memory used to separate function frames for local memory usage
  • Starts at a high address and grows down
  • Dynamic memory that is globally accessible*
  • Must be allocated & freed manually

C experts now?

/* 1. What is wrong here? */
int *baz(){
    int i = 10;
    return &i;
}
/* 2. Is this valid? */
int *bar() {
    static int i = 5;
    return &i;
}    
/* 3. Is this valid? */
int *foo() {
    void *yeet = malloc(sizeof(double)*10);
    return (int *)yeet;
}

/* 4. Is this valid? */
int main() {
    char *yeett = (char *)foo();
    printf(yeett);
    
    /* 5. Missing something? */
    return 0;
}

Why do we care about details like these?

What does the stack look like?

int *foo(int c, int d) {
    char e;
    void *yeet = malloc(sizeof(c)*d);
    /* Stop! */
    return (int *)yeet;
}

int main(int argc, char *argv[]) {
    int a = 5, 3;
    int b = 7;
    char *bar = foo((b,a),b);
    
    return 0;
}

High

Low

argv

argc

ret addr

old base

5

7

5

7

ret addr

old base

junk

heap addr

C Programming

By Drake P

C Programming

C Programming basics that are relevant to reverse engineering.

  • 138