In C#, accessing memory directly is considered “unmanaged memory”, while memory that is handled by the garbage collector and CLR is considered “managed”. As an example, allocating memory via Marshal.AllocHGlobal
will allocate unmanaged memory that can be written to via Marshal.Copy
. Creating a byte array like byte[] bruh = new byte[] { 0x00};
will create a managed byte array that the garbage compiler will handle. Working with the Windows API involves working with unmanaged memory. To provide interoperability between these things, stuff like Pinvoke is used and the System.Runtime.InteropServices
namespace.
Please read 0xrick’s post for a comprehensive, detailed explanation. This is very summarized
The PE Structure contains multiple parts
0x3c
bytes in is the e_lfanew
property which contain a Int32
of the distance between the base of the exe and the Nt Headers0x18
bytes into the NT headers. Within the Optional Headers are a lot of properties about the PE, such as the size of its code, the base of its code, and other information (helpful for loading it into memory).
IMAGE_DATA_DIRECTORY
structures.
IMAGE_DATA_DIRECTORY
structure has only 2 DWORD
(integer) values: The first is a Virtual Address (VA) to the location of the actual data directory, and the 2nd is the size of the Data directory.text
⇒ Contains the executable code of the program..data
⇒ Contains the initialized data, like global variables..bss
⇒ Contains uninitialized data..rdata
⇒ Contains read-only initialized data..edata
⇒ Contains the export tables..idata
⇒ Contains the import tables..reloc
⇒ Contains image relocation information. Executables often don’t have memory address range that they want allocated to them, so theres information on how to relocate them (useful for inline PE).rsrc
⇒ Contains resources used by the program, these include images, icons or even embedded binaries..tls
⇒ (Thread Local Storage), provides storage for every executing thread of the program.