查找所有 C++使用 WinDbg 堆上 X 类型的对象

发布于 2024-09-07 20:26:32 字数 221 浏览 4 评论 0原文

我试图在堆中查找 module!SomeClass 类型的所有对象。我以为这样的命令会起作用:

> s -v 0 L?0xfffffff module!SomeClass

但是可惜,它不起作用。如果我知道如何找到该类的 vtable 地址,我就可以在内存中搜索对该 vtable 的引用,但我也没有太多运气找到它。我该怎么做呢?

I'm trying to find all objects of type module!SomeClass in the heap. I thought a command like this would've worked:

> s -v 0 L?0xfffffff module!SomeClass

but alas, it does not. If I knew how to find the vtable address for that class, I could then search memory for references to that vtable, but I haven't had much luck finding that either. How can I do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜是你 2024-09-14 20:26:32
0:000> x module!SomeClass*table*
0:000> !heap -srch 'address_of_vtable'
0:000> x module!SomeClass*table*
0:000> !heap -srch 'address_of_vtable'
超可爱的懒熊 2024-09-14 20:26:32
class Polygon {
protected:
    int width, height;
public:
    virtual int area()
    {
        return 0;
    }
};

class Rectangle : public Polygon {
public:
    int area()
    {
        return width * height;
    }
};

class Triangle : public Polygon {
public:
    int area()
    {
        return (width * height / 2);
    }
};


class RectangleTriangle : public Rectangle, Triangle //RectangleTriangle  <-- This class will have two Vtables for each base class
{
public:
    int area()
    {
        return (2* 3/ 2);
    }
};

int main() {
    RectangleTriangle *rect = new RectangleTriangle();
    Triangle trgl;
    Polygon poly;
    return 0;
}

我们从 vtable 开始的原因是因为任何继承虚函数的对象都会有一个 vtable 指针,它基本上是类上的静态变量。因此,当在堆中创建对象时,该类的每个对象都应该拥有对此 vtable 位置的引用。因此,我们基本上是试图从 vtable 指针获取对象本身。

0:000> x Win32Sample!RectangleTriangle*table*
00007ff7`81ed3288 Win32Sample!RectangleTriangle::`vftable' = <function> *[2] <-- one for each base class
00007ff7`81ed3278 Win32Sample!RectangleTriangle::`vftable' = <function> *[2] <-- one for each base class

0:000> !heap -srch 00007ff7`81ed3288  // <-- We are asking !heap "who owns a pointer to this vtable in the entire process heap"
    _HEAP @ 1e5ed710000
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
        000001e5ed716620 0006 0000  [00]   000001e5ed716630    00021 - (busy)
          Win32Sample!RectangleTriangle::`vftable'

0:000> !heap -srch 00007ff7`81ed3278 // <-- We are asking !heap "who owns a pointer to this vtable in the entire process heap"
    _HEAP @ 1e5ed710000
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
        000001e5ed716620 0006 0000  [00]   000001e5ed716630    00021 - (busy)
          Win32Sample!RectangleTriangle::`vftable'

UserPtr 基本上是堆管理器为 new 运算符返回的内存块的开始。这就是为什么 UserPtr 并不表示包含该值的内存位置,而是表示堆块的起始位置,因此在两个 vtable 中该值相同 000001e5ed716630

0:000> dt Win32Sample!RectangleTriangle 000001e5ed716630
   +0x000 __VFN_table : 0x00007ff7`81ed3278 
   +0x008 width            : 0n0
   +0x00c height           : 0n0
   +0x010 __VFN_table : 0x00007ff7`81ed3288 
   +0x018 width            : 0n0
   +0x01c height           : 0n0

我们不能使用 s 命令来搜索 vtable 指针和堆中的对象,因为堆块不连续!

class Polygon {
protected:
    int width, height;
public:
    virtual int area()
    {
        return 0;
    }
};

class Rectangle : public Polygon {
public:
    int area()
    {
        return width * height;
    }
};

class Triangle : public Polygon {
public:
    int area()
    {
        return (width * height / 2);
    }
};


class RectangleTriangle : public Rectangle, Triangle //RectangleTriangle  <-- This class will have two Vtables for each base class
{
public:
    int area()
    {
        return (2* 3/ 2);
    }
};

int main() {
    RectangleTriangle *rect = new RectangleTriangle();
    Triangle trgl;
    Polygon poly;
    return 0;
}

The reason why we start with vtables is because any object which inherit a virtual function will have a vtable pointer which is basically a static variable on the class. So every object of that class should have a reference to this vtable location when the object is created in the heap. So from vtable pointer we are basically trying to get hold of the object itself.

0:000> x Win32Sample!RectangleTriangle*table*
00007ff7`81ed3288 Win32Sample!RectangleTriangle::`vftable' = <function> *[2] <-- one for each base class
00007ff7`81ed3278 Win32Sample!RectangleTriangle::`vftable' = <function> *[2] <-- one for each base class

0:000> !heap -srch 00007ff7`81ed3288  // <-- We are asking !heap "who owns a pointer to this vtable in the entire process heap"
    _HEAP @ 1e5ed710000
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
        000001e5ed716620 0006 0000  [00]   000001e5ed716630    00021 - (busy)
          Win32Sample!RectangleTriangle::`vftable'

0:000> !heap -srch 00007ff7`81ed3278 // <-- We are asking !heap "who owns a pointer to this vtable in the entire process heap"
    _HEAP @ 1e5ed710000
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
        000001e5ed716620 0006 0000  [00]   000001e5ed716630    00021 - (busy)
          Win32Sample!RectangleTriangle::`vftable'

UserPtr is basically the starting of the block of memory returned by heap manager for new operator. That is why UserPtr does not mean the memory location which includes this value instead it is the starting of the heap block hence in both vtables the value is same 000001e5ed716630

0:000> dt Win32Sample!RectangleTriangle 000001e5ed716630
   +0x000 __VFN_table : 0x00007ff7`81ed3278 
   +0x008 width            : 0n0
   +0x00c height           : 0n0
   +0x010 __VFN_table : 0x00007ff7`81ed3288 
   +0x018 width            : 0n0
   +0x01c height           : 0n0

We cannot use s command to search for the vtable pointer and the object in heap because heap blocks are not contiguous!!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文