기초 공부 Code Virtualization

2017. 12. 5. 07:130x03 Reversing Theory

728x90

컴퓨터에는 가상머신이라는게 존재한다.

대표적으로 자바의 경우 JVM, 안드로이드의 경우 Dalvik VM이 있다.


기계어로 이루어져 있는 cpu의 아키텍쳐는 보편적으로 i386, x86_64, ARM 등 주로 사용되는 아키텍쳐가 정해져 있다.


이러한 아키텍쳐는 기존부터 존재하기 때문에 분석하는데 쉽다고 한다.

물론 아직 나에게는 이러한 아키텍쳐도 힘들다. 


하지만, 이보다 더 어려운것이 잘 알려져있지 않거나 사용자가 직접 정의한 아키텍쳐에서 프로그램이 실행되게 되는 상황이다. 


환경이 익숙하지 않고, 분석에 필요한 정보가 전혀 없는 상황에서는 당연히 분석하는 시간이 늘어나고, 사람이라면 분석할 의지가 떨어지게 된다. 

나 역시 너무 어려워 보이는 문제는 그냥 포기해버렸었다. 하지만 이제는 포기하지 않으려고 한다. 포기하면 얻지 못하고 가는 게 너무나 많다. 


오늘 배울 것은 Code Virtualization이다. 이것은 프로그램이 실행되는 환경을 일반적인 CPU 아키텍쳐에서 사용자가 직접 만든 새로운 아키텍쳐, vm으로 옮기고, 일반적인 실행 코드 대신 "가상화된 코드"를 실행시키는 안티 리버싱 기법이라고 한다.

프로그램 실행환경이 cpu에서 사용자가 직접 만든 VM으로 바뀌면 지식이 없으면 엄청나게 많은 시간이 소요된다. 


Code Virtualization은 프로그램의 주요 코드 영역을 역공학자로부터 보호하기 위해, VM에서만 실행되어지는 가상화된 코드 영역으로 변환한다. 이렇게 가상화된 코드는 디스어셈블러나, 디컴파일러에 의해서 해석되지 않기 때문에, 일반적인 정적 분석과정을 깨뜨릴 수 있다고 한다. 

런타임에 이루어지는 것이 아니라 정적으로 이루어진다.


일반적인 프로그램의 흐름은 이렇다.

[CPU] -> [.text] 


Code Virtualization의 흐름은 이렇다.

[CPU] -> [VM] -> [.vcode] 


일반적인 프로그램이 이었다면 CPU가 .text영역에서 기계어를 가져와서 한 줄 한 줄 실행한다. 

하지만, Code Virtualization에서는 코드영역을 보호하기 위해 .text 섹션에 있는 기계어들을 가상화하여 .vcode 영역에 저장하게 된다. 


아, Code Virtualization은 Virtual Code Protection이라고 부르기도 한다고 한다.


VCP가 적용 된 프로그램을 실행시키면 CPU가 하는 일은 VM을 실행시키는 것이다.

계속 내 머릿속에는 VM하면 VMWARE가 생각난다. 어서 이런 생각을 없애버려야한다.


여튼, VM을 실행시킨다음 .vcode에서 가상화된 명령어들을 하나씩 하나씩 가져와서 해석 후 실행하게 된다.


이렇게 2차적인 요소를 띠고 있기 때문에 평범한 일반 프로그램보다 실행 시간은 조금 느려지는 단점은 존재한다. 그리고 일반적으로 제공되는 디스컴파일러나 디스어셈블러에 의해 해석되지 않기 때문에 분석가의 입장에서 가상화 코드의 패턴이 보이지 않는다면 엄청나게 많은 시간이 소요되게 된다.


가상화는 전가상화와 반가상화로 분류 된다고 한다.


전가상화는 (전체 가상화라는 의미) 즉 모든 소스코드가 VM에서 구동된다. 

VM은 소스를 위한 메모리를 할당하고, 소스를 메모리에 적재하고 해석 후 실행하게 된다. 여기서 흥미로운 사실은 소스 프로그램은 자신이 "VM"에 있다는 것을 인지하지 못한다.


왜 상하관계라고 다른분이 표현했는지는 아직 잘 모르겠지만 소스프로그램과 VM은 상하관계에 놓인다고 한다. 

VM이 상위 소스프로그램이 하위인 것 같다. 


반가상화는 (반만 가상화라는 의미) 명령어 일부는 CPU가 직접 실행, 나머지는 VM이 실행시키는 구조를 말한다. 전가상화에서는 소스프로그램과 VM이 상하관계로 나뉘어 졌다면, 반 가상화는 "둘은 동등한 관계(소스프로그램과 VM)를 지닌다"

CPU가 기존 기계어들을 실행시키다가 VM을 요청 받게 되면, CPU는 명령어 실행 권한을 VM에게 넘기게 된다. 그 후 VM은 가상화 된 명령어를 실행할 것이고 다 실행했으면 다시 CPU에게 실행 권한을 넘겨주게 된다. 

권한을 넘겨줄 수 있는 행위가 "동등하다고 표현하는갑다."


권한을 넘겨줄 수 있다는 것은 메모리 영역도 공유하게 된다는 것이다.

이것을 쉽게 이해하기 위해 달리기 릴레이에서 '배턴'을 넘기는 행위를 상상해보았다.

A주자는 열심히 달리다가 B주자에게 "달릴 수 있는 권한"을 준다. 

권한을 주기 위해 '배턴'을 넘겨준다. 그렇다면 '배턴'을 메모리 영역으로 생각할 수 있다.


메모리 영역을 공유하면, 서로의 영역을 넘보다가 침범할 수 있는 문제가 발생할 수도 있다.. 

따라서 메모리 영역을 침해받지 않기 위해 가상메모리를 사용하는 것 같다.




'0x03 Reversing Theory' 카테고리의 다른 글

GCC Asembler  (0) 2017.12.06
따라만들어보는 VCP - 상상만 하던걸 드디어..!  (3) 2017.12.05
ELF 기초 공부중  (0) 2017.12.05
installing xv6 in ubuntu  (0) 2017.10.19
[First Document] D0 you Know Anti-Debugging  (0) 2017.08.24