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

[C++ Lineage 2] Не работают функции из SDK в DLL

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

Хэллоу всем. Учу С++, интересен реверс, знаний мало , если что - бейте по голове.

 

Ковыряюсь в клиенте High Five, нашел SDK под него, всё как надо подцепил и нихрена в итоге не работает. 

DLL после инжекта находит адреса функций, адреса других dll-ок процесса, а получать значения никак не желает.

 

Куски кода брал с ютуба (под FarCry писался), немного переделал под себя, т.к. в VS19 никак не шел вывод в консоль.

Код:

Спойлер

// main
#include <Windows.h>
#include <iostream>
#include <string>
// for console
#include <io.h>
#include <fcntl.h>
#include <conio.h>
// others

// sdk
#include "L2Sdk/SDK.hpp"

using namespace L2v273;

HINSTANCE hInst = 0;

HANDLE hConsole;
void CreateConsole() 
{
	AllocConsole();
	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
}

bool write(std::string description, ...)
{
	char buf[1024];
	memset(buf, 0, sizeof(buf));

	va_list vaList;
	va_start(vaList, description);
	vsprintf_s(buf, (description + "\n").c_str(), vaList);
	va_end(vaList);

	if (WriteConsoleA(hConsole, buf, strlen(buf), 0, 0) == 0) {

		return false;
	}

	return true;
}

DWORD* ReadPointer(DWORD baseAddr, DWORD offset)
{
	return *(DWORD**)(baseAddr + offset);
}

DWORD __stdcall MainThread(LPVOID)
{
	CreateConsole();
	write("Dll successfuly loaded!  ---  ESC to unload dll\n");

	HMODULE hEngine = GetModuleHandleA("engine.dll");
	HMODULE hCore = GetModuleHandleA("core.dll");
	HMODULE hWinDrw = GetModuleHandleA("windrv.dll");
	write("WinDrw addr: %p", hWinDrw);
	HMODULE hNWindow = GetModuleHandleA("nwindow.dll");

	FEngine::APawn* pawn = reinterpret_cast<FEngine::APawn*>(GetProcAddress(hEngine, "??0APawn@@QAE@ABV0@@Z"));
	FCore::UObject* uobject = reinterpret_cast<FCore::UObject*>(GetProcAddress(hCore, "??0UObject@@QAE@ABV0@@Z"));
	FWinDrv::UWindowsViewport* Viewport = reinterpret_cast<FWinDrv::UWindowsViewport*>(GetProcAddress(hWinDrw, "??0UWindowsViewport@@QAE@ABV0@@Z"));

	write("Viewport: %p\n", Viewport);
	write("Pawn: %p", pawn);
	write("Uobject: %p\n", uobject);
	
	if(Viewport)
	{
		FCore::FVector Loc = Viewport->Actor->Location;
		write("Location: X: %.2f, Y: %.2f, Z: %.2f", Loc.X, Loc.Y, Loc.Z);
	}

	/*
	DWORD* ptr1 = ReadPointer( (DWORD)GetModuleHandleA("core.dll"), 0x000C6898);
	DWORD* ptr2 = ReadPointer(reinterpret_cast<DWORD>(ptr1), 0x1bc);
	DWORD* ptr3 = ReadPointer(reinterpret_cast<DWORD>(ptr2), 0x0);
	DWORD* ptr4 = ReadPointer(reinterpret_cast<DWORD>(ptr3), 0x300);


	FCore::UObject* uobj = reinterpret_cast<FCore::UObject*>(ReadPointer(reinterpret_cast<DWORD>(ptr1), 0x0034));
	write("FCore::Uobject addr = %p", uobj);

	auto gg = uobj->FindObject<FWinDrv::UWindowsViewport>("WindowsViewport Transient.WindowsClient0.WindowsViewport0");
	*/


	/* Пример получения координат (от Akumu)
	auto Viewport = FCore::UObject::FindObject<FWinDrv::UWindowsViewport>("WindowsViewport Transient.WindowsClient0.WindowsViewport0");
	if (Viewport)
	{
		write("Viewport: %p", &Viewport);
		auto Controller = Viewport->Actor;
		if (Controller)
		{
			auto Actor = Controller->ViewTarget;
			if (Actor)
			{
				auto& Location = Actor->Location;
				auto Name = Actor->GetHumanReadableName();
				write("Pos = %.02f, %.02f, %.02f)", Location.X, Location.Y, Location.Z);
			}
		}
	}
	*/
	
	for (;; Sleep(100))
	{
		if (GetAsyncKeyState(VK_ESCAPE)) 
		{
			break;
		}
	}

	FreeConsole();
	FreeLibraryAndExitThread(hInst, 0);
	return 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	if (fdwReason == DLL_PROCESS_ATTACH)
	{
		
		hInst = hinstDLL;
		CreateThread(0, 0, &MainThread, 0, 0, 0); 
	}

	return 1;
}

 

