• 검색 결과가 없습니다.

저작자표시

N/A
N/A
Protected

Academic year: 2022

Share "저작자표시"

Copied!
28
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

저작자표시-비영리-변경금지 2.0 대한민국 이용자는 아래의 조건을 따르는 경우에 한하여 자유롭게

l 이 저작물을 복제, 배포, 전송, 전시, 공연 및 방송할 수 있습니다. 다음과 같은 조건을 따라야 합니다:

l 귀하는, 이 저작물의 재이용이나 배포의 경우, 이 저작물에 적용된 이용허락조건 을 명확하게 나타내어야 합니다.

l 저작권자로부터 별도의 허가를 받으면 이러한 조건들은 적용되지 않습니다.

저작권법에 따른 이용자의 권리는 위의 내용에 의하여 영향을 받지 않습니다. 이것은 이용허락규약(Legal Code)을 이해하기 쉽게 요약한 것입니다.

Disclaimer

저작자표시. 귀하는 원저작자를 표시하여야 합니다.

비영리. 귀하는 이 저작물을 영리 목적으로 이용할 수 없습니다.

변경금지. 귀하는 이 저작물을 개작, 변형 또는 가공할 수 없습니다.

(2)

공학석사학위논문

가상머신 난독화 코드의 정적분석

Static analysis of virtualization obfuscated codes

2014 년 2 월

서울대학교 대학원

전기.컴퓨터 공학부

이 영 석

(3)

가상머신 난독화 코드의 정적분석

Static analysis of virtualization obfuscated codes

지도교수 이 광 근

이 논문을 공학석사 학위논문으로 제출함

2014 년 2 월

서울대학교 대학원

전기.컴퓨터 공학부

이 영 석

이영석의 공학석사 학위논문을 인준함

2014 년 2 월

위 원 장 이상구 (인)

부위원장 이광근 (인)

위 원 김선 (인)

(4)

요약

가상머신 난독화 코드의 정적분석을 위해 알아보기 쉬운 프로그램으로 변 환하는방법을 설명하였다. 코드 언어와 인터프리터 언어를 디자인 했으며, 그 것의 실행 의미를 정의하였다. 프로그램 카운터 변수와 코드 부분, 인터프리터 부분을 알고 있다면, 가상머신 난독화 코드를 보기 쉬운 인터프리터 언어로된 프로그램으로 변환 할 수 있다. 이러한 변환을 통해 쉽게 분석할 수 없는 가상 머신 난독화 코드를 정적분석 가능하게 할 수 있다.

주요어: 가상머신 난독화, 프로그램 분석, 정적분석, 악성코드, 변환 학번: 2011-23376

(5)

목차

요약 i

목차 ii

그림 목차 iv

제 1 장 서론 1

1.1 동기 . . . 1

1.2 목표 . . . 2

1.3 가상 머신 난독화 코드의 변환 예 . . . 3

1.4 논문 구성 . . . 5

제 2 장 언어 6 2.1 코드 언어 . . . 6

2.2 인터프리터 언어 . . . 7

2.3 실행 의미 . . . 8

제 3 장 변환 11 3.1 공간 . . . 14

3.2 대입문의 변환 . . . 14

3.3 조건문의 변환 . . . 14

3.4 재귀호출의 변환 . . . 15

3.5 식의 변환 . . . 15

(6)

제 4 장 한계 및 관련 연구 16 4.1 언어의 한계 . . . 16 4.2 변환의 한계 . . . 17

제 5 장 관련 연구 18

제 6 장 결론 19

참고문헌 20

(7)

그림 목차

그림 1.1 가상 머신 인터프리터 예 . . . 3

그림 1.2 데이터형식의 코드 예 . . . 4

그림 1.3 변환된 코드 . . . 4

그림 2.1 코드 언어 정의 . . . 6

그림 2.2 인터프리터 언어 정의 . . . 7

그림 2.3 의미 공간 정의 . . . 8

그림 2.4 실행 의미 정의 1 . . . 9

그림 2.5 실행 의미 정의 2 . . . 10

그림 3.1 변환에 사용되는 공간 . . . 11

그림 3.2 변환 규칙 1 . . . 11

