**** first layer - blocks decryptor ****

0137:0040C10B  B800C04000          MOV     EAX,0040C000
0137:0040C110  6A00                PUSH    00
0137:0040C112  6812624000          PUSH    00406212                  ; use SEH to transfer control 
0137:0040C117  64FF3500000000      PUSH    DWORD PTR FS:[00000000]   ; to the next layer (2)
0137:0040C11E  64892500000000      MOV     FS:[00000000],ESP
0137:0040C125  669C                PUSHF
0137:0040C127  60                  PUSHAD
0137:0040C128  50                  PUSH    EAX
0137:0040C129  8BD8                MOV     EBX,EAX
0137:0040C12B  0300                ADD     EAX,[EAX]
.... omissis .......................................
0137:0040C1A0  50                  PUSH    EAX
0137:0040C1A1  E82D000000          CALL    0040C1D3          ; fnDecryptBlock (convoluted)
0137:0040C1A6  85C0                TEST    EAX,EAX
0137:0040C1A8  0F8420FFFFFF        JZ      0040C0CE
0137:0040C1AE  5F                  POP     EDI
0137:0040C1AF  5F                  POP     EDI
0137:0040C1B0  58                  POP     EAX
0137:0040C1B1  5B                  POP     EBX
0137:0040C1B2  EBB5                JMP     0040C169

**** second layer - xHandler gateway ****

0137:00406212  E84F000000          CALL    00406266         ; just transfers control to _layer3

**** third layer - imports & relocs handlers ****

0137:00406266  33C0                XOR     EAX,EAX
0137:00406268  5E                  POP     ESI
0137:00406269  648B18              MOV     EBX,FS:[EAX]
0137:0040626C  8B1B                MOV     EBX,[EBX]
0137:0040626E  8D63DA              LEA     ESP,[EBX-26]     ; all needed infos was left onto stack 
0137:00406271  8B6B08              MOV     EBP,[EBX+08]     ; when exception has been raised
0137:00406274  8B6DFC              MOV     EBP,[EBP-04]
0137:00406277  8B0B                MOV     ECX,[EBX]
0137:00406279  648908              MOV     FS:[EAX],ECX     ; manually restore previus xFrame
0137:0040627C  8B3C24              MOV     EDI,[ESP]
0137:0040627F  81C702010000        ADD     EDI,00000102
0137:00406285  6A0E                PUSH    0E
0137:00406287  59                  POP     ECX
0137:00406288  F3A4                REPZ MOVSB
0137:0040628A  56                  PUSH    ESI
0137:0040628B  57                  PUSH    EDI
0137:0040628C  8DB7EC140000        LEA     ESI,[EDI+000014EC]
0137:00406292  8BCE                MOV     ECX,ESI
0137:00406294  2BCF                SUB     ECX,EDI
0137:00406296  F3AA                REPZ STOSB
0137:00406298  833E00              CMP     DWORD PTR [ESI],00
0137:0040629B  7470                JZ      0040630D
0137:0040629D  0FBA261F            BT      DWORD PTR [ESI],1F
0137:004062A1  7305                JAE     004062A8
0137:004062A3  83C60C              ADD     ESI,0C
0137:004062A6  EBF0                JMP     00406298
0137:004062A8  8B7E08              MOV     EDI,[ESI+08]
0137:004062AB  03FD                ADD     EDI,EBP
0137:004062AD  8B4E0C              MOV     ECX,[ESI+0C]
0137:004062B0  D1F9                SAR     ECX,1
0137:004062B2  51                  PUSH    ECX
0137:004062B3  7215                JB      004062CA
0137:004062B5  037E04              ADD     EDI,[ESI+04]
0137:004062B8  C1F902              SAR     ECX,02
0137:004062BB  33C0                XOR     EAX,EAX
0137:004062BD  F3AB                REPZ STOSD
0137:004062BF  59                  POP     ECX
0137:004062C0  83E103              AND     ECX,03
0137:004062C3  F3AA                REPZ STOSB
0137:004062C5  83C610              ADD     ESI,10
0137:004062C8  EBCE                JMP     00406298
0137:004062CA  8B5E04              MOV     EBX,[ESI+04]
0137:004062CD  83EB06              SUB     EBX,06
0137:004062D0  33D2                XOR     EDX,EDX
0137:004062D2  72E1                JB      004062B5
0137:004062D4  8A043A              MOV     AL,[EDI+EDX]
0137:004062D7  3CE8                CMP     AL,E8            ; call near rel32
0137:004062D9  740E                JZ      004062E9
0137:004062DB  3CE9                CMP     AL,E9            ; jmp near rel32
0137:004062DD  740A                JZ      004062E9
0137:004062DF  3C0F                CMP     AL,0F            ; jxx near rel32
0137:004062E1  7412                JZ      004062F5
0137:004062E3  42                  INC     EDX
0137:004062E4  83EB01              SUB     EBX,01
0137:004062E7  EBE9                JMP     004062D2
                                                            ; * handle JUMP/CALL NEAR 32 *
