SlideShare a Scribd company logo
1 of 189
Download to read offline
Windows Heap Exploitation
Angelboy
Windows Heap Exploitation
• Windows Memory Allocator

• NT heap

• BackEnd

• Exploitation

• FrontEnd

• LowFragmentationHeap

• Exploitation
Windows memory allocator
• Memory allocator in Win10 is very complicated, there are mainly two kind
of memory allocator.

• Nt Heap

• Default memory allocator

• SegmentHeap

• New memory allocator in Win10

• Some system process and UWP will use.
Windows memory allocator
• Nt Heap can be divided into

• Back-End

• Front-End

• LowFragmentationHeap

• In order to prevent memory fragmentation problem, it will enable LFH
after allocating a certain number of the same size of chunk. (e.g.
Continuously allocate same size of chunks 18 times)

• Size <= 0x4000
Windows memory allocator
• The slide based on win10 (1809)

• OS build - 17763.379

• Later versions may not be completely correct

• 1903 is very smimilar

• The structure of heap often change a lot. In the new release version,
you need to trace the structure and workflow by yourself.
Windows memory allocator
• Overview
Kernel32.dll
HeapAlloc
HeapFree
msvcrt140.dll
malloc
free
ntdll.dll
RtlAllocateHeap
RtlFreeHeap
ntdll.dll
RtlpAllocateHeap
RtlpFreeHeap
ntdll.dll
RtlpLowFragHeapAlloc
RtlpLowFragHeapFree
Kernel
Front-End
Back-End
Windows memory allocator
• When we call malloc if LFH is disable.
Kernel32.dll
HeapAlloc
HeapFree
msvcrt140.dll
malloc
free
ntdll.dll
RtlAllocateHeap
RtlFreeHeap
ntdll.dll
RtlpAllocateHeap
RtlpFreeHeap
Kernel
Back-End
Windows memory allocator
• When we call malloc at the first time or when 

memory pool called userblock of LFH is used 

up if LFH is enable. 

• It will use back-end allocator to allocate 

userblock for LFH.
Kernel32.dll
HeapAlloc
HeapFree
msvcrt140.dll
malloc
free
ntdll.dll
RtlAllocateHeap
RtlFreeHeap
ntdll.dll
RtlpAllocateHeap
RtlpFreeHeap
ntdll.dll
RtlpLowFragHeapAlloc
RtlpLowFragHeapFree
Kernel
Front-End
Back-End
Windows memory allocator
• When we allocate the same size after enabling LFH,

it will use front-end allocator and use userblock in 

LFH
Kernel32.dll
HeapAlloc
HeapFree
msvcrt140.dll
malloc
free
ntdll.dll
RtlAllocateHeap
RtlFreeHeap
ntdll.dll
RtlpLowFragHeapAlloc
RtlpLowFragHeapFree
Front-End
Windows memory allocator
• HEAP can be divide into

• Process Heap

• Default heap

• The heap shared by the entire process, it will be used when you use
windows API 

• Stored in _PEB

• Used in CRT function

• Stored in crt_heap
Windows memory allocator
• HEAP can be divide into

• Private heap

• Create by HeapCreate
Windows memory allocator
• Core data structure

• _HEAP_ENTRY (chunk)

• The basic structure of memory allocator

• It is different in front-end and back-end, but it use same name.
Windows memory allocator
• _HEAP_ENTRY (chunk)
data
chunk header
chunk header
data
_HEAP
chunk header
.
.
.
malloc return value
Windows memory allocator
• Core data structure

• _HEAP

• The core structure of memory allocator, it is used to manage the
heap.

• Each heap correspond to a _HEAP structure, usually at the
beginning of the heap
Windows memory allocator
• _HEAP

• EncodeFlagMask

• It will be set to 0x100000 after
heap initialization. It’s used to
determine whether to encode the
header of the chunk in the heap

• Encoding (_HEAP_ENTRY)

• It’s used to do xor with chunk
header
…
EncodeFlagMask0x7c
0x80
0x138
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
0x150
0x198
FrontEndHeapUsageData0x1a8
…
Windows memory allocator
• _HEAP

• BlocksIndex (_HEAP_LIST_LOOKUP_)

• The core structure in back-end
allocator used to manage chunks.

• FreeList (_HEAP_ENTRY)

• A linked list used to collect all freed
chunk in back-end

• Similar as unsorted bin in libc

• Sorted list
…
EncodeFlagMask0x7c
0x80
0x138
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
0x150
0x198
FrontEndHeapUsageData0x1a8
…
Windows memory allocator
• _HEAP

• FrontEndHeap

• A pointer pointed to the structure of
front-end heap

• FrontEndHeapUsageData

• Record the number of chunks used
by various sizes.

• When it reaches a certain level, it
will enable the Front-End allocator
of the corresponding chunk.
…
EncodeFlagMask0x7c
0x80
0x138
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
0x150
0x198
FrontEndHeapUsageData0x1a8
…
Windows memory allocator
• Nt Heap

• Back-End

• Front-End
Nt heap
• Nt Heap

• Back-End

• Data structure

• Memory allocation mechanism
Windows memory allocator
• _HEAP_ENTRY (chunk)

• Divided into

• Allocated chunk

• Freed chunk

• VirtualAlloc chunk
Nt heap
• _HEAP_ENTRY (chunk)

• PreviousBlockPrivateData

• The data of the previous chunk,
because chunk must be aligned to a
multiple of 0x10 

• Size

• The size of chunk.

• The value is right shift by 4 bits.
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
Nt heap
• _HEAP_ENTRY (chunk)

• Flag

• Indicates whether the chunk is busy

• SmallTagIndex

• Checksum is the xor of the first three
bytes

• It will be used to verify the header of
chunk
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
xor
Nt heap
• _HEAP_ENTRY (chunk)

• PreviousSize

• The size of previous chunk.

• The value is right shift by 4 bits.
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
Nt heap
• _HEAP_ENTRY (chunk)

• Unusedbyte

• The remaining size of chunk after
allocation

• It can be used to determine the status
of chunk (front-end or back-end)

• User Data

• The data used by user
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
Nt heap
• _HEAP_ENTRY (chunk)

