[정보 보안] 리버스 엔지니어링 2편 : 기본 개념과 분석 방식

Cookie·2025년 7월 31일
0

정보보안

목록 보기
38/40
post-thumbnail

앞서 리버싱의 개요와 활용분야를 살혀봤다면, 이번에는 실제로 리버싱을 하기위한 핵심 개념과 분석 방식에 대해 알아봄




🫧바이너리와 소스코드의 관계

소프트웨어는 처음에 사람이 이해하기 쉬운 고급 언어(C, C++, JAVA 등)으로 작성되고, 컴파일러에 의해 컴퓨터가 실행 가능한 바이너리 파일(기계어)로 변환됨

리버싱은 이 바이너리를 분석하여, 소스코드 수준의 구조와 동작을 역추론하는 과정

소스코드 → Complie → [실행 파일]
             ↑
         리버싱 분석

📌 핵심: "소스 없이 프로그램을 이해하는 기술"이 리버싱의 본질




🫧어셈블리 언어와 리버싱

바이너리는 순수한 기계어지만, 사람이 보기 위해서는 보통 어셈블리어(Assembly) 형태로 디코딩함

어셈블리어는 리버스 엔지니어링에서 가장 핵심적인 분석 언어로,
기계어와 1:1 매칭되는 저수준 언어이며, 바이너리를 해석할 수 있는 가장 직접적인 수단임


어셈블리어가 중요한 이유⚠️

  • 컴파일된 바이너리 파일은 대부분 어셈블리 형태로 디스어셈블됨
  • 고급 언어의 흐름을 직접적으로 확인할 수 있음
  • 디버깅이나 패치, 취약점 분석 등에서 코드 수준의 조작이 가능함

어셈블리를 모른 채 리버싱을 하는 것은 지도를 모르고 탐험을 나서는 것과 같음



주요 CPU 아키텍처💻

어셈블리어는 CPU구조에 따라 명령어 집합(Instruction Set)이 다름

아키텍처특 징
x86 (32비트)전통적인 PC 기반 아키텍처, 레지스터 크기 32bit
x86_64 (64비트)64bit OS에서 사용, 레지스터 및 주소 처리 능력 향상
ARM모바일, IoT 기기에서 많이 사용됨, 저전력 구조



어셈블리 명령어와 기능🤖

리버싱 분석에서 자주 등장하는 명령어와 그 역할

명령어역할 / 분석 포인트
mov데이터 이동 (메모리 ↔ 레지스터) → 변수 저장 위치 추적
push / pop스택에 값 저장 / 꺼내기 → 함수 호출, 지역 변수 사용 시
call / ret함수 호출 / 반환 → 함수 흐름, 호출 관계 분석
cmp, test조건 비교 → 분기 조건 분석
jmp, je, jne조건 분기 → if/else, loop 구조 추론
lea주소 계산 → 포인터 연산, 구조체 접근 분석
int, syscall시스템 콜 → OS 함수 호출 여부 확인 (예: 파일 읽기, 네트워크 통신)

실전 활용 예시

  • call sub_401000 → 특정 함수 호출 → 어떤 기능을 하는지 추적
  • cmp eax, 0x1 / je 0x401050 → 조건 비교 후 분기 → 조건문 추론
  • push ebp / mov ebp, esp → 함수 시작부 → 함수 스택 프레임 구성
  • mov eax, [ebp-0x4] → 지역 변수 접근 → 변수 값 추적




🫧리버싱 분석 방식 및 대상

리버시에서 주로 사용하는 분석 방법은 크게 두 가지가 있음


정적 분석 [Static Analysis]🔬

실행하지 않고 바이너리를 그대로 분석하는 방법.
안전하고 빠르며, 분석자가 프로그램 흐름을 전반적으로 이해할 수 있게 해줌


🔹분석 방식

  • 디스어셈블리(Disassembly): 어셈블리어로 코드 구조 확인 (IDA, Ghidra 등)
  • 디컴파일(Decompiler): 고급 언어 형태로 코드 흐름 추정
  • 문자열 검색(strings), 헤더 정보 분석, 바이너리 뷰어 사용 등

🔹주요 분석 포인트

  • 코드 흐름 파악: call, jmp 등을 통해 함수 호출 관계 확인
  • PE 구조 확인: Entry Point, Section 구성, Import/Export Table 등
  • 리소스 분석: 내부 포함된 문자열, 이미지, 인증서 등

🔹장점

  • 실행하지 않으므로 악성코드 감염 위험 없음
  • 전체 구조를 빠르게 파악 가능
  • 샌드박스 환경 없이도 분석 가능

🔹한계

  • 난독화(Obfuscation), 압축(Packing)된 경우 분석이 어려움
  • 실제 런타임 행위는 보이지 않음 → 조건부 실행, 암호화된 코드 탐지 불가

예: UPX로 패킹된 악성코드는 정적 분석으로 보면 아무 내용도 안 나옴
→ 언패킹 없이 분석 불가



동적 분석 [Dynamic Analysis]⚙️

실제로 프로그램을 실행하면서 행위 기반으로 분석하는 방법
실행중의 메모리, 레지스터, 시스템 호출, 네트워크 동작을 추적할 수 있음


🔹분석 방식

  • 디버거 사용 (x64dbg, OllyDbg 등) → 브레이크포인트 설정, 레지스터 추적
  • 행위 모니터링 툴 (Procmon, Wireshark, API Monitor)
  • 샌드박스 분석 환경 (Cuckoo Sandbox, Any.run 등)

🔹주요 분석 포인트

  • 프로세스 생성 / 종료, 파일 읽기/쓰기, 레지스트리 접근 여부
  • 메모리 덤프 확인 → 복호화된 문자열, 코드 확보 가능
  • 조건부 실행 로직 확인 → 시간 지연, 특정 환경에서만 동작 등

🔹장점

  • 정적으로 보이지 않는 실제 실행 경로 및 조건 확인 가능
  • 은폐된 악성 행위, 암호화된 페이로드 추출 가능
  • 복호화된 문자열이나 메모리 위에 올라온 코드 분석에 효과적

🔹한계

  • 악성코드 실행으로 분석 환경 감염 위험 존재
  • 분석 대상이 탐지를 우회하거나 환경을 인식하면 분석 회피 가능
    → VM, 디버거 탐지 우회 기술 사용

예: 분석 환경에서 실행 시 아무런 동작을 안 하는 악성코드는,
실제 사용자 PC에서만 악성 행위를 실행하도록 설계되어 있음



구 분정적 분석동적 분석
실행 여부프로그램 실행 안함프로그램 실행함
분석 대상바이너리 파일실행 중 프로세스
장 점전체 구조 파악 가능, 탐지 위험 없음실제 동작 확인 가능, 숨겨진 동작 발견 가능
단 점난독화 대응 어려움, 동작 추론 한계환경 구축 복잡, 탐지될 수 있음
용 도코드 흐름 이해, 취약점 탐색악성 행위 분석, 디버깅



두 방식의 결합➕

대부분의 리버싱 작업은 정적 분석 + 동적 분석을 병행
정적 분석은 “지도 보기”, 동적 분석은 “현장 답사”에 해당

두 접근을 함께 써야 전체 구조와 실제 행위를 모두 이해할 수 있음

  • 정적으로 구조를 파악 → 동적으로 특정 지점 추적
  • 정적 분석으로 추측한 흐름을 동적으로 검증하는 방식



분석 대상: 실행 파일(PE구조)📄

Windows 환경에서 주요 리버싱 대상은 .exe, .dll파일 등이며, 이들은 모두 PE(Portable Excutable)포맷을 따름


🔹주요 분석 포인트

  • Entry Point: 실행이 시작되는 지점
  • Import Table: 어떤 외부 라이브러리(API, DLL 등)를 사용하는가
  • Section Header: 코드와 데이터가 어떻게 구분되어 있는가

이 구조를 이해하면, 어떤 코드가 실제로 실행되는지, 그리고 악성 코드가 삽입될 가능성이 있는 위치를 추적할 수 있음




🫧컴파일러와 디컴파일러


컴파일러 [Complier]

고급 언어(C, C++, JAVA 등)로 작성된 소스코드를 기계어(바이너리)로 변환하는 프로그램

  • 사람이 이해하기 쉬운 코드를 CPU가 실행할 수 있는 형태로 만들어 줌
  • 컴파일 과정에서 코드 최적화, 구조 변경 등이 일어남
  • 최종 산출물은 .exe,.dll,.elf 등 실행 가능한 파일



디컴파일러 [Decomplier]

바이너리 파일을 다시 고급 언어 형태로 역변환해 주는 도구

  • 완벽한 원본 소스코드를 복원하지는 못하지만, 코드 흐름과 로직을 이해하는데 도움이 됨
  • 변수명, 주석, 구조 정보는 사라지고, 함수 이름 등도 자동 생성됨
  • 리버싱 분석 시 가독성을 높이기 위해 많이 사용됨

구 분컴파일러디컴파일러
역 할고급 언어 → 기계어 변환기계어 → 고급 언어 형태 역변환
목 적실행 가능한 프로그램 생성분석 및 이해 용이성 제공
결과물정확하고 최적화된 바이너리근사치 코드, 원본과 차이 있음
한 계소스코드가 필요함완전한 소스 복원 불가
profile
나만의 공부 일지... [임시 休]

0개의 댓글