【问题标题】:Return function int64 C++ to a C# project将函数 int64 C++ 返回到 C# 项目
【发布时间】:2019-04-13 22:31:57
【问题描述】:

我编写了一个在游戏中注入的 dll,并在服务器上返回我的 localplayer 和 listArrayplayer。好的,工作正常 代码dll项目: C++代码:

__int64 RerturnLocalPlayer() {

    __int64 player = GetLocalPlayer_EX();// __Int64 GetLocalPlayer_EX() is a function that return type __int64 value
    return player;
}

在 main.h 中:

extern "C" {

__declspec(dllexport) __int64 RerturnLocalPlayer();

}

mt 函数

extern "C" {
    __declspec(dllexport) __int64  GetLocalPlayer_EX()
    {
        DWORD64 pClientGameContext = *(DWORD64*)OFFSET_CLIENTGAMECONTEXT;
        if (!(pClientGameContext)) return 0;
        DWORD64 pPlayerManager = *(DWORD64*)(pClientGameContext + 0x68);
        if (!(pPlayerManager)) return 0;

        DWORD64 pObfuscationMgr = *(DWORD64*)OFFSET_ObfuscationMgr;
        if (!(pObfuscationMgr)) return 0;

        DWORD64 LocalPlayerListXorValue = *(DWORD64*)((DWORD64)pPlayerManager + 0xF0);
        DWORD64 LocalPlayerListKey = LocalPlayerListXorValue ^ *(DWORD64 *)(pObfuscationMgr + 0x70);
        hashtable<DWORD64>* table = (hashtable<DWORD64>*)(pObfuscationMgr + 8);
        hashtable_iterator<DWORD64> iterator = { 0 };

        hashtable_find(table, &iterator, LocalPlayerListKey);
        if (iterator.mpNode == table->mpBucketArray[table->mnBucketCount])
            return 0;

        DWORD64 EncryptedPlayerMgr = (DWORD64)iterator.mpNode->mValue.second;
        if (!(EncryptedPlayerMgr)) return 0;

        DWORD MaxPlayerCount = *(DWORD *)(EncryptedPlayerMgr + 0x18);
        if (MaxPlayerCount != 1) return 0;

        return EncryptedPlayerMgr__GetPlayer(EncryptedPlayerMgr, 0);
    }
}

C#代码:

[System.Runtime.InteropServices.DllImportAttribute("BFClient1.dll", EntryPoint = "RerturnLocalPlayer",
CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
public static extern Int64 RerturnLocalPlayer();                    
Int64 localp = NativeMemory.Read<Int64> (RerturnLocalPlayer());

 Console.WriteLine("LocalPlayer " + localp.ToString("X"));

问题是当我运行我的 c# 应用程序时,我的控制台打开并在 3 秒后关闭,有时会出现错误:**尝试读取或写入受保护的内存。通常,这表明另一个内存已损坏。

有人可以帮我吗?

【问题讨论】:

  • NativeMemory.Read 将函数的返回值解释为 pointer 指向 int64 值并读取它指向的值。如果真的是这样?
  • 请注意,如果您的本机库编译为 x86(32 位)代码,您的调用约定可能不匹配(您的 P/Invoke 声明了 stdcall 调用约定,但您编译的 C++ 函数导出很可能使用 cdecl 调用约定。)修复/避免此类情况的建议建议:在 main.h 中显式声明导出的 C/C++ 函数的调用约定,然后使用相同的调用约定在您的 P/Invoke 声明中。
  • Klaus Gütter 是的,是一个读取 int64 的函数,但我不需要这个函数。

标签: c# c++ c++11 visual-c++ c#-4.0


【解决方案1】:

__int64 RerturnLocalPlayer() 是一个通过某种调用约定返回 64 位值的函数。你好像以为是stdcall,我觉得你错了。但是我没有你的源代码,所以你可以自己用头撞墙。

public static extern Int64 RerturnLocalPlayer(); 是正确的定义(同样,除了调用约定,32 位 CPU 上没有 64 位寄存器,因此不会是 stdcall)。

但是,Int64 localp = NativeMemory.Read&lt;Int64&gt; (RerturnLocalPlayer()); 简直就是疯子。您已经直接从编组器获取整数作为返回值,就这样使用它!这将是调用函数的正确方法:

Int64 localp = RerturnLocalPlayer();

【讨论】:

  • @CerraossoUC,好吗?还是有问题吗?你试过我的建议了吗?我仍然在您更新的代码中看到相同的本机内存读取调用。
  • 是的,我忘记从描述中删除 nativememory,但我尝试了 Int64 localp = RerturnLocalPlayer();但有同样的问题没有发生并关闭我的应用程序。是的,我从 StdCall) 更改为 CallingConvention.Cdecl)。 =/
猜你喜欢
  • 2012-01-04
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
相关资源
最近更新 更多