Where im failing on native dll?

так из того же примера, что ты скидывал ссылку на тему.

C++:
#include "stdafx.h"

#define RESULT_DECL void*const Result
typedef void (*Native)(struct FFrame& TheStack, RESULT_DECL);
typedef BYTE(__cdecl* GRegisterNative_fnType)(INT iNative, const Native& Func);
GRegisterNative_fnType volatile GRegisterNative_fn = NULL;

void hookCore();

extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /* lpReserved */)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        //MessageBox(nullptr, L"DLL_PROCESS_ATTACH", L"DllMain", MB_OK);
        hookCore();
        break;
    }
    case DLL_THREAD_ATTACH:
    {
        //MessageBox(nullptr, L"DLL_THREAD_ATTACH", L"DllMain", MB_OK);
        break;
    }
    case DLL_THREAD_DETACH:
    {
        //MessageBox(nullptr, L"DLL_THREAD_DETACH", L"DllMain", MB_OK);
        break;
    }
    case DLL_PROCESS_DETACH:
    {
        //MessageBox(nullptr, L"DLL_PROCESS_DETACH", L"DllMain", MB_OK);
        break;
    }
    }
    return TRUE;
}

void PRIVATE_OnCalled_execDebug(struct FFrame& Stack, RESULT_DECL)
{
    MessageBox(nullptr, L"Call delegate PRIVATE_OnCalled_execDebug", L"hook", MB_OK);
}

void hookCore()
{
    auto hCore = GetModuleHandleA("Core.dll");

    if (hCore) {
        MessageBox(nullptr, L"hCore is not null", L"hook", MB_OK);
        GRegisterNative_fn = (GRegisterNative_fnType)GetProcAddress(hCore, "?GRegisterNative@@YAEHABQ8UObject@@AEXAAUFFrame@@QAX@Z@Z");

        if (GRegisterNative_fn)
        {
            MessageBox(nullptr, L"GRegisterNative_fn is not null", L"hook", MB_OK);
            
            GRegisterNative_fn(2, &PRIVATE_OnCalled_execDebug);
        }
    }
}



Стало быть осталось только разобраться как присвоить айди функции из той же темы
 
Тут вместо 2 например 4069:
Код:
GRegisterNative_fn(2

Это как раз номер функции для вызова которую можно вызвать из кода .uc
Но что-то не работает, хорошо бы оба варианта как вызов с dll и выполнение кода по номеру из .uc и чтение текста из dll и вывод через .uc
 
Ну ждите, может еще кто подтянется поделится своими соображениями по этому поводу
 
Well i did some changes but i still get the same Critical Error, lets hope that some1 give us a light, because for now im stucked on it
 
Я посмотрел пример кода, что вы дали выше, собрал такой код но не знаю как получить (struct FFrame) моя функция вызывается из dll по нажатие на кнопку в интерфейсе, появляется диалоговое окно но после выполнения игра крашится(

С++
C++:
#include <windows.h>

typedef void (*Native)(struct FFrame&, void* const);
typedef BYTE(__cdecl* GRegisterNative_fnType)(INT iNative, const Native& Func);

void  functionUC(struct FFrame&, void* const)
{
   MessageBox(nullptr, L"Load functionUC", L"hook", MB_OK);
}

void hookCore()
{
    auto hCore = GetModuleHandleA("Core.dll");

    if (hCore) {
        GRegisterNative_fnType GRegisterNative_fn = (GRegisterNative_fnType)GetProcAddress(hCore, "?GRegisterNative@@YAEHABQ8UObject@@AEXAAUFFrame@@QAX@Z@Z");

        if (GRegisterNative_fn) {
            GRegisterNative_fn(1247, &functionUC);


        }
    }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /* lpReserved */)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        hookCore();
        break;
    }
    return TRUE;
}

UnrealScript
C++:
class TestScriptNative extends UICommonAPI;

native(1247) final static function TestDllFunction();

//В xdat создал окно с кнопкой и по нажатию кнопки вызвал функцию из dll
function OnClickButton( string strID )
    {
 switch( strID )
    {
      case "btnTest":
      TestDllFunction();
   break;
      }

Загружаю dll просто назвав ее interface.dll в interlude и hf можно подгрузить dll таким способом не используя сторонних программ.
 

Вложения

  • 1723746925562.png
    346,2 КБ · Просмотры: 61
  • 1723746986008.png
    27,9 КБ · Просмотры: 56
Можно подглядеть в Duke Nukem Leak исходниках с GitHub структуру FFrame, надеюсь поможет докопаться до истины )

 
А как наоборот что то в UI вызвать из dll ?
 
Чтобы ошибки после выполнения не было надо сдвинуть стак.
C++:
struct FFrame
{
public:
    int* ftable;
    void* Node;
    UObject* Object;
    BYTE* Code;
    BYTE* Locals;
    INT    LineNum;
};

void functionUC(struct FFrame &Stack, void* const)
{
   Stack.Code++;
   MessageBox(nullptr, L"Load functionUC", L"hook", MB_OK);
}
 
