어셈블리 프로그램을 작성한다는 것은 CPU가 지원해주는 각종 연산 기능들을 이용해서
레지스터나 메모리에 데이터를 저장한다는 것이다.
sasm 을 이용하여 변수를 선언하고, 레지스터에 데이터를 복사해보자.
가장 헷갈렸던 부분이 여기다.
eax와 ax에 0x1234를 저장하고,
mov ax, eax 를 실행했을 때 에러가 난다.
32비트 짜리를 16비트에 억지로 집어넣으려고 하니까 탈이 난거다.
이 부분을 주의하도록 하자.
어셈블리 변수 선언
어셈블리에서 변수는 메모리의 시작 주소와 사용되는 메모리의 크기를 의미한다.
변수는 다음과 같은 정보를 지닌다.
- 시작 주소
- 저장 되어 있는 값
- 사용하는 데이터의 크기
> 데이터의 크기 지시어
타입 | 설명 |
byte | 8비트 정수 |
word | 16비트 정수 |
dword | 32비트 정수 |
qword | 64비트 정수 |
> 변수 선언 위치
변수는 section .bss 또는 section .data에 선언할 수 있다.
section .bss 에 변수 선언하기
section .bss 에는 크기와 변수의 개수를 지정해줄 수 있다.
크기지시자 | 설명 |
resb | 1 byte |
resw | 2 byte |
resd | 4 byte |
resq | 8 byte |
변수명 크기지시자 개수
의 형식으로 변수를 선언한다.
저것은 a 라는 이름의 변수를 2바이트 5개(총 10바이트) 의 크기로 선언한 것이다.
section .data 에 변수 선언하기
section .data 영역에는 초기값이 설정된 변수를 선언할 수 있다.
크기지시자 | 설명 |
db | 1 byte |
dw | 2 byte |
dd | 4 byte |
dq | 8 byte |
변수명 크기지시자 초기값
의 형식으로 변수를 선언한다.
a 라는 변수를 2바이트 크기로 초기값을 5를 줘서 선언한 예시이다.
바이트와 워드가 가장 많이 사용된다.
변수 선언과 배열, 변수 사용
먼저 다양한 크기의 변수들에 대해서 알아보자.
> 바이트 변수
- 1바이트 크기의 변수를 표현한다.
- 변수의 크기는 DB 로 표시하고 초기값을 설정해준다.
- 초기값을 설정할 필요가 없을 때는 ? 로 대신한다.
> 워드 변수
- 2바이트 크기의 변수를 표현한다.
- 변수의 크기는 DW 로 표시하고 초기값을 설정해준다.
- 초기값을 설정할 필요가 없을 때는 ? 로 대신한다.
- 가장 기본이 되는 변수이다.
어셈블리 배열
어셈블리에서 배열은 동일한 크기의 연속적인 메모리 변수를 표현하는 것이다.
배열은 바이트 크기를 가지는 바이트 배열과 워드 크기를 가지는 워드배열이 사용된다.
각각의 배열 요소 초기값은 배열 정의에서 모두 포함되어야 한다.
+ mov 명령어를 통한 메모리에 값 전달하기
mov 명령어는 메모리에 데이터를 복사하는 명령어이다.
어셈블리 언어에서 메모리 변수의 이름은 일종의 라벨이다.
이 라벨은 그 변수의 주소값을 표현하고 있는 것인데,
주소가 가리키는 곳의 값은 [변수명] 으로 표현한다.
- 레지스터는 사이즈가 같아야만 복사가능(mov 연산 이용가능)하다.
- 메모리에서 곧바로 메모리로 복사는 불가능하다.
mov eax, [a] 를 통해 a라는 라벨 안의 값을 eax에 넘겨주었다.
[](대괄호)는 메모리 주소를 가리킬 때 사용한다.
만약 [] (대괄호) 표시가 없다면?
결과를 확인해보자.
엉뚱한 값이 나오는 것을 확인할 수 있다.
내 메모리 주소 10번지에는 12304가 들어있나보다.
변수는 이렇게 mov 해야한다.
그럼 레지스터 끼리는?
eax와 ebx 레지스터를 이용해서 대괄호가 있고 없고의 차이를 알아보자.
eax안에 7777 이라는 값이 있다고 가정한다.
1. mov ebx, eax -> eax 안의 7777이라는 값을 ebx에 복사
2. mov ebx, [eax] -> 7777번지에 위치한 값을 ebx에 복사
이상하게 계속 잊어버리는 요소라 꼭 기억해두길 바란다.
>메모리 값 출력하는 방법
- 16진수 출력 : PRINT_HEX 바이트 수, 레지스터 또는 변수 이름
- 10진수 출력 : PRINT_DEC 바이트 수, 레지스터 또는 변수 이름
- 문자열 출력 : PRINT_STRING 변수이름 또는 문자열
- \n (줄바꿈) : NEWLINE
리틀엔디언
: 가장 작은 자리의 값이 작은 주소에 들어가는 것.
그냥 반대로 들어간다고 생각하면 쉽다.
'Archive > Hacking' 카테고리의 다른 글
[ Assemble ] 어셈블리 입력 매크로함수 (2) | 2020.04.15 |
---|---|
[ Assemble ] 문자열 변수 선언 & 출력 (0) | 2020.04.15 |
[ Protocol ] 프로토콜 문서 기본 지식 (0) | 2020.04.03 |
[ Assemble ] 어셈블리어 출력, add 연산, imul 연산실습 (0) | 2020.03.31 |
[ Assemble ] 어셈블리어 개요 & SASM 설치 (2) | 2020.03.31 |