그림 3.3 변환 규칙 2 . . . 12

그림 3.4 변환 규칙 3 . . . 13

그림 3.5 eval 함수의 정의 . . . 13

(8)

제 1 장 서론

1.1 동기

코드의 분석을 어렵게 하는 난독화 방법은 여러가지다. 간단한 방법으로는 프로그램의 소스 코드를 알아보기 힘들게 바꾸는 것이 있다. 아무 일도 하지 않는 데드 코드를 삽입 하거나 필요 이상으로 복잡한 코드를 만들어 가독성을 줄이는 방법이다. 컴파일 된 후의 바이너리 코드를 난독화 하는 방법도 있다.

기존의 바이너리 명령어들을 좀더 복잡하게 변경하여 역공학을 어렵게 할 수 있다.

그 중에서도 가상 머신 난독화는 정적으로 분석하기 매우 까다롭다. 가상 머신 난독화된 코드는 가상 머신 인터프리터와 난독화된 코드로 이루어져 있 다. 일반적인 코드를 실행 시키는 것과는 달리 따로 작성 되어있는 인터프리 터가 난독화된 코드를 실행한다. 코드의 겉모습만 보고는 그 코드의 작동을 알아보기 매우 힘들기 때문에 역공학을 막는 효과적인 방법이라 할 수 있다.

이러한 난독화를 도와주는 상용도구도 존재한다.

이러한 난독화의 목적은 크게 두 가지다. 첫 번째로는 상용화된 프로그램 을 보호하려는 목적이 있다. 중요 알고리즘 등의 유출을 막기 위해 난독화를 이용하면 충분히 효과적으로 방어할 수 있다. 두 번째로는 악성 행동을 감추기 위한 것이다. 실제로 많은 악성코드들은 여러 난독화 기법을 사용하여 백신의 탐지를 회피하고 있다. 간단한 난독화만으로도 기존 백신 시스템의 탐지율을 55%나 떨어뜨릴 수 있다.

이 연구의 목적은가상 머신 난독화 코드를 정적으로 분석하는 것이다. 특히 나날이 증가하고 있는 난독화된 악성코드에 발맞추어 가상 머신 난독화 코드

(9)

의 분석의 방향을 제시하고자 한다. 기존의 백신 기술들은 악성코드의 명령어 패턴을 검색하는 지문 탐지 방식이다. 이러한 방식으로는 가상 머신 난독화된 악성코드를 감지 할 수 없다. 수많은 변종을 만들어 낼 수 있는 난독화 기법이 기 때문에 지문 탐지 방식은 적절하지 않다. 이 연구에서는 가상 머신 난독화 코드를 인터프리터를 작성한 언어로 변환 하여 의미 기반 분석을 할 수 있음을 보인다.

1.2 목표

가상 머신 난독화 기법은 코드를 데이터로 바꾸어 가상 머신 인터프리터 위에서 실행시킨다. 일반적인 코드와는 달리 겉으로 보이는 부분이 인터프리터 와 데이터형식의 난독화된 코드이다. 그렇기 때문에 기존 코드에 비해 굉장히 복잡하며 가독성이 현저하게 떨어진다.

이 연구에서는 가상머신 난독화 코드에서 데이터형식의 코드를 인터프리 터의 언어로 변환하고자 한다. 데이터형식의 코드는 인터프리터의 동작을 정 확하게 이해하지 못하면 원래 프로그램의 의도를 파악 할 수가 없다. 그러나 인터프리터의 언어로 변환을 하게 되면, 읽을 수 있는 코드가 생성이 된다. 전혀 알아볼 수 없는 정수의 배열이 그래도 알아 볼 수 있는 어셈블리 언어로 작성된 프로그램으로 바뀌는 것으로 생각할 수 있다.

이러한변환의 장점은 여러가지가 있다. 인터프리터가 작성된 언어로 변환 을 했다는 것은 그 코드에 대해 여러 가지 분석을 가능하게 해준다. 실행 흐름 그래프를 미리 작성할 수 있어 난독화된 코드를 쉽게 이해 할 수 있다. 또한 해 당 언어를 분석하는 분석기가 있다면 그 코드의 행동을 분석할 수 있게 해준다.

