본문으로 바로가기

어셈블리 프로그래밍 심화 및 CPU 구조

category Pwnable 2018. 7. 4. 14:38

1. C언어 와 어셈블리어


주소 vs 메모리


C언어

- 포인터: 메모리에 대한 직접 접근이 가능하다.

어셈블리어

- 변수를 선언해서 사용하지 않는다.

- 메모리를 직접 사용한다.(레이블)


1) 주소

- 단순히 메모리 상의 위치이다.

- 파일 offset과 동일한 용어이다.

- 정수이다.


2) 메모리

- 데이터가 들어있는 실제 메모리를 의미한다.

- size [주소]: 주소에 해당하는 메모리(값)를 나타낸다.


c언어 -> 어셈블리어


1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
int a;
int b;
 
int main()
{
    scanf("%d"&a);                // &a -> 주소
    scanf("%d"&b);                // &b -> 주소
 
    printf("a: %d\n", a);            // a -> 메모리
    printf("b: %d\n", b);            // b -> 
}
 
cs


위의 C언어를 어셈블리어로 바꾸면 아래와 같이 나타낼 수 있다.



2. CPU 구조


INTEL IA32 Architecture

- instruction set

- register


1) Register

- cpu가 사용하는 아주 빠른 기억 저장소

- cpu가 사용하는 고속의 기억 장치


a. 범용 레지스터 : EAX, EBX, ECX, EDX (AH 상위 16bit, AL 하위 16bit)


EAX(Extended Accumulator Register)

EBX(Extended Base Register)

ECX(Extended Counter Register)

EDX(Extended Data Register)


b. 포인터 레지스터: ESI, EDI, EBP, ESP, EIP


모두 주소를 가지고 있다.


ESI(Extended Source Index)

EDI(Extended Destination Index)

EBP(Extended Base Pointer)

ESP(Extended Stack Pointer)

EIP(Extended Instruct pointer)


c. 플레그 레지스터: EFLAGS


0~31까지 32비트로 이루어져 있다.

해당 프로세스에 대한 상태 정보를 가지고 있다.


d. 세그먼트 레지스터: CS, DS, SS, ES, ....


E가 앞에 붙어 있으면 32bit, E가 없으면 대다수 16비트이다.


e. 처리속도


레지스터 >> 메모리(주 기억장치) >> 보조 기억 장치 (디스크, usb)


2) 명령어


a. 데이터 복사: mov

- int a = 10

- 두 피연산자 모두 메모리에 올 수 없다.



혹은 아래와 같이 어셈블리 프로그래밍을 작성할 수 있다.




3. 연습문제



1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
int a;
int b;
 
int main()
{
    scanf("%d"&a);                // &a -> 주소
    scanf("%d"&b);                // &b -> 주소
 
    printf("a: %d\n", b);            // b -> 메모리
    printf("b: %d\n", a);            // a -> 메모리
}
 
cs


1번에서 작성했던 C코드와 거의 유사하지만 출력되는 순서가 바뀌었다.

따라서 mov 명령을 이용해 a,b의 출력 순서를 바꿔볼려고 한다.



위와 같이 mov 명령을 이용해 push 하기 전 입력 값을 바꾸어주면 된다.