Не работает как пример который предоставил Akumu вместе с SDK, так и написанный мной код. Вернее, он не выводит ничерта..

В UE по этим адресам функции находит нормально.

 

Скрин:

Спойлер

ca3c49d13fd313901c57f26adb2d87c1.jpg

Объясните недалекому, что может быть не так? Неправильные исходные названия для поиска адреса?

 

Перерыл все форумы, включая зарубежные, там говорят что в UE идет все через ProcessEvent (без хука сего чуда все же не обойтись, да?), но я пока не понимаю как его хукануть, тёмный лес ;(

На кодерксе древние темы про отлов пакетов, это меня не интересует, т.к. под любой UE можно сделать SDK.

 

Сам SDK вместе с исходными названиями функций (Yandex)

 

P.s.

С detours'ом я не дружу, да что там, он даже компилироваться не хочет падла, все какой-то sn требует 😕

Изменено пользователем edx

Поделиться сообщением


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

Ну так ты посмотри что происходит в коде, почему адреса не получаются, через отладчик

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
5 часов назад, imaginary сказал:

Ну так ты посмотри что происходит в коде, почему адреса не получаются, через отладчик

Т.е., по сути, я все таки могу это дело без detours'a и прочего получить? 

Я пытался через CE выйти на начало класса, с помощью какой-нибудь его функции, но в ECX кажется не тот адрес записывается (где-то слышал что в плюсах это адрес начала класса при вызове функции), потому что когда считаю указатель, все равно бред получается:(

Поделиться сообщением


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

В принципе, работают найденные здесь функции, это точно.

Спойлер

// Lineage 2 (v273) SDK

#ifdef _MSC_VER
	#pragma pack(push, 0x4)
#endif

#include "../SDK.hpp"

namespace L2v273
{
TArray<FNameEntry*>* FName::GNames = (TArray<FNameEntry*>*)GetProcAddress(GetModuleHandleW(L"core.dll"), "?Names@FName@@0V?$TArray@PAUFNameEntry@@@@A");
TArray<FCore::UObject*>* FCore::UObject::GObjects = (TArray<FCore::UObject*>*)GetProcAddress(GetModuleHandleW(L"core.dll"), "?GObjObjects@UObject@@1V?$TArray@PAVUObject@@@@A");
} 

#ifdef _MSC_VER
	#pragma pack(pop)
#endif

 

А дальше неточно..

С помощью FCore::UObject::GObjects получилось вытащить названия и адреса всех объектов.

(Отрывок) 

Спойлер

11961    04F72440    TimeEnv0.INT
11962    04F71B80    TimeEnv1.INT
11963    04F712C0    TimeEnv2.INT
11964    04F70A00    TimeEnv3.INT
11965    086EF5A0    FontManager
11966    085B0D20    FontCacheManager
11967    04D13C00    MasterLevel
11968    12230000    AmbientSoundObject7933
11969    085B0CD0    WinDrv
11970    1112DBA8    WindowsViewport
11971    1112D678    WindowsClient

11972    090F0B40    UseJoystick
11973    090F0AA0    UseWindowFrame
11974    08A48E00    WindowsClient
11975    08EF46A0    D3DDrv
11976    096D1610    ShaderCommandlet
11977    096D10E0    D3DRenderDevice
11978    090F0A00    UseHardwareTL
11979    090F0960    UseHardwareVS
11980    090F08C0    UsePrecaching
11981    090F0820    UseTrilinear
11982    090F0780    UseVSync
11983    090F06E0    UseTripleBuffering
11984    090F0640    UseCubemaps

Я нашел здесь этот чертов вьюпорт, но по этому адресу всё равно ничего не получается)

Но мне нужно, как я понимаю, получать указатели на классы, чтобы вытащить хоть что-то оттуда..

auto Viewport = FCore::UObject::FindObject<FWinDrv::UWindowsViewport>("WindowsViewport Transient.WindowsClient0.WindowsViewport0");

Есть здесь кто-нибудь кто работал с этой SDK? Объясните хотя бы на словах что нужно делать и куда копать.

А то про "посмотреть в отладчике" я итак знаю..) Там все равно темный лес, а тут целый SDK)

