리버스 엔지니어링 기초 (레지스터 및 명령어)

2021. 1. 28. 04:24악성코드 분석

프로그램을 분석할 때의 두가지 방법이 있음

정적 분석 : 프로그램을 실제로 실행시켜보지 않고 그 자체의 내용들을 분석 (ghidra, IDA 등등)

동적 분석 : 실행 단계별로 자세한 동작 과정을 살펴보고 환경에 맞는 디버거를 이용해 단계별로 분석 (OllyDbg 등등)

 

레지스터 (Register)

CPU가 사용하는 저장 공간

 

범용 레지스터

특별히 정해두지 않고 다양하게 쓸 수 있는 레지스터 rax rcx rdx rbx rsi rdi rbp r8 r9 r10 r11 r12 r13 r14 r15 rsp 들이 존재함

 

rax : 함수가 반환되기 전까지 범용 레지스터로 자유롭게 사용되다가 종료 후 함수가 실행된 후 리턴값을 저장 하기 위해 쓰임
rcx rdx r8 r9... : windows 64bit에서 함수를 호출할때 필요한 인자들을 순서대로 저장 (앞순서와 같이)
rsp : 스택 포인터, 스택의 가장 위쪽 주소를 가르킴 (스택 : 함수가 사용할 지역 변수들을 저장하기 위한 공감)

 

명령어 포인터

엄격히 정해져 있는 레지스터

 

rip : 다음에 실행될 명령어가 위치한 주소를 가르킴

rsp : Intel은 스택에 메모리가 쌓일 때 높은주소에서 낮은주소로 이동하게 된다. 만약 첫번째 메모리는 0x80에 쌓였다면 두번째는 0x76, 세번째는 0x72로 쌓이게 됨, 그러므로 rsp는 계속 갱신되면서 스택에서 가장 낮은 주소를 가진 레지스터

 

상태 레지스터

현재 상태나 조건을 0과 1로 나타내는 레지스터


CF : 더하거나 빼는 등의 산술 연산 혹은 bit shift/rotate 등의 연산이 일어났을때, 자리 올림이 생기는 경우 CF == 1

ZF : 연산의 결과가 0일 때 ZF는 1이 됨
SF : CF와 반대로 부호가 있는 연산, 수행한 결과가 양수 == 0, 음수면 대면 == 1
OF : 부호가 있는 연산에서 CF의 역할을 함 

 

명령 코드 (Operation code)

명령어에서 실제로 어떤 동작을 할지를 나타내는 부분

 

피연산자 (Operand) : 명령 코드가 연상할 대상임, 상수, 레지스터, 혹은 레지스터가 가리키고 있는 메모리의 주소가 올 수도 있음

 

mov	rcx, rdx	;rdx의 값을 rcx로 이동
lea	rcx, rdx	;rdx의 주소를 rcx로 이동
inc	dst		; ++dst
dec	dst		; --dst
neg	dst		; dst = -dst
not	dst		; dst = ~dst
add	dst,src		; dst += src
sub	dst,src		; dst -= src
imul	dst,src		; dst *= src
and	dst,src		; dst &= src
or	dst,src		; dst |= src
xor	dst,src		; dst ^= src

shift 연산 (왼쪽 or 오른쪽으로 이동하는 연산)

shl	dst,k		; dst << k
shr	dst,k		; dst >> k
			; 부호 없음
            
sal	dst,k		; dst << k 
sar	dst,k		; dst >> k
			; 부호 있음

※ 부호가 없는 연산은 왼쪽/오른쪽으로 이동했을때 범위를 넘어가면 값을 잃어버림

 

jump 명령어

jmp 무조건 이동
je ==
jne !=
jg >
jge >=
jl <
jle <=
ja > (unsigned)
jb < (unsigned)
js SF = 1
jns SF = 0

바로 위에 명령어 들을 옆에 대응하는 조건들이 성립했을때만 점프를 한다.

 

 

'악성코드 분석' 카테고리의 다른 글

easy-crackme1.exe 분석 보고서  (0) 2021.05.06
지역변수 출력 (리버싱 유형 - 1)  (0) 2021.03.17
메모리 구조  (0) 2021.02.25
abex' crackme #1 write-up  (0) 2021.02.06
x64dbg 사용법  (0) 2021.01.30