• Flink

• Point to the next chunk in the linked list

• Blink

• Point to the previous chunk in the
linked list

• Unusedbyte 

• Must be zero
User Data
PreviousBlockPrivateData
(8byte)
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
freed
Flink
Blink
Nt heap
• _HEAP_VIRTUAL_ALLOC_ENTRY (mmap
chunk)

• Flink

• Point to the next chunk of VirtualAlloc

• Blink

• Point to the previous chunk of
VirtualAlloc
User Data
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
inused
Flink
Blink
…
Nt heap
• _HEAP_VIRTUAL_ALLOC_ENTRY (mmap
chunk)

• Size

• The size here refers to unused size
without shifting

• Unusedbyte

• Must be 4
User Data
Size (2byte)
Flag (1byte)
SmallTagIndex (1byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
inused
Flink
Blink
…
Nt heap
• FreeLists (_HEAP_ENTRY)

• After free a chunk, it will be placed in FreeLists and will be inserted in
FreeLists according to the size.
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
Nt heap
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateDat
…
EncodeFlagMask0x7c
0x80
0x138
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
0x150
0x198
FrontEndHeapUsageData0x1a8
…
Flink
Blink
_HEAP
Nt heap
• Remark

• About header encoding

• Every chunk header will be xor with _HEAP->Encoding

• It will be verified when it is decoded

• The verification method is to check whether the checksum is
correct.

• The xor of the first three bytes and compare with fourth byte.
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• It is mainly used to manage freed chunks of various sizes, so that it can
quickly find suitable chunks.
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• ExtendedLookup (_HEAP_LIST_LOOKUP)

• Point to next ExtendedLookup

• The next BlocksIndex will manage larger
chunks

• ArraySize

• The max chunk size that will be managed by
the BlocksIndex.

• The first BlocksIndex ArraySize will by 0x80
(Actually is 0x800)
BlocksIndex
ExtendedLookup0x0
ArraySize0x8
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
0x10
0x14
BaseIndex0x18
ListHead
ListsInUseUlong
ListHint
0x20
0x28
0x30
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• ItemCount

• The number of chunks in the
BlocksIndex

• OutofRangeItems

• The number of chunks that exceed
the size managed by this
BlocksIndex
BlocksIndex
ExtendedLookup0x0
ArraySize0x8
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
0x10
0x14
BaseIndex0x18
ListHead
ListsInUseUlong
ListHint
0x20
0x28
0x30
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• BaseIndex

• The starting index of the chunk in the
Blocksindex.

• It is used to find a suitable freed chunk in
ListHint

• The next BaseIndex of next BlocksIndex is the
maximum value of current BaseIndex.

• ListHead (_HEAP_ENTRY)

• FreeList 的 Head
BlocksIndex
ExtendedLookup0x0
ArraySize0x8
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
0x10
0x14
BaseIndex0x18
ListHead
ListsInUseUlong
ListHint
0x20
0x28
0x30
Nt heap
• BlocksIndex (_HEAP_LIST_LOOKUP)

• ListsInUseUlong

• Used to determine whether there is a suitable
chunk in ListHint, which is a bitmap

• ListHint 

• Important structure in back-end.

• A pointer array which point to the corresponding
size of chunk array.

• The goal is to find the suitable chunk faster.

• The interval of chunk size is 0x10
BlocksIndex
ExtendedLookup0x0
ArraySize0x8
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
0x10
0x14
BaseIndex0x18
ListHead
ListsInUseUlong
ListHint
0x20
0x28
0x30
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageDat
…
_HEAP
BlocksIndex
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivate
Flink
Blink
Chunk header(0x160)
PreviousBlockPrivat
ListHint
Flink
Flink
Flink
ListHint[7]
ListHint[0x11]
ListHint[0x16]
000001…1…1000000000
ListsInUseUlong
Nt heap
• Nt Heap

• Back-End

• Data structure

• Memory allocation mechanism
Nt heap
• Allocate (RtlpAllocateHeap)

• It can be divided into

• Size <= 0x4000

• 0x4000 < size <= 0xff000

• Size > 0xff000
Nt heap
• Allocate (RtlpAllocateHeap)

• Size <= 0x4000

• The memory allocation is implemented in RtlpAllocateHeap

• First, it will check whether FrontEndHeapStatusBitmap corresponds to the
size is set (which indicates if LFH is enabled)

• If not, add 0x21 to the corresponding FrontEndHeapUsageData

• And check if the value exceeds 0xff00 or (& 0x1f) is larger than 0x10

• If true, it will enable LFH.
Nt heap
• Allocate (RtlpAllocateHeap)

• Size <= 0x4000

• Next, it will check whether ListHint corresponds to the size has a value. If true, it will take
the chunk in ListHint first.

• If there is a suitable chunk on the ListHint, remove the ListHint, and see whether the size
of chunk's Flink is the same size.

• If true, replace the ListHint with Flink

• If not, clear the ListHint.

• Finally, unlink the chunk to remove the chunk from the linked list and return it to user.
Nt heap
• Allocate (RtlpAllocateHeap)

• Size <= 0x4000

• If there is no suitable chunk

• Search from the larger ListHint. If it finds a large one, remove it
from the ListHint.

• Then split the chunk and insert remaining chunk into freelist and
put into ListHint.
Nt heap
• Allocate (RtlpAllocateHeap)

• Size <= 0x4000

• If there is no suitable chunk in FreeList

• Try ExtendHeap to increase heap space, then take the chunk from
it
Nt heap
• Allocate (RtlpAllocateHeap)

• 0x4000 < size <= 0xff000

• Everything is similar except without LFH-related operations
Nt heap
• Allocate (RtlpAllocateHeap)

• Size > 0xff000 (VirtualMemoryThreshold << 4)

• Use ZwAllocateVirtualMemory directly

• Similar to mmap, it will allocate large memory block , and will be
inserted into _HEAP->VirtualAllocdBlocks

• _HEAP->VirtualAllocdBlocks is linked list used to collect all
VirtualAllocate chunk in back-end
Nt heap
• Free (RtlpFreeHeap)

• Divide into

• Size <= 0xff000 

• Size > 0xff000
Nt heap
• Free (RtlpFreeHeap)

• Size <= 0xff000 

• It will check the alignment first and use the unused byte to determine the
chunk state

• If LFH is disable, decrease 1 to the corresponding
FrontEndHeapUsageData

• Then it will check whether the previous chunk or next chunk is freed. If it is
freed, then coalesce them.

• Unlink the coalesced chunk and remove from ListHint.
Nt heap
• Free (RtlpFreeHeap)

• Size <= 0xff000 

• After the coalescence, update size & prevsize, and check whether it
is the front or last of FreeList. If true, then insert into FreeList. If not,
insert into ListHint and update it. 

• It will check the linked list integrity when inserting

• But this check won’t terminate the process.
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Free(Q)
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find Prevchunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Prevchunk =
Chunk address
-
(prevsize << 4)
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find Prevchunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Prevchunk =
chunk addr - 0x70
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Decode prevchunk

header
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check checksum
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
SmallTagInex ==

(size & 0xff)
xor
(size >> 8)
xor
Flag
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check checksum
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
7 ==

0x7^0x0^0x0
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

linked list
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
P->Flink->Blink == 

P->Blink->Flink == 

P
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find 

BlocksIndex
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find suitable 

BlocksIndex
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Check
P->size < ArraySize
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

ListHint
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Check
ListHint[7] ==
Prevchunk
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

ListHint
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Check
prevchunk->Flink ==
ListHead
If true, update

ListHint
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

ListHint[7]->Flink
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
decode
prevchunk->Flink
And check
the checksum
Because the previous
slide is not true, it

will check the size

of Flink
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

ListHint[7]->Flink
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Size == 

prevchunk->Flink->size
If true, replace ListHint

with Flink

ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Update

ListHint[7]
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
ListHint[7] =

prevchunk->Flink
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Unlink

prevchunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x7)
Flag (0x0)
SmallTagIndex (0x7)
Prevchunk->Blink->Flink

