[Bug 44860] New: 4k/ 8k demos crash due to Crinkler executable file compressor expecting PEB address in %EBX on process entry

wine-bugs at winehq.org wine-bugs at winehq.org
Fri Mar 30 09:12:04 CDT 2018


https://bugs.winehq.org/show_bug.cgi?id=44860

            Bug ID: 44860
           Summary: 4k/8k demos crash due to Crinkler executable file
                    compressor expecting PEB address in %EBX on process
                    entry
           Product: Wine
           Version: 3.4
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: kernel32
          Assignee: wine-bugs at winehq.org
          Reporter: focht at gmx.net
      Distribution: ---

Hello folks,

split out from bug 42125 which is about OS loader compatibility/PE image header
fields/mappings.

Most of the PE tools struggle or even crash when trying to get something useful
out of this due to the "optimized" usage (truncation) of DOS, PE headers
(basically providing the bare minimum info to not have the OS loader crash).

Example: http://www.pouet.net/prod.php?which=66502 ("Psyltcipher by Loonies")

ProtectionID scan:

--- snip ---
-=[ ProtectionID v0.6.9.0 DECEMBER]=-
(c) 2003-2017 CDKiLLER & TippeX
Build 24/12/17-21:05:42
Ready...
Scanning -> Z:\home\focht\Downloads\lns-lpt-psyltcipher_720.exe
[!] Warning : File has NO sections (suspicious)
[!] Warning : File has NO imports (suspicious)
File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 7242 (01C4Ah) Byte(s)
| Machine: 0x14C (I386)
[!] Warning - Entrypoint is INVALID (file may be damaged)
Compilation TimeStamp : 0x7F61DB01 -> Mon 21st Sep 2037 04:18:09 (GMT)
[TimeStamp] 0x7F61DB01 -> Mon 21st Sep 2037 04:18:09 (GMT) | PE Header | - |
Offset: 0x0000000C | VA: 0x0040000C | -
[LoadConfig] CodeIntegrity -> Flags 0xA3F0 | Catalog 0x46 (70) | Catalog Offset
0x2000001 | Reserved 0x46A4A0
[LoadConfig] GuardAddressTakenIatEntryTable 0x8000011 | Count 0x46A558
(4629848)
[LoadConfig] GuardLongJumpTargetTable 0x8000001 | Count 0x46A5F8 (4630008)
[LoadConfig] HybridMetadataPointer 0x8000011 | DynamicValueRelocTable 0x46A66C
[LoadConfig] FailFastIndirectProc 0x8000011 | FailFastPointer 0x46C360
[LoadConfig] UnknownZero1 0x8000011
[File Heuristics] -> Flag #1 : 00010001000001111110000011001000 (0x1107E0C8)
[DllCharacteristics] -> Flag : (0x0000) -> NONE
[SectionCount] 0 (0x0) | ImageSize 0x2263B6EB (576960235) byte(s)
[!} Warning - image has NO Data Directories... 
[!] Warning : Import Table is bad !!!
-> Suspicious MZ Header.. 
[!] File appears to have no protection or is using an unknown protection
- Scan Took : 0.211 Second(s) [0000000D3h (211) tick(s)] [506 of 580 scan(s)
done]
--- snip ---

LordPE dump (helper tool crashes during analysis but main app still shows
info):

--- snip ---
->DOS Header
   e_magic:     0x5A4D
   e_cblp:      0x3032
   e_cp:        0x4550
   e_crlc:      0x0000
   e_cparhdr:   0x014C
   e_minalloc:  0x0000
   e_maxalloc:  0xDB01
   e_ss:        0x7F61
   e_sp:        0xD010
   e_csum:      0x7317
   e_ip:        0x4775
   e_cs:        0xF9EB
   e_lfarlc:    0x0008
   e_ovno:      0x0002
   e_res:       0x010BC911854579C0
   e_oemid:     0x011F
   e_oeminfo:   0x50D3
   e_res2:      0xE2F73D90005C0000F3F7C139DB1948EB00000040
   e_lfanew:    0x00000004

