将 C# 代码注入另一个进程并调用目标函数
inject C# code to another process and call target functions
我正在尝试通过代码注入调用游戏函数。经过一番尝试,我找到了一个可以满足我要求的 dll。
所以我用 ILSpy 看到了 dll,但无法理解代码。
class <Module>
{
[SecurityCritical, SuppressUnmanagedCodeSecurity]
[DllImport("", CallingConvention = CallingConvention.ThisCall, SetLastError = true)]
[MethodImpl(MethodImplOptions.Unmanaged)]
internal unsafe static extern float* GetHealth(AttackableUnit*);
}
--------------------------
namespace Native
{
[NativeCppClass]
[StructLayout(LayoutKind.Sequential, Size = 1)]
internal struct AttackableUnit
{
}
}
---------------------
public unsafe float MaxHealth
{
get
{
Native.AttackableUnit* ptr = (Native.AttackableUnit*)base.GetPtr();
if (ptr != null)
{
return *<Module>.Native.AttackableUnit.GetMaxHealth(ptr);
}
return 0f;
}
}
dll 似乎使用 c++ dll 和目标中的 bootstrap .net 将 c# 代码注入目标应用程序。
现在我不明白
是什么意思
[DllImport("", CallingConvention = CallingConvention.ThisCall,
SetLastError = true)]
为什么文件路径是空的?
dll如何管理class和函数调用?我的意思是程序员使用什么技术?
编辑:
我想了解的图书馆名称是 Elobuddy 也许有帮助。
为避免开门见山,C# 语言未参与生成此程序集。您看到的是 C++/CLI 项目的输出。一个 混合模式 程序集,它包含 MSIL 和本机代码。您将使用 File > New > Project > Visual C++ > CLR > Class Library.
生成类似的程序集
作者可能更喜欢它来解决CLR注入问题。不可能将纯托管 DLL 注入另一个进程,必须先加载和初始化 CLR,然后才能执行任何托管代码。一个先有鸡还是先有蛋的问题,需要反向调用(本机代码调用托管代码),这与 [DllImport] 所做的相反。 C++/CLI 使这变得非常简单,我在 this answer 中描述了该技术。 Unmanaged Exports 实用程序很流行 (google DllExport),它是一种程序集重写器,使用与 C++/CLI 使用的技术相同的技术。
但作者也想使用原生C++代码来实现游戏破解。他使用的是纯原生 DLL,其中包含 GetHealth() 函数和 AttackableUnit class 定义。这个 DLL 由 OS 加载器隐式加载,就像 DLL 通常那样,[DllImport] 属性的空字符串就足够了。否则必要时,编译器无法知道哪个 DLL 具有此本机代码,只有在链接器运行并使用本机 DLL 的导入库时才会将其整理出来。
C++/CLI 编译器为代码中的纯本机构造发出元数据有点过头了。但尽最大努力使它们看起来尽可能像它们的托管等效项。请注意它非常不完整,例如,您看不到 AttackableUnit C++ class 成员的名称。您会在程序集中发现 lot 其他内容,许多 CRT 声明也将其放入元数据中。本机链接器并没有很好地隐藏它。主要是因为不需要,这段代码很好地隔离到内部 <Module>
class.
将 GetHealth 等本机函数的机器代码反编译回原始 C++ 代码通常是不可能的。特别是内置于编译器后端的优化器做得非常出色,几乎不可能猜测原始代码可能是什么样子。 Hex-Rays 通常被称为机器代码反编译器,它至少可以正确识别代码与数据。
我正在尝试通过代码注入调用游戏函数。经过一番尝试,我找到了一个可以满足我要求的 dll。
所以我用 ILSpy 看到了 dll,但无法理解代码。
class <Module>
{
[SecurityCritical, SuppressUnmanagedCodeSecurity]
[DllImport("", CallingConvention = CallingConvention.ThisCall, SetLastError = true)]
[MethodImpl(MethodImplOptions.Unmanaged)]
internal unsafe static extern float* GetHealth(AttackableUnit*);
}
--------------------------
namespace Native
{
[NativeCppClass]
[StructLayout(LayoutKind.Sequential, Size = 1)]
internal struct AttackableUnit
{
}
}
---------------------
public unsafe float MaxHealth
{
get
{
Native.AttackableUnit* ptr = (Native.AttackableUnit*)base.GetPtr();
if (ptr != null)
{
return *<Module>.Native.AttackableUnit.GetMaxHealth(ptr);
}
return 0f;
}
}
dll 似乎使用 c++ dll 和目标中的 bootstrap .net 将 c# 代码注入目标应用程序。
现在我不明白
是什么意思[DllImport("", CallingConvention = CallingConvention.ThisCall, SetLastError = true)]
为什么文件路径是空的? dll如何管理class和函数调用?我的意思是程序员使用什么技术?
编辑: 我想了解的图书馆名称是 Elobuddy 也许有帮助。
为避免开门见山,C# 语言未参与生成此程序集。您看到的是 C++/CLI 项目的输出。一个 混合模式 程序集,它包含 MSIL 和本机代码。您将使用 File > New > Project > Visual C++ > CLR > Class Library.
生成类似的程序集作者可能更喜欢它来解决CLR注入问题。不可能将纯托管 DLL 注入另一个进程,必须先加载和初始化 CLR,然后才能执行任何托管代码。一个先有鸡还是先有蛋的问题,需要反向调用(本机代码调用托管代码),这与 [DllImport] 所做的相反。 C++/CLI 使这变得非常简单,我在 this answer 中描述了该技术。 Unmanaged Exports 实用程序很流行 (google DllExport),它是一种程序集重写器,使用与 C++/CLI 使用的技术相同的技术。
但作者也想使用原生C++代码来实现游戏破解。他使用的是纯原生 DLL,其中包含 GetHealth() 函数和 AttackableUnit class 定义。这个 DLL 由 OS 加载器隐式加载,就像 DLL 通常那样,[DllImport] 属性的空字符串就足够了。否则必要时,编译器无法知道哪个 DLL 具有此本机代码,只有在链接器运行并使用本机 DLL 的导入库时才会将其整理出来。
C++/CLI 编译器为代码中的纯本机构造发出元数据有点过头了。但尽最大努力使它们看起来尽可能像它们的托管等效项。请注意它非常不完整,例如,您看不到 AttackableUnit C++ class 成员的名称。您会在程序集中发现 lot 其他内容,许多 CRT 声明也将其放入元数据中。本机链接器并没有很好地隐藏它。主要是因为不需要,这段代码很好地隔离到内部 <Module>
class.
将 GetHealth 等本机函数的机器代码反编译回原始 C++ 代码通常是不可能的。特别是内置于编译器后端的优化器做得非常出色,几乎不可能猜测原始代码可能是什么样子。 Hex-Rays 通常被称为机器代码反编译器,它至少可以正确识别代码与数据。