[정보 보안] 리버스 엔지니어링 4편 : 리버싱 분석 절차와 흐름

Cookie·2025년 8월 5일
0

정보보안

목록 보기
40/40
post-thumbnail

3편의 기초 구조 이해 내용의 다음으로 리버싱을 분석하는 절차와 흐름에 대해 정리하고 예시와 전략에 대해 작성함




🫧코드 흐름 분석

코드 흐름 분석은 리버싱의 핵심 작업 중 하나로, 프로그램이 어떻게 실행되는지, 그리고 어떤 조건에서 어떤 동작을 하는지 파악하는 과정

이를 통해 프로그램히

  • 어떤 조건에서 분기하며
  • 어떤 함수를 호출하고
  • 어떤 루틴이 반복 수행되는가
    에 대해 정확하게 추적할 수 있음

🔸Branch(분기) 흐름 분석

Branch란 조건에 따라 실행 흐름이 바뀌는 구조로 어셈블리에서는 cmp명령어로 값을 비교하고, je,jne,jg,jl 등의 조건 점프(jump)명령으로 흐름이 갈라짐


주요 조건 점프 명령어

명령어의 미예시 상황
je / jzEqual / Zero[cmp eax, 1] → [eax == 1]
jne / jnzNot Equal / Not Zero[eax != 1]
jgGreater than (signed)[eax > ebx]
jlLess than (signed)[eax < ebx]
jaAbove (unsigned)[eax > ebx] (unsigned 기준)
jbBelow (unsigned)[eax < ebx] (unsigned 기준)
cmp eax, 0x5	; EAX와 5 비교
je 0x401020		; 같으면 0x401020으로 점프
jne 0x401030	; 다르면 0x401030으로 점프

💡cmp는 내부적으로 sub와 비슷하게 작동하며, 연산 결과에 따라 ZF(Zero Flag)등 플래그가 바뀌고, 그걸 조건 점프가 확인함



🔸Loop(루프) 흐름 분석

반복문은 일반적으로 조건 분기 + 점프 조합으로 구현되어 있음
루프 구조는 jmp로 되돌아가면서 반복 수행되며, loop,ecx레지스터 기반 반복도 자주 등장함

mov ecx, 3		; 반복 횟수
loop_start:
; ...코드...
loop loop_start	; ECX--, 0이 아니면 loop_start로 점프

또는

mov eax, 0
cmp eax, 5
jge end_loop
inc eax
jmp short loop_start



🔸Call(함수 호출) 흐름 분석

어셈블리에서 함수 호출은 call, 함수 종료는 ret 으로 표현됨

call 0x401000	; 401000 주소의 함수 호출

🔍함수 호출 시 중요한 흐름

  • call 실행 시, return 주소스택에 push
  • 함수 내부에서 ret 명령을 만나면, 스택에서 복귀 주소 pop하고 원래 위치로 돌아감
push return_address		; call 명령으로 인해 자동으로 push 됨
jmp 함수주소			 ; 내부적으로 jump와 동일

🔍함수 인자 전달 방식

  • _cdecl, _stdcall 등 Calling Convention에 따라 인자 전달 방식이 달라짐
  • 일반적으로 스택을 이용함 (push 인자1,push 인자2,...)
push 0x1234
pushs 0x5678
call MessageBoxA

💡API 호출을 분석할 때는 인자 순서와 개수를 정확히 파악해야 의미 있는 분석이 가능



🔸흐름 추적 팁

x64dbg, IDA 등 기준

  1. Entry Point → main 함수까지 흐름 추적
    : 함수명이 없으면 패턴으로 추청(sub_401000 등)
  2. 조건문과 루프 확인
    : cmp,testjXX 조합 주목
  3. 함수 호출 → 내부 구조 확인
    : API 호출인지, 자체 함수인지 분리
  4. 중요 변수나 입력값의 처리 흐름 추적
    : mov,lea,add,xor 등 값 조작 주목
  5. 레지스터/스택 값 변화 관찰
    : esp,ebp,eax,ecx 등 주요 레지스터 집중




🫧실행 흐름 추적과 조작

디버깅을 통해 프로그램의 실행을 멈추고, 레지스터∙메모리 값을 직접 조작하거나 흐름을 바꾸는 행위로 흔히 Dynamic Analysis라 부르며, 정적 분석으로 파악하기 힘든 부분을 보완 함


🔹Breakpoint 설정

Breakpoint[BP]는 디버깅 시 특정 명령에서 실행을 멈추게 하는 일종의 중단점으로 함수 시작, 조건 분기 전, API 호출 전, 루프 시작 등에서 자주 사용됨


주요 Breakpoint 유형

종 류설 명
코드 BP[0x041000] 같은 주소나 함수 시작 위치
API BPCreateFileA, MessageBoxA 같은 외부 함수 호출 시
조건 BP특정 레지스터 값일 때 멈춤
메모리 BP (H/W BP)특정 메모리 읽기/쓰기 발생 시 중단 (watchpoint)

💡실전 팁

  • 암호 검증 루틴 분석 시, strcmp,memcmp,GetDlgItemTextA 등에 BP 걸기
  • 특정 입력 처리 후 흐름 분기 직전 (cmp,test 전) 위치에 BP
  • 암호화/복호화 루틴 진입 직접 BP → 복호화된 평무 메모리 확인 가능



🔹Step Into/Step Over/Run to Return

코드를 한 줄씩 실행하면서 동작을 확인할 수 있는 디버거의 핵심 기능

기 능설 명
Step Into (F7)함수 내부로 진입
Step Over함수 전체를 한 번에 실행하고 다음 줄로 이동
Run to Return현재 함수가 끝날 때까지 실행 후 복귀점에서 멈춤
Run Until Selection커서가 위치한 지점까지 실행



🔹레지스터 조작

레지스터의 값을 직접 바꾸는 것이 바로 리버서의 무기 중 하나로 조건 분기 결과나 반환값 등을 조작하여 인위적으로 실행 흐름을 바꾸는 데 사용됨


✅실전 예시

cmp eax, 0x1
jne fail_branch
  • eax != 1이면 fail_branch로 가는 상황이라면 EAX 값을 디버거에서 0x1로 변경하여 우회할 수 있음

  • 응용 시나리오

    • 라이센스 검사, 암호 검사 등에서의 조건 우회
    • 함수 반환값 위조
    • 특정 API의 실행 횟수를 강제로 초기화



🔹메모리, 스택 조작

디버깅 중 스택이나 메모리 값을 바꾸면 함수 동작이나 결과가 달라질 수 있음 특히 복호화 루틴, 포인터 체인, 문자열 처리 등에서 효과적임


✅실전 예시

  • 특정 문자열을 직접 메모리에 써넣고 복호화 루틴에 전달
  • ESPEBP의 값을 조작해서 리턴 주소 변경
  • 구조체 내부 포인터 값 강제 변경
profile
나만의 공부 일지... [임시 休]

0개의 댓글