특히 의미 기반 분석이 가능하다는 장점은 매우 매력적이다. 가상 머신 난 독화 기법을 사용한 악성코드의 경우, 무한히 많은 변종을 생성할 수 있다. 이 러한 악성코드에 대해서는 기존의 지문 탐지 방식의 백신으로는 탐지해낼 수

(10)

없다. ScanDal[1]과 같은 개인정보 누출을 의미 기반 분석을 통해 탐지해 내 는 분석기가 필요하다. 이러한 의미 기반 분석을 가능하게 해주는 변환은 매우 효과적이다.

1.3 가상 머신 난독화 코드의 변환 예

그림 1.1 가상 머신 인터프리터 예

데이터형식의 코드를 인터프리터의 언어로 변환한 예를 소개한다. 그림 1.1 은 코드를 실행하는 인터프리터, 그림 1.2은 데이터형식의 코드의 예이다. 해 당 프로그램은 10부터 1까지 더한 수를 레지스터 0번에 저장하는 코드이다.

이러한 인터프리터와 코드를 가지고 인터프리터의 언어로 작성된 같은 의미의

(11)

그림 1.2 데이터형식의 코드 예

그림 1.3 변환된 코드

(12)

프로그램으로 변환한다. 코드의 실행 결과로 동일하게 레지스터 0번에 55가 저장된다. 변환된 코드는 그림 1.3와 같다.

1.4 논문 구성

이 논문은 다음과 같이 구성된다. 2장에서는 인터프리터와 코드 언어를 디 자인하고 그것의 실행의미를 정의한다. 3장에서는 인터프리터와 데이터형식의 코드를 인터프리터의 언어로 변환하는 과정을 설명한다. 4장과 5장에서는 이 연구의 한계와 관련연구에 대해 논한다. 마지막으로 6장에서 결론을 내린다.

(13)

제 2 장 언어

변환을 위해서 코드 언어와 인터프리터 언어를 정의한다. 인터프리터 언 어는 임의의 모든 인터프리터를 표현할 수 있게 디자인했다. 또한 코드언어도 임의의 바이너리 코드를 표현할 수 있으면서 간단하게 디자인했다. 또한 해당 언어의 실행의미도 엄밀하게 정의한다.

2.1 코드 언어

Cc → Cc; Cc

| xc:= ec

| jmpcxcidx

| run xc ec → n | xc

| xc+ xc| − xc

| ?

| box Cc

