Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 16

Thema: std::map mit Pointern iterieren...

  1. #1
    Registered User
    Registriert seit
    Mar 2009
    Beiträge
    70
    Renommee
    39

    std::map mit Pointern iterieren...

    Moin - ich habe momentan ein Verständnisproblem mit der std::map.
    Und zwar bin ich nicht in der Lage die Map nur mittels dem "Startpointer" zu durchlaufen...

    Hier das bsp. Programm:

    Code:
    #include<Windows.h>
    #include<map>
    
    #define MAP_KEY_OFFSET 0x10
    #define MAP_VALUE_OFFSET 0x14
    void main()
    {
    	DWORD MapPtr = NULL;
    	std::map<DWORD,DWORD> Test;
    	Test[1] = 10;
    	Test[2] = 20;
    	Test[3] = 30;
    	Test[4] = 40;
    	Test[5] = 50;
    	Test[6] = 60;
    	Test[8] = 80;
    
    	printf("%.8X\n",(MapPtr = (DWORD)&Test));
    
    	DWORD ListItem = (*(DWORD*)((*(DWORD*)(MapPtr + 0x4)) + 0x0));
    	DWORD Item_Key		= (*(DWORD*)(ListItem + MAP_KEY_OFFSET));
    	DWORD Item_Value	= (*(DWORD*)(ListItem + MAP_VALUE_OFFSET));
    	printf("Item<%d,%d>\n", Item_Key, Item_Value);
    	
    	getchar();
    }
    Ausgehend vom Pointer "&MapTest"... ich hoffe ihr könnt mir weiter helfen... vielen Dank =)
    Geändert von valvepro (20.10.2013 um 18:36 Uhr)

  2. #2
    Member
    Registriert seit
    May 2004
    Beiträge
    1.432
    Renommee
    1142

    AW: std::map mit Pointern iterieren...

    Du triffst Annahmen, die Dir die ABI schlichtweg nicht zusichert. Korrektes Beispiel mit begin: http://www.cplusplus.com/reference/map/map/begin/

  3. #3
    Registered User
    Registriert seit
    Aug 2010
    Beiträge
    2
    Renommee
    10

    AW: std::map mit Pointern iterieren...

    Es geht darum, gerade nicht begin zu verwenden und nur den Objekt ptr zu nutzen, um durch alle Werte zu gehen.

  4. #4
    Member
    Registriert seit
    May 2004
    Beiträge
    1.432
    Renommee
    1142

    AW: std::map mit Pointern iterieren...

    O.o Mit welchem Ziel? Das führt die Verwendung des Templates ad absurdum.

  5. #5
    Registered User
    Registriert seit
    Aug 2010
    Beiträge
    2
    Renommee
    10

    AW: std::map mit Pointern iterieren...

    Kann man gebrauchen, wenn man zum Beispiel reverse engineered, da hat man nicht gerade den ganzen Sourcecode zur Verfügung^^

  6. #6
    Member
    Registriert seit
    May 2004
    Beiträge
    1.432
    Renommee
    1142

    AW: std::map mit Pointern iterieren...

    Na wenn Ihr meint. Nun, offensichtlich sind die Offsets nicht korrekt. Im Zweifel einfach mal verschiedene Werte probieren, bis man auf die erwarteten Daten stößt.

    Woher stammen denn die Annahmen über die Speicherstruktur?

  7. #7
    Registered User
    Registriert seit
    Mar 2009
    Beiträge
    70
    Renommee
    39

    AW: std::map mit Pointern iterieren...

    Die Annahmen stammten aus dem testen mit CheatEngine. Ich habe keinerlei wissen über die Speicherstruktur, da ich auch nicht weiß wie das Template aufgebaut ist bzw. welche Strukturen dahinter stecken, daher frage ich hier ja.

  8. #8
    Member
    Registriert seit
    May 2004
    Beiträge
    1.432
    Renommee
    1142

    AW: std::map mit Pointern iterieren...

    Bei mir sieht *(void **)((int *)&test + 4) so aus:

    Code:
      0000  01 00 00 00 00 00 00 00 c8 b4 7f f3 ff 7f 00 00  ................
      0010  10 70 ed 00 00 00 00 00 a0 70 ed 00 00 00 00 00  .p.......p......
      0020  02 00 00 00 14 00 00 00 31 00 00 00 00 00 00 00  ........1.......
      0030  01 00 00 00 00 00 00 00 a0 70 ed 00 00 00 00 00  .........p......
      0040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      0050  03 00 00 00 1e 00 00 00 31 00 00 00 00 00 00 00  ........1.......
      0060  00 00 00 00 00 00 00 00 40 70 ed 00 00 00 00 00  ........@p......
      0070  70 70 ed 00 00 00 00 00 00 71 ed 00 00 00 00 00  pp.......q......
      0080  04 00 00 00 28 00 00 00 31 00 00 00 00 00 00 00  ....(...1.......
      0090  00 00 00 00 00 00 00 00 00 71 ed 00 00 00 00 00  .........q......
      00a0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      00b0  05 00 00 00 32 00 00 00 31 00 00 00 00 00 00 00  ....2...1.......
      00c0  01 00 00 00 00 00 00 00 a0 70 ed 00 00 00 00 00  .........p......
      00d0  d0 70 ed 00 00 00 00 00 30 71 ed 00 00 00 00 00  .p......0q......
      00e0  06 00 00 00 3c 00 00 00 31 00 00 00 00 00 00 00  ....<...1.......
      00f0  00 00 00 00 00 00 00 00 00 71 ed 00 00 00 00 00  .........q......
    Offensichtlich sitzen die Keys auf den Offsets 0, 20, 50, 80, b0, e0. Den ersten Wert kann ich nicht entdecken, die anderen folgen direkt auf den jeweiligen Key.

    libstdc++-v3 GCC 4.8.1

    Wenn ich das richtig sehe, müsste das der von map intern verwendete RB-Tree sein. Dessen Implementierung ist in stl_tree.h zu sehen.

  9. #9
    Registered User
    Registriert seit
    Mar 2009
    Beiträge
    70
    Renommee
    39

    AW: std::map mit Pointern iterieren...

    Danke, das erklärt aber leider immer noch nicht wie ich die Map durchlaufen kann.

    Aber mit dem Tree hast du recht, hinter der std::map versteckt sich ein Tree...

  10. #10
    Member
    Registriert seit
    May 2004
    Beiträge
    1.432
    Renommee
    1142

    AW: std::map mit Pointern iterieren...

    Am einfachsten und zuverlässigsten: Die API nutzen. Auch beim Reversen hindert dich nichts daran einen Speicherbereich als Objekt zu behandeln.

    Oder: Darauf verlassen, dass 0x10 auf den Tree zeigt und die RB-Tree-Funktionen aus stl_tree.h nutzen. (Die sind zwar eigentlich nur intern, aber auch daran hindert Dich niemand.)

    Oder: Wenn Du aus irgendeinem Grund unbedingt im Speicher herumrennen willst, analysiere die RB-Tree-Implementierung. Ich bin mir aber relativ sicher, dass das sich ergebende Bild im Speicher sehr unterschiedlich ausfallen wird. Das sind nämlich wohl die einzelnen Einträge, zwischen denen beliebige andere Dinge allokiert werden können. Was Du dann also effektiv machen müsstest, ist die RB-Tree-Implementierung nachbauen, was die vorherige Option nahelegt.

  11. #11
    Moderator
    Registriert seit
    Aug 2004
    Beiträge
    1.310
    Renommee
    1286

    AW: std::map mit Pointern iterieren...

    Wie Shakademus schon gesagt hat, ist der Speicher-Dump aus seinem Post die Sammlung der Baum-Elemente. Dadurch, dass zwischen drin keine anderen Allokationen mit malloc/new gemacht worden sind, liegen die Einträge alle schön dicht beeinander. Das ist reiner Zufall, verlass dich also nicht darauf.

    Wenn du über die Einträge iterieren möchtest, ist es wirklich am besten, du schaust in der passenden http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.1/stl__tree_8h-source.html nach um herauszufinden wie ein Eintrag ausschaut.

    Hier sieht es ungefähr so aus:
    PHP-Code:
    enum _Rb_tree_color _S_red false_S_black true };

    struct _Rb_tree_node_base
    {
    ...
      
    _Rb_tree_color  _M_color;
      
    _Base_ptr       _M_parent;
      
    _Base_ptr       _M_left;
      
    _Base_ptr       _M_right;
    ...
    };

    template<typename _Val>
    struct _Rb_tree_node : public _Rb_tree_node_base
    {
    ...
      
    _Val _M_value_field;
    }; 
    Da _Rb_tree_node von _Rb_tree_node_base erbt, wird im Speicher erst die Struktur zur Baum-Verwaltung und dann der Wert vom Typ deiner Map liegen (hier std::pair<int,int>).
    Wenn du das auf den Dump mapst, kommst du zu folgendem Ergebnis:

    PHP-Code:
    _M_color      0x00000001;         //Farbe: black, dann 4 Byte padding wg alignment in der struct
    _M_parent     0x00007ffff37fb4c8//64-bit Pointer auf Parent (hier die Wurzel, die keinen Wert enthält und auf dem Stack angelegt wurde)
    _M_left       0x0000000000ed7010//keine Verbindung nach links
    _M_right      0x0000000000ed70a0//keine Verbindung nach rchts
    pair::first   0x00000002;         //key   = 3
    pair::second  0x00000014;         //value = 30, danach 8 byte Platz

    _M_color      0x00000001;         //Farbe: black, dann 4 Byte padding wg alignment in der struct
    _M_parent     0x0000000000ed70a0//64-bit Pointer auf Parent
    _M_left       0x0000000000000000//keine Verbindung nach links
    _M_right      0x0000000000000000//keine Verbindung nach rchts
    pair::first   0x00000003;         //key   = 3
    pair::second  0x0000001e;         //value = 30, danach 8 byte Platz

    _M_color      0x00000000;         //Farbe: red, dann 4 Byte padding wg alignment in der struct
    _M_parent     0x0000000000ed7040//64-bit Pointer auf Parent
    _M_left       0x0000000000ed7070//keine Verbindung nach links
    _M_right      0x0000000000ed7100//keine Verbindung nach rchts
    pair::first   0x00000004;         //key   = 3
    pair::second  0x00000028;         //value = 30, danach 8 byte Platz 
    Die 8 Byte Platz am Ender der Structs liegt vermutlich an der größe der Speicherblöcke die der Memoryhandler rausgibt. -> 48 Byte pro Struct

    @Shakademus:
    Kann das sein, dass dein Stack an 00007ffff37fb4c8 liegt?

  12. #12
    Member
    Registriert seit
    May 2004
    Beiträge
    1.432
    Renommee
    1142

    AW: std::map mit Pointern iterieren...

    Zitat Zitat von nait Beitrag anzeigen
    Kann das sein, dass dein Stack an 00007ffff37fb4c8 liegt?
    Klar, ausschließen würde ich das nie. ;)

  13. #13
    Registered User
    Registriert seit
    Mar 2009
    Beiträge
    70
    Renommee
    39

    AW: std::map mit Pointern iterieren...

    Okay, dann nehmen wir mal an die Struct schaut so aus
    Code:
    struct _Rb_tree_node_base 
    { 
      BYTE			_M_color; 
      _Rb_tree_node_base*		_M_parent; 
      _Rb_tree_node_base*		_M_left; 
      _Rb_tree_node_base*		_M_right;
      DWORD			_M_Key;
      DWORD			_M_Value;
    };
    Würde bedeuten ich caste das Erste Element auf dieser Struct und schaue ob links/rechts ein Element ist? und verfolge dieses?

    Code:
    void main()
    {
    	DWORD MapPtr = NULL;
    	std::map<DWORD,DWORD> Test;
    	
    	Test[1] = 10;
    	Test[2] = 20;
    	Test[3] = 30;
    	Test[4] = 40;
    	Test[5] = 50;
    		
    	_Rb_tree_node_base *TEST = (_Rb_tree_node_base *)(*(DWORD*)&Test.begin());
    
    	printf("\n");
    	printf("O[%.8X] P[%.8X] L[%.8X] R[%.8X]std::map<%d,%d> Test;\n",TEST, TEST->_M_parent,TEST->_M_left, TEST->_M_right, TEST->_M_Key, TEST->_M_Value);
    	//...
    	//...Was nun...
    	//...
    
    	getchar();
    }

  14. #14
    Member
    Registriert seit
    May 2004
    Beiträge
    1.432
    Renommee
    1142

    AW: std::map mit Pointern iterieren...

    Genau, man kann das Rad (lies: den _Rb_tree_base_iterator) kopieren oder nutzen. ;)

  15. #15
    Registered User
    Registriert seit
    Mar 2009
    Beiträge
    70
    Renommee
    39

    AW: std::map mit Pointern iterieren...

    Also ich habe es jetzt mal 1zu1 übernommen aber es wird mir immer nur das erste Element angezeigt...

    Code:
    #include<Windows.h>
    #include<map>
    
    struct _Rb_tree_node_base 
    { 
    	BYTE COLOR;
    	_Rb_tree_node_base*		_M_parent; 
    	_Rb_tree_node_base*		_M_left; 
    	_Rb_tree_node_base*		_M_right;
    	DWORD			_M_Key;
    	DWORD			_M_Value;
    };
    
    void _M_increment(_Rb_tree_node_base* _M_node)
    {
        if (_M_node->_M_right != 0) {
    		_M_node = _M_node->_M_right;
    		while (_M_node->_M_left != 0)
    			_M_node = _M_node->_M_left;
        }
        else {
    		_Rb_tree_node_base* __y = _M_node->_M_parent;
    		while (_M_node == __y->_M_right) {
    			_M_node = __y;
    			__y = __y->_M_parent;
    		}
    		if (_M_node->_M_right != __y)
    			_M_node = __y;
    	}
    }
    
    void main()
    {
    	DWORD MapPtr = NULL;
    	std::map<DWORD,DWORD> Test;
    	
    	Test[1] = 10;
    	Test[2] = 20;
    	Test[3] = 30;
    	Test[4] = 40;
    	Test[5] = 50;
    	printf("%.8X\n",(MapPtr = (DWORD)&Test));
    
    	_Rb_tree_node_base *TEST = (_Rb_tree_node_base *)(*(DWORD*)&Test.begin());
    	for(int i=0;i<Test.size();i++)
    	{
    		printf("O[%.8X] P[%.8X] L[%.8X] R[%.8X]std::map<%d,%d>\n",TEST, TEST->_M_parent,TEST->_M_left, TEST->_M_right, TEST->_M_Key, TEST->_M_Value);
    		_M_increment(TEST);
    	}
    	
    	getchar();
    }

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Ähnliche Themen

  1. Antworten: 1
    Letzter Beitrag: 16.03.2005, 23:08
  2. structs mit gegenseitigen pointern
    Von nfb im Forum C / C++
    Antworten: 1
    Letzter Beitrag: 30.09.2003, 09:54
  3. [Pascal : Protected Mode] Probleme mit Pointern
    Von spectrumizer im Forum Pascal / Delphi
    Antworten: 3
    Letzter Beitrag: 25.10.2001, 19:46

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •