[Autogenerated] We've seen in previous courses what the address
space layout for processes looks like but I want to focus a bit
more on 64-bit systems in terms of the layout of the address space
for using what processes mainly.
Now, I'm not going to discuss 32-bit systems.
And one reason is that Windows 11 doesn't support 32 bit systems at all.
And even if you're working with earlier versions of Windows
32 bit systems are essentially going away.
So let's see what that looks like for 64-bit systems.
The most common case today is that you have a 64-bit
process when you have a 64-bit process,
you have access to 100 100 100 128 terabytes of address space.
Remember this is just an address space mostly empty
when the process starts its life,
we only have anti DLL and executable mapped into that
address space once the process begins its life but there's
definitely room to move around.
There's lots of room there.
In fact you can't really use all these address space today
because you don't have enough RAM and large enough page files to
accommodate that kind of large memory.
But the address space is fairly big.
Now there is the kernel space or system space which is also
128 terabyte in size in today's systems.
And again,
it doesn't mean that the kernel uses all that memory but the colonel has uh
that memory or that address space used to be more precise,
in fact, it uses that in a very interesting way,
for example, it's random.
There's certain pieces of memory within that address space to make
it harder for Attackers to utilize well known addresses when
trying to get access to certain memory locations by perhaps
invoking vulnerable kernel drivers.
Now, if we summarize or sum up 120 terabytes times two,
we get 256 terabytes terabytes,
which is nowhere near the limit for 64-bit systems,
which is 16 exabyte, that's giga, tera,
peta and then exa so obviously there is a large memory addresses here,
so really arrange of addresses which cannot be mapped today and
they're referred to in internal documentation as non canonical
addresses so they can't be used today.
Your intel processors actually support even more and
discuss that in the next slide with space.
So for 32 bit processes, here's what we get there.
In fact two cases here.
One of them is the case where the executable itself doesn't have a
flag called large address aware in its header,
in the in its pe header.
If it doesn't have that flag,
it gets two gigabytes of address space the same that it would get on a 32
bit system if it would be running on such a system.
I'll explain a moment what that flag is and why it matters and then if you
look at the other aspects we have the kernel memory,
which of course is unchanged.
It's the same kernel it's not on a per process basis.
Um it's just they're just like in the 64-bit process case and
then there's the range that spans two gigabytes to 128
terabytes that cannot be used by that.
32-bit process may be pieces of that are kind of obvious
because it can get these high addresses,
it only has 32 bits to work with,
but there's the extra two gigabytes which are not available either.
That explain the moment why that is.
So the last case is the case where we have a 32-bit executable
and the process is created based on that,
that does have the large address aware of flag in its speed header
and in that case it actually gets four gigabytes.
The full four gigabytes which are theoretically accessible by a
32-bit process because they're using 32-bit pointers.
So four gigabytes is the maximum that they can use obviously and again,
sister space doesn't change and there's still a big chunk of unusable
address space that can't really be used by 32-bit processes because they
can't see anything beyond four gigabytes now.
What is that flag?
Why is that important?
So here's the thing when you use two gigabytes only,
you just need 31 bits for an address and so uh programmers
sometimes are not very sane and they can say well I know that
the most significant bit is always zero because I'm not going
to get two gigabytes at most,
so maybe I'll use that bit for some application specific flag or whatever.
So every time it tries to access memory,
the first thing the code does is mask away that high bit,
the most significant bit and then makes the access And so having that flag in
the P header essentially says to windows or to the loader,
I'm okay accepting 32 bits in their entirety.
I don't have any specific um information I'm storing in the most integral bits.
So I don't care if I get two gigabytes or four gigabytes and this is
definitely recommended for 32-bit executable especially if they need more
memory than a normal two gigabyte address space would give,
which would be the standard case on the 32 bit Windows system.
So that's the difference.
There just just says two windows.
Hey,
I'm okay accepting 32-bit addresses and I'm not using the
most significant bit for any specific case.