Перейти к содержанию

Указатель на D3DDevice


Рекомендуемые сообщения

Всем привет, в уроке [gamehacking] D3D9 hook - Часть 2 в функции : GetDevice9Method есть строка 
DWORD* vtablePtr = (DWORD*)(*((DWORD*)d3dDevicee)); которая в одних примерах работает, а в других крашит процесс, подскажите, что делать, что бы не крашило

Ссылка на комментарий
Поделиться на другие сайты

В 20.09.2016в18:24, keng сказал:

Во-первых, отладчик - в помощь

Судя по нику вы создатель этих уроков, я поклонник вашего творчества, желаю успехов в дальнейшем творчестве =) 
А  теперь по делу, у вас есть видео где вы курочете d3d приложение, я пробовал с ollydbg 1.1 и 2.01, но код(asm) у меня в отладчике сильно отличается от вашего и из-за этого я не смог разобраться в основах. Кроме кода у вас еще функции все выделены, а у меня нет. Может это плагины или еще что то я к сожалению не знаю. Вот код:
 

Скрытый текст

void CopyVMT9(DWORD* vtableFrag)
{
	HWND hWnd = CreateWindowA("STATIC", "dummy", 0, 0, 0, 0, 0, 0, 0, 0, 0);
	HMODULE hD3D9 = GetModuleHandleA("d3d9");
	DIRECT3DCREATE9 Direct3DCreate9 = (DIRECT3DCREATE9)GetProcAddress(hD3D9, "Direct3DCreate9"); // это можно но закоментить и подключить библиотеку d3d9.lib
	IDirect3D9* d3d = Direct3DCreate9(D3D_SDK_VERSION);
	D3DDISPLAYMODE d3ddm;
	d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = 1;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	IDirect3DDevice9* d3dDevicee = 0;
	d3d->CreateDevice(0, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3dDevicee);
	DWORD* vtablePtr = (DWORD*)(*((DWORD*)d3dDevicee));// в этом месте крашит программу после инжекта
	printf("gfg\n");
	for (int i = 0; i < 4; i++)
	{
		vtableFrag[i] = vtablePtr[i + 6];
		
	}
	d3dDevicee->Release();
	d3d->Release();
	DestroyWindow(hWnd);
}

 

Я тестил не на игре, а на простом приложении, если надо могу проект скинуть или exe написано на VS13, может кода хватить:
 

Скрытый текст

#include <Windows.h>
#include <d3d9.h>

#pragma comment(lib, "d3d9.lib")

LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;

bool globalRunning = true;

void CleanD3D()
{
	d3ddev->Release();
	d3d->Release();
}

void RenderFrame()
{
	d3ddev->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
	d3ddev->BeginScene();
	d3ddev->EndScene();
	d3ddev->Present(0, 0, 0, 0);
}

void InitD3D(HWND window)
{
	d3d = Direct3DCreate9(D3D_SDK_VERSION);
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = 1;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.hDeviceWindow = window;
	d3d->CreateDevice(0, D3DDEVTYPE_HAL, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
}

LRESULT CALLBACK Win32MainWindowCallbak(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_DESTROY:
	{
		PostQuitMessage(0);
		return 0;
	}
	}
	return DefWindowProc(window, message, wParam, lParam);;
}

int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASS windowClass = {};

	windowClass.style = CS_VREDRAW | CS_HREDRAW;
	windowClass.lpfnWndProc = Win32MainWindowCallbak;
	windowClass.lpszClassName = "test";
	windowClass.hInstance = instance;

	RegisterClass(&windowClass);

	HWND window = CreateWindowEx(0, windowClass.lpszClassName, "test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
		CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, instance, 0);

	MSG message;

	InitD3D(window);
	while (true)
	{
		while (PeekMessage(&message, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&message);
			DispatchMessage(&message);
		}
		if (message.message == WM_QUIT)
			break;
		RenderFrame();
	}

	CleanD3D();


	return 0;
}

 

 

Ссылка на комментарий
Поделиться на другие сайты

Спасибо за отзыв, я выкладываю что-нибудь время от времени и по мере сил. :)

 

Посмотрел код, все вроде бы неплохо. Возможно, что или не создается hwnd окна для создания объекта d3d, или же сам d3d-объект. Нужно смотреть, больше пока ничего не могу сказать. Если можешь - поделись тестовым приложением, я соберу твой код у себя и попробую отладить. Да, отладчиком я пользовался скорее всего v2.01, без плагинов вообще.

 

