2주차에는 유튜브 리버싱 강의를 4강~7강까지 학습하였다.
https://www.youtube.com/playlist?list=PLY12b4RRLcSdsxgVvTW3mnNzMjVrd8JhO
<레지스터>
목표: IA-32 Register에 대해 배워보자
1. CPU 레지스터
: CPU 내부에 있는 저장공간
→ CPU 내부에 있기에 데이터 연산속도가 매우 빠름(용량이 매우 작음)
2. 범용 레지스터(General Register): 일반적인 레지스터
- IA-32 4byte(reg size: 4byte)
범용 레지스터(General Register)의 종류
- EAX: 결과값을 저장하거나 피연산자를 축적
- EBX: 메모리 주소를 저장하기 위한 용도
- ECX: 반복문을 사용할 때 ECX loop count -1 감소
- EDX: 입출력 연산에 사용
→ 위의 4개의 레지스터는 산술 명령어에서 상수/변수 값이 저장되는 용도
- ESI, EDI: 문자열이나 각종 반복 데이터를 처리, 데이터를 복사할 때 사용
- EBP: 함수의 시작 주소 값 저장
- ESP: 스택 메모리 주소 저장
→ 위의 4개의 레지스터는 메모리 주소를 저장하는 포인터로 사용
- EIP: CPU가 처리할 명령어 주소
Ex) 0x123 mov eax, 1(Hex) EIP = 0x123
→ 다음 명령어가 실행될 때 0x123 주소에 있는 명령어가 실행됨
*참고 사항 (용량)
- EAX: 4byte
- AX: 2byte
- AH(High): 1byte
- AL(Low): 1byte → 다른 레지스터도 동일함
3. Flag Register
- 명령어의 실행 여부를 결정. (실행 조건)
- 명령어 수행에 따라 true(1), false(0)로 설정됨
- 32개의 개수가 있음.
1) Zero Flag(ZF): 연산 명령 후에 결과 값이 0이 되면 ZF가 1(true)로 설정됨
Ex) mov eax, 1
mov ebx, 1
sub eax, ebx
→ eax가 0이므로 ZF = 1
2) Oveflow Flag(OF): 부호가 있는 수(signed integer)의 오버플로우가 발생했을 때, 1로 설정됨
MSB(최상위 비트)가 변경되었을 때 1로 설정됨
3) Carry Flag(CF): 부호가 없는 수(unsigned integer)의 오버플로우가 발생했을 때 1로 설정됨
<스택>
스택(Stack): 메모리 내부에 스택 존재함
스택의 역할
1) 함수 내의 로컬 변수가 임시저장
2) 함수 호출 시 매개변수(파라미터) 전달
3) 복귀 주소 저장
스택의 특징
- FILO(First In, Last Out), LIFO(Last In, First Out) 구조
- 스택에서 ESP(스택 포인터)는 움직이고, EBP(ESP 값을 저장)는 움직이지 않음
<스택 프레임(Stack Frame)>
1. 스택 프레임(Stack Frame)
: EBP를 사용하여 스택 내의 변수나 파라미터 복귀 주소에 접근하는 기법
Ex) Assembly code
push ebp ; 함수 시작 EBP 값을 스택에 넣음(EBP 백업)
mov ebp, esp ; ESP의 값을 EBP에 넣음(ESP 백업)
. ; 함수 로직
. ; ESP는 변경 가능함 (EBP에 백업함)
mov esp, ebp ; ESP 복원
pop ebp ; EBP 복원
return ; 함수 종료
→ esp 값이 변해도 ebp를 기준으로 해당 변수나 매개변수, 복귀 주소에 안전하게 접근 가능
→ 스택에 값이 저장되는 것은 보안상 취약할 수 있음
→ 스택만 수정하면 주소 조작 등이 가능해지기 때문
<크랙미 실습>
목표: HDD를 CD-ROM으로 인식시키기 위해서는 GetDriveTypeA의 리턴값이 무엇이 되어야 하는가?
실습순서
(CodeEngn Basic RCE L01)
- 01.exe 파일을 실행했을 때 위의 메시지와 오류가 출력됨
- x32dbg에서 exe 파일을 열어서 구조를 확인, 에러 코드 뒤에 있는 “YEAH” 구문이 실행되면 목표 달성
01.exe 파일: cmp로 EAX와 ESI를 비교한 후 error 구문 혹은 성공 구문으로 이동하는 프로그램
→ cmp로 EAX와 ESI를 비교했을 때 둘이 같지 않아 ZF가 0 → error 구문 실행됨
- cmp: if문. 결과값이 0이거나 1임
- je: jmp equal, cmp로 비교하여 같으면 jmp
- jz: jmp zero, 값이 0일 때, jmp
- jmp: 조건 없이 jump
→ if Zero flag != 1, je/jz가 실행 안됨
1) 치트엔진
실행시키고 싶은 코드에서 change register at this location 클릭
EIP(CPU가 실행할 명령어)를 해당 주소값으로 변경하면 “YEAH” 구문으로 이동
메모리 변조되어 성공
2) x32dbg
je -> jmp로 변경하여 조건 없이 0x0040103D push 0로 이동함
메모리 변조됨
이외의 방법은 cmp를 바꾸어 비교할 값을 같게 만들기, cmp로 비교하는 두 값 ESP, ESI를 동일한 값이 되게 하기가 있음
'2. Reversing (리버싱)' 카테고리의 다른 글
[2024.11.02]리버씽씽이_4주차 활동 (4) | 2024.11.08 |
---|---|
[2024.10.26]리버씽씽이_3주차 활동 (0) | 2024.11.01 |
[2024.09.21] 리버씽씽이_1주차 활동 (5) | 2024.09.27 |
[2024.05.25] 리버씽씽카 7주차 활동 (0) | 2024.05.24 |
[2024.05.18] 리버씽씽카 6주차 활동 (0) | 2024.05.19 |