상세 컨텐츠

본문 제목

0x02 - Reversing 의 서막...Part 2(어셈블리어)

Reversing

by 조땡땡이 2020. 6. 22. 12:49

본문

자 이제 어셈블리어...하고 담주부터 바로 레나 튜토리얼 시작해볼게요 ㅎㅎ

우선 어셈블리어는 블로깅 내용을 많이 차지하기 때문에 Part2로 뺏어요.. 다들 긴 글은 싫어하잖아요???

사실 이번주부터 할려했지만... 약속들이 너무 많아서 늦어졋지만... 그래도 열심히 해보자 임마!!!!(나에게 하는 말..)

 

 

# 어셈블리어란??

어셈블리어는 우선 저급언어라고 부릅니다... 여기서 저급 언어란 기계중심의 언어 입니다. 즉 사람이 보기 위한 언어가 아닌 기계가 읽기 쉬운 언어라는거죠... 그래도 기계어를 보완하기 위해 나온 언어라고 합니다...

기계어가 CPU 종류에 따라 달라지기 때문에 어셈블리어 역시 통일된 규격이 없습니다.. 호환이 쓰레기라는 것이지요..

젠장....ㅋㅋㅋㅋ

그래도 앞으로 사용할 어셈블리어를 우리 한번 열심히 배워봅시다.

 

 

1. 어셈블리어의 명령어 종류(전체)

종류

설명

INC

피연산자에 1을 더한다.
연산 결과에 따라 ZF(Zero Flag)나 OF(Overflow Flag)가 세트될 수 있다.
ex. INC reg, INC mem

DEC

피연산자에 1을 뺀다.
연산 결과에 따라 ZF나 OF가 세트될 수 있다.
ex. DEC reg, DEC mem

ADD

Destination에 Source의 값을 더해서 Destination에 저장한다.
연산 결과에 따라 ZF, OF, CF(Carry Flag)가 세트될 수 있다.
ex. ADD eax(Destination), 100(Source) : eax레지스터에 100을 더해서 eax레지스터에 저장

SUB

Destination에 Source의 값을 빼서 Destination에 저장한다.
연산 결과에 따라 ZF, OF, CF가 세트될 수 있다.
ex. Sub eax(Destination), 100(Source) : eax레지스터에 100을 빼서 eax레지스터에 저장

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

피연산자가 가리키는 코드로 점프한다.

 

2. 자주 보일 어셈블리어...ㅎㅎ

종류

설명

push 스택에 저장
pop 스택 가장 사이에 있는 값을 꺼내서 저장
mov 메모리나 레지스터 값을 옮길 때 사용
lea 주소값을 옮길 때 사용
inc 1 증가
dec 1 감소
add 레지스터나 메모리의 값을 덧셈할 때 쓰임
sub 레지스터나 메모리 값을 뺄셈할 때 쓰임
call 프로시져를 호출
ret 호출했던 바로 다음 지점으로 이동
cmp 레지스터와 레지스터 값을 비교
nop 아무동작도 하지 않는다
jmp 특정한 곳으로 분기

 

개념은 넷상에 어디에나 많이 있는 글이기 때문에 더 잘 요약된 블로그도 많다....ㅜㅜ(개념글이 제일 어렵다... ㅠ) 다음에 포스팅 될 레나 튜토리얼부터는 시간을 많이 투자해서 좀 더 상세하게 포스팅을 하자...!

 

 

 

3. EFLAGS 플래그(필요한 개념이므로 추가!)

다양한 산술 연산 결과의 상태를 알려주는 플래그 비트들이 모인 레지스터!! 연산 결과에 따라 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)가 된다.

 

 

관련글 더보기