PS: Простыни исходного кода лучше убирать под тег "спойлер".

Ссылка на комментарий
Поделиться на другие сайты

41 минуты назад, keng сказал:

PS: Простыни исходного кода лучше убирать под тег "спойлер".

Я искал не нашел спойлер, похоже это скрытый текст

Вот проект, и exe: http://rgho.st/8Cs76zJNp

А вот как код в отладчике выглядит у вас и у меня:

Скрытый текст

6IaPnQju48gFkSmj0HFsgCu56kCkXh XtL5CQwF6hUUwFSZ2YZFFFCSthYlYW

Изображения не работают, попробую так:

https://monosnap.com/file/6IaPnQju48gFkSmj0HFsgCu56kCkXh

https://monosnap.com/file/XtL5CQwF6hUUwFSZ2YZFFFCSthYlYW

У вас функции подсвечиваются и вызов этих функций понятный call address. Естественно не везде такой вызов, но в туториале именно такой. А у меня в отладчике мало чего понятного + в asm я новичок(

Изменено пользователем helldrg
Ссылка на комментарий
Поделиться на другие сайты

крашить в том месте может только в случае IsBadReadPtr(d3dDevicee,4) == true, от сюда вывод, что CreateDevice у тебя отрабатывает коряво.

И вообще где все проверки? а то у тебя код как-то линейно выполняется, будь что будет ..

 

суть этого цикла вообще не понял

	for (int i = 0; i < 4; i++)
	{
		vtableFrag[i] = vtablePtr[i + 6];
		
	}
Изменено пользователем Dino
Ссылка на комментарий
Поделиться на другие сайты

54 минуты назад, helldrg сказал:

Я искал не нашел спойлер, похоже это скрытый текст

Вот проект, и exe: http://rgho.st/8Cs76zJNp

с D3D тестом у тебя все ОК . Думаю, проблема именно в хуке.

 

Изменено пользователем Dino
Ссылка на комментарий
Поделиться на другие сайты

Так, ок. У меня Win10 x64 и мой же код работает некорректно. Хук отрабатывает, но что-то не так с перехваченной функцией, которой я подменяю оригинальную Present(). Моя рушит стек при вызове. Буду разбираться, но это займет какое-то время.

Ссылка на комментарий
Поделиться на другие сайты

Это все kenga хук, http://kekekeng.blogspot.ru/2012/10/direct3d-1.html, я так понимаю это создаем сигнатуру по которой будем искать нужный указатель. Проверок нету я так понял для уменьшения размера кода

Ссылка на комментарий
Поделиться на другие сайты

Скрытый текст

#include <Windows.h>
#include "Include\d3d9.h"
#include "Include\d3dx9.h"
#include <io.h>
#include <stdio.h>

#pragma comment(lib, "d3d9.lib")

typedef IDirect3D9* (STDMETHODCALLTYPE *DIRECT3DCREATE9)(UINT);
typedef HRESULT(WINAPI* tPresent)(LPDIRECT3DDEVICE9 pDevice, CONST RECT*, CONST RECT*, HWND, LPVOID);
typedef HRESULT(WINAPI* tReset)(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters);
typedef DWORD(STDMETHODCALLTYPE *GETPROCESSHEAPS)(DWORD, PHANDLE);

static DWORD vtableFrag9[] = { 0, 0, 0, 0 };
static DWORD* presentPtr = 0;
static DWORD* resetPtr = 0;
static DWORD offsetPresent = 0;
static DWORD offsetReset = 0;
static tPresent g_D3D9_Present = 0;
static tReset g_D3D9_Reset = 0;
LPDIRECT3DDEVICE9 npDevice;

bool indicator = 0;

//DWORD*vtbl = 0;
//DWORD table;
//
//BOOL bCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
//{
//	for (; *szMask; ++szMask, ++pData, ++bMask)
//		if (*szMask == 'x' && *pData != *bMask)
//			return false;
//	return (*szMask) == NULL;
//}
//DWORD FindPattern(DWORD dwAddress, DWORD dwLen, BYTE *bMask, char * szMask)
//{
//	for (DWORD i = 0; i < dwLen; i++)
//		if (bCompare((BYTE*)(dwAddress + i), bMask, szMask))
//			return (DWORD)(dwAddress + i);
//
//	return 0;
//}

void CreateConsole()
{
	int hConHandle = 0;
	HANDLE lStdHandle = 0;
	FILE *fp;
	AllocConsole();
	SetConsoleTitle("Generals console!");
	lStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	hConHandle = _open_osfhandle(PtrToUlong(lStdHandle), 0);
	fp = _fdopen(hConHandle, "w");
	*stdout = *fp;
	setvbuf(stdout, NULL, _IONBF, 0);
}


void DrawIndicator(LPVOID self)
{
	IDirect3DDevice9* dev = (IDirect3DDevice9*)self;
	dev->BeginScene();
	D3DRECT rec = { 10, 10, 30, 30 };
	D3DCOLOR color = 0;
	if (indicator)
	{
		color = D3DCOLOR_XRGB(0, 255, 0);
	}
	else
	{
		color = D3DCOLOR_XRGB(255, 0, 0);
	}
	dev->Clear(1, &rec, D3DCLEAR_TARGET, color, 1.0f, 0);
	dev->EndScene();
}

HRESULT WINAPI hkPresent(LPDIRECT3DDEVICE9 pDevice, CONST RECT* src, CONST RECT* dest, HWND hWnd, LPVOID unused)
{
	while (!npDevice)
	{
		npDevice = pDevice;
	}
	DrawIndicator(pDevice);
	return g_D3D9_Present(pDevice, src, dest, hWnd, unused);
}

HRESULT WINAPI hkReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
{
	return g_D3D9_Reset(pDevice, pPresentationParameters);
}

BOOL SearchHeap(HANDLE heap)
{
	int vtableLenBytes = sizeof(DWORD) * 4;
	PROCESS_HEAP_ENTRY mem;
	mem.lpData = 0;
	while (HeapWalk(heap, &mem))
	{
		if (mem.wFlags == PROCESS_HEAP_UNCOMMITTED_RANGE) continue;
		DWORD* p = (DWORD*)mem.lpData;
		for (int i = 0; i < (int)(mem.cbData / sizeof(DWORD)); i++)
		{
			if (memcmp(p, vtableFrag9, vtableLenBytes) == 0)
			{
				presentPtr = p + 11;
				resetPtr = p + 10;
				offsetPresent = *presentPtr;
				offsetReset = *resetPtr;
				g_D3D9_Present = (tPresent)((DWORD*)offsetPresent);
				g_D3D9_Reset = (tReset)((DWORD*)offsetReset);
				break;
			}
			p++;
		}
		if (presentPtr != 0) break;
	}
	return(presentPtr != 0);
}

void CheckAndHookPresent9()
{
	if (presentPtr != 0 && (*presentPtr) == (DWORD)hkPresent) return;
	HANDLE heap = 0;
	HMODULE hKern = GetModuleHandleA("kernel32.dll");
	GETPROCESSHEAPS getProcessHeaps = (GETPROCESSHEAPS)GetProcAddress(hKern, "GetProcessHeaps");
	if (getProcessHeaps != 0)
	{
		HANDLE heaps[1000];
		int numHeaps = (getProcessHeaps)(1000, heaps);
		for (int k = 0; k < numHeaps; k++)
		{
			heap = heaps[k];
			if (SearchHeap(heap)) break;
		}
	}
	else
	{
		heap = GetProcessHeap();
		SearchHeap(heap);
	}
	HeapLock(heap);
	if (presentPtr != 0)
	{
		(*presentPtr) = (DWORD)hkPresent;
	}
	if (resetPtr != 0)
	{
		(*resetPtr) = (DWORD)hkReset;
	}
	HeapUnlock(heap);
}

void CopyVMT9(DWORD* vtableFrag)
{
	HWND hWnd = CreateWindowA("STATIC", "dummy", 0, 0, 0, 0, 0, 0, 0, 0, 0);
	HMODULE hD3D9 = GetModuleHandleA("d3d9");
	//DIRECT3DCREATE9 Direct3DCreate9 = (DIRECT3DCREATE9)GetProcAddress(hD3D9, "Direct3DCreate9"); lib add
	IDirect3D9* d3d = Direct3DCreate9(D3D_SDK_VERSION);
	D3DDISPLAYMODE d3ddm;
	d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = 1;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	IDirect3DDevice9* d3dDevicee = 0;
	d3d->CreateDevice(0, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3dDevicee);

	DWORD* vtablePtr = (DWORD*)(*((DWORD*)d3dDevicee));
	for (int i = 0; i < 4; i++)
	{
		vtableFrag[i] = vtablePtr[i + 6]; //6ad21c70  6acdb5a0  6adaf540  6ad20760
		
	}
	d3dDevicee->Release();
	d3d->Release();
	DestroyWindow(hWnd);
}

PBYTE HookVTableFunction(PDWORD* dwVTable, PBYTE dwHook, INT Index)
{
	DWORD dwOld = 0;
	VirtualProtect((void*)((*dwVTable) + (Index * 4)), 4, PAGE_EXECUTE_READWRITE, &dwOld);

	PBYTE pOrig = ((PBYTE)(*dwVTable)[Index]);
	(*dwVTable)[Index] = (DWORD)dwHook;

	VirtualProtect((void*)((*dwVTable) + (Index * 4)), 4, dwOld, &dwOld);
	return pOrig;
}

bool hooked = 0;
DWORD WINAPI TF(LPVOID lpParam)
{
	CopyVMT9(vtableFrag9);
	CheckAndHookPresent9();
	//DWORD hhD3D9 = (DWORD)LoadLibraryA("d3d9.dll");
	//table = FindPattern(hhD3D9, 0x128000, (PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86", "xx????xx????xx");
	//memcpy(&vtbl, (void*)(table + 2), 4);
	//

	while (!npDevice && !hooked)
	{
		Sleep(50);
	}
	hooked = !hooked;
	
	printf("npDevice: %x, g_D3D9_Present: %x, g_D3D9_Reset: %x\n",(DWORD*)npDevice, g_D3D9_Present, g_D3D9_Reset);
	//printf("npDevice: %x, g_D3D9_Present: %x, g_D3D9_Reset: %x\n", (DWORD*)table, vtbl[17], vtbl[16]);
	while (1)
	{
		Sleep(1000);
		//printf("npDevice: %x, g_D3D9_Present: %x, g_D3D9_Reset: %x\n", (DWORD*)npDevice, g_D3D9_Present, g_D3D9_Reset);
		HookVTableFunction((PDWORD*)npDevice, (PBYTE)hkReset, 16);
		HookVTableFunction((PDWORD*)npDevice, (PBYTE)hkPresent, 17);
	}
	return 0;
}

DWORD WINAPI KeyboardHook(LPVOID lpParam)
{
	while (1)
	{
		if (GetAsyncKeyState(VK_F1))
		{
			indicator = !indicator;
			Beep(500, 200);
		}
		Sleep(100);
	}
	return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	{
		CreateConsole();
		CreateThread(0, 0, &TF, 0, 0, 0);
		CreateThread(0, 0, &KeyboardHook, 0, 0, 0);
	}
	case DLL_PROCESS_DETACH:
		break;
	}
	return 1;
}

 

