본문 바로가기

해킹 공부

[NOOBHACK] 어셈블리어 구동 방식과 명령어

어셈블리어를 입문하는 사람들을 위해 친절하고 링크도 걸어주고 다 할테니까 어셈블리어를 처음 접하는 분이라면

아래 링크에 들어가길 바란다

https://noobhack.tistory.com/22

 

[NOOBHACK] 어셈블리어란

해킹을 배운다면 정말정말 중요한 어셈블리어에 대해 배워보자 일단 어셈블리어란 프로그래밍 언어인데 이게 좀 저급 언어다 언어로서 질이 낮다는게 아니라 프로그래밍 언어 중 고급 언어와

noobhack.tistory.com

아무튼 오늘은 어셈블리어 구동 방식과 명령어를 알아볼 것이다

일단 예시로 알아보자

 

여기 1,2,3번이 있는데

일단 위에서 부터 아래로 진행 되며

 

1.코드를 실행하는 메모리 위치

 

2.명령어

 

3.인자값

 

위 사진의 1,2,3번의 내용이다

메모리 위치를 보여주며 명령어를 보여주고 이에 대한 인자값을 보여주면 한 코드가 끝나는 것이다

 

그럼 명령어 부터 알아보자

 

이건 기본적인 명령어다

명령어   설명
MOV Move 데이터 이동 (전송)
PUSH Push 오퍼랜드의 내용에 스택을 쌓는다.
POP Pop 스택으로부터 값을 뽑아낸다.
XCHG Exchange Register / memory with Register 첫번째 오퍼랜드와 두번째 오버랜드 교환
IN Input from AL/AX to Fixed port 오퍼랜드로 지시된 포트로부터 AX에 데이터 입력
OUT Output from AL/AX to Fixed port 오퍼랜드가 지시한 포트로 AX의 데이터 출력
XLAT Translate byte to AL BX:AL이 지시한 데이블의 내용을 AL로 로드
LEA Load Effective Address to Register 메모리의 오프셋값을 레지스터로 로드
LDS Load Pointer to DS REG←(MEM), DS←(MEM+2)
LES Load Pointer ti ES REG←(MEM), ES←(MEM+2)
LAHF Load AH with Flags 플래그의 내용을 AH의 특정 비트로 로드
SAHF Store AH into Flags AH의 특정 비트가 플래그 레지스터로 전송
PUSHF Push Flags 플래그 레지스터의 내용을 스택에 쌓음
POPF Pop Flags 스택으로부터 플래그 레지스터로 뽑음

 

 

그리고 이건 연산자 명령어

명령어   설명
ADD Add 캐리를 포함하지 않은 덧셈
SBB Subtract with Borrow 캐리를 포함한 뺄셈
DEC Decrement 오퍼랜드 내용을 1 감소
NEG Change Sign 오퍼랜드의 2의 보수, 즉 부호 반전
CMP Compare 두 개의 오퍼랜드를 비교한다
ADC Add with Carry 캐리를 포함한 덧셈
INC Increment 오퍼랜드 내용을 1 증가
AAA ASCII adjust for Add 덧셈 결과 AL값을 UNPACK 10진수로 보정
DAA Decimal adjust for Add 덧셈 결과의 AL값을 PACK 10진수로 보정
SUB Subtract 캐리를 포함하지 않은 뺄셈
AAS ASCII adjust for Subtract 뺄셈 결과 AL값을 UNPACK 10진수로 보정
DAS Decimal adjust for Subtract 뺄셈 결과의 AL값을 PACK 10진수로 보정
MUL Multiply (Unsigned) AX와 오퍼랜드를 곱셈하여 결과를 AX 또는 DX:AX에 저장
IMUL Integer Multiply (Signed) 부호화된 곱셈
AAM ASCII adjust for Multiply 곱셈 결과 AX값을 UNPACK 10진수로 보정
DIV Divide (Unsigned) AX 또는 DX:AX 내용을 오퍼랜드로 나눔. 몫은 AL, AX 나머지는 AH, DX로 저장
IDIV Integer Divide (Signed) 부호화된 나눗셈
AAD ASCII adjust for Divide 나눗셈 결과 AX값을 UNPACK 10진수로 보정
CBW Convert byte to word AL의 바이트 데이터를 부호 비트를 포함하여 AX 워드로 확장
CWD Convert word to double word AX의 워드 데이터를 부호를 포함하여 DX:AX의 더블 워드로 변환

 

 

비트 연산자 명령어

명령어   설명
NOT Invert 오퍼랜드의 1의 보수, 즉 비트 반전
SHL/SAL Shift logical / arithmetic Left 왼쪽으로 오퍼랜드만큼 자리 이동 (최하위 비트는 0)
SHR Shift logical Right 오른쪽으로 오퍼랜드만큼 자리 이동 (최상위 비트 0)
SAR Shift arithmetic Right 오른쪽 자리이동, 최상위 비트는 유지
ROL Rotate Left 왼쪽으로 오퍼랜드만큼 회전 이동
ROR Rotate Right 오른쪽으로 오퍼랜드만큼 회전 이동
RCL Rotate through Carry Left 캐리를 포함하여 오른쪽으로 오퍼랜드만큼 회전 이동
AND And 논리 AND
TEST And function to Flags, no result 첫 번째 오퍼랜드와 두 번째 오퍼랜드를 AND하여 그 결과로 플래그 세트
OR Or 논리 OR
XOR Exclusive Or 배타 논리 합 (OR)

 

자주 쓰이는 명령어들이다 이것만 알아서 반은 갈 수 있다

 

 

 

그러면 이제 변수를 알아보자

특이하게도 어셈블리어의 변수는 원래 코드의 변수명을 사용하지 않고 주소에 따라 변수를 구별하며

어셈블리어를 실행할때 사용되는 범용 레지스터들을 알아보자

 

먼저 레지스터들은 R과 E로 나뉘는데

RAX라는 레지스터로 예를 들자면

 

RAX안에 EAX가 있고 EAX안에 AX가 있다고 생각하면 된다

레지스터는 이렇게 나뉜다 아래표의 *는 R과 E가 들어가도 같은 의미가 있다

단 용도가 다를 수 있다는 것.

레지스터 이름 용도  
*AX 누산기 산술 연산에 사용(함수의 반환값 저장)  
*BX 베이스 레지스터 특정 주소 저장(주소를 담기위한 인덱스)  
*CX 카운트 레지스터 반복되는 특정 명령에 카운트 해준다(C언어의 for문 i?)  
*DX 데이터 레지스터 일반 자료 저장  
       
*BP 베이스 포인터 스택 내의 변수 값을 읽는데 사용  
*SP 스택 포인터 스택의 가장 끝 주소  
*IP 명령 포인터 다음 명령의 오프셋을 저장하며 CS 레지스터와 합쳐져 다음에 수행될 명령의 주소 형성  

 

이렇게 알면 된다 끝