옛날부터 구현해 해보고 싶었던건데 이제서야 쫌 해보게되네요.


리버싱을 좀 하셨다 싶은 분들은 Themida로 패킹된 파일을 한번씩은 올디로 분석을 해보셨을 것입니다.


위 그림은 더미다의 가상머신 핸들러 내부인데요.


더미코드도 많이 있지만 명령어 조금 실행하고 JMP해버리고 조금 실행하고 JMP 해버리고...

사실 분석하는데 다른 리버서분들은 모르겠지만 저 같은 경우는 코드가 한눈에 보이지 않아서 너무 짜증나더군요.


그래서 위 기술을 구현해보기로 했습니다. ( JMP Trick.. 그냥 제가 지은겁니다;; )


제가 생각한 JMP Trick 구현 방식은 다음과 같습니다.

1. JMP Trick 시작 전 대상 HEX 값 얻기


2. 디스어셈블 엔진을 돌려서 각 명령어를 얻음


3. 각 명령어들을 2~6개 사이의 랜덤한 값으로 나눔

  (즉, 명령어가 16개라면 6-3-5-2 이런식으로 나눔 )

  첫번째 블럭은 명령어 6개

  두번째 블럭은 명령어 3개

  세번째 블럭은 명령어 5개

  네번째 블럭은 명령어 2개


4. 명령어 재구성할 영역 할당 (VirtualAlloc 사용)


5. 할당된 공간에 JMP(E9) 인 Long 점프 5Byte를 확보하면서 각 블럭들을 가져다 명령어 채움

   [5Byte][Block1][5Byte][Block2][5Byte][Block3]... 이런식

   저기서 각 블럭 순서는 랜덤 ( 블럭 번호, 명령어 개수 등등을 한번에 관리할 수 있는 구조체 배열로 구현 )


6. 할당된 영역에 남겨진 JMP 오퍼랜드 완성 시키기


7. 기존 함수 앞에 JMP문을 넣어 새로 만들어진 영역으로 JMP 되도록 함.


주의

1. 타겟 코드 내부에 상대주소로 접근하는 코드가 있어선 안됨

2. 점프문이 있어선 안됨( 조건문, 반복문 사용 금지 )


코드는 버그없이 돌아갑니다. 한줄한줄 신경써서 했더니 :D


main 함수와 타겟 함수입니다.

MyIsDebugger 함수는 쓰레기코드와 섞어서 쫌 구현해보았습니다.


main함수에서 JMPTrickFunction  함수 전에 쓰인 MyIsDebugger는 JMP Trick 적용 전이고 아래 쓰인 경우엔 JMP Trick이 적용된 후 입니다.


프로그램이 실행될 때 마다 JMP Trick 함수가 실행되기 때문에 MyIsDebugger는 실행 시마다 다르게 변경됩니다.

3번 실행 후 바뀐 결과를 보겠습니다.



전부 MyIsDebugger 함수입니다. 아 정확히 말하면 새로 재구성된 함수이죠.



여기가 원본 함수입니다. 위쪽에 JMP 생긴 것을 볼 수 있습니다.

그리고 이 경우에 원본 함수에서 나머지 부분은 그냥 그대로 놔뒀는데요.

나머지 부분은 그냥 쓰레기 값으로 채워버리는게 낫습니다. 원본 함수를 그대로 놔둘 이유가 없겠죠?

하지만 귀찮아서 패스.. =_=; (코드 한줄이면 끝나는데 뭘 귀찮아 하냐! @= )


아무튼 마지막 동영상 보고 마무리 하겠습니다.. 



실제 더미다 JMP 트릭에 비하면 뭔가 어설픈 편이지만 비슷하게 구현했네요. 뿌듯 :D

'My Study > Programming&Theory' 카테고리의 다른 글

Context 는 매우 중요하다!!  (0) 2012.11.06
x86 자가보호 DLL  (1) 2012.11.06
Themida의 JMP Trick 따라해보기  (1) 2012.10.16
SYSENTER Hooking 후 PsGetCurrentProcess  (2) 2012.10.09
가변인자 OutputDebugString  (0) 2012.10.03
WRP 무력화  (5) 2012.07.31
Posted by Ezbeat