0137:004062E9  29543A01            SUB     [EDI+EDX+01],EDX ; fixup
0137:004062ED  83C205              ADD     EDX,05
0137:004062F0  83EB05              SUB     EBX,05
0137:004062F3  EBDD                JMP     004062D2
                                                            ; * handle JXX NEAR 32 *
0137:004062F5  8A443A01            MOV     AL,[EDI+EDX+01]  
0137:004062F9  3C80                CMP     AL,80            ; check opcode ranges   
0137:004062FB  72E6                JB      004062E3         
0137:004062FD  3C8F                CMP     AL,8F            ; JO=0x80 .. JG=0x8F
0137:004062FF  77E2                JA      004062E3         
0137:00406301  29543A02            SUB     [EDI+EDX+02],EDX ; fixup
0137:00406305  83C206              ADD     EDX,06
0137:00406308  83EB06              SUB     EBX,06
0137:0040630B  EBC5                JMP     004062D2

0137:0040630D  5B                  POP     EBX
0137:0040630E  5A                  POP     EDX
0137:0040630F  58                  POP     EAX
0137:00406310  6A00                PUSH    00
0137:00406312  53                  PUSH    EBX
0137:00406313  33DB                XOR     EBX,EBX
0137:00406315  6847030000          PUSH    00000347
0137:0040631A  8B0C24              MOV     ECX,[ESP]
0137:0040631D  0FBAE300            BT      EBX,00
0137:00406321  721A                JB      0040633D
0137:00406323  66648B351C000000    MOV     SI,FS:[0000001C]   ; TibFlags !=1 if debugged
0137:0040632B  660FBAF600          BTR     SI,00
0137:00406330  6664033522000000    ADD     SI,FS:[00000022]   ; word ptr [DebugContext] != 0
0137:00406338  6646                INC     SI
0137:0040633A  6633DE              XOR     BX,SI
0137:0040633D  321C11              XOR     BL,[EDX+ECX]       ; check loader layers integrity
0137:00406340  C1C30B              ROL     EBX,0B
0137:00406343  49                  DEC     ECX
0137:00406344  7DD7                JGE     0040631D
0137:00406346  8D8800010000        LEA     ECX,[EAX+00000100]
0137:0040634C  3119                XOR     [ECX],EBX          ; use crc as decryption key 
0137:0040634E  315904              XOR     [ECX+04],EBX       ; for the 4th layer's code
0137:00406351  315908              XOR     [ECX+08],EBX
0137:00406354  31590C              XOR     [ECX+0C],EBX
0137:00406357  59                  POP     ECX
0137:00406358  315C1101            XOR     [EDX+ECX+01],EBX   ; build "call _layer4"
0137:0040635C  33DB                XOR     EBX,EBX
0137:0040635E  8BF2                MOV     ESI,EDX
0137:00406360  81BAAB9EFFFF0BC10000CMP     DWORD PTR [EDX+FFFF9EAB],0000C10B ; check JMP->OEP rva
0137:0040636A  7521                JNZ     0040638D
0137:0040636C  81EE7D610000        SUB     ESI,0000617D           ; lpPEHeader
0137:00406372  0FB64E06            MOVZX   ECX,BYTE PTR [ESI+06]  ; NumberOfSection 
0137:00406376  6BC90A              IMUL    ECX,ECX,0A             
0137:00406379  6681C13E00          ADD     CX,003E                ; sizeOf(NtHeaders) 
0137:0040637E  331E                XOR     EBX,[ESI]
0137:00406380  D3C3                ROL     EBX,CL
0137:00406382  83C604              ADD     ESI,04
0137:00406385  49                  DEC     ECX
0137:00406386  75F6                JNZ     0040637E
0137:00406388  395804              CMP     [EAX+04],EBX           ; check PE Header integrity
0137:0040638B  7408                JZ      00406395
0137:0040638D  83C42A              ADD     ESP,2A
0137:00406390  E9495D0000          JMP     0040C0DE
0137:00406395  BE00700000          MOV     ESI,00007000
0137:0040639A  8B8D28010000        MOV     ECX,[EBP+00000128]
0137:004063A0  03F5                ADD     ESI,EBP
0137:004063A2  03CD                ADD     ECX,EBP
0137:004063A4  8BD8                MOV     EBX,EAX
0137:004063A6  833E00              CMP     DWORD PTR [ESI],00     ; while !(NameRVA)
0137:004063A9  0F847F010000        JZ      0040652E
0137:004063AF  51                  PUSH    ECX
0137:004063B0  FF710C              PUSH    DWORD PTR [ECX+0C]
0137:004063B3  012C24              ADD     [ESP],EBP
0137:004063B6  8B13                MOV     EDX,[EBX]
0137:004063B8  FF541A10            CALL    [EBX+EDX+10]           ; LoadLibraryA
0137:004063BC  85C0                TEST    EAX,EAX
0137:004063BE  0F84D5000000        JZ      00406499
0137:004063C4  8BF8                MOV     EDI,EAX
0137:004063C6  03403C              ADD     EAX,[EAX+3C]           ; get lpNtHeaders
0137:004063C9  8B4078              MOV     EAX,[EAX+78]           ; DataDirectory.ExportsDirRva
0137:004063CC  FF743818            PUSH    DWORD PTR [EDI+EAX+18] ; ExportsDir->NumberOfNames
0137:004063D0  8B4C3824            MOV     ECX,[EDI+EAX+24]       
0137:004063D4  03CF                ADD     ECX,EDI                ; ExportsDir->AddressOfNameOrdinals
0137:004063D6  51                  PUSH    ECX
0137:004063D7  8B4C3820            MOV     ECX,[EDI+EAX+20]       
0137:004063DB  03CF                ADD     ECX,EDI                ; ExportsDir->AddressOfNames
0137:004063DD  51                  PUSH    ECX
0137:004063DE  FF743810            PUSH    DWORD PTR [EDI+EAX+10] ; ExportsDir->Base
0137:004063E2  FF743814            PUSH    DWORD PTR [EDI+EAX+14] ; ExportsDir->NumberOfFunctions
0137:004063E6  8B44381C            MOV     EAX,[EDI+EAX+1C]
0137:004063EA  03C7                ADD     EAX,EDI                ; ExportsDir->AddressOfFunctions
0137:004063EC  50                  PUSH    EAX
0137:004063ED  56                  PUSH    ESI
0137:004063EE  8B36                MOV     ESI,[ESI]            ; FirstThunk
0137:004063F0  03F5                ADD     ESI,EBP              
0137:004063F2  8B06                MOV     EAX,[ESI]            
0137:004063F4  85C0                TEST    EAX,EAX              ; while !(*lpFirstThunk)
0137:004063F6  0F8487000000        JZ      00406483             
0137:004063FC  0FBAE01F            BT      EAX,1F               ; ? imported by ordinal
0137:00406400  732B                JAE     0040642D
0137:00406402  25FFFF0000          AND     EAX,0000FFFF         
0137:00406407  2B44240C            SUB     EAX,[ESP+0C]         ; index = ordinal - base
0137:0040640B  0F8295000000        JB      004064A6
0137:00406411  3B442408            CMP     EAX,[ESP+08]         ; check if >=NumberOfFunctions
0137:00406415  0F838B000000        JAE     004064A6
0137:0040641B  C1E002              SHL     EAX,02               ; normalize index (word)
0137:0040641E  03442404            ADD     EAX,[ESP+04]         
0137:00406422  8B00                MOV     EAX,[EAX]            
0137:00406424  03C7                ADD     EAX,EDI              ; lpfn = *AddressOfFunctions[index] + IB
0137:00406426  8906                MOV     [ESI],EAX            ; patch *lpFirstThunk (IAT)
0137:00406428  83C604              ADD     ESI,04               ; lpFirstThunk++
0137:0040642B  EBC5                JMP     004063F2
0137:0040642D  03C5                ADD     EAX,EBP
0137:0040642F  50                  PUSH    EAX
0137:00406430  50                  PUSH    EAX
0137:00406431  57                  PUSH    EDI
0137:00406432  8B13                MOV     EDX,[EBX]
0137:00406434  FF541A14            CALL    [EBX+EDX+14]         ; GetProcAddress
0137:00406438  85C0                TEST    EAX,EAX
0137:0040643A  7469                JZ      004064A5
0137:0040643C  FF4C2428            DEC     DWORD PTR [ESP+28]   ; stub inserction counter
0137:00406440  7D25                JGE     00406467
0137:00406442  8B542424            MOV     EDX,[ESP+24]
0137:00406446  3B542420            CMP     EDX,[ESP+20]
0137:0040644A  7714                JA      00406460
0137:0040644C  C602E9              MOV     BYTE PTR [EDX],E9    ; jmp near rel32
0137:0040644F  2BC2                SUB     EAX,EDX              ; calc API_EntryPoint delta
0137:00406451  83E805              SUB     EAX,05
0137:00406454  894201              MOV     [EDX+01],EAX         
0137:00406457  8BC2                MOV     EAX,EDX
0137:00406459  83C205              ADD     EDX,05
0137:0040645C  89542424            MOV     [ESP+24],EDX
0137:00406460  83E207              AND     EDX,07               ; pseudo random value as counter
0137:00406463  89542428            MOV     [ESP+28],EDX
0137:00406467  8906                MOV     [ESI],EAX            ; patch lpFirstThunk (IAT)
0137:00406469  873C24              XCHG    EDI,[ESP]            ; lpImageImportByName
0137:0040646C  83C9FF              OR      ECX,-01
0137:0040646F  33C0                XOR     EAX,EAX
0137:00406471  F2AE                REPNZ SCASB                  ; strlen(lpImageImportByName)             
0137:00406473  FD                  STD
0137:00406474  F7D1                NOT     ECX
0137:00406476  4F                  DEC     EDI
0137:00406477  F3AA                REPZ STOSB                   ; destroy lpImageImportByName
0137:00406479  5F                  POP     EDI
0137:0040647A  FC                  CLD
0137:0040647B  83C604              ADD     ESI,04               ; lpFirstThunk++
0137:0040647E  E96FFFFFFF          JMP     004063F2
0137:00406483  5E                  POP     ESI
0137:00406484  83C418              ADD     ESP,18
0137:00406487  59                  POP     ECX
0137:00406488  C70600000000        MOV     DWORD PTR [ESI],00000000  ; destroy FirstThunk 
0137:0040648E  83C604              ADD     ESI,04
0137:00406491  83C114              ADD     ECX,14
0137:00406494  E90DFFFFFF          JMP     004063A6
0137:00406499  59                  POP     ECX                   
0137:0040649A  83C604              ADD     ESI,04                ; lpFirstThunk++
0137:0040649D  83C114              ADD     ECX,14                ; lpImageImportDescriptor++
0137:004064A0  E901FFFFFF          JMP     004063A6


