Die Addresse 0x40000000 im Arbeitsspeicher



  • Nun da ich mich etwas intensiver mit dem Arbeitsspeicher geschäftigt habe stellt sich die Frage warum sich die Funktionen im Arbeitsspeicher wiederholen, das heißt der eig. Code der Funktion steht in einer Addresse welche kleiner als 0x40000000 ist und der Ausführbare Code steht in einer Addresse welche größer ist als 0x40000000. Da wollte ich fragen ob das immer so ist nicht das ,dass 1000 mal klappt und beim 1001 mal fehlschlägt. Ich suche nach der Funktion , indem ich sie bitweise in ein unsigned char array kopiere un den Arbeitsspeicher durchsuche , ob nocheinmal genau das gleiche muster , wie das was ich aufgezeichnet habe vorkommt. So finde ich 2 Addresse raus eine ist kleiner als 0x40000000 und eine ist größer als 0x40000000. Die Addresse welche größer als 0x40000000 ist ist die Addresse , mit welcher ich die Funktion aufrufe per inline assembler jmp oder call. Seitdem ich das herausgefunden habe suche ich immer nur den Bereich größer als 0x40000000 ab. Wäre nur blöd wenn dann auf einmal der ausführbare Code in einer Addresse kleiner als 0x40000000 steht. Daher bezieht es sich nur auf die Wissensfrage ob es ausführbaren Code gibt , welcher an einer addresse kleiner als 0x40000000 steht.


  • Mod

    Das ist sowas von compiler- und systemabhängig, wie es nur sein kann. Ein paar Stichworte, die du nicht zu kennen scheinst, die aber wichtig sind:
    Für die Grundlagen, wie Speicher überhaupt funktioniert:
    http://en.wikipedia.org/wiki/Virtual_memory

    Was zum Beispiel passieren könnte, so dass deine Annahmen komplett falsch sind:
    http://en.wikipedia.org/wiki/Address_space_layout_randomization

    Wie durchsuchst du eigentlich den Speicher? Ich hätte erwartet, dass das sofort abstürzt, denn deine Annahmen und Erklärungen klingen wild. was ist zum Beispiel der unterschied zwischen dem Code der Funktion und dem ausführbaren Code? Und bitweise Kopien? Ojeh! Irgendwie kann ich nicht glauben, dass du Assembler kannst und trotzdem so etwas schreibst. Verkackerst du uns?



  • xD ganz sicher nicht und Assembler kann ich auch nicht, ich kenne nur ein paar Basics , da ich mich ein wenig mit dem Instruction Pointer beschäftigt habe. Ich lese die ersten X Bytes von dem Speicherbereich aus an welchem die Funktion steht und speichere diese Bytes in ein Array. Nun lese ich mit VirtualQuery den Arbeitsspeicher ab der Application Base Address aus. Mit Virtual Query hole ich mir wie gesagt einen Teil des Arbeitsspeichers ab. Diesen vergleiche ich dan Byte für Byte mit dem , was ich mir vorher abgeholt habe. Ich poste einfach mal den Code.Der Code ist nicht kommentiert!

    #include <iostream>
    #include <winsock2.h>
    #include <windows.h>
    #include <string>
    #include "C:\\Users\\HA_0xFF\\Desktop\\C++\\Memory\\Memory\\WMemory.h"
    #pragma comment(lib,"ws2_32.lib")
    using namespace std;
    const bool cmpbits(unsigned char b,unsigned char bb)
    	{
    		unsigned long x1=0;
    		x1=x1|b;
    		unsigned long x2=0;
    		x2=x2|bb;
    		if(x1==x2)
    			return true;
    		return false;
    	}
    const bool SearchFunktionWithBitmask(const unsigned long startaddr, MemStr t_cpy_bitmask, unsigned long *ULAddress)
    {
    	*ULAddress=0;
    	unsigned long startaddress;
    	unsigned long tempaddr;
    	unsigned long endaddress;
    	if(startaddr==0)
    	{
    		SYSTEM_INFO sys;
    		GetSystemInfo(&sys);
    		tempaddr=0x40000000;
    		startaddress=reinterpret_cast<unsigned long>(sys.lpMinimumApplicationAddress);
    		endaddress=reinterpret_cast<unsigned long>(sys.lpMaximumApplicationAddress);
    	}
    	else
    	{
            SYSTEM_INFO sys;
    		GetSystemInfo(&sys);
    		startaddress=startaddr;
    		endaddress=reinterpret_cast<unsigned long>(sys.lpMaximumApplicationAddress);
    		tempaddr=startaddress;
    	}
    	MEMORY_BASIC_INFORMATION mbi;
    	unsigned char *readptr;
    	do
    	{
    		VirtualQuery(reinterpret_cast<void*>(tempaddr),&mbi,sizeof(MEMORY_BASIC_INFORMATION));
    		unsigned long start=reinterpret_cast<unsigned long>(mbi.BaseAddress);
    
    		unsigned long end=reinterpret_cast<unsigned long>(mbi.BaseAddress)+mbi.RegionSize;
    if(mbi.State==MEM_COMMIT)
    {
            for(unsigned long x=start;x<end;x++)
    		{
    			unsigned long fail=0;
    			readptr=reinterpret_cast<unsigned char*>(x);
    			for(unsigned long n=0;n<t_cpy_bitmask.GetLength();n++)
    			{
    				if(cmpbits(*readptr,t_cpy_bitmask[n])==false)
    				{
    					fail++;
    					break;
    				}
    				readptr++;
    			}
    			if(fail==0)
    			{
    
    				*ULAddress=x;
    				return true;
    
    			}
    
    		}
    }
    tempaddr+=mbi.RegionSize;
    	}while((tempaddr<endaddress)&&(*ULAddress==0));
    
    }
    const MemStr CreateFunctionBitmask(const unsigned long addroffunc, unsigned long SizeOfByteWritesToBitmask)
    {
    	MemStr mem;
    	mem="";
    
    	unsigned char *Func=(unsigned char*)addroffunc;
    	for(unsigned long x=0;x<SizeOfByteWritesToBitmask;x++)
    	{
    		mem[x]=0;
    		mem[x]=mem[x]|(*Func&1);
    		mem[x]=mem[x]|(*Func&2);
    		mem[x]=mem[x]|(*Func&4);
    		mem[x]=mem[x]|(*Func&8);
    		mem[x]=mem[x]|(*Func&16);
    		mem[x]=mem[x]|(*Func&32);
    		mem[x]=mem[x]|(*Func&64);
    		mem[x]=mem[x]|(*Func&128);
            Func++;
    	}
    	mem.SetLength(SizeOfByteWritesToBitmask-1);
    	return mem;
    }
    void ShowBits(unsigned char bit)
    {
    	cout<<((bit&1)==1?1:0);
        cout<<((bit&2)==2?1:0);
    	cout<<((bit&4)==4?1:0);
    	cout<<((bit&8)==8?1:0);
    	cout<<" "<<((bit&16)==16?1:0);
    	cout<<((bit&32)==32?1:0);
    	cout<<((bit&64)==64?1:0);
    	cout<<((bit&128)==128?1:0)<<endl;
    }
    typedef int (_stdcall *Proc)(SOCKET s,const char *send,int len,int flag);
    int main()
    {     
    	    //Erstelle Bitmask von der Funktion WSAStartup
    	MemStr ss=CreateFunctionBitmask((unsigned long)&WSAStartup,4000);
       unsigned long addr;
       //Durchsuche den Ram nach WSAStartup
       SearchFunktionWithBitmask(0x40000000,ss,&addr);
       cout<<"0x"<<(unsigned*)addr<<endl;
       cout<<"0x"<<&WSAStartup<<endl;
    
    	system("Pause");
    	return 0;
    }
    

    Falls ich die Addresse ab der ich Anfange nach der Funktion zu suchen selbst setze finde ich immer mehrere Ergebnisse



  • Danke für die hilfreichen Links und ich hatte keineswegs vor euch zu "verkackern" allerdings wie du sicher siehst habe ich noch nicht viel gepostet und habe scheinbar auch kein talent zu posten^^
    Trotzdem Danke ich dir. Außerdem arbeite ich sehr an meinen posts vielleicht sind sie ja in ein paar Wochen halbwegs verständlich 😉


Anmelden zum Antworten