如何基于第三方MSVC进程内实例地址获取对应RTTI类名(C#实现)
跨进程获取MSVC编译程序RTTI类名实现方案
步骤1核心实现逻辑(你当前卡住的环节)
MSVC编译的带虚函数的C++类实例,内存首地址固定存储虚函数表指针(vftable ptr),RTTI元数据就绑定在虚表的前置偏移位置,对应规则如下:
- 32位目标进程:虚表地址向前偏移
0x4字节,存储的是RTTICompleteObjectLocator结构体的直接指针 - 64位目标进程:虚表地址向前偏移
0x8字节,存储的是RTTICompleteObjectLocator相对于虚表地址的32位有符号偏移,实际地址计算公式为虚表地址 + 读取到的偏移值
你可以直接通过ReadProcessMemoryAPI跨进程读取对应位置的内存数据,即可拿到RTTI定位器地址,完成步骤1的需求。
完整实现流程
- 调用
ReadProcessMemory读取传入的实例地址StructAddress处的指针值,得到虚表地址 - 按照目标进程位数,计算并读取
RTTICompleteObjectLocator结构体地址 - 读取定位器中指向
TypeDescriptor的指针,TypeDescriptor偏移0x14的位置存储的就是MSVC修饰后的类名字符串 - 可选:调用
UnDecorateSymbolName系统API,将修饰名还原为可读性更高的原始类名
C#开发注意点
// ReadProcessMemory API 导入示例 [DllImport("kernel32.dll", SetLastError = true)] public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
- 提前通过
IsWow64Process等API判断目标进程的架构,不要硬编码指针长度,不同架构的偏移计算逻辑完全不同 - 跨进程读取字符串时,需要逐字节读取直到遇到
\0终止符,MSVC默认RTTI类名采用ANSI编码 - 访问内存前建议做有效性校验,避免读取非法地址导致程序崩溃
内容的提问来源于stack exchange,提问作者TheLeftExit
相关产品推荐
相关产品推荐

