[Bug 29792] New: Gothic 2 (JoWood Productions) installer fails due to media validation tool failing (don't add FILE_ATTRIBUTE_ARCHIVE by default to file entries)

wine-bugs at winehq.org wine-bugs at winehq.org
Sat Feb 4 14:43:11 CST 2012


http://bugs.winehq.org/show_bug.cgi?id=29792

             Bug #: 29792
           Summary: Gothic 2 (JoWood Productions) installer fails due to
                    media validation tool failing (don't add
                    FILE_ATTRIBUTE_ARCHIVE by default to file entries)
           Product: Wine
           Version: 1.4-rc1
          Platform: x86
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: ntdll
        AssignedTo: wine-bugs at winehq.org
        ReportedBy: focht at gmx.net
    Classification: Unclassified


Hello,

I first wanted to investigate bug 22515 hence i bought the game for a few bucks
and looked into it...

Well, it seems there exist different editions of the game and the problems
might not be connected at all.

Although this is related to copy protection it's not the SecuROM 4.x tests
failing here - that part of protection works fine.

I have the 3 CD set by JoWood Productions released on November 29, 2002.

Near the end of installation process there is a tool "g2setup.exe" launched
which verifies the authenticity of install media.
That process returns a specific exit code (0x777 -> 1911) which basically says:
"all checks passed".
Any different exit code will roll back the whole installation!

Current workaround: kill the installer from another terminal when this
verification process starts.

Everything has already been copied up to this point so just wait until the disc
spins up and execute 'wineserver -k'.

--- snip ---
0024:Starting process L"C:\\Program Files\\Jowood\\Gothic II\\g2setup.exe"
(entryproc=0x4c6929) 
--- snip ---

--- snip ---
-=[ ProtectionID v0.6.4.0 JULY]=-
(c) 2003-2010 CDKiLLER & TippeX
Build 07/08/10-17:57:05
...
Scanning -> Z:\home\focht\.wine\drive_c\Program Files\Jowood\Gothic
II\g2setup.dll
File Type : 32-Bit Dll (Subsystem : Win GUI / 2), Size : 229376 (038000h)
Byte(s)
[File Heuristics] -> Flag : 00000000000000001100001100000001 (0x0000C301)
[!] Armadillo v2.xx - v3.xx detected !
[i] Splash Setting (0x0) -> NONE / Duration : 00 second(s)
[CompilerDetect] -> Visual C/C++
- Scan Took : 0.560 Second(s)
--- snip ---

Various anti-debugging/hacking trickery which of course can be bypassed ;-)

Additionally to physical media analysis of GOTHIC2_CD3 (part of SecuROM) there
are "custom" checks present.
Most of them are simple ones like comparing disc serial against hard coded
value.

The directory structure is read from disc and CRC32 checksums are calculated
for specific files.

--- snip ---
   ATTRIBS       SIZE       CRC32   NAME
____________________________________________________________


     A R         362,789,836  5f4cb098  Gothic2-Setup.W03
     A R                 123            JoWooD Homepage.url
     A R              14,816            Readme.txt
     A R                 289            Register.url
     A R               5,569            eula.txt
     A R                 766            gothic2.ico
       (DIR)     168,146,318            ArxDemo
     A R              31,744  1d31e5c6  ArxDemo\Setup.exe
     A R                 877            ArxDemo\Setup.ini
     A R           1,304,064            ArxDemo\Setup.msi
     A R         101,581,207            ArxDemo\Setup1.cab
     A R          23,103,162            ArxDemo\Setup2.cab
     A R          31,150,491            ArxDemo\Setup3.cab
     A R           1,309,184            ArxDemo\Setup_Deutsch.msi
     A R           1,708,856  34ec21c0  ArxDemo\instmsi.exe
     A R           1,822,520  e5563f20  ArxDemo\instmsiw.exe
...
Scan time.............[          551.80] Seconds (551801 ms)
Total files...........[              35] Files
Total size............[     558,468,227] Bytes
Dirlist Text CRC32....[        0032ED44]
____________________________________________________________
...
--- snip ---

Forget the scan time, I was debugging at this place ;-)

What makes things complicated is that additionally to per-file CRC32 checksums
there is also a CRC32 for the whole in-memory folder listing content generated
(see snippet) -> "Dirlist Text CRC32" (in snippet the address is printed, not
the value itself).

That overall checksum didn't match the internal hard-coded one.

One problem is that Wine adds FILE_ATTRIBUTE_ARCHIVE by default to each file
info entry.

Source:
http://source.winehq.org/git/wine.git/blob/c7cb3e6cb21598281cf2b00b2ccd8323598b12ff:/dlls/ntdll/file.c#l1579

This is breaks the overall checksum (file entries get "A" added).
The file entries have to have only FILE_ATTRIBUTE_READONLY set -> "R" (reside
on CDROM).

