helldrg Опубликовано 20 сентября, 2016 Поделиться Опубликовано 20 сентября, 2016 Всем привет, в уроке [gamehacking] D3D9 hook - Часть 2 в функции : GetDevice9Method есть строка DWORD* vtablePtr = (DWORD*)(*((DWORD*)d3dDevicee)); которая в одних примерах работает, а в других крашит процесс, подскажите, что делать, что бы не крашило Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 20 сентября, 2016 Поделиться Опубликовано 20 сентября, 2016 Привет! Во-первых, отладчик - в помощь. Во-вторых, покажи код и игру, где код падает. Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 20 сентября, 2016 Автор Поделиться Опубликовано 20 сентября, 2016 В 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; } Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 20 сентября, 2016 Поделиться Опубликовано 20 сентября, 2016 Спасибо за отзыв, я выкладываю что-нибудь время от времени и по мере сил. Посмотрел код, все вроде бы неплохо. Возможно, что или не создается hwnd окна для создания объекта d3d, или же сам d3d-объект. Нужно смотреть, больше пока ничего не могу сказать. Если можешь - поделись тестовым приложением, я соберу твой код у себя и попробую отладить. Да, отладчиком я пользовался скорее всего v2.01, без плагинов вообще. PS: Простыни исходного кода лучше убирать под тег "спойлер". Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 20 сентября, 2016 Автор Поделиться Опубликовано 20 сентября, 2016 (изменено) 41 минуты назад, keng сказал: PS: Простыни исходного кода лучше убирать под тег "спойлер". Я искал не нашел спойлер, похоже это скрытый текст Вот проект, и exe: http://rgho.st/8Cs76zJNp А вот как код в отладчике выглядит у вас и у меня: Скрытый текст Изображения не работают, попробую так: https://monosnap.com/file/6IaPnQju48gFkSmj0HFsgCu56kCkXh https://monosnap.com/file/XtL5CQwF6hUUwFSZ2YZFFFCSthYlYW У вас функции подсвечиваются и вызов этих функций понятный call address. Естественно не везде такой вызов, но в туториале именно такой. А у меня в отладчике мало чего понятного + в asm я новичок( Изменено 20 сентября, 2016 пользователем helldrg Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 20 сентября, 2016 Поделиться Опубликовано 20 сентября, 2016 (изменено) крашить в том месте может только в случае IsBadReadPtr(d3dDevicee,4) == true, от сюда вывод, что CreateDevice у тебя отрабатывает коряво. И вообще где все проверки? а то у тебя код как-то линейно выполняется, будь что будет .. суть этого цикла вообще не понял for (int i = 0; i < 4; i++) { vtableFrag[i] = vtablePtr[i + 6]; } Изменено 20 сентября, 2016 пользователем Dino Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 20 сентября, 2016 Поделиться Опубликовано 20 сентября, 2016 для дальнейшего анализа слишком мало кода Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 20 сентября, 2016 Поделиться Опубликовано 20 сентября, 2016 (изменено) 54 минуты назад, helldrg сказал: Я искал не нашел спойлер, похоже это скрытый текст Вот проект, и exe: http://rgho.st/8Cs76zJNp с D3D тестом у тебя все ОК . Думаю, проблема именно в хуке. Изменено 20 сентября, 2016 пользователем Dino Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 20 сентября, 2016 Поделиться Опубликовано 20 сентября, 2016 Так, ок. У меня Win10 x64 и мой же код работает некорректно. Хук отрабатывает, но что-то не так с перехваченной функцией, которой я подменяю оригинальную Present(). Моя рушит стек при вызове. Буду разбираться, но это займет какое-то время. Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 20 сентября, 2016 Автор Поделиться Опубликовано 20 сентября, 2016 Это все kenga хук, http://kekekeng.blogspot.ru/2012/10/direct3d-1.html, я так понимаю это создаем сигнатуру по которой будем искать нужный указатель. Проверок нету я так понял для уменьшения размера кода Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 20 сентября, 2016 Автор Поделиться Опубликовано 20 сентября, 2016 Скрытый текст #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; } Вот так код у меня выглядит Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 21 сентября, 2016 Автор Поделиться Опубликовано 21 сентября, 2016 6 часов назад, keng сказал: Так, ок. У меня Win10 x64 и мой же код работает некорректно. Хук отрабатывает, но что-то не так с перехваченной функцией, которой я подменяю оригинальную Present(). Моя рушит стек при вызове. Буду разбираться, но это займет какое-то время. Если бы еще видео сделали бы по фиксу или лучше стрим какой нибудь было бы шикарно =) Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 21 сентября, 2016 Поделиться Опубликовано 21 сентября, 2016 (изменено) Скрытый текст #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); } Изменено 22 сентября, 2016 пользователем Xipho Большие куски кода нужно убирать под спойлер. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 21 сентября, 2016 Автор Поделиться Опубликовано 21 сентября, 2016 Везде крашит Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 21 сентября, 2016 Поделиться Опубликовано 21 сентября, 2016 Блин , спойлер похабит код, запостил заново Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 21 сентября, 2016 Автор Поделиться Опубликовано 21 сентября, 2016 (изменено) Теперь все работает! Вы какой то другой метод используете. Можете вот эту функцию расписать, что и зачем делает: Скрытый текст 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); } А тут где-нибудь спасибо можно поставить? Изменено 21 сентября, 2016 пользователем helldrg Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 21 сентября, 2016 Поделиться Опубликовано 21 сентября, 2016 @helldrg, в нижнем-правом углу сообщения стрелочки - плюс и минус. А метод перехвата у @Dino, по-моему, тот же что и у меня - в начало функции записывается ассемблерная инструкция вида "jmp addr", где addr - адрес перехваченной функции в нашей dll. Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 21 сентября, 2016 Автор Поделиться Опубликовано 21 сентября, 2016 (изменено) 20 минуты назад, keng сказал: в нижнем-правом углу сообщения стрелочки - плюс и минус. У меня их нету( 20 минуты назад, keng сказал: по-моему, тот же что и у меня - в начало функции записывается ассемблерная инструкция вида "jmp addr", где addr - адрес перехваченной функции в нашей dll. Вы через heap искали в первом уроке А можно по подробней о функции рассказать, зачем это условие нужно, цикл в конце с нопами какой то появляется Мне ваш пример нравился, там просто создавали d3d, находили d3d процесса, делали указатель d3d->d3d процесса все легко и понятно было, вот только почему то не везде этот пример работает( я поэтому тему и создал что бы разобраться почему не работает =) Изменено 21 сентября, 2016 пользователем helldrg Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 21 сентября, 2016 Поделиться Опубликовано 21 сентября, 2016 (изменено) 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 сказал: А тут где-нибудь спасибо можно поставить? Похоже у стажеров нет такой возможности=) Изменено 21 сентября, 2016 пользователем Dino Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 21 сентября, 2016 Автор Поделиться Опубликовано 21 сентября, 2016 Просто хотелось бы не просто копипастить или качать detour и им пользоваться, а разобраться во всем процессе, ведь люди которые к примеру разрабатывают велосипеды новые, они сперва изучают старые, собирают их а потом начинают усовершенствовать =) Если бы объяснили бы функцию подробно я был бы премного благодарен, а если бы еще и кенг разобрался бы почему его пример не работает так было бы идеально =) Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 21 сентября, 2016 Поделиться Опубликовано 21 сентября, 2016 @helldrg, вообще, у меня в блоге лежит два варианта и оба ищут через кучу. Штука только в том, что в одном случае для перехвата функции используется библиотека MS Detours, а в другом я написал сам нужную для этого функцию, чтобы не таскать с собой лишнего и упростить код. Эта функция и есть в коде @Dino. Тебе хочется разобраться вообще в алгоритме работы всей этой штуки, или только в конкретной функции? Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 21 сентября, 2016 Автор Поделиться Опубликовано 21 сентября, 2016 1 минуту назад, keng сказал: Тебе хочется разобраться вообще в алгоритме работы всей этой штуки, или только в конкретной функции? Я вроде более-менее разобрался в алгоритме и зачем эта функция нужна, я только не понял что в ней происходит, то есть разобраться в этой функции Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 21 сентября, 2016 Поделиться Опубликовано 21 сентября, 2016 грубо говоря она записывает по переданному адресу команду jmp <адрес нашего хука> , затем создает трамплин состоящий из оригинальных байт (которые затерли в оригинальной функции командой jmp ) и команды jmp<адрес оригинальной функции + число байт которые затерли> Трамплин нужен на случай, если мы захотим выполнить оригинальную функцию из хука. Ссылка на комментарий Поделиться на другие сайты Поделиться
helldrg Опубликовано 21 сентября, 2016 Автор Поделиться Опубликовано 21 сентября, 2016 Давай сначала разберемся что там за условие, я понять не могу зачем оно Ссылка на комментарий Поделиться на другие сайты Поделиться
Dino Опубликовано 21 сентября, 2016 Поделиться Опубликовано 21 сентября, 2016 в коде опечатался это case WM_LBUTTONDOWN: if (lpmsg->wParam == VK_F1) return 0; на это case WM_KEYUP: if (lpmsg->wParam == VK_F1) return 0; Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения