【发布时间】: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