Вот так код у меня выглядит

Ссылка на комментарий
Поделиться на другие сайты

6 часов назад, keng сказал:

Так, ок. У меня Win10 x64 и мой же код работает некорректно. Хук отрабатывает, но что-то не так с перехваченной функцией, которой я подменяю оригинальную Present(). Моя рушит стек при вызове. Буду разбираться, но это займет какое-то время.

Если бы еще видео сделали бы по фиксу или лучше стрим какой нибудь было бы шикарно =)

Ссылка на комментарий
Поделиться на другие сайты

Скрытый текст

 


#include <Windows.h>
#include "SDK/Include/d3d9.h"
#include "SDK/Include/d3dx9.h"
#include "SDK/Include/d3dx9core.h"
#include "SDK/Include/xnamath.h"
#pragma comment(lib, "SDK/Lib/d3d9.lib") 
#pragma comment(lib, "SDK/Lib/d3dx9.lib")

DWORD WINAPI InitThread(LPVOID);
BOOL __cdecl GetDevice9Methods(DWORD CountRetMethods, ...);
void* DetourCreate(BYTE *src, const BYTE *dst, const int len);
HRESULT WINAPI HookedPresent(LPDIRECT3DDEVICE9 pDevice, THIS_ CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion);
HRESULT WINAPI HookedReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS *params);
LRESULT WINAPI HookedDispatchMessage(_In_ const MSG *lpmsg);

