Question

Comme un exercice de programmation, je vous écris une marque et-balayage éboueur dans souhait C. I analyser le segment de données (globals, etc.) pour des pointeurs vers la mémoire allouée, mais je ne sais pas comment la plage des adresses de ce segment. Comment pourrais-je faire?

Était-ce utile?

La solution

Les limites pour le texte (code du programme) et des données pour Linux (et d'autres) unix:

#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;
}

Lorsque ces symboles proviennent de: Où sont les symboles EText, edata et à la fin définie?

Autres conseils

Si vous travaillez sous Windows, puis il y a API Windows qui vous aide.

//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++;
}

Définir ImageSectionInfo comme,

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); 
       }
};

Voici un programme de console WIN32 complète, minimale, vous pouvez exécuter dans Visual Studio qui illustre l'utilisation de l'API Windows:

#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)
}

Cette page peut être utile si vous êtes intéressé dans d'autres utilisations de la bibliothèque DbgHelp.

Vous pouvez lire le format d'image PE ici, de savoir dans les détails. Une fois que vous comprenez le format PE, vous serez en mesure de travailler avec le code ci-dessus, et peut même modifier pour répondre à vos besoins.

  • Format de PE

Peering A l'intérieur du PE: Tour du format de fichier Portable Executable Win32

Un regard en profondeur dans le Portable Executable Win32 Format de fichier, partie 1

Un regard en profondeur dans le Portable Executable Win32 Format de fichier, Partie 2

  • API Windows et structures

IMAGE_SECTION_HEADER Structure

ImageNtHeader Fonction

IMAGE_NT_HEADERS Structure

Je pense que cela vous aidera dans une grande mesure, et le reste, vous pouvez vous la recherche: -)

Par ailleurs, vous pouvez également voir ce fil, comme tous ces éléments sont en quelque sorte liés à ceci:

Scénario: Les variables globales dans DLL qui est utilisé par l'application multi-thread

Puisque vous aurez probablement à faire votre éboueur l'environnement dans lequel les pistes de programme, vous pouvez l'obtenir à partir du fichier elfe directement.

Charger le fichier que l'exécutable est venu et analyser les en-têtes de PE, pour Win32. Je ne sais pas à propos d'autres systèmes d'exploitation. Rappelez-vous que si votre programme se compose de plusieurs fichiers (par exemple DLL) vous pouvez avoir plusieurs segments de données.

Pour iOS, vous pouvez utiliser cette solution . Il montre comment trouver la gamme de segment de texte, mais vous pouvez facilement changer pour trouver un segment que vous aimez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top