오늘 공부한 내용 날림 나 혼자 보려고 끄적인 것
(어셈블리 명령어 정리)
[ compiler ]
어셈블리어 -------> 어셈블러 --------> 기계어
0x01 어셈블리 언어란? & 배우는 목적
0x02 어셈블리를 위한 기본 지식
(1) 기본적인 하드웨어
(2) 80x86 프로세서
[+] CPU 레지스터 종류:
[->] 범용 레지스터 (General register)
[->] 상태 레지스터
[->] 플래그 레지스터
[+] 레지스터의 구조
[->] 데이터 레지스터 (data register)
: EAX[Accumulator], EBX[Base], ECX[Counter], EDX[Data]
[->] 포인터 레지스터 (pointer register)
: ESP (Stack pointer), EBP (Base pointer)
[->] 인덱스 레지스터 (index register)
: ESI (Source Index), EDI (Destination Index)
[->] 세그먼트 레지스터 (Segment register)
: CS, DS, SS, ES
[*] 범용레지스터
[->] RAX(64) - EAX(32) - AX(16) - AH(8) - AL(8) : 누산기 레지스터라 불리며, 곱셈이나 나눗셈 연산에 중요하게 사용
int v1 = 0x4;
00A616BE mov dword ptr [v1],4
int v2 = 0x10;
00A616C5 mov dword ptr [v2],10h
int v3 = 0x0;
00A616CC mov dword ptr [v3],0
v3 = v1 + v2;
00A616D3 mov eax,dword ptr [v1]
00A616D6 add eax,dword ptr [v2]
00A616D9 mov dword ptr [v3],eax
[->] RBX(64) - EBX(32) - BX(16) - BH(8) - BL(8) : 베이스 레지스터라 불리며 메모리 주소 지정시에 사용
[->] RCX(64) - ECX(32) - CX(16) - CH(8) - CL(8) : 계수기(Counter)레지스터라 불리며 Loop 등의 반복 명령에 사용
# include <stdio.h>
# include <stdlib.h>
int main(void) {
int v = 0x0;
__asm {
mov ecx, 0x10;
T:
inc v;
loop T;
leave;
retn;
}
}
[->] RDX(64) - EDX(32) - DX(16) - DH(8) - DL(8)
[->] ESI - SI
[->] EDI - DI
[->] ESP - SP
[->] EBP - BP
ESP [0019FEB8] = EBP [0019FF04]
주소 지정 방식의 이해
[+] 즉시 지정방식(Immediate addressing)
[+] 레지스터 지정방식(Register addressing)
[+] 직접 주소 지정방식(Directly addressing)
[+] 레지스터 간접 주소 지정 방식
[+] 베이스 상대 주소 지정 방식
어셈블리어 명령어 정리
[+] push : stack에 데이터를 적재 시킬 경우
[+] pop : stack에 데이터를 제거 시킬 경우
# include <stdio.h>
int main(void)
{
__asm {
push 0x10;
push 0x11;
push 0x12;
push 0x13;
pop ebx;
pop ebx;
pop ebx;
pop ebx;
}
return 0;
}
ebp = 0019FF04
esp = 0019FEB8
[+] push ____________________
esp = 0019FEB4 => 0x10
esp = 0019FEB0 => 0x11
esp = 0019FEAC => 0x12
esp = 0019FEA8 => 0x13
-----------------------------
[-] pop ____________________
esp = 0019FEAC => 00000013
esp = 0019FEB0 => 00000012
esp = 0019FEB4 => 00000011
esp = 0019FEB8 => 00000010
-----------------------------
[+] mov
[+] lea
[+] inc
__asm {
mov eax, 0x11;
inc eax;
}
[+] dec
__asm {
mov eax, 0x10;
dec eax;
}
[+] add
# include <stdio.h>
int main(void) {
__asm mov eax, 0x10;
__asm add eax, 0x11;
return 0;
}
[+] sub
[+] call => 프로시져 호출
# include <stdio.h>
void f(int param1, int param2);
int main(void) {
__asm {
push 0xb; // param2 <= 0xb
push 0xa; // param1 <= 0xa
call dword ptr[f];
pop ebx;
pop ebx;
leave;
retn;
}
} // end of main function
void f(int param1, int param2) {
char* p = "param1 => %d, param2 => %d\n";
__asm {
mov eax, dword ptr[ebp + 0x8];
mov ebx, dword ptr[ebp + 0xc];
push ebx;
push eax;
push p;
call dword ptr[printf];
pop ebx;
pop ebx;
pop ebx;
leave;
retn;
}
} // end of f function
[+] cmp
# include <stdio.h>
int main(void) {
int result = 0;
_asm {
mov eax, 0x10;
cmp eax, 0x10;
je equal_;
equal_:
mov eax, 0x10;
mov result, eax;
jmp END;
END:
leave;
retn;
}
}
[+] jmp => 특정한 곳으로 분기
*참고
je : jump equal
jne : jump not equal
jz : jump zero
jnz : jump not zero
ja : jump above
jae : jump above or equal
jna : jump not above - 크지 않을 때 점프
jnae : jump not above or equal
jb : jump below - cmp a, b 에서 a가 작을 때 점프
# include <stdio.h>
int main(void) {
int v1 = 0x10;
int v2 = 0x9;
int result = 0;
char* r = "result => %d\n";
_asm {
mov eax, dword ptr[v1];
cmp eax, v2;
jb jump_below;
jae jump_above_or_equal;
jump_below:
mov ebx, 10;
mov result, ebx;
jmp TheEnd;
jump_above_or_equal:
mov ebx, 11;
mov result, ebx;
jmp TheEnd;
TheEnd:
push result;
push r;
call dword ptr[printf];
pop ebx;
pop ebx;
}
return 0;
} // end of main function
'어셈블리' 카테고리의 다른 글
2018_05_30_키트리_침해대응 (0) | 2018.05.29 |
---|---|
2018_05_30_01 (0) | 2018.05.29 |
네이버 풀이 (0) | 2017.12.22 |
어셈블리 cdq (3) | 2017.12.01 |
랜덤 어셈블리 (0) | 2017.12.01 |