0137:004064A5  59                  POP     ECX                   ; * handle imports errors *
0137:004064A6  E800000000          CALL    004064AB              
0137:004064AB  5A                  POP     EDX                   ; get eip
0137:004064AC  8B06                MOV     EAX,[ESI]
0137:004064AE  83C41C              ADD     ESP,1C
0137:004064B1  59                  POP     ECX
0137:004064B2  83C42A              ADD     ESP,2A
0137:004064B5  8B790C              MOV     EDI,[ECX+0C]
0137:004064B8  03FD                ADD     EDI,EBP
0137:004064BA  57                  PUSH    EDI
0137:004064BB  8BF3                MOV     ESI,EBX
0137:004064BD  0336                ADD     ESI,[ESI]
0137:004064BF  0FBAF01F            BTR     EAX,1F
0137:004064C3  720B                JB      004064D0
0137:004064C5  03C5                ADD     EAX,EBP
0137:004064C7  50                  PUSH    EAX
0137:004064C8  8DBA42000000        LEA     EDI,[EDX+00000042]    ; szImportNotFound
0137:004064CE  EB07                JMP     004064D7
0137:004064D0  50                  PUSH    EAX
0137:004064D1  8DBA63000000        LEA     EDI,[EDX+00000063]    ; szModuleNotFound
0137:004064D7  57                  PUSH    EDI
0137:004064D8  6681E700F0          AND     DI,F000
0137:004064DD  57                  PUSH    EDI
0137:004064DE  FF5604              CALL    [ESI+04]
0137:004064E1  83C410              ADD     ESP,10
0137:004064E4  8BD7                MOV     EDX,EDI
0137:004064E6  8BC3                MOV     EAX,EBX
0137:004064E8  E9A3FEFFFF          JMP     00406390


