본문 바로가기

pwnable/분석

gcc options (-mpreferred-stack-boundary)

-mpreferred-stack-boundary

#!/usr/bin/env bash
set -ex
start_string=++++++++++++++++
end_string=-----------------

echo > result32.txt
echo > result64.txt

for BIT_SIZE in 32 64
do
    for VAR in "default" {2..12}
    do
        OPTION="-mpreferred-stack-boundary=$VAR"
        if [ "default" = "$VAR" ]; then
            OPTION=""
        fi

        if [[ "$VAR" -eq 2 && "$BIT_SIZE" -eq 64 ]]; then
            continue
        fi
        filename="flag$BIT_SIZE""_""$VAR"
        gcc main.c -o $filename -m$BIT_SIZE $OPTION -Wno-format-security
        echo $start_string >> result$BIT_SIZE.txt
        echo option: $VAR >> result$BIT_SIZE.txt
        gdb -batch -ex 'x/10i main' $filename >> result$BIT_SIZE.txt
        echo $end_String >> result$BIT_SIZE.txt
        rm $filename
    done
done
  • -mpreferred-stack-boundary=N 옵션

    main 을 포함하여 이후에 불리는 모든 함수들의 스택프레임에서 가장 낮은 주소가 2^N 에 배수가 되도록 align 을 해줌

    • result32.txt
      ++++++++++++++++
      option: default
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x1335 <main>:	endbr32 
         0x1339 <main+4>:	lea    ecx,[esp+0x4]
         0x133d <main+8>:	and    esp,0xfffffff0
         0x1340 <main+11>:	push   DWORD PTR [ecx-0x4]
         0x1343 <main+14>:	push   ebp
         0x1344 <main+15>:	mov    ebp,esp
         0x1346 <main+17>:	push   esi
         0x1347 <main+18>:	push   ebx
         0x1348 <main+19>:	push   ecx
         0x1349 <main+20>:	sub    esp,0x8c
      
      ++++++++++++++++
      option: 2
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x132f <main>:	endbr32 
         0x1333 <main+4>:	push   ebp
         0x1334 <main+5>:	mov    ebp,esp
         0x1336 <main+7>:	push   esi
         0x1337 <main+8>:	push   ebx
         0x1338 <main+9>:	sub    esp,0x70
         0x133b <main+12>:	call   0x11d0 <__x86.get_pc_thunk.bx>
         0x1340 <main+17>:	add    ebx,0x2c70
         0x1346 <main+23>:	mov    eax,DWORD PTR [ebp+0xc]
         0x1349 <main+26>:	mov    DWORD PTR [ebp-0x78],eax
      
      ++++++++++++++++
      option: 3
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x1332 <main>:	endbr32 
         0x1336 <main+4>:	lea    ecx,[esp+0x4]
         0x133a <main+8>:	and    esp,0xfffffff8
         0x133d <main+11>:	push   DWORD PTR [ecx-0x4]
         0x1340 <main+14>:	push   ebp
         0x1341 <main+15>:	mov    ebp,esp
         0x1343 <main+17>:	push   esi
         0x1344 <main+18>:	push   ebx
         0x1345 <main+19>:	push   ecx
         0x1346 <main+20>:	sub    esp,0x7c
      
      ++++++++++++++++
      option: 4
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x1335 <main>:	endbr32 
         0x1339 <main+4>:	lea    ecx,[esp+0x4]
         0x133d <main+8>:	and    esp,0xfffffff0
         0x1340 <main+11>:	push   DWORD PTR [ecx-0x4]
         0x1343 <main+14>:	push   ebp
         0x1344 <main+15>:	mov    ebp,esp
         0x1346 <main+17>:	push   esi
         0x1347 <main+18>:	push   ebx
         0x1348 <main+19>:	push   ecx
         0x1349 <main+20>:	sub    esp,0x8c
      
      ++++++++++++++++
      option: 5
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x133e <main>:	endbr32 
         0x1342 <main+4>:	lea    ecx,[esp+0x4]
         0x1346 <main+8>:	and    esp,0xffffffe0
         0x1349 <main+11>:	push   DWORD PTR [ecx-0x4]
         0x134c <main+14>:	push   ebp
         0x134d <main+15>:	mov    ebp,esp
         0x134f <main+17>:	push   esi
         0x1350 <main+18>:	push   ebx
         0x1351 <main+19>:	push   ecx
         0x1352 <main+20>:	sub    esp,0xac
      
      ++++++++++++++++
      option: 6
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x1344 <main>:	endbr32 
         0x1348 <main+4>:	lea    ecx,[esp+0x4]
         0x134c <main+8>:	and    esp,0xffffffc0
         0x134f <main+11>:	push   DWORD PTR [ecx-0x4]
         0x1352 <main+14>:	push   ebp
         0x1353 <main+15>:	mov    ebp,esp
         0x1355 <main+17>:	push   esi
         0x1356 <main+18>:	push   ebx
         0x1357 <main+19>:	push   ecx
         0x1358 <main+20>:	sub    esp,0xec
      
      ++++++++++++++++
      option: 7
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x1344 <main>:	endbr32 
         0x1348 <main+4>:	lea    ecx,[esp+0x4]
         0x134c <main+8>:	and    esp,0xffffff80
         0x134f <main+11>:	push   DWORD PTR [ecx-0x4]
         0x1352 <main+14>:	push   ebp
         0x1353 <main+15>:	mov    ebp,esp
         0x1355 <main+17>:	push   esi
         0x1356 <main+18>:	push   ebx
         0x1357 <main+19>:	push   ecx
         0x1358 <main+20>:	sub    esp,0x16c
      
      ++++++++++++++++
      option: 8
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x1356 <main>:	endbr32 
         0x135a <main+4>:	lea    ecx,[esp+0x4]
         0x135e <main+8>:	and    esp,0xffffff00
         0x1364 <main+14>:	push   DWORD PTR [ecx-0x4]
         0x1367 <main+17>:	push   ebp
         0x1368 <main+18>:	mov    ebp,esp
         0x136a <main+20>:	push   esi
         0x136b <main+21>:	push   ebx
         0x136c <main+22>:	push   ecx
         0x136d <main+23>:	sub    esp,0x2ec
      
      ++++++++++++++++
      option: 9
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x1356 <main>:	endbr32 
         0x135a <main+4>:	lea    ecx,[esp+0x4]
         0x135e <main+8>:	and    esp,0xfffffe00
         0x1364 <main+14>:	push   DWORD PTR [ecx-0x4]
         0x1367 <main+17>:	push   ebp
         0x1368 <main+18>:	mov    ebp,esp
         0x136a <main+20>:	push   esi
         0x136b <main+21>:	push   ebx
         0x136c <main+22>:	push   ecx
         0x136d <main+23>:	sub    esp,0x5ec
      
      ++++++++++++++++
      option: 10
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x1356 <main>:	endbr32 
         0x135a <main+4>:	lea    ecx,[esp+0x4]
         0x135e <main+8>:	and    esp,0xfffffc00
         0x1364 <main+14>:	push   DWORD PTR [ecx-0x4]
         0x1367 <main+17>:	push   ebp
         0x1368 <main+18>:	mov    ebp,esp
         0x136a <main+20>:	push   esi
         0x136b <main+21>:	push   ebx
         0x136c <main+22>:	push   ecx
         0x136d <main+23>:	sub    esp,0xbec
      
      ++++++++++++++++
      option: 11
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x1360 <main>:	endbr32 
         0x1364 <main+4>:	lea    ecx,[esp+0x4]
         0x1368 <main+8>:	and    esp,0xfffff800
         0x136e <main+14>:	push   DWORD PTR [ecx-0x4]
         0x1371 <main+17>:	push   ebp
         0x1372 <main+18>:	mov    ebp,esp
         0x1374 <main+20>:	push   esi
         0x1375 <main+21>:	push   ebx
         0x1376 <main+22>:	push   ecx
         0x1377 <main+23>:	sub    esp,0x1000
      
      ++++++++++++++++
      option: 12
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x136a <main>:	endbr32 
         0x136e <main+4>:	lea    ecx,[esp+0x4]
         0x1372 <main+8>:	and    esp,0xfffff000
         0x1378 <main+14>:	push   DWORD PTR [ecx-0x4]
         0x137b <main+17>:	push   ebp
         0x137c <main+18>:	mov    ebp,esp
         0x137e <main+20>:	push   esi
         0x137f <main+21>:	push   ebx
         0x1380 <main+22>:	push   ecx
         0x1381 <main+23>:	sub    esp,0x1000
    • result64.txt
      ++++++++++++++++
      option: default
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12b4 <main>:	endbr64 
         0x12b8 <main+4>:	push   rbp
         0x12b9 <main+5>:	mov    rbp,rsp
         0x12bc <main+8>:	push   rbx
         0x12bd <main+9>:	sub    rsp,0x98
         0x12c4 <main+16>:	mov    DWORD PTR [rbp-0x94],edi
         0x12ca <main+22>:	mov    QWORD PTR [rbp-0xa0],rsi
         0x12d1 <main+29>:	mov    rax,QWORD PTR fs:0x28
         0x12da <main+38>:	mov    QWORD PTR [rbp-0x18],rax
         0x12de <main+42>:	xor    eax,eax
      
      ++++++++++++++++
      option: 3
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12b4 <main>:	endbr64 
         0x12b8 <main+4>:	push   rbp
         0x12b9 <main+5>:	mov    rbp,rsp
         0x12bc <main+8>:	push   rbx
         0x12bd <main+9>:	sub    rsp,0x88
         0x12c4 <main+16>:	mov    DWORD PTR [rbp-0x84],edi
         0x12ca <main+22>:	mov    QWORD PTR [rbp-0x90],rsi
         0x12d1 <main+29>:	mov    rax,QWORD PTR fs:0x28
         0x12da <main+38>:	mov    QWORD PTR [rbp-0x10],rax
         0x12de <main+42>:	xor    eax,eax
      
      ++++++++++++++++
      option: 4
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12b4 <main>:	endbr64 
         0x12b8 <main+4>:	push   rbp
         0x12b9 <main+5>:	mov    rbp,rsp
         0x12bc <main+8>:	push   rbx
         0x12bd <main+9>:	sub    rsp,0x98
         0x12c4 <main+16>:	mov    DWORD PTR [rbp-0x94],edi
         0x12ca <main+22>:	mov    QWORD PTR [rbp-0xa0],rsi
         0x12d1 <main+29>:	mov    rax,QWORD PTR fs:0x28
         0x12da <main+38>:	mov    QWORD PTR [rbp-0x18],rax
         0x12de <main+42>:	xor    eax,eax
      
      ++++++++++++++++
      option: 5
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12bd <main>:	endbr64 
         0x12c1 <main+4>:	push   rbp
         0x12c2 <main+5>:	mov    rbp,rsp
         0x12c5 <main+8>:	push   rbx
         0x12c6 <main+9>:	and    rsp,0xffffffffffffffe0
         0x12ca <main+13>:	sub    rsp,0xa0
         0x12d1 <main+20>:	mov    DWORD PTR [rsp+0x1c],edi
         0x12d5 <main+24>:	mov    QWORD PTR [rsp+0x10],rsi
         0x12da <main+29>:	mov    rax,QWORD PTR fs:0x28
         0x12e3 <main+38>:	mov    QWORD PTR [rsp+0x98],rax
      
      ++++++++++++++++
      option: 6
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12c3 <main>:	endbr64 
         0x12c7 <main+4>:	push   rbp
         0x12c8 <main+5>:	mov    rbp,rsp
         0x12cb <main+8>:	push   rbx
         0x12cc <main+9>:	and    rsp,0xffffffffffffffc0
         0x12d0 <main+13>:	sub    rsp,0xc0
         0x12d7 <main+20>:	mov    DWORD PTR [rsp+0x3c],edi
         0x12db <main+24>:	mov    QWORD PTR [rsp+0x30],rsi
         0x12e0 <main+29>:	mov    rax,QWORD PTR fs:0x28
         0x12e9 <main+38>:	mov    QWORD PTR [rsp+0xb8],rax
      
      ++++++++++++++++
      option: 7
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12c3 <main>:	endbr64 
         0x12c7 <main+4>:	push   rbp
         0x12c8 <main+5>:	mov    rbp,rsp
         0x12cb <main+8>:	push   rbx
         0x12cc <main+9>:	and    rsp,0xffffffffffffff80
         0x12d0 <main+13>:	sub    rsp,0x100
         0x12d7 <main+20>:	mov    DWORD PTR [rsp+0x7c],edi
         0x12db <main+24>:	mov    QWORD PTR [rsp+0x70],rsi
         0x12e0 <main+29>:	mov    rax,QWORD PTR fs:0x28
         0x12e9 <main+38>:	mov    QWORD PTR [rsp+0xf8],rax
      
      ++++++++++++++++
      option: 8
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12c9 <main>:	endbr64 
         0x12cd <main+4>:	push   rbp
         0x12ce <main+5>:	mov    rbp,rsp
         0x12d1 <main+8>:	push   rbx
         0x12d2 <main+9>:	and    rsp,0xffffffffffffff00
         0x12d9 <main+16>:	sub    rsp,0x200
         0x12e0 <main+23>:	mov    DWORD PTR [rsp+0xfc],edi
         0x12e7 <main+30>:	mov    QWORD PTR [rsp+0xf0],rsi
         0x12ef <main+38>:	mov    rax,QWORD PTR fs:0x28
         0x12f8 <main+47>:	mov    QWORD PTR [rsp+0x1f8],rax
      
      ++++++++++++++++
      option: 9
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12c9 <main>:	endbr64 
         0x12cd <main+4>:	push   rbp
         0x12ce <main+5>:	mov    rbp,rsp
         0x12d1 <main+8>:	push   rbx
         0x12d2 <main+9>:	and    rsp,0xfffffffffffffe00
         0x12d9 <main+16>:	sub    rsp,0x400
         0x12e0 <main+23>:	mov    DWORD PTR [rsp+0x1fc],edi
         0x12e7 <main+30>:	mov    QWORD PTR [rsp+0x1f0],rsi
         0x12ef <main+38>:	mov    rax,QWORD PTR fs:0x28
         0x12f8 <main+47>:	mov    QWORD PTR [rsp+0x3f8],rax
      
      ++++++++++++++++
      option: 10
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12c9 <main>:	endbr64 
         0x12cd <main+4>:	push   rbp
         0x12ce <main+5>:	mov    rbp,rsp
         0x12d1 <main+8>:	push   rbx
         0x12d2 <main+9>:	and    rsp,0xfffffffffffffc00
         0x12d9 <main+16>:	sub    rsp,0x800
         0x12e0 <main+23>:	mov    DWORD PTR [rsp+0x3fc],edi
         0x12e7 <main+30>:	mov    QWORD PTR [rsp+0x3f0],rsi
         0x12ef <main+38>:	mov    rax,QWORD PTR fs:0x28
         0x12f8 <main+47>:	mov    QWORD PTR [rsp+0x7f8],rax
      
      ++++++++++++++++
      option: 11
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12d5 <main>:	endbr64 
         0x12d9 <main+4>:	push   rbp
         0x12da <main+5>:	mov    rbp,rsp
         0x12dd <main+8>:	push   rbx
         0x12de <main+9>:	and    rsp,0xfffffffffffff800
         0x12e5 <main+16>:	sub    rsp,0x1000
         0x12ec <main+23>:	or     QWORD PTR [rsp],0x0
         0x12f1 <main+28>:	mov    DWORD PTR [rsp+0x7fc],edi
         0x12f8 <main+35>:	mov    QWORD PTR [rsp+0x7f0],rsi
         0x1300 <main+43>:	mov    rax,QWORD PTR fs:0x28
      
      ++++++++++++++++
      option: 12
      [31m[1mpwndbg: [0m[31m[0m[91mloaded 193 commands. Type [35mpwndbg [filter][0m[91m for a list.[0m
      [31m[1mpwndbg: [0m[31m[0m[91mcreated [35m$rebase[0m[91m, [35m$ida[0m[91m gdb functions (can be used with print/break)[0m
         0x12e1 <main>:	endbr64 
         0x12e5 <main+4>:	push   rbp
         0x12e6 <main+5>:	mov    rbp,rsp
         0x12e9 <main+8>:	push   rbx
         0x12ea <main+9>:	and    rsp,0xfffffffffffff000
         0x12f1 <main+16>:	sub    rsp,0x1000
         0x12f8 <main+23>:	or     QWORD PTR [rsp],0x0
         0x12fd <main+28>:	sub    rsp,0x1000
         0x1304 <main+35>:	or     QWORD PTR [rsp],0x0
         0x1309 <main+40>:	mov    DWORD PTR [rsp+0xffc],edi

    -m32, -m64 무관하게 디폴트는 N=4 이고, 따라서 모든 함수의 스택 프레임의 최하위주소가 16의 배수가 됨.

관련 gcc 소스코드

gcc-mirror/gcc
Contribute to gcc-mirror/gcc development by creating an account on GitHub.
https://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/gcc/config/i386/i386-options.c

64bit은 default 와 N=3 에서 and 연산 없이 align을 해주는데, 이는 _start 에서 (32bit, 64bit 무관하게) 0xfffffff...ff0 과 Stack Pointer 를 xor 시키고 시작하기 때문에, 64bit 기준 main 에 진입할 시점은 sp 의 LSB가 0x8 이 됨 (0x10 - 0x8(return address)) 여기서 rbp 와 rbx 를 push하기 때문에 LSB 는 변하지 않음

물론, __libc_start_main 을 거쳐 가기는 하지만, 이곳에서는 align 을 고려하지 않고 default 로 생각하며 N=4 만 맞추어진 상태이다(이미 라이브러리는 N=4, 즉 디폴트로 컴파일 되었기 때문)

따라서 main 에 진입했을 때도, LSB 가 0x8 인 상태라고 볼 수 있음

따라서 main 에서는 LSB가 0x8 인 Constant 로 rsp 를 감소시켜주기만 하면 N=4 조건까지 충족시키기 때문에, 64bit 바이너리에서 N≤4 일 때 rsp 를 and 시켜주지 않아도 됨

N = 4

N=3 일 때는 사실 64bit 이 8바이트 단위이기 때문에 당연히 align 되어있기 때문에 무시하자.

N = 4 일 때 다른 함수를 부르게 되면 마찬가지로 return address 가 차지하는 공간으로 rsp 의 LSB 가 0x8 이 되고 rbp 를 push 하면서 다시 16의 배수가 되기 때문에, 적당한 16의 배수 constant 를 빼줌으로 N=4 align 을 맞추는 것을 볼 수 있다.

N = 4

반면, 32bit 의 경우는 default 가 N=4 이고 block 단위가 4바이트이기 때문에 and 연산으로 esp 를 16에 align 시키는 것을 볼 수 있다.

반면 N=2 인 경우, 명령어에 아무런 변화없이도 기본적으로 4의 배수가 성립되므로 align 을 위한 명령어가 추가되지 않는 것을 볼 수 있음 → 분석에 용이

그렇다면 32bit 에서는 기본적으로 인자를 스택에 전달하고, 64bit 에서는 7번째 인자부터는 스택에 전달하는데, 위에서 고생하며 align 맞춘거를 다 깨버리지 않을까?

  • 그래서 push 하기 전에, 적절한 상수로 esp 를 낮춰줌으로써 자연스럽게 call 하기 직전에 align 이 되어있도록 함

64bit 은 (main 함수 기준으로) 인자가 레지스터에 있기 때문에 뭐 레지스터에서 읽어오면 되는데, 32bit 은 main 에서 align 을 하고 ebp 를 쌓고, 인자는 ebp 기준으로 가져와야할텐데 어떻게 하지??

  • and 이후에 ebp 를 쌓기 때문에, 인자들이 ebp 를 기준으로 얼마나 떨어졌는지 알 방법이 없어진다.
  • 이제는 ecx 가 인자들이 위치하는 시작주소를 가리키는 포인터가 된다. (lea ecx, [esp + 0x4])
  • 따라서 argc 를 출력하는 프로그램에서 [ecx] 에서 인자를 가져오는 것을 볼 수 있다.

그리고 main 이후에 불리는 함수에서는??

  • N align 을 맞춘 상태에서 함수 foo 를 부름
  • foo 에 진입할 때는 N align - 4 일 것이고, 이제 ebp와 callee saved register 를 push 한 후에 sub esp, CONST 를 적절히 연산해줌으로 다시 stack frame 을 align 시킴
    • 이제는 ebp 에서 인자를 읽어오면 됨(별다른 align 과정이 없었기 때문에)