Search

5장 : x86 Assembly : Essential Part

대분류
보안
소분류
기초 리버싱
유형
어셈블리어
최종 편집 일시
2024/11/02 10:31
생성 일시
2022/10/15 05:19
15 more properties

기본 구조

동사에 해당하는 명령어(Operation Code, Opcode)와 목적어에 해당하는 피연산자(Operand)로 구성

명령어(Operation Code, Opcode)

Arithmetic Instruction

ADD
캐리를 포함하지 않은 덧셈
SUB
캐리를 포함하지 않은 뺄셈
ADC
캐리를 포함한 덧셈
SBB
캐리를 포함한 뺄셈
CMP
두개의 오퍼랜드 비교
INC
오프랜드 내용을 1 증가
DEC
오프랜드 내용을 1 감소
NEG
오퍼랜드의 2의 보수, 즉 부호 반전
AAA
덧셈 결과 AL 값을 UNPACK 10 진수로 보정
DAA
덧셈 결과 AL 값을 PACK 10진수로 보정
AAS
뺄셈 결과 AL 값을 UNPACK 10 진수로 보정
DAS
뺄셈 결과 AL 값을 PACK 10진수로 보정
MUL
AX와 오퍼랜드를 곱셈하여 결과를 AX 또는 DX:AX에 저장
IMUL
부호화된 곱셈
AAM
곱셈 결과 AX 값을 UNPACK 10진수로 보정
DIV
AX 또는 DX:AX 내용을 오퍼랜드로 나눔. 몫은 AL, AX 나머지는 AH, DX로 저장
IDIV
부호화된 나눗셈
AAD
나눗셈 결과 AX 값을 UNPACK 10진수로 보정
CBW
AL의 바이트 데이터를 부호 비트를 포함하여 AX 워드로 확장
CWD
AX의 워드 데이터를 부호를 포함하여 DX:AX의 더블 워드로 변환

Data Transfer Instruction

MOV
데이터 이동(전송)
PUSH
오퍼랜드 내용을 스택에 쌓음
POP
스택으로부터 값을 가져옴
XCHG
첫 번째 오퍼랜드와 두 번째 오퍼랜드 교환
XLAT
BX:AL 이 지시한 테이블의 내용을 AL로 로드
LEA
메모리 오프셋값을 레지스터로 로드
LDS
REG ← (MEM), ds ← (MEM+2)
LES
REG ← (MEM), ES ← (MEM+2)
LAHF
플래그의 내용을 AH의 특정 비트로 로드
SAHF
AH의 특정 비트가 플래그 레지스터로 전송
PUSHF
플래그 레지스터의 내용을 스택에 쌓음
POPF
스택으로부터 플래그 레지스터로 가져옴

Logical Instruction

NOT
오퍼랜드의 1의 보수, 즉 비트 반전
SHL / SAL
왼쪽으로 오퍼랜드만큼 자리 이동(최하위 비트는 0)
SHR
오른쪽으로 오퍼랜드만큼 자리이동(최상위 비트는 0)
SAR
오른쪽으로 자리 이동, 최상위 비트는 유지
ROL / ROR
왼쪽 / 오른쪽으로 오퍼랜드만큼 회전이동
RCL / RCR
캐리를 포함하여 왼쪽 / 오른쪽으로 오퍼랜드만큼 회전 이동
AND
논리 AND
TEST
첫 번째 오퍼랜드와 두 번째 오퍼랜드를 AND 하여 그 결과로 플래그 세트
OR
논리 OR
XOR
배타 논리 합(OR)

String Instruction

REP
REP 뒤에 오는 STRING 명령어를 CS가 0이 될 때까지 반복
MOVS
DS:DI가 지시한 메모리 데이터를 ES:DI가 지시한 메모리로 전송
COMPS
DS:DI와 ES:DI의 내용을 비교하고 결과에 따라 플래그 설정
SCAS
AL 또는 AX와 ES:DI가 지시한 메모리 내용 비교하고 결과에 따라 플래그 설정
LODS
SI 내용을 AL 또는 AX로 로드
STOS
AL 또는 AX를 ES:DI가 지시하는 메모장에 저장

Control Transfer Instruction

CALL
프로시저 호출
JMP
무조건 분기
RET
CALL로 스택에 PUSH된 주소로 복귀
JE / JZ
결과가 0이면 분기
ZF = 1
JL / JNGE
결과가 작으면 분기(부호화된 수)
SF ≠ OF
JB / JNAE
결과가 작으면 분기(부호화 안된 수)
CF = 1
JLE / JNG
결과가 작거나 같으면 분기(부호화된 수)
ZF = 1 or SF ≠ OF
JBE / JNA
결과가 작거나 같으면 분기(부호화 안된 수)
CF = 1 or ZF = 1
JP / JPE
Parity Flag가 1이면 분기
PF = 1
JO
오버플로우가 발생하면 분기
OF = 1
JS
플래그가 1이면 분기
SF = 1

JUMP Instruction

JC
캐리가 발생하면 분기
CF = 1
JNE / JNZ
결과가 0이 아니면 분기
ZF = 0
JNL / JGE
결과가 크거나 같으면 분기(부호화 된 수 )
SF = OF
JNB / JAE
결과가 크거나 같으면 분기(부호화 안된 수)
CF = 0
JNLE / JG
결과가 크면 분기(부호화된 수)
ZF = 0 AND SF = OF
JNBE / JA
결과가 크면 분기(부호화 안된 수)
CF = 0 AND ZF = 0
JNP / JPO
패리티 플래그가 0이면 분기
PF = 0
JNO
오버플로우가 아닌 경우 분기
OF = 0
JNS
부호 플래그가 0이면 분기
SF = 0
JNC
캐리가 아닌 경우 분기
CF = 0
LOOP
CX를 1로 감소, 0이 될 때까지 지정된 라벨로 분기
LOOPZ / LOOPE
CX가 0이면 지정된 라벨로 분기
ZF = 1
LOOPNZ / LOOPNE
CX가 0이 아니면 지정된 라벨로 분기
ZF = 0
JCXZ
CX가 0이면 분기
CX = 0
INT
인터럽트 실행
INTO
오버플로우가 발생하면 인터럽트 실행
IRET
인터럽트 복귀(리턴)

Processor Control Instruction

CLC
캐리 플래그 클리어
CMC
캐리 플래그를 반전
CLD
디렉션 플래그를 클리어
CLI
인터럽트 플래그를 클리어
HLT
정지
STC
캐리 플래그 셋
NOP
아무 동작 하지 않음
STD
디렉션 플래그 셋
STI
인터럽트 플래그 셋
WAIT
프로세서를 일시 정지 상태로 한다.
ESC
이스케이프 명령

피연산자(Operand)

상수(Immediate Value)
레지스터(Register)
메모리(Memory)
BYTE, WORD, DWORD, QWORD 각각 1바이트, 2바이트, 4바이트, 8바이트의 크기를 지정

프로시저

특정 기능을 수행하는 코드 조각
호출(Call) : 프로시저를 부르는 행위
반환(Return) : 프로시저에서 돌아오는 것
call addr : addr에 위치한 프로시져 호출
연산
push return_address
jmp addr
leave : 스택프레임 정리
연산
mov rsp, rbp
pop rbp
스택 프레임 함수별로 서로가 사용하는 스택의 영역을 구분하기 위한 프레임
ret : return address로 반환
연산
pop rip