->File Header
   Machine:               0x014C  (I386)
   NumberOfSections:      0x0000
   TimeDateStamp:         0x7F61DB01  (GMT: Mon Sep 21 04:18:09 2037)
   PointerToSymbolTable:  0x7317D010
   NumberOfSymbols:       0xF9EB4775
   SizeOfOptionalHeader:  0x0008
   Characteristics:       0x0002
                          (EXECUTABLE_IMAGE)

->Optional Header
   Magic:                        0x010B  (HDR32_MAGIC)
   MajorLinkerVersion:           0x11
   MinorLinkerVersion:           0xC9  -> 17.201
   SizeOfCode:                   0x79C08545
   SizeOfInitializedData:        0x50D3011F
   SizeOfUninitializedData:      0x3D90E2F7
   AddressOfEntryPoint:          0x0000005C
   BaseOfCode:                   0xC139F3F7
   BaseOfData:                   0x48EBDB19
   ImageBase:                    0x00400000
   SectionAlignment:             0x00000004
   FileAlignment:                0x00000004
   MajorOperatingSystemVersion:  0xA30F
   MinorOperatingSystemVersion:  0x7D2D  -> 41743.32045
   MajorImageVersion:            0x4001
   MinorImageVersion:            0x8D00  -> 16385.36096
   MajorSubsystemVersion:        0x0004
   MinorSubsystemVersion:        0xCEEB  -> 4.52971
   Win32VersionValue:            0x00000000
   SizeOfImage:                  0x2263B6EB      ; <------- important!
   SizeOfHeaders:                0x00000040
   CheckSum:                     0xBBED3153
   Subsystem:                    0x0002  (WINDOWS_GUI)
   DllCharacteristics:           0x0000
   SizeOfStackReserve:           0x0154BE90
   SizeOfStackCommit:            0x016A0040
   SizeOfHeapReserve:            0x0000BF58
   SizeOfHeapCommit:             0x00B10042
   LoaderFlags:                  0x12EB5757
   NumberOfRvaAndSizes:          0x00000000
--- snip ---

The PE compressor used for most of these 4K/8K demos is named 'Crinkler':

http://www.crinkler.net/

--- quote ---
Crinkler is an executable file compressor (or rather, a compressing linker) for
Windows specifically targeted towards executables with a size of just a few
kilobytes. As of 2018, it is the most widely used tool for compressing 4k
intros.

Crinkler is being developed by Rune L. H. Stubbe (Mentor/TBC) and Aske Simon
Christensen (Blueberry/Loonies). 
--- quote ---

The compression itself and some parts of imports resolver are nicely covered
here:

http://code4k.blogspot.de/2010/12/crinkler-secrets-4k-intro-executable.html

The decompression area for code, data etc. starts usually at fixed 0x420000
address range.
One can easily bypass all the decompression stuff from entry and set a hardware
breakpoint on execution to 0x420000.

NOTE: Not all 8K demos from http://www.pouet.net can be fixed in Wine nor run
in modern Windows (bug 42125). Crinkler uses the PE optional header
'SizeOfImage' field to have the loader allocate a huge chunk of memory used for
decompression.

Memory map:

--- snip ---
Address   Size      Owner     Section         Contains
00110000  00010000
00220000  00001000                            Process Parameters
00230000  00003000                            Environment
00400000  2263C000  lns-lpt-psyltcipher_720   PE header (+SizeOfImage)
22A40000  00001000
22A41000  00001000
22A42000  016AE000                            Stack of main thread
7B420000  00001000  KERNEL32                  PE header
7B421000  00221000  KERNEL32  .text           Code
7B642000  001B1000  KERNEL32  .data           Data,imports,exports, ..
7BC30000  00001000  ntdll                     PE header
7BC31000  000BF000  ntdll     .text           Code
7BCF0000  0001D000  ntdll     .data           Data,exports,resources
7FFD8000  00004000                            Data block of main thread
7FFDF000  00001000                            Process Environment Block
7FFE0000  00010000
...
--- snip ---

