미친해커

[WoW] Far와 Near 어셈블리 명령의 차이점 본문

Windows/Heaven's Gate (Windows on Windows x64)

[WoW] Far와 Near 어셈블리 명령의 차이점

미친해커 2022. 6. 1. 01:30
반응형
 

[WoW] 32Bit 모드에서 64Bit 모드로 전환하기

[WoW] 32Bit 응용 프로그램에서의 Kernel 함수 호출 Windows 64Bit에서 32Bit 응용 프로그램을 실행하고 디버거로 커널 함수의 어셈블리를 확인하면 대부분 다음과 같은 형식을 띄게 된다. mov eax, 0x00000026 #

crazyhacker.tistory.com

이전 포스팅에서 jmp far 라고하는 처음보는 형태의 어셈블리를 확인했었다. 그리고 해당 far 어셈블리는 CS 레지스터의 값을 변경하는 어셈블리였으며 32Bit 모드에서 64Bit 모드로 변경하기 위해서는 CS 레지스터의 값을 변경해야 한다는 것도 알았다. 이번 포스팅에서는 Far 어셈블리와 Near 어셈블리의 차이점을 알아보려고 한다.

jmp instruction

Opcode 0xE9 (Relative jump instruction, Near jump)

Opcode 0xE9를 사용한 상대거리를 이용한 점프 어셈블리 명령이다.

상대 거리를 사용하는 opcode 0xE9 어셈블리 명령어

opcode인 0xE9가 존재하고 상대거리인 0x00000010이 operand로 들어가 있다. 해당 어셈블리 명령의 동작과정은 EIP(IP)에 operand를 더하는 방식으로 계산된다. (혹시라도 0x77F20FE5 주소로 점프하는지 이해가 안된다면 아래 접은 글을 확인하자)

더보기

EIP는 다음에 실행할 명령의 주소를 갖고 있기 때문에 0x77F20FD0 주소의 명령어를 실행하는 동안의 EIP의 값은 0x77F20FD5가 되기 때문에 해당 주소에 0x00000010을 더한 0x77F20FE5로 점프하게 되는 원리이다.

Opcode 0xEA (Static jump and change CS register instruction, Far jump)

Opcode 0xEA를 사용한 점프할 주소의 Code Segment를 지정하고 해당 주소로 점프하는 어셈블리 명령이다.

왼쪽은 어셈블리 명령, 오른쪽은 32Bit 에서의 Segment Register의 값

opcode 0xEA(jmp far) 어셈블리 명령은 다른 jmp 어셈블리 명령들과는 큰 차이가 존재한다.

 

  1. 2개의 Operand를 가진다
  2. 점프(이동)할 주소를 절댓값(static)으로 받는다.
  3. 점프(이동)할 주소가 존재하는 Code Segment를 받는다.

즉 위 어셈블리에서 이동할 주소인 0x77F20FE5가 상대적으로 계산되어 있지 않다. 그리고 두번째 Operand로 해당 주소가 존재하는 Code Segment를 받았다. 해당 주소는 CS 0x0023에 존재하는 주소이기 때문에 0x0023으로 설정했다. 위 어셈블리를 실행하게 되면 CS Register의 값이 0x0023으로 변경되고 0x77F20FE5로 EIP가 이동하게 된다.

ret instruction

Opcode 0xC3 (Near Return)

Opcode 0xC3를 사용한 리턴 어셈블리 명령이다.

ret 어셈블리는 모두가 알다시피 return 하는 어셈블리이다. 기본적으로 현재 스택의 최상단에서 4 Byte를 꺼내 해당 주소로 점프하는 어셈블리이다. ret 어셈블리를 풀어 써보자면 다음과 같다.

  1. pop eip
  2. jmp eip

Opcode 0xCB (Change CS register instruction, Far Return)

Opcode 0xCB를 사용하는 리턴 어셈블리이다. 해당 어셈블리는 CS 레지스터를 변경한다.

해당 어셈블리는 똑같이 ret 어셈블리의 기능도 갖고 있으면서 동시에 CS 레지스터의 값을 변경할 수 있다. 그런데 이 CS 레지스터의 값을 변경하는 방식이 기존의 jmp 어셈블리와는 큰 차이가 있다. ret far 어셈블리의 동작 방식은 다음과 같다.

  1. 스택에서 4Byte를 꺼내 CS 레지스터의 넣는다. (pop cs)
  2. 스택에서 4Byte를 꺼내 ret 한다. (ret 또는 pop eip; jmp eip)

즉 총 8Byte를 꺼내게 되는데 처음 4Byte는 CS 레지스터에 들어가고 그 다음 4Byte의 주소로 리턴하게 되는 원리이다.

반응형
Comments