justinstenning / Direct3DHook

DirectX Capture and Overlays by using Direct3D API hooks
http://spazzarama.com/2011/03/14/c-screen-capture-and-overlays-for-direct3d-9-10-and-11-using-api-hooks
MIT License
580 stars 178 forks source link

Test Screenshot Crashes with Borderlands 2 and XCOM Enemy Within #12

Closed KristjanLaane closed 8 years ago

KristjanLaane commented 10 years ago

Thanks for the great work!

When trying to Inject to XComEW.exe TestScreenshot produces the exception below and fails.

The test is on a Steam game XCOM Enemy Within, running on Windows 8.1 64bit As a positive result, the Steam game Wasteland 2 overlays work fine on the same machine (using Direct3D v9)

I'm not compentent to understand any of the below I'm afraid, so I was hoping you could determine what the issue is.

Here are the error details:

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
Capture.InjectionFailedException: Injection to the target process failed. See InnerException for more detail. ---> System.ApplicationException: STATUS_INTERNAL_ERROR: Unknown error in injected C++ completion routine. (Code: 14)

Server stack trace: 
   at EasyHook.NativeAPI.Force(Int32 InErrorCode)
   at EasyHook.RemoteHooking.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at EasyHook.HelperServiceInterface.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at EasyHook.HelperServiceInterface.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at EasyHook.RemoteHooking.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) in i:\code\Direct3DHook\Capture\CaptureProcess.cs:line 67
   --- End of inner exception stack trace ---
   at Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) in i:\code\Direct3DHook\Capture\CaptureProcess.cs:line 92
   at TestScreenshot.Form1.AttachProcess() in i:\code\Direct3DHook\TestScreenshot\Form1.cs:line 134
   at TestScreenshot.Form1.btnInject_Click(Object sender, EventArgs e) in i:\code\Direct3DHook\TestScreenshot\Form1.cs:line 52
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34014 built by: FX45W81RTMGDR
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll
----------------------------------------
TestScreenshot
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///I:/code/Direct3DHook/bin/TestScreenshot.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.33440 built by: FX45W81RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.33440 built by: FX45W81RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34003 built by: FX45W81RTMGDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
EasyHook
    Assembly Version: 2.7.4761.0
    Win32 Version: 2.7.4761.0
    CodeBase: file:///I:/code/Direct3DHook/bin/EasyHook.DLL
----------------------------------------
Capture
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///I:/code/Direct3DHook/bin/Capture.DLL
----------------------------------------
System.Runtime.Remoting
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34107 built by: FX45W81RTMGDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Remoting/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------
System.Configuration
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.33440 built by: FX45W81RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.33440 built by: FX45W81RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
justinstenning commented 9 years ago

Sorry for the delay - is that game 64-bit or 32-bit?

You could try the latest EasyHook release from codeplex, that has some fixes to hooking on Windows 8.1 64-bit that may help you.

KristjanLaane commented 9 years ago

the game is 32-bit.

KristjanLaane commented 9 years ago

updating EasyHook did not help: EasyHook 2.7 Beta Binaries (2.7.5558.0)

KristjanLaane commented 9 years ago

exactly same issue occurs with Borderlands 2 as well is there anything else I could try to make it work? what is common between XCom Enemy Within and Borderlands 2? they are both 32bit. but do they both rely exclusively on Direct3D v11 ? not sure, how can i check?

justinstenning commented 9 years ago

Using .net 3.5 or .net 4? From memory 3.5 works with borderlands 2 but .net 4 doesn't

KristjanLaane commented 9 years ago

Was using .NET 4 as you had set for the project in Visual Studio. But when I switched the Capture (library) project to .NET 3.5 then indeed injection to both games started to work!

However, another issue appeared now with the 3.5 build: in Sid Meier's Civilization Beyond Earth for instance, as well as in Sid Meier's Civilization V - whenever using DirectX 11 now - then the overlay does not work any more: The reason this seems to happen is because I also upgraded SharpDX to version 2.6.3 (so that I could get the non .NET 4 binaries for SharpDX) but then had to change two lines in source code in Hook/DX11/DXOverlayEngine.cs because the SetViewports overload has changed in SharpDX : https://github.com/spazzarama/Direct3DHook/blob/master/Capture/Hook/DX11/DXOverlayEngine.cs#L75 and https://github.com/spazzarama/Direct3DHook/blob/master/Capture/Hook/DX11/DXOverlayEngine.cs#L120 When I changed .SetViewports to .SetViewport (notice no s at the end), then no fps counter overlay was displayed However when i changed .SetViewports(new ViewportF to .SetViewports(new[] {new ViewportF ...} then instead of getting fps overlay I got a load of random letters appearing in about the same position, something like @ABCDEFGH.. and then another line on top of the first line @ABCDEFGH..

So using .NET 3.5 build works for Direct3D v9 (incl Borderlands 2 and XCom EW) but messes up overlay for Direct3D v11 due to having to change the version of SharpDX (to newest .NET 2.0 build).

Could you advise how to make the overlay work in 3.5 build with DirectX v11?

thanks!

P.S. I had to also comment out a Task usage though, in https://github.com/spazzarama/Direct3DHook/blob/master/Capture/EntryPoint.cs#L266 As well as copying in the .NET 3.5 build of EasyHook 2.7.5558 rather than the .NET 4 build

justinstenning commented 8 years ago

Kristjan are you able to test this still with the latest overlay code? The approach to rendering has been adjusted since this issue was raised and perhaps will make a difference for you.

KristjanLaane commented 8 years ago