https://github.com/wine-staging/wine-staging/blob/master/patches/kernel32-PE_Loader_Fixes/0003-kernel32-On-process-entry-store-PEB-address-in-ebx.patch

Relevant part of Crinkler code:

--- snip ---
; PE entry
0040005C  53           PUSH EBX                 ; PEB, see later
0040005D  31ED         XOR EBP,EBP
0040005F  BB 02000000  MOV EBX,2
00400064  90           NOP
00400065  BE 54014000  MOV ESI,OFFSET 00400154
0040006A  6A 01        PUSH 1
0040006C  58           POP EAX
0040006D  BF 00004200  MOV EDI,OFFSET 00420000
00400072  B1 00        MOV CL,0
00400074  57           PUSH EDI
00400075  57           PUSH EDI
00400076  EB 12        JMP SHORT 0040008A
...

; OEP after decompression
00420000  5F           POP EDI
00420001  B9 1D000000  MOV ECX,1D
00420006  B0 E8        MOV AL,0E8
00420008  AE           SCAS BYTE PTR ES:[EDI]
00420009  75 FB        JNE SHORT 00420006
0042000B  8B07         MOV EAX,DWORD PTR DS:[EDI]
0042000D  98           CWDE
0042000E  3B07         CMP EAX,DWORD PTR DS:[EDI]
00420010  75 F4        JNE SHORT 00420006
00420012  29F8         SUB EAX,EDI
00420014  98           CWDE
00420015  AB           STOS DWORD PTR ES:[EDI]
00420016  E2 EE        LOOP SHORT 00420006
00420018  BB 08014000  MOV EBX,OFFSET 00400108
0042001D  BE D3124200  MOV ESI,OFFSET 004212D3
00420022  BF 00004300  MOV EDI,OFFSET 00430000
00420027  58           POP EAX                       ; was EBX -> PEB
00420028  8B40 0C      MOV EAX,DWORD PTR DS:[EAX+0C] ; PEB_LDR_DATA
; InLoadOrderModuleList->LDR_DATA_TABLE_ENTRY
0042002B  8B40 0C      MOV EAX,DWORD PTR DS:[EAX+0C]
; LDR_DATA_TABLE_ENTRY->InLoadOrderLinks
0042002E  8B00         MOV EAX,DWORD PTR DS:[EAX]
00420030  8B00         MOV EAX,DWORD PTR DS:[EAX]    ; Flink
; _LDR_DATA_TABLE_ENTRY.DllBase (kernel32)
00420032  8B68 18      MOV EBP,DWORD PTR DS:[EAX+18] 
00420035  31C0         XOR EAX,EAX
00420037  AC           LODS BYTE PTR DS:[ESI]        ; "user32"
00420038  85ED         TEST EBP,EBP
0042003A  75 12        JNE SHORT 0042004E
0042003C  85C0         TEST EAX,EAX
0042003E  74 5B        JE SHORT 0042009B
00420040  6A 00        PUSH 0
00420042  6A 00        PUSH 0
00420044  52           PUSH EDX                      ; "d3d11"
00420045  6A 00        PUSH 0
00420047  FF15 180043. CALL DWORD PTR DS:[430018]    ; user32.MessageBoxA
0042004D  C3           RETN
...
--- snip ---

$ sha1sum lns-*
482e8d0fe4b5e6f7ffa6f2125143da5aadab34ad  lns-lpt-psyltcipher_1080.exe
1da4738309c2738f5f89c4713c689a93b94cd898  lns-lpt-psyltcipher_1080_vsync.exe
7bab7cb1c8f528878b1547147d2c97dfa1032eab  lns-lpt-psyltcipher_720.exe
85d1624523110af6c00cc53027e3b504ef3d5362  lns-lpt-psyltcipher.zip

$ du -sh lns-*
8.0K    lns-lpt-psyltcipher_1080.exe
8.0K    lns-lpt-psyltcipher_1080_vsync.exe
8.0K    lns-lpt-psyltcipher_720.exe
24K    lns-lpt-psyltcipher.zip

$ wine --version
wine-3.4-256-g725ad420e1

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list