У меня есть прокси-сервер dxgi.dll, и я пытаюсь отключить функцию Present в оригинальном dxgi.dll для отображения объектов на экране..Dll успешно загружен и объезд размещен.Однако объезд сбивает программу, как только мой новый подарок называется. Имейте в виду, что .dll и программы являются 64-битными.
Ниже приведено изображение того, как функция выглядит в памяти до модификации (начало выделено):
Хорошо, я только что узнал, что я не могу публиковать изображения прямо здесь, если у меня нет 10 репутации, поэтому используйте эту ссылку (замените DOT): https://imgur DOTcom / a / Jf53dYc
Я не уверен, где именно происходит сбой, я полагаю, что программа продолжает работать некоторое время, но она определенно падает в середине / вскоре после вызова обходного Present, я знаю этопотому что я могу записать указатель на параметр SwapChain в файл из обхода Present до его сбоя.
Я нашел оригинальный адрес функции Present с помощью IDA.Вы можете увидеть, что говорит IDA о функции на картинке в галерее imgur.
Я смотрю на память и пытаюсь выяснить, что не так, когда я следую за прыжками, используя Cheat engine, который онипривести к правильным местам, тем не менее что-то в обход делает сбой программы.Переопределенные коды операций также, кажется, заменены должным образом.
Я пытался изменить соглашение о вызовах и тип возвращаемого значения в моей функции Present, я прочитал в руководстве по перехвату dxgi, что возвращаемый тип был HRESULT, я пыталсяизменить на это безрезультатно.Что касается соглашения о вызовах, я попробовал WINAPI.
Я также немного изучил, не поврежден ли стек или регистры моим обходом функции.Однако я не очень хорошо разбираюсь в ассемблере и не могу с уверенностью сказать, так ли это.
У меня есть класс с именем Core, который занимается перехватом, вот файл заголовка с некоторыми соответствующими определениями:
#pragma once
#include <iostream>
#include <Windows.h>
#include <intrin.h>
#include <dxgi.h>
#include <fstream>
// Seems my C++ doesn't have QWORD predefined, defining it myself
typedef unsigned __int64 QWORD;
// Definition of the structure of the DXGI present function
typedef __int64 (__fastcall* PresentFunction)(IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags);
class Core
{
private:
QWORD originalDllBaseAddress;
QWORD originalPresentFunctionOffset;
public:
void Init();
bool Hook(PresentFunction originalFunction, void* newFunction, int bytes);
~Core();
};
Init запускает процесс, получая соответствующие адреса:
void Core::Init()
{
originalDllBaseAddress = (QWORD)GetModuleHandleA("dxgi_.dll");
originalPresentFunctionOffset = 0x5070;
originalPresentFunction = (PresentFunction)(originalDllBaseAddress + (QWORD)originalPresentFunctionOffset);
Hook(originalPresentFunction, FixAndReturn, 14);
}
Hook пытается выполнить переход по целевому адресу, Я твердо верю, что проблема где-то здесь, (комментарии теперь изменили мое мнение, возможно, это как-то связано со сборкой, регистрами или стеком), более конкретно, с назначениями originalFunction:
bool Core::Hook(PresentFunction originalFunction, void* newFunction, int length)
{
DWORD oldProtection;
VirtualProtect(originalFunction, length, PAGE_EXECUTE_READWRITE, &oldProtection);
memset(originalFunction, 0x90, length);
// Bytes are flipped (because of endianness), could alternatively use _byteswap_uint64()
*(QWORD*)originalFunction = 0x0000000025FF;
// The kind of jump I'm doing here seems to only use 6 bytes,
// and then grabs the subsequent memory address,
// I'm not quite sure if I'm doing this right
*(QWORD*)((QWORD)originalFunction + 6) = (QWORD)newFunction;
DWORD temp;
VirtualProtect(originalFunction, length, oldProtection, &temp);
originalPresentFunction = (PresentFunction)((QWORD)originalFunction + length);
presentAddr = (QWORD)Present;
jmpBackAddr = (QWORD)originalPresentFunction;
return true;
}
Я пробовал много вещей, когда дело доходит до записи байтов в память, но ни одна из них не устранила мою проблему.
Присвоение функции «originalPresentFunction» в конце функции - это адрес, который объездпопытается вернуться к.
Вот определение функции обхода, расположенной в Core.cpp:
__int64 __fastcall Present(IDXGISwapChain *pSwapChain, UINT SyncInterval, UINT Flags)
{
//The program crashes with and without these file writes.
std::ofstream file;
file.open("HELLO FROM PRESENT.txt");
file << pSwapChain;
file.close();
return originalPresentFunction(pSwapChain, SyncInterval, Flags);
}
Это функция при вызовеЭд, что вызывает сбой.Как видите, я записываю здесь параметр pSwapChain в файл.Я сделал это, чтобы проверить, передаются ли параметры из исходной функции.Эта запись успешна, и содержимое файла выглядит как правильный указатель.таким образом сбой происходит после этой записи.FixAndReturn () - это функция сборки.
includelib legacy_stdio_definitions.lib
.data
extern presentAddr : qword
extern jmpBackAddr : qword
; This performs instructions originally performed by dxgi.dll in the
; memory that we've replaced, and then returns
.code
FixAndReturn PROC
call [presentAddr]
mov [rsp+10h],rbx
mov [rsp+20h],rsi
push rbp
push rdi
push r14
jmp qword ptr [jmpBackAddr]
FixAndReturn ENDP
end
Я загрузил весь код на Github, если требуется больше кода: https://github.com/techiew/KenshiDXHook