我是新手,我做了以下实验只是为了帮助我理解。我创建了一个非常简单的64位c ++程序。

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char* argv[])
{
    string s1{ "test" };
    cout << s1 << endl;
    cout << &s1 << endl;

    cout << "============" << endl;

    int i{ 10 };
    cout << i << endl;
    cout << &i << endl;

    getchar();
}


然后编译并启动了它。输出为:



现在我知道这两个变量的地址,我想在x64dbg中对其进行检查。在x64dbg中,我附加了正在运行的进程,似乎不是上述地址处的变量:



#1 楼

1)您的std :: string不是普通的ascii字符串,它是一个结构(实际上是一个类)
,因此您无法在特定情况下获取地址并找到字符串

,因为字符串测试的长度小于阈值,很幸运,您可以在屏幕快照中看到它,查找74 65 73 74 ascii,您会注意到它是“测试”

,并且您看到的int是可见
尝试查看0xa == 0n10

编辑

您的源经过略微修改以显示上述语句的结果

#include <iostream>
#include <string>
using namespace std;
int main(void)
{
    //small string will be embedded inside std::string class 
    // you can see 74657374 (hex for "test")
    string s1{ "test" };
    cout << s1 << endl;
    cout << &s1 << endl;
    printf("%llx\n", *(__int64 *)(&s1) );
    printf("%p\n" , s1.c_str());
    printf("%s\n" , s1.c_str());

    cout << "\n=========================================================================\n" ;

    // big string a pointer will be present to the c_str member
    // you cannot see the string unless you dereference the pointer for c_str() member

    string s2 { "this is a very very very very very very biggy biggy biggy stringyyyyyy" };
    cout << s2 << endl;
    cout << &s2 << endl;
    printf("%llx\n", *(__int64 *)&s2 );
    printf("%p\n" , s2.c_str());
    printf("%s\n" , s2.c_str());


    return getchar();
}


结果

>ogrish.exe
test
001AF7C8
eafc0074736574  <<<< see the hex embedded
001AF7C8   << both &std::string and std::strin.c_str() are same
test  << c_str()  

=========================================================================
this is a very very very very very very biggy biggy biggy stringyyyyyy
001AF7E0   &std::string 
1af7f000265cf0   << address of std::string and c_str() are different
00265CF0   & string->c_str()
this is a very very very very very very biggy biggy biggy stringyyyyyy  << c_str()


和顺便说一句,如果您附加到此控制台进程,请记住所有代码已经运行,并且堆栈上的所有内容都可以运行超出范围并包含虚假值,您需要逐步检查调试器上的内容
不执行并附加

评论


这种“地址可变”类型是否取决于编译器?我已经用MSVC编译的二进制文件而不是G ++看到了这一点。

– Biswapriyo
19年2月19日在13:42

不知道您要问x64dbg是Windows特定的,所以我给op了一个普通的vc编译的std :: string详细信息sizeof(std :: string)== 0x18其中0x10是char缓冲区,这是iirc,称为短字符串优化,msvc可能不同来自gcc和gcc可能与clang不同

– blabb
19年2月19日在20:32

@Biswapriyo这是一篇文章,讨论了std :: string wrt msvc,gcc,clang shaharmike.com/cpp/std-string的不同实现

– blabb
19年2月19日在20:42

#2 楼

blabb的答案是正确的,我将添加更多信息。

您在x64的错误窗口中搜索值。正如您在图片中所看到的,此窗口的内容(CPU)正在自动尝试将内存中的数据分解为代码。如果要查看值,最好在转储窗口(左下)或堆栈窗口(右下)中查找地址。