HxD
헥스(Hex): 16진수로 표현된 이진 파일을 읽을 수 있게 보여줌
목적: 파일 및 프로그램의 내부 데이터 값 분석, 수정, 복구, 삭제 등에 사용
리버싱 (Reversing)
물건이나 기계장치 혹은 시스템 등의 구조, 기능, 동작 등을 분석하는 과정에서
그 원리를 이해하고 단점을 보완하며 새로운 아이디어를 추가하는 작업
= 완성품의 설계도 없이 구조와 동작 과정을 알아내는 모든 단계를 의미
과정
1. 소스 코드가 없는 상태에서 컴파일된 대상 소프트웨어의 구조를 여러가지 방법으로 분석
2. 메모리 덤프를 비롯한 바이너리 분석 결과를 토대로 동작 원리와 내부 구조 파악
3. 이를 바탕으로 원래의 소스가 어떻게 작성된 것인지 알아냄
-> 패치, 크랙, 게임 핵 제작 등에 이용됨
정적 분석 방법 (Static Analysis)
파일을 실행하지 않고 겉모습을 관찰하여 분석하는 방법
파일 종류나 크기, 헤더(PE) 정보, API, 내부 문자열, 실행 압축 여부, 등록 정보, 디버깅 정보, 디지털 인증서 등의 다양한 내용을 확인하는 것
동적 분석 방법 (Dynamic Analysis)
파일을 직접 실행시켜 분석하고 디버깅을 통해 코드 흐름과 메모리 상태 등을 자세히 살펴보는 방법
파일, 레지스트리, 네트워크 등을 관찰하면서 프로그램 행위 분석
디버거를 이용하여 프로그램의 내부 구조와 동작 원리 분석 가능
ASCII
미국 국립 표준 협회(ANSI)에서 표준화한 정보교환용 7비트 부호체계
"33개의 출력 불가능한 제어 문자 + 95개의 출력 가능한 문자"
- 0x00(0), NUL : 널 문자 (\0)
- 0x0A(10), LF : 개행(Line Feed), 줄바꿈
- 0x0D(13), CR : 복귀(Carriage Return)
- 0x00 ~ 0x1F, 0x7F(0~31, 127) : 제어문자 또는 비인쇄 문자
- 0x20(32) : 스페이스(공백)
- 0x21 ~ 0x2F(33~47), 0x3A ~ 0x40(58~64), 0x5B ~ 0x60(91~96), 0x7B ~ 0x7E(123~126) : 특수 문자
- 0x30 ~ 0x39(48~57) : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 숫자
- 0x41 ~ 0x5A(65~90) : A부터 Z까지 알파벳 대문자
- 0x61 ~ 0x7A(97~122) : a부터 z까지 알파벳 소문자
파이썬으로 아스키코드 변환
ord() : 하나의 문자에 해당하는 아스키코드 값(정수)으로 변환
chr() : 아스키코드 값(정수)을 받아 문자로 변환 (10진수, 16진수 사용가능)
Byte Order
엔디안 (Endianness) : 컴퓨터 메모리와 같은 1차원 공간에 여러 개의 연속된 대상을 배열하는 방법
빅 엔디안(Big-endian)
최상의 바이트(MSB - Most Significant Byte)부터 차례로 저장하는 방식
Big-endian 예시
1. 32비트 크기의 정수를 가정
0x12345678
2. 이 정수는 아래와 같이 1바이트 값 4개로 구성
0x12 0x34 0x56 0x78
3. 4개의 1바이트 값을 빅 엔디안 방식으로 저장

리틀 엔디안(Little-endian)
최하위 바이트(LSB - Least Significant Byte)부터 차례로 저장하는 방식
Little-endian 예시
1. 32비트 크기의 정수를 가정
0x12345678
2. 이 정수는 아래와 같이 1바이트 값 4개로 구성
0x78 0x56 0x34 0x12
3. 4개의 1바이트 값을 리틀 엔디안 방식으로 저장

