회사 프로젝트 때문에~ 이런저런 Packer/Protector 들을 많이 살펴보게 됩니다...

그 중에 가장~ 난감한 녀석을 꼽으라면 역시 Themida 가 아닐까 싶네요;;;...
( ㅋ.. 이쪽 분야를 접한 분들 중에서 알만한 분들은 다 아실듯한... )

Themida 의 여러 기능 중~ 타겟을 분석하기 짜증나게(?) 하는 것 중의 하나가 바로 API Wrapping 인데요...

오늘은 API Wrapping 에 대해서 알게된 것을 정리를 해볼까합니다;;ㅋ...

API Wrapping ... 말그대로 "API 를 감싼다" 라고 생각하시면 될듯 합니다.
( 실제로 대상 API 를 이런저런 더미코드 및 정크코드로 둘러싼거니까요~ :D )


지금부터~ㅋ 특정 API 하나를 타겟으로 잡아서 Themida 가 어떤식으로 Wrapping 했는지 추적을 해봅시다~

#01. 원본파일의 코드


#02. Themida 로 팩된 파일의 코드


원본파일에서 "FF 15 ~ XXXXXXXX" 로 되어있는 6 바이트 CALL 문을

"E8 ~ XXXXXXXX" 의 5 바이트 CALL 문으로 바꾸면서~ 길이를 맞추기 위해 NOP 추가했습니다.

코드가 조금 변경되면서 보이는 길이가 달라지긴 했지만 전체적인 형태를 보면 같은 형태인걸 확인하실 수 있을겁니다.

SendDlgItemMessageW 를 콜하는 부분이 016005F9 를...
lstrcpyW 를 콜하는 부분이 014D0000 를...
CloseHandle 를 콜하는 부분이 014C0BD9 를.. 콜하도록 변경된거죠~~

이걸 바꿔말하면 016005F9 에서는 어떻게든 SendDlgItemMessageW 를 호출할테고...
014D0000 에서는 역시 lstrcpyW 를 호출할테고...
014C0BD9 에서는 CloseHandle 을 호출한다고 볼 수 있습니다.

이 중에서 CloseHandle 을 호출할 014C0BD9 .. 이 곳을 트레이스 해보도록 하겠습니다.


먼저 원본에서 CloseHandle API 가 어떤 구조로 되어있나 확인부터 해봅니다~ :)

#03. 원본의 CloseHandle API 코드



CloseHandle API 코드 한줄 한줄을 잘 봐두시길 바라면서~~ 이제 트레이스를 시작합니다.

크.. 터무니없이 길어질 것 같아서~~ 트레이스 과정은 접어두도록 하겠습니다.


ㅋ... 트레이스는 끝이 났네요;;;

이제 REAL CODE 라고 되어있는 코드만 쭉~~ 모아볼까요?;

=============================================================
MOV   EDI, EDI
XCHG   EAX, EBP
PUSH   EAX
XCHG   EAX, EBP
MOV    EBP, ESP
MOV    EAX, DWORD PTR FS:[18]
MOV    ECX, DWORD PTR [EAX+30]
MOV    EAX, DWORD PTR SS:[EBP+8]
CMP    EAX, -0C
JE     Kernel32.7C830A42
CMP    EAX, -0B
JE     Kernel32.7C830A37
CMP    EAX, -0A
JE     Kernel32.7C839BC1
MOV    ECX, EAX
AND    ECX, 10000003
CMP    ECX, 3
PUSH  EAX
JE     Kernel32.7C81D3CF
CALL  DWORD PTR DS:[<&ntdll.NtClose>]
TEST  EAX, EAX
JL     Kernel32.7C830A2A
SUB    EAX, EAX
INC    EAX
POP    EBP
RETN  4
=============================================================

요렇게 모인 코드와... 조~~기 위의 CloseHandle API 코드를 비교를 해볼까요~~ㅋ

붉은색으로 칠한 코드빼고는 완전히 똑같은 걸 알 수 있습니다..

붉은색으로 칠한 코드는... =0=;; 코드 자체는 살짝 다르긴 하지만.. 동작은 동일합니다..;

XCHG  EAX, EBP
PUSH  EAX
XCHG  EAX, EBP 


이 부분에 대한 내용은 위에서 언급을 했으니 넘어가고..


SUB  EAX, EAX...

원본 코드에선 XOR EAX, EAX 가 되어있는데...

XOR 이나 SUB 나.. 앞뒤로 같은 레지스터를 넣어버리면

둘다~ 해당 레지스터의 값을 0 으로 만들어버린다는 것은 동일하거든요;;


즉, Themida 의 API Wrapping 을 정리를 하자면...

