[Bug 29448] GameShield/SoftwareShield protected apps/games won't start (SetCurrentDirectoryA calling W API causes detours recursion)
wine-bugs at winehq.org
wine-bugs at winehq.org
Sat Aug 17 14:23:31 CDT 2013
http://bugs.winehq.org/show_bug.cgi?id=29448
Anastasius Focht <focht at gmx.net> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |obfuscation
CC| |focht at gmx.net
Component|-unknown |kernel32
Summary|Software Shield demo won't |GameShield/SoftwareShield
|start |protected apps/games won't
| |start (SetCurrentDirectoryA
| |calling W API causes
| |detours recursion)
--- Comment #12 from Anastasius Focht <focht at gmx.net> 2013-08-17 14:23:31 CDT ---
Hello folks,
encountered this problem with "Louisiana Adventure Demo" (bug 34275) which is
protected by GameShield.
A common symptom is the message:
--- snip ---
err:seh:setup_exception_record stack overflow 832 bytes in thread 002c eip
0049fdcf esp 00240ff0 stack 0x240000-0x241000-0x340000
--- snip ---
The protection hooks (detours) a number of win32 API.
Example dump from memory:
--- snip ---
00FE2A88 0103ACA0 ; PTR to ASCII 10,"THookCreateFileW"
00FE2A8C 0103ACC0 ; PTR to ASCII 0D,"THookReadFile"
00FE2A90 0103ACE0 ; PTR to ASCII 0F,"THookReadFileEx"
00FE2A94 00000000
00FE2A98 00000000
00FE2A9C 0103AD00 ; PTR to ASCII 10,"THookCloseHandle"
00FE2AA0 0103AD20 ; PTR to ASCII 13,"THookSetFilePointer"
00FE2AA4 0103ADA0 ; PTR to ASCII 17,"THookCreateFileMappingW"
00FE2AA8 0103AD60 ; PTR to ASCII 17,"THookCreateFileMappingA"
00FE2AAC 0103ADE0 ; PTR to ASCII 12,"THookMapViewOfFile"
00FE2AB0 0103AE20 ; PTR to ASCII 18,"THookGetOverlappedResult"
00FE2AB4 0103AE60 ; PTR to ASCII 10,"THookGetFileSize"
00FE2AB8 0103AE80 ; PTR to ASCII 12,"THookGetFileSizeEx"
00FE2ABC 0103AEC0 ; PTR to ASCII 14,"THookUnmapViewOfFile"
00FE2AC0 0103AF00 ; PTR to ASCII 14,"THookMapViewOfFileEx"
00FE2AC4 0103AF40 ; PTR to ASCII 0E,"THookCopyFileW"
00FE2AC8 0103AF60 ; PTR to ASCII 10,"THookCopyFileExW"
00FE2ACC 0103AF80 ; PTR to ASCII 13,"THookFindFirstFileW"
00FE2AD0 0103AFC0 ; PTR to ASCII 15,"THookFindFirstFileExW"
00FE2AD4 0103B000 ; PTR to ASCII 12,"THookFindNextFileW"
00FE2AD8 0103B040 ; PTR to ASCII 0E,"THookFindClose"
00FE2ADC 0103B0C0 ; PTR to ASCII 10,"THookSearchPathW"
00FE2AE0 0103B0E0 ; PTR to ASCII 17,"THookGetFileAttributesW"
00FE2AE4 0103B120 ; PTR to ASCII 19,"THookGetFileAttributesExW"
00FE2AE8 0103B8C0 ; PTR to ASCII 17,"THookAddFontResourceExA"
00FE2AEC 0103B900 ; PTR to ASCII 17,"THookAddFontResourceExW"
00FE2AF0 0103B940 ; PTR to ASCII 1A,"THookRemoveFontResourceExW"
00FE2AF4 0103B140 ; PTR to ASCII 10,"THookGetFileType"
00FE2AF8 0103B160 ; PTR to ASCII 10,"THookGetFileTime"
00FE2AFC 0103B180 ; PTR to ASCII 1F,"THookGetFileInformationByHandle"
00FE2B00 0103B1A0 ; PTR to ASCII 19,"THookSetCurrentDirectoryA"
00FE2B04 0103B1C0 ; PTR to ASCII 19,"THookSetCurrentDirectoryW"
00FE2B08 0103B260 ; PTR to ASCII 1D,"THookGetPrivateProfileStringA"
00FE2B0C 0103B280 ; PTR to ASCII 1D,"THookGetPrivateProfileStringW"
00FE2B10 0103B2A0 ; PTR to ASCII 1E,"THookGetPrivateProfileSectionA"
00FE2B14 0103B2C0 ; PTR to ASCII 1E,"THookGetPrivateProfileSectionW"
00FE2B18 0103B060 ; PTR to ASCII 21,"THookFindFirstChangeNotificationW"
00FE2B1C 0103B080 ; PTR to ASCII 1F,"THookFindNextChangeNotification"
00FE2B20 0103B0A0 ; PTR to ASCII 20,"THookFindCloseChangeNotification"
00FE2B24 0103B220 ; PTR to ASCII 15,"THookSetFilePointerEx"
00FE2B28 0103B1E0 ; PTR to ASCII 14,"THookReadFileScatter"
00FE2B2C 00000000
...
--- snip ---
Each API to be detoured has a descriptor.
Example for "SetCurrentDirectoryA":
--- snip ---
0103B1A0 00D6D9F4 ; ASCII 19,"THookSetCurrentDirectoryA"
0103B1A4 01041EE0 ; ASCII "SetCurrentDirectoryA"
0103B1A8 7B810000 ; base
0103B1AC 7FFC04D4 ; detour continuation thunk
0103B1B0 7B8600AB ; KERNEL32.SetCurrentDirectoryA
0103B1B4 00000001 ; ref
0103B1B8 00000000 ; entry terminator
--- snip ---
The original entry point detoured:
KERNEL32.SetCurrentDirectoryA(Path)
--- snip ---
7B8600AB E9 13047604 JMP 7FFC04C3
7B8600B0 E4 F0 IN AL,0F0
7B8600B2 FF71 FC PUSH DWORD PTR DS:[ECX-4]
7B8600B5 55 PUSH EBP
7B8600B6 89E5 MOV EBP,ESP
7B8600B8 53 PUSH EBX
7B8600B9 51 PUSH ECX
7B8600BA 83EC 20 SUB ESP,20
7B8600BD E8 EEF2FBFF CALL 7B81F3B0
7B8600C2 81C3 3E8F0500 ADD EBX,58F3E
7B8600C8 89C8 MOV EAX,ECX
7B8600CA C74424 04 00000 MOV DWORD PTR SS:[ESP+4],0
7B8600D2 8B00 MOV EAX,DWORD PTR DS:[EAX]
7B8600D4 890424 MOV DWORD PTR SS:[ESP],EAX
7B8600D7 E8 12D0FDFF CALL 7B83D0EE
7B8600DC 8945 F4 MOV DWORD PTR SS:[EBP-0C],EAX
7B8600DF 837D F4 00 CMP DWORD PTR SS:[EBP-0C],0
7B8600E3 75 07 JNE SHORT 7B8600EC
7B8600E5 B8 00000000 MOV EAX,0
7B8600EA EB 0E JMP SHORT 7B8600FA
7B8600EC 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-0C]
7B8600EF 890424 MOV DWORD PTR SS:[ESP],EAX
7B8600F2 E8 46FFFFFF CALL SetCurrentDirectoryW
7B8600F7 83EC 04 SUB ESP,4
7B8600FA 8D65 F8 LEA ESP,[EBP-8]
7B8600FD 59 POP ECX
7B8600FE 5B POP EBX
7B8600FF 5D POP EBP
7B860100 8D61 FC LEA ESP,[ECX-4]
7B860103 C2 0400 RETN 4
--- snip ---
This is the call sequence leading to failure, gathered from debugging:
--- snip ---
SetCurrentDirectoryA[entry]
-> THookSetCurrentDirectoryA
-> SetCurrentDirectoryA[cont]
-> SetCurrentDirectoryW[entry]
-> THookSetCurrentDirectoryW
-> SetCurrentDirectoryA[cont] (bug)
-> SetCurrentDirectoryW[entry] (recursion)
--- snip ---
The problem appears with nested hooks.
The protection code reads private data from TLS during detour-handling to
retrieve the continuation thunk address.
Although per thread the code doesn't handle nesting properly, ending with
previous (parent) continuation thunk being called, leading to recursion.
Windows SetCurrentDirectoryA() probably doesn't forward the native API call to
W API.
I made a small inline wrapper for SetCurrentDirectoryW() code and had both,
SetCurrentDirectoryW() and SetCurrentDirectoryA() call it.
This avoids hitting both hooks with SetCurrentDirectoryA().
With the patch applied, the protection code is happy.
There might be still similar issues for other API left but the game from bug
34275 started to work (only to run into d3dx9 shader compiler bug).
Also "iw4win.exe" (IronWrapper: IronWrap Linker) starts now though I didn't
bother to figure out how the thing works.
It seems to require an application xml config file as input for further
processing.
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