= Prevchunk->Flink

Prevchunk->Flink->Blink
= Prevchunk->Blink
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Update

prevchunk

and next chunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
Prevchunk->size =

0x11 + Prevchunk->size(7)
R->Prevsize = 0x18
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Check

next chunk
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
Check if next chunk

is freed
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Find suitable

BlocksIndex

For P
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
Check

P->Size < ArraySize
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Search

insert

point
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
Check

P->size <
ListHead->Blink->Size

P->size <
ListHead->Flink->Size
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Insert

linked list
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
Check

S->Blink->Flink

== S
If not pass it will not 

abort

But it will not unlink
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Update

ListHint
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x7)
If LintHint[0x18] == NULL

LintHint[0x18] = P
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
FlinkListHint[0x18]
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Update

header
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0x18)
Flag (0x0)
SmallTagIndex (0x18)
SmallTagIndex = 

(size >> 8) ^

(size & 0xff) ^

Flag
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
FlinkListHint[0x18]
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Flink
Blink
Chunk header(0x110)
PreviousBlockPrivat
FlinkListHint[7]
Flink
Blink
Chunk header(0x70)
PreviousBlockPrivat
merge chunk
P
Q
R
S
Encode

header
Size (0x11)
Flag (0x1)
SmallTagIndex (0x10)
Prevsize (0x7)
Size (0xda)
Flag (0xab)
SmallTagIndex (0x41)
P->header ^

_HEAP->Encoding
P
Flink
Blink
Chunk header (0x180)
PreviousBlockPrivate
FlinkListHint[0x18]
Nt heap
• Free (RtlpFreeHeap)

• Size > 0xff000 

• Check the linked list integrity and remove from _HEAP-
>VirtualAllocdBlocks

• Then use RtlpSecMemFreeVirtualMemory to munmap the chunk
Back-End Exploitation
• Unlink

• Similar bypass method in Linux.

• In short, use the behavior of removing nodes from linked list.

• It should be noted that the checksum must correct when decoding
chunk.

• The good thing is that Flink and Blink are directly point to UserData,
that is, you don’t have to forge chunk header
Back-End Exploitation
• Unlink

• Q->Blink->Flink = Q->Flink

• Q->Flink->Blink = Q->Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
QP R
Back-End Exploitation
• Unlink

• Q->Blink->Flink = Q->Flink

• Q->Flink->Blink = Q->Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
QP R
Back-End Exploitation
• Unlink

• Q->Blink->Flink = Q->Flink

• Q->Flink->Blink = Q->Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x110)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
QP R
Back-End Exploitation
• Unlink

• Q->Blink->Flink = Q->Flink

• Q->Flink->Blink = Q->Blink
Flink
Blink
Chunk header (0x70)
PreviousBlockPrivateData
Flink
Blink
Chunk header (0x160)
PreviousBlockPrivateData
QP R
A
A
Chunk header (0x110)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
UAF
T
A
A
A
Chunk header (0x110)
PreviousBlockPrivate
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
Free(Q)
T
A
Q
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
A
ListHead
QListHint[0x11]
free(S)
Update ListHint
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
A
S
SListHint[0x11]
Q
ListHead
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
A
S
SListHint[0x11]
Q
ListHead
Let’s corrupt the heap !
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
free(P)
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Check next chunk 

is free
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Decode 

chunk Q
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead(&Q-8)->Blink
==
(&Q)->Flink
== Q
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead(&Q-8)->Blink
==
(&Q)->Flink
== Q
Flink
Blink
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead(&Q-8)->Blink
==
(&Q)->Flink
== Q
Flink
Blink
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead*(&Q)
==
*(&Q)
== Q
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead*(&Q)
==
*(&Q)
== Q
Pass the check !!
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Find 

BlockIndex
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Check

ListHint[0x11]
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHeadBecause S != Q

it will not replace

ListHint with Q
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
Data Pointer
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Unlink !!
Q->Blink->Flink
= Q->Flink
Flink
Blink
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
&Q - 8
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHeadUnlink !!
Q = &Q-8
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
&Q - 8
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHead
Unlink !!
Q->Flink->Blink
= Q->Blink
Flink
Blink
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHeadUnlink !!
Q = &Q
S
A
Chunk header (0x110)
PreviousBlockPrivate
Q
Chunk header (0x110)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
P
Q
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
&Q - 8
&Q
SListHint[0x11]
Q
ListHeadUpdate 

