개발 블로그

[스무디]어셈블리어 강의 13~17강 정리 본문

해킹 및 보안/리버싱

[스무디]어셈블리어 강의 13~17강 정리

갹둥 2022. 10. 13. 17:03

13. 메모리 지정 방식

-offset 이용하는 방법
ex) [eax+4]
*offset: 변위차

mov ebx, 402000
mov byte ptr [ebx], 0
mov byte ptr [ebx+2], 1 
mov byte ptr [ebx+3], 2 
mov byte ptr [ebx+4], 3 

결과

[402000]:  00 01 02 03 ...

mov ecx, 0
mov byte ptr [402000 + ecx], cl
-> [402000] : 00 00 00 00
inc ecx
mov byte ptr [402000 + ecx], ecx
-> [402000] : 00 01 00 00
inc ecx
mov byte ptr [402000 + ecx], ecx
-> [402000] : 00 01 02 00


-index 지정 방식
mov ecx, 0
mov byte ptr [402000 + ecx*4], cl
-> 402000 : 00 00 00 00 |  00 00 00 00 |  00 00 00 00  |  00 00 00 00 
inc ecx
mov byte ptr [402000 + ecx*4], ecx
-> 402000 : 00 00 00 00 |  01 00 00 00 |  00 00 00 00  |  00 00 00 00 
inc ecx
mov byte ptr [402000 + ecx*4], ecx
-> 402000 : 00 00 00 00 |  01 00 00 00 |  02 00 00 00  |  00 00 00 00 



**규칙**
[base 주소 + offset + index * scale]
레지스터는 최대 2개 사용 가능
-> base로는 레지스터가 올 수 없음
index로는 반드시 레지스터를 사용해야 함
scale은 주로 자료형의 크기 (int: 4byte)



14~15. 조건분기 명령어 

-점프는 종류가 여러개 있음, 인자는 하나
      > 무조건분기: JMP [주소] 

      > 조건분기: 상태레지스터에 따라 다름

 

-상태 레지스터(비트)

Z (ero) 제로 플래그 연산 결과가 0일 경우 
C(arry) 캐리 플래그  부호 없는 숫자의 연산 결과가 비트 범위를 넘어섰을 경우, 캐리가 발생한 경우
O(verflow) 오버플로우 플래그 부호 있는 숫자의 연산 결과가 비트 범위를 넘어섰을 경우
S(ign) 사인 플래그 연산 결과가 음수일 때, 연산 결과의 최상위 비트인 부호 비트가 담김

이번 강의에서 나온 상태 레지스터들을 정리해보았다. 

 

조건 분기 명령어

-JZ: 제로플래그가 1이면 분기

ex)

z=0이면 점프를 하지 않는다.

 

z=1이면 점프

eax를 1 감소시키면 0이 되므로 z=1로 바뀐다. 그 다음 eip에 분기 주소가 담기고 점프한다.

*mov eax, 0 한다고 z 플래그가 0으로 바뀌는건 아님

*je와 기계어가 같아서 올리디버거에서 명령어를 입력하면 자동으로 바뀐다. 


-JE(Eqaul): 비교 결과가 같으면 점프
*cmp: 비교 연산자, 내부적으로 빼기를 수행해서 비교, 빼기를 한 결과를 저장하지 않고 버림
ex) 

mov eax, 0

cmp eax, 0  

cmp eax, 1


따라서 ZE와 JE가 같은 역할을 함, 기계어로 같음, 비교 결과가 같으면 z flag가 0이 되기 때문

-JNE(Not Equal) / JNZ(Not Zero): 제로 플래그가 0이면 분기, 둘이 기계어로 같음

-JA(Above): 부호가 없는 데이터 비교 결과 앞에 연산자가 크면 점프

Carry=0, Zero=0일 때 

eax에 있는 값이 0보다 크므로 z=0이고 c=0임 -> 점프
eax에 들어있는 값이 2보다 작기 때문에 z=0이고 c=1임 -> 점프x


*JNBE = JA

-JB(Below) : 부호가 없는 데이터 비교 결과 앞에 연산자가 작으면 점프

Carry=1이면 점프(Zero는 상관 없음)
mov eax, 0
cmp eax, 1                        c  1

-JNA(Not Above) / JNB(Not Below) 
*각 JBE / JAE와 같음 (기계어가 같음), 등호 조건 포함
JNA(JBE): z=1 or c=1 이면 점프
JNB(JAE): z=0, c=0 or z =1, c=0이면 점프

-JC(Carry): carry 플래그가 세팅되어 있을 때





17강 조건분기 명령어 JG JL 상태레지스터 SF OF

-JG와 JL은 JA, JB와 다르게 부호가 있는 데이터로 비교

*오버플로우 비트

0 1 1 1 + 0  0 0 1 = 1 0 0 0 

부호비트(sign bit)가 1이 되었음
부호가 있는 비트로 읽으면 -8이 되어버림, 이런 경우 오버플로우 비트 세팅

-JG(Greater): 부호가 있는 데이터를 비교해서 앞에 데이터가 크면 분기

Z=0, S=O면 점프

연산 결과 부호비트가 1이고 오버플로우 비트가 0이므로 점프하지 않음
JA는 부호가 없는 데이터로 비교하기 때문에 점프함

부호가 있는 데이터인지 없는 데이터인지는 명령어가 결정하는 것임

 

-JL(Less): 

1과 2를 비교한 결과 S=1이지만 O=0임 -> 점프


S<> O인 경우 점프

->연산 결과가 음수인 경우 오버플로우가 일어나지 않았을 때