| box ((unbox xc); (unbox xc)

그림 2.1 코드 언어 정의

코드언어는 크게 대입문, 조건부 분기문, 생성된 코드를 실행하는 실행문 으로 이루어져있다. 이 언어로 임의의 바이너리 코드를 표현할 수 있을 뿐만 아니라 2단계 프로그램까지 작성할 수 있다. box 식과 대입문을 이용하여 변수

(14)

에 코드를 저장하고, box와 unbox의 결합된 식으로 코드 두개를 합칠 수 있다.

그 정의는 그림 2.1이다.

2.2 인터프리터 언어

Interpreter I → fun f (code){pc := 0; while cond C}

Cmd C → C; C

| lv := e

| if cond C C

| label l | goto l

| f (lv)

Condition cond → code[pc + n] = ce | lv > e Cond − exp ce → := | jmp | run

| num | var | plus | minus | top | box | buu

Exp e → n | e + e | lv | code[pc + n] | read() | code(Cc) | merge(lv, lv) L − exp lv → x | r[e] | pc

그림 2.2 인터프리터 언어 정의

인터프리터는 루프를 포함하고 있는 함수로 정의한다. box식과 merge식을 이용하여 코드언어의 2단계 프로그램의 성질을 가진 식을 표현할 수 있다. 그 코드의 실행은 인터프리터 함수의 재귀호출인 f (lv)로 표현 가능하다.

또한 인터프리터 내의 변수들을 특성에 따라 구분한다. 코드언어의 프로 그램 카운터에 해당하는 pc변수가 구분되어 있다. 또한 인터프리터 내부에서 사용하는 변수와 전역 변수와 같은 역할을 하는 레지스터 변수를 따로 구분한 다. 마지막으로 데이터형식의 코드내용을 접근하는 식도 따로 구분한다. 그림

(15)

2.2에서 인터프리터 언어의 정의를 볼 수 있다.

2.3 실행 의미

Interpreter = Code × cond × BODY × Env σ ∈ Env = Id→ Addr + Interpreterfin M ∈ M em = Addr→ V alfin

R ∈ Resisters = Int→ V alfin

그림 2.3 의미 공간 정의

인터프리터 언어의 실행의미와 의미공간을 정의한다. 우선 의미공간의 정 의는 그림 2.3이다. 인터프리터 내부에서 사용하는 변수는 메모리에 저장되고, 전역변수처럼 사용되는 레지스터는 레지스터 메모리에 따로 저장한다. 재귀 함수 호출을 위해 환경 속에 변수의 주소 혹은 그 변수가 함수라면 그 함수의 내용을 저장한다. 그에 따른 실행의미의 정의는 그림 2.4,2.5이다.

(16)

σ0, M0, R0 `condcond ⇒ f alse

σ0, M0, R0 ` fun f (Cc){while cond BODY } ⇒ M0, R0

σ0, M0, R0 `condcond ⇒ true

init(σ0{f 7→< Cc, cond, BODY, σ0>}), M0, R0 `cBODY ⇒ M, R σ0, M, R ` fun f (Cc){while cond BODY } ⇒ M1, R1

σ0, M0, R0 ` fun f (Cc){while cond BODY } ⇒ M1, R1

σ, M, R `cC1 ⇒ M1, R1 σ, M1, R1 `cC2 ⇒ M2, R2 σ, M, R `cC1; C2 ⇒ M2, R2

σ, M, R `ee ⇒ n

σ, M, R `cx := e ⇒ M {σ(x) 7→ n}, R σ, M, R `ee1⇒ n1 σ, M, R `ee2⇒ n2 σ, M, R `cr[e1] := e2 ⇒ M, R{n1 7→ n2}

σ, M, R `ee ⇒ n

σ, M, R `cpc := e ⇒ M {σ(pc) 7→ n}, R σ, M, R `cond cond ⇒ true σ, M, R `cC1 ⇒ M1, R1

σ, M, R `cif cond C1 C2⇒ M1, R1

σ, M, R `cond cond ⇒ f alse σ, M, R `cC2⇒ M1, R1

σ, M, R `cif cond C1 C2⇒ M1, R1

σ, M, R `clabel l ⇒ M, R

σ(f ) =< Cc, BODY, σ0 > σ, M, R `cnextl(BODY ) ⇒ M1, R1 σ, M, R `cgoto l ⇒ M1, R1

σ(f ) =< Cc, BODY, σ0>

σ, M, R `elv ⇒ Cc0 init(σ0{f 7→< Cc0, BODY, σ0 >}), M, R `cBODY ⇒ M0, R0 σ, M, R `cf (lv) ⇒ M0, R0

그림 2.4 실행 의미 정의 1

(17)

σ, M, R `ecode[pc + n] ⇒ ce σ, M, R `condcode[pc + n] = ce ⇒ true σ, M, R `ecode[pc + n] ⇒ ce0 ce0 6= ce σ, M, R `condcode[pc + n] = ce ⇒ f alse σ, M, R `elv ⇒ n1 σ, M, R `ee ⇒ n2 n1 > n2

σ, M, R `cond lv > e ⇒ true

σ, M, R `elv ⇒ n1 σ, M, R `ee ⇒ n2 n1 ≤ n2 σ, M, R `condlv > e ⇒ f alse

σ, M, R `e n ⇒ n

σ, M, R `e e1 ⇒ n1 σ, M, R `ee2 ⇒ n2 σ, M, R `ee1+ e2 ⇒ n1+ n2

σ, M, R `e x ⇒ M (σ(x)) σ, M, R `ee ⇒ n σ, M, R `e r[e] ⇒ R(n)

σ, M, R `e pc ⇒ M (σ(pc))

σ(f ) =< Cc, BODY, σ0 > M (σ(pc)) = n1 index(Cc, n1+ n) = v σ, M, R `e code[pc + n] ⇒ v

σ, M, R `e read() ⇒ M (σ(x))

σ, M, R `ecode(Cc) ⇒ Cc

σ, M, R `e lv1⇒ Cc1 σ, M, R `elv2⇒ Cc2 σ, M, R `emerge(lv1, lv2) ⇒ Cc1; Cc2

그림 2.5 실행 의미 정의 2

(18)

제 3 장 변환

σ ∈ Env = V ar→ V ar + Cfin M ∈ M emory = V ar→ V alfin

L ∈ Labels = 2Z V al = Z ∪ Cc

그림 3.1 변환에 사용되는 공간

Code translation σ, M, L, cond, C ` Cc7→ C0, σ0, M0, L0

σ, M, L, cond, C ` Cc17→ C1, σ1, M1, L1 σ1, M1, L1, cond, C ` Cc27→ C2, σ2M2, L2 σ, M, L, cond, C ` Cc1; Cc27→ C1; C2, σ2, M2, L2

σ, M, L `iC(xc:= ec) 7→ C0, σ0, M0, L0

σ, M, L, cond, C ` xc:= ec7→ C0, σ0, M0, L0 (satisfy cond with M ) σ, M, L `iC(jmpcxcidx) 7→ C0, σ0, M0, L0

σ, M, L, cond, C ` jmpcxcidx 7→ C0, σ0, M0, L0 (satisfy cond with M ) σ, M, L `iC(run xcidx) 7→ C0, σ0, M0, L0

σ, M, L, cond, C ` run xc 7→ C0, σ0, M0, L0 (satisfy cond with M )

그림 3.2 변환 규칙 1

인터프리터와 코드 프로그램을 받아 코드를 인터프리터 언어로 작성된 프 로그램으로변환한다. 자세한 변환 규칙은 그림 3.2, 3.3, 3.4 이다. fun f (code){pc :=

0; while cond C} 로 되어있는 인터프리터와 그 인자로 들어가는 코드 Cc

(19)

I & codedata translation σ, M, L `i C(Cc) 7→ C0, σ0, M0, L0

σ, M, L `i C1 (Cc) 7→ C10, σ1, M1, L1 σ1, M1, L1 `iC2 (Cc) 7→ C20, σ2, M2, L2

σ, M, L `iC1; C2 (Cc) 7→ C10; C20, σ2, M2, L2 eval(M, e, Cc) = n x /∈ dom(σ)

σ, M, L `i x := e (Cc) 7→ x0 := n, σ{x 7→ x0}, M {x 7→ n}, L (new x0) eval(M, e, Cc) = n σ(x) = x0

σ, M, L `ix := e (Cc) 7→ x0 := n, σ, M {x 7→ n}, L eval(M, e, Cc) = e0 x /∈ dom(σ)

σ, M, L `i x := e (Cc) 7→ x0 := e0, σ{x 7→ x0}, M, L (new x0) eval(M, e, Cc) = e0 σ(x) = x0

σ, M, L `i x := e (Cc) 7→ x0 := e0, σ, M, L eval(M, e1, Cc) = e01 eval(M, e2, Cc) = e02

σ, M, L `ir[e1] := e2 (Cc) 7→ r[e01] := e02, σ{x 7→ x0}, M, L (new x0) eval(M, pc + n, Cc) = n1 ∈ L/

σ, M, L `i pc := code[pc + n] (Cc) 7→ goto n1, M, L eval(M, e, Cc) = n /∈ L

σ, M, L `i pc := e (Cc) 7→ label n; pc := n, M {pc 7→ n}, L ∪ {n}

eval(M, e, Cc) = n ∈ L

σ, M, L `ipc := e (Cc) 7→ goto n, M, L σ, M, L `i C1(Cc) 7→ C10, M1, L1 σ, M, L `i C2(Cc) 7→ C20, M2, L2

eval(M, e, Cc) = e1 M (pc) = M1(pc)

σ, M, L `iif lv > e C1 C2 (Cc) 7→ if lv > e1 C10 C20, M2, L2

σ, M, L `i C1(Cc) 7→ C10, M1, L1 σ, M, L `i C2(Cc) 7→ C20, M2, L2 eval(M, e, Cc) = e1 M (pc) = M2(pc)

σ, M, L `iif lv > e C1 C2 (Cc) 7→ if lv > e1 C10 C20, M1, L1

그림 3.3 변환 규칙 2

(20)

eval(M, code[pc + n], Cc) = ce σ, M, L `iC1 (Cc) 7→ C10, M1, L1

σ, M, L `iif code[pc + n] = ce C1 C2 (Cc) 7→ C10, M1, L1

eval(M, code[pc + n], Cc) = ce0 ce0 6= ce σ, M, L `iC2 (Cc) 7→ C20, M2, L2

σ, M, L `iif code[pc + n] = ce C1 C2 (Cc) 7→ C20, M2, L2

eval(M, lv, Cc) = Cc0 σ(f ) = C σ0, M, L0`i C(Cc0) 7→ C0, σ00, M0, L00 σ, M, L `if (lv) (Cc) 7→ C0, σ, M0, L

그림 3.4 변환 규칙 3

eval : M emory × Exp × Cc→ Exp ∪ Cond − exp

eval(M, n, Cc) = n

eval(M, x, Cc) = M (x)(if x ∈ dom(M )) eval(M, x, Cc) = x (if x /∈ dom(M )) eval(M, pc, Cc) = M (pc)

eval(M, r[e], Cc) = r[eval(M, e, (Cc))]

eval(M, code[pc + n], Cc) = index(Cc, M (pc) + n) eval(M, read(), Cc) = read()

eval(M, code(Cc1), Cc2) = Cc1

eval(M, merge(lv1, lv2), Cc) = Cc1; Cc2(if M (lv1) = Cc1 ∧ M (lv2) = Cc2) eval(M, e1+ e2, Cc) = n (if eval(M, ei, Cc) = ni ∧ n = n1+ n2) eval(M, e1+ e2, Cc) = eval(M, e1, Cc) + eval(M, e2, Cc)

그림 3.5 eval 함수의 정의

(21)

를 인터프리터 언어로 작성된 C0으로 변환을 하게된다. 변환 규칙의 시작은

∅, ∅, ∅, cond, C ` Cc7→ C0, σ, M, L 이다. Cc는 코드 언어로 되어있는 프로그램 을 데이터형식으로 표현한 것이다.

3.1 공간

공간은 환경과 메모리, 레이블의 집합으로 이루어져있다. 환경에는 재귀함 수 호출시에 변경해야할 변수들의 이름, 그 변수가 함수일 경우 함수의 내용이 들어간다. 메모리에는 상수가 대입되는 변수들의 값이 저장된다. 레이블의 셋 에는 변환을 했던 코드에 해당하는 프로그램 카운터값들을 저장한다. 공간의 정의는 그림 3.1으로 한다.

3.2 대입문의 변환

일반 변수의 대입문과 프로그램 카운터 변수의 대입문이 다르다. 일반 변수 의 대입문은 상수 대입이 확실한경우에는 대입하는 식을 상수로 바꾸어 준다.

단 레지스터변수를 대입할 경우에는 상수여도 그대로 둔다. 그 이유는 인터프 리터 루프를 계속 돌면서 레지스터변수가 계속 바뀔 수 있기 때문이다. 프로그 램 카운터 변수에 대입할 경우에는 label과 goto문을 사용한다. 이미 변환을 한 지점으로 프로그램 카운터 값이 바뀔 경우에는 goto문으로, 변환을 해야하 는 지점으로 프로그램 카운터 값이 바뀌는 경우에는 label문으로 변환한다.

3.3 조건문의 변환

조건문에는 코드의 내용을 확인하는 것과 변수의 내용을 확인하는 것 두 종 류가 있다. 코드의 내용을 확인하는 경우에는 코드가 항상 상수이므로 조건문 으로 변환하는 것이 아니라 조건문에 맞게 실행하는 코드만 변환한다. 변수의

(22)

내용을 확인하는 경우에는 if문으로 변환하며 이 경우에는 프로그램 카운터의 값이 코드의 내용으로 점프하는 경우가 생긴다.

3.4 재귀호출의 변환

재귀호출의 변환에서 중요한 것은 변수의 이름을 바꾸는 것이다. 실제 인 터프리터 프로그램에서의 변수이름은 같지만 변환 했을 경우에는 재귀호출 안 에서의 변수와 밖의 변수의 이름이 달라야 한다. 그 정보를 환경에 저장하고 재귀호출시에는 환경을 초기화하는 방법을 사용한다.

3.5 식의 변환

식의 변환은 eval함수를 통해 이루어진다. 식을 변환 할 때에는 해당 변수 가 상수대입을 한 적이 있는지 확인한다. 레지스터 변수가 아닌 일반 변수가 상수인 것이 확실 할 때에는 상수로 변환을 한다. 식의 부품들도 마찬가지로 상수인지 확인하고 변환한다. eval함수의 정의는 그림 3.5으로 한다.

(23)

제 4 장 한계 및 관련 연구

4.1 언어의 한계

인터프리터 언어에서 프로그램 카운터 변수를 다른 변수들과 구분하고 있 다. 이것은 인터프리터 코드 안에서 프로그램 카운터에 해당하는 변수가 무 엇인지 정확하게 알고 있다고 가정한다는 뜻이다. 실제로 임의의 인터프리터 코드를 보면서 프로그램 카운터에 해당하는 변수를 찾는 것은 쉬운 문제가 아 니다. 이 변수를 찾기 위한 방법으로 변수가 가질 수 있는 값의 개수를 분석하 는 방법이 있다. 코드의 크기는 유한하기 때문에 프로그램 카운터가 가질 수 있는 값의 개수도 당연히 유한하다. 인터프리터 코드를 분석하여 유한한 개수 의 값을 가질 수 있는 변수들을 찾으면 그것들 중 하나가 프로그램 카운터에 해당하는 변수라 생각할 수 있다. 그러나 그러한 변수가 여러개 있을 경우에 문제가 된다. 앞으로 연구해야 할 부분이다.

또한 코드의 내용에 접근하는 식이 일반 변수에 접근하는 식과 구분되어 있다. 이것은 코드와 인터프리터 각각에 해당하는 부분을 정확하게 알고 있다 고 할 수 있다. 그러나 실제 코드에서 가상머신 난독화된 부분을 찾는 것 또한 쉬운 문제가 아니다. 또한 가상머신 난독화 코드에서 인터프리터와 코드를 정 확하게 구분 할 수 있어야 그 코드를 인터프리터 언어의 정의에 맞춰 작성할 수 있을 것이다.

이 연구는 프로그램 카운터 변수와 코드 부분, 인터프리터 부분을 정확하게 알고 있다고 가정하고 진행하였다. 이것들을 다 알고 있을 경우에 가상머신 인 터프리터와 코드를 인터프리터 언어로 된 프로그램으로 변환 할 수 있다. 위의 것을 알아내는 부분은 향후 연구 과제라고 할 수 있다.

(24)

4.2 변환의 한계

변환 규칙으로 변환하지 못하는 인터프리터 프로그램이 존재할 수 있다.

예를 들어 프로그램 카운터 변수에 입력 값이 들어가 임의의 지점으로 점프를 하는경우에 대한 변환 규칙은 없다. 변환 규칙이 없다는 것은 해당 프로그램을 변환할 수 없다는 것을 의미하기 때문에, 모든 가상머신 난독화 코드를 변환할 수는 없다라고 생각할 수 있다.

그러나위와 같은 경우는 제대로 된 인터프리터라 할 수 없기 때문에 크게 문제되지 않는다. 실제로 프로그램 카운터 변수에 임의의 값이 들어가게 되면 매우 운이 좋지 않은 이상 제대로 동작하지 않기 때문이다. 이런 식으로 제대로 동작 하지 않는 인터프리터 프로그램에 대한 변환규칙은 정의되지 않았다.

(25)

제 5 장 관련 연구

정적으로 악성코드를 검출하기 위한 연구로 [2]가 있다. 지문탐지 기법으 로는 찾아낼 수 없는 악성코드를 찾아낼 수 있지만 가상머신 난독화 코드를 포함하지는 않는다.

정적으로 가상머신 난독화 코드를 분석하는 연구로는 [3]가 있다. 이 연구 에서는 pc값에 대해 민감하게 요약해석[4, 5, 6]을 이용하여 분석하는 방법을 사용한다. 이 방법은 실행 흐름 그래프가 직관적이지 않고 복잡하게 그려지는 단점이 있다.

역공학을 이용하여 가상머신 난독화 코드의 분석하는 연구에는 [7]가 있다.

이 연구에서는 타겟 난독화 도구에 특화된 역공학 방법을 설명하고 있다.

(26)

제 6 장 결론

이 논문에서는가상머신 난독화 코드의 정적분석을 위해 간단한 프로그램 으로 변환하는 방법을 설명하였다. 그것을 위해 인터프리터 언어와 코드 언어 를 정의하였으며, 인터프리터와 코드를 받아 인터프리터 언어로 된 프로그램 으로변환하는 규칙을 정의하였다. 인터프리터의 프로그램 카운터 변수를 알고 있고, 코드 부분과 인터프리터 부분을 정확하게 알고 있다면, 미리 실행 흐름 그래프를 그릴 수 있는 인터프리터 언어로 된 프로그램으로 변환 할 수 있음을 보였다.

(27)

참고문헌

[1] Jinyung Kim, Yongho Yoon, and Kwangkeun Yi, “SCANDAL: Static An- alyzer for Detecting Privacy Leaks in Android Applications,”, in Mobile Security Technologies 2012, a part of the IEEE Computer Society Security and Privacy Workshops, San Fransisco, USA, May 2012.

[2] Seung Jung Lee and Kwangkeun Yi, “정적으로 악성코드를 검출하기 위한 행동 기술 언어의 설계,” in 한국정보과학회 2012한국컴퓨터 학술발표논 문집, June 2012.

[3] Kinder, Johannes. “Towards static analysis of virtualization-obfuscated bi- naries,” in Reverse Engineering, 2012 19th Working Conference on IEEE, October 2012. pp. 61-70.

[4] Patrick Cousot and Radhia Cousot, “Abstract Interpretation: a Unified Lattice Model for Static Analysis of Programs by Construction or Approx- imation of Fixpoints,” in Proceedings of ACM Symposium on Principles of Programming Languages, January 1977. pp. 238-252.

[5] Patrick Cousot and Radhia Cousot, “Systematic design of program analy- sis frameworks,”, in Proceedings of ACM Symposium on Principles of Pro- gramming Languages, 1979. pp. 269-282.

[6] Patrick Cousot and Radhia Cousot, “Comparing the Galois Connec- tion and Widening/Narrowing Approaches to Abstract Interpretation,” in

(28)

PLILP ’92: Proceedings of the 4th International Symposium on Program- ming Language Implementation and Logic Programming, 1992. pp. 269- 295.

[7] R. Rolles. Unpacking virtualization obfuscators. In Proc. 3rd USENIX Workshop on Offensive Technologies (WOOT ’09), 2009.

참조

관련 문서

force output compare, waveform generation mode, compare match output mode, clock select 이중 waveform generation mode는 Normal, PWM, Phase Correct, CTC, Fast PWM

이 물음에 대한 간단한 답은 다음과 같다: 현상 믿음 p가 지각경험 e의 내용을 정확히 기술하면 p는 참이다.. 따라서 주어진 인식주체가 e에 접근 할

• 주의해서 봐야 할 부위, 놓치기 쉬운 부위.. •

Glucuronic acid conjugation의 conjugate donor를 알고 있다. Sulfate conjugation의 conjugate

경영자가 조직의 중요한 문제에 대한 가장 좋은 해결책을 알고 있고 이를 실행할 수 있는 충분한 권한이 있다면 의사결정과 집행과정에 다른 경영자를 참여시키는

㈑ 계젃별로 별자리가 달라짐을 알고, 계젃별로 나타나는 대표적읶 별자리를 찾을 수

71) 강제채혈의 경우 주사를 잘못 놓은 경우 등 극히 이례적인 경우를 제외하고는 건강훼손의 위험이 통상적으로 발생하지 않는다는 점에서 강제채뇨(삽관을 함으로

또한 색채를 활용하여 보기 쉬운 표시를 하거나 문자를 크게