soluciĆ³n lol legends league error descargar d3dx9_39 crear c++ directx hook dll-injection

c++ - legends - dll d3dx9_39 lol download



Enganchar DirectX EndScene desde una DLL inyectada (3)

Quiero desviar EndScene de una aplicación DirectX 9 arbitraria para crear una pequeña superposición. Como ejemplo, puede tomar la superposición de contadores de fotogramas de FRAPS, que se muestra en los juegos cuando se activa.

Conozco los siguientes métodos para hacer esto:

  1. Creando un nuevo d3d9.dll , que luego se copia a la ruta de los juegos. Como la carpeta actual se busca primero, antes de ir a system32, etc., se carga mi DLL modificada, ejecutando mi código adicional.

    Desventaja: tienes que ponerlo allí antes de comenzar el juego.

    • Igual que el primer método, pero reemplazando la DLL en system32 directamente.

    Desventaja: No puedes agregar código específico del juego. No puede excluir aplicaciones en las que no desea que se cargue su DLL.

    • Obtención del offset de EndScene directamente desde la DLL utilizando herramientas como IDA Pro 4.9 Free. Como la DLL se carga como está, puede agregar este desplazamiento a la dirección de inicio de la DLL, cuando se asigna al juego, para obtener el desplazamiento real, y luego conectarlo.

    Desventaja: el desplazamiento no es el mismo en todos los sistemas.

    • Conectar Direct3DCreate9 para obtener el D3D9, luego conectar D3D9-> CreateDevice para obtener el puntero del dispositivo, y luego conectar Dispositivo-> EndScene a través de la tabla virtual.

    Desventaja: la DLL no se puede inyectar, cuando el proceso ya se está ejecutando. CREATE_SUSPENDED iniciar el proceso con el indicador CREATE_SUSPENDED para CREATE_SUSPENDED el Direct3DCreate9 inicial.

    • Crear un nuevo dispositivo en una nueva ventana, tan pronto como la DLL se inyecta. Luego, obtener el offset de EndScene de este dispositivo y conectarlo, resultando en un gancho para el dispositivo que usa el juego.

    Desventaja: a partir de cierta información que he leído, la creación de un segundo dispositivo puede interferir con el dispositivo existente y puede tener problemas con el modo de pantalla de ventana vs. pantalla completa, etc.

    • Igual que el tercer método. Sin embargo, harás una exploración de patrones para obtener EndScene .

    Desventaja: no parece tan confiable.

¿Cómo puedo conectar EndScene desde una DLL inyectada, que puede cargarse cuando el juego ya se está ejecutando, sin tener que lidiar con diferentes d3d9.dll en otros sistemas, y con un método que sea confiable? ¿Cómo FRAPS, por ejemplo, realiza sus ganchos de DirectX? El archivo DLL no debe aplicarse a todos los juegos, solo a procesos específicos donde lo inyecto a través de CreateRemoteThread .


Sé que esta pregunta es antigua, pero esto debería funcionar para cualquier programa que use DirectX9. Básicamente, está creando su propia instancia, y luego obtiene el puntero a la tabla VT, luego simplemente lo conecta. Necesitará desvíos 3.X por cierto:

//Just some typedefs: typedef HRESULT (WINAPI* oEndScene) (LPDIRECT3DDEVICE9 D3DDevice); static oEndScene EndScene; //Do this in a function or whatever HMODULE hDLL=GetModuleHandleA("d3d9"); LPDIRECT3D9(__stdcall*pDirect3DCreate9)(UINT) = (LPDIRECT3D9(__stdcall*)(UINT))GetProcAddress( hDLL, "Direct3DCreate9"); LPDIRECT3D9 pD3D = pDirect3DCreate9(D3D_SDK_VERSION); D3DDISPLAYMODE d3ddm; HRESULT hRes = pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm ); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp)); d3dpp.Windowed = true; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = d3ddm.Format; WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,TempWndProc,0L,0L,GetModuleHandle(NULL),NULL,NULL,NULL,NULL,("1"),NULL}; RegisterClassEx(&wc); HWND hWnd = CreateWindow(("1"),NULL,WS_OVERLAPPEDWINDOW,100,100,300,300,GetDesktopWindow(),NULL,wc.hInstance,NULL); hRes = pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT, &d3dpp, &ppReturnedDeviceInterface); pD3D->Release(); DestroyWindow(hWnd); if(pD3D == NULL){ //printf ("WARNING: D3D FAILED"); return false; } pInterface = (unsigned long*)*((unsigned long*)ppReturnedDeviceInterface); EndScene = (oEndScene) (DWORD) pInterface[42]; DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)EndScene, newEndScene); DetourTransactionCommit();

Y luego su función:

HRESULT WINAPI D3D9Hook::newEndScene(LPDIRECT3DDEVICE9 pDevice) { //Do your stuff here //Call the original (if you want) return EndScene(pDevice); }


Se instala un gancho de todo el sistema. (SetWindowsHookEx) Una vez hecho esto, puedes cargarte en cada proceso.

Ahora, cuando se llama al gancho, busca un d3d9.dll cargado.

Si se carga uno, crea un objeto D3D9 temporal y recorre el vtable para obtener la dirección del método EndScene.

Luego puede parchear la llamada de EndScene, con su propio método. (Reemplace la primera instrucción en EndScene por una llamada a su método.

Cuando haya terminado, debe volver a parchear la llamada para llamar al método original de EndScene. Y luego vuelva a instalar su parche.

Así es como lo hace FRAPS. ( Link )

Puede encontrar una dirección de función desde el vtable de una interfaz.

Así que puedes hacer lo siguiente (Pseudo-Código):

IDirect3DDevice9* pTempDev = ...; const int EndSceneIndex = 26 (?); typedef HRESULT (IDirect3DDevice9::* EndSceneFunc)( void ); BYTE* pVtable = reinterpret_cast<void*>( pTempDev ); EndSceneFunc = pVtable + sizeof(void*) * EndSceneIndex;

EndSceneFunc ahora contiene un puntero a la función en sí. Ahora podemos parchear todos los sitios de llamadas o podemos parchear la función en sí.

Tenga en cuenta que todo esto depende del conocimiento de la implementación de las interfaces COM en Windows. Pero esto funciona en todas las versiones de Windows (32 o 64, no ambas al mismo tiempo).


Una pregunta un poco vieja que conozco, pero en caso de que alguien esté interesado en hacer esto con C #, aquí está mi ejemplo para conectar la API de Direct3D 9 usando C # . Esto utiliza EasyHook, un ensamblado .NET de código abierto que le permite instalar "en forma segura" ganchos desde código administrado a funciones no administradas. (Nota: EasyHook se encarga de todos los problemas relacionados con la inyección de DLL, por ejemplo, CREATE_SUSPENDED, ACL, 32 vs 64-bit, etc.)

Utilizo un enfoque de VTable similar como lo menciona Christopher a través de una pequeña DLL de C ++ helper para determinar dinámicamente la dirección de las funciones IDirect3DDevice9 para enganchar. Esto se hace creando un controlador de ventana temporal y creando un IDirect3Device9 desechable dentro del ensamblaje inyectado antes de enganchar las funciones deseadas. Esto permite que su aplicación enganche un objetivo que ya se está ejecutando (Actualización: tenga en cuenta que esto también es posible dentro de C # también - vea los comentarios en la página vinculada).

Actualización : también hay una versión actualizada para conectar Direct3D 9, 10 y 11 que siguen utilizando EasyHook y con SharpDX en lugar de SlimDX