示例#1
0
HRESULT WINAPI D3D10CreateDeviceAndSwapChainHook(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software,
    UINT Flags, UINT SDKVersion, DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, IDXGISwapChain **ppSwapChain,
    ID3D10Device **ppDevice)
{

    printf("In D3D10CreateDeviceAndSwapChainHook\n");

    //Create the device and swap chain
    HRESULT hResult = pD3D10CreateDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, SDKVersion,
        pSwapChainDesc, ppSwapChain, ppDevice);

    //Save the device and swap chain interface.
    //These aren't used in this example but are generally nice to have addresses to
    if(ppSwapChain == NULL)
    {
        printf("Swap chain is NULL.\n");
        return hResult;
    }
    else
    {
        pSwapChain = *ppSwapChain;
    }
    if(ppDevice == NULL)
    { 
        printf("Device is NULL.\n");
        return hResult;
    }
    else
    {
        pDevice = *ppDevice;
    }

    //Get the vtable address of the swap chain's Present function and modify it with our own.
    //Save it to return to later in our Present hook
    if(pSwapChain != NULL)
    {
        DWORD_PTR *SwapChainVTable = (DWORD_PTR *)pSwapChain;
        SwapChainVTable = (DWORD_PTR *)SwapChainVTable[0];
        printf("Swap chain VTable: %X\n", SwapChainVTable);
        PresentAddress = (pPresent)SwapChainVTable[8];
        printf("Present address: %X\n", PresentAddress);

        DWORD OldProtections = 0;
        VirtualProtect(&SwapChainVTable[8], sizeof(DWORD_PTR), PAGE_EXECUTE_READWRITE, &OldProtections);
        SwapChainVTable[8] = (DWORD_PTR)PresentHook;
        VirtualProtect(&SwapChainVTable[8], sizeof(DWORD_PTR), OldProtections, &OldProtections);
    }

    //Create the font that we will be drawing with
    CreateDrawingFont();

    return hResult;
}
示例#2
0
文件: d3d10.cpp 项目: fwaggle/mumble
/// Prepares DXGI and D3D10 data by trying to determining the module filepath
/// and function offsets in memory.
/// (This data can later be used for hooking / code injection.
///
/// Adjusts the data behind the global variables dxgi and d3d10.
void PrepareDXGI10(IDXGIAdapter1 *pAdapter, bool initializeDXGIData) {

	if (!dxgi || !d3d10 || !pAdapter)
		return;

	ods("D3D10: Preparing static data for DXGI and D3D10 Injection");

	d3d10->wcFileName[0] = 0;
	d3d10->iOffsetAddRef = 0;
	d3d10->iOffsetRelease = 0;

	HMODULE hD3D10 = LoadLibrary("D3D10.DLL");

	if (hD3D10 != NULL) {

		HWND hwnd = CreateWindowW(L"STATIC", L"Mumble DXGI Window", WS_OVERLAPPEDWINDOW,
								  CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0,
								  NULL, NULL, 0);

		D3D10CreateDeviceAndSwapChainType pD3D10CreateDeviceAndSwapChain = reinterpret_cast<D3D10CreateDeviceAndSwapChainType>(GetProcAddress(hD3D10, "D3D10CreateDeviceAndSwapChain"));

		DXGI_SWAP_CHAIN_DESC desc;
		ZeroMemory(&desc, sizeof(desc));

		RECT rcWnd;
		GetClientRect(hwnd, &rcWnd);
		desc.BufferDesc.Width = rcWnd.right - rcWnd.left;
		desc.BufferDesc.Height = rcWnd.bottom - rcWnd.top;

		ods("D3D10: Got ClientRect W %d H %d", desc.BufferDesc.Width, desc.BufferDesc.Height);

		desc.BufferDesc.RefreshRate.Numerator = 60;
		desc.BufferDesc.RefreshRate.Denominator = 1;
		desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
		desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
		desc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;

		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality = 0;

		desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

		desc.BufferCount = 2;

		desc.OutputWindow = hwnd;

		desc.Windowed = true;

		desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

		IDXGISwapChain *pSwapChain = NULL;
		ID3D10Device *pDevice = NULL;
		HRESULT hr = pD3D10CreateDeviceAndSwapChain(pAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &desc, &pSwapChain, &pDevice);
		if (FAILED(hr))
			ods("D3D10: pD3D10CreateDeviceAndSwapChain failure!");

		if (pDevice && pSwapChain) {

			// For VC++ the vtable is located at the base addr. of the object and each function entry is a single pointer. Since p.e. the base classes
			// of IDXGISwapChain have a total of 8 functions the 8+Xth entry points to the Xth added function in the derived interface.

			void ***vtbl = (void ***) pSwapChain;

			void *pPresent = (*vtbl)[8];
			int offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pPresent), dxgi->wcFileName, ARRAY_NUM_ELEMENTS(dxgi->wcFileName), "D3D10", "Present");
			if (offset >= 0) {
				if (initializeDXGIData) {
					dxgi->iOffsetPresent = offset;
					ods("D3D10: Successfully found Present offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetPresent);
				} else {
					if (dxgi->iOffsetPresent == offset) {
						ods("D3D10: Successfully verified Present offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetPresent);
					} else {
						ods("D3D10: Failed to verify Present offset for %ls. Found %d, but previously found %d.", dxgi->wcFileName, offset, dxgi->iOffsetPresent);
					}
				}
			}

			void *pResize = (*vtbl)[13];
			offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pResize), dxgi->wcFileName, ARRAY_NUM_ELEMENTS(dxgi->wcFileName), "D3D10", "ResizeBuffers");
			if (offset >= 0) {
				if (initializeDXGIData) {
					dxgi->iOffsetResize = offset;
					ods("D3D10: Successfully found ResizeBuffers offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetResize);
				} else {
					if (dxgi->iOffsetResize == offset) {
						ods("D3D10: Successfully verified ResizeBuffers offset: %ls: %d", dxgi->wcFileName, dxgi->iOffsetResize);
					} else {
						ods("D3D10: Failed to verify ResizeBuffers offset for %ls. Found %d, but previously found %d.", dxgi->wcFileName, offset, dxgi->iOffsetResize);
					}
				}
			}

			vtbl = (void ***) pDevice;

			void *pAddRef = (*vtbl)[1];
			offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pAddRef), d3d10->wcFileName, ARRAY_NUM_ELEMENTS(d3d10->wcFileName), "D3D10", "AddRef");
			if (offset >= 0) {
				d3d10->iOffsetAddRef = offset;
				ods("D3D10: Successfully found AddRef offset: %ls: %d", d3d10->wcFileName, d3d10->iOffsetAddRef);
			}

			void *pRelease = (*vtbl)[2];
			offset = GetFnOffsetInModule(reinterpret_cast<voidFunc>(pRelease), d3d10->wcFileName, ARRAY_NUM_ELEMENTS(d3d10->wcFileName), "D3D10", "Release");
			if (offset >= 0) {
				d3d10->iOffsetRelease = offset;
				ods("D3D10: Successfully found Release offset: %ls: %d", d3d10->wcFileName, d3d10->iOffsetRelease);
			}
		}

		if (pDevice)
			pDevice->Release();
		if (pSwapChain)
			pSwapChain->Release();
		DestroyWindow(hwnd);
	} else {
		FreeLibrary(hD3D10);
	}
}
示例#3
0
extern "C" __declspec(dllexport) void __cdecl PrepareDXGI() {
	// This function is called by the Mumble client in Mumble's scope
	// mainly to extract the offsets of various functions in the IDXGISwapChain
	// and IDXGIObject interfaces that need to be hooked in target
	// applications. The data is stored in the dxgi shared memory structure.

	if (! dxgi)
		return;

	ods("Preparing static data for DXGI Injection");

	dxgi->wcDXGIFileName[0] = 0;
	dxgi->wcD3D10FileName[0] = 0;
	dxgi->iOffsetPresent = 0;
	dxgi->iOffsetResize = 0;
	dxgi->iOffsetAddRef = 0;
	dxgi->iOffsetRelease = 0;

	OSVERSIONINFOEXW ovi;
	memset(&ovi, 0, sizeof(ovi));
	ovi.dwOSVersionInfoSize = sizeof(ovi);
	GetVersionExW(reinterpret_cast<OSVERSIONINFOW *>(&ovi));
	if ((ovi.dwMajorVersion >= 7) || ((ovi.dwMajorVersion == 6) && (ovi.dwBuildNumber >= 6001))) { // Make sure this is vista or greater as quite a number of <=WinXP users have fake DX10 libs installed
		HMODULE hD3D10 = LoadLibrary("D3D10.DLL");
		HMODULE hDXGI = LoadLibrary("DXGI.DLL");

		if (hDXGI != NULL && hD3D10 != NULL) {
			CreateDXGIFactoryType pCreateDXGIFactory = reinterpret_cast<CreateDXGIFactoryType>(GetProcAddress(hDXGI, "CreateDXGIFactory"));
			ods("Got %p", pCreateDXGIFactory);
			if (pCreateDXGIFactory) {
				HRESULT hr;
				IDXGIFactory * pFactory;
				hr = pCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory));
				if (pFactory) {
					HWND hwnd = CreateWindowW(L"STATIC", L"Mumble DXGI Window", WS_OVERLAPPEDWINDOW,
					                          CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0,
					                          NULL, NULL, 0);

					IDXGIAdapter *pAdapter = NULL;
					pFactory->EnumAdapters(0, &pAdapter);

					D3D10CreateDeviceAndSwapChainType pD3D10CreateDeviceAndSwapChain = reinterpret_cast<D3D10CreateDeviceAndSwapChainType>(GetProcAddress(hD3D10, "D3D10CreateDeviceAndSwapChain"));

					IDXGISwapChain *pSwapChain = NULL;
					ID3D10Device *pDevice = NULL;

					DXGI_SWAP_CHAIN_DESC desc;
					ZeroMemory(&desc, sizeof(desc));

					RECT rcWnd;
					GetClientRect(hwnd, &rcWnd);
					desc.BufferDesc.Width = rcWnd.right - rcWnd.left;
					desc.BufferDesc.Height = rcWnd.bottom - rcWnd.top;

					ods("W %d H %d", desc.BufferDesc.Width, desc.BufferDesc.Height);

					desc.BufferDesc.RefreshRate.Numerator = 60;
					desc.BufferDesc.RefreshRate.Denominator = 1;
					desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
					desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
					desc.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;

					desc.SampleDesc.Count = 1;
					desc.SampleDesc.Quality = 0;

					desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

					desc.BufferCount = 2;

					desc.OutputWindow = hwnd;

					desc.Windowed = true;

					desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

					hr = pD3D10CreateDeviceAndSwapChain(pAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &desc, &pSwapChain, &pDevice);

					if (pDevice && pSwapChain) {
						HMODULE hRef;
						// For VC++ the vtable is located at the base addr. of the object and each function entry is a single pointer. Since p.e. the base classes
						// of IDXGISwapChain have a total of 8 functions the 8+Xth entry points to the Xth added function in the derived interface.
						void ***vtbl = (void ***) pSwapChain;
						void *pPresent = (*vtbl)[8];
						if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pPresent, &hRef)) {
							ods("DXGI: Failed to get module for Present");
						} else {
							GetModuleFileNameW(hRef, dxgi->wcDXGIFileName, 2048);
							unsigned char *b = (unsigned char *) pPresent;
							unsigned char *a = (unsigned char *) hRef;
							dxgi->iOffsetPresent = b-a;
							ods("DXGI: Successfully found Present offset: %ls: %d", dxgi->wcDXGIFileName, dxgi->iOffsetPresent);
						}

						void *pResize = (*vtbl)[13];
						if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pResize, &hRef)) {
							ods("DXGI: Failed to get module for ResizeBuffers");
						} else {
							wchar_t buff[2048];
							GetModuleFileNameW(hRef, buff, 2048);
							if (wcscmp(buff, dxgi->wcDXGIFileName) == 0) {
								unsigned char *b = (unsigned char *) pResize;
								unsigned char *a = (unsigned char *) hRef;
								dxgi->iOffsetResize = b-a;
								ods("DXGI: Successfully found ResizeBuffers offset: %ls: %d", dxgi->wcDXGIFileName, dxgi->iOffsetResize);
							}
						}

						vtbl = (void ***) pDevice;

						void *pAddRef = (*vtbl)[1];
						if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pAddRef, &hRef)) {
							ods("D3D10: Failed to get module for AddRef");
						} else {
							GetModuleFileNameW(hRef, dxgi->wcD3D10FileName, 2048);
							unsigned char *b = (unsigned char *) pAddRef;
							unsigned char *a = (unsigned char *) hRef;
							dxgi->iOffsetAddRef = b-a;
							ods("D3D10: Successfully found AddRef offset: %ls: %d", dxgi->wcD3D10FileName, dxgi->iOffsetAddRef);
						}

						void *pRelease = (*vtbl)[2];
						if (! GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (char *) pRelease, &hRef)) {
							ods("D3D10: Failed to get module for Release");
						} else {
							wchar_t buff[2048];
							GetModuleFileNameW(hRef, buff, 2048);
							if (wcscmp(buff, dxgi->wcD3D10FileName) == 0) {
								unsigned char *b = (unsigned char *) pRelease;
								unsigned char *a = (unsigned char *) hRef;
								dxgi->iOffsetRelease = b-a;
								ods("D3D10: Successfully found Release offset: %ls: %d", dxgi->wcD3D10FileName, dxgi->iOffsetRelease);
							}
						}
					}

					if (pDevice)
						pDevice->Release();
					if (pSwapChain)
						pSwapChain->Release();
					DestroyWindow(hwnd);

					pFactory->Release();
				}
			}
		}
	} else {
		ods("No DXGI pre-Vista");
	}
}