0 views
1. 개요 및 정의
1.1 한 줄 요약
- 책을 읽을 때 왼쪽에서 오른쪽으로 읽는 문화권(영어, 한국어)과 오른쪽에서 왼쪽으로 읽는 문화권(아랍어)이 있듯이, 컴퓨터가 데이터(숫자)를 메모리에 기록할 때 앞쪽 바이트부터 쓸지 뒤쪽 바이트부터 쓸지 결정하는 규칙이다.
1.2 공식 정의
- 바이트 오더링(Byte Ordering)은 2 바이트 이상의 크기를 갖는 멀티 바이트 데이터를 메모리에 연속적으로 저장할 때의 바이트 정렬 방식을 의미한다.
- 이를 엔디안(Endianness)이라고도 부른다.
참고: 바이트 오더링은 비트(Bit)의 순서가 아닌 바이트(Byte) 단위의 순서를 제어하는 규칙이다.
2. 동작 원리
- 데이터
0x01234567(4 Bytes)을 메모리에 저장하는 상황을 가정하여 내부 동작을 설명한다.
2.1 주요 개념: MSB와 LSB (Byte Level)

- 바이트 오더링을 이해하기 위해서는 비트가 아닌 바이트 관점의 MSB와 LSB를 명확히 해야 한다.
- MSB (Most Significant Byte): 가장 큰 자릿수의 바이트 (왼쪽 끝,
0x01) - LSB (Least Significant Byte): 가장 작은 자릿수의 바이트 (오른쪽 끝,
0x67)
- MSB (Most Significant Byte): 가장 큰 자릿수의 바이트 (왼쪽 끝,
2.2 방식 비교: 빅 엔디안 vs 리틀 엔디안
| 구분 | 빅 엔디안 (Big Endian) | 리틀 엔디안 (Little Endian) |
|---|---|---|
| 저장 순서 | MSB부터 낮은 주소에 저장 | LSB부터 낮은 주소에 저장 |
| 직관성 | 사람이 숫자를 읽는 순서와 동일함 | 사람이 읽기에 역순이라 직관적이지 않음 |
| 주요 사용 | 네트워크 프로토콜, SPARC, RISC 일부 | Intel x86, x86-64 (대부분의 PC/서버) |
| 연산 장점 | 대소 비교가 빠름 (큰 자릿수부터 비교) | 산술 연산이 빠름 (캐리 처리가 쉬움) |
2.3 메모리 적재 예시
- 32비트 정수
0x01234567을 메모리 주소0x1000에 저장할 때의 차이는 다음과 같다.
-
빅 엔디안 (Big Endian)
- 낮은 주소(0x1000)에 가장 큰 바이트(0x01)가 먼저 들어간다.
Address | Value ------------------ 0x1000 | 0x01 (MSB) 0x1001 | 0x23 0x1002 | 0x45 0x1003 | 0x67 (LSB) -
리틀 엔디안 (Little Endian)
- 낮은 주소(0x1000)에 가장 작은 바이트(0x67)가 먼저 들어간다.
Address | Value ------------------ 0x1000 | 0x67 (LSB) 0x1001 | 0x45 0x1002 | 0x23 0x1003 | 0x01 (MSB)
3. 사용법 및 구문 (Syntax)
- C언어를 통해 문자열과 정수형 데이터가 메모리에 저장되는 차이를 확인함으로써 리틀 엔디안의 특징을 파악할 수 있다.
3.1 문자열 vs 정수형 데이터 저장 차이
- 문자열(String)
- 1 바이트 크기의 문자(
char) 배열이다. - 1 바이트 단위 데이터이므로 엔디안의 영향을 받지 않고 순서 그대로 저장된다.
- 1 바이트 크기의 문자(
- 정수(Integer)
- 4 바이트(32비트) 등의 멀티 바이트 데이터이므로, x86 아키텍처에서는 리틀 엔디안 방식으로 역순 저장된다.
3.2 검증 코드 (C Language)
#include <stdio.h>
#include <stdlib.h>
int main(void) {
// 1. 문자열 "ABCD" (ASCII: 0x41, 0x42, 0x43, 0x44)
// 문자열은 1바이트 배열이므로 엔디안의 영향을 받지 않음
char *str = "ABCD";
puts(str); // 출력: ABCD
// 메모리 덤프 가정:
// 낮은 주소 -> [0x41][0x42][0x43][0x44] -> 높은 주소
// 2. 정수 0x41424344
// 4바이트 정수는 리틀 엔디안에 의해 바이트 역순으로 저장됨
unsigned int num = 0x41424344;
printf("Integer Output: %x\n", num); // 출력: 41424344 (CPU가 읽어서 다시 정렬해 보여줌)
// 실제 메모리에 저장된 바이트 확인 (포인터 캐스팅 이용)
unsigned char *ptr = (unsigned char *)#
printf("Memory Dump: ");
for(int i = 0; i < 4; i++) {
printf("0x%x ", ptr[i]);
}
// 출력 결과: 0x44 0x43 0x42 0x41
// 설명: LSB인 0x44가 가장 낮은 인덱스(주소)에 저장됨
return 0;
}
4. 기타
4.1 시스템 해킹에서 페이로드 구성
- 만약 RET를 덮어쓰려고 할 때 아키텍쳐가 어떤 엔디언 방식을 사용하는지 보고 작성해야한다.
- 상황:
- 리턴 주소를
0x08048320으로 덮어씌워야 한다.
- 리턴 주소를
- 작성:
- 대상 시스템이 리틀 엔디안(x86)이라면, 페이로드는
\x20\x83\x04\x08순서로 작성해야 한다.
- 대상 시스템이 리틀 엔디안(x86)이라면, 페이로드는
- 실수:
- 만약
\x08\x04\x83\x20그대로 입력하면 엉뚱한 주소로 점프하여 공격에 실패(Segmentation Fault)한다.
- 만약
'Etc'카테고리의 다른 글
Loading comments...