typedef LRESULT(WINAPI* tDispatchMessage)(_In_ const MSG *lpmsg);
typedef HRESULT(WINAPI* tPresent)(LPDIRECT3DDEVICE9 pDevice, THIS_ CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion);
typedef HRESULT(WINAPI *tReset)(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS *a);
typedef HRESULT(WINAPI*D3D9CREATEEXPROC)(UINT, IDirect3D9Ex**);

tDispatchMessage _tDispatchMessage = nullptr, _mDispatchMessage = nullptr;
tPresent _tPresent = nullptr, _mPresent = nullptr;
tReset _tReset = nullptr, _mReset = nullptr;
int indicator = 1;

BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{

	if (dwReason == DLL_PROCESS_ATTACH)
	{
		CreateThread(0, 0, InitThread, 0, 0, 0);
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{

	}
	return TRUE;
}

DWORD WINAPI InitThread(LPVOID)
{
	GetDevice9Methods(2, &_mPresent, &_mReset, 17, 16);
	_mDispatchMessage = (tDispatchMessage)GetProcAddress(GetModuleHandleA("USER32.dll"), "DispatchMessageW");
	if (_mPresent && _mReset && _mDispatchMessage)
	{
		_tPresent = (tPresent)DetourCreate((PBYTE)_mPresent, (PBYTE)HookedPresent, 5);
		_tReset = (tReset)DetourCreate((PBYTE)_mReset, (PBYTE)HookedReset, 5);
		_tDispatchMessage = (tDispatchMessage)DetourCreate((PBYTE)_mDispatchMessage, (PBYTE)HookedDispatchMessage, 5);
	}

	return 1;
}

void* DetourCreate(BYTE *src, const BYTE *dst, const int len)
{
	BYTE *jmp;
	DWORD dwback, dwold;
	DWORD jumpto, newjump;
	VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &dwback);
	if (src[0] == 0xE9)
	{
		jmp = (PBYTE)malloc(10);
		VirtualProtect(jmp, 10, PAGE_EXECUTE_READWRITE, &dwold);
		jumpto = (*(DWORD*)(src + 1)) + ((DWORD)src) + 5;
		newjump = (jumpto - (DWORD)(jmp + 5));
		jmp[0] = 0xE9;
		*(DWORD*)(jmp + 1) = newjump;
		jmp += 5;
		jmp[0] = 0xE9;
		*(DWORD*)(jmp + 1) = (DWORD)(src - jmp);
	}
	else
	{
		jmp = (PBYTE)malloc(5 + len);
		VirtualProtect(jmp, 5 + len, PAGE_EXECUTE_READWRITE, &dwold);
		memcpy(jmp, src, len);
		jmp += len;
		jmp[0] = 0xE9;
		*(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5;
	}
	src[0] = 0xE9;
	*(DWORD*)(src + 1) = (DWORD)(dst - src) - 5;
	for (int i = 5; i < len; i++)
		src[i] = 0x90;
	VirtualProtect(src, len, dwback, &dwback);
	return (jmp - len);
}

BOOL __cdecl GetDevice9Methods(DWORD CountRetMethods, ...)
{
	BOOL result = FALSE;
	va_list   va_alist;
	DWORD arg = 0;
	PDWORD* Methods = nullptr;
	PDWORD Index = nullptr;
	Methods = new PDWORD[CountRetMethods];
	Index = new DWORD[CountRetMethods];
	va_start(va_alist, CountRetMethods);
	for (int i = 0; i < CountRetMethods * 2; i++)
	{
		arg = va_arg(va_alist, DWORD);
		if (i < CountRetMethods)
		{
			if (IsBadReadPtr((LPVOID)arg, 4))
			{
				delete[] Index;
				delete[] Methods;
				return result;
			}
			Methods[i] = (PDWORD)arg;
		}
		else
		{
			Index[i - CountRetMethods] = arg;
		}
	}
	va_end(va_alist);

	HMODULE hD3D9Dll = GetModuleHandleA("d3d9.dll");
	if (hD3D9Dll)
	{
		D3D9CREATEEXPROC d3d9CreateEx = (D3D9CREATEEXPROC)GetProcAddress(hD3D9Dll, "Direct3DCreate9Ex");
		if (d3d9CreateEx)
		{
			LPDIRECT3D9EX d3d9ex = nullptr;
			if (SUCCEEDED(d3d9CreateEx(D3D_SDK_VERSION, &d3d9ex)))
			{
				D3DPRESENT_PARAMETERS pp;
				ZeroMemory(&pp, sizeof(pp));
				pp.Windowed = 1;
				pp.SwapEffect = D3DSWAPEFFECT_FLIP;
				pp.BackBufferFormat = D3DFMT_A8R8G8B8;
				pp.BackBufferCount = 1;
				pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
				IDirect3DDevice9Ex *deviceEx = nullptr;
				if (SUCCEEDED(d3d9ex->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, GetForegroundWindow(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, NULL, &deviceEx)))
				{
					d3d9ex->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, NULL, &deviceEx);
					if (deviceEx)
					{
						for (int i = 0; i < CountRetMethods; i++)
							*Methods[i] = *((DWORD*)(*(DWORD*)deviceEx) + Index[i]);
						deviceEx->Release();
						result = TRUE;
					}
				}
				d3d9ex->Release();
			}
		}
	}
	delete[] Methods;
	delete[] Index;
	return result;
}