0137:0040652E  8DB50000C0FF        LEA     ESI,[EBP+FFC00000]    ; * handle relocs - optional *
0137:00406534  8D8D00B00000        LEA     ECX,[EBP+0000B000]    ; note that this code is not present
0137:0040653A  8BF9                MOV     EDI,ECX               ; if relocations are stripped
0137:0040653C  33D2                XOR     EDX,EDX
0137:0040653E  8B01                MOV     EAX,[ECX]
0137:00406540  85C0                TEST    EAX,EAX
0137:00406542  741A                JZ      0040655E
0137:00406544  3CFF                CMP     AL,FF
0137:00406546  7508                JNZ     00406550
0137:00406548  8B5101              MOV     EDX,[ECX+01]
0137:0040654B  83C105              ADD     ECX,05
0137:0040654E  EB08                JMP     00406558
0137:00406550  41                  INC     ECX
0137:00406551  25FF000000          AND     EAX,000000FF
0137:00406556  03D0                ADD     EDX,EAX
0137:00406558  01741500            ADD     [EDX+EBP+00],ESI
0137:0040655C  EBE0                JMP     0040653E
0137:0040655E  2BCF                SUB     ECX,EDI                ; wipe relocs
0137:00406560  F3AA                REPZ STOSB
0137:00406562  59                  POP     ECX
0137:00406563  5E                  POP     ESI
0137:00406564  FD                  STD
0137:00406565  33C0                XOR     EAX,EAX
0137:00406567  B960030000          MOV     ECX,00000360           ; sizeof loader layers (2-3)
0137:0040656C  E8915B0000          CALL    0040C102               ; next layer

**** forth layer - cleanup & jump to host ****

0137:0040C102  5F                  POP     EDI                    ; lpPrevLayer  = ret address
0137:0040C103  F3AA                REPZ STOSB                     ; wipe loader layers (2-3)
0137:0040C105  61                  POPAD
0137:0040C106  669D                POPF                           ; restore register & flags
0137:0040C108  83C40C              ADD     ESP,0C                 ; stack cleanup
0137:0040C10B  E9F04EFFFF          JMP     00401000               ; jmp to OEP
FFFF4Ef0

* imports stubs - example *

0137:0040C110  E9F9CD9C7F          JMP     SHELL32!ShellExecuteA
0137:0040C115  E9120DB9BF          JMP     KERNEL32!LocalLock
.............  ..........          ...     ......................
0137:0040C18D  E95563B2BF          JMP     GDI32!SetBkMode
0137:0040C192  E9865AB2BF          JMP     GDI32!SetWindowExtEx
0137:0040C197  E9078EA77F          JMP     comdlg32!GetFileTitleA