Поделиться сообщением


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

Без ProcessEvent никак
Его нужно хукать и хукать обязательно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
5 часов назад, roma912 сказал:

Без ProcessEvent никак
Его нужно хукать и хукать обязательно

Понятно, спасибо. Буду пытаться компилить detours. Не подскажешь кстати, что за sn он при компиляции требует? Что то с какими-то ключами связано, 2 ошибки выбивает.

И вообще, можно без деторса обойтись же?

И ещё вопрос: почему работает функция GObjects?

Изменено пользователем edx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
13 минут назад, edx сказал:

Буду пытаться компилить detours.

Зачем его компилить? Берешь из поставки хедер и либ файл, и подключаешь их к проекту.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
4 минуты назад, Xipho сказал:

Зачем его компилить? Берешь из поставки хедер и либ файл, и подключаешь их к проекту.

А в том-то и дело, что либ файла там нет, либо я тупой совсем) Надо скомпилить чтобы либ вышел.. Он кстати появляется, даже с ошибкой компилирования, его можно использовать так?

 

з.ы. 

попробую, спасибо за ответы)

Изменено пользователем edx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
7 часов назад, edx сказал:

А в том-то и дело, что либ файла там нет

Возьми из репозитория с уроками по графике с нашего канала. Там должны быть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В 18.11.2019 в 05:47, roma912 сказал:

Без ProcessEvent никак
Его нужно хукать и хукать обязательно

Нашел Ваш мануал по UE3, не сразу въехал, но, да, я сделал это)

 

Спойлер

void coords(FEngine::ALineagePlayerController* pPlayerController)
{
	if (pPlayerController)
	{
		FCore::FVector loc = pPlayerController->ViewTarget->Location;
		write("X: %i, Y: %i, Z: %i", (int)loc.X, (int)loc.Y, (int)loc.Z);
	}
}

void __fastcall HookedPE(FCore::UObject* pObject, void* edx, FCore::UFunction* pFunction, void* pParms, void* pResult)
{
	const char* szName = pFunction->GetFullName().c_str();

	if (strcmp(szName, "Function Engine.LineagePlayerController.PlayerTick") == 0)
	{
		coords((FEngine::ALineagePlayerController*)(pObject));
	}

	ProcessEvent(pObject, pFunction, pParms, pResult);
}

 

l59UogMb0vDqnUQWx7Jy3qTHQTJVCeljdsHLDIJTHycXw0QnvFGT2rmg2GTazGtDQ4U63ih1pyXNqkI7TEAeZA==?uid=0&filename=1.JPG&disposition=inline&hash=&limit=0&content_type=image%2Fjpeg&tknv=v2&owner_uid=548182919&size=1514x741

 

И еще вопрос:) Это нормально сделать вот так? :

Спойлер

Задать указатель на класс как глобальную переменную


FEngine::ALineagePlayerController* pPlayerController;

А затем инициализировать его при хуке функции:


pPlayerController = reinterpret_cast<FEngine::ALineagePlayerController*>((FEngine::ALineagePlayerController*)(pObject));

Просто некоторые функции не нужно вызывать при каждом хуке..

 

Изменено пользователем edx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
3 часа назад, edx сказал:

И еще вопрос:) Это нормально сделать вот так? :

Можешь при каждой отработке функции просто обновлять указатель на объект а потом пользоваться функциями
Примерно также как у меня и сделано

Поделиться сообщением


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

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

×

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

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