Als Programmierübung schreibe ich einen Mark-and-Sweep-Speicherbereiniger in C. Ich möchte das Datensegment (Globals usw.) nach Zeigern auf zugewiesenen Speicher durchsuchen, aber Ich weiß nicht, wie ich die Reichweite der Adressen dieses Segments ermitteln kann. Wie könnte ich das tun?Ermitteln des Adressbereichs des Datensegments
Antwort
Die Grenzen für Text (Programmcode) und Daten für Linux (und andere Unix-Varianten):
#include <stdio.h>
#include <stdlib.h>
/* these are in no header file, and on some
systems they have a _ prepended
These symbols have to be typed to keep the compiler happy
Also check out brk() and sbrk() for information
about heap */
extern char etext, edata, end;
int
main(int argc, char **argv)
{
printf("First address beyond:\n");
printf(" program text segment(etext) %10p\n", &etext);
printf(" initialized data segment(edata) %10p\n", &edata);
printf(" uninitialized data segment (end) %10p\n", &end);
return EXIT_SUCCESS;
}
Wo diese Symbole kommen aus: Where are the symbols etext ,edata and end defined?
brk() und sbrk() sind allgegenwärtig, aber nicht POSIX, von Entwurf. Das liegt daran, dass die Argumente implementiert sind. Überprüfen Sie Ihre Manpage für Details. –
Da diese also das Ende jedes der drei Segmente darstellen, würden wir, um das Datensegment zu durchsuchen, von & etext nach & edata suchen, richtig? – Nick
Wie skaliert das auf ein gemeinsames Objekt? Wenn ich ein So lade, hat es auch ein Daten- und ein BSS-Segment. Dieses Symbol wird in diesem Fall nicht funktionieren. Oder sie? Kannst du mich aufklären? – deadalnix
Laden Sie die Datei, von der die ausführbare Datei stammte, und analysieren Sie die PE-Header für Win32. Ich habe keine Ahnung von anderen Betriebssystemen. Denken Sie daran, dass, wenn Ihr Programm aus mehreren Dateien (z. B. DLLs) besteht, Sie möglicherweise mehrere Datensegmente haben.
Da Sie wahrscheinlich Ihre Garbage Collector die Umgebung, in der das Programm ausgeführt wird, machen müssen, können Sie es direkt aus der Elf-Datei abrufen.
Wenn Sie unter Windows arbeiten, dann gibt sind Windows-API, die Ihnen helfen würden.
//store the base address the loaded Module
dllImageBase = (char*)hModule; //suppose hModule is the handle to the loaded Module (.exe or .dll)
//get the address of NT Header
IMAGE_NT_HEADERS *pNtHdr = ImageNtHeader(hModule);
//after Nt headers comes the table of section, so get the addess of section table
IMAGE_SECTION_HEADER *pSectionHdr = (IMAGE_SECTION_HEADER *) (pNtHdr + 1);
ImageSectionInfo *pSectionInfo = NULL;
//iterate through the list of all sections, and check the section name in the if conditon. etc
for (int i = 0 ; i < pNtHdr->FileHeader.NumberOfSections ; i++)
{
char *name = (char*) pSectionHdr->Name;
if (memcmp(name, ".data", 5) == 0)
{
pSectionInfo = new ImageSectionInfo(".data");
pSectionInfo->SectionAddress = dllImageBase + pSectionHdr->VirtualAddress;
**//range of the data segment - something you're looking for**
pSectionInfo->SectionSize = pSectionHdr->Misc.VirtualSize;
break;
}
pSectionHdr++;
}
ImageSectionInfo definieren als,
struct ImageSectionInfo
{
char SectionName[IMAGE_SIZEOF_SHORT_NAME];//the macro is defined WinNT.h
char *SectionAddress;
int SectionSize;
ImageSectionInfo(const char* name)
{
strcpy(SectioName, name);
}
};
Hier ist ein komplettes, minimal WIN32 Konsole Programm, das Sie in Visual Studio ausführen können, die die Verwendung des Windows-API demonstriert:
#include <stdio.h>
#include <Windows.h>
#include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")
void print_PE_section_info(HANDLE hModule) // hModule is the handle to a loaded Module (.exe or .dll)
{
// get the location of the module's IMAGE_NT_HEADERS structure
IMAGE_NT_HEADERS *pNtHdr = ImageNtHeader(hModule);
// section table immediately follows the IMAGE_NT_HEADERS
IMAGE_SECTION_HEADER *pSectionHdr = (IMAGE_SECTION_HEADER *)(pNtHdr + 1);
const char* imageBase = (const char*)hModule;
char scnName[sizeof(pSectionHdr->Name) + 1];
scnName[sizeof(scnName) - 1] = '\0'; // enforce nul-termination for scn names that are the whole length of pSectionHdr->Name[]
for (int scn = 0; scn < pNtHdr->FileHeader.NumberOfSections; ++scn)
{
// Note: pSectionHdr->Name[] is 8 bytes long. If the scn name is 8 bytes long, ->Name[] will
// not be nul-terminated. For this reason, copy it to a local buffer that's nul-terminated
// to be sure we only print the real scn name, and no extra garbage beyond it.
strncpy(scnName, (const char*)pSectionHdr->Name, sizeof(pSectionHdr->Name));
printf(" Section %3d: %p...%p %-10s (%u bytes)\n",
scn,
imageBase + pSectionHdr->VirtualAddress,
imageBase + pSectionHdr->VirtualAddress + pSectionHdr->Misc.VirtualSize - 1,
scnName,
pSectionHdr->Misc.VirtualSize);
++pSectionHdr;
}
}
// For demo purpopses, create an extra constant data section whose name is exactly 8 bytes long (the max)
#pragma const_seg(".t_const") // begin allocating const data in a new section whose name is 8 bytes long (the max)
const char const_string1[] = "This string is allocated in a special const data segment named \".t_const\".";
#pragma const_seg() // resume allocating const data in the normal .rdata section
int main(int argc, const char* argv[])
{
print_PE_section_info(GetModuleHandle(NULL)); // print section info for "this process's .exe file" (NULL)
}
This page kann hilfreich, wenn Sie an weiteren Verwendungen der DbgHelp-Bibliothek interessiert sind.
Sie können das PE-Bildformat hier lesen, um es im Detail zu wissen. Sobald Sie das PE-Format verstanden haben, können Sie mit dem obigen Code arbeiten und ihn sogar an Ihre Bedürfnisse anpassen.
- PE Format
Peering Inside the PE: A Tour of the Win32 Portable Executable File Format
An In-Depth Look into the Win32 Portable Executable File Format, Part 1
An In-Depth Look into the Win32 Portable Executable File Format, Part 2
- Windows-API und Strukturen
IMAGE_SECTION_HEADER Structure
ich denke, das Sie zu großen Teil dazu beitragen würde, und der Rest kann man sich die Forschung :-)
By the way, können Sie auch sehen Dieser Thread, wie alle diese sind irgendwie damit zusammenhängen:
Scenario: Global variables in DLL which is used by Multi-threaded Application
Für iOS können Sie this solution verwenden. Es zeigt, wie man den Textsegmentbereich findet, aber Sie können es leicht ändern, um irgendein Segment zu finden, das Sie mögen.
- 1. Ermitteln des Computernamens des Kunden
- 2. Ermitteln des "System Load"
- 3. Ermitteln des verfügbaren Videospeichers
- 4. Ermitteln des Anwendungsneufokusereignisses
- 5. Ermitteln des Erweiterungstyps mithilfe des Image-Streams
- 6. Ermitteln des Typs des Klassentypparameters Typescipt
- 7. NodeJS: Ermitteln des aktuellen Arbeitsverzeichnisses des Benutzers
- 8. Ermitteln des angehaltenen Zustands des Quarzauslösers?
- 9. Ermitteln des Ergebnistyps in OnException des Controllers
- 10. Ermitteln des Dateityps mithilfe des Dialogfelds "Elektron"
- 11. Ermitteln iPhone Land des Benutzers
- 12. Ermitteln des Farbraums mit openCV
- 13. Ermitteln des Klassennamens von SVGAnimatedString
- 14. Android: Ermitteln des aktuellen Audiokanals
- 15. Ermitteln des Dateityps eines Bildes
- 16. Ermitteln des ausführbaren C-Namens
- 17. Silverlight: Ermitteln des übergeordneten TreeViewItem?
- 18. Ermitteln PID des beendeten Prozesses
- 19. Ermitteln der Bildschirmkoordinaten des Aktionsleistenmenüeintrags zum Erstellen des Einführungsbildschirms
- 20. SQL Server: Ermitteln des Domänenbenutzers bei Verwendung des Dienstkontos
- 21. Strippen eines Strings und Ermitteln des Startindex und des Endindex
- 22. Ermitteln der Uhrzeit und des Datums des Benutzers in PHP
- 23. Ermitteln des Schlüssels des einzigen Elements in einem PHP-Array
- 24. Ermitteln des physischen Pfads einer ISAPI-DLL
- 25. Ermitteln des varchar-Inhalts in nvarchar-Spalten
- 26. Ermitteln des Debug-Modus in verwaltetem C++
- 27. Ermitteln der Gesamtgröße des SVN-Verzeichnisses/Trunks
- 28. Ermitteln des Fensters/der Bildschirmgröße der Anwendung
- 29. Ermitteln des Namens der Elternklasse mit Reflection
- 30. Ermitteln des aktiven Seitenobjekts in Typo3
Ich würde sagen, es ist Betriebssystem abhängig. – ruslik
Ich stimme zu, aber gibt es eine Möglichkeit, dies in das Programm zu bekommen, wie bei einem Systemanruf? – Nick
Wie können wir das beantworten, wenn Sie uns nicht sagen, was das System ist? – Puppy