본문 바로가기

Research/LLVM

[OLLVM] 난독화 기법 (1) Instruction Substitution

명령어 대체 기법 (Instructions substitution)

 해당 난독화 기법의 목표는 덧셈, 뺄셈, 또는 부울 대수 연산과 같은 표준 이진 연산에 대해 기능적으로 동일하지만 더 복잡한 명령어 시퀀스로 대체하는 것이다. 여러 동등한 명령어 시퀀스를 선택할 수 있을 때, 임의로 하나의 명령어 시퀀스를 선택한다. 이러한 종류의 난독화는 비교적 직관적이고, 생성된 코드를 쉽게 역난독화가 가능하기 때문에 많은 보안을 추가하지 않는다. 하지만, 의사 난수 발생기(pseudo-random generator)가 다른 값으로 시드된다면 명령어 대체 기법은 생성된 이진수에서 다양성을 가져온다. 현재 LLVM 4.0을 기반으로 한 OLLVM에서는 부동 소수점 값에 대해서 반올림 오류와 불필요한 숫자 부정확성을 가져올 수 있어 정수 연산자에 대해서만 적용이 가능하다.

 

다음과 같은 컴파일러 옵션으로 난독화가 가능하다.

-mllvm -sub : 명령어 대체 기법 활성화

-mllvm -sub_loop=3 : 해당 패스가 활성화 되었을 때, 하나의 함수에 3회 적용한다.

 

 각 명령어에 대해 다음과 같은 대체 기법이 적용 가능하다.

 

1. 덧셈 연산 (Addition)

 

a = b - (-c)

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = sub i32 0, %1
%3 = sub nsw i32 %0, %2

 

 

a = - (b + (-c))

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = sub i32 0, %0
%3 = sub i32 0, %1
%4 = add i32 %2, %3
%5 = sub nsw i32 0, %4

 

 

r = rand (); a = b + r; a = a + c; a = a - r

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = add i32 %0, 1107414009
%3 = add i32 %2, %1
%4 = sub nsw i32 %3, 1107414009

 

 

r = rand (); a = b - r; a = a + b; a = a + r

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = sub i32 %0, 1108523271
%3 = add i32 %2, %1
%4 = add nsw i32 %3, 1108523271

 

 

2. 뺄셈 연산 (Subtraction)

 

a = b + (-c)

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = sub i32 0, %1
%3 = add nsw i32 %0, %2

 

 

r = rand (); a = b + r; a = a - c; a = a - r

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = add i32 %0, 1571022666
%3 = sub i32 %2, %1
%4 = sub nsw i32 %3, 1571022666

 

 

r = rand (); a = b - r; a = a - c; a = a + r

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = sub i32 %0, 1057193181
%3 = sub i32 %2, %1
%4 = add nsw i32 %3, 1057193181

 

 

3. AND 연산

 

a = b & c => a = (b ^ ~c) & b

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = xor i32 %1, -1
%3 = xor i32 %0, %2
%4 = and i32 %3, %0

 

 

4. OR 연산

 

a = b | c => a = (b & c) | (b ^ c)

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = and i32 %0, %1
%3 = xor i32 %0, %1
%4 = or i32 %2, %3

 

5. XOR 연산

 

a = a ^ b => a = (~a & b) | (a & ~b)

%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = xor i32 %0, -1
%3 = and i32 %1, %2
%4 = xor i32 %1, -1
%5 = and i32 %0, %4
%6 = or i32 %3, %5