chunk size
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHeadUpdate 

chunk size
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
Search insert point
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHeadFind the last one
And decode it
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
P
Find the first one
And decode it
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHeadIt want to insert 

in front of A
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
Check

A->Blink->Flink
== A
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
Check

Q->Flink
== A
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHeadFailed

but not aborting
It will not insert
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
Update 

ListHint
P
S
A
Chunk header (0x220)
PreviousBlockPrivate
Chunk header(0x50)
PreviousBlockPrivat
S
Chunk header(0x110)
PreviousBlockPrivat
R
S
P
&Q
R
S
T
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
BlockIndex
ListHint
T
A
SListHint[0x11]
Q
ListHead
P
PListHint[0x22]
Back-End Exploitation
• Edit Q

• We can overwrite the pointer around
Q

• Finally, we can do arbitrary
memory reading and writing.
P
&Q
R
S
T
Back-End Exploitation
• Edit Q

• We can overwrite the pointer around
Q

• Finally, we can do arbitrary
memory reading and writing.

• We can overwrite Target 1 - 4
P
Target 1
Target 2
Target 3
Target 4
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• ntdll.dll

• PebLdr

• binary address

• Kernel32.dll
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• kernelbase

• KERNELBASE!BasepFilterInfo

• Stack address
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• ntdll.dll

• _HEAP_LOCK

• _HEAP->LockVariable.Lock

• CriticalSection->DebugInfo

• Point to ntdll
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• ntdll!PebLdr

• _PEB_LDR_DATA

• You can find all the location of dll

• However the drawback is that the last two byte may be 0.

• You can find the binary base first and find kernel32 from IAT
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• BinaryBase

• Find kernel32 from IAT
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• Kernel32

• Important dll

• Many useful function(CreateFile, ReadFile,WriteFile) 

• IAT

• Find kernelbase.dll
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• kernelbase

• KERNELBASE!BasepFilterInfo

• Point to the structure on heap

• You have high probability to find stack pointer in the structure

• https://j00ru.vexillium.org/2016/07/disclosing-stack-data-from-the-default-
heap-on-windows/
Back-End Exploitation
• After arbitrary memory reading and writing

• Leak

• If there is no stack address in BasepFilterInfo

• You can find stack address in TEB which usually locate one page
before or after PEB
Back-End Exploitation
• After arbitrary memory reading and writing

• Write 

• Return address

• Control RIP

• ROP to VirtualProtect/VirtualAlloc

• Jmp to shellcode
Windows memory allocator
• Nt Heap

• Back-End

• Front-End
Windows memory allocator
• Nt Heap

• Front-End

• Commonly use in win10 

• LowFragmentationHeap

• Only enable in non-debug mode

• Size < 0x4000
Windows memory allocator
• Nt Heap

• Front-End

• Data Structure

• Memory allocation mechanism
Windows memory allocator
• Nt Heap

• Front-End

• Data Structure

• Memory allocation mechanism
LFH
• FrontEndHeap (_LFH_HEAP)

• HEAP (_HEAP)

• Point to the corresponding _HEAP

• Buckets (_HEAP_BUCKET)

• An array to find the malloc size
corresponding to the block size
…
Heap0x18
0x2a4
…
Buckets
SegmentInfoArray
…
…
LocalData
0x4a8
0xcc0
LFH
• FrontEndHeap (_LFH_HEAP)

• SegmentInfoArray
(_HEAP_LOCAL_SEGMENT_INFO)

• _HEAP_LOCAL_SEGMENT_INFO array

• Different sizes correspond to different
Segment_info structures, to manage the
information of the corresponding Subsegment.

• LocalData (_HEAP_LOCAL_DATA)

• One of the fields points to the LFH itself, which
is usually used to retrieve the LFH.
…
Heap0x18
…
Buckets
SegmentInfoArray
…
…
LocalData
0x2a4
0x4a8
0xcc0
LFH
• Buckets (_HEAP_BUCKET)

• BlockUnits

• The block size >> 4

• SizeIndex

• Required size >> 4
BlockUnits
Buckets
SizeIndex
…
BlockUnits
SizeIndex
…
…
…
Buckets[0]
Buckets[1]
LFH
• SegmentInfoArray
(_HEAP_LOCAL_SEGMENT_INFO)

• LocalData (_HEAP_LOCAL_DATA)

• Corresponding to _LFH_HEAP-
>LocalData to retrieve _LFH_HEAP
from SegmentInfo

• BucketIndex

• The index in Buckets[]
LocalData
SegmentInfoArray[x]
ActiveSubsegment
CachedItems
…
BucketIndex
…
LFH
• SegmentInfoArray
(_HEAP_LOCAL_SEGMENT_INFO)

• ActiveSubsegment (_HEAP_SUBSEGMENT)

• Very important structure

• Corresponding to the assigned Subsegment

• To maintain Userblock

• Record number of remaining chunk

• The maximum number of chunk in
Userblock
SegmentInfoArray[x]
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LFH
• SegmentInfoArray
(_HEAP_LOCAL_SEGMENT_INFO)

• CachedItems (_HEAP_SUBSEGMENT)

• _HEAP_SUBSEGMENT array

• Stored the available Subsegment
correspond to the SegmentInfo

• When the ActiveSubsegment used
up, it will reload from CachedItems.
SegmentInfoArray[x]
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LFH
…
Heap
…
…
…
LocalData
0x18
0x2a4
0x4a8
0xcc0
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageData
…
_HEAP
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LFH
• ActiveSubsegment (_HEAP_SUBSEGMENT)

• LocalInfo
(_HEAP_LOCAL_SEGMENT_INFO)

• Point back to corresponding
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
ActiveSubsegment
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
0x0
0x8
0x20
0x24
0x28
0x2a
LFH
• ActiveSubsegment (_HEAP_SUBSEGMENT)

• UserBlock (_HEAP_USERDATA_HEADER)

• Memory pool of LFH

