I'm trying to learn how to unpack a simple executable which has been compressed with crinkler, let be the nasm listing here compressed with crinkler.example1.asm:global start; kernel32.lib Exportsextern _ExitProcess@4extern _GetStdHandle@4extern _WriteFile@20section .textstart:    ; DWORD  bytes;    mov     ebp, esp    sub     esp, 4    ; hStdOut = GetstdHandle( STD_OUTPUT_HANDLE)    push    -11    call    _GetStdHandle@4    mov     ebx, eax    ; WriteFile( hstdOut, message, length(message), &bytes, 0);    push    0    lea     eax, [ebp-4]    push    eax    push    (message_end - message)    push    message    push    ebx    call    _WriteFile@20    ; ExitProcess(0)    push    0    call    _ExitProcess@4    ; never here    hltmessage:    db      'Hello, World', 10message_end:To generate the exe I'm using latest version of nasm & crinkler like this nasm -f win32 example1.asm && crinkler example1.obj kernel32.lib user32.lib opengl32.lib winmm.lib gdi32.lib legacy_stdio_definitions.lib oldnames.lib ucrt.lib /out:example1_crinkler.exe /CRINKLER /HASHTRIES:300 /COMPMODE:SLOW /ORDERTRIES:4000 /entry:start /subsystem:consoleTo unpack the exe I'm using OllyDbg v201 and the latest version of OllyDumpEx v1.50. Problem here is, the OllyDebugEx's website only has these sections {Overview, Features, Screenshots, Supported Debuggers, Download, Changelog}, no documentation at all, which means the plugin assumes you've already experience with the whole bunch of options/terms.Right now I've reached the point where I've figured out how to uncompress my test executable and finding the OEP, current status below:What I'd like to know now is understand the whole set of available options provided by OllyDumpEx:Module {PE Base, List Section, Dump Mode, PE Source}Search { Search Area, Search Mode}PE {Image Base, Section Align, Entry Point}OptionsSectionOnce I know how to dump it properly I'd also like to know how to fix it so I'll get the final uncompressed exe.
Trying to decompress a hello world program using OllyDbg v201
windows;ollydbg;tools
Just out of curiosity i downloaded crinkler compiled this code with visual c++#include <windows.h>int WINAPI WinMain(__in HINSTANCE,__in_opt HINSTANCE,__in LPSTR,__in int) {    MessageBox(NULL, Testing Crinky, CRINKLE, MB_OK);    ExitProcess(NULL);}and linked the object file  with crinkler20.exewith cl -c /nologo /W4 /O1 /Zi /analyze *.cppcrinkler.exe /ENTRY:WinMain crinky.obj kernel32.lib user32.lib /CRINKLER /HASHTRIES:300 /COMPMODE:SLOW /ORDERTRIES:4000 /SUBSYSTEM:windows /out:crinky.exeit created a 459 byte exe which runs finels -la crinky.exe-rwxrwxrwx  1 HP 0 459 2016-11-15 15:25 crinky.exeopened it in a hexeditor to see whats inside it appears crinkler employs pe header damaging techniques (it seems to use the peheader to stuff code )here is a hexedit view (from hxd)Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F00000000  4D 5A 32 30 50 45 00 00 4C 01 00 00 01 DB 61 7F  MZ20PE..L....a.00000010  10 D0 17 73 75 47 EB F9 08 00 02 00 0B 01 11 C9  ..suG.......00000020  45 85 C0 79 1F 01 D3 50 F7 E2 90 3D 5C 00 00 00  Ey..P.=\...00000030  F7 F3 39 C1 19 DB EB 48 00 00 40 00 04 00 00 00  9.H..@.....00000040  04 00 00 00 0F A3 2D 29 01 40 00 8D 04 00 EB CE  .....-).@....00000050  00 00 00 00 EB B6 42 06 40 00 00 00 53 31 ED BB  ....B.@...S100000060  02 00 00 00 90 BE 14 01 40 00 6A 01 58 BF 00 00  .......@.j.X..00000070  42 00 B1 00 90 57 EB 12 00 00 00 00 00 00 00 00  B...W.........00000080  5A 72 07 92 29 D1 04 00 29 D0 60 AD 01 F8 74 2C  Zr.)..)`..t,00000090  6A 0A 5A 89 14 54 89 54 24 10 AD 31 ED 4D 45 01  j.Z.TT$..1ME.000000A0  C0 72 FB 74 AF 60 AC 88 C2 32 07 6B C0 6F 02 87  rt`2.ko.000000B0  00 00 00 00 48 4F 00 D2 72 EF 75 F9 BF CE 00 42  ....HO.ru.B000000C0  00 B9 F5 E9 1F 03 73 0C F3 66 AB 0A 06 61 8D 76  ...s.f..a.v000000D0  0C 7B B7 C3 F7 F1 8D 3C 57 89 E9 31 C0 AE 74 04  .{.<W1t.000000E0  00 07 75 02 41 41 0F B6 14 07 D3 E2 01 54 84 34  ..u.AA....T4000000F0  48 7A F3 85 DB 7F 0D D0 2C 1F 75 03 D0 14 1F F7  Hz..,.u...00000100  D3 FE 04 1F 61 46 EB 95 E8 6A A6 38 C6 6F 82 E9  ..aFj8o00000110  1B 13 09 4F 55 FF BD FF FE FF FF 9A 00 20 80 90  ...OU. .00000120  32 FF BD FF FF FF FF DF 00 44 BE 63 EE 28 9E 30  2.Dc(000000130  07 9C 4B 16 0D 6B A8 05 A4 65 86 46 50 14 FE B3  .K..k.eFP.00000140  42 F6 F7 88 0C 1A 94 68 7D 22 BF 3C 30 2F DD C7  B..h}<0/00000150  6B F9 26 24 83 12 7D A2 3A 05 85 FE B3 D2 B1 CF  k&$.}:.00000160  0F B2 80 7D 9A 49 1C 61 97 36 9F 22 F6 54 CD 3F  .}I.a6T?00000170  3B 0E 4B 81 F7 A3 6D 3C 54 89 06 C3 37 51 99 E0  ;.K.m<T.7Q00000180  E6 1E D8 B1 E4 7C 73 D4 9C 36 78 DA 27 8C 39 F3  .|s6x'900000190  BD BF 42 6B F3 1C D9 B1 E7 A5 E7 60 1F C6 5B DF  Bk.`.[000001A0  8F A6 47 E0 B5 A7 DD 3D D6 4A CA 91 3C 35 B3 74  .G=J<5t000001B0  CB A1 81 90 90 32 39 E4 B0 0F 4D EA E4 EA 2F 0A  ...29.M/.000001C0  6C 06 7C 8F E8 9B B1 50 6E 55 0B                 l.|.PnU.linux file utility says it is a ms dos exe dumpbin complains no COFF headerdumpbin /nologo crinky.exeDump of file crinky.exeFile Type: EXECUTABLE IMAGELINK : fatal error LNK1235: corrupt or invalid COFF symbol tablefile crinky.execrinky.exe; MS-DOS executable, MZ for MS-DOSloaded it into windbg and looked at header appears to be completely corrupt cdb -c .foreach /pS 4 /ps 100 (place { lm }) { !dh place };q crinky.exe | grep quit: -B 53File Type: EXECUTABLE IMAGEFILE HEADER VALUES     14C machine (i386)       0 number of sections7F61DB01 time date stamp Mon Sep 21 09:48:09 20377317D010 file pointer to symbol tableF9EB4775 number of symbols       8 size of optional header       2 characteristics            ExecutableOPTIONAL HEADER VALUES     10B magic #  17.201 linker version79C08545 size of code50D3011F size of initialized data3D90E2F7 size of uninitialized data      5C address of entry pointC139F3F7 base of code         ----- new -----00400000 image base       4 section alignment       4 file alignment       2 subsystem (Windows GUI)41743.10541 operating system version16385.36096 image version 4.52971 subsystem version 642B6EB size of image      40 size of headersBBED3153 checksum0114be90 size of stack reserve016a0040 size of stack commit0000bf58 size of heap reserve00b10042 size of heap commit       0  DLL characteristics       0 [9207725A] address [size] of Export Directory   4D129 [AD60D029] address [size] of Import Directory2C74F801 [895A0A6A] address [size] of Resource Directory54895414 [31AD1024] address [size] of Exception Directory 1454DED [74FB72C0] address [size] of Security Directory88AC60AF [6B0732C2] address [size] of Base Relocation Directory87026FC0 [       0] address [size] of Debug DirectoryD2004F48 [F975EF72] address [size] of Description Directory4200CEBF [E9F5B900] address [size] of Special Directory C73031F [ AAB66F3] address [size] of Thread Storage Directory768D6106 [C3B77B0C] address [size] of Load Configuration Directory3C8DF1F7 [31E98957] address [size] of Bound Import Directory 474AEC0 [ 2750700] address [size] of Import Address Table DirectoryB60F4141 [E2D30714] address [size] of Delay Import Directory34845401 [85F37A48] address [size] of COR20 Header DirectoryD00D7FDB [ 3751F2C] address [size] of Reserved Directoryquit:tested if the entry point function is a function with single exit using cdb there were no indirect calls / jmps and it contained only one exit a single returncdb -c g @$exentry;uf @eip;q crinky.exe | grep -iE call|ret004000d3 c3              retso set a bp there and executed and dumped the decryted areacdb -c g 4000d3;t \dc @eip l38;q\ crinky.exe  | grep quit: -B 170:000> cdb: Reading initial command 'g 4000d3;t dc @eip l38;q'*** WARNING: Unable to verify timestamp for image00400000*** ERROR: Module load completed but symbols could not be loaded for image0040000000420000  400108bb 00abbe00 00bf0042 58004300  ...@....B....C.X00420010  8b0c408b 008b0c40 688b008b 75ed8518  .@..@......h...u00420020  6a006a0e 006a5200 000815ff 31c30043  .j.j.Rj.....C..100420030  6091acc0 013c458b 78508be8 4a8bea01  ...`.E<...Px...J00420040  20428b18 748be801 ee01fc88 c7c1ff31  ..B ...t....1...00420050  acc03106 7d48c731 e03b3bf5 24428be4  .1..1.H}.;;...B$00420060  8b66e801 428b480c 8be8011c 44898804  ..f..H.B.......D00420070  01611c24 c383abe8 56b8e204 000415ff  $.a........V....00420080  89950043 c8feacf2 c0fefb79 006a8f74  C.......y...t.j.00420090  4200b868 00c06800 006a0042 000815ff  h..B.h..B.j.....004200a0  006a0043 000015ff 02cc0043 72657375  C.j.....C...user004200b0  01003233 000000ff 4e495243 00454c4b  32......CRINKLE.004200c0  74736554 20676e69 6e697243 0000796b  Testing Crinky..004200d0  00000000 00000000 00000000 00000000  ................quit:it appears the data has been decrypted but imports are resolved here any way we can reach our code in three calls cdb -c g 4000d3;rm 0;pct 3  crinky.exe0:000> cdb: Reading initial command 'g 4000d3;rm 0;pct 3'0042007c ff1504004300    call  dword ptr [(00430004)] ={kernel32!LoadLibraryA (7676395c)}0042007c ff1504004300    call  dword ptr [(00430004)] ={kernel32!LoadLibraryA (7676395c)}0042009c ff1508004300    call  dword ptr [(00430008)] ={user32!MessageBoxA (75e6ea11)}0:000> ub @eipimage00400000+0x20086:00420086 fec8            dec     al00420088 79fb            jns     image00400000+0x20085 (00420085)0042008a fec0            inc     al0042008c 748f            je      image00400000+0x2001d (0042001d)0042008e 6a00            push    000420090 68b8004200      push    offset image00400000+0x200b8 (004200b8)00420095 68c0004200      push    offset image00400000+0x200c0 (004200c0)0042009a 6a00            push    00:000> da 4200b8004200b8  CRINKLE0:000> da 4200c0004200c0  Testing Crinky0:000>based on these the uncompressed executable may be impossible to dump without serious code ( it doesn't have any import table / nor pe header to work with )you may have to prepend a pe header and append an import section to the raw memory as to ollydumpex it is a tool with lots of options pebase you can either select any module , memory range , address range list section will list the found section based on the pebase selection for example if you choose memory list sections will list the whole virtual address range from 0x10000 to 0x7fffffff (32 bit 2 gb va range )when you rescan  search pe searches for pe header in the range dump mode rebuild tries to rebuild the imports if possible (possibly runnable exe)raw dumps what is in memory (usefull for forensics not fro running the exe) but you can see ollydumpex complaining corrupt header in status bar so dumping with ollydumpex is not a viable option as of nowwell you can dump the contents if you start coding a special dumper fill the pe headers imports etc it might be serious work maybe s small start #define _CRT_SECURE_NO_WARNINGS#include <windows.h>#include <stdio.h>int dumpdos (char * filepath){  IMAGE_DOS_HEADER imdos = {0};  FILE * fp = fopen(filepath,r);  if(fp)  { fseek(fp,0,SEEK_SET);    fread(&imdos,sizeof(BYTE),sizeof(IMAGE_DOS_HEADER),fp); fclose(fp);  }  printf(%08x\n,imdos.e_magic);  printf(%08x\n,imdos.e_lfanew);  return imdos.e_lfanew;}void dumpnt (char * filepath , int off_pehead){  IMAGE_NT_HEADERS imnt = {0};  FILE * fp = fopen(filepath,r);  if(fp)  { fseek(fp,off_pehead,SEEK_SET);    fread(&imnt,sizeof(BYTE),sizeof(IMAGE_NT_HEADERS),fp); fclose(fp);  }  printf(%08x\n,imnt.Signature);  printf(%08x\n,imnt.FileHeader.Machine);  printf(%08x\n,imnt.FileHeader.NumberOfSections);  printf(%08x\n,imnt.FileHeader.SizeOfOptionalHeader);  printf(%08x\n,imnt.OptionalHeader.Magic);  printf(%08x\n,imnt.OptionalHeader.AddressOfEntryPoint);   printf(%08x\n,imnt.OptionalHeader.ImageBase);}void main (int argc,char* argv[]){  if(argc !=2){     printf(usage %s <path to binary>,argv[0] ); exit(-1); }  printf (dumping e_magic and e_lfanew from header of %s\n , argv[1]);  int pehead = dumpdos(argv[1]);  printf(dumping NtSig , M/c, sect_nos, sizeopt_hdr, opthdrmagic, &EP, imgbase\n);  dumpnt(argv[1],pehead);}executing it dumpcrink.exe ..\crinky.exedumping e_magic and e_lfanew from header of ..\crinky.exe00005a4d00000004dumping NtSig , M/c, sect_nos, sizeopt_hdr, opthdrmagic, &EP, imgbase000045500000014c00000000000000080000010b0000005c00400000the custom import resolver is cute CPU DisasmAddress   Command                                  Comments00420000  MOV     EBX, OFFSET 00400108             ; hashtable00420005  MOV     ESI, OFFSET 004200AB             ; no of imports to resolve in k320042000A  MOV     EDI, OFFSET 00430000             ; destination for resolved imports0042000F  POP     EAX                              ; peb00420010  MOV     EAX, DWORD PTR DS:[EAX+0C]       ; Peb.Ldr00420013  MOV     EAX, DWORD PTR DS:[EAX+0C]       ; inLoadorderModuleList00420016  MOV     EAX, DWORD PTR DS:[EAX]          ; flink ntdll00420018  MOV     EAX, DWORD PTR DS:[EAX]          ; flink k320042001A  MOV     EBP, DWORD PTR DS:[EAX+18]       ; kernel32.dllbaseAddr0042001D  TEST    EBP, EBP                         ;  dx ((ntdll!_LDR_DATA_TABLE_ENTRY *)((int )((ntdll!_PEB *) @$peb)->Ldr->;InLoadOrderModuleList.Flink->Flink->Flink))->DllBase0042001F  JNE     SHORT 0042002F                   ; if this is not k32base exit00420021  PUSH    000420023  PUSH    000420025  PUSH    EDX00420026  PUSH    000420028  CALL    NEAR DWORD PTR DS:[430008]       ; will never reach here ;if reaches here in case of no k32 it will crash with null dereference0042002E  RETN0042002F  XOR     EAX, EAX00420031  LODS    BYTE PTR DS:[ESI]                ; no of imports from k3200420032  XCHG    EAX, ECX                         ; save no of imports from k3200420033  PUSHAD00420034  MOV     EAX, DWORD PTR SS:[EBP+3C]       ; k32peheaderptr (e_lfanew)00420037  ADD     EAX, EBP                         ; k32peheaderptr PE00420039  MOV     EDX, DWORD PTR DS:[EAX+78]       ; exporttable of k320042003C  ADD     EDX, EBP                         ; k32_imageexportdir0042003E  MOV     ECX, DWORD PTR DS:[EDX+18]       ; noofname00420041  MOV     EAX, DWORD PTR DS:[EDX+20]       ; addressofnamerva00420044  ADD     EAX, EBP                         ; virtualaddrof export names00420046  MOV     ESI, DWORD PTR DS:[ECX*4+EAX-4]  ; last export rva0042004A  ADD     ESI, EBP                         ; last export addr name0042004C  XOR     EDI, EDI                         ; 00042004E  ROL     EDI, 6                           ; creating hash00420051  XOR     EAX, EAX00420053  LODS    BYTE PTR DS:[ESI]                ; first/nth letter of export name00420054  XOR     EDI, EAX00420056  DEC     EAX00420057  JGE     SHORT 0042004E                   ; null termin seek00420059  CMP     EDI, DWORD PTR DS:[EBX]          ; comparehash with [400108]0042005B  LOOPNZ  SHORT 00420041                   ; reloop0042005D  MOV     EAX, DWORD PTR DS:[EDX+24]       ; matched hash end of iit00420060  ADD     EAX, EBP00420062  MOV     CX, WORD PTR DS:[ECX*2+EAX]00420066  MOV     EAX, DWORD PTR DS:[EDX+1C]       ; addroffunctions00420069  ADD     EAX, EBP0042006B  MOV     EAX, DWORD PTR DS:[ECX*4+EAX]0042006E  MOV     DWORD PTR SS:[ESP+1C], EAX       ; modify register eax so popad will hold the rva of k32 export00420072  POPAD                                    ; eax stays same as addr of ;functions00420073  ADD     EAX, EBP                         ; rva+ base = addr of proc00420075  STOS    DWORD PTR ES:[EDI]               ; getprocaddr achieved00420076  ADD     EBX, 4                           ; store at 43000000420079  LOOP    SHORT 00420033                     ; resolves all exports from k32 + loadlibrary0042007B  PUSH    ESI                              ; ASCII user320042007C  CALL    NEAR DWORD PTR DS:[430004]       ; loadlibs user32 or whatever dll00420082  XCHG    EAX, EBP00420083  MOV     EDX, ESI                         ; ASCII user3200420085  LODS    BYTE PTR DS:[ESI]                ; again null term for dll name00420086  DEC     AL00420088  JNS     SHORT 004200850042008A  INC     AL0042008C  JE      SHORT 0042001D                   ;; so this is standard sized custom import resolverso i created another exe with more api calls and checked it andset a hardware exec bp on 42008e and f9nned i landed on actual code   CPU DisasmAddress   Hex dump               Command                                                  Comments004000BC    BF 3A014200          MOV     EDI, OFFSET 0042013A <---------004000C1    B9 23E91F03          MOV     ECX, OFFSET 031FE923004000C6    73 0C                JAE     SHORT 004000D4004000C8    F3:66:AB             REP STOS WORD PTR ES:[EDI]so 42008e is start of actual code and spans upto the hard coded address   430000 is resolved imports   CPU DumpAddress   Hex dump                                         ASCII0042008E  53 56 8B 35|08 00 43 00|33 DB 57 53|BF E4 00 42| SV5 C 3WS B0042009E  00 57 68 1C|01 42 00 53|FF D6 53 57|68 0C 01 42|  WhB SSWhB004200AE  00 53 FF D6|53 57 68 2C|01 42 00 53|FF D6 53 57|  SSWh,B SSW004200BE  68 FC 00 42|00 53 FF D6|53 57 68 EC|00 42 00 53| h B SSWh B S004200CE  FF D6 53 FF|15 00 00 43|00 5F 5E 5B|02 75 73 65| S  C _^[use004200DE  72 33 32 00|01 FF 43 52|49 4E 4B 4C|45 00 54 65| r32 CRINKLE Te004200EE  73 74 69 6E|67 20 43 72|6F 6E 6B 79|00 00 54 65| sting Cronky  Te004200FE  73 74 69 6E|67 20 43 72|65 6E 6B 79|00 00 54 65| sting Crenky  Te0042010E  73 74 69 6E|67 20 43 72|61 6E 6B 79|00 00 54 65| sting Cranky  Te0042011E  73 74 69 6E|67 20 43 72|69 6E 6B 79|00 00 54 65| sting Crinky  Te0042012E  73 74 69 6E|67 20 43 72|75 6E 6B 79|00 00 00 00| sting Crunkyif i binary copy and dump it to a bin file i can easily analyze it with ida by rebasing it  0x40008e creating an xtern segment a, d  etc josh wrote a lengthy post below with patching  instructions one doesnt have to go patching instructions all that is needed is hw bp 0x42008e -> f9 _> change addr of entry point to 2008e instead of 5c in the original pe header create backup and save backupthis mem dump can be loaded as is in idapro and it will be dandy enough like a pristine exeollydbg crinkledexe -> ctrl+g 42008e -> right click-> exec hw bpt -> f9 _> patch ADDROF ENTRYPOINT TO 0X2008E INSTEAD OF 0X5C ->right click_> createbackup _> right click _> save backup-> load in ida demo 6.9 bingo it is as nice as it get 