varias superponer studio redes rango publicas privadas graficos graficas direcciones clases c memory-management garbage-collection global-variables memory-layout

studio - superponer graficas en r



Encontrar el rango de direcciones del segmento de datos (5)

Cargue el archivo del que proviene el archivo ejecutable y analice los encabezados PE, para Win32. No tengo idea acerca de otros sistemas operativos. Recuerde que si su programa consta de varios archivos (por ejemplo, DLL) puede tener múltiples segmentos de datos.

Como ejercicio de programación, estoy escribiendo un recolector de basura de marca y barrido en C. Deseo escanear el segmento de datos (globales, etc.) en busca de punteros a la memoria asignada, pero no sé cómo obtener el rango de Las direcciones de este segmento. ¿Cómo podría hacer esto?


Como probablemente tendrá que hacer que su recolector de basura sea el entorno en el que se ejecuta el programa, puede obtenerlo directamente desde el archivo elf.


Los límites para texto (código de programa) y datos para linux (y otros unixes):

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

De dónde vienen esos símbolos: ¿Dónde están los símbolos etext, edata y end definidos?


Para iOS puedes usar esta solución . Muestra cómo encontrar el rango del segmento de texto, pero puede cambiarlo fácilmente para encontrar el segmento que desee.


Si estás trabajando en Windows, entonces hay una API de Windows que te puede ayudar.

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

Definir ImageSectionInfo como,

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

Aquí hay un programa de consola WIN32 mínimo y completo que puede ejecutar en Visual Studio que demuestra el uso de la API de 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) }

Esta página puede ser útil si está interesado en usos adicionales de la biblioteca DbgHelp.

Puedes leer el formato de imagen de PE aquí, para conocerlo en detalle. Una vez que entienda el formato PE, podrá trabajar con el código anterior e incluso modificarlo para satisfacer sus necesidades.

  • Formato PE

Mirando dentro del PE: un recorrido por el formato de archivo ejecutable portátil Win32

Una mirada en profundidad al formato de archivo ejecutable portátil Win32, Parte 1

Una mirada en profundidad al formato de archivo ejecutable portátil de Win32, Parte 2

  • API de Windows y Estructuras

Estructura de IMAGE_SECTION_HEADER

Función ImageNtHeader

Estructura de IMAGE_NT_HEADERS

Creo que esto te ayudaría en gran medida, y el resto puedes investigarlo tú mismo :-)

Por cierto, también puedes ver este hilo, ya que todos estos están relacionados de alguna manera con esto:

Escenario: Variables globales en DLL que utiliza la aplicación de subprocesos múltiples