• That is, the location of chunk (Block)

• Some metadata will manage the
chunks at the beginning of UserBlock

• Important !
LocalInfo
ActiveSubsegment
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
0x0
0x8
0x20
0x24
0x28
0x2a
LFH
• ActiveSubsegment (_HEAP_SUBSEGMENT)

• AggregateExchg (_INTERLOCK_SEQ)

• To indicate remaining amount of
freed chunk in Userblock

• LFH uses it to determine if it should
allocate from this UserBlock
LocalInfo
ActiveSubsegment
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
0x0
0x8
0x20
0x24
0x28
0x2a
LFH
• ActiveSubsegment (_HEAP_SUBSEGMENT)

• BlockSize

• The size of each block (chunk) in the
UserBlock

• BlockCount

• The number of blocks in the UserBlock

• SizeIndex

• The SizeIndex corresponding to the
UserBlock
LocalInfo
ActiveSubsegment
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
0x0
0x8
0x20
0x24
0x28
0x2a
LFH
• AggregateExchg (_INTERLOCK_SEQ)

• Depth

• The remaining amount of freed chunk in
UserBlock

• Lock

• Just a Lock
AggregateExchg
Depth0x0
Hint (15bit)
Lock (1bit)
0x8
LFH
• UserBlock (_HEAP_USERDATA_HEADER)

• SubSegment

• Point to corresponding Subsegment

• EncodeOffsets

• To verify chunk header integrity

• BusyBitmap

• Indicate which chunk is being used
SubSegment
UserBlock
…
EncodedOffsets
BusyBitmap
0x8
0x18
0x20
chunk header
chunk header
chunk header
LFH
• UserBlock (_HEAP_USERDATA_HEADER)

• Block (chunk)

• The allocated memory return to user.
SubSegment
UserBlock
…
EncodedOffsets
BusyBitmap
0x8
0x18
0x20
chunk header
chunk header
chunk header
LFH
• _HEAP_ENTRY (chunk)

• SubSegmentCode

• Encoded metadata to retrieve the
location of UserBlock

• PreviousSize

