强制转换内存位置以获取字符串
Casting memory location to get String
我正在尝试从 Win32 应用程序访问一个变量,该应用程序具有基于源代码的已知变量:
Foo foo; // Class foo
foo.mystring = "All your base are belong to us"; // where this is defined as: 'string mystring'
现在我尝试使用反汇编器拆卸 PE,我找到了这个
.rdata:00446074 aAllYourBaseAre db 'all your base are belong to us',0
现在我有另一个 win32 进程,它获取具有我需要的类变量的前 win32 应用程序的图像基址。
我使用以下代码获取进程地址:
HMODULE parent = ::GetModuleHandle(NULL);
if (parent) {
const BYTE* imageBase = reinterpret_cast<const BYTE*> ( parent );
const char* strMemberValue = *reinterpret_cast<const char**>((unsigned char*)imageBase + 0x00446074);
std::cout << "Value=" << strMemberValue;
}
父级是我试图访问的进程。我还测试了父级是正确的过程。问题是,当我尝试通过强制转换基址 + 偏移量来获取字符串时,我无法获得任何东西。
编辑:
我错过了我的观点。我无法重新编译目标 Win32 应用程序,它已经在生产中。但是,我需要访问该可执行文件上的一些变量。我在这里的代码只是一个概念验证**
我也在做"DLL注入"
调试:
由于类是带有方法的结构,因此我假设我使用 IDAPro 挖掘的这段代码是Foo
的类定义
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 ; (Class Informer)
00000000 type_info struc ; (sizeof=0x8, variable size)
00000000 vftable dd ? ; offset (00000000)
00000004 _m_data dd ?
00000008 _m_d_name db 0 dup(?) ; string(C)
00000008 type_info ends
00000008
00000000 ; ---------------------------------------------------------------------------
但是,我仍然不确定这一点。
您通过双间接寻址以错误的方式访问进程内存。 .rdata:00446074
是字符串所在的地址,而不是指向实际位置的指针。您应该像这样访问它:
HMODULE parent = ::GetModuleHandle(NULL);
if (parent) {
const BYTE* imageBase = reinterpret_cast<const BYTE*> ( parent );
const char* strMemberValue = (const char *)imageBase + 0x00446074;
std::cout << "Value=" << strMemberValue;
}
此外,您是否确定反汇编程序将映像基于0x0
而不是默认PE基址0x00400000
,在这种情况下,字符串的RVA将是0x00046074
而不是0x00446074
。此外,这是用于初始化成员变量的字符串常量,而不是变量本身。
好的,首先要注意的是:在使用外来进程内存时,如果您重新编译其他可执行文件,您可能再也找不到任何数据。链接器可以自由地将数据和代码放置在任何位置并重新排列。要重新查找某些值或函数,您必须搜索二进制模式。
接下来要注意的是:您实际上有一个成员变量。这意味着每个对象的内容实际上可能不同。您当前正在搜索默认分配给它的字符串(而不是直接分配给成员,而是在 std::string 类中的某个位置)。
最后但并非最不重要的一点是:当您尝试访问外部进程的内容时,您必须使用ReadProcessMemory。不过,请考虑使用共享内存进行进程间通信。命名管道也可以。
访问实际值的最简单方法是将Foo
对象的地址(例如&foo
)传递给读取过程,并将Foo
类放在两个项目都可以访问的公共项目库中。然后将整个对象读入地址空间(请参阅上面的ReadProcessMemory
),并像访问任何其他成员一样访问该成员。请注意,您实际处理的是真实对象的副本。共享内存可以使单个对象可访问两个进程(创建文件映射)
- 获取字符串的长度并将其分配给数组
- 调用CreateProcess()并获取字符串的返回值
- 你如何从 Boost Spirit X3 词法解析器中获取字符串?
- 使用 ReadProcessMemory 获取字符串值的访问冲突
- 如何从输入中获取字符串向量?
- 如何获取字符串输入n次?
- property_tree获取字符串形式的数组值
- 使用 ctypes 和 wchar_t 时如何从 C++ 获取字符串到 python?
- 获取字符串大小的各种方法之间的比较
- 方法获取字符串
- 在getline()之后获取字符串
- 为什么我的拆卸C 代码使用指令指针和偏移来获取字符串文字
- 无法使用 Poco 获取字符串的路径
- 如何在qtablewidget中获取字符串的行号
- 如何获取字符串和字节进行比较
- 恒定字符阵列的获取字符串长度函数(strlen)不是恒定表达式
- 我需要创建一个函数来获取字符串中的这些数字
- 如何从地址获取字符串?
- 为什么即使尚未初始化,获取字符串[0]也是有效的?
- 获取C++字符串的位