format PE section '.text' code readable executable entry start start: call [GetCommandLineA] xchg eax, esi call skip_spaces call get_file_name test al, al jz usage call get_file_name mov [infilename], edi test al, al jnz two_files mov [outfilename], edi jmp cont usage: push usage_str write_exit: call [puts] pop eax push 1 pop eax ret two_files: call get_file_name mov [outfilename], edi test al, al jnz usage cont: push rbstr push [infilename] call [fopen] pop ecx ecx test eax, eax jnz @f infileerr: push errload_str jmp write_exit @@: xchg eax, edi push edi call [_fileno] pop ecx push eax call [_get_osfhandle] pop ecx push LastWriteTime push LastAccessTime push CreationTime push eax call [GetFileTime] push 2 push 0 push edi call [fseek] push edi call [ftell] xchg eax, ebx push ebx call [malloc] add esp, 5*4 test eax, eax jz nomem xchg eax, esi push 0 push 0 push edi call [fseek] push edi push ebx push 1 push esi call [fread] add esp, 7*4 cmp eax, ebx jnz infileerr push edi call [fclose] pop ecx cmp dword [esi], 'KPCK' jz @f push notpacked_str jmp write_exit @@: mov ebx, [esi+4] push ebx call [malloc] pop ecx test eax, eax jnz @f nomem: push nomem_str jmp write_exit @@: xchg eax, edi push edi push esi call unpack push wb push [outfilename] call [fopen] pop ecx ecx test eax, eax jnz @f outfileerr: push errsave_str jmp write_exit @@: push eax push ebx push 1 push edi call [fwrite] xchg edi, eax add esp, 12 call [_fileno] push eax call [_get_osfhandle] pop ecx push LastWriteTime push LastAccessTime push CreationTime push eax call [SetFileTime] call [fclose] pop ecx cmp edi, ebx jnz outfileerr xor eax, eax ret include 'kglobals.inc' include 'unpacker.inc' get_file_name: mov edi, esi lodsb cmp al, 0 jz _ret cmp al, '"' setz dl jz @f dec esi @@: mov edi, esi @@loop: lodsb cmp al, 0 jz _ret cmp al, ' ' ja @f test dl, 1 jz @@end @@: cmp al, '"' jnz @@loop test dl, 1 jz @@loop @@end: mov byte [esi-1], 0 skip_spaces: lodsb cmp al, 0 jz @f cmp al, ' ' jbe skip_spaces @@: dec esi mov al, [esi] _ret: ret section '.data' data readable writable data import macro thunk a {a#_thunk:dw 0 db `a,0} dd 0, 0, 0, rva kernel32_name, rva kernel32_thunks dd 0, 0, 0, rva msvcrt_name, rva msvcrt_thunks dd 0, 0, 0, 0, 0 kernel32_thunks: GetCommandLineA dd rva GetCommandLineA_thunk GetFileTime dd rva GetFileTime_thunk SetFileTime dd rva SetFileTime_thunk dd 0 msvcrt_thunks: fopen dd rva fopen_thunk fread dd rva fread_thunk fseek dd rva fseek_thunk ftell dd rva ftell_thunk fwrite dd rva fwrite_thunk fclose dd rva fclose_thunk malloc dd rva malloc_thunk puts dd rva puts_thunk _fileno dd rva _fileno_thunk _get_osfhandle dd rva _get_osfhandle_thunk dw 0 thunk GetCommandLineA thunk GetFileTime thunk SetFileTime thunk fopen thunk fread thunk fseek thunk ftell thunk fwrite thunk fclose thunk malloc thunk puts thunk _fileno thunk _get_osfhandle kernel32_name db 'kernel32.dll',0 msvcrt_name db 'msvcrt.dll',0 end data usage_str db 'Usage: kunpack []',0 rbstr db 'rb',0 wb db 'wb',0 errload_str db 'Cannot load input file',0 errsave_str db 'Cannot save output file',0 nomem_str db 'No memory',0 notpacked_str db 'Input file is not packed',0 align 4 infilename dd ? outfilename dd ? LastWriteTime dq ? LastAccessTime dq ? CreationTime dq ? IncludeUGlobals