악성코드 제작자들은 악성코드 분석을 어렵게 하려는 목적으로 각종 Anti-Disassembly 기법을 사용한다.

이 포스팅에서는 GandCrab 5.0.4 v을 분석하던 중 맞닥뜨린 Anti-Disassembly 기법과 해결법에 대해 다룬다.

 

IDA Pro로 악성코드를 디컴파일 하는 과정에서 다음과 같은 부분을 발견하게 되었다.

디컴파일 초기 상태

분명히 push ebp로 시작하는 함수의 프롤로그가 보이고, 0x403c02에서 call 0x403b12라는 instruction으로 호출되고 있는 함수임에도 불구하고 loc_403b12라고 레이블링되면서 중간의 opcode는 분석이 불가능하고 f5를 사용해도 디컴파일이 되지 않는 것을 확인할 수 있다.

 

먼저 해결해야 하는 부분은 0x403b22 주소의

jnz    short near ptr loc_403B26+3

jz      short near ptr loc_403B26+3

부분이다. zf플래그가 설정되어 있든 아니든 403b29주소로 점프하지만, 디컴파일러는 이를 해석하지 못한다.

 

opcode 보기 설정

options-general에서 number of opcode bytes옵션을 5이상으로 설정해서 opcode를 함께 보자.

 

 

 

75 는 jnz, 05는 이 opcode가 끝나는 지점으로부터 5바이트라는 뜻으로, zf플래그가 설정되어 있지 않을 때 403b24 오프셋에서 5바이트 뒤인 403b29로 점프하라는 뜻이다. 분기에 상관없이 무조건 403b29로 점프하도록 instruction을 패치한다.

edit->patch programs -> change byte 옵션에서 75와 74를 EB(jmp instruction)로 바꾸어준다

 

1차 패치된 프로그램

이후 u키로 loc_403b12와 loc_403b26을 undefine해주고 p키를 눌러 다시 함수로 해석한다. 위는 그 과정을 거치고 난 disassembly의 모습이다.

 

이제 디컴파일은 수행되지만 0x403b12 하나의 함수로 해석되어야 할 것이, sub_403b12와 sub_403b2c 두 개의 함수로 잘못 해석되는 문제가 발생한다.

 

더불어 sub_403b2c 는 함수 프롤로그가 없어서 스택프레임이 적절히 생성되지 않아 디컴파일 시 아래의 오류가 발생하며 디컴파일이 실패한다.

함수 진행중 ebp 보다 esp의 값이 커지는 부분이 있다는 것이다.

 

 

esp 가 positive value 를 갖게 되는 instruction에서 alt+k 를 눌러서 sp value를 수정해주면 디컴파일은 가능해진다.

스택 포인터 조정

 

아래는 디컴파일 결과이다.

 

그러나 sp value를 임의로 수정한 것이므로 적절한 해결책은 아니며 변수 표현이 정확히 되지 않는 문제가 발생한다 . 스택 정리가 정확히 될 수 있도록 프롤로그에서부터 함수 흐름을 제대로 이어줄 필요가 있다.

 

 

아래의 그림을 보자.

먼저 0x403b18에서 call $+5로 0x403b1d를 호출하는데, 이때 call instruction은 ret 주소(0x403b1d)를 스택에 push하므로 esp에는 0x403b1d 값이 존재하게 되는데  0x403b1d에서 [esp]에 0x11값을 더하므로, esp에는 0x403b2e값이 들어가게 된다. 다음으로 0x403b29에서 pop eax, jmp eax명령어를 통해 esp의 0x403b2e로 점프하게 된다.

 

따라서 jmp eax를 jmp 403b2e로 바꾸어주면 스택프레임을 유지하면서 프로그램의 흐름도 똑같이 유지할 수 있게 된다. 아래는 patch program을 이용하여 패치한 결과이다.

디컴파일이 적절히 된 것을 알 수 있다.

+ Recent posts