【UE4逆向】ProcessEvent调用操作UI函数时的错误

错误:

`Assertion failed: IsInGameThread() || IsInSlateThread() [File:D:/UnrealEngines/UnrealEngine/Engine/Source/Runtime/SlateCore/Private/Widgets/SWidget.cpp] [Line: 1119] Slate can only be accessed from the GameThread or the SlateLoadingThread!

JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
JH_Win64_Shipping
UE4_ProcessEvent!JhSDK::UObject::ProcessEvent() [D:\项目\UE4_ProcessEvent\UE4_ProcessEvent\JhSDK.h:545]
UE4_ProcessEvent!JhSDK::UItemManager::AddItem() [D:\项目\UE4_ProcessEvent\UE4_ProcessEvent\JhSDK.h:1316]
UE4_ProcessEvent!HackThread() [D:\项目\UE4_ProcessEvent\UE4_ProcessEvent\dllmain.cpp:72]`

解释:这个错误信息指出在尝试访问 Unreal Engine 的 Slate UI 系统时违反了线程安全规则。Slate UI 组件只能在游戏线程(GameThread)或 Slate 加载线程(SlateLoadingThread)上被访问或修改。

在你的代码中,你似乎在一个名为 HackThread 的线程中调用了与 Slate 相关的代码(可能是通过 JhSDK::UItemManager::AddItem() 方法),而这个线程并不是 Unreal Engine 所允许的线程之一。

解决方法:

1. 使用FTimerDelegate

FTimerDelegate 可以用于在指定的延迟后执行一个委托(delegate),并且这个执行是在游戏线程上进行的。虽然这不是直接的消息队列,但它可以作为一种延迟执行任务的方式。

FTimerHandle timerHandle;  
GetWorld()->GetTimerManager().SetTimer(  
    timerHandle,  
    FTimerDelegate::CreateLambda([&]()  
    {  
        // 这里是你要在游戏线程上执行的代码  
    }),  
    0.0f,  // 立即执行  
    false  // 不重复  
);

2.Hook FEngineLoop::Tick

该函数在游戏主线程内,负责处理游戏逻辑、用户输入、物理模拟、动画更新等核心游戏功能。它也是其他线程的数据发起者,并在每帧的更新中执行逻辑更新。
特征:
x64dbg搜索

Tick loop starting

3.Hook PostRender

typedef void(__fastcall* tPostRender)(JhSDK::UGameViewportClient* viewport_client, JhSDK::UCanvas* canvas);
static tPostRender hkPostRender = nullptr;

void RenderText(JhSDK::UCanvas* Canvas,JhSDK::FVector2D Position,JhSDK::FString text,JhSDK::FLinearColor color) {
    
    Canvas->K2_DrawText(engine_font, text, Position, {1.f,1.f}, color, false, {0.0f,0.0f,0.0f,1.f}, {0.0f,0.0f}, false, false, true, color);
}

void HookedPostRender(JhSDK::UGameViewportClient* viewport_client, JhSDK::UCanvas* canvas)
{
    RenderText(canvas, { 150.f,150.f }, L"[#] Hello From PostRender", { 1.f,0.0f,1.f,1.f });

    if (GetAsyncKeyState(VK_F1) & 1) {
        ManagerFuncLib->ItemManager->AddItem(1, 1, JhSDK::EItemRandPoolType::Normal);
    }

    return hkPostRender(viewport_client, canvas);
}

    auto localPlayer = (*JhSDK::m_UWorld)->PersistentLevel->OwningWorld->
        OwningGameInstance->LocalPlayers.Data[0];
        
    world_peh.ApplyHook((uintptr_t)localPlayer->ViewportClient, (std::uintptr_t*)&hkPostRender, (std::uintptr_t)HookedPostRender,0x62);

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值