티스토리 뷰

Security/시스템 해킹

어셈블리어

on1ystar 2019. 1. 10. 04:29
728x90
반응형

Ø 어셈블리어


ü  개요

프로그래밍 언어의 하나로 기계어에서 한 단계 위의 언어이며 기계어와 함께 단 둘 뿐인 low level언어에 속합니다.


기계어 1라인당 어셈블리 명령어가 대부분 1라인씩 대응되어 있고 이를 비교적 간단하게 짤 수 있는 어셈블러를 통해 

기계어로 변환되도록 합니다. 때문에 고급 언어와 기계어 사이의 중간 언어라고 불리기도 합니다.( 어셈블러는 어셈

블리어를 기계어로 바꿔주는 프로그램입니다 )


이 어셈블리어는 통일된 규격이 없으므로, 모든 플랫폼에서 공통된 사항이 아닙니다. x86 CPU에서는 크게 인텔 방식

AT&T 방식으로 나뉘어 집니다. 인텔 방식은 가독성이 뛰어나고, AT&T 방식은 가독성은 떨어지나, 인텔 방식보다 

좀 더 많은 정보를 포함하고 있습니다.



ü  레지스터

컴퓨터의 프로세서 내에서 자료를 보관하는 아주 빠른 기억 장소입니다. 일반적으로 현재 계산을 수행중인 값을 저장

하는 데 사용됩니다. 대부분의 현대 프로세서는 메인 메모리에서 레지스터로 데이터를 옮겨와 데이터를 처리한 후 그 내용을 다시 레지스터에서 메인 메모리로 저장합니다.

 레지스터는 메모리 계층의 최상위에 위치하며, 가장 빠른 속도로 접근 가능한 메모리입니다.

 32비트 운영체제 앞에는 레지스터 앞에 E가 붙게 되고 64비트 운영체제 앞에는 R이 붙습니다. 물론 그 레지스터의 크기

64비트 운영체제의 레지스터가 32비트 운영체제의 레지스터 2배 크기입니다. 64비트 운영체제는 32비트 운영체제의 

프로그램을 모두 실행할 수 있는 반면 그 역은 성립되지 않습니다.

 

[범용 레지스터]

EAX(RAX)      :        누산기(Accumulator)로 주로 산술 연산에 사용

EBX(RBX)      :        베이스 레지스터로 특정 주소 저장

                           메모리의 주소 지정을 확장하기 위해 ESIEDI와 결합하여 인덱스로 사용될 수 있는 유일한 범용 레지스터입니다.

ECX(RCX)      :        카운트 레지스터로 반복적으로 실행되는 특정 명령에 사용

EDX(RDX)      :        데이터 레지스터로 입출력 연산에 사용하며 큰 수의 곱셈과 나눗셈 연산에서 EAX와 함께 사용

[포인터 레지스터]

EBP(RBP)      :        베이스 포인터로 스택 세그먼트에서 현재 호출되어 사용되는 함수의 시작 주소 값을 저장합니다. ( 

함수의 파라미터 지역변수의 주소를 가리키는 용도로 사용)

ESP(RSP)      :        스택 포인터로 현재 스택 영역에서 가장 하위 주소(스택의 최종점)를 저장합니다. EBP와 마찬가지

로 실제 메모리 상의 주소를 참조할 때 SS레지스터와 함께 사용됩니다.

EIP(RIP)        :        명령 포인터로 다음 명령어의 상대 위치 주소를 저장하며 CS레지스터와 합쳐져 다음에 수행될 명

령의 주소를 형성합니다.

[인덱스 레지스터] ( 여기까지 범용 레지스터로 칭하기도 합니다 )

EDI(RDI)       :        목적지 인덱스로 목적지 주소에 대한 값을 저장

ESI(RSI)        :        출발지 인덱스로 출발지 주소에 대한 값을 저장

둘은 주로 메모리의 한 영역에서 다른 영역 즉, source에서 destination으로 데이터를 연속적으로 복사할 때 사용됩니다.

