2010-03-13 56 views
1

你怎麼會在內存中找到一個對象,讓說你有一個結構定義爲:查找內存中的對象(結構) - 如何?

struct POINT { 
    int x; 
    int y; 
}; 

我怎麼會掃描我的應用程序的內存區域找到這個結構的情況下,這樣我也能閱讀出來嗎?

謝謝R.

+5

你究竟想通過這個來實現什麼? – randomThought 2010-03-13 00:08:26

+1

首先,這些實例是如何迷失在內存中的?你有做新的POINT嗎?新POINT;'然後嘗試找到它們? – UncleBens 2010-03-13 00:09:58

回答

4

你不能沒有添加類型信息的結構。在內存中,這樣的結構不是別的,而是2個整數,所以你不能識別它們比識別任何其他對象更好。

+2

...即使添加了類型信息,它可能會很難(你怎麼知道哪些位代表類型信息?) – UncleBens 2010-03-13 00:07:30

+0

你將不得不創建一個相當獨特的字節序列來識別它(每個人都有'0xDEADBEEF'? ) – Wolph 2010-03-13 00:16:26

2

你不能。你必須知道佈局以知道哪部分內存必須代表一個變量。這是一種協議,這就是爲什麼我們使用基於文本的語言代替原始值。

2

你不會 - 你怎麼區分隨機噪聲的兩個任意整數?

(但在源代碼中給出Point p;,可以使用操作符地址獲得其地址... Point* pp = &p;)。

1

無法識別該結構。您需要將結構放置在可以找到的位置,堆棧或堆上。

有時候數據結構被標記有識別信息來協助調試或內存管理。作爲數據組織的一種手段,它是最糟糕的可能方法之一。

您可能需要大量的一般閱讀內存管理

1

有沒有這樣做的標準方式。該平臺可能會指定一些允許您訪問堆棧和免費商店的API。此外,即使你做了,沒有任何額外的信息,你如何確定你正在閱讀POINT對象而不是幾個int?編譯器/鏈接器可以讀取它,因爲它處理(雖然是虛擬的)地址,並且比你有更多的信息(和控制)。

3

你不能。結構體不存儲任何類型的信息(除非它們具有虛擬成員函數),所以你不能將它們與任何sizeof(POINT)字節的其他塊區分開來。

爲什麼你不把你的點存儲在一個向量或東西?

1

你不行。類似的東西可能在某些「標記」架構上也是可能的,它們也支持用戶定義類型的標記對象。但是在傳統架構中,僅僅通過查看原始內存內容來確定存儲在內存中的內容是絕對不可能的。

您可以更接近於通過引入一個獨特的簽名改成類型實現你想要的東西,像

struct POINT { 
    char signature[8]; 
    int x; 
    int y; 
}; 

,並小心地設置一些固定的,「獨特」的POINT類型的每個對象模式,並然後在記憶中尋找那種模式。如果它是您的應用程序,您可以確定可以確定每個模式實例都是您的POINT對象。但總的來說,當然,不可能保證你發現的圖案屬於你的物體,而不是純粹意外地存在。

+0

您是否知道具有C++編譯器並支持任何類型標記的體系結構? – 2010-03-13 00:13:05

+0

將校驗和與簽名一起使用可能有助於防止誤報 - 其他數據有可能包含與簽名相同的字節序列。 – 2010-03-13 00:14:46

+0

@Roger Pate:在現實生活中?不,我不知道。 – AnT 2010-03-13 02:32:15

2

簡答:你不能。任何(適當對齊的)8個字節的序列都可能代表一個POINT。實際上,一個int數組將與POINTS數組無法區分。在某些情況下,你可以利用編譯器實現的知識來做得更好。例如,如果結構體具有虛函數,則可以查找正確的vtable指針 - 但也可能存在誤報。

如果你想跟蹤的對象,則需要在其構造登記他們和他們的析構函數註銷他們(支付的性能損失),或給他們自己的分配器。

1

其他人都說過的話是真的。在內存中,你的結構只是幾個字節,沒有什麼特別的區別它。但是,如果您覺得自己有點黑客攻擊,那麼您可以查看C庫的內部結構,並找出內存在堆中的存儲位置以及它的顯示方式。例如,this link顯示瞭如何在一個特定的系統中分配東西。

有了這方面的知識,你可以掃描你的堆找到分配的塊是sizeof(POINT),這將大大縮小搜索範圍。如果您查看錶格,您會注意到malloc()調用的文件名和行號正在被記錄下來 - 如果您知道源代碼中的分配POINT s的位置,則可以將其用作參考。

但是,如果你的結構被分配在堆棧上,那麼你的運氣不好。