스택프레임 시각화 - ( StackFrame visualization) (2)

2023. 1. 17. 16:13코딩

반응형

최근에 포너블 공부를 하면서 시간이 생기면 만들고 싶었던게 있었다.

c언어로 된 소스가 있으면 그 코드의 스택 프레임을 시각화해서 출력해주는 프로그램을 만들면 

포너블을 처음 시작한 사람들이 보고 스택에 대한 이해를 더 쉽게 할수 있을것같아서 기획을 쭉 해왔었다.

 

출처 : TCP school

이런식으로 높은 주소 -> 낮은 주소로 표현할것이고 main함수와 그 함수가 호출하는 부분의 스택만 저런식으로 시각화 해서 띄워줄 예정.

 

-----------------------


from pwn import *
import subprocess
import sys
import time
import re

def disas(a):
    context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
    command = 'gdb -ex "disas main" {} > output.txt'.format(a)
    for i in range(1):
        pi = subprocess.Popen(command, shell=True)

def makeFrame(mainfuncFile):
    a = None
    subrsp_list = []
    cny_found = None

    matches = re.finditer(r'(0x[0-9a-f]+).*pushrbp', mainfuncFile, re.IGNORECASE)
    matches2 = re.finditer(r'subrsp.+(0x[0-9a-f]+)', mainfuncFile, re.IGNORECASE)
    matches3 = re.finditer(r'__stack_chk_fail@plt', mainfuncFile, re.IGNORECASE)
    for match in matches:
        if match:
            a = match.group(1)
    for match2 in matches2:
        if match2:
            subrsp_list.append((match2.group(0), match2.group(1)))
    for match3 in matches3:
        if match3:
            cny_found = True
    return a, subrsp_list , cny_found

print("[*] Please same directory ELF & StackVisual file")
a = input("[*] process : ").strip('\n')

disas(a)

with open("output.txt",'r') as f:
    mainfuncFile = f.read().replace(" ",'')

x,subrsp_list,cny_found = makeFrame(mainfuncFile)

print("*"*30)
print("RET <-- [rbp + 0x8]")
print("*"*30)
print("SFP <-- [rbp here]")
print("*"*30)
if cry_found == True:
    print("CANARY <-- [rbp - 0x8]")
    print("*"*30)
else:
    pass
for i, subrsp in enumerate(subrsp_list):
    print("var_{} <--[rbp - {}]".format(i+1, subrsp[1]))
    print("*"*30)

 

완성(이긴 한데 코드가 너무 지저분 함, 리눅스 환경의 x64 Elf 파일만 작동된다는 함정)

반응형