retested the newest TestScreenshot with Borderlands 2 and still getting an exception and it does not attach. However, when I tried with my own project which uses your library but compiled with .NET 3.5 then all is in order and it attaches to Borderlands 2 without exceptions.

so your fix might be to use and require .NET 3.5

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
Capture.InjectionFailedException: Injection to the target process failed. See InnerException for more detail. ---> System.ApplicationException: STATUS_INTERNAL_ERROR: Unknown error in injected C++ completion routine. (Code: 15)

Server stack trace: 
   at EasyHook.NativeAPI.Force(Int32 InErrorCode)
   at EasyHook.RemoteHooking.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at EasyHook.HelperServiceInterface.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at EasyHook.HelperServiceInterface.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at EasyHook.RemoteHooking.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) in i:\code\Direct3DHookNu\Capture\CaptureProcess.cs:line 67
   --- End of inner exception stack trace ---
   at Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) in i:\code\Direct3DHookNu\Capture\CaptureProcess.cs:line 92
   at TestScreenshot.Form1.AttachProcess() in i:\code\Direct3DHookNu\TestScreenshot\Form1.cs:line 131
   at TestScreenshot.Form1.btnInject_Click(Object sender, EventArgs e) in i:\code\Direct3DHookNu\TestScreenshot\Form1.cs:line 52
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34209 built by: FX452RTMGDR
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll
----------------------------------------
TestScreenshot
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/zzz/non/idrop/ipart/code/Direct3DHookNu/bin/TestScreenshot.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34250 built by: FX452RTMGDR
    CodeBase: file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34262 built by: FX452RTMGDR
    CodeBase: file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34239 built by: FX452RTMGDR
    CodeBase: file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
Accessibility
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.33440 built by: FX45W81RTMREL
    CodeBase: file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/Accessibility/v4.0_4.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
----------------------------------------
EasyHook
    Assembly Version: 2.7.5726.0
    Win32 Version: 2.7.5726.0
    CodeBase: file:///C:/zzz/non/idrop/ipart/code/Direct3DHookNu/bin/EasyHook.DLL
----------------------------------------
Capture
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/zzz/non/idrop/ipart/code/Direct3DHookNu/bin/Capture.DLL
----------------------------------------
System.Runtime.Remoting
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34243 built by: FX452RTMGDR
    CodeBase: file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Remoting/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------
System.Configuration
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34209 built by: FX452RTMGDR
    CodeBase: file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34230 built by: FX452RTMGDR
    CodeBase: file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Web
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34274 built by: FX452RTMGDR
    CodeBase: file:///C:/windows/Microsoft.Net/assembly/GAC_64/System.Web/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Web.dll
----------------------------------------
System.Core
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34209 built by: FX452RTMGDR
    CodeBase: file:///C:/windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.
VinciShark commented 8 years ago

some problem with windows10. Is there a fix? I just start to build my toy project with this repo. THX

justinstenning commented 8 years ago

@VinciShark are you using .NET 4 or 3.5?

VinciShark commented 8 years ago

I try either. But crash

VinciShark commented 8 years ago

Capture.InjectionFailedException: Injection to the target process failed. See InnerException for more detail. ---> System.ApplicationException: STATUS_INTERNAL_ERROR: Unknown error in injected C++ completion routine. (Code: 15) 在 EasyHook.NativeAPI.Force(Int32 InErrorCode) 在 EasyHook.RemoteHooking.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs) 在 EasyHook.RemoteHooking.Inject(Int32 InTargetPID, InjectionOptions InOptions, String InLibraryPath_x86, String InLibraryPath_x64, Object[] InPassThruArgs) 在 Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) 位置 D:\Develop\Direct3DHook-master\Capture\CaptureProcess.cs:行号 67 --- 内部异常堆栈跟踪的结尾 --- 在 Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) 位置 D:\Develop\Direct3DHook-master\Capture\CaptureProcess.cs:行号 79 在 TestScreenshot.Form1.AttachProcess() 位置 D:\Develop\Direct3DHook-master\TestScreenshot\Form1.cs:行号 131 在 TestScreenshot.Form1.btnInject_Click(Object sender, EventArgs e) 位置 D:\Develop\Direct3DHook-master\TestScreenshot\Form1.cs:行号 52 在 System.Windows.Forms.Control.OnClick(EventArgs e) 在 System.Windows.Forms.Button.OnClick(EventArgs e) 在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 在 System.Windows.Forms.Control.WndProc(Message& m) 在 System.Windows.Forms.ButtonBase.WndProc(Message& m) 在 System.Windows.Forms.Button.WndProc(Message& m) 在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

VinciShark commented 8 years ago

@spazzarama When I switch to 3.5. VS tells me that task is unvaild

justinstenning commented 8 years ago

@VinciShark I believe the issue is with EasyHook - I have just implemented a workaround for an issue in the .NET Framework where an executables stack commit size cannot exceed 0x3E000 or AppDomain.CreateDomain fails. You can see the details of the issue and the release here.

justinstenning commented 8 years ago

@KristjanLaane are you able to retest using the v2.7.5870.0 version of the EasyHook binaries?

KristjanLaane commented 8 years ago

re-retested the newest TestScreenshot with Borderlands 2 and it works! no exceptions seen and the red fps counter becomes visible on the top left (:

justinstenning commented 8 years ago

@KristjanLaane thanks for testing mate. I'm going to close this off, as the two issues appear to be dealt with: 1) use .NET 3.5 or 4.0 appropriately (depending on if target uses one), and 2) a fix to revert to the current domain if AppDomain.CreateDomain fails.

@VinciShark I'm not sure if it fixes your issue, but I think either open as a new one, or over to EasyHook issue tracker.