개요
* Easy_CrackMe.exe 실습 리뷰 및 Easy_KeygenMe.exe 파일 실습
1. 디스어셈블리 상세 기능
- 스택 프레임 및 함수 호출 규약의 이해
- 동적 디버깅 사용 및 코드 실행
- 데이터 타입과 데이터 구조
- 기본 데이터/코드 변환
2. 스택/힙 할당 배열 및 구조체 접근
목차
0. Easy CrackMe 실습 이어서
1. 스택 프레임(stack frame)이란?
2. 레지스터: ESP, EBP, EIP, ECX, EAX
3. 어셈블리어: CMP, LEA, TEST
4. Debugger
[Review] (2주차) 실습 - Easy CrackMe (1)
2022.06.12 - [IDA Pro] - IDA Pro 악성코드 정적분석 툴 사용법&실습 - week.02(Easy_CrackMe) (1)
0. Easy CrackMe 실습 이어서
- 성공 시의 메시지 출력(Congratulation !!)
- 실패 시의 메시지 출력(Incorrect Password)
.text:004010B0 cmp [esp+68h+var_63], 61h ; 'a'
.text:004010BD push offset Str2 ; "5y"
.text:004010D1 mov esi, offset aR3versing ; "R3versing"
.text:0040110D cmp [esp+68h+String], 45h ; 'E'
strcmp: 문자열 비교 함수
strncmp: strcmp + n(검사할 문자의 개수 지정)
형태: char * strncmp( const char *s1, const char *s2, size_t n);
1. 스택 프레임(stack frame)이란?
스택에 할당된 메모리 블록, 호출된 함수에 지정
함수가 호출되면,
1) 함수 호출자가 파라미터 형태로 정보를 넘겨줄 때 어딘가에 저장되고, 호출된 함수가 정보를 찾게 해야 한다.
2) 함수의 작업을 위한 임시 저장소가 필요하다.
* 스택: 제한적으로 접근할 수 있는 자료 구조(LIFO, Last In First Out)
* 임시 저장소: 주로 지역 변수가 사용, 함수가 종료되면 더 이상 접근 불가
2. 레지스터: ESP, EBP, EIP, ECX, EAX
예제
32비트 x86 기반 컴퓨터의 컴파일된 함수 코드
void bar(int j, int k); // 호출할 함수
void demo_stackframe(int a, int b, int c) {
int x;
char buffer[64];
int y;
int z;
// 스택 프레임 테스트 용도 외에는 다른 목적이 없는 함수
bar(z, y);
}
지역 변수에 최소 76바이트(3개의 4바이트 정수, 64바이트 버퍼)가 필요
변수 | 오프셋 | ESP 기반 스택 프레임 |
z | [esp] | 지역 변수 |
y | [esp+4] | |
buffer | [esp+8] | |
x | [esp+72] | |
저장된 eip | [esp+76] | |
a | [esp+80] | 파라미터 |
b | [esp+84] | |
c | [esp+88] |
모든 오프셋은 ESP가 바뀜에 따라 다시 조절
변수 | 오프셋 | EBP 기반 스택 프레임 |
z | [ebp-76] | 지역 변수 |
y | [ebp-72] | |
buffer | [ebp-68] | |
x | [ebp-4] | |
저장된 ebp | [ebp] | 저장된 레지스터 |
저장된 eip | [ebp+4] | |
a | [ebp+8] | 파라미터 |
b | [ebp+12] | |
c | [ebp+16] |
개념 정리
* E: Extended(16bit → 32bit system), 64bit에서는 R로 표현
ESP(stack pointer register)
: 현재의 스택 지점(stack의 가장 아래 부분), 스택의 크기를 조정할 때 사용
- 스택에 값을 넣을 때마다 ESP가 4만큼 줄어듦
EBP(base pointer)
: 프레임 포인터를 사용하는 함수를 가리킴(함수가 프레임 포인터를 쓰는지 여부의 분석이 필요할 때, 이 속성을 이용해 수작업으로 지정 가능 - 레지스터의 크기 보정 필요)
- 스택의 가장 윗 부분, 스택 프레임 형태로 저장된 함수의 지역 변수나 전달인자를 참조/변경시 사용하는 레지스터
- 고정적, 코드 유지에 용이(스택프레임 생성시)
EIP(instruction pointer)
: 실행할 명령의 주소
3. 어셈블리어: CMP, LEA, TEST
1) .text:004010B0
디스어셈블리 코드 | 설명 |
.text:00401080 var_63 | 스택 프레임에서 바로 참조할 수 있는 모든 변수의 목록을 변수 크기와 프레임 포인터에서 떨어진 거리와 함께 요약해 보여줌 |
.text:00401080 sub esp, 64h | 스택 프레임에 지역 변수를 위한 98바이트(64h 대략 환산) 할당 |
.text:004010B0 cmp [esp+68h+var_63], 61h | dest == source 이면 ZF(Zero Flag) = 1, CF(Carry Flag) = 0 |
CMP
cmp [esp+68h+var_63], 61h: esp+68h+var_63의 값이 61h 위치에 있는 값과 같은지 비교(값을 빼서 비교)
LEA
lea edi, [esp+68h+var_63]: esp+68h+var_63에 저장된 주소를 esp에 저장
2) .text:004010BD
ECX(Extended Counter Register)
: 주로 반복 명령어 사용시 반복 카운터로 사용
EAX(Extended Accum ulator Register)
: 산술(덧셈, 곱셈, 나눗셈 등) 논리 연산을 수행할 때 사용, 함수의 반환값이 이 레지스터에 저장
TEST
: 인수1과 인수2 내용을 AND 연산하여 결과가 0이면 ZF = 1로 설정(보통 NULL check할 때 사용)
(두 operand가 0이 아닌 경우를 제외하고는 값을 판별하기 어려움 → eax, eax와 같은 형태로 사용하여 0인지 아닌지 확인)
3) .text:004010D1
4) .text:0040110D
주소 | 해당 문자열 | ESP 스택 포인터 | 10진수 변환 | 순번 |
.text:004010B0 | a | [esp+68h+var_63] | [esp+5] | 2 |
.text:004010BD | 5y | [esp+6Ch+Str1] | [esp+10] | 3 |
.text:004010D1 | R3versing | [esp+70h+var_60] | [esp+16] | 4 |
.text:0040110D | E | [esp+68h+String] | [esp+4] | 1 |
∴ 참조 순서: E - a - 5y - R3versing
4. Debugger
options: No debugger / Local Bochs debugger / Local Windows debugger / PIN tracer
Remote GDB debugger / Remote Windows debugger / Trace replayer / Windbg debugger
어셈블리 코드 파악을 위한 Local Windows debugger
[Next] (4주차) 실습 - Easy KeygenMe
2022.07.04 - [Security & Analysis/IDA Pro] - IDA Pro 악성코드 정적분석 툴 사용법&실습 - week.03(Easy_KeygenMe)
'Security & Analysis > IDA Pro' 카테고리의 다른 글
[IDA Pro] 악성코드 정적분석 툴 사용법&이론 - week.04(전 과정 Review) (0) | 2022.07.19 |
---|---|
[IDA Pro] 악성코드 정적분석 툴 사용법&실습 - week.03(Easy_KeygenMe) (0) | 2022.07.04 |
[IDA Pro] 악성코드 정적분석 툴 사용법&실습 - week.02(Easy_CrackMe) (1) (0) | 2022.06.12 |
[IDA Pro] 악성코드 정적 분석 툴 사용법(기본 개념 이론) - week.01 (0) | 2022.05.22 |
[Contents] IDA Pro Tutorial & Practical Malware Analysis (0) | 2022.05.18 |