Итак, я начал изучать C++ в последние несколько дней, так как хотел немного заняться взломом игр и обратным проектированием. Я попытал счастья с основным методом обхода, просто вставив jmp в свою функцию в памяти моей целевой программы, которая работала нормально. Однако я хотел начать использовать библиотеку обхода Microsoft и попробовал. Моя единственная цель сейчас — регистрироваться каждый раз, когда вызывается функция.
Почему-то моя DLL записывает в память неправильный адрес для перехода и тем самым вылетает программа.
Прыжок, прикрепленный адрес приводит к пустой памяти
Он пишет по правильному адресу, но просто не переходит в нужное место. Я ОЧЕНЬ новичок в С++, поэтому, вероятно, это моя ошибка, но я не могу заставить его работать.
#include "stdafx.h"
#include <detours.h>
#include <windows.h>
#include <iostream>
DWORD AddressOfFunc;
typedef int (__cdecl* func)(int x);
int hookFunc(int x) {
std::cout << "TRIGGERED!" << std::endl;
func originalFunc = (func)AddressOfFunc;
return originalFunc(x);
}
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) {
AddressOfFunc = (DWORD)GetModuleHandleA("Borderlands2.exe") + 0xA18940;
if (dwReason = DLL_PROCESS_ATTACH) {
AllocConsole();
FILE* fp;
freopen_s(&fp, "CONOUT$", "w", stdout);
std::cout << "Injected!" << std::endl;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID*)&AddressOfFunc, &hookFunc);
DetourTransactionCommit();
}
else if (dwReason == DLL_PROCESS_DETACH) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(LPVOID&)AddressOfFunc, &hookFunc);
DetourTransactionCommit();
}
}
IdaPro говорит мне, что функция принимает целое число и возвращает целое число, но у меня мало опыта, чтобы проверить любую эту информацию, поэтому любая помощь будет оценена по достоинству.
И вы должны проверить код ошибки, возвращаемый DetourAttach.
Не размещайте ссылки на фотографии, а код в письменном виде
@john Я изменил его на (PVOID *), но результат тот же, он правильно записывает переход, но по адресу в памяти, для которого нет инструкций.
Без обид, но это худший подход к изучению C++, который я когда-либо видел.
@Beta, все хорошо :) На самом деле речь идет не об изучении C++, а о модификации игр для удовольствия. Это просто прошлое время, пока я скучаю в универе.
Я пытался изменить росу вещей, но безрезультатно, это должно быть что-то с обходом, я думаю, так как он просто записывает переход в пустую память, но по правильному адресу.
кстати, в просочившемся исходном коде NT4 есть интересный инструмент - "nt4/private/sdktools/autowrap", который делает существующую dll в качестве входных данных и генерирует проект для фиктивной dll, который имитирует настоящую DLL. Такая фиктивная DLL, однажды скомпилированная и загруженная исполняемым файлом, по очереди загружает реальную dll и передает все вызовы реальной dll, давая вам возможность анализировать ввод и результат каждого вызова. Я дал своим фиктивным DLL немного другое имя. единственное, что вам нужно сделать, чтобы заставить exe использовать его - пропатчить один байт в exe, например, изменить kernel32.dll на zernel32.dll. этот метод не выполняет никаких исправлений на лету в памяти.





Поскольку вы используете MS Detours, я не думаю, что он записывает неправильный адрес перехода для jmp. Ваш код правильный, за исключением двух незначительных проблем, которые у меня есть.
Вы используете PVOID*, это не должно вызывать проблем, но это избыточно. PVOID определяется как void*, поэтому, когда вы пишете PVOID*, вы на самом деле делаете void**, что не имеет смысла.
Есть небольшие отличия в синтаксисе от того, как я обычно использую MS Detours.
Вот как это выглядело бы, если бы я его использовал:
typedef int (__cdecl* tFunc)(int x);
tFunc oFunc = nullptr;
int hkFunc(int x)
{
//stuff
}
oFunc = (tFunc)(DWORD)GetModuleHandleA("Borderlands2.exe") + 0xA18940;
DetourAttach(&(PVOID &)oFunc, hkFunc);
Если эти изменения не решат вашу проблему, я думаю, что используемое вами соглашение о вызовах (cdecl) неверно. Вы не всегда можете доверять IDA Pro, иногда вам приходится вручную подтверждать соглашение о вызовах, аргументы и тип возвращаемого значения.
Разместите дополнительную информацию, если вам нужна дополнительная помощь, нам нужно будет увидеть 10 инструкций до и после звонка, а также первую и последнюю 10 инструкций вызываемого абонента.
Я понятия не имею, что вы делаете, но строго с точки зрения C++ это должно быть
DetourAttach((PVOID*)&AddressOfFunc, (PVOID)hookFunc);.