Memory Structure
Memory: 프로그램 실행을 위해 컴퓨터의 운영체제에서 할당하는 공간
RAM(=주기억장치, 메모리)
- 자유롭게 읽고 쓸 수 있는 기억장치
- 사용 중인 프로그램이나 데이터가 저장됨
- 휘발성 메모리
ROM
- 내용을 읽을 수만 있는 기억 장치
- 변경 가능성이 없는 시스템
- 소프트웨어를 기억시키는 데 이용
- 비휘발성 메모리
메모리 공간은 Stack, Heap, Data, Code(text) 4개의 영역으로 나눌 수 있음
1. Stack 영역
함수 호출과 관계되는 지역변수, 매개변수가 저장되는 영역
함수 호출과 함께 할당되며, 호출 완료되면 소멸
- 스택 프레임: 스택 영역에 저장되는 함수 호출 정보
- 푸시(push): 데이터 저장
- 팝(pop): 데이터 인출
- 방식: 후입선출(LIFO, Last-In First-Out)
-> 가장 늦게 저장된 데이터가 가장 먼저 인출 - 메모리의 높은 주소 -> 낮은 주소 방향으로 할당
2. Heap 영역
사용자가 직접 관리하는 메모리 영역
사용자에 의해 메모리 공간이 동적 할당 및 해제
- 방식: 선입선출(FIFO, Fast-In First-Out)
-> 가장 먼저 저장된 데이터가 가장 먼저 인출 - 메모리의 낮은 주소 -> 높은 주소 방향으로 할당
3. Data 영역
프로그램의 전역 변수와 정적 변수가 저장되는 영역
프로그램 시작과 함께 할당되며, 종료 시 소멸
4. Code 영역
실행할 프로그램의 코드가 저장되는 영역
텍스트(text) 영역이라고도 부름
CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리
Instruction Cycle
기계 코드가 실행되는 한 번의 과정

Fetch: 다음 실행할 명령어를 읽어옴
Decode: 읽어온 명령어 해석
Execute: 해석한 명령어 실행
컴퓨터 구조

CPU (중앙처리장치): 프로그램을 실행하고 입력된 데이터를 처리
Memory (주기억장치): 실행 중인 프로그램(=프로세스)와 프로그램 실행에 필요한 데이터를 일시적으로 저장
Disk (보조기억장치): 프로그램과 데이터를 영구적으로 저장
프로그램: 컴퓨터를 실행시키기 위해 차례대로 작성된 명령어 모음
프로세스: 정적 프로그램이 메모리에 올라와서 실행 가능해진 상태
레지스터: CPU에서 명령어를 실행하는 동안 필요한 정보를 저장하는 기억 장소
레지스터의 개수와 크기는 CPU 종류에 따라 다르고, 목적에 따라 레지스터 종류가 나눠짐(전용, 범용)
범용 레지스터 (General Register)
- 연산을 하거나 자유롭게 사용이 가능함(필요에 따라 자유롭게 사용하도록 CPU가 제공)
- 특정 용도 이외에도 자유롭게 사용할 수 있음
| EAX | 산술 연산 및 논리 연산 수행 | |
| EBX | 메모리 주소 저장 | |
| ECX | 반복문 사용시 반복 카운터로 사용 반복할 횟수 지정하고 반복 작업 수행 |
|
| EDX | EAX 레지스터와 같이쓰임 부호 확장 명령 등에 사용 큰 수의 곱셈 또는 나눗셈 연산 |
|
| EDI | 복사할 때 목적지 주소 저장 | 주로 메모리 주소저장 |
| ESI | 데이터를 조작하거나 복사할 때 데이터의 주소 저장 | |
| ESP | 메모리 스택의 끝 지점 주소 포인터 | |
| EBP | 메모리 스택의 첫 시작 주소 포인터 |
EIP(Extended Instruction Pointer, 명령어 포인터 레지스터)
- 용도가 엄격하게 정해져 있으며, 다음에 실행될 명령어가 위치한 주소를 가리킴
- 레지스터에 어떤 값이 저장되어 있는지 파악하는 것이 리버싱에 도움이 됨
어셈블리어
Intel & AT&T
서로 호환되지 않는 문법을 지님
| Intel | AT&T | |
| 레지스트리 표현 | eax | %eax |
| 상수 표현 | h(16진수), b(2진수), o(6진수) ex) 80h |
$숫자 ex) $0x80 |
| operands 위치 | <instr> <dest> <src> | <intr> <src> <dest> |
| 메모리 주소 참조 | [eax] | (%eax) |
| 레지스터+offset 위치 | [eax+숫자] | 숫자(%eax) |
Intel Syntax: <명령어> <피연산자1> <피연산자2>;주석
ex) mov eax, 5
- 데이터 이동
- mov a b: b(데이터)를 a로 복사
- lea a b: b(주소)를 a에 저장
- ex)
lea eax, [ebx+8] => EBX+8을 EAX에 저장함
mov eax, [ebx+8] => EBX+8 주소에 저장된 값을 EAX에 복사
- 스택 조작
- push a: a(레지스터)의 값을 스택에 저장
- pop a: 스택의 값을 a(레지스터)로 가져옴
- 연산
- inc a: a의 값을 1 증가
- dec a: a의 값을 1 감소
- add a b: a에 b를 더함 (a+=b)
- sub a b: a에서 b를 뺌 (a-=b)
- 흐름제어
- jmp a: a(주소)로 가서 명령어 실행
- cmp a b: a와 b를 비교. 이후 분기문이 나옴. 조건 점프 명령어나 조건 이동 명령어와 사용
- je(jump equal) a: 비교한 값이 같으면 a(주소)로 가서 명령어 실행
- jne(jump not equal) a: 비교한 값이 다르면 a(주소)로 가서 명령어 실행
- 프로시저
- call A: A함수를 call하고 그 주소로 제어를 옮김. EIP를 변경시킴
- ret: Return. 호출된 함수에서 호출한 함수로 복귀. ESP에 있는 값을 꺼내 EIP에 할당
How to Reverse Engineering?
도구
Debugger
: 중간에 Breakpoint(중단점)을 잡고 그때의 레지스터 값을 관찰하며 소프트웨어를 분석하기 위해 사용
OllyDbg(Win GUI, x86)
F2: Breakpoint 선택/해제
F9: 실행
Ctrl+F2: 처음으로 돌아가서 재시작
x64Dbg(Win GUI, x64)
F2: Breakpoint 선택/해제
F9: 실행
Ctrl+F2: 처음으로 돌아가서 재시작
gdb, pwndbg(Linux CLI)
GDB(GNU Debugger): 리눅스용 대표 디버거
Pwndbg: GDB의 플러그인 중 하나, 바이너리 분석
gdb <프로그램명>: 프로그램 gdb로 실행
set diassembly-flavor intel: 디스어셈블리 문법을 intel로 설정
disass <함수명>: 해당 함수의 어셈블리 코드 보기
-> disass main: 메인 함수 어셈블리 코드 보기
b * <메모리 주소> or <함수명>+nn:
특정 메모리 주소 또는 <함수명>+nn에 breakpoint 설정
r: run(처음부터 실행)
c: continue (breakpoint 이후로 실행)
q: quit (디버거 종료)
x/print 명령어
x 명령어는 프로그램 실행 시 메모리를 검사할 때 사용
형식: (gdb) x/옵션 기준점

