Hola a todos:
No se si este sera el foro adecuado para esta consulta pero bueno lo intentamos.
En un ejecutable quien decide todos los parametros de Image Base, Entry Point,
o sea , todos los parametros que podemos ver en el LordPE.
Mi duda es si todo debe seguir estas diractrices, o sea que fuera una configuracion estandard y que por ejemplo yo no pudiera tener un programa con una ImageBase por ejemplo en 00003000 en vez de 00400000.
Otra pregunta seria quien decide las direcciones de memoria a las que debe ir el programa al cargarse en la memoria, o sea las direcciones de memoria que nos aparecen al hacer un dump del programa.
Saludos
Esos parámetros generalmente vienen definidos por el compilador. Pero los puedes crear a mano, más que parámetros podríamos llamarles reglas.
En primer lugar tenemos la cabecera 'MZ'
IMAGE_DOS_HEADER que sería esta:
typedef struct _IMAGE_DOS_HEADER
{
WORD e_magic;
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
LONG e_lfanew;
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
Luego ya tienes la de sistemas 'NT' (elfa_new apunta a ella)
IMAGE_NT_HEADERS:
typedef struct _IMAGE_NT_HEADERS
{
ULONG Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
Donde:
struct IMAGE_FILE_HEADER
typedef struct _IMAGE_FILE_HEADER
{
WORD Machine;
WORD NumberOfSections;
ULONG TimeDateStamp;
ULONG PointerToSymbolTable;
ULONG NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_OPTIONAL_HEADER
{
WORD Magic;
UCHAR MajorLinkerVersion;
UCHAR MinorLinkerVersion;
ULONG SizeOfCode;
ULONG SizeOfInitializedData;
ULONG SizeOfUninitializedData;
ULONG AddressOfEntryPoint;
ULONG BaseOfCode;
ULONG BaseOfData;
ULONG ImageBase;
ULONG SectionAlignment;
ULONG FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
ULONG Win32VersionValue;
ULONG SizeOfImage;
ULONG SizeOfHeaders;
ULONG CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
ULONG SizeOfStackReserve;
ULONG SizeOfStackCommit;
ULONG SizeOfHeapReserve;
ULONG SizeOfHeapCommit;
ULONG LoaderFlags;
ULONG NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[16];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
Ahora, sobre la pregunta de si necesita estar en la base
0x00400000 la respuesta es: No.
No es necesario, el Sistema Operativo siempre da prioridad al ImageBase, pero en caso de no poder mapearse en esa zona de memoria lo situaría en una página sin reservar.
El caso más fácil de ver son por ejemplo las librerías, la mayoría de ellas intentan mapearse en
0x01000000 pero si te fijas en tu
debugger favorito verás que siempre se van alojando de forma contigua.
En cuánto a la última pregunta deberías definir a qué secciones te refieres. Si es a la parte de las secciones (IMAGE_SECTION_HEADER) como ".text"/".data"/etc entonces el header del binario es el que lo define.
Ahora si me preguntas sobre el resto de direcciones quitando las que reservan las librerías tienes las páginas de
Stack y contextos (PEB y TEB) en los últimos 100K de los 2GB.
El resto son páginas que se reservan para generar memoria (y devolver heaps).
Un saludo.