Home > Net >  How to see the alignment of a struct in C?
How to see the alignment of a struct in C?

Time:06-09

I have an assignment where I need to log in to a simple program using a buffer overflow. The program takes two args with gets() and strcpy()'s them into v.username and v.password.

struct {
        int32_t goodcanary;
        char password[25];
        int32_t canary;
        char good_username[25];
        char good_password[25];
        char username[25];
    } v;

The canary is a 10 digit number which I know. Since a int32_t is only 4 bytes I converted the number to ascii and want to overflow password which is input2 and since canary comes after password in memory I thought I could put it at the end of input2 after it overflows. I can't get it working and I know that structs have padding but I don't know exactly how it works and where the padding is. Here is the memory locations of each member of the struct: screenshot

How can I see where the padding is and how do I know where to put the canary value?

Thank you.

CodePudding user response:

The rules are basically as follows:

  • On systems with alignment requirements, a struct must always be allocated starting at an even address. For this reason, a struct needs to end with trailing padding bytes so that an array of such structs doesn't get the next array item misaligned.
  • On a computer with 4 byte alignment requirement for integers, each member in your struct that has such a requirement must start at an address evenly divisible by 4.
  • Character arrays have no alignment requirement so they may get allocated at any address.

You can use offsetof (stddef.h) to print the byte position of any struct member. Example:

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>

typedef struct 
{
    int32_t goodcanary;
    char password[25];
    int32_t canary;
    char good_username[25];
    char good_password[25];
    char username[25];
} v;

#define print_offset(x) printf("Offset %s: %zu\n", #x, offsetof(v,x))

int main (void)
{
  printf("Size of struct: %zu\n", sizeof(v));
  print_offset(goodcanary);
  print_offset(password);
  print_offset(canary);
  print_offset(good_username);
  print_offset(good_password);
  print_offset(username);
  return 0;
}

Output (x86_64 computer):

Size of struct: 112
Offset goodcanary: 0
Offset password: 4
Offset canary: 32
Offset good_username: 36
Offset good_password: 61
Offset username: 86

Since canary starts at 32, there must have been 32-25-4=3 padding bytes inserted. And they must have been inserted after password since goodcanary is 4 byte aligned with no trailing padding necessary.

Or if you will:

offsetof(v, canary) - sizeof((v){0}.password) - offsetof(v,password)
  • Related