Where im failing on native dll?

Там пример есть, но что-то не то)
Хотелось бы не только вызывать код внутри dll, но и получать из dll например string с текстом.
Хорошо бы разобраться в этом и выложить готовые исходники с инклудами в ресурсы.
так из того же примера, что ты скидывал ссылку на тему.

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);
        }
    }
}

1723724929242.png

Стало быть осталось только разобраться как присвоить айди функции из той же темы
 

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

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);
        }
    }
}

Посмотреть вложение 77648

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

Это как раз номер функции для вызова которую можно вызвать из кода .uc
Но что-то не работает, хорошо бы оба варианта как вызов с dll и выполнение кода по номеру из .uc и чтение текста из dll и вывод через .uc
 
Это как раз номер функции для вызова которую можно вызвать из кода .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
    1723746925562.png
    346,2 КБ · Просмотры: 54
  • 1723746986008.png
    1723746986008.png
    27,9 КБ · Просмотры: 50
Я посмотрел пример кода, что вы дали выше, собрал такой код но не знаю как получить (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 таким способом не используя сторонних программ.
Можно подглядеть в 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);
}
 
Чтобы ошибки после выполнения не было надо сдвинуть стак.
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


I looked at the example code that you gave above, I assembled the following code, but I don’t know how to get (struct FFrame), my function is called from the dll by clicking on a button in the interface, a dialog box appears, but after execution the game crashes(

C++
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();

//In xdat I created a window with a button and when the button was clicked, I called a function from the dll
function OnClickButton( string strID )
    {
 switch( strID )
    {
      case "btnTest":
      TestDllFunction();
   break;
      }

I load the dll by simply calling it interface.dll in interlude and hf you can load the dll in this way without using third-party programs.

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?
Проверил ошибки осталась(
 
Сделал все как вы советовали но ошибка не пропадает( Менял диалог на другие вызовы таже ошибка(
Может ошибка происходит иза того, что при выполнение моей функции останавливается основной поток?
Возможно что-то еще нужно передать при вызове функции или при регистрации?

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;
}
Может нужно номер 1247 заменить на другой и он занят уже в нативных функциях? 🤔
 
Что-то еще нужно передать странно что крашит хотя ошибок быть не должно. 🤔
 
Дополню: Если закомментировать UObject* Object; то ошибка после выполнения функции не пропадает.
Что-то еще нужно передать странно что крашит хотя ошибок быть не должно. 🤔
Действительно, ошибка есть. Достаточно запустить дебагер и посмотреть причину краша. Нашу нативную функцию вызывает функция UObject::execHighNative0.
1723884608602.png

Она не чистит стек после выполнения нашей нативки. Аналогично не чистит стек наша нативная функция, т.к. по умолчанию в 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);
}
 
Она не чистит стек после выполнения нашей нативки. Аналогично не чистит стек наша нативная функция, т.к. по умолчанию в vs установлено соглашение о вызовах __cdecl. Если принудительно установить для нужной функции __stdcall, то все работает.
Я уже менял соглашения о вызове мне это не помогло((
 
Назад
Сверху Снизу