검색결과 리스트
글
Day-02 어셈블리어
1.데이터 형식
메모리에 접근 했을때 얼만큼 읽어들일지 결정
데이터 타입 |
사용 용도 |
||
BYTE |
부호 없는 1 byte |
||
WORD |
부호 없는 2 byte |
||
DWORD |
부호 없는 4 byte |
2. 어셈블리언어 명령어
플랫폼에 따라서 다르다(IA32 : intel 기반, AT&T : linux 기반)
ADD [EBP-0x04],0x01
└> 명령어(OPCODE) └>피연산자(OPERAND)
1.명령어(OPCODE)
사용할 명령어가 들어가는 부분
2.피연산자(OPERAND)
operand의 갯수는 opcode에 따라 정해져 있다.(','로 구분)
<[EBP-0x04]>
메인 함수도 함수이기 때문에 호출 시 스텍프레임 생성
32bit 레지스터 이기때문에 자료형에 상관없이 4씩 변화
<0x01> : 상수
10진수로 표현가능하나 어셈블리어로 열면 16진수로 표시되어 있기 때문에 혼동이 될수도 있다.
<operand 표시법>
표시 기법 |
설명 |
mem |
메모리 |
label |
지정된 레이블 |
imm |
즉시 값, 상수 |
reg | 범용 레지스터 |
*레이블은 소스코드 중간에 이름을 지정하는것으로 뛰어넘을때나 반복할때 사용된다.
-뛰어넘기
int main(void)
{
int a = 0;
goto L1;
a = 5;
L1:
printf("%d\n", a);
return 0;
}
이렇게 되면 a=5;는 뛰어넘고 바로 printf로 가게 되어 0이 출력된다.
-반복하기
int main(void)
{
int a = 0;
L1:
a = 5;
printf("%d\n", a);
goto L1;
return 0;
}
이렇게되면 a=5; 와 printf가 계속 반복해서 실행되어 5가 무한번 출력된다.
3.INC
opernad의 값을 1증가시켜주는 명령어(operand 1개)
"++"연산자와 동일
결과 : a = 2
<사용가능한 operand>
INC reg (ex>INC EAX) |
INC mem(ex>INC [EBP-0x04]) |
*인라인 어셈
-상위레벨 언어에서 어셈블리어를 사용할 수 있게 해준다.
-문법상 오류가 발생해도 오류를 잘 표시 안된다
-한줄에는 한 명령어만!
-opcode 대/소문자 구분하지 않는다
-변수 a 대신에 [EBP-0x04]로 표현가능하다(피연산자 부분 참조)
-"_asm"영역 안에서는 기존 c언어의 함수를 사용할수없다(printf등)
4.DEC
operand의 값을 1감소시켜주는 명령어(operand 1개)
"--"연산자와 동일
결과 : a = 0
<사용가능한 operand>
DEC reg (ex>DEC EAX) | DEC mem(ex>DEC [EBP-0x04]) |
5.ADD
첫번째 operand의 값과 두번째 operand의 값을 더해서 첫번째 operand에 저장(operand 2개)
"+="과 동일
결과 : a = 20, b= 10 (동일한 결과지만 형태가 다른것을 보기위해서 저렇게 표현함)
<사용가능한 operand>
ADD reg, reg(ex>ADD EAX,EBX) |
ADD mem,reg(ex>ADD [EBP-0x04], EAX) |
ADD reg, mem(ex>ADD EBX, [EBP-0x04]) |
ADD reg, imm(ex>ADD EAX, 0x04) |
ADD mem, imm(ex>ADD [EBP-0x04], 0x01) |
|
6.SUB
첫번째 operand의 값과 두번째 operand의 값을 빼서 첫번째 operand에 저장(operand 2개)
"-="과 동일
결과 : a = -15, b = -2
*주석처리한결과가 다른 이유(주의!!!)
[EBP-0x08]은 b의 주소값이다. 그런데 b는 현재 0으로 초기화되있다.
이 경우 0에서 -2를 하는 것이아니라 메모리공간의 끝인 256에서 -2가 되기때문에 254가 출력된다.
*그렇다면 a는 왜 그렇게 되지 않을까?
a는 현재 5라고 초기화되어 있고 바로 앞에서 이미 계산이 되고 있기 때문에 이어서 계산이 진행된다.
<사용가능한 operand>
SUB reg, reg(ex>SUB EAX,EBX) | SUB mem,reg(ex>SUB [EBP-0x04], EAX) |
SUB reg, mem(ex>SUB EBX, [EBP-0x04]) | SUB reg, imm(ex>SUB EAX, 0x04) |
SUB mem, imm(ex>SUB [EBP-0x04], 0x01) |
|
7.MOV
첫번째 operand에 두번째 operand의 값을 복사(대입) 한다(operand 2개)
변수 초기화와 동일
결과 : a = 16
<사용가능한 operand>
MOV reg, reg(ex>MOV EAX,EBX) | MOV mem,reg(ex>MOV [EBP-0x04], EAX) |
MOV reg, mem(ex>MOV EBX, [EBP-0x04]) | MOV reg, imm(ex>MOV EAX, 0x04) |
MOV mem, imm(ex>MOV [EBP-0x04], 0x01) |
|
*operand가 mem,mem 은 실행되지 않는다
<해결법> : mem의 값을 reg에 저장 후 사용
레지스터는 저장공간이기 때문에 어떠한 레지스터를 사용하던 상관없다.
<예제 1>
a=16; b=5; b++; c=a+b; d=a-b; 를 어셈블리어로 표현하라.
결과 : a=16, b=6 c=22, d=10
<예제 2>
a=3; b=5; c=10; b++; c--; a=b+c; b=a-c; 를 어셈블리어로 표현하라.
결과 : a=15, b=6, c=9
'i2sec > Reverse Engineering' 카테고리의 다른 글
DAY 1 - 어셈블리언어 (0) | 2014.04.25 |
---|