Посмотрите видео ниже, чтобы узнать, как установить наш сайт в виде веб-приложения на главном экране.
Примечание: Эта функция может быть недоступна в некоторых браузерах.
Буду пробовать изучать спасибо! я просто мало сталкивался с c++
Я проверил ваш код работает но после выполняя зависает Stack.Code++; использую
Test
Заработало использовал 2 раза Stack.Code++; до и после выполнения код
Мне кажется я нашел причину и ошибка исчезла теперь Stack.Code++ использую один раз.
Я правильно сделал?
C++:Code += sizeof(INT)+1;
const INT B = Stack.ReadByte();
INT value;
if (B == 29)
value = Stack.ReadInt();
else if (B == 44)
value = Stack.ReadByte();
inline BYTE ReadByte()
{
return *Code++;
}
inline void SkipBytes(const INT Count)
{
Code += Count;
}
inline void SkipByte()
{
++Code;
}
inline INT ReadInt()
{
INT Result;
Result = *(INT*)Code;
Code += sizeof(INT);
return Result;
}
native(4005) final function execDebugReadInt(int value);
//
// Evaluatable expression item types.
//
enum EExprToken
{
// Variable references.
EX_LocalVariable = 0x00, // A local variable.
EX_InstanceVariable = 0x01, // An object variable.
EX_DefaultVariable = 0x02, // Default variable for a concrete object.
// Tokens.
EX_Return = 0x04, // Return from function.
EX_Switch = 0x05, // Switch.
EX_Jump = 0x06, // Goto a local address in code.
EX_JumpIfNot = 0x07, // Goto if not expression.
EX_Stop = 0x08, // Stop executing state code.
EX_Assert = 0x09, // Assertion.
EX_Case = 0x0A, // Case.
EX_Nothing = 0x0B, // No operation.
EX_LabelTable = 0x0C, // Table of labels.
EX_GotoLabel = 0x0D, // Goto a label.
EX_EatString = 0x0E, // Ignore a dynamic string.
EX_Let = 0x0F, // Assign an arbitrary size value to a variable.
EX_DynArrayElement = 0x10, // Dynamic array element.!!
EX_New = 0x11, // New object allocation.
EX_ClassContext = 0x12, // Class default metaobject context.
EX_MetaCast = 0x13, // Metaclass cast.
EX_LetBool = 0x14, // Let boolean variable.
EX_MapKeyElement = 0x15, // Map key element.!!
//
EX_EndFunctionParms = 0x16, // End of function call parameters.
EX_Self = 0x17, // Self object.
EX_Skip = 0x18, // Skippable expression.
EX_Context = 0x19, // Call a function through an object context.
EX_ArrayElement = 0x1A, // Array element.
EX_VirtualFunction = 0x1B, // A function call with parameters.
EX_FinalFunction = 0x1C, // A prebound function call with parameters.
EX_IntConst = 0x1D, // Int constant.
EX_FloatConst = 0x1E, // Floating point constant.
EX_StringConst = 0x1F, // String constant.
EX_ObjectConst = 0x20, // An object constant.
EX_NameConst = 0x21, // A name constant.
EX_RotationConst = 0x22, // A rotation constant.
EX_VectorConst = 0x23, // A vector constant.
EX_ByteConst = 0x24, // A byte constant.
EX_IntZero = 0x25, // Zero.
EX_IntOne = 0x26, // One.
EX_True = 0x27, // Bool True.
EX_False = 0x28, // Bool False.
EX_NativeParm = 0x29, // Native function parameter offset.
EX_NoObject = 0x2A, // NoObject.
EX_IntConstByte = 0x2C, // Int constant that requires 1 byte.
EX_BoolVariable = 0x2D, // A bool variable which requires a bitmask.
EX_DynamicCast = 0x2E, // Safe dynamic class casting.
EX_Iterator = 0x2F, // Begin an iterator operation.
EX_IteratorPop = 0x30, // Pop an iterator level.
EX_IteratorNext = 0x31, // Go to next iteration.
EX_StructCmpEq = 0x32, // Struct binary compare-for-equal.
EX_StructCmpNe = 0x33, // Struct binary compare-for-unequal.
EX_UnicodeStringConst = 0x34, // Unicode string constant.
EX_EatCtrExpr = 0x35, // Ignore a constructor expression.
//
EX_StructMember = 0x36, // Struct member.
EX_StructConstruct = 0x37, // Struct constructor.
//
EX_GlobalFunction = 0x38, // Call non-state version of a function.
// Native conversions.
EX_MinConversion = 0x39, // Minimum conversion token.
EX_RotatorToVector = 0x39,
EX_ByteToInt = 0x3A,
EX_ByteToBool = 0x3B,
EX_ByteToFloat = 0x3C,
EX_IntToByte = 0x3D,
EX_IntToBool = 0x3E,
EX_IntToFloat = 0x3F,
EX_BoolToByte = 0x40,
EX_BoolToInt = 0x41,
EX_BoolToFloat = 0x42,
EX_FloatToByte = 0x43,
EX_FloatToInt = 0x44,
EX_FloatToBool = 0x45,
//
EX_ObjectToBool = 0x47,
EX_NameToBool = 0x48,
EX_StringToByte = 0x49,
EX_StringToInt = 0x4A,
EX_StringToBool = 0x4B,
EX_StringToFloat = 0x4C,
EX_StringToVector = 0x4D,
EX_StringToRotator = 0x4E,
EX_VectorToBool = 0x4F,
EX_VectorToRotator = 0x50,
EX_RotatorToBool = 0x51,
EX_ByteToString = 0x52,
EX_IntToString = 0x53,
EX_BoolToString = 0x54,
EX_FloatToString = 0x55,
EX_ObjectToString = 0x56,
EX_NameToString = 0x57,
EX_VectorToString = 0x58,
EX_RotatorToString = 0x59,
EX_MaxConversion = 0x60, // Maximum conversion token.
// Natives.
EX_ExtendedNative = 0x60,
EX_FirstNative = 0x70,
EX_MallocConstRef = 0xD1,
EX_RefIsValid = 0x0191,
EX_ArrayOperation = 0x01F3,
EX_ArrayIterator = 0x0203,
EX_MapIterator = 0x0204,
EX_MapHasValue = 0x0201,
EX_MapRemoveValue = 0x0217,
EX_MapEmptyValue = 0x021A,
EX_AnyOperator = 0x021D,
EX_TeriaryCondition = 0x021E, // Evaluate variable.
EX_DeleteObject = 0x0288,
EX_Max = 0x1000,
};
#pragma once
#include <string>
#define EX_INT 29
#define EX_FLOAT 30
#define EX_STRING 31
#define EX_TRUE 39
#define EX_FALSE 40
#define EX_BYTE 44
void ReadInt(unsigned char*& Code, unsigned int& output) {
output = *reinterpret_cast<int*>(Code);
Code += sizeof(output);
Code++;
}
void ReadFloat(unsigned char*& Code, float& output) {
output = *reinterpret_cast<float*>(Code);
Code += sizeof(output); // Move pointer forward by the size of a float
Code++;
}
void ReadByte(unsigned char*& Code, unsigned char& output) {
output = *Code;
Code += 2;
}
void ReadBool(unsigned char*& Code, bool& output) {
switch (*Code) {
case EX_TRUE:
output = true;
break;
case EX_FALSE:
output = false;
break;
}
Code++;
}
void ReadString(unsigned char*& Code, std::string& output) {
// Ensure codePtr is valid
if (Code)
{
// Extract the null-terminated string
while (*Code != '\0')
{
output += static_cast<char>(*Code);
Code++; // Move to the next byte
}
// Increment past the null terminator
Code++;
}
}
// Grab string as reference when possible.
#define P_GET_STR_LOCAL(var, code) \
if (*Stack.Code == EX_LocalVariable || *Stack.Code == EX_InstanceVariable) \
{ \
Stack.Step(Stack.Object, nullptr); \
const FString& var = *reinterpret_cast<FString*>(GPropAddr); \
code; \
} \
else \
{ \
FString var; \
Stack.Step(Stack.Object, &var); \
code; \
}
/*----------------------------------------------------------------------------
Global variables.
----------------------------------------------------------------------------*/
// Core globals.
CORE_API extern FMemStack GMem;
CORE_API extern FOutputDevice* GLog;
CORE_API extern FOutputDevice* GNull;
CORE_API extern FOutputDevice* GThrow;
CORE_API extern FOutputDeviceError* GError;
CORE_API extern FFeedbackContext* GWarn;
CORE_API extern FConfigCache* GConfig;
CORE_API extern FTransactionBase* GUndo;
CORE_API extern FOutputDevice* GLogHook;
CORE_API extern FExec* GExec;
CORE_API extern FMalloc* GMalloc;
CORE_API extern FFileManager* GFileManager;
CORE_API extern USystem* GSys;
CORE_API extern UObject* GNetObject;
CORE_API extern UProperty* GProperty;
CORE_API extern BYTE* GPropAddr;
CORE_API extern USubsystem* GWindowManager;
CORE_API extern TCHAR GErrorHist[4096];
CORE_API extern TCHAR GTrue[64], GFalse[64], GYes[64], GNo[64], GNone[64], GIni[256];
CORE_API extern TCHAR GCdPath[];
CORE_API extern FLOAT GSecondsPerCycle;
CORE_API extern DOUBLE GSecondsPerCycleLong;
CORE_API extern DOUBLE GPerformanceFrequency;
CORE_API extern FTime GTempTime;
CORE_API extern void (*GTempFunc)(void*);
CORE_API extern SQWORD GTicks;
CORE_API extern INT GScriptCycles;
CORE_API extern DWORD GPageSize;
CORE_API extern INT GProcessorCount;
CORE_API extern QWORD GPhysicalMemory;
CORE_API extern DWORD GUglyHackFlags;
CORE_API extern UBOOL GIsScriptable;
CORE_API extern UBOOL GIsEditor;
CORE_API extern UBOOL GIsClient;
CORE_API extern UBOOL GIsServer;
CORE_API extern UBOOL GIsCriticalError;
CORE_API extern UBOOL GIsStarted;
CORE_API extern UBOOL GIsRunning;
CORE_API extern UBOOL GIsSlowTask;
CORE_API extern UBOOL GIsGuarded;
CORE_API extern UBOOL GIsRequestingExit;
CORE_API extern UBOOL GIsStrict;
CORE_API extern UBOOL GIsCollectingGarbage;
CORE_API extern UBOOL GScriptEntryTag;
CORE_API extern UBOOL GLazyLoad;
CORE_API extern UBOOL GSafeMode;
CORE_API extern UBOOL GIsSetupMode;
CORE_API extern UBOOL GUnicode;
CORE_API extern UBOOL GUnicodeOS;
CORE_API extern UBOOL GIsUTracing;
CORE_API extern UBOOL GUseTransientNames;
CORE_API extern UBOOL GIsDemoPlayback;
CORE_API extern UBOOL GIsUCC; // Currently running on UCC commandline enviroment.
CORE_API extern UBOOL GEnableRunAway;
//CORE_API extern UBOOL GIsOnStrHack;
CORE_API extern class FGlobalMath GMath;
CORE_API extern URenderDevice* GRenderDevice;
CORE_API extern class FArchive* GDummySave;
CORE_API extern UViewport* GCurrentViewport;
// Shambler
CORE_API extern UBOOL GDuplicateNames;
CORE_API extern UBOOL GAntiTCC; // Prevents temporary console commands...i.e. online use of set command on non-config variables
CORE_API extern UBOOL GTCCUsed;
CORE_API extern UBOOL GScriptHooksEnabled;
CORE_API extern class GameCacheFolderIni* GCacheFolderIni;
CORE_API extern UINT GFrameNumber; // Current frame number, increased every tick.
CORE_API extern DWORD GMessageTime; // Msg.time for the last message we received from the message queue
#ifdef UTPG_MD5
CORE_API extern UZQ5Gnoyr* TK5Ahisl; // MD5Table
CORE_API extern UBOOL ForceMD5Calc;
CORE_API extern UBOOL DisableMD5;
CORE_API extern UObject* MD5NotifyObject;
#endif
В другой теме это уже обсуждали и объясняли. Но не помню показывали ли рабочие примеры со строками.I've just took FString implementation from publicly available Interlude SDK v746. It works very nice, now I'm trying to figure out, how I can pass data back to unreal script.
ExecuteUIEvent не экспортируемая функция. Нужно найти ее offset и вызывать по адресу. Адрес легко найти, используя ghidra/ida или отладчик.they found address of `XMLUIManager::ExecuteUIEvent` but I'm not able to find that function, it's probably dynamically created somewhere inside nwindow.dll
// initXMLUIManager
fExecuteUIEvent = (ExecuteUIEvent_fn)(nwindowBaseAddr + 0xd1790);
// typedef и fGetXMLUIManagerPtr сделайте сами
void Client::CallExecuteUIEvent(int eventID, const wchar_t* strParam)
{
if (fExecuteUIEvent == nullptr) {
initXMLUIManager();
}
FString param(strParam);
fExecuteUIEvent(fGetXMLUIManagerPtr(), eventID, ¶m);
}
local string test;
test = "Hello from UC!";
SomeDllFunction(test);
У меня такая же проблема.А если строка "Hello from UC!" находится как переменная а не константа? Проблема в том, что переменные не работают. Как их читать из .длл?
Код:local string test; test = "Hello from UC!"; SomeDllFunction(test);
function sendRequestToServer(optional int shotID, optional int _type)
{
local string zParam, test;
if (shotID <= 0 || _type != 0 && _type != 1) {
return;
}
RequestAutoSoulShot(shotID, _type);
if( _type == 1 )
{
ActivateAnimation(zParam);
}
return;
}
#include "pch.h"
#include <Windows.h>
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <iomanip>
using namespace std;
#define EX_INT 29
#define EX_FLOAT 30
#define EX_STRING 31
#define EX_TRUE 38
#define EX_FALSE 37
#define EX_BYTE 44
template <class T>
struct TArray
{
friend struct FString;
public:
inline TArray()
{
Data = nullptr;
Count = Max = 0;
};
inline TArray(const size_t size)
{
Data = new T[size];
Count = 0;
Max = static_cast<int32_t>(size); // Defina o tamanho máximo corretamente
};
inline void Add(T value)
{
if (Count < Max) { // Certifique-se de que não exceda o limite
Data[Count++] = value;
}
}
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];
}
void Restart() {
Count = 0;
}
// Getter para o tamanho máximo
inline int32_t GetMax() const
{
return Max;
}
private:
T* Data;
int32_t Count;
int32_t Max;
};
struct FString : private TArray<wchar_t>
{
FString() = default;
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;
}
std::wstring ToWString() const
{
return std::wstring(c_str());
}
};
class UObject {};
struct FFrame
{
public:
int* ftable;
void* Node;
UObject* Object;
BYTE* Code;
BYTE* Locals;
INT LineNum;
inline INT ReadIntLocal() {
INT Result;
Result = *(INT*)Locals;
Locals += sizeof(INT) + 1;
return Result;
}
inline INT ReadInt() {
INT Result;
Result = *(INT*)Code;
Code += sizeof(INT)+1;
return Result;
}
inline void SkipByte() {
++Code;
}
inline void SkipBytes(const INT Count) {
Code += Count;
}
inline BYTE ReadByte() {
return *Code++;
}
inline bool ReadBool() {
bool Result = false; // Inicializa com false por padrão
switch (*Code) {
case EX_TRUE:
Result = true;
break;
case EX_FALSE:
Result = false;
break;
}
Code++;
return Result;
}
inline INT ReadLocalInt() {
INT Result;
Result = *(INT*)Locals;
Locals += sizeof(INT) + 1;
return Result;
}
};
#define RESULT_DECL void*const Result
typedef void(__stdcall* Native)(FFrame&, void* const);
typedef BYTE(__cdecl* GRegisterNative_fnType)(INT iNative, const Native& Func);
void __stdcall functionUC(struct FFrame& Stack, RESULT_DECL)
{
std::ofstream codeFile("code_bytes.txt", std::ios::out);
std::ofstream localsFile("locals_bytes.txt", std::ios::out);
if (!codeFile.is_open() || !localsFile.is_open()) {
MessageBox(nullptr, L"Erro ao abrir os arquivos", L"Erro", MB_OK);
return;
}
std::wstringstream debugMessage;
debugMessage << L"Bytes em Code e Locals:\n";
int maxBytesToRead = 90;
int bytesRead = 0;
while (bytesRead < maxBytesToRead) {
BYTE codeByte = Stack.ReadByte();
BYTE localsByte = *Stack.Locals++;
debugMessage << L"Code: 0x"
<< std::hex << std::setw(2) << std::setfill(L'0')
<< static_cast<int>(codeByte)
<< L" Locals: 0x"
<< std::hex << std::setw(2) << std::setfill(L'0')
<< static_cast<int>(localsByte)
<< L"\n";
codeFile << "0x"
<< std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(codeByte) << " ";
localsFile << "0x"
<< std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(localsByte) << " ";
if ((bytesRead + 1) % 16 == 0) {
codeFile << "\n";
localsFile << "\n";
}
bytesRead++;
}
codeFile.close();
localsFile.close();
MessageBox(nullptr, debugMessage.str().c_str(), L"Bytes", 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(3003, &functionUC);
}
}
}
extern "C" __declspec(dllexport)
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hinstDLL);
CreateThread(0, 0, LPTHREAD_START_ROUTINE(hookCore), 0, 0, 0);
}
if (fdwReason == DLL_PROCESS_DETACH) {}
if (fdwReason == DLL_THREAD_ATTACH) {}
if (fdwReason == DLL_THREAD_DETACH) {}
return true;
}
0x00 0x80 0xf6 0x65 0x06 0x00 0x00 0x4c 0x61 0x06 0x16 0x1b 0x7d 0x2c 0x00 0x00
0x00 0x80 0x5a 0x68 0x06 0x1f 0x53 0x68 0x6f 0x74 0x49 0x44 0x00 0x39 0x53 0x00
0x80 0xf6 0x65 0x06 0x16 0x1b 0x7d 0x2c 0x00 0x00 0x00 0x80 0x5a 0x68 0x06 0x1f
0x62 0x45 0x6e 0x61 0x62 0x6c 0x65 0x00 0x39 0x53 0x00 0x00 0x4c 0x61 0x06 0x16
0x07 0xcf 0x00 0x9a 0x00 0x00 0x4c 0x61 0x06 0x26 0x16 0x1b 0xd2 0xd9 0x00 0x00
0x00 0x80 0x5a 0x68 0x06 0x16 0x04 0x0b 0x04 0x0b
У меня такая же проблема.
.uc
C++:function sendRequestToServer(optional int shotID, optional int _type) { local string zParam, test; if (shotID <= 0 || _type != 0 && _type != 1) { return; } RequestAutoSoulShot(shotID, _type); if( _type == 1 ) { ActivateAnimation(zParam); } return; }
my dll:
C++:#include "pch.h" #include <Windows.h> #include <iostream> #include <string> #include <sstream> #include <fstream> #include <iomanip> using namespace std; #define EX_INT 29 #define EX_FLOAT 30 #define EX_STRING 31 #define EX_TRUE 38 #define EX_FALSE 37 #define EX_BYTE 44 template <class T> struct TArray { friend struct FString; public: inline TArray() { Data = nullptr; Count = Max = 0; }; inline TArray(const size_t size) { Data = new T[size]; Count = 0; Max = static_cast<int32_t>(size); // Defina o tamanho máximo corretamente }; inline void Add(T value) { if (Count < Max) { // Certifique-se de que não exceda o limite Data[Count++] = value; } } 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]; } void Restart() { Count = 0; } // Getter para o tamanho máximo inline int32_t GetMax() const { return Max; } private: T* Data; int32_t Count; int32_t Max; }; struct FString : private TArray<wchar_t> { FString() = default; 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; } std::wstring ToWString() const { return std::wstring(c_str()); } }; class UObject {}; struct FFrame { public: int* ftable; void* Node; UObject* Object; BYTE* Code; BYTE* Locals; INT LineNum; inline INT ReadIntLocal() { INT Result; Result = *(INT*)Locals; Locals += sizeof(INT) + 1; return Result; } inline INT ReadInt() { INT Result; Result = *(INT*)Code; Code += sizeof(INT)+1; return Result; } inline void SkipByte() { ++Code; } inline void SkipBytes(const INT Count) { Code += Count; } inline BYTE ReadByte() { return *Code++; } inline bool ReadBool() { bool Result = false; // Inicializa com false por padrão switch (*Code) { case EX_TRUE: Result = true; break; case EX_FALSE: Result = false; break; } Code++; return Result; } inline INT ReadLocalInt() { INT Result; Result = *(INT*)Locals; Locals += sizeof(INT) + 1; return Result; } }; #define RESULT_DECL void*const Result typedef void(__stdcall* Native)(FFrame&, void* const); typedef BYTE(__cdecl* GRegisterNative_fnType)(INT iNative, const Native& Func); void __stdcall functionUC(struct FFrame& Stack, RESULT_DECL) { std::ofstream codeFile("code_bytes.txt", std::ios::out); std::ofstream localsFile("locals_bytes.txt", std::ios::out); if (!codeFile.is_open() || !localsFile.is_open()) { MessageBox(nullptr, L"Erro ao abrir os arquivos", L"Erro", MB_OK); return; } std::wstringstream debugMessage; debugMessage << L"Bytes em Code e Locals:\n"; int maxBytesToRead = 90; int bytesRead = 0; while (bytesRead < maxBytesToRead) { BYTE codeByte = Stack.ReadByte(); BYTE localsByte = *Stack.Locals++; debugMessage << L"Code: 0x" << std::hex << std::setw(2) << std::setfill(L'0') << static_cast<int>(codeByte) << L" Locals: 0x" << std::hex << std::setw(2) << std::setfill(L'0') << static_cast<int>(localsByte) << L"\n"; codeFile << "0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(codeByte) << " "; localsFile << "0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(localsByte) << " "; if ((bytesRead + 1) % 16 == 0) { codeFile << "\n"; localsFile << "\n"; } bytesRead++; } codeFile.close(); localsFile.close(); MessageBox(nullptr, debugMessage.str().c_str(), L"Bytes", 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(3003, &functionUC); } } } extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hinstDLL); CreateThread(0, 0, LPTHREAD_START_ROUTINE(hookCore), 0, 0, 0); } if (fdwReason == DLL_PROCESS_DETACH) {} if (fdwReason == DLL_THREAD_ATTACH) {} if (fdwReason == DLL_THREAD_DETACH) {} return true; }
Когда я отправляю значения напрямую в свою функцию, например: RequestAutoSoulShot(3952, 1), я могу прочитать первый байт, определить, что это 1 int, и прочитать следующие 4 байта, которые являются ID моего SoulShot, а следующий байт — это 37 = 0 или 38 = true. Но когда я отправляю переменные, этот сценарий меняется, и первый байт всегда будет 0x00, чтобы указать локальную переменную.
Код:0x00 0x80 0xf6 0x65 0x06 0x00 0x00 0x4c 0x61 0x06 0x16 0x1b 0x7d 0x2c 0x00 0x00 0x00 0x80 0x5a 0x68 0x06 0x1f 0x53 0x68 0x6f 0x74 0x49 0x44 0x00 0x39 0x53 0x00 0x80 0xf6 0x65 0x06 0x16 0x1b 0x7d 0x2c 0x00 0x00 0x00 0x80 0x5a 0x68 0x06 0x1f 0x62 0x45 0x6e 0x61 0x62 0x6c 0x65 0x00 0x39 0x53 0x00 0x00 0x4c 0x61 0x06 0x16 0x07 0xcf 0x00 0x9a 0x00 0x00 0x4c 0x61 0x06 0x26 0x16 0x1b 0xd2 0xd9 0x00 0x00 0x00 0x80 0x5a 0x68 0x06 0x16 0x04 0x0b 0x04 0x0b
То есть, в локальных переменных я могу извлечь только первую локальную переменную, а остальное, как я полагаю, является ссылкой в памяти. Но я понятия не имею, как это извлечь. Кто-нибудь сталкивался с этим? Кто-нибудь может помочь решить? Я готов заплатить.
function sendRequestToServer(optional int shotID, optional int _type)
{
local string zParam, test;
local int shotID2, type2
if (shotID <= 0 || _type != 0 && _type != 1) {
return;
}
test = "ASDASDASDASD";
shotID2 = shotID;
type2 = _type;
RequestAutoSoulShot(shotID2, type2);
if( _type == 1 )
{
ActivateAnimation(zParam);
}
return;
}