Спасибо за такую ценную информацию. Тоже попробую вызвать свою нативную функцию из интерфейса.
А как наоборот что то в UI вызвать из dll ?
Через ивенты? Я сделал так: получаю адрес функции XMLUIManager::ExecuteUIEvent и вызываю ее, передавая номер ивента и переменную-строку FString. В самих uc скриптах нужно зарегистрировать ивент с таким же номером и обрабатывать его. Не знаю насколько это изящное решение, я нигде не нашел информации как это реализовать. Но у меня это работает
 
Чтобы ошибки после выполнения не было надо сдвинуть стак.
Спасибо! за ответ но теперь не понятно откуда взять UObject* Object; я пытался его взять из Unreal но я никогда с этим не работал) получаю миллион ошибок после подключения заголовочных файлов(

Дополню: Если закомментировать UObject* Object; то ошибка после выполнения функции не пропадает.
 
Последнее редактирование модератором:
Вот пытался сделать и ошибки, нужно еще что-то.
Может заголовочные файлы нужно другие.
 
will there be code examples?
i removed the changes since it wasnt working nothing so relevant



What about creating a new dll instead of interface.dll, will it have the same result?
 
не нужно его убирать. Объяви пустышку ( class UObject; ) или поставь int*
Сделал все как вы советовали но ошибка не пропадает( Менял диалог на другие вызовы таже ошибка(
Может ошибка происходит иза того, что при выполнение моей функции останавливается основной поток?
Возможно что-то еще нужно передать при вызове функции или при регистрации?

C++:
#include <windows.h>

// Структура
struct FFrame
{
public:
    int* ftable;        // Указатель на таблицу функций
    void* Node;         // Указатель на узел
    INT* Object;        // Указатель на объект
    BYTE* Code;         // Указатель на код
    BYTE* Locals;       // Указатель на локальные переменные
    INT  LineNum;       // Номер строки
};

// Тип для указателя на функцию, принимающую структуру FFrame и указатель на void
typedef void (*Native)(struct FFrame&, void* const);

// Тип для указателя на функцию GRegisterNative
typedef BYTE(__cdecl* GRegisterNative_fnType)(INT iNative, const Native& Func);

// Функция, которая будет вызываться вместо оригинальной функции с номером 1247
void  functionUC(struct FFrame& Stack, void* const)
{
    // Переход на следующую инструкцию кода
    Stack.Code++;

    // Вывод сообщения о загрузке функции functionUC
    MessageBox(nullptr, L"Load functionUC", L"hook", MB_OK);
}

// Функция для хука функции в модуле "Core.dll"
void hookCore()
{
    // Получение дескриптора модуля "Core.dll"
    auto hCore = GetModuleHandleA("Core.dll");

    // Проверка, найден ли модуль "Core.dll"
    if (hCore) {
        // Получение адреса функции GRegisterNative из модуля "Core.dll"
        GRegisterNative_fnType GRegisterNative_fn = (GRegisterNative_fnType)GetProcAddress(hCore, "?GRegisterNative@@YAEHABQ8UObject@@AEXAAUFFrame@@QAX@Z@Z");

        // Проверка, найден ли адрес функции GRegisterNative
        if (GRegisterNative_fn) {
            // Вызов функции GRegisterNative, передавая в качестве аргументов номер функции (1247) и адрес функции functionUC
           GRegisterNative_fn(1247, &functionUC);
        }
    }
}

// Точка входа для DLL
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID)
{
    // Обработка события, которое указывает на причину вызова функции DllMain
    switch (ul_reason_for_call)
    {
        // Обработка события DLL_PROCESS_ATTACH, которое происходит при загрузке DLL в процесс
    case DLL_PROCESS_ATTACH:
        // Вызов функции hookCore для выполнения хука
        hookCore();
        break;
    }
    // Возвращение значения TRUE, сигнализируя о успешном завершении функции DllMain
    return TRUE;
}

What about creating a new dll instead of interface.dll, will it have the same result?
Проверил ошибки осталась(
 
Может нужно номер 1247 заменить на другой и он занят уже в нативных функциях?
 
Что-то еще нужно передать странно что крашит хотя ошибок быть не должно.
 
Что-то еще нужно передать странно что крашит хотя ошибок быть не должно.
Действительно, ошибка есть. Достаточно запустить дебагер и посмотреть причину краша. Нашу нативную функцию вызывает функция UObject::execHighNative0.


Она не чистит стек после выполнения нашей нативки. Аналогично не чистит стек наша нативная функция, т.к. по умолчанию в vs установлено соглашение о вызовах __cdecl. Если принудительно установить для нужной функции __stdcall, то все работает.
C++:
class UObject {};
struct FFrame
{
public:
    int* ftable;
    void* Node;
    UObject* Object;
    BYTE* Code;
    BYTE* Locals;
    INT    LineNum;
};

typedef void(__stdcall* Native)(FFrame&, void* const);
typedef BYTE(__cdecl* GRegisterNative_fnType)(INT iNative, const Native& Func);

void __stdcall functionUC(FFrame& Stack, void* const)
{
    Stack.Code++;
    MessageBox(nullptr, L"Load functionUC", L"hook", MB_OK);
}
 
Я уже менял соглашения о вызове мне это не помогло((