Как вернуть строку из DLL C++ в UnrealScript?

BIT_hack

Знающий
Участник
Сообщения
254
Розыгрыши
0
Решения
2
Репутация
79
Реакции
158
Баллы
485
Как можно вернуть строку из DLL C++ в UnrealScript, не используя сторонние библиотек?
Я пробую так и еще 1000 способов но постоянно получаю ошибку связанную с FArray

1732447607747.png

C++ (.*dll)
C++:
// Класс-заглушка
class UObject {};

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

// Тип для нативных функций
typedef void(__stdcall* Native)(FFrame&, void* const);

// Тип для функции регистрации нативных функций в UnrealScript
typedef BYTE(__cdecl* GRegisterNative_fnType)(INT iNative, const Native& Func);

//Функция которая должна вернуть строку в UnrealScript
static void __stdcall GetMyString(struct FFrame& Stack, void* Result) {

    const wchar_t* source = L"Hello, world!";
    size_t len = wcslen(source) + 1;

    // Выделяем память + проверка на ошибку
    wchar_t* buffer = (wchar_t*)malloc(len * sizeof(wchar_t));
    if (buffer == NULL) {
        *((wchar_t**)Result) = NULL;
        return;
    }

    // Используем wcscpy_s
    errno_t err = wcscpy_s(buffer, len, source); // len - размер буфера

    if (err != 0) {
        free(buffer); // Обязательно освободить память в случае ошибки
        *((wchar_t**)Result) = NULL;
        return;
    }

    *((wchar_t**)Result) = buffer;
    
}

// Подключение Core.dll
void hookCore() {

    HMODULE hCore = GetModuleHandleA("Core.dll"); // Получение дескриптора Core.dll
    // Проверка на успешное получение дескриптора
    if (hCore) {

        GRegisterNative_fnType GRegisterNative_fn = (GRegisterNative_fnType)GetProcAddress(hCore, "?GRegisterNative@@YAEHABQ8UObject@@AEXAAUFFrame@@QAX@Z@Z");
        
        // Проверка на успешное получение адреса функции
        if (GRegisterNative_fn) {
        
            // Регистрация нативных функций в UnrealScript
            GRegisterNative_fn(1255, &GetMyString);
        }
    }

}

// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {
    if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
        // Отключение отслеживания вызовов функций библиотеки
        DisableThreadLibraryCalls(hModule);
        
        hookCore();
        
    }
    return TRUE;
}

UnrealScript (.*uc)
C-подобный:
native(1255) final function string GetMyString(); 

AddSystemMessageString("DLL_TEXT="@GetMyString()); //string Вывод системных сообщений в чат
 

реализовать класс FString. Он имеет не просто массив байт но и размер и важно использовать менеджер памяти клиента для создания/удаления строки.
 
реализовать класс FString. Он имеет не просто массив байт но и размер и важно использовать менеджер памяти клиента для создания/удаления строки.
Могли бы вы привести пример, я пока не понимаю как это работает(
 
у тебя даже по ошибки видно что она идет в освобождении. Чтобы он смог удалить он должен знать о ней.
Хорошо, спасибо, я понял. Буду разбираться. Буду очень признателен, если кто-то сможет дать мне более подробные разъяснения.
 
Могли бы вы привести пример, я пока не понимаю как это работает(
Fyyre и акуму заливали сдк для грации и интерлюда, там это есть. Точно уже не вспомню чью работу я взял себе (мне нужен был только FString)
C++:
template<class T>
struct TArray
{
    friend struct FString;
public:
    inline TArray()
    {
        Data = nullptr;
        Count = Max = 0;
    };

    inline size_t Num() const
    {
        return Count;
    };

    inline T& operator[](size_t i)
    {
        return Data[i];
    };

    inline const T& operator[](size_t i) const
    {
        return Data[i];
    };

    inline bool IsValidIndex(size_t i) const
    {
        return i < Num();
    }

    inline T& GetByIndex(size_t i)
    {
        return Data[i];
    }

    inline const T& GetByIndex(size_t i) const
    {
        return Data[i];
    }

private:
    T* Data;
    int32_t Count;
    int32_t Max;
};

struct FString : private TArray<wchar_t>
{
    inline FString(){}

    FString(const wchar_t* other)
    {
        Max = Count = *other ? std::wcslen(other) + 1 : 0;
        if (Count)
        {
            Data = const_cast<wchar_t*>(other);
        }
    };

    inline bool IsValid() const
    {
        return Data != nullptr;
    }

    inline const wchar_t* c_str() const
    {
        return Data;
    }

    std::string ToString() const
    {
        auto length = std::wcslen(Data);
        std::string str(length, '\0');
        std::use_facet<std::ctype<wchar_t>>(std::locale()).narrow(Data, Data + length, '?', &str[0]);
        return str;
    }
};

Использую для ивентов так:
C++:
void CallExecuteUIEvent(int eventID, const wchar_t* strParam)
{
    FString param(strParam);
    fExecuteUIEvent(fGetXMLUIManagerPtr(), eventID, &param);
}
 
Fyyre и акуму заливали сдк для грации и интерлюда, там это есть. Точно уже не вспомню чью работу я взял себе (мне нужен был только FString)
Да спасибо помог все работает!
 
Fyyre and akuma were poured with SDK for grace and interlude, there it is. I don't remember exactly whose job I took for myself (I only needed FString)


I use it for events like this:
C++:
void CallExecuteUIEvent(int eventID, const wchar_t* strParam)
{
    FString param(strParam);
    fExecuteUIEvent(fGetXMLUIManagerPtr(), eventID, &param);
}
Hello Charmant :)

Can you post here code you used to get pointer to IUManager? :)
Thank you in advance
 
code you used to get pointer to IUManager? :)
Нужно найти оффсет XMLUIManager в nwindow.dll, он отличается в разных версиях клиента. Дальше всё просто:
C++:
uintptr_t XMLUIPtrOffset = 0x1100; // gracia epilogue
uintptr_t nwindowBaseAddr = 0;
GetXMLUIManager_fn fGetXMLUIManagerPtr = nullptr;

typedef int(__fastcall* GetXMLUIManager_fn)();

// nwindowBaseAddr уже получен, !=0
fGetXMLUIManagerPtr = (GetXMLUIManager_fn)(nwindowBaseAddr + XMLUIPtrOffset);
 
Назад
Сверху Снизу