[Rev] 리버싱 · 작성: 2026-07-19 19:32:50 · 조회 4
정적 분석만으로는 "이 변수가 실제로 어떤 값을 갖는지", "이 분기가 실제로 어느 쪽으로 가는지"를 확신하기 어려울 때가 많다. 디버거로 실제 실행시키면서 관찰하면 훨씬 빠르게 답이 나온다.
| 플랫폼 | 도구 |
|---|---|
| Linux | gdb (+ pwndbg 또는 gef 플러그인으로 UI 개선) |
| Windows | x64dbg, WinDbg |
| macOS | lldb |
| 크로스플랫폼 후킹 | Frida (다음 글에서 별도로 다룸) |
기본 gdb는 화면이 텍스트뿐이라 레지스터/스택 상태를 보기 불편해서, 실무에서는 거의 항상 pwndbg나 gef 같은 플러그인을 얹어서 쓴다.
gdb ./target
break *0x401234 # 특정 주소에 브레이크포인트
break check_password # 함수 이름으로 브레이크포인트 (심볼이 있을 때)
run # 실행 시작
next / n # 한 줄 실행 (함수 호출은 건너뜀)
step / s # 한 줄 실행 (함수 호출 안으로 들어감)
continue / c # 다음 브레이크포인트까지 실행
info registers # 전체 레지스터 값
x/10xg $rsp # 스택 상위 10개(8바이트씩)를 16진수로
x/s $rdi # rdi가 가리키는 문자열 출력
disassemble # 현재 함수 어셈블리 보기
pwndbg/gef를 쓰면 브레이크포인트에 걸릴 때마다 레지스터·스택·현재 명령어를 한 화면에 자동으로 정리해서 보여줘서, 위 명령어들을 매번 칠 필요가 줄어든다.
strings로 "Wrong password" 같은 실패 메시지 문자열을 찾는다cmp/je/jne 분기 지점에 브레이크포인트를 건다브레이크포인트를 하나씩 거는 대신, 어떤 시스템 콜/라이브러리 함수를 호출하는지 순서대로 쭉 보고 싶을 때는 트레이싱 도구가 더 빠르다.
strace ./target # 시스템 콜 추적 (open, read, connect 등)
ltrace ./target # 라이브러리 함수 호출 추적 (strcmp, malloc 등)
암호화되지 않은 비교라면 ltrace에 strcmp("입력값", "실제정답") 형태로 그냈로 정답이 찍히는 경우도 흔하다 — 정적 분석보다 훨씬 빠른 지름길이 될 때가 있다.
특정 조건일 때만 멈추게 하면 반복문 안에서 원하는 순간만 잡을 수 있다.
break *0x401234 if $rax == 5
정적 분석으로 "어디를 봐야 할지" 가설을 세우고, 동적 분석으로 그 가설을 실제 값으로 검증하는 반복이 리버싱의 기본 사이클이다.