简体   繁体   English

如何在 C 中查看结构的对齐方式?

[英]How to see the alignment of a struct in C?

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.该程序使用gets() 和strcpy() 将两个args 放入v.username 和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.金丝雀是我知道的 10 位数字。 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.由于 int32_t 只有 4 个字节,我将数字转换为 ascii 并希望溢出作为 input2 的密码,并且由于金丝雀在内存中的密码之后,我想我可以在它溢出后将它放在 input2 的末尾。 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:这是结构的每个成员的内存位置:截屏

How can I see where the padding is and how do I know where to put the canary value?如何查看填充的位置以及如何知道金丝雀值的放置位置?

Thank you.谢谢你。

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.在对整数有 4 字节对齐要求的计算机上,结构中具有这种要求的每个成员都必须从可被 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.您可以使用offsetof ( stddef.h ) 打印任何结构成员的字节位置。 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):输出(x86_64 计算机):

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.由于canary从 32 开始,因此必须插入 32-25-4=3 个填充字节。 And they must have been inserted after password since goodcanary is 4 byte aligned with no trailing padding necessary.并且它们必须是在password之后插入的,因为goodcanary是 4 字节对齐的,不需要尾随填充。

Or if you will:或者,如果您愿意:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM