Por supuesto que estan en memoria cuando un programa se carga para su ejecucion (es decir se transforma en un proceso).
Las variables locales se ubican en la pila y las funciones en alguna sección de codigo, asi que la respuesta es no, lo que sucede es que se cargan todas las secciones, de datos y de codigo, que tiene el programa en memoria segun el formato de ejecutable.
A este ejemplo lo compile de manera que no incluyera la RTL y no fuera optimizado el codigo (o x desapareceria):
#include <windows.h>
char msg[] = "hola";
void main()
{
__debugbreak();
unsigned int x = MB_OKCANCEL;
MessageBox(0, msg, msg, x);
}
Mi ejemplo se llama hi, voy a ejecutarlo y con el depurador le vamos a dar una minima ojeada, lm nos muestra los modulos cargados en el proceso:
0:000> lm
start end module name
00830000 00837000 hi C (private pdb symbols) C:\ProgramData\dbg\sym\hi.pdb\2A2EA34E458847C7B510C3251A92BACFe\hi.pdb
74ee0000 74ef8000 win32u (deferred)
74f00000 74f7b000 msvcp_win (deferred)
74f80000 75120000 USER32 (deferred)
75460000 75484000 GDI32 (deferred)
759d0000 75af0000 ucrtbase (deferred)
76290000 764a4000 KERNELBASE (deferred)
76830000 7690e000 gdi32full (deferred)
769c0000 76ab0000 KERNEL32 (pdb symbols) C:\ProgramData\dbg\sym\wkernel32.pdb\5DBE558364DB859C4A8BF0C3F35C0FFD1\wkernel32.pdb
76d50000 76d75000 IMM32 (deferred)
76f60000 77103000 ntdll (pdb symbols) C:\ProgramData\dbg\sym\wntdll.pdb\433094D2BBFF99FD8B094875FD33DF661\wntdll.pdb
Ahora con !dh (dump header) vemos las cabeceras y algunas secciones de hi.exe:
0:000> !dh hi.exe
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (i386)
5 number of sections
61FCE3DF time date stamp Fri Feb 4 09:29:19 2022
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
102 characteristics
Executable
32 bit word machine
OPTIONAL HEADER VALUES
10B magic #
14.16 linker version
1200 size of code
A00 size of initialized data
0 size of uninitialized data
1005 address of entry point ;este es el
offset al punto de entrada, aca arranca la ejecucion del programa
1000 base of code
----- new -----
00830000 image base ;se carga en la direccion especificada en nuestro ejecutable (formato PE)
1000 section alignment
200 file alignment
3 subsystem (Windows CUI)
6.00 operating system version
0.00 image version
6.00 subsystem version
7000 size of image
400 size of headers
0 checksum
00100000 size of stack reserve
00001000 size of stack commit
00100000 size of heap reserve
00001000 size of heap commit
8540 DLL characteristics
Dynamic base
NX compatible
No structured exception handler
Terminal server aware
0 [ 0] address [size] of Export Directory
5030 [ 28] address [size] of Import Directory
0 [ 0] address [size] of Resource Directory
0 [ 0] address [size] of Exception Directory
0 [ 0] address [size] of Security Directory
6000 [ 10] address [size] of Base Relocation Directory
3000 [ 38] address [size] of Debug Directory
0 [ 0] address [size] of Description Directory
0 [ 0] address [size] of Special Directory
0 [ 0] address [size] of Thread Storage Directory
0 [ 0] address [size] of Load Configuration Directory
0 [ 0] address [size] of Bound Import Directory
5000 [ 30] address [size] of Import Address Table Directory
0 [ 0] address [size] of Delay Import Directory
0 [ 0] address [size] of COR20 Header Directory
0 [ 0] address [size] of Reserved Directory
SECTION HEADER #1
.text name
104D virtual size
1000 virtual address
1200 size of raw data
400 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
(no align specified)
Execute Read
SECTION HEADER #3
.data name
106 virtual size
4000 virtual address
200 size of raw data
1A00 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
(no align specified)
Read Write
...
¿Entonces donde estara nuestro codigo? En 00830000 + 1000, veamos que hay ahi:
0:000> u 0x1000+hi.exe
hi!ILT+0(_main)+0xffffffff`fffffffb:
00831000 cc int 3
00831001 cc int 3
00831002 cc int 3
00831003 cc int 3
hi!ILT+0(_main) (hi+0x1004):
00831004 cc int 3
hi!ILT+0(_main):
00831005 e906000000 jmp hi!main (00831010)0083100a cc int 3
0083100b cc int 3
¿Cual era el punto de entra segun las cabeceras? 00831005, donde hay un salto a nuestra funcion main.
0:000> uf
00831010hi!main [c:\src\hi.cpp @ 6]:
6 00831010 55 push ebp
6 00831011 8bec mov ebp,esp
6 00831013 51 push ecx
7 00831014 cc int 3
8 00831015 c745fc01000000 mov dword ptr [ebp-4],1 ;aca esta la X, en la pila, no en una sección del ejecutable
9 0083101c 8b45fc mov eax,dword ptr [ebp-4]
9 0083101f 50 push eax
9 00831020 6800408300 push offset hi!msg (00834000) ;.data
9 00831025 6800408300 push offset hi!msg (00834000) ;.data
9 0083102a 6a00 push 0
9 0083102c ff1500508300 call dword ptr [hi!_imp__MessageBoxA (00835000)]
10 00831032 33c0 xor eax,eax
10 00831034 8be5 mov esp,ebp
10 00831036 5d pop ebp
10 00831037 c3 ret
¿Donde esta msg? En la sección de datos .data, veamosla:
0:000> db 4000+hi.exe
00834000 68 6f 6c 61 00 00 00 00-00 00 00 00 00 00 00 00 hola............
Hay sección omitidas arriba, las vamos a obviar para simplificar. Y si vamos agregando funciones seran ubicadas en la sección de codigo (.code) por defecto.