"원래 API 의 코드를 새로운 메모리에 복사를 하면서 정상코드를 더미코드 / 정크코드와 같이 섞어두는 것"
정도면 되려나요...;;;

더미코드 / 정크코드를 실행하는 중간에 정상코드를 실행하도록해서 분석을 어렵게 만드건데...

흠... API Redirect 개념과는 조금 다르지 않나 생각되네요...;;


아...  보너스로 Themida 에서 보이는 코드 변형 패턴은.. 대체로 아래와 같은 형식입니다..

XOR  EAX, EAX
=> SUB  EAX, EAX

PUSH  EBP
=> Type1) XCHG EAX, EBP / PUSH EAX / XCHG EAX, EBP
=> Type2) PUSH ESI / MOV DWORD PTR SS:[ESP], EBP

.......

이상으로 ㅋ.. Themida 의 API Wrapping 에 대한 정리를 마칠까 합니다..ㅡ.ㅡ;;

크... 포스팅에 2시간이나 걸렸네요;;;; ㄷㄷㄷ;;;..

타겟 함수 잡는 것도 꽤 힘들었는데.. 포스팅이 더 힘든;;;;
( 여담이지만.. API Wrapping 에 사용된 더미코드/정크코드는 실행할 때 마다 형태가 달라집니다;; 다형성이죠;;.. )

매번 느끼는거지만.. ㅋ... 실행파일 프로텍터들;;;.. 다른 파일을 감염시키지 않을 뿐;;..

어떻게보면 "바이러스" 와 비슷하다고 볼 수도 있을 것 같네요...ㅋ

그런 측면에서.. 백신들의 인공지능 체크에서 프로텍터들을 감지하는 것도 이해가 가기도 하구요;;ㅋㅋㅋㅋ

