Some people asked be about tutorial on ungeneric unpacking and using disassembler only for cut and paste approach of coding unpackers.
There is a short example using disassembly of PELOCKnt 2.04 unmodified version (same for the modified Impact emulator). The source code given below is used on the modified PELOCKnt and works only for it because it reads part from the file at constant offset - no PE header analyze is done.
Tools used:
HIEW, TASM, MOW (with few macros added by myself - read at the end about them), text editor, hex calculator
1) Open in hiew the target file (PELOCKNT.EXE). Press enter twice until you get the disassembly view. Press F8 to show PE header and F5 to go to the entry point. You will see next code:
.00057000: EB03 jmps .000057005 -------- (1)
.00057002: CD20C71EEB03 VxDcall 03EB.1EC7
.00057008: CD20EA9CEB02 VxDjmp 02EB.1CEA
.0005700E: EB01 jmps .000057011 -------- (2)
.00057010: EB01 jmps .000057013 -------- (3)
.00057012: EB60 jmps .000057074 -------- (4)
.00057014: EB03 jmps .000057019 -------- (5)
.....
It's full of shits, isn't it?

Better to go to the next step
2) Run MOW on the target file. Open the file PELOCKNT.NOP with hiew and go again to the entry point as done in 1). You will see next better looking code:
.00057000: 90 nop
.00057001: 90 nop
.00057002: 90 nop
.00057003: 90 nop
.00057004: 90 nop
.00057005: 1E push ds
.00057006: 90 nop
.00057007: 90 nop
.00057008: 90 nop
.00057009: 90 nop
.0005700A: 90 nop
.0005700B: 9C pushfd
.0005700C: 90 nop
.0005700D: 90 nop
.0005700E: 90 nop
.0005700F: 90 nop
.00057010: 90 nop
.00057011: 90 nop
.00057012: 90 nop
.00057013: 60 pushad
Now scroll down until you reach the first internal decryption layer. You will recognize it very easy (as in most protectors
(I removed most NOPs because they are waste of space)
.00057038: E800000000 call .00005703D -------- (1)
.0005703D: 90 nop
.00057041: 90 nop
.00057042: 5E pop esi
.00057043: 90 nop
.00057047: 90 nop
.00057048: 0F014EF4 sidt [esi][-000C]
.0005704C: 90 nop
.00057053: 90 nop
.00057054: 83C65F add esi,05F ;"_"
.00057057: 90 nop
.0005705B: 90 nop
.0005705C: 8BFE mov edi,esi
.0005705E: 90 nop
.00057061: 90 nop
.00057062: B90B260000 mov ecx,00000260B
.00057067: 90 nop
.0005706D: 90 nop
.0005706E: B487 mov ah,087 ;"Ç"
.00057070: 90 nop
.00057077: 90 nop
.00057078: AC lodsb
.00057079: 90 nop
.0005707F: 90 nop
.00057080: 32C4 xor al,ah
.00057082: 90 nop
.00057085: 90 nop
.00057086: 32C1 xor al,cl
.00057088: 90 nop
.0005708D: AA stosb
.0005708E: 90 nop
.00057091: 90 nop
.00057092: 49 dec ecx
.00057093: 90 nop
.00057099: 90 nop
.0005709A: 75D4 jne .000057070 -------- (1)
.0005708B: 90 nop
Now I will copy all that code with remove all NOPs and you will see that it is really easy to understand it (all hex opcodes are remove too and some labels are added):
.00057038:call .00005703D ; Call next line to get delta offset
.0005703D:nop
.00057042

op esi ; ESI contains the delta offset
.00057048:sidt [esi][-000C] ; Maybe a/d trick? Who cares

.00057054:add esi,05F ;"_" ; ESI points to the area to decrypt
.0005705C:mov edi,esi ; EDI too
.00057062:mov ecx,00000260B ; Lenght of decrypt area
.0005706E:mov ah,087 ; Decrypt key

label_1:
.00057070:nop
.00057078:lodsb
.00057080:xor al,ah
.00057086:xor al,cl
.0005708D:stosb
.00057092:dec ecx
.0005709A:jne .000057070 -------- (1) ; jmp label_1
3) Now rip all that code in your assembler program (because it is really easy to it in asm). My example is DOS code. It opens the input file, moves file pointer to the pelock layer (because file size is bigger than one segment and I didnt wanted to waste my time with intersegment loader), reads 4000h bytes (pelocknt layer) into buffer and does the decryption (look at the end the whole piece of code). This is how looks decryption of the first layer which is copied and pasted into my source
mov ah,3fh
mov cx,4000h
lea dx,buffer
int 21h
mov read_len,ax
lea bp,buffer
cld
;======= Layer 1
lea si, [bp+009ch]
mov edi, esi
mov ecx, 0000260Bh
mov ah, byte ptr [bp+006fh] ; get the decryption key from the pelocknt layer
u1:
lodsb
xor al, ah
xor al, cl
stosb
dec cx
jne u1
After that the buffer is written at it's place in the file so you will have the ability to analyze it again.
4) Open with hiew again the file with the decrypted first layer and go to entry point, scroll a bit to find the code after the first layer. You will find again a code full of shits. Run MOW on it and analyze again with hiew. You will find the second decryption layer and just copy'n'paste it into your source
5) Repeat all previous steps until you get the whole pelocknt layer decrypted. Run MOW on it and disassemble it with your favourite disassembler (IDA should work without any problems on the file but w32dasm needs some modifications to be done to the PE header to get it to work - delete all sections before the PELOCKnt one and set it's section characteristics to e0000020h).
After disassembling and analyzing you will find all nice anti-debugging tricks that mister Marquis De Soiree used (sorry that I explained how to get into that too easy).
Now the full source code of the program that decrypts the PELOCKnt layer of Impact emulator:
.model tiny
.code
.386
crlf equ 0dh,0ah
org 100h
start proc
jmp begin
mess_01 db 'Modified PELOCK-NT 2.04 decryptor v1.00',crlf,'$'
f_name db 'DDD.EXE',00h
f_handle dw ?
read_len dw ?
begin: mov ah,09h
lea dx,mess_01
int 21h
mov ax,3d02h
lea dx,f_name
int 21h
jnc open_ok ; If not error - continue
jmp exit
open_ok:
xchg ax,bx ; BX is file handle
mov f_handle,bx ; Save it
mov ax,4200h ; SetFilePointer
mov cx,0002h ; Hardcoded position of PELOCK-NT layer
mov dx,3000h ;
int 21h ; Do it
mov ah,3fh
mov cx,4000h
lea dx,buffer
int 21h
mov read_len,ax
lea bp,buffer
cld
;======= Layer 1
lea si, [bp+009ch]
mov edi, esi
mov ecx, 0000260Bh
mov ah, byte ptr [bp+006fh]
u1:
lodsb
xor al, ah
xor al, cl
stosb
dec cx
jne u1
;======= Layer 2
lea si,[bp+0124h]
mov edi, esi
mov ecx, 00002583h
mov ah, byte ptr [bp+00f9h]
u2:
lodsb
xor al, ah
xor ah, cl
stosb
dec cx
jne u2
;======= Layer 3
lea si, [bp+0232h]
mov edi, esi
mov ecx, 00002475h
mov ah, byte ptr [bp+0207h]
u3:
lodsb
xor al, ah
xor ah, cl
stosb
dec cx
jne u3
;======= Layer 4
lea si, [bp+02dah]
mov edi, esi
mov ecx, 000023CDh
mov ah, byte ptr [bp+0296h]
u4:
lodsb
xor al, ah
mov bh, cl
and cl, 07h
ror al, cl
mov cl, bh
xor ah, cl
stosb
loop u4
;======= Get checksum
write_file:
mov ax,4200h ; SetFilePointer
mov bx,f_handle
mov cx,0002h ; Hardcoded position of PELOCK-NT layer
mov dx,3000h ;
int 21h ; Do it
mov ah,40h ; Write decrypted part
mov cx,read_len ;
lea dx,buffer ;
int 21h ;
mov ah,3eh
int 21h
exit:
mov ax,4c00h
int 21h
start endp
buffer label byte
end start
=========================================
Now about the macros I added to MOW:
EB03 - jump over next useless code
CD20?? - disassembled as VxDcall
These 5 bytes can be patched with NOPs
Adding a macro in MOW is easy:
SetM(440, #$EB+#$03+#$CD+#$20, 'ÐÐÐÐÐ');
Recompile it and you can use it on PELOCKnt.
Maybe there are some other macros I missed now (I lost the modified MOW source

) but you can find them when MOWing with the original version and looking with hiew.
That's all. Hope you will understand it.
Greetings to Xoanino, DAEMON, tE!, all friends in TMG, UG, UCF
Cheers
Unknown One/[TMG]