HRESULT WINAPI HookedPresent(LPDIRECT3DDEVICE9 pDevice, THIS_ CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
{
	pDevice->BeginScene();
	//    ТУТ РИСУЕМ!
	D3DRECT rec = { 10, 10, 30, 30 };
	D3DCOLOR color = 0;
	if (indicator)
	{
		color = D3DCOLOR_XRGB(0, 255, 0);
	}
	else
	{
		color = D3DCOLOR_XRGB(255, 0, 0);
	}
	pDevice->Clear(1, &rec, D3DCLEAR_TARGET, color, 1.0f, 0);

	pDevice->EndScene();
	return  _tPresent(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
}

HRESULT WINAPI HookedReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS *params)
{
	return _tReset(pDevice, params);
}

LRESULT WINAPI HookedDispatchMessage(_In_ const MSG *lpmsg)
{
	switch (lpmsg->message)
	{
	case WM_KEYDOWN:
		if (lpmsg->wParam == VK_F1)
		{
			indicator = !indicator;
			Beep(500, 500);
			return 0;
		}

		break;
	case WM_LBUTTONDOWN:
		if (lpmsg->wParam == VK_F1)
			return 0;
		break;
	case WM_LBUTTONUP:
		break;

	default:
		break;
	}
	return _tDispatchMessage(lpmsg);
}

 

 

 

Изменено пользователем Xipho
Большие куски кода нужно убирать под спойлер.
  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Теперь все работает! Вы какой то другой метод используете. Можете вот эту функцию расписать, что и зачем делает:
 

Скрытый текст

void* DetourCreate(BYTE *src, const BYTE *dst, const int len)
{
	BYTE *jmp;
	DWORD dwback, dwold;
	DWORD jumpto, newjump;
	VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &dwback);
	if (src[0] == 0xE9)
	{
		jmp = (PBYTE)malloc(10);
		VirtualProtect(jmp, 10, PAGE_EXECUTE_READWRITE, &dwold);
		jumpto = (*(DWORD*)(src + 1)) + ((DWORD)src) + 5;
		newjump = (jumpto - (DWORD)(jmp + 5));
		jmp[0] = 0xE9;
		*(DWORD*)(jmp + 1) = newjump;
		jmp += 5;
		jmp[0] = 0xE9;
		*(DWORD*)(jmp + 1) = (DWORD)(src - jmp);
	}
	else
	{
		jmp = (PBYTE)malloc(5 + len);
		VirtualProtect(jmp, 5 + len, PAGE_EXECUTE_READWRITE, &dwold);
		memcpy(jmp, src, len);
		jmp += len;
		jmp[0] = 0xE9;
		*(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5;
	}
	src[0] = 0xE9;
	*(DWORD*)(src + 1) = (DWORD)(dst - src) - 5;
	for (int i = 5; i < len; i++)
		src[i] = 0x90;
	VirtualProtect(src, len, dwback, &dwback);
	return (jmp - len);
}

 

А тут где-нибудь спасибо можно поставить?

Изменено пользователем helldrg
Ссылка на комментарий
Поделиться на другие сайты

@helldrg, в нижнем-правом углу сообщения стрелочки - плюс и минус. А метод перехвата у @Dino, по-моему, тот же что и у меня - в начало функции записывается ассемблерная инструкция вида "jmp addr", где addr - адрес перехваченной функции в нашей dll.

Ссылка на комментарий
Поделиться на другие сайты

20 минуты назад, keng сказал:

в нижнем-правом углу сообщения стрелочки - плюс и минус.

У  меня их нету(

 

20 минуты назад, keng сказал:

по-моему, тот же что и у меня - в начало функции записывается ассемблерная инструкция вида "jmp addr", где addr - адрес перехваченной функции в нашей dll.

Вы через heap искали в первом уроке
А можно по подробней о функции рассказать, зачем это условие нужно, цикл в конце с нопами какой то появляется

Мне ваш пример нравился, там просто создавали d3d, находили d3d процесса, делали указатель d3d->d3d процесса все легко и понятно было, вот только почему то не везде этот пример работает( 
я поэтому тему и создал что бы разобраться почему не работает =)

Изменено пользователем helldrg
Ссылка на комментарий
Поделиться на другие сайты

32 минуты назад, helldrg сказал:

Теперь все работает! Вы какой то другой метод используете. Можете вот эту функцию расписать, что и зачем делает:

  Показать содержимое


void* DetourCreate(BYTE *src, const BYTE *dst, const int len)
{
	BYTE *jmp;
	DWORD dwback, dwold;
	DWORD jumpto, newjump;
	VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &dwback);
	if (src[0] == 0xE9)
	{
		jmp = (PBYTE)malloc(10);
		VirtualProtect(jmp, 10, PAGE_EXECUTE_READWRITE, &dwold);
		jumpto = (*(DWORD*)(src + 1)) + ((DWORD)src) + 5;
		newjump = (jumpto - (DWORD)(jmp + 5));
		jmp[0] = 0xE9;
		*(DWORD*)(jmp + 1) = newjump;
		jmp += 5;
		jmp[0] = 0xE9;
		*(DWORD*)(jmp + 1) = (DWORD)(src - jmp);
	}
	else
	{
		jmp = (PBYTE)malloc(5 + len);
		VirtualProtect(jmp, 5 + len, PAGE_EXECUTE_READWRITE, &dwold);
		memcpy(jmp, src, len);
		jmp += len;
		jmp[0] = 0xE9;
		*(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5;
	}
	src[0] = 0xE9;
	*(DWORD*)(src + 1) = (DWORD)(dst - src) - 5;
	for (int i = 5; i < len; i++)
		src[i] = 0x90;
	VirtualProtect(src, len, dwback, &dwback);
	return (jmp - len);
}

 

 

Этот распространенный метод установки хуков, можно найти на просторах интернета, дабы не изобретать каждый раз велосипед. Смысл тот же что и у @keng  только реализация немного другая

 

32 минуты назад, helldrg сказал:

А тут где-нибудь спасибо можно поставить?

Похоже у стажеров нет такой возможности=)

Изменено пользователем Dino
Ссылка на комментарий
Поделиться на другие сайты

Просто хотелось бы не просто копипастить или качать detour и им пользоваться, а разобраться во всем процессе, ведь люди которые к примеру разрабатывают велосипеды новые, они сперва изучают старые, собирают их а потом начинают усовершенствовать =)
Если бы объяснили бы функцию подробно я был бы премного благодарен, а если бы еще и кенг разобрался бы почему его пример не работает так было бы идеально =)

Ссылка на комментарий
Поделиться на другие сайты

@helldrg, вообще, у меня в блоге лежит два варианта и оба ищут через кучу. Штука только в том, что в одном случае для перехвата функции используется библиотека MS Detours, а в другом я написал сам нужную для этого функцию, чтобы не таскать с собой лишнего и упростить код. Эта функция и есть в коде @Dino. Тебе хочется разобраться вообще в алгоритме работы всей этой штуки, или только в конкретной функции?

Ссылка на комментарий
Поделиться на другие сайты

1 минуту назад, keng сказал:

Тебе хочется разобраться вообще в алгоритме работы всей этой штуки, или только в конкретной функции?

Я вроде более-менее разобрался в алгоритме и зачем эта функция нужна, я только не понял что в ней происходит, то есть разобраться в этой функции

Ссылка на комментарий
Поделиться на другие сайты

грубо говоря она записывает по переданному адресу команду jmp <адрес нашего хука> , затем создает трамплин состоящий из оригинальных байт (которые затерли в оригинальной функции командой jmp ) и команды jmp<адрес оригинальной функции + число байт которые затерли>

Трамплин нужен на случай, если мы захотим выполнить оригинальную функцию из хука.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.