Debugger의 종류
GUI 환경
- OllyDBG
- Immunity Debugger
파이썬에 사용할 때 유용
OllyDBG와 IDA-PRO의 장점을 다 가져와 만든 디버거
- ghidra
제일 최신의 디버거
다른 디버거에 비해 무겁다.
- IDA-PRO
파이썬에 사용할 때 유용
유료버전
다른 디버거에 비해 무겁다.
- x64 dbg
64비트에서 전문적으로 사용되는 디버거
다른 디버거에 비해 무겁다.
CLI환경
- gdb
명령 창이라 보기 힘든 것을 보완하기 위해 PEDA 플러그인을 사용한다.
- windbg
Immunity Debugger 환경
단축키
Ctrl + G //주소의 위치로 이동 가능.
F7 //내부 들어가서 실행
F8 //내부 코드 전부 실행하고 넘어가기
F4 //선택한 지점 전까지 실행.
F9 //프로그램 끝까지 실행
Ctrl + F2 //재시작
F2 // Software Breakpoint
Breakpoint를 설정해 놓으면, 그 지점까지 실행이 된다. 따라서 Breakpoint를 걸고 재시작하고 다시 시작하면 Breakpoint까지 실행이 된다. (일종의 보험)
명령 수정
데이터 부분은 Space 바를 통해 수정 가능
레지스터 부분은 Enter키를 통해 수정 가능
스택 부분 Ctrl + e 키를 통해 수정 가능
데이터 부분에서 CALL 같은 함수의 안을 보고 싶을 때 Enter키 사용
entry point
가장 먼저 실행할 명령어
값이 변경될 수 있다.
startup() 함수가 main 함수를 호출한다. 즉, 함수의 시작은 main이라 할 수 없다.
하지만 개발자가 시작하는 부분은 main함수부터이기 때문에 시작이라 말할 수도 있다.
startup 함수를 분석하는 것은 시간낭비가 될 수도 있다.
main() 함수부터가 개발자가 만든 코드이기 때문에 main부터 분석하는 것이 효율적이다.
winmain()이라는 함수가 시작되는 부분이다.
F7을 통해 내부 함수로 들어간다. (winmain에 대한 함수 명령어들이다.)
visual 6.0
Maximize Speed와 Minimize size 최적화 때문에 해석하기 어렵다.
Default, Disable은 쉽게 해석된다. (리버싱 초심자들이 사용하기 편함.)
위와 같이 설정한 후,
F7로 빌드
폴더에 아래와 같이 생성되면, test.exe파일을 디버거를 통해 실행.
오른쪽 네모 박스를 통해 개발자 코드 시작 부분을 알 수 있다.
메인 함수의 argument가 3개여서 envp , argv , argc 순으로 3개의 PUSH가 일어나고, 마지막으로 main CALL을 통해 호출이 되는 것이다.
CALL test.00401000의 의미
push return address(004010 D7) //리턴 값을 PUSH 하고
mov eip, 00401000 //00401000이라는 주소를 eip에 넣는다.
PUSH EBP 다음 지역변수 설정이 나온다.
위의 명령이 실행되면서 스택에 저장되는 구조이다.
variable(지역변수) |
EBP |
return address |
ARG1 (argc) |
ARG2 (argv) |
ARG3 (envp) |
3번째 부분 SUB ESP, 8을 하는 이유는 코드에서 int형을 2번 잡았기 때문에 지역변수 크기 8byte를 빼는 것이다.
즉, 이 함수가 사용할 총사이즈이다. 8 //char만 선언 시 1byte지만 내부 안에서는 4바이트로본다.
EBP의 값은 끝나기 전까지 변하지 않는다.
시작 과 끝부분
아래 세 가지 명령은 함수가 시작할 때 스택의 공간을 확보하기 위해 나오는 코드이다.
PSH EBP
MOV EBP, ESP
SUB ESP,8 //이 문장은 있을 수도 없을 수도 있다.
이제 스택이 개발자의 코드값을 넣을 준비가 된 것이다.
함수가 끝나는 부분도 역시 아래 명령 3가지가 나온다. 시작 부분과 반대
RETN
POP EIP 만 수행
RETN 0C
POP EIP
ADD ESP,0C 2가지 수행
즉 현재 exe의 코드는 분석해보면 RETN명령 후, ADD ESP, 0C를 하는데 RETN 0C가 나오면 한 번에 처리한다.
MOV ESP, EBP
POP EBP를 했을 때
RETN //CALL로 넣었던 주소가 나온다.
아래 함수 까지가 함수다. 이 함수는 썼던 명령들을 다시 되돌리는 작업이다.
개발자 코드 부분
PTR : 포인터
[ ] : 주소를 의미
SS : Segment Selecter Stack을 의미
DS : 주소라는 것을 의미한다.
Segment Selecter
MOV DWORD PTR SS:[EBP-8] , 0A
//int a = 10; EBP의 -가 붙으면 지역변수이다. 이제부터 EBP -8은 a라는 이름을 붙인다.
MOV DWORD PTR SS:[EBP-4] , 0A
//int b = 10; 이제부터 EBP -4은 b라는 이름을 붙인다.
MOV EAX,DWORD PTR SS:[EBP-8]
// a의 값을 EAX의 저장 a
ADD EAX,DWORD PTR SS:[EBP-4]
// a+b의 값을 EAX의 저장 a+b
MOV DWORD PTR SS:[EBP-8],EAX
// a = a+b
XOR EAX,EAX
// return 0을 의미
'악성코드 분석' 카테고리의 다른 글
패스워드 알아내기 (0) | 2019.06.04 |
---|---|
quiz를 통해 익숙해지기 (0) | 2019.05.22 |
어셈블리어 로 test.cpp 해석 (0) | 2019.05.21 |
기초지식(스택) (0) | 2019.05.16 |
기초지식 (레지스터와 어셈블리어) (1) | 2019.05.15 |