ü  명령어

mov   : (mov DESTINATION, SOURCE) SOURCE위치에 들어있는 데이터를 복사하여 DESTINATION위치에 저장

lea     : (lea DESTINATION, SOURCE OPERLAND) SOURCE OPERLAND에서 지정된 주소를 DESTINATION으로 로드합니

. Lea의 주된 용도는 매개변수나 지역변수의 주소를 얻어 오는 것입니다.

add    : (add opr1, opr2) opr1opr2을 더해 opr1에 저장

sub    : (sub opr1, opr2) opr1opr2을 뺀 후 opr1에 저장

jmp    : (jmp proc) 프로그램의 흐름을 바꿀 때 사용하는 명령어로 proc의 주소로 가서 그곳의 명령어를 실행

cmp   : (cmp value1, value2

           조건 점프 명령어 ) 두 값을 비교해서 비교 결과가 같다면 start로 분기하고 같지 않다면 조건 점프 명령어를 실행합니다.

call     : 함수를 호출했다가 다시 원래 위치로 돌아올 때 사용합니다. Jmp와 다른 점은 실행한 뒤에 끝나게 되면 ret에 저장하고 다시 원래 상태로 돌아옵니다.

Ret     : 현재 함수가 끝난 뒤에 돌아갈 주소를 지정하기 위해 사용

Push   : 스택의 top에 데이터를 저장

Pop    : 스택의 top에서 데이터를 삭제

Leave  : 현재까지의 메모리 스택을 비우고 EBP에 자신을 호출한 메모리 주소로 채웁니다. 실행 중인 함수를 종료하기 

위해 정리하는 작업에 사용됩니다.

ü  어셈블리어로 디버깅



먼저 첫 번째 줄을 보면 가장 앞에 주소 값이 있습니다. 그리고 Main이라는 라벨이 있고뒤에 붙는 +숫자는 출력한 라벨에서 몇 바

이트 떨어져 있는지를 나타내 줍니다.

가장 처음으로 Main함수의 베이스 포인터를 지정하기 위해 ebp레지스터를 프로세스 스택 메모리에 push 해줍니다.

그 다음 ebp의 메모리주소를 스택 포인터(esp)에 옮기기 위해 mov를 해줍니다.

다음으로 4바이트 만큼의 주소 값을 esp에서 sub하는 명령이 나오는데 이는 int c를 메모리에 할당하기 위함입니다.

여기서 메모리를 할당하는데 왜 메모리 주소 값을 빼 줄까 라는 의문이 생길 수 있는데 이는 스택 영역의 프로세스 메모리 구조가 

아래 쪽이 상위 메모리 주소이고, 위쪽이 하위 메모리 주소이기 때문입니다. (출처 : http://tcpschool.com/c/c_memory_stackframe)


다음으로 연이어서 2바이트와 1바이트만큼을 push해주고 있는데 이는 function함수의 파라미터 값으로 2 1을 전달하기 위해 먼

저 메모리에 위치시키는 작업입니다.

그러면 이제 call 명령어를 통해 0x80483bc로 함수 콜을 합니다. 그러면 다시


이렇게 0x80483bc 주소에 다시 새로운 함수인 function 작업하기 위한 메모리 공간을 할당합니다.

이런 식으로 한 줄 씩 분석하며 스택에 변수나 함수들을 쌓아가며 디버깅을 합니다.


Reference

https://www.youtube.com/watch?v=YiXc3Mi3Jtc


728x90
반응형

'Security > 시스템 해킹' 카테고리의 다른 글

어셈블리로 구구단 짜기(nasm)  (1) 2019.04.02
RTL (Return to Libc)  (0) 2019.02.05
리버싱 실습(Easy_ELF)  (0) 2019.01.24
버퍼오버플로우 실습  (0) 2019.01.23
쉘 코드(/bin/sh  (0) 2019.01.16
댓글