VC++如何破坏本地静态变量名?

Owe*_*wen 6 c++ scope

这是我的一些代码:

MyClass* MyClass::getInstance()
{
   static MyClass instance;
   return &instance;
}
Run Code Online (Sandbox Code Playgroud)

我想研究一下这个单身人士的当前价值.但我现在暂停执行三个小时,而我暂停的原因是我失去记忆.所以我不能在这个方法中设置一个断点来看看它的价值.

那么我的问题是如何instance从全局范围引用这个变量.我试过把它称为MyClass::getInstance::instance但是这不起作用.我猜getInstance不得不以某种方式装饰.谁知道怎么样?

这是在Visual Studio 2008中.

bk1*_*k1e 5

好吧,函数作用域的静态instance变量不会出现在由.map生成的文件中cl.exe /Fm,并且在我x programname!*MyClass*在 WinDbg 中使用时也不会出现,因此损坏的名称似乎根本不包含MyClass

选项 1:拆卸 MyClass::getInstance

这种方法似乎更容易:

0:000> uf 程序名!MyClass::getInstance
programname!MyClass::getInstance [programname.cpp @ 14]:
   14 00401050 55 推 ebp
   14 00401051 8bec mov ebp,esp
   15 00401053 a160b34200 mov eax,dword ptr [程序名!$S1 (0042b360)]
   15 00401058 83e001 和 eax,1
   15 0040105b 7526 jne funcstat!MyClass::getInstance+0x33 (00401083)

programname!MyClass::getInstance+0xd [programname.cpp @ 15]:
   15 0040105d 8b0d60b34200 mov ecx,dword ptr [程序名!$S1 (0042b360)]
   15 00401063 83c901 或 ecx,1
   15 00401066 890d60b34200 mov dword ptr [程序名!$S1 (0042b360)],ecx
   15 0040106c b9b0be4200 mov ecx,偏移程序名!实例(0042beb0)
   15 00401071 e88ffffffff 调用程序名!ILT+0(??0MyClassQAEXZ) (00401005)
   15 00401076 68e03e4200 推送偏移程序名!`MyClass::getInstance'::`2'::`'instance'' 的动态 atexit 析构函数(00423ee0)
   15 0040107b e8f3010000 调用程序名!atexit (00401273)
   15 00401080 83c404 添加 esp,4

programname!MyClass::getInstance+0x33 [programname.cpp @ 16]:
   16 00401083 b8b0be4200 mov eax,偏移程序名!实例(0042beb0)
   17 00401088 5d 流行音乐 ebp
   17 00401089 c3 ret

由此我们可以看出编译器调用了对象$S1。当然,这个名字将取决于你的程序有多少函数范围的静态变量。

选项 2:在内存中搜索对象

为了扩展@gbjbaanb 的建议,如果MyClass有虚函数,您可能很难找到它的位置:

  • 对进程进行完整的内存转储。
  • 将完整的内存转储加载到 WinDbg。
  • 使用x命令查找MyClass的vtable地址:
    0:000> x 程序名!MyClass::`vftable'
    00425c64 程序名!MyClass::`vftable' = 
  • 使用该s命令搜索进程的虚拟地址空间(在本例中为 0-2GB)以查找指向 MyClass 的 vtable 的指针:
    0:000> s -d 0 L?7ffffffff 00425c64
    004010dc 00425c64 c35de58b cccccccc cccccccc d\B...]........
    0040113c 00425c64 8bfc458b ccc35de5 cccccccc d\B..E...]......
    0042b360 00425c64 00000000 00000000 00000000 d\B .....................
  • 使用该dt命令查找类的 vtable 偏移量,并从搜索返回的地址中减去该偏移量。这些是对象的可能地址。
    0:000> dt 程序名!MyClass
       +0x000 __VFN_table : Ptr32 
       +0x008 x : Int4B
       +0x010 y : 浮动
  • 使用dt programname!MyClass 0042b360检查对象的成员变量,检验假设,即目标位于0042b360(或其他地址)。您可能会得到一些误报,就像我上面所做的那样,但是通过检查成员变量,您可能会找出哪个是您的单身人士。

这是查找 C++ 对象的通用技术,当您可以反汇编MyClass::getInstance.