[Bug 45249] Zockinger Facilitator (TFFT) v1.15 crashes on startup

wine-bugs at winehq.org wine-bugs at winehq.org
Mon Jul 16 10:51:24 CDT 2018


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

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |obfuscation
                 CC|                            |focht at gmx.net
            Summary|page fault on read access - |Zockinger Facilitator
                   |Zockinger Facilitator       |(TFFT) v1.15 crashes on
                   |                            |startup

--- Comment #5 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

the app contains various anti-debug measures.
The first layer is PE Compact v2.x:

--- 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\zocfft\ZOCFFT.exe
File Type : 32-Bit Exe (Subsystem : Win GUI / 2), Size : 1898824 (01CF948h)
Byte(s) | Machine: 0x14C (I386)
Compilation TimeStamp : 0x5A008BA1 -> Mon 06th Nov 2017 16:19:45 (GMT)
[TimeStamp] 0x5A008BA1 -> Mon 06th Nov 2017 16:19:45 (GMT) | PE Header | - |
Offset: 0x00000088 | VA: 0x00400088 | -
-> File Appears to be Digitally Signed @ Offset 01CD850h, size : 020F8h / 08440
byte(s)
[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 : 00000000000001011100000000100110 (0x0005C026)
[Entrypoint Section Entropy] : 8.00 (section #0) ".text   " | Size : 0x1CC000
(1884160) byte(s)
[DllCharacteristics] -> Flag : (0x0000) -> NONE
[SectionCount] 3 (0x3) | ImageSize 0x2E8000 (3047424) byte(s)
[VersionInfo] Company Name : Zockinger Technologies
[VersionInfo] Product Name : The Facilitator for TSM
[VersionInfo] Product Version : 1.15.0.555
[VersionInfo] File Description : The Facilitator for TSM
[VersionInfo] File Version : 555
[VersionInfo] Original FileName : ZOCFFT.exe
[VersionInfo] Internal Name : TFFT
[VersionInfo] Legal Copyrights : (C) 2017 Zockinger Technologies
[ModuleReport] [IAT] Modules -> kernel32.dll
[!] PE Compact v20352 (internal version) compressed !
- Scan Took : 0.488 Second(s) [0000001E8h (488) tick(s)] [506 of 580 scan(s)
done]
--- snip ---

Unwrapping the first layer until OEP is fairly easy. There is another
protection scheme though, which seems custom. The app uses custom imports
resolver and relay thunks don't work here.

* kernel32.dll
* user32.dll
* advapi32.dll
* comctl32.dll

--- snip ---
...
002f:Call KERNEL32.VirtualProtect(00503000,001e2000,00000040,0033fe04)
ret=00401244
002f:Ret  KERNEL32.VirtualProtect() retval=00000001 ret=00401244
002f:Call KERNEL32.VirtualAlloc(00000000,00334930,00003000,00000040)
ret=0051cfbf
002f:Ret  KERNEL32.VirtualAlloc() retval=00b00000 ret=0051cfbf
002f:Call KERNEL32.VirtualAlloc(00000000,00003700,00003000,00000040)
ret=00b2e4f9
002f:Ret  KERNEL32.VirtualAlloc() retval=00360000 ret=00b2e4f9
002f:Call KERNEL32.VirtualAlloc(00000000,00003700,00003000,00000040)
ret=00b2e4f9
002f:Ret  KERNEL32.VirtualAlloc() retval=00370000 ret=00b2e4f9
002f:Call KERNEL32.VirtualAlloc(00000000,00003700,00003000,00000040)
ret=00b2e4f9
002f:Ret  KERNEL32.VirtualAlloc() retval=00380000 ret=00b2e4f9
002f:Call KERNEL32.VirtualFree(00360000,00000000,00008000) ret=00b174b8
002f:Ret  KERNEL32.VirtualFree() retval=00000001 ret=00b174b8
002f:Call KERNEL32.VirtualFree(00370000,00000000,00008000) ret=00b174b8
002f:Ret  KERNEL32.VirtualFree() retval=00000001 ret=00b174b8
002f:Call KERNEL32.LoadLibraryA(00b0038e "KERNEL32.dll") ret=00b1c0b7
002f:Ret  KERNEL32.LoadLibraryA() retval=7b420000 ret=00b1c0b7
002f:trace:seh:raise_exception code=c0000005 flags=0 addr=0x836d0cd9
ip=836d0cd9 tid=002f
002f:trace:seh:raise_exception  info[0]=00000008
002f:trace:seh:raise_exception  info[1]=836d0cd9
002f:trace:seh:raise_exception  eax=0059ceff ebx=00b002b2 ecx=00000083
edx=00000000 esi=00b00014 edi=0033fbb8
002f:trace:seh:raise_exception  ebp=0033fb98 esp=0033fb78 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00210293
002f:trace:seh:call_stack_handlers calling handler at 0x7b490024 code=c0000005
flags=0
wine: Unhandled page fault on execute access to 0x836d0cd9 at address
0x836d0cd9 (thread 002f), starting debugger...
002f:trace:seh:start_debugger Starting debugger "winedbg --auto 46 136"
002f:trace:seh:call_stack_handlers handler at 0x7b490024 returned 1
Unhandled exception: page fault on execute access to 0x836d0cd9 in 32-bit code
(0x836d0cd9).
Register dump:
 CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
 EIP:836d0cd9 ESP:0033fb78 EBP:0033fb98 EFLAGS:00210293(  R- --  I S -A- -C)
 EAX:0059ceff EBX:00b002b2 ECX:00000083 EDX:00000000
 ESI:00b00014 EDI:0033fbb8
Stack dump:
0x0033fb78:  7b4313c0 0059ceff 00a40248 00b0af2d
0x0033fb88:  0033fbb8 7b420000 7b64ce3d 00b00014
0x0033fb98:  0033fcf4 00b2091c 00b00014 0033fbb8
0x0033fba8:  00000000 0033fd84 0033fd24 00b00014
0x0033fbb8:  6c64746e 7bd0006c 7bd0f2d6 7bd0f388
0x0033fbc8:  7bd0f2c1 7bd0f388 00000000 00000000
Backtrace:
=>0 0x836d0cd9 (0x0033fb98)
  1 0x00b2091c (0x0033fcf4)
  2 0x00b062be (0x0033fd9c)
  3 0x00b1c5f3 (0x0033fdc8)
  4 0x00b00f36 (0x00503104)
  5 0x7b432ad4 in kernel32 (+0x12ad3) (0x7b431754)
--- snip ---

--- snip ---
002f:Call KERNEL32.VirtualAlloc(00000000,00334930,00003000,00000040)
ret=0051cfbf
002f:Ret  KERNEL32.VirtualAlloc() retval=00b00000 ret=0051cfbf 
--- snip ---

--- snip ---
00B00000  E8 00000000   CALL 00B00005
00B00005  5B            POP EBX
00B00006  8DB3 5F430000 LEA ESI,[EBX+435F]
00B0000C  E9 C7040000   JMP 00B004D8
--- snip ---

Another debugging tidbit: the app protection stores state data past the current
ESP which makes single stepping painful. You have to recognize those sequences
and *not* single step nearby -> bug 28089 ("exception handling code touches
stack for exceptions handled by the debugger")

Examples:

--- snip ---
0051D033  F0:DB2B       LOCK FLD TBYTE PTR DS:[EBX]                             
0051D036  83EC 04       SUB ESP,4
0051D039  890424        MOV DWORD PTR SS:[ESP],EAX
0051D03C  C1F8 00       SAR EAX,0                                               
0051D03F  897424 FC     MOV DWORD PTR SS:[ESP-4],ESI ; taint if single stepped
0051D043  83EC 04       SUB ESP,4
0051D046  83EC 04       SUB ESP,4
0051D049  890C24        MOV DWORD PTR SS:[ESP],ECX   
0051D04C  894424 FC     MOV DWORD PTR SS:[ESP-4],EAX ; taint if single stepped
0051D050  83EC 04       SUB ESP,4
0051D053  60            PUSHAD
--- snip ---

--- snip ---
00B1D0F3  5F            POP EDI
00B1D0F4  894424 FC     MOV DWORD PTR SS:[ESP-4],EAX ; taint if single stepped
00B1D0F8  F3:EB 02      REP JMP SHORT 00B1D0FD
00B1D0FB  D15CE9 B1     RCR DWORD PTR DS:[EBP*8+ECX-4F],1
00B1D0FF  E4 FF         IN AL,0FF
00B1D101  FFC3          INC EBX
00B1D103  E9 02000000   JMP 00B1D10A
--- snip ---

Additionally various threads check for hardware breakpoints being used which is
expected as most of the (obfuscated) protection code unwraps dynamically -> you
don't want to use softbp here.

--- snip ---
0147:trace:seh:__regs_NtGetContextThread 0xfffffffe: dr0=00000000 dr1=00000000
dr2=00000000 dr3=00000000 dr6=00000000 dr7=00000000
016b:trace:seh:__regs_NtGetContextThread 0xfffffffe: dr0=00000000 dr1=00000000
dr2=00000000 dr3=00000000 dr6=00000000 dr7=00000000
01b1:trace:seh:__regs_NtGetContextThread 0xfffffffe: dr0=00000000 dr1=00000000
dr2=00000000 dr3=00000000 dr6=00000000 dr7=00000000
01db:warn:process:SetProcessWorkingSetSize (0xffffffff,-1,-1): stub - harmless
01de:trace:seh:__regs_NtGetContextThread 0xfffffffe: dr0=00000000 dr1=00000000
dr2=00000000 dr3=00000000 dr6=00000000 dr7=00000000
--- snip ---

TFFT v1.15 doesn't crash with Wine 3.12 for me but just exits after
considerable number of seconds (maybe because I run a no-PIC build by default).

Interestingly the author published a new version TFFT v1.16 which seems to run
fine for me (shows GUI).

--- quote ---
TFFT V1.16 released
posted 10 Jul 2018, 11:28 by Good old Zockinger

TFFT V1.16 contains a lot of bug fixes and brings improved ISP 8.x support 
--- quote ---

Maybe some of the bugfixes are Windows compatibility issues. Things that just
worked by chance on certain Windows versions and the fixes helped Wine too.

It would be still interesting to figure out what makes FFT V1.15 unhappy with
Wine since it is reported to work on Windows. By chance or depending on some
internals/implementation details of Windows binaries/loader.

$ sha1sum TFFT11*
b0c1af725743ff48f7b37c8c6ce5e04443d85d2d  TFFT115.ZIP
2c4660f0cbf6f65ce29724aac809fed746dec342  TFFT116.ZIP

$ du -sh TFFT11*
2.1M    TFFT115.ZIP
2.2M    TFFT116.ZIP

$ wine --version
wine-3.12-111-g8ae98cfdc3

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