[Reversing] 리틀 엔디언 표기법

(1) 바이트 오더링
-
바이트 오더링은 데이터를 저장하는 방식을 뜻함
-
이는 애플리케이션의 디버깅할 때, 알아두어야 하는 기본 개념 중 하나
-
빅 엔디언(Big Endian)과 리틀 엔디언(Little Endian) 두 가지 방식이 존재
예제 코드를 보면서 이해해보도록 하자.

총 4개의 크기가 다른 자료형이 있다.
각 엔디언 방식에 따라서 같은 데이터를 어떤 형식으로 저장하는지 비교해보도록 하자.
[표 1] 빅 엔디언과 리틀 엔디언 차이점
Type | Name | Size | 빅 엔디언 | 리틀 엔디언 |
BYTE | b | 1 | [12] | [12] |
WORD | w | 2 | [12][34] | [34][12] |
DWORD | dw | 4 | [12][34][56][78] | [78][56][34][12] |
char [] | str | 6 | [61][62][63][64][65][00] | [61][62][63][64][65][00] |
#참고
-
ASCII 문자 'a'는 0x61과 같고, 'e'는 0x65와 같음
-
그리고 문자열 마지막은 NULL로 끝이 남
바이트(BYTE) 타입의 b 변수를 저장할 때는 두 방식의 차이가 없지만, 2바이트 이상 크기를 가진 자료형을 저장할 때부터 차이가 나타난다.
빅 엔디언 방식은 데이터를 저장할 때 사람이 보는 방식과 동일하게 앞에서부터 순차적으로 저장한다.
하지만, 리틀 엔디언 방식은 데이터를 저장할 때 역순으로 저장한다.
즉, 저장되는 바이트의 순서가 뒤집어져 있다.
리틀 엔디언이라고 할지라도 바이트 자체는 정상적인 순서로 저장이 된다.
오로지 2바이트 혹은 4바이트 자료형과 같이 멀티바이트(multi-bytes)인 경우 각 바이트가 역순으로 저장되는 것이다.
또한 str 문자열은 Endian 형식에 상관없이 동일하다.
이유는 문자열이란 결국 캐릭터(char) 배열이기 때문에 각 바이트를 하나씩 연속해서 저장한다고 생각해보면 리틀 엔디언에서도 문자열 자체는 빅 엔디언과 동일한 순서로 저장되는 것이다.
1-1. 리틀 엔디언 & 빅 엔디언
-
데이터를 순서대로 저장시키는 빅 엔디언 장점은 사람이 보기에 직관적이라는 것
-
빅 엔디언은 대형 UNIX 서버에 사용되는 RISC 계열 CPU에서 많이 사용되며, 네트워크 프로토콜에도 사용
-
이것은 x86 계열의 응용 프로그램 개발자와 리버서에게 중요한 의미를 가짐
-
애플리케이션 개발에 사용된 데이터를 네트워크로 송수신할 때 엔디언 타입을 변경해야 하기 때문
바이트 오더링이 빅 엔디언으로만 사용된다면 굳이 설명이 필요 없을 것이다.
문제는 Intel x86 CPU에서 리틀 엔디언 방식을 사용한다는 것이다.
따라서 Windows 계열 리버서들은 리틀 엔디언에 대해서 잘 알고 있어야 한다.
데이터를 역순으로 저장시키는 리틀 엔디언 방식도 산술 연산과 데이터의 타입이 확장/축소 될 때 더 효율적이라는 장점을 가진다.
1-2. OllyDbg에서 리틀 엔디언 확인

코드를 빌드하여 LittleEndian.exe를 생성한 후 OllyDbg로 디버깅을 진행한다.

[그림 3]을 보면 main() 함수의 주소는 401000이다.
그리고 전역 변수들의 주소는 40AC40(b), 40AC48(w), 40AC48(dw), 40AC4C(str)이다.
이 메모리 영역을 OllyDbg의 데이터 창에서 살펴보겠다.
(Goto 명령[Ctrl+G]을 통해 40AC40으로 이동)

변수 w와 dw 값들이 리틀 엔디언 형식으로 저장된 것을 확인할 수 있다.
# Reference
'Reversing' 카테고리의 다른 글
[Reversing] Process Explorer (0) | 2020.03.26 |
---|---|
[Reversing] 스택 (0) | 2020.03.25 |
[Reversing] IA-32 Register (0) | 2020.03.25 |
[Reversing] OllyDbg 사용법 (0) | 2020.03.24 |
[Reversing] 리버스 엔지니어링이란? (0) | 2020.01.04 |