티스토리 뷰

반응형

수많은 안티디버깅 기법이 있지만, 이번에 소개할 코드가상화 기법은 사실상 안티디버깅이라고 보기는 힘들다.

안티디버깅 보다는 코드 난독화쪽에 가까운 기법을 소개하겠다.

 

우선 자세한 내용을 들어가기 전에, 개발자 관점에서 VCP를 구현하기 위해 생각해야되는 점들을 보겠다.

  • 원래 코드를 어떻게 변환시킬 것인가? (Binary Translation) → 이 후 포스트에서 살펴볼 예정이다.
  • 변환된 코드는 VM(Virtual Machin)에서 어떻게 실행을 시킬것인가? ★★★
  • 변환된 코드와 VM을 PE파일에 어떻게 포함시킬 것인가?
  • 어떻게 해야 해석하기 어려운 변환코드를 만들 수 있을까? (opcode의 랜덤화)
    이럴경우 어떻게 접근해야되는지 생각해보자.

 

 

코드가상화 기법이 적용된 프로그램을 살펴보면 보통 아래와 같이 구성되어 있다.

(해당 포스트에서는 전가상화 기법은 포함하지 않고, 반가상화 기법에 대해서만 다루겠다.)

 

 

코드 가상화가 적용된 프로그램 흐름

 

<프로그램 구성>

  • Source Program#1
  • Stub Code  → push "Virtualized Code Addr" 명령어가 가상화 코드로 변환되어 저장된 주소
                                                                   (가상화 코드로 변환하는 내용은 나중에 다룸)

                      jmp "VM" → 변환된 명령어를 실행할 수 있는 Virtual CPU쪽 흐름으로 jump
  • Source program#2

 

 

정말 간단해 보이지만 사실 Source Program#1, #2만 살펴보면 뭔가 비어있다는 느낌이 들것이다.

이 사이에는 코드 가상화된 코드가 생략되어 있는 것이다. 그러면 이건 어디에 있을까?

아래 프로그램 흐름을 보자.

 

  • Stack영역을 확보 → push ebp
                               sub esp, 0x300
                               mov ebp, esp
                               sub esp, 0x100
  • State Switching → 기존에 사용하던 Register정보, 가상화 코드에서 사용해야 하는 데이터를 위에서 확보한
                             Stack에 저장하는 과정이다. (이 주소를 반드시 기억하자)
  • Virtualized Code Addr을 반복실행 → 실질적으로 VM이 Virtualized Code를 실행 시키는 과정
  • State Switching Back
             → 원래 프로그램 흐름으로 복귀하기위해 Register정보, 스택 정리 등을 수행하는 과정

 

위 프로그램 흐름은 가상화된 코드를 실행하고 가상화 되지 않은 원래 코드로 흐름 전환을 하기까지이다.

 

우선 첫 번째 프로그램 흐름에서 Source Code#1을 진행하다가, Stub Code를 만난다. 여기서 Stub Code란 무엇이냐면 우리가 프로그램을 실행하던 CPU가 가상화된 코드를 실행할 VM CPU에게 프로그램 흐름을 넘겨주기 위해서 존재하는 녀석이라고 생각하면 된다. Stub Code를 만남으로써 프로그램 흐름은 바로 밑인 Source Code#2가 아니라, 지정된 VM주소로 jump하게 된다.

 

 

그러면 두 번째 프로그램 흐름을 살펴보겠다. (이쪽 흐름으로 jump했다는건 VM CPU가 흐름을 잡았다는 뜻!)

 

가장 먼저 Virtualized Code 를 수행하면서 사용할 Register 및 Stack 영역이 필요하다.

         (당연하겠지만, 기존에 사용하던 Register 및 Stack 영역을 같이 사용할 수 없다.)

그러므로 이 영역에 대한 작업을 가장먼저 진행한다.

 

                                                            (이 과정을 State Switching 이라고 한다.)

그리고 나서 두번째로 각 레지스터를 조금전 확보했던 스택영역에 하나씩 복사해서 저장하기 시작한다.

분석을 하다보면 이 주소를 통해 Register 정보 및 Stack 영역을 확인해야 하므로 반드시 dump창에 띄워두자 !!

 

그 후, 반복문을 돌면서 내가 변환한 Virtualized Code를 실행하기 시작하는데, 이 과정을 통해 난독화 시킨 코드부분이 실행되는 것이다. (VM의 주기능 이라고 보면 된다.)

이 때 기억해야 할 점은, Virtualized Code Table을 통해, Virtualized Code의 opcode를 참고해 opcode마다 서로다른 함수를 호출하게 된다. 이걸 opcode에 대한 handler라고 표현한다. 즉, 기존의 mov, add, del 등의 handler를 사용하는게 아니라 내가 변환한 Virtualized Code가 제대로 동작할수있는 my_mov, my_add, my_del을 구성해두고 실행하는 것이다. 이 함수(handler)들의 주소는 마찬가지로 어딘가에 저장되어있는데, 분석시 이 주소도 반드시 dump창에 띄워두자 !! 보통 Virtualized_Code_Table[opcode] 이와같이 접근해서 서로다른 함수를 호출하게 된다.

 

 

 

<스택구성>

 스택 구성은 위에서 어느정도 설명했기 때문에, 그림 하나만 확인하고 넘어가겠다.

VM Stack 구성도

하나만 기억하자면, 이 Stack 의 주소는 가상화코드를 실행하면서 매우매우 중요한 요소다. 이 주소를 기억 못한다는 것은, Register없이 프로그램을 진행한다는 뜻과 동일하다. 그래서 항상 Handler 함수를 호출할 때에도 매개변수로 Stack의 주소를 가져가게 된다.

 

 

 

<Virtualized Code 실행과정>

기본적으로 Virtualized Code 를 실행하는 함수 구성

 

BYTE opcode; 
while(true) {
       opcode = GetBytes(RegisterBlock.eip); → 여기서 RegisterBlock.eip는 레지스터 스택에 위치한다.

       opcode_handler_table[opcode].handler(); → 해당 opcode의 handler를 호출할 때는 반드시 Register와

                                                                   data가 저장된 Stack Address를 인자로 가져가야한다.

         → 여기서 opcode_handler_table은 handler 함수의 주소가 담긴 영역이다.

             인덱스(opcode) 로 어떤 함수(handler)를 호출할 지 결정한다.

       적적히 eip 증가;
}

 

위 코드에서 handler에서는 opcode 이후에 나오는 값들로 그에 따라서 다르게 동작한다.

( 조건문에 따른 여러가지 동작을 한다. 이 내용은 이후 가상화 코드 변환 포스트에서 자세히 설명하겠다.)

그리고 EIP를 다음 명령어의 opcode를 가리키게 증가시킨다. 아래는 그 증가시키는 코드이다.

 

EIP = pBlock->EIP;

EIP++;

operandinfo = *(operandinfo*)EIP;

EIP += sizeof(operandinfo);

op_data1 = *(int*)EIP;

EIP += sizeof(op_data1);

op_data2 = *(int*)EIP;

EIP += sizeof(op_data2);

pBlock->EIP = EIP;

 

실제로 분석해본 결과 귀신같이 위와같이 동작했다. 

반응형

'Reversing > Anti Debugging' 카테고리의 다른 글

[Anti Debugging] Virtualized Code 변환  (0) 2019.05.24
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함