Results 1 to 2 of 2
  1. #1
    Sergeant Major
    Reputation
    76
    Join Date
    May 2009
    Posts
    167
    CoreCoins
    0

    Trade Feedbacks

    Status
    n/a
    Positive
    0 (0%)
    Negative
    0 (0%)

    Using XNA to draw in WoW



    Donate to Remove Ads, Get ShoutBawx - Elite Forum Access
    I got this working a while ago but have only just recently got round to cleaning* up the code to release it. (* code still isn't really that clean)

    I've written a proof-of-concept library (which you can get over at github: https://github.com/adaephon/InjectedXna/) that allows you to use XNA to draw inside WoW. It's a fairly hackish solution, but it works (relatively well at this stage, hasn't been thoroughly tested).

    The basic premise is as follows:
    • Start process suspended
    • Inject .NET Bootstrapper / .NET DLL
    • Hook Direct3D Device creation
    • Intercept device creation, and create XNA GraphicsDevice
    • Intercept XNA device creation, do some magic with the presentation paremeters
    • Extract native pointer from XNA GraphicsDevice, detour EndScene (etc)
    • Resume process, start XNA 'InjectedGame' which uses the GraphicsDevice created on startup



    The GraphicsDevice creation looks like this:
    Code:
    private static uint IDirect3D9CreateDeviceHandler(IntPtr thisPtr, uint adapter, uint deviceType, IntPtr hFocusWindow, uint behaviorFlags, IntPtr pPresentationParameters, [Out] IntPtr ppReturnedDeviceInterface)
    {
    	uint ret;
    	if (!_isXnaCreateDeviceCall)
    	{
    		try
    		{
    			var nativePresentationParameters = 
    				(NativePresentationParameters)Marshal.PtrToStructure(pPresentationParameters, typeof(NativePresentationParameters));
    			var presentationParameters = nativePresentationParameters.ToXnaPresentationParameters(hFocusWindow);
    
    			_preservedBehaviorFlags = behaviorFlags;
    			_isXnaCreateDeviceCall = true;
    
    			_xnaGraphicsDevice = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.Reach,
    													presentationParameters);
    
    			var pComPtrField = _xnaGraphicsDevice.GetType().GetField("pComPtr", BindingFlags.NonPublic | BindingFlags.Instance);
    			if (pComPtrField == null)
    				throw new Exception("Unable to get pComPtr field from XNA Graphics Device");
    
    			unsafe
    			{
    				var pComPtr = new IntPtr(Pointer.Unbox(pComPtrField.GetValue(_xnaGraphicsDevice)));
    				Marshal.WriteIntPtr(ppReturnedDeviceInterface, pComPtr);
    
    				_endSceneDetour = pComPtr.VTable(IDirect3DDevice9VTable.EndScene)
    					.DetourWith(EndSceneFunc);
    
    				_resetDetour = pComPtr.VTable(IDirect3DDevice9VTable.Reset)
    					.DetourWith(ResetFunc);
    			}
    			// TODO
    			OnCreateDevice();
    			ret = 0;
    		}
    		catch (Exception)
    		{
    			// If we get an exception trying to create the XNA device, just call the original method and pass out the return
    			ret = (uint)_createDeviceDetour.CallOriginal(
    				thisPtr, adapter, deviceType, hFocusWindow, 
    				behaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
    		}
    	}
    	else
    	{
    		// Now we're inside the XNA Device's call to CreateDevice - get our cached presentation parameters and add a required flag
    		// TODO: check this process / flag
    		var pp = (NativePresentationParameters)Marshal.PtrToStructure(pPresentationParameters, typeof(NativePresentationParameters));
    		pp.Flags |= 0x1;
    		Marshal.StructureToPtr(pp, pPresentationParameters, true);
    
    		ret = (uint) _createDeviceDetour.CallOriginal(
    			thisPtr, adapter, deviceType, hFocusWindow,
    			_preservedBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
    	}
    	return ret;
    }
    The example uses Extemory (https://github.com/jeffora/extemory) for DLL injection, memory editing, detouring etc, but there's no reason it couldn't be implemented using your injector of choice / mem editing library of choice. As part of the POC, I've modified one of the basic Microsoft samples (Primitives3D) to work using InjectedXna. As you can see from the code, I didn't have to modify much, and using conditional compilation you can still run it as a standalone XNA game. Interestingly, the HandleInput routine worked without needing to be touched, meaning you can click on the screen and change the shape / colour / turn wireframe on or off, as per the standard sample.

    There are still a few bugs, and the code is far from perfect. For instance, after exiting WoW, the process doesn't close properly (you have to End Process from task manager). I think this is a problem with my bootstrapper / injector (Extemory). It also has one C++/CLI class to expose the IDirect3D9StateBlock which is a bit of a pain. There are alternatives to do it all in .NET (like SharpDx), but by the time you pull something like that in, you have to wonder why you're still using XNA. The XNA GameTime class also has internal setters, so at the moment I'm setting the time values by reflection, which is obviously a lot slower than native property setting, but at this stage doesn't seem to be an issue.

    As I said, it's mainly a buggy POC, but interested to hear any thoughts / feedback.

  2. #2
    #define true false Jadd's Avatar
    Reputation
    880
    Join Date
    May 2008
    Location
    ntoskrnl.exe
    Posts
    1,810
    CoreCoins
    120

    Trade Feedbacks

    Status
    n/a
    Positive
    0 (0%)
    Negative
    0 (0%)
    Awesome dude, awesome. +Rep +Rep +Rep +Rep +Rep!
    If Java had true garbage collection, most programs would delete themselves upon execution. Robert Sewell

 

 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
All times are GMT -4. The time now is 09:09 AM. Powered by vBulletin® Version 4.2.0
Copyright © 2014 vBulletin Solutions, Inc. All rights reserved.
Content Relevant URLs by vBSEO Resources saved on this page: MySQL 21.43%
vBulletin Optimisation provided by vB Optimise (Pro) - vBulletin Mods & Addons Copyright © 2014 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233