ex) 메모리 주소가 0x8048200 일 때
(gdb) x/10b 0x8048200: 1byte단위로(b) 10개의 값을 보여준다.
0x7f5bfff2324c: 0x30 0x30 0x37 0x34 0x39 030 0x38
0x7f5bfff23254: 0x5f 0x64
(gdb) x/4bx $esp: esp를 기준으로 16진법(x)으로 1바이트 단위(b) 4개 보여준다.
0xbfffedf8 : 0x41 0x41 0x41 0x41
과제 1) 리버싱 기초 문제 (Window)
rev-basic-0 풀기
https://dreamhack.io/wargame/challenges/14/


x64dbg chall0.exe 파일 열기
scanf 역할하는 부분 -> sub_7FF7523A11F0
문자열 비교 함수 -> sub_7FF7523A1000

sub_7FF7523A1000 분석 결과
Compar3_the_str1ng 확인
과제 2) int_reversing, string_reversing 풀기
int_reversing 답: 326


main함수가 시작되고 int형식의 두 변수가 선언되면서 스택에 쌓임
int correct_num -> DWORD PTR [rbp-0xc],0x146
16진수 형태인 0x146를 10진수로 변환 => 326
string_reversing 답: Hacked_By_ISly


char correct_string -> movabs rax,0x425f64656b636148 / movabs rdx,0x796c53495f79
x86-64는 리틀 엔디언이므로
0x425f64656b636148 -> 48 61 63 6b 65 64 5f 42
아스키코드 변환 => Hacked_B
0x796c53495f79 -> 79 5f 49 53 6c 79
아스키코드 변환 => y_ISly
합치면 Hacked_By_ISly
'동아리' 카테고리의 다른 글
| 9) 암호와 네트워크 해킹, 컴퓨터 구조 정리 (0) | 2026.05.29 |
|---|---|
| 8) 포너블 (1) | 2026.05.21 |
| 중간세미나 요약 (0) | 2026.05.01 |
| 4) SQL Injection, 파일 업로드 취약점, XSS, CSRF (0) | 2026.04.10 |
| 3) 리눅스 개념 정리 및 OverTheWire 풀이 (1) | 2026.04.03 |