http://bugs.winehq.org/show_bug.cgi?id=26284
Summary: Crysis 2 demo needs msvcr90.dll._snscanf (purist) Product: Wine Version: 1.3.14 Platform: x86 OS/Version: Linux Status: NEW Keywords: download Severity: enhancement Priority: P2 Component: msvcrt AssignedTo: wine-bugs@winehq.org ReportedBy: austinenglish@gmail.com
Mscodescan shows: ./OpenAutomatePlugin.dll imports following stub symbols: msvcr90:_CRT_RTC_INITW msvcr90:_wassert
which doesn't look very bad, so I tried setting it to builtin in winecfg. Running crysis2 then crashes on: wine: Call from 0x7b8396d3 to unimplemented function msvcr90.dll._snscanf, aborting
There may be more missing, but mscodescan isn't finding them for some reason...
http://bugs.winehq.org/show_bug.cgi?id=26284
--- Comment #1 from Austin English austinenglish@gmail.com 2011-03-02 14:49:13 CST --- For the curious, apparently that function isn't being imported directly: austin@aw21 ~/.wine/drive_c/Program Files/Electronic Arts/Crytek/Crysis 2 Demo/bin32 $ for x in *.dll ; do grep -al snscanf $x ; done CryNetwork.dll CrySystem.dll
austin@aw21 ~/.wine/drive_c/Program Files/Electronic Arts/Crytek/Crysis 2 Demo/bin32 $ winedump -j imports CrySystem.dll Contents of CrySystem.dll: 9198080 bytes
Done dumping CrySystem.dll
winedump on CryNetwork.dll shows some imports, but for msvcr90, only shows: offset 0089d21a MSVCR90.dll Hint/Name Table: 00000000 TimeDateStamp: 00000000 (Wed Dec 31 16:00:00 1969) ForwarderChain: 00000000 First thunk RVA: 00D0517A Ordn Name 0 malloc d050d0
http://bugs.winehq.org/show_bug.cgi?id=26284
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #2 from Anastasius Focht focht@gmx.net 2011-03-02 16:07:11 CST --- Hello,
well the PE files are probably protected/encrypted/obfuscated hence you won't see much useful stuff using "offline" tools.
Various PE protectors decrypt the import address table at runtime at dynamic memory location. Usually a matter of seconds to find and reconstruct using the right tools ;-) If you're lucky msvcr90._snscanf might be the only one needed here...
Regards
http://bugs.winehq.org/show_bug.cgi?id=26284
--- Comment #3 from Anastasius Focht focht@gmx.net 2011-03-02 18:16:46 CST --- Hello,
[priv email]
What sort of tools?
well it's not secret knowledge, hence I answer in public as others might be interested too...
Tools like LordPE and Imprec. They are discontinued for some time now but still very useful for various tasks. Fortunately, these tools work decently with Wine ;-)
If you are only after import address table/imported functions in dynamic memory without dumping/reconstructing the PE file, "Imprec" might be your friend. I maintain appdb entries for some of these tools.
Imprec: http://appdb.winehq.org/objectManager.php?sClass=application&iId=8554
LordPE: http://appdb.winehq.org/objectManager.php?sClass=application&iId=8541
You need to operate on the "live" process, e.g. you need to keep the process in memory before it gets terminated due to unimpl stub handling (using crash handler/debugger/fault reporting tool). Most likely you will have enough time to attach after startup without resorting to trickery.
Imprec: attach to the desired process using process list - make sure you use same WINEPREFIX/wineserver. These tools usually work by injecting helper dlls into remote process address space or by reading remote process memory directly.
Select the PE dll from attached process you want to investigate. Use "auto search" in "IAT infos needed". If you get an error message "Could not find anything ..." the original entry point address (taken from PE header) is most likely not suitable, e.g. points to startup code or initial protection code. Adjust the OEP field to a low offset like 0x1000 and do auto search again. If it succeeds, use "get imports" and you will be presented a list of imported dlls and functions gathered by using various sophisticated methods (you can apply even more methods manually thereafter to get better results). You can save the imports list to a text file using "Save tree".
Unfortunately you need to manually search the saved tree or use a script to find the unimpl Wine stubs among all the imports.
It should be possible to get the "Mscodescan" script to work for these dlls but that requires a bit more work. Basically you need to dump the PE at runtime from memory (using LordPE) and reconstruct/rebuild a new (valid) import table (using Imprec) and then run the script on it.
Regards
http://bugs.winehq.org/show_bug.cgi?id=26284
--- Comment #4 from Austin English austinenglish@gmail.com 2011-03-02 20:21:12 CST --- Thanks Anastasius!
Using Imprec, looks like it's missing: _crt_debugger_hook _i64toa _snscanf _wassert
from CryNetwork.dll
CrySystem.dll just gave me a bunch of ordinal addresses, not proper imports...
http://bugs.winehq.org/show_bug.cgi?id=26284
--- Comment #5 from Anastasius Focht focht@gmx.net 2011-03-03 02:54:52 CST --- Hello,
--- quote --- CrySystem.dll just gave me a bunch of ordinal addresses, not proper imports... --- quote ---
Hmm ok, I took a look at it. The demo is a whopping 1.5 GiB download :| As suspected these PE files are wrapped with some custom protection (PEid tools don't reveal a known protection).
After installation you start the demo with msvcr90 set to Wine builtin.
--- snip --- ~/.wine/drive_c/Program Files/Electronic Arts/Crytek/Crysis 2 Demo/bin32$ WINEDEBUG=+loaddll,+process WINEDLLOVERRIDES="msvcr90=b" wine ./Crysis2Demo.exe
... wine: Call from 0x7b838547 to unimplemented function msvcr90.dll._snscanf, aborting trace:loaddll:load_builtin_dll Loaded L"C:\windows\system32\faultrep.dll" at 0x6af60000: builtin fixme:faultrep:ReportFault 0x32df34 0x0 stub trace:loaddll:free_modref Unloaded module L"C:\windows\system32\faultrep.dll" : builtin --- snip ---
Fortunately due to fault reporting stub, the process is left in zombie state ;-) At this point attach using Imprec, select the process and then "pick dll" -> "crysystem.dll" (it has a default load base of 0x10000000). You need to fix the OEP offset to some sane value, e.g. 0x1000 (original one points to protector code). After that do "IAT auto search". It finds a possible IAT in dynamic memory.
--- snip --- ... ->> Module selected: c:\program files\electronic arts\crytek\crysis 2 demo\bin32\crysystem.dll Image Base:10000000 Size:010BB000 Original IAT RVA found at: 002BA2E0 in Section RVA: 002BA000 Size:0003C000 --- snip ---
Use "get imports" to retrieve the table.
--- snip --- IAT read successfully. ... Current imports: A (decimal:10) valid module(s) (added: +A (decimal:+10)) 171 (decimal:369) imported function(s). (added: +171 (decimal:+369)) --- snip ---
If you look at the list you notice some nodes are marked "valid:NO". Collapse these. The 4th node is the one with msvcr90.dll imports we are interested in. The tool treats the memory location like the original bound IAT - the imports are grouped by dll and separated by NULL IAT entries.
You can use the "Show Invalid" feature to highlight thunks that the tools treats as suspect. Basically the tool expects a NULL IAT entry (like original bound IAT) between groups of functions belonging to different imported modules.
Because some of the imports are forwarded ones (kernel32.dll -> ntdll.dll, msvcr90.dll -> msvcrt.dll and the like) they are resolved at this point. The tool doesn't know the original non-resolved forwards and treats it as "suspect".
Select the first import that has a different dll name within the thunk group. For example: there is a single msvcrt.dll _strcmpi import in between the all msvcr90.dll imports. Double click it. Select "msvcr90.dll" as module and "_stricmp" (which is the original import). Now the node state changes to "valid" -> all imports from this module are correctly resolved. You could fix the other remaining entries (kernel32/ntdll) in same manner if you like but we only interested in msvcrt90 imports. Just do a quick cut/delete thunk for the remaining ones (right click on first suspect one and cut). NOTE: this renders the executable unsuable at runtime but we only want to rebuild PE header for running the "mscodescan.pl" tool.
Keep Imprec running and dump the dll using LordPE. Fire the tool up and select the correct process. Right click on desired dll and "dump full". This creates a large (17 MiB) "dumped.dll" file on disk as raw dump. Go back to "Imprec" and select "Fix dump", select the file "dumped.dll" previously created by LordPE.
Now a "dumped_.dll" is created on disk with a new PE header written (additional section for rebuilt IAT got appended). NOTE: this PE binary is not runnable at all due to shortcuts previously taken (some IAT thunks cut/deleted, original entry point still points to wrong location, section header flags ...).
Now run "mscodescan.pl" again and voila:
./dumped_.dll imports following stub symbols: msvcr90:_snscanf
Looks like we got lucky and its really the only one needed here ;-)
Regards
http://bugs.winehq.org/show_bug.cgi?id=26284
--- Comment #6 from Austin English austinenglish@gmail.com 2011-03-03 13:28:55 CST --- /me bookmarks this bug for future debugging reference :-)
http://bugs.winehq.org/show_bug.cgi?id=26284
zil zilforever@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |zilforever@gmail.com
--- Comment #7 from zil zilforever@gmail.com 2011-03-26 05:47:37 CDT --- wine: Call from 0x7b8396d3 to unimplemented function msvcr90.dll._snscanf, aborting
confirm in demo and full game
http://bugs.winehq.org/show_bug.cgi?id=26284
Piotr Caban piotr.caban@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |piotr.caban@gmail.com
--- Comment #8 from Piotr Caban piotr.caban@gmail.com 2011-04-05 10:13:14 CDT --- I've sent patches that should fix this game: http://source.winehq.org/patches/data/72940 http://source.winehq.org/patches/data/72941 http://source.winehq.org/patches/data/72943
http://bugs.winehq.org/show_bug.cgi?id=26284
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |FIXED
--- Comment #9 from Austin English austinenglish@gmail.com 2011-04-05 14:24:21 CDT --- Fixed by: http://source.winehq.org/git/wine.git/commitdiff/220b6ab37f9d42f9e2d09fdad8c... http://source.winehq.org/git/wine.git/commitdiff/405e6eb309ba7dbefe88725a96f... http://source.winehq.org/git/wine.git/commitdiff/d09ab74d9bc6d6ad8221a22b315... http://source.winehq.org/git/wine.git/commitdiff/2d7fa5f2435ed2a7f322851a594...
http://bugs.winehq.org/show_bug.cgi?id=26284
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #10 from Alexandre Julliard julliard@winehq.org 2011-04-15 12:51:24 CDT --- Closing bugs fixed in 1.3.18.
http://bugs.winehq.org/show_bug.cgi?id=26284
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |2d7fa5f2435ed2a7f322851a594 | |e993c52d85395