二进制文件中堆栈对齐问题初探

明白程序的执行逻辑

链接如下,问题是:

stackoverflow

  在程序开始运行前,都有对临时环境变量保存的习惯,这个操作在x86体系下是对堆栈进行操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
8048394:8d 4c 24 04  lea0x4(%esp),%ecx  ; ??
8048398:83 e4 f0 and$0xfffffff0,%esp; ??
804839b:ff 71 fc pushl -0x4(%ecx) ; ??
804839e:55 push %ebp; Store the Base pointer
804839f:89 e5mov%esp,%ebp ; Initialize the Base pointer with the stack pointer
80483a1:51 push %ecx; ??
80483a2:83 ec 4c sub$0x4c,%esp ; ??
80483a5:c7 45 f8 0c 00 00 00 movl $0xc,-0x8(%ebp) ; Move 12 into -0x8(%ebp)
80483ac:c7 45 f4 14 00 00 00 movl $0x14,-0xc(%ebp); Move 20 into -0xc(%ebp)
80483b3:8b 45 f8 mov-0x8(%ebp),%eax ; Move 12@-0x8(%ebp) into eax
80483b6:83 c0 7b add$0x7b,%eax ; Add 123 to 12@eax
80483b9:89 45 f4 mov%eax,-0xc(%ebp) ; Store the result into b@-0xc(%ebp)
80483bc:b8 00 00 00 00 mov$0x0,%eax ; Move 0 into eax
80483c1:83 c4 10 add$0x10,%esp ; ??
80483c4:59 pop%ecx; ??
80483c5:5d pop%ebp; ??
80483c6:8d 61 fc lea-0x4(%ecx),%esp ; ??

Understanding the purpose of some assembly statements
如何理解?

and $0xfffffff0,%esp 

官方给出的解释是:

This code makes sure that the stack is aligned to 16 bytes. After this operation esp will be less than or equal to what it was before this operation, so the stack may grow, which protects anything that might already be on the stack. This is sometimes done in main just in case the function is called with an unaligned stack, which can cause things to be really slow (16 byte is a cache line width on x86, I think, though 4 byte alignment is what is really important here). If main has a unaligned stack the rest of the program will too.

总的来说就是为了对齐

Many architectures have a concept called alignment where the hardware is designed to operate on addresses that are multiples of the word size. For example, on a 32-bit processor, objects might be aligned to 32-bit boundaries (4 bytes), and on a 64-bit processor, objects might be aligned to 64-bit boundaries (8 bytes). An aligned pointer is one that points to an address that’s a multiple of the word size, and an unaligned pointer is one that’s not pointing to an address that’s a multiple of the word size.

On most architectures, reading or writing unaligned pointers suffers some sort of penalty. On some processors, doing this causes a bus error, which usually terminates the program immediately. On others, such as x86, unaligned reads and writes are legal but suffer a performance penalty due to how the hardware is structured.

In your code, 0xBAD = 2989 is probably not aligned, since it’s not a multiple of most common word sizes, and the pointer you write to is also probably not aligned.

Hope this helps!

链接地址:https://stackoverflow.com/questions/20183094/what-is-a-misaligned-pointer

亲自搜一搜

随便搜搜bin文件里,

可以看到0x80482E5 esp自身自身进行了对齐,而Libc_csu_fini中实现了对main调用前的初始化操作,很多细节还是需要看

调试下查看下位置,程序执行前,esp地址为:

ESP: 0xffffd0d4 --> 0xffffd2ad 

程序执行以后,栈的地址应该是低地址延伸:

ESP: 0xffffd0d0 --> 0x1

然后,可以看到向下移动了0x04个地址空间,浪费了这点地址,但是对齐了。

Sometimes , compiler will optimize the code by adding some padding to make it align to word boundary
You have to inspect the assembly code to know the exactly stack position

编译器执行操作命令