• The index of the chunk in UserBlock
User Data
PreviousBlockPrivateData
(8byte)
SubSegmentCode (4byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
LFH
• _HEAP_ENTRY (chunk)

• Unusedbyte

• Unusedbyte & 0x80 must be true

• To indicate it is LFH chunk
User Data
PreviousBlockPrivateData
(8byte)
SubSegmentCode (4byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Inused
LFH
• _HEAP_ENTRY (chunk)

• Unusedbytes

• Must be 0x80

• To indicate it is LFH freed chunk
User Data
PreviousBlockPrivateData
(8byte)
SubSegmentCode (4byte)
PreviousSize (2byte)
SegmentOffset (1byte)
Unusedbyte (1byte)
Freed
LFH
• Remark

• About EncodedOffsets

• EncodedOffsets is xor of the following values

• (sizeof(userblock header) | (BlockUnit*0x10 << 16))

• LFHkey

• Userblock address

• _LFH_HEAP address
LFH
• Remark

• About LFH header encoding

• The chunk header will xor with following values when initialization

• _HEAP address

• LFHkey

• Chunk address >> 4

• ((chunk address) - (UserBlock address)) << 12
LFH
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Windows memory allocator
• Nt Heap

• Front-End

• Data Structure

• Memory allocation mechanism
Windows memory allocator
• Nt Heap

• Front-End

• Initialization

• If FrontEndHeapUsageData[x] & 0x1f > 0x10, LFH will be initialized in next allocation

• It will ExtendFrontEndUsageData and create new BlocksIndex (0x80-0x400)

• Create FrontEndHeap

• Initialize SegmentInfoArrays[idx]

• It will start using front-end allocator from next allocation with same size
Windows memory allocator
• LFH(Initialization)

• malloc(0x40) * 16
FrontEndHeapUsageData
…
0x210
The range of LFH is index
from 0x0 to 0x80
Windows memory allocator
• LFH(Initialization)

• malloc(0x40) (17th)
FrontEndHeapUsageData
…
0x231 0x231 & 0x1f > 0x10
Windows memory allocator
• LFH(Initialization)
FrontEndHeapUsageData
…
0x231
heap->CompatibilityFlag |= 0x20000000
After setting this flag, it will initialize

LFH in the next allocation
Windows memory allocator
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageData
…
_HEAP
FrontEndHeapUsageData
0x231
BlocksIndex
ExtendedLookup
ArraySize
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex
ListHead
ListsInUseUlong
ListHint
Windows memory allocator
• LFH(Initialization)

• malloc(0x40) (18th)

• ExtendFrontEndUsageData and create new BlocksIndex
(0x80-0x400)

• The range of LFH is modified to index from 0x0 to
0x400

• Create and initialize FrontEndHeap (mmap)

• initialize SegmentInfoArrays[idx]

• Assign SegmentInfoArrays[BucketIndex] to
segmentInfo
FrontEndHeapUsageData
…
0x4
Windows memory allocator
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageData
…
_HEAP
FrontEndHeapUsageData
0x251 0x4
BlocksIndex
ExtendedLookup
ArraySize(0x80)
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex (0x0)
ListHead
ListsInUseUlong
ListHint
BlocksIndex
ExtendedLookup
ArraySize (0x400)
…
ItemCount (4 bytes)
OutofRangeItems (4 bytes)
BaseIndex (0x80)
ListHead
ListsInUseUlong
ListHint
Windows memory allocator
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
…
EncodeFlagMask
Encoding
…
BlocksIndex
…
FreeList
…
FrontEndHeap
…
FrontEndHeapUsageData
…
_HEAP
FrontEndHeapUsageData
0x251 0x4
Windows memory allocator
• LFH(Initialization)

• malloc(0x40) (19th)

• Allocate Userblock and initialize every
chunk.

• Set the corresponding ActiveSubsegment
to the UserBlock

• Randomly return chunk to user
Userblock metadata
Chunk 00
Chunk 01
…
Chunk MaxBlockCount
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Windows memory allocator
• LFH

• Allocate (RtlpLowFragHeapAllocFromContext)

• It will check whether ActiveSubsegment has chunk available.

• Check ActiveSubsegment->depth

• If not, it will search from CachedItem, and replace ActiveSubsegment
with CachedItem’s SubSegment if available.
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Find SegementIfoArray by bucket->SizeIndex
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Find SegementIfoArray by bucket->SizeIndex
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check ActiveSubsegment
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check ActiveSubsegment
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check ArgregateExchg.Depth not 0
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check ArgregateExchg.Depth not 0
…
Heap
…
…
…
LocalData
Buckets[x]
SegmentInfoArray[x]
BlockUnits
SizeIndex
…
_LFH_HEAP
_HEAP_BUCKET
_HEAP_LOCAL_SEGMENT_INFO
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
LocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
Check Userblock
Windows memory allocator
• LFH

• Allocate (RtlpLowFragHeapAllocFromContext)

• Retrieve RtlpLowFragHeapRandomData[x] 

• It will retrieve the value from RtlpLowFragHeapRandomData[x+1] next
round.

• x is 1 byte, x = rand() %256 after 256 rounds

• RtlpLowFragHeapRandomData is a 256-byte array filled with random value

• The range of random value is 0x0 - 0x7f
Windows memory allocator
• LFH

• Allocate (RtlpLowFragHeapAllocFromContext)

• Finally, the index of chunk is

• RtlpLowFragHeapRandomData[x]*maxidx >> 7 

• Take the nearest chunk if collision

• Check (unused byte & 0x3f) !=0 (indicate chunk is freed)

• Modify index and unused byte in header and return to user
….
….
….
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADER
• Get an index

• RtlpLowFragHeapRandomData[x]*maxidx >> 7

• Check if the BusyBitmap correspond to index is
0

• Return the chunk if true

• Otherwise take the next nearest chunk
chunk header
….
….
….
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADER
• If the index is inused 

• Take next nearest chunk

• Set the bitmap to 1
chunk header
….
….
….
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADER
chunk header
• If the index is inused 

• Take next nearest chunk

• Set the bitmap to 1
Windows memory allocator
• LFH

• Free (RtlFreeHeap)

• Update unused byte in chunk header

• Find the index of the Chunk and reset Userblock->BusyBitmap

• Update ActiveSubsegment->AggregateExchg

• If the free chunk is not belong to ActiveSubsegment, it will try to put
into cachedItems
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• Find UserBlock by chunk
header
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• Find UserBlock by chunk
header

• Find corresponding
SubSegment
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• Find UserBlock by chunk
header

• Find corresponding
SubSegment

• Assign unused byte to
0x80

• Clear the bitmap

• Update AggregateExchg
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• Find UserBlock by chunk
header

• Find corresponding
SubSegment

• Assign unused byte to
0x80

• Clear the bitmap

• Update AggregateExchg
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
Depth
Hint (15bit)
Lock (1bit)
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_INTERLOCK_SEQ
_HEAP_USERDATA_HEADER
• Free

• Find UserBlock by chunk
header

• Find corresponding
SubSegment

• Assign unused byte to
0x80

• Clear the bitmap

• Update AggregateExchg
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADERLocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
_HEAP_SUBSEGMENT
Depth (1)
Hint (15bit)
Lock (1bit)
_INTERLOCK_SEQ
CachedItems
ActiveSubsegment 

is not equivalent to

SubSegment of free

chunk
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
_HEAP_SUBSEGMENT
SubSegment
…
EncodedOffsets
BusyBitmap
chunk header
chunk header
chunk header
_HEAP_USERDATA_HEADERLocalData
ActiveSubsegment
CachedItems
…
BucketIndex
…
LocalInfo
UserBlock
…
AggregateExchg
BlockSzie
BlockCount
…
SizeIndex
…
_HEAP_SUBSEGMENT
Depth (1)
Hint (15bit)
Lock (1bit)
_INTERLOCK_SEQ
CachedItems
CachedItems[0]
LFH Exploitation
• Reuse attack

• If we have Use After Free

• Because of randomness of LFH, we can not predict the next chunk.

• We can fill up UserBlock and then free one of them, it will return
same chunk in next allocation with same size.
LFH Exploitation
• normal case

• malloc(sizeof(A))
Userblock header
LFH Exploitation
• normal case

• malloc(sizeof(B))
Userblock header
fptr
LFH Exploitation
• normal case

• free(A)
Userblock header B
fptr
LFH Exploitation
• normal case

• malloc(sizeof(A))
Userblock header B
fptr
LFH Exploitation
• normal case

• malloc(sizeof(B))
Userblock header B
fptr
LFH Exploitation
• normal case

• malloc(sizeof(B))
Userblock header B
fptr
Hard to use
LFH Exploitation
• Reuse attack 

• malloc(sizeof(A))
Userblock header
LFH Exploitation
• Reuse attack 

• malloc(sizeof(B)) x 6
Userblock header
fptr
LFH Exploitation
• Reuse attack 

• free(A)
Userblock header
B
B B B
fptr B B
LFH Exploitation
• Reuse attack 

• malloc(sizeof(B))
Userblock header
B
B B B
fptr B B
LFH Exploitation
• Reuse attack 

• A->fptr
Userblock header
B
B B B
fptr B B
LFH Exploitation
• Reuse attack 

• A->fptr
Userblock header
B
B B B
fptr B B
Hijack the control flow !
Reference
• https://github.com/saaramar/
35C3_Modern_Windows_Userspace_Exploitation

• http://illmatics.com/Understanding_the_LFH.pdf

• https://github.com/saaramar/Deterministic_LFH
Thank you for listening
angelboy@chroot.org @scwuaptx

More Related Content

What's hot

Pwning in c++ (basic)
Pwning in c++ (basic)Pwning in c++ (basic)
Pwning in c++ (basic)Angel Boy
 
Linux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeLinux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeAngel Boy
 
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote ShellcodeAj MaChInE
 
Advanced heap exploitaion
Advanced heap exploitaionAdvanced heap exploitaion
Advanced heap exploitaionAngel Boy
 
Modern Kernel Pool Exploitation: Attacks and Techniques
Modern Kernel Pool Exploitation: Attacks and TechniquesModern Kernel Pool Exploitation: Attacks and Techniques
Modern Kernel Pool Exploitation: Attacks and TechniquesMichael Scovetta
 
Linux Binary Exploitation - Return-oritend Programing
Linux Binary Exploitation - Return-oritend ProgramingLinux Binary Exploitation - Return-oritend Programing
Linux Binary Exploitation - Return-oritend ProgramingAngel Boy
 
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
50 Shades of Fuzzing by Peter Hlavaty & Marco GrassiShakacon
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented ProgrammingAngel Boy
 
HES2011 - Tarjei Mandt – Kernel Pool Exploitation on Windows 7
HES2011 - Tarjei Mandt – Kernel Pool Exploitation on Windows 7HES2011 - Tarjei Mandt – Kernel Pool Exploitation on Windows 7
HES2011 - Tarjei Mandt – Kernel Pool Exploitation on Windows 7Hackito Ergo Sum
 
Return to dlresolve
Return to dlresolveReturn to dlresolve
Return to dlresolveAngel Boy
 
TDOH x 台科 pwn課程
TDOH x 台科 pwn課程TDOH x 台科 pwn課程
TDOH x 台科 pwn課程Weber Tsai
 
ROP 輕鬆談
ROP 輕鬆談ROP 輕鬆談
ROP 輕鬆談hackstuff
 
CNIT 127 Ch 1: Before you Begin
CNIT 127 Ch 1: Before you BeginCNIT 127 Ch 1: Before you Begin
CNIT 127 Ch 1: Before you BeginSam Bowne
 
Binary exploitation - AIS3
Binary exploitation - AIS3Binary exploitation - AIS3
Binary exploitation - AIS3Angel Boy
 
台科逆向簡報
台科逆向簡報台科逆向簡報
台科逆向簡報耀德 蔡
 
Linux Kernel Booting Process (1) - For NLKB
Linux Kernel Booting Process (1) - For NLKBLinux Kernel Booting Process (1) - For NLKB
Linux Kernel Booting Process (1) - For NLKBshimosawa
 
NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27Sheng-Hao Ma
 
Vm escape: case study virtualbox bug hunting and exploitation - Muhammad Alif...
Vm escape: case study virtualbox bug hunting and exploitation - Muhammad Alif...Vm escape: case study virtualbox bug hunting and exploitation - Muhammad Alif...
Vm escape: case study virtualbox bug hunting and exploitation - Muhammad Alif...idsecconf
 
Social Engineering the Windows Kernel by James Forshaw
Social Engineering the Windows Kernel by James ForshawSocial Engineering the Windows Kernel by James Forshaw
Social Engineering the Windows Kernel by James ForshawShakacon
 

What's hot (20)

Pwning in c++ (basic)
Pwning in c++ (basic)Pwning in c++ (basic)
Pwning in c++ (basic)
 
Linux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeLinux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledge
 
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode[若渴計畫] Challenges and Solutions of Window Remote Shellcode
[若渴計畫] Challenges and Solutions of Window Remote Shellcode
 
Advanced heap exploitaion
Advanced heap exploitaionAdvanced heap exploitaion
Advanced heap exploitaion
 
x86
x86x86
x86
 
Modern Kernel Pool Exploitation: Attacks and Techniques
Modern Kernel Pool Exploitation: Attacks and TechniquesModern Kernel Pool Exploitation: Attacks and Techniques
Modern Kernel Pool Exploitation: Attacks and Techniques
 
Linux Binary Exploitation - Return-oritend Programing
Linux Binary Exploitation - Return-oritend ProgramingLinux Binary Exploitation - Return-oritend Programing
Linux Binary Exploitation - Return-oritend Programing
 
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
50 Shades of Fuzzing by Peter Hlavaty & Marco Grassi
 
Sigreturn Oriented Programming
Sigreturn Oriented ProgrammingSigreturn Oriented Programming
Sigreturn Oriented Programming
 
HES2011 - Tarjei Mandt – Kernel Pool Exploitation on Windows 7
HES2011 - Tarjei Mandt – Kernel Pool Exploitation on Windows 7HES2011 - Tarjei Mandt – Kernel Pool Exploitation on Windows 7
HES2011 - Tarjei Mandt – Kernel Pool Exploitation on Windows 7
 
Return to dlresolve
Return to dlresolveReturn to dlresolve
Return to dlresolve
 
TDOH x 台科 pwn課程
TDOH x 台科 pwn課程TDOH x 台科 pwn課程
TDOH x 台科 pwn課程
 
ROP 輕鬆談
ROP 輕鬆談ROP 輕鬆談
ROP 輕鬆談
 
CNIT 127 Ch 1: Before you Begin
CNIT 127 Ch 1: Before you BeginCNIT 127 Ch 1: Before you Begin
CNIT 127 Ch 1: Before you Begin
 
Binary exploitation - AIS3
Binary exploitation - AIS3Binary exploitation - AIS3
Binary exploitation - AIS3
 
台科逆向簡報
台科逆向簡報台科逆向簡報
台科逆向簡報
 
Linux Kernel Booting Process (1) - For NLKB
Linux Kernel Booting Process (1) - For NLKBLinux Kernel Booting Process (1) - For NLKB
Linux Kernel Booting Process (1) - For NLKB
 
NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27NTUSTxTDOH - Pwn基礎 2015/12/27
NTUSTxTDOH - Pwn基礎 2015/12/27
 
Vm escape: case study virtualbox bug hunting and exploitation - Muhammad Alif...
Vm escape: case study virtualbox bug hunting and exploitation - Muhammad Alif...Vm escape: case study virtualbox bug hunting and exploitation - Muhammad Alif...
Vm escape: case study virtualbox bug hunting and exploitation - Muhammad Alif...
 
Social Engineering the Windows Kernel by James Forshaw
Social Engineering the Windows Kernel by James ForshawSocial Engineering the Windows Kernel by James Forshaw
Social Engineering the Windows Kernel by James Forshaw
 

Similar to Windows 10 Nt Heap Exploitation (English version)

Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_heRecon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_heLiang Chen
 
Everything I Ever Learned About JVM Performance Tuning @Twitter
Everything I Ever Learned About JVM Performance Tuning @TwitterEverything I Ever Learned About JVM Performance Tuning @Twitter
Everything I Ever Learned About JVM Performance Tuning @TwitterAttila Szegedi
 
7 (or so) deadly sins - PLMCE 2015
7 (or so) deadly sins - PLMCE 20157 (or so) deadly sins - PLMCE 2015
7 (or so) deadly sins - PLMCE 2015Martin Arrieta
 
cache memory introduction, level, function
cache memory introduction, level, functioncache memory introduction, level, function
cache memory introduction, level, functionTeddyIswahyudi1
 
RecSplit Minimal Perfect Hashing
RecSplit Minimal Perfect HashingRecSplit Minimal Perfect Hashing
RecSplit Minimal Perfect HashingThomas Mueller
 
A survey on Heap Exploitation
A survey on Heap Exploitation A survey on Heap Exploitation
A survey on Heap Exploitation Alireza Karimi
 
Dynamic Memory Allocation(DMA)
Dynamic Memory Allocation(DMA)Dynamic Memory Allocation(DMA)
Dynamic Memory Allocation(DMA)Kamal Acharya
 
Linux Kernel Booting Process (2) - For NLKB
Linux Kernel Booting Process (2) - For NLKBLinux Kernel Booting Process (2) - For NLKB
Linux Kernel Booting Process (2) - For NLKBshimosawa
 
Cache Memory for Computer Architecture.ppt
Cache Memory for Computer Architecture.pptCache Memory for Computer Architecture.ppt
Cache Memory for Computer Architecture.pptrularofclash69
 
Computer organization memory hierarchy
Computer organization memory hierarchyComputer organization memory hierarchy
Computer organization memory hierarchyAJAL A J
 
Computer System Architecture Lecture Note 8.1 primary Memory
Computer System Architecture Lecture Note 8.1 primary MemoryComputer System Architecture Lecture Note 8.1 primary Memory
Computer System Architecture Lecture Note 8.1 primary MemoryBudditha Hettige
 
Webinar: Understanding Storage for Performance and Data Safety
Webinar: Understanding Storage for Performance and Data SafetyWebinar: Understanding Storage for Performance and Data Safety
Webinar: Understanding Storage for Performance and Data SafetyMongoDB
 
.NET Memory Primer
.NET Memory Primer.NET Memory Primer
.NET Memory PrimerMartin Kulov
 
Cache aware hybrid sorter
Cache aware hybrid sorterCache aware hybrid sorter
Cache aware hybrid sorterManchor Ko
 
D2 t2 steven seeley - ghost in the windows 7 allocator
D2 t2   steven seeley - ghost in the windows 7 allocatorD2 t2   steven seeley - ghost in the windows 7 allocator
D2 t2 steven seeley - ghost in the windows 7 allocator_mr_me
 

Similar to Windows 10 Nt Heap Exploitation (English version) (20)

Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_heRecon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
Recon2016 shooting the_osx_el_capitan_kernel_like_a_sniper_chen_he
 
Everything I Ever Learned About JVM Performance Tuning @Twitter
Everything I Ever Learned About JVM Performance Tuning @TwitterEverything I Ever Learned About JVM Performance Tuning @Twitter
Everything I Ever Learned About JVM Performance Tuning @Twitter
 
04 cache memory
04 cache memory04 cache memory
04 cache memory
 
7 (or so) deadly sins - PLMCE 2015
7 (or so) deadly sins - PLMCE 20157 (or so) deadly sins - PLMCE 2015
7 (or so) deadly sins - PLMCE 2015
 
Lecture 25
Lecture 25Lecture 25
Lecture 25
 
cache memory
 cache memory cache memory
cache memory
 
cache memory
cache memorycache memory
cache memory
 
cache memory introduction, level, function
cache memory introduction, level, functioncache memory introduction, level, function
cache memory introduction, level, function
 
RecSplit Minimal Perfect Hashing
RecSplit Minimal Perfect HashingRecSplit Minimal Perfect Hashing
RecSplit Minimal Perfect Hashing
 
A survey on Heap Exploitation
A survey on Heap Exploitation A survey on Heap Exploitation
A survey on Heap Exploitation
 
Dynamic Memory Allocation(DMA)
Dynamic Memory Allocation(DMA)Dynamic Memory Allocation(DMA)
Dynamic Memory Allocation(DMA)
 
Linux Kernel Booting Process (2) - For NLKB
Linux Kernel Booting Process (2) - For NLKBLinux Kernel Booting Process (2) - For NLKB
Linux Kernel Booting Process (2) - For NLKB
 
Cache Memory for Computer Architecture.ppt
Cache Memory for Computer Architecture.pptCache Memory for Computer Architecture.ppt
Cache Memory for Computer Architecture.ppt
 
Computer organization memory hierarchy
Computer organization memory hierarchyComputer organization memory hierarchy
Computer organization memory hierarchy
 
Computer System Architecture Lecture Note 8.1 primary Memory
Computer System Architecture Lecture Note 8.1 primary MemoryComputer System Architecture Lecture Note 8.1 primary Memory
Computer System Architecture Lecture Note 8.1 primary Memory
 
Webinar: Understanding Storage for Performance and Data Safety
Webinar: Understanding Storage for Performance and Data SafetyWebinar: Understanding Storage for Performance and Data Safety
Webinar: Understanding Storage for Performance and Data Safety
 
C dynamic ppt
C dynamic pptC dynamic ppt
C dynamic ppt
 
.NET Memory Primer
.NET Memory Primer.NET Memory Primer
.NET Memory Primer
 
Cache aware hybrid sorter
Cache aware hybrid sorterCache aware hybrid sorter
Cache aware hybrid sorter
 
D2 t2 steven seeley - ghost in the windows 7 allocator
D2 t2   steven seeley - ghost in the windows 7 allocatorD2 t2   steven seeley - ghost in the windows 7 allocator
D2 t2 steven seeley - ghost in the windows 7 allocator
 

Recently uploaded

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 

Recently uploaded (20)

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 

Windows 10 Nt Heap Exploitation (English version)