암튼.. 오늘은 이만 잘렵니다...ㅋ

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. BlogIcon window31 2008.11.21 00:22  댓글주소  수정/삭제  댓글쓰기

    오우 멋져부러~! 개고생 했을듯 ㅎㅎ
    좋은 힌트가 많이 나오네 : )

    • BlogIcon XeroNic(HS) 2008.11.21 22:25 신고  댓글주소  수정/삭제

      :) ㅋ.. 타겟잡는데 고생좀했지만...;;
      포스팅하는게.. 최고로 어려웠던거 같네요;;ㅋ
      전문적인 내용 포스팅하는 사람들 존경스럽다는...

  2. 하루 2008.11.21 14:45  댓글주소  수정/삭제  댓글쓰기

    ㅊㅈㄷ!!

  3. BlogIcon naggingmachine 2008.11.22 09:29  댓글주소  수정/삭제  댓글쓰기

    우와. 장문의 포스팅 감사합니다. 너무 대단하시네요~ ^^.

  4. BlogIcon vbdream 2008.11.25 18:36  댓글주소  수정/삭제  댓글쓰기

    와~ 대단하십니다!! 저는 엄두도 못낼 작업이군요 ㅎㄷㄷ...

    수고하셨습니다..^^;

    • BlogIcon XeroNic(HS) 2008.11.25 19:13 신고  댓글주소  수정/삭제

      ㅋ 패커~~ 기대됩니다..ㅋ
      얼릉 릴리즈되길 바라면서~
      언팩을 해볼 기회를 살포시 기다리고 있겠습니다~ :)

    • BlogIcon vbdream 2008.11.25 19:46  댓글주소  수정/삭제

      ㅎㄷㄷ 갑자기 무서워지네요... ㄷㄷ

      패커가 탄생하자마자 많은 분들의 언팩 시도가 몰려올 것을 생각하니...ㅋㅋㅋ

  5. 하와이 2008.12.11 20:29  댓글주소  수정/삭제  댓글쓰기

    야이 자식아 ㅋㅋㅋ
    검색 욜라 떄려서 겨우 찾았다. ㅋㅋ

    잘사냐? 아직 서울? ㅎ

  6. BlogIcon m4dnut 2008.12.15 10:47  댓글주소  수정/삭제  댓글쓰기

    ㅎㅎㅎ 수고하셨습니다.. 간만에 들렀는데 재미 있는 자료 포스팅 많이하셨네요..^^

    • BlogIcon XeroNic(HS) 2008.12.15 22:28 신고  댓글주소  수정/삭제

      ^^; 오랜만입니다..
      요즘 회사 프로젝트 마무리하느라...
      올리고 싶은게 있어도~~ 시간이 잘 안나더라구요..^^;;
      틈나면.. 몇 개 더 올릴 예정입니다..ㅋ

  7. BlogIcon m4dnut 2008.12.15 10:51  댓글주소  수정/삭제  댓글쓰기

    그리고.. 아직 병특 이시라니...ㅎㅎㅎㅎ고생 많으시겠네요!! 하핫..^^
    올해 병특 소집해제된 1人

  8. BlogIcon vbdream 2008.12.16 23:18  댓글주소  수정/삭제  댓글쓰기

    더미다의 API-Wrapping 기법은 지금도 좀 무섭네요 ㄷㄷㄷ

    지금은 대상 API가 무슨 API인지 알고 봤으니까 좀 쉽게 트레이스 할 수 있는 것 같지만,

    아예 통째로 패킹된 상태에서 분석하려고 하면 귀찮을것 같네요 ㅋㅋㅋ

    • BlogIcon XeroNic(HS) 2008.12.17 21:39 신고  댓글주소  수정/삭제

      그쵸...ㅋ
      그냥 팩된 파일 달랑 하나가지고 하려하면;;; ㅎㄷㄷ;;
      생각도 하기 싫어요..ㅡㅜ
      그래도 집중해서 잘만 따라가면...
      원래 함수의 본체형태는 구해올 수 있을테니..
      로딩된 DLL 뒤적거리면서 삽질하면.. 찾을수도 :)
      .
      .

      사실 쓰레기코드만 제대로 걸러낼 수만 있으면..
      Wrapping 한 API 를 구해오는 것을 자동화시킬 수도 있을텐데 말이죠;;;
      눈으로는 따라가도 그걸 코드로 구현하려니. 거참;ㅋ
      난감하더라구요..

    • BlogIcon vbdream 2008.12.18 18:26  댓글주소  수정/삭제

      제 생각에는, 대부분의 API는 IAT를 참조하는 루틴이 내부적으로 들어있으므로, CALL DWORD PTR [] 형태로 된 코드에서 가리키는 주소값이 다른 dll의 IAT 내부라면, 해당 코드를 Wrap된 API로 볼 수도 있겠네요. (일반적으로 다른 dll의 IAT를 참조하는 일은 없죠. 그것도 native code 상에서요.(주소값을 알고 있을리도 없으니))

      그렇게 해서 wrap된 API를 하나 확정하면, 해당 wrap된 API를 호출하는 다른 루틴도 wrap된 API라고 생각해볼 수 있겠죠... ㅋㅋ

  9. BlogIcon seyool 2009.01.06 09:42  댓글주소  수정/삭제  댓글쓰기

    잘 보았습니다. 감동이네요.
    winlicense로 패킹된 녀석들중에 브포가 걸리지 않는 몇몇 녀석들이 왜 걸리지 않았었는지
    이제서야 알겠네요.

    • BlogIcon XeroNic(HS) 2009.01.06 14:25 신고  댓글주소  수정/삭제

      감사합니다..^^;;
      ㅋ 저도 Themida 로 팩된 녀석들 트레이스하면서...
      그런 의문을 가졌었는데..
      =0=;; 알고보니까.. 이런 식이더라구요..ㅋ

  10. BlogIcon gunny 2012.03.19 01:09  댓글주소  수정/삭제  댓글쓰기

    잘 읽었습니당
    api redirect 에대해서도 간단히 설명해주실수있나요???

    • BlogIcon XeroNic(HS) 2012.03.19 10:03 신고  댓글주소  수정/삭제

      음.. API Redirect 는 용어 그대로 API 를 Redirect 하는건데..
      간단하게 표현을 하자면~~
      대상 API 를 직접 호출하지 않고...
      몇단계 거쳐서 호출하는 방식이라고 할까요~^^;;

  11. 2012.05.04 10:50  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  12. BlogIcon musangub 2012.05.07 02:58  댓글주소  수정/삭제  댓글쓰기

    진짜 사람 짜증나게 만드는 더미다 ㅡㅡ

  13. BlogIcon 휘바골드 2013.02.08 15:07  댓글주소  수정/삭제  댓글쓰기

    VM은 어떻게 처리해야되나요...?? 원래코드가 뿔뿔히 흩어지는데... 궁금하네요

    • BlogIcon XeroNic(HS) 2013.02.09 00:51 신고  댓글주소  수정/삭제

      VM 의 경우는 API Wrapping 과는 방식 자체가 다릅니다.
      API Wrapping 의 경우 코드 코드를 분산시켜서 처리를 할 뿐...
      그래도 x86 ASM 명령어 체계 하에서 동작하지만...
      VM 은 명령어 체계 자체가 살짝 다릅니다.
      이걸 VM 엔진에서 처리를 해주는 방식이랄까요~

      이 명령체계를 분석해서 x86 ASM 형태로 역변환하게 되면 분석은 가능하겠죠..
      실제로 Orenas UnVirtualizer 라는 플러그인이 어느정도 그 기능을 수행하구요..