If FILE_ATTRIBUTE_ARCHIVE is omitted (and a second bug is worked around) the
verification process exits with exit code 0x777 which allows the main installer
to successfully finish.

---

There is another problem, a bug in the verification tool that unfortunately
prevents a "full" fix for this installer.

One of the file CRC32 on CD3 gets miscalculated ...
It took me some hours to find out this brain damage after successfully pinning
down the first problem and wondering why the overall checksum still didn't
match.

--- snip ---
...
0024:Call KERNEL32.CreateFileA(0032d734
"D:\\arxdemo\\setup.exe",80000000,00000001,00000000,00000003,00000080,00000000)
ret=00d86dfe
0024:Ret  KERNEL32.CreateFileA() retval=000000a0 ret=00d86dfe
0024:Call KERNEL32.GetFileSize(000000a0,00000000) ret=00d87385
0024:Ret  KERNEL32.GetFileSize() retval=00007c00 ret=00d87385
0024:Call ntdll.RtlAllocateHeap(00fc0000,00000000,00010010) ret=00be379b
0024:Ret  ntdll.RtlAllocateHeap() retval=00fc5238 ret=00be379b
0024:Call KERNEL32.ReadFile(000000a0,00fc5238,00010000,00bfd464,00000000)
ret=00d8725a
0024:Ret  KERNEL32.ReadFile() retval=00000001 ret=00d8725a
0024:Call ntdll.RtlFreeHeap(00fc0000,00000000,00fc5238) ret=00be3cea
0024:Ret  ntdll.RtlFreeHeap() retval=00000001 ret=00be3cea
0024:Call KERNEL32.CloseHandle(000000a0) ret=00d8743a
0024:Ret  KERNEL32.CloseHandle() retval=00000001 ret=00d8743a 
--- snip ---

"D:\\arxdemo\\setup.exe" is the culprit. The file size is 31744 bytes.
The tool allocates a fixed 65552 byte buffer to read file content in and
calculate checksum on (actually 65536 bytes are used for checksumming).

Prior to calculating file CRC32 for "D:\\arxdemo\\setup.exe", the 350 MiB
"D:\\gothic2-setup.w03" was checksummed in 0x10000 byte chunks.

It had the same heap chunk address 0x00fc5238 which was later reused for
"D:\\arxdemo\\setup.exe" checksum calculation.

--- snip ---
0024:Call KERNEL32.CreateFileA(0032dd20
"D:\\gothic2-setup.w03",80000000,00000001,00000000,00000003,00000080,00000000)
ret=00d86dfe
0024:Ret  KERNEL32.CreateFileA() retval=0000009c ret=00d86dfe
0024:Call KERNEL32.GetFileSize(0000009c,00000000) ret=00d87385
0024:Ret  KERNEL32.GetFileSize() retval=159fbbcc ret=00d87385
0024:Call ntdll.RtlAllocateHeap(00fc0000,00000000,00010010) ret=00be379b
0024:Ret  ntdll.RtlAllocateHeap() retval=00fc5238 ret=00be379b
0024:Call KERNEL32.ReadFile(0000009c,00fc5238,00010000,00bfd464,00000000)
ret=00d8725a
0024:Ret  KERNEL32.ReadFile() retval=00000001 ret=00d8725a 
...
0024:Call KERNEL32.ReadFile(0000009c,00fc5238,00010000,00bfd464,00000000)
ret=00d8725a
0024:Ret  KERNEL32.ReadFile() retval=00000001 ret=00d8725a
0024:Call KERNEL32.ReadFile(0000009c,00fc5238,00008480,00bfd464,00000000)
ret=00d8725a
0024:Ret  KERNEL32.ReadFile() retval=00000001 ret=00d8725a
0024:Call KERNEL32.ReadFile(0000009c,00fc5238,00008480,00bfd464,00000000)
ret=00d8725a
0024:Ret  KERNEL32.ReadFile() retval=00000001 ret=00d8725a
0024:Call ntdll.RtlFreeHeap(00fc0000,00000000,00fc5238) ret=00be3cea
0024:Ret  ntdll.RtlFreeHeap() retval=00000001 ret=00be3cea
...
--- snip ---

Because the heap chunk was reused and the buffer was fully filled from previous
run, the read file operation for "D:\\arxdemo\\setup.exe" only initialized the
first 31744 bytes.
The checksum is done on 65536 bytes of buffer which includes garbage/leftover
already present.

Well, the developers didn't bother to pass HEAP_ZERO_MEMORY to
RtlAllocateHeap() or explicit memset(ptr, 0, nbytes).

The tool "works" in Windows most likely due to different heap manager
implementation/usage or maybe application shims.

They put some effort into anti-debugging/hacking/copying and rambled about
piracy in hidden messages (found while debugging) ... and yet managed to put in
such bugs.

You can hack/patch ntdll.dll RtlAllocateHeap() -> forcing flags |=
HEAP_ZERO_MEMORY to verify the installer really works after fixing the first
problem.

Regards

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
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