자 이제 어셈블리어...하고 담주부터 바로 레나 튜토리얼 시작해볼게요 ㅎㅎ
우선 어셈블리어는 블로깅 내용을 많이 차지하기 때문에 Part2로 뺏어요.. 다들 긴 글은 싫어하잖아요???
사실 이번주부터 할려했지만... 약속들이 너무 많아서 늦어졋지만... 그래도 열심히 해보자 임마!!!!(나에게 하는 말..)
어셈블리어는 우선 저급언어라고 부릅니다... 여기서 저급 언어란 기계중심의 언어 입니다. 즉 사람이 보기 위한 언어가 아닌 기계가 읽기 쉬운 언어라는거죠... 그래도 기계어를 보완하기 위해 나온 언어라고 합니다...
기계어가 CPU 종류에 따라 달라지기 때문에 어셈블리어 역시 통일된 규격이 없습니다.. 호환이 쓰레기라는 것이지요..
젠장....ㅋㅋㅋㅋ
그래도 앞으로 사용할 어셈블리어를 우리 한번 열심히 배워봅시다.
종류 |
설명 |
INC |
피연산자에 1을 더한다. |
DEC |
피연산자에 1을 뺀다. |
ADD |
Destination에 Source의 값을 더해서 Destination에 저장한다. |
SUB |
Destination에 Source의 값을 빼서 Destination에 저장한다. |
MUL |
부호 없는 al, ax, eax의 값을 피연산자와 곱한다. 피연산자가 8비트이면 al과 곱해서 ax에 저장되고 16비트면 ax와 곱하고 dx(상위16비트):ax(하위16비트)에 저장된다. 연산 결과에 따라 OF, ZF 플래그가 세트될 수 있다. |
IMUL |
부호 있는 al, ax, eax의 값을 피연산자와 곱한다. 연산결과에 따라 CF, OF가 세트될 수 있다. |
SBB |
Destination에 Source 값과 CF값을 빼서 Destination에 저장한다. |
DIV |
부호 없는 정수의 나눗셈을 한다. |
MOV |
Source에서 Destination으로 데이터를 복사한다. |
INT |
소프트웨어 인터럽트를 발생시켜 운영체제의 서브루틴을 호출한다. |
AND |
Destination과 Source 피연산자의 각 비트가 AND 연산된다.(AND 연산은 두개의 모두 1일 때만 결과 값이 1이 된다.) |
TEST |
두 피연산자 사이에 논리적인 AND 연산을 수행하여 플래그 레지스터에 영향을 주지만 결과값은 저장하지 않는다. |
OR |
Destination과 Source 피연산자의 각 비트가 OR 연산된다.(OR 연산은 두개의 비트가 모두 0이면0이고 모두 0이 아니면 1이된다.) |
XOR |
Destination과 Source 피연산자의 각 비트가 XOR 연산된다. |
STC |
CF를 1로 세팅 한다. |
CLC |
CF를 0으로 세팅 한다. |
STD |
DF를 1로 세팅 한다. |
CLD |
DF를 0으로 세팅한다 |
STI |
IF 를 1로 세팅한다 |
CLI |
IF를 0으로 세팅한다 |
SHL |
Destination 피연산자를 Source 피연산자의 크기만큼 왼쪽으로 각 비트를 시프트 시킨다. |
SHR |
Destination 피연산자를 Source 피연산자의 크기만큼 오른쪽으로 각 비트를 시프트 시킨다. |
PUSH |
스택에 값을 넣는다. |
PUSHAD |
EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP 레지스터의 값을 스택에 PUSH한다.(레지스터의 값을 보관해야 할때) |
PUSHFD |
플래그 레지스터를 스택에 PUSH한다. |
POP |
스택에서 값을뺀다. |
POPAD |
스택에 존재하는 값을 EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP 레지스터로 POP한다. |
POPFD |
스택에 존재하는 값을 플래그 레지스터로 POP한다. |
XCFG |
두 피연산자 내용이 서로 교환된다. ex) XCHG reg, reg XCHG reg, mem XCHG mem, reg |
NEG |
피연산자의 2의 보수를 계산하여 결과를 피연산자에 저장한다. |
PTR |
피연산자의 크기를 재설정한다. |
OFFSET |
세그먼트의 시작으로부터 변수가 위치한 거리까지의 상대거리를 리턴한다. |
LEA |
Source 피연산자의 유효 주소를 계산하여 Destination 피연산자에 복사한다. |
REP |
ECX 레지스터를 카운터로 사용해서 문자열 관련 명령을 ECX > 0인 동안 반복한다. |
CALL |
함수를 호출할 때 사용된다. |
CMP |
두 피연산자를 비교할 때 사용한다. |
NOP |
아무것도 하지 않을 때 사용한다. |
JMP |
피연산자가 가리키는 코드로 점프한다. |
종류 |
설명 |
push | 스택에 저장 |
pop | 스택 가장 사이에 있는 값을 꺼내서 저장 |
mov | 메모리나 레지스터 값을 옮길 때 사용 |
lea | 주소값을 옮길 때 사용 |
inc | 1 증가 |
dec | 1 감소 |
add | 레지스터나 메모리의 값을 덧셈할 때 쓰임 |
sub | 레지스터나 메모리 값을 뺄셈할 때 쓰임 |
call | 프로시져를 호출 |
ret | 호출했던 바로 다음 지점으로 이동 |
cmp | 레지스터와 레지스터 값을 비교 |
nop | 아무동작도 하지 않는다 |
jmp | 특정한 곳으로 분기 |
개념은 넷상에 어디에나 많이 있는 글이기 때문에 더 잘 요약된 블로그도 많다....ㅜㅜ(개념글이 제일 어렵다... ㅠ) 다음에 포스팅 될 레나 튜토리얼부터는 시간을 많이 투자해서 좀 더 상세하게 포스팅을 하자...!
다양한 산술 연산 결과의 상태를 알려주는 플래그 비트들이 모인 레지스터!! 연산 결과에 따라 True와 False가 될 수 있다... 다른 블로그에서는 플래그가 1로 설정하는 것은 SET(세트)라고 하며 0으로 설정하는 것을 CLEAR 혹은 RESET이라고 한다고 하네요... ㅎ EFLAGS 레지스터는 목적에 따라 상태플래그, 제어플래그, 시스템 플래그로 나눌 수 있다!
리버싱을 할때 모든 개념이 필요한것은 아니기 때문에 가장 많이 사용되는 상태 플래그만 다뤄보도록 한다!
종류 |
설명 |
CF(Carry) | 부호 없는 수(unsigned integer)의 오버플로우가 발생했을 때 True(1)가 된다. |
PF(Parity) | 연산 결과에서 1인 비트의 수가 짝수면 True(1), 아니면 False(0)가 된다. |
OF(Overflow) | 부호 있는 수(signed integer)의 오버플로우가 발생했을 때 True(1)가 된다. |
AF(Auxiliary) | 3번 bit에 올림수나 빌림수가 발생할 때 True(1), 아니면 Flase(0)가 된다. |
ZF(Zero) | 연산의 결과가 0일 때 ZF는 True(1)가 된다. 아니면 Flase(0)가 된다. |
SF(Sign) | 연산의 결과가 음수일 때 True(1)가 된다. 아니면 False(0)가 된다. |
0x06 레나 튜토리얼 04 (0) | 2020.09.08 |
---|---|
0x04 - 레나튜토리얼 02(라이센스 키 알고리즘 분석하기) (0) | 2020.08.10 |
0x03 - 레나튜토리얼 01 (0) | 2020.08.09 |
0x01 - Reversing 의 서막...Part 1(레지스터, 메모리) (2) | 2020.06.15 |
0x00 - Reversing (0) | 2020.05.31 |