YeoPEVA
리버싱 핵심원리 6장, 7장 필기 및 정리 본문
리버싱 핵심원리 6장 및 7장 필기 및 정리 본입니다.
필기 할 때 정신줄 놓은 상태여서 그런지 혼잣말이 많네요 ㅎㅎ..
6. abex’s 크랙미 1 분석 | [코드엔진 문제 1번을 참고해주시면 감사하겠습니다.]
crackme -> 크랙 연습을 목적으로한 프로그램
[1]프로그램 테스트 및 분석 시작
실행 하고 나서 보며는 메시지 박스 출력이 되는데, 여기서
CD-ROM 인식을 시키게 만들어야함. [관련 API 호출 숙지]
소스코드가 매우 짧음.. [어셈블리로 개발 예상]
why?
-> VC++, VC , Delphi 등 개발툴을 사용하게 되면 소스코드 외에 컴파일러가 stub code를 추가,
디스 어셈블시 엄청 복잡해짐 [어쩐지 쓸데 없는거 엄청 많아보인다카더만..]
-> 어셈블리 언어 작성 | 어셈 코드가 곧 디스어셈 코드 | 군더더기 없는 직관적인 코드가 바로 어셈블리
언어로 등#장! [어셈블리 언어]
책과 함께 코드 분석 시작
[2] win32 API 중점으로 분석
MessageBox | GetDriveType() API -> C 드라이브 타입을 얻어옴 [대부분 HDD 리턴]
드라이브 타입 [CD-ROM]이면 클리어! [은근 간단한 것 같기도..]
PUSH – 스택 값 입력 | CALL – 지정된 주소의 함수 호출 | INC, DEC 값 1 증가, 감소
JMP – 지정된 주소로 점프 | CMP 주어진 두개의 operand 비교 [SUB랑 비슷하나 레지스터만 변경]
값 동일시 SUB 결과는 0, ZF가 1로 세팅 | JE – 조건 분기 [ZF - 1일시 점프] [ex]
[3]단순 크랙 -> JE short 부분 수정 | GetDriveType 반환 값 수정 해서 크랙 [EAX 리턴값 – 5 수정하면 END]
스택에 파라미터를 전달하는 방법 #
메시지박스 함수 호출 전에 4번 PUSH 명령을 통해 필요한 파라미터를 역순으로 입력하고 있음
-> 스택 메모리 구조 [역순으로 입력해야 올바른 순서로 꺼내는게 가능함]
+ 지식
메시지박스A() 주석 -> ESI 0xFFFFFFFF 세팅 | F8 통한 레지스터 값 확인을 통해 확인 가능
win32 API 호출시, 특정 레지스터 값이 변경되는 경우가 있음 | 주의바람
Garbage code -> 디버깅 방해 및 리버서 혼란
+ 외부 영향을 덜 받을 수 있는 조건 분기 명령어를 건들이자.
7. 스택 프레임
프로그램에서 선언되는 로컬 변수 및 함수 호출에 사용되는 스택 프레임!에 대해 알아보는 시간이라칸다.
함수 파라미터 및 함수 로컬 변수 등이 쉽게 파악 된다캄 [이해만 한다면요 ㅇㅁㅇ]
스택 프레임 – ESP [스택 포인터]가 아닌 EBP 레지스터를 이용하여 스택 내의 로컬 변수 및 파라미터, 복귀주소에
접근하는 기법을 말한다고 함. [ESP – 스택 포인터 / EBP – 베이스 포인터 역할]
스택 프레임을 이용해서 함수 호출 관리 -> 스택 완벽 관리 가능
PUSH EBP [함수 시작 [EBP 사용 전, 기존 값 스택 저장]
MOV EBP, ESP [현재의 ESP를 EBP에다가 저장함]
MOV ESP, EBP [ESP 정리 | 함수 시작했을때의 값으로 복원]
POP EBP [리턴 전 저장해 놓았던 원래 EBP 값으로 복원]
RETN [함수 END]
+ 최신 컴파일러 – 최적화 옵션으로 인해, 간단한 함수의 경우 스택 프레임 형성을 안함
+ 스택에 복귀 주소 저장 -> 보안 취약점 [BOF]
코드 참고 -> StackFrame.cpp
1. PUSH EBP
-> 값을 스택에 집어 넣는 명령 | EBP 값을 스택에 집어 넣자 | main() 함수에서 EBP가 베이스 포인터 역할
| 이전에 가지고 있던 값을 백업해두기 위해 사용합니다. [나중에 RETN 전에 회복 시킵니다.]
2.MOV EBP, ESP
-> MOV를 통해 데이터를 옮김 | ESP 값을 EBP로 옮김 | 스택에 저장된 함수 파라미터 및 로컬 변수들은
EBP를 통해 접근함 | main() 함수에 대한 스택 프레임이 생성됨
3. SUB ESP,8
로컬 변수 세팅 | esp 값을 빼주면서 로컬 변수 공간 확보 | long 타입 - 4바이트 [8바이트 크기 공간 필요]
그 후 EBP 값을 통해 -4, -8 이런 식으로 로컬 변수에 엑세스가 가능해진다.
MOV DWORD PTR SS:[EBP -4],1 [요로콤 말이죠]
MOV DWORD PTR SS:[EBP -4],2 [요로콤 말이죠!!]
[DWORD PTR ? -> 포인터 개념이라고 생각하면 편함]
[DWORD, WORD, BYTE] PTR SS:[EBP-4]
위에서 SS를 같이 표시하는 이유
windows에서 세그먼트 메모리 모델을 사용하기 때문에, 해당 메모리가 어떤 세그먼트에 소속되어 있는지
표시해주는 용도로 쓰임, 실제로는 32비트 win os에서 SS,DS,ES 값은 모두 0..
그래서 큰 의미는 없다만, EBP,ESP는 스택을 가리키는 레지스터들이라 SS 레지스터를 붙여준 것임.
[+ 옵션으로 DWORD PTR 및 SS 등의 문자열을 보이지 않게 하는 것이 가능]
그 후
인자 값을 EAX 및 ECX에 넣어주고, 함수를 호출시킨다. [전형적인 함수 호출 과정]
인자 입력 순서 [반대로 입력]
그 다음 복귀 주소 저장 [PUSH EBP 저장] | 반환 값 – EAX 저장 후 리턴
옵션 변경
디버깅 옵션에서 Option Dialog [Alt+O]
Disasm 탭에서 show default segments 항목 | Always show size of memory operands
항목 선택해제시 -> 세그먼트 표시 및 메모리 크기 표시가 사라지게 됨
+DWORD PTR이 그래도 있는 경우? -> 크기 해석이 모호할 경우
+Analysis1 에서
Show ARGs and LOCALs in procedures 항목 체크하면 EBP 표시되던 함수 로컬 변수와 파라미터가
[LOCAL,1] 및 [ARG,1] 형식으로 바뀜 , 가독성이 높아져 분석이 더욱 쉬워진다 ㅇㅇ…
'#Reversing > Reversing - 정리' 카테고리의 다른 글
쿠쿠 샌드박스 구축 (0) | 2019.03.14 |
---|---|
어셈블리어 - CMP, 그리고 JMP에 대해 알아보자! (3) | 2017.07.23 |
리버싱 핵심 원리 챕터1,2장 필기 및 정리 (0) | 2017.07.21 |
리버스 엔지니어링 - 전반적인 계획 (0) | 2017.07.21 |
올리디버거 색상 설정 (0) | 2017.07.19 |