stxxp

간단한 바이너리 분석하기 본문

Hacking

간단한 바이너리 분석하기

stxxp 2020. 7. 12. 02:03

위 코드를 참고해 간단한 바이너리를 분석해봅시다. 

 

 

#스택 프레임(Stack Frame)

스택 프레임(Stack Frame)이란 RSP(Stack Point Register)와 RBP(Base Point Register)로 스택을 관리하는 기법을 말합니다. 

 

스택 구조

 

위 그림과 같이 스택은 먼저 RBP를 스택에 넣어주고 RSP를 RBP에 넣어줍니다.  

호출된 함수의 인자의 값만큼 RSP를 올린 후 RSP에 다시 RBP를 넣는 과정(RSP가 처음으로 되돌아감)을 반복하여 스택이 쌓이게 됩니다.

 

이 과정에서 RIP는 다음에 실행될 함수의 주소 값을 저장해둡니다. (실행이 계속되면서 RIP도 계속 바뀜)

 

 

다음과 같이 RBP에서 0x110을 뺀 값을 RAX에 저장하고 RAX를 함수의 첫 번째 인자로 이동시킵니다. 

마지막으로 EAX를 0으로 초기화하면 함수가 호출되는 것입니다.

 

 

 

 

 

 

 

#PLT & GOT

PLT(Produre Linkage Table)는 실제로 호출될 코드를 담고 있는 테이블입니다. 

 

PLT는 프로그램 외부에 있는 라이브러리에서 함수의 주소를 알아오는 역할을 하며 함수를 호출할 때 PLT는 GOT로 점프를 하게 됩니다.

 

 

이때 GOT(Global Offset Table)는 PLT가 실행할 코드를 가지고 있는 테이블입니다. (실제 함수의 주소가 담김)

 

만약 GOT에서 함수 호출이 첫 호출이라면 GOT에는 실제 함수의 주소가 쓰여있지 않아서 필요한 함수의 주소를 알아오는 과정을 거치고 알아낸 주소를 GOT에 저장합니다. 

 

두 번째 호출이라면 GOT에 실제 함수의 주소가 있으므로 해당 함수를 호출합니다.

 

위 사진에서 puts함수를 처음 호출하기 전, 함수의 주소 값이 어떤지 봅시다. 

 

함수를 호출하기 전에 puts 함수는 0x4005c0 이라는 주소를 갖지만 호출 후에는 0x7ffff7a7c690 이라는 주소를 갖게 되며 두 번째 호출부터 puts 함수를 가리키는 것을 볼 수 있습니다.  

 

PLT가 GOT를 참조해 함수를 호출하는 과정에서 프로그램의 외부에 있는 라이브러리를 통해 함수가 있는 주소를 먼저  알아오게 되므로 위와 같은 결과가 나온 것입니다.

 

따라서 우리는 PLT와 GOT를 통해 함수가 호출되었음을 알게 되었습니다.

 

 

 

 

 

 

 

#어셈블리 코드의 흐름 간단하게 분석하기

어셈블리 전체 코드

위 사진은 어셈블리의 전체 코드입니다.

 

 

맨 처음에 스택에 RBP가 들어오고 RSP를 RBP로 이동시키는 작업을 합니다.

 

그다음, RSP를 사용할 함수의 값만큼 위로 올려주고 PLT와 GOT가 함수를 호출하는 과정을 거쳐 EAX는 0으로 초기화되고 함수를 호출합니다. 

 

이후에 스택을 앞서 말한 작업을 반복해 필요한 함수를 호출하게 됩니다.

 

 

마지막으로 스택의 프레임을 해제하는 과정을 거칩니다.

 

 

 

 

 

 

 

#디버거 명령어

-----gdb명령어-----

간단하고 많이 사용하는 기초적인 명령어 위주

 

r (run) 바이너리를 실행합니다.
q (quit) 바이너리를 종료합니다.
disassemble [함수이름] 해당 함수의 어셈블리 코드를 출력합니다.
si (step into) 코드를 실행하다 함수를 만나면 함수 안으로 들어갑니다.
ni (next into) 코드를 실행하다 함수를 만나면 지나갑니다.
print [함수이름] 해당 함수의 주소를 출력합니다.
u 현재 루프를 빠져나갑니다.
b(*[주소]) (breakpoint) 해당 주소 또는 명령어가 실행된 후에 멈출 메모리 위치를 지정합니다.
finish 현재 함수를 실행한 후 빠져나갑니다.
return 현재 함수를 실행하지 않고 빠져나갑니다.
c (continue) 다음 브레이크 포인트까지 진행합니다.
watch [변수이름] 특정 변수에 와치 포인트를 걸어 변수가 바뀔 때마다 브레이크가 걸리고 이전값과 현재값을 출력합니다.
info locals 현재 스택의 로컬 변수를 모두 출력합니다.
info variables 현재 스택의 전역 변수를 모두 출력합니다.
info catch 함수의 예외 핸들러를 출력합니다.
p [변수이름] 해당 변수의 주소값을 출력합니다. (vlaue값)
x/[범위][출력형식][범위의 단위] [메모리주소 or 함수이름] 메모리 상태를 검사합니다.
stack [숫자] 해당 숫자만큼의 스택을 출력합니다.
up [숫자] 숫자만큼의 상위 스택프레임으로 이동합니다.
down [숫자] 숫자만큼의 하위 스택프레임으로 이동합니다.

 

'Hacking' 카테고리의 다른 글

Codegate 2018, BaskinRobbins31  (0) 2020.09.01
NX-bit 예제 풀기 (with ASLR ON)  (0) 2020.08.27
NX-bit 예제 풀기  (0) 2020.08.25
C언어 코드 분석  (0) 2020.07.02
C pointer 보고서  (1) 2020.06.24