Stack Corruption?
요즘에 쓰이는 buffer over flow의 말 스텍에 할당량 공간에 버퍼의 메모리를 넘치게 해서 메모리를 오염시킨다는 의미.
Kernel - os의 시스템 코드가 로드되는 부분
-- Off limit -- 사용자가 접근 못하도록 남겨둔 공간
Stack - 프로그램에서 사용되는 각종 환경변수, 파라미터, 리턴, 지역변수등 있는 공간
libc - 라이브러리가 이따..
Heap - 동적 할당되는 변수의 데이터가 위치하는 영역
BSS, Data - 프로그램에서 사용하는 전역변수, 정적변수 등 각종 변수들이 실제로 위치하는 메모리 영역.
변수가 초기화 = > Data 초기화 X = > BSS
Code - 실제 실행되는 기계어 명령어, 어셈블리 코드가 있는 곳, 프로그램 실행시 코드 영역에 있는 어세블리 코드가 해석되어 실행
(스택 쌓이는 구조는 안올렸는데...검색하세용 낄낄 ^ㅡ^)노양심
함수 프롤로그? 에필로그?
어셈블을 하면 보게되는 내용. 말그대로 시작부분과 끝부분을 지칭한다.
프롤로그에는
push EBP
mov EBP, ESP
이는 이전 함수의 Stack Frame의 시작점을 백업 하고 새로운 Stack Frame 을 생성하는 의미.
에필로그에는
mov ESP, EBP
pop EBP
Stack Pointer를 Caller Function 의 Stack Frame 시작 주소가 저장되어 있는 곳으로 변경하고 EBP를 원래대로 복구 하는것을 의미.
Stack Frame 시작점을 백업하여 함수가 끝나고 이전 함수로 넘어갈 때 base pointer 를 복원 시켜준다. 이때 push EBP 값이 sfp이다.
그리고 mov EBP, ESP 를 하여 이 함수가 끝나는 새로운 Stack Frame 을 생성한다.
mov ESP, EBP 를 해서 sfp가 저장되어 있는 곳으로 스택 포인터를 맞추고 그걸 POP EBP, sfp를 EBP에 빼내 이전 EBP를 다시 복구시켜준다.
그리고 ReTurn Address . Stack Frame Pointer 바로 밑에 있는 이전 함수의 리턴 주소를 EIP에 POP해서 복구.
함수 호출규약
cdecl - 부모쪽 에서 스택 복구
stdcall - 자식쪽에서 스택 복구
fastcall - 레지스터를 통해 인자 전달.
이거에 대해서는 머릿속에서 정확히 정리를 못했다. 다시 공부해야될듯..
Registers!
EIP - Extend instruction pointer :: 다음에 실행될 주소를 담고 있다.
EBP - Extend base pointer :: 함수로 전달되는 파라미터 또는 지역변수를 나타낼때의 기준.
ESP - Extend stack pointer :: 스택의 끝부분.
eip를 컨트롤 한다는것이 eip는 다음에 실행될 주소가 담겨 있다. 때문에 우리가 원하는 주소를 eip에 넣으면 거기로 건너뛰어 원하는것을 실행 가능 !
EAX - 대부분의 산술 연산에 사용되며, 함수의 반환값이 들어기도함.
EBX - 주로 주소 지정을 확장하기 위해 index로 사용된다.
ECX - 루프의 반복 횟수, 좌우방향의 쉬프트 수를 기억.
EDX - 곱, 나눗 셈에서 EAX와 같이 사용되며 부호 확장 명령 등에 쓰인다.
ESI / EDI - cpu가 현재 코드 세그먼트에서 다음에 실행할 명령어의 오프셋을 저장하는 32bit 레지스터이다.
데이터, 인덱스 레지스터이다. 걍 변수랜다. 그래도! 기억은 하자
gdb!
명령어에 대해 서술할 것이다!
gdb -q [이름] : gdb 온 !
run (r) : 바이너리 실행
continue (c) : 다음 브레이크 포인트까지 실행
quit (q) : 종료
disas [함수이름] : 특정 함수의 어셈블리 코드 출력
info
- function : 함수의 정보 출력
- break : 브레이크 포인트의 정보 출력
- del : 모든 브레이크 포인트 제거
- del [숫자] : 특정 브레이크 포인트 제거
- reg : 레지스터의 정보 출력
break (b * [ㅡㅡ] )
- function (main...add...기타등등 이름) : 함수에 브레이크 포인트를 건다. 함수 프롤로그 포함.
- address : 특정 주소에 break를 건다.
stepi (si) : 코드 한줄 실행. - 세부
nexti (ni) : 코드 한줄 실행. - 세부 x
print [function] (p) : 해당 함수 주소 출력
p $reg : 해당 레지스터 값 출력
x/[범위][출력형식][범위단위][메모리주소 나 함수명]
- x/[범위]i [address] : 특정 주소를 범위 만큼 어셈블리로 출력
- x/[범위]s [address] : 특정 주소를 범위 만큼 문자로 출력
- x/[범위]wx [address] : 특정주소를 범위만큼 16진수 4바이트 단위로 출력
set {type}[address] 특정메모리에 값을 지정 = set{int}0x000000 = 100
set $[reg] : 특정 레지스터에 값을 지정 = set $eip = 0x41414141
finsh : 현재 함수를 수행하고 빠짐
u : 현재 루프를 탈출
disas [address] [address] : 주소 사이의 어셈블리 코드를 출력
" 출처 : http://shayete.tistory.com/ "