Добавил:
github.com Кофедра ВТ-помойка Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Тимофеев 2018 / ОС 4 лаб.docx
Скачиваний:
26
Добавлен:
26.01.2019
Размер:
2.6 Mб
Скачать

Информация о процессе в livekd: 2338

Информация о VAD(virtual addres descriptor) приложения OS4.exe до вызова какой-либо функции:

Зарезервируем место в памяти (10 байт) в автоматическом режиме и посмотрим на изменения информации в VAD-Root.

Количество VADs увеличилось на 1. Появился виртуальный адресный дескриптор с характеристикой start = 7B0. Адрес, возвращаемый в программе при запросе резервирования памяти равен 7B0000. Commit = 1, что отражает количество предоставленных программе страниц виртуальной памяти.

Теперь зарезервируем 10 байт по адресу 0х12121515 в ручном режиме.

Появился ещё один VAD с характеристикой start 12100 и end 12121.

0x12120000 - 0x12121000 = 0x1000 = 4096 байт. Таким образом были зарезервирована 1 страница. Commit все также равен 1.

Попробуем зарезервировать больше памяти (17000 байт) по адресу 0х00030000

Количество VADs увеличилось на 1. Теперь Commit = 5 (5*4096 =20480), чего как раз хватает для использования 17000 байт.

Запишем число 451 в память по адресу 0х00030000

По сравнению с предыдущим скриншотом ничего не изменилось. Прочитаем содержимое ячеек памяти с базовым адресом 0x00030000

Число = показывает, что с помощью функции WriteProcessMemory данные были успешно записаны по адресу 0х00030000.

Теперь изменим protection option страницы по адресу 0x00030000 на NOACCESS

Отображение информации в VAD root о дескрипторе с полем start равном 30 не изменилось (READWRITE), возможно поле, отображающее атрибуты защиты, хранит атрибут защиты памяти при её инициализации, то есть только начальный.

Теперь освободим память, которую мы зарезервировали в процессе выполнения работы, а именно память по адресам: 0x12121515, 0x007B0000, 0x00030000:

Как видно количество VADs изменилось, пропали 3 дескриптора отвечающие за 3 адреса, по которым мы ранее зарезервировали память.

Вывод: в ОС windows 10 резервируемое количество памяти всегда кратно полю с dwAllocationGranularity структуры _SYSTEM_INFO, которое в моем случае оказалось равно = байт. При резервировании памяти, вводя начальный адрес ос выделяет регион страниц длиной кратной 32768 байт. Поле dwPageSize равное в моем случае 4096 байт = 0x1000 определяет размер страницы, то есть минимально выделяемое операционной системой количество памяти пользовательским процессам, так же это минимально адресуемое количество памяти для установления атрибутов защиты и освобождения памяти. Размер региона в байтах на скриншотах в лабораторной работе отражает размер подряд идущих страниц с одинаковыми значениями атрибутов.

Задание 4.3. Использование проецируемых файлов для обмена данными между процессами.

Информация о VAD root каждого из процессов до вызова каких-либо функций:

reader.exe

writer.exe

Откроем дескриптор файла размером 55 байт и создадим объект в программе writer.exe

Cпроецируем фрагмент в 13 байт файла file.txt размером 55 байт на ОЗУ

Количество VADs увеличилось на 1. Появился новый VAD с характеристикой mapped.

Введем 333 в спроецированный на ОЗУ файл:

Данные успешно записаны.

Теперь откроем существующий объект в reader.exe

Спроецируем фрагмент файла:

Количество VADs увеличилось на 1. Появился новый VAD с характеристикой mapped.

Просмотрим содержимое памяти отображенного на ОЗУ файла file.txt

Просмотрим содержимое памяти с помощью livekd:

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

Вывод: с помощью WinApi можно выполнить проецирование файлов на ОЗУ. Проецирование файлов — это ассоциация содержимого файла с некоторой областью виртуального адресного пространства процесса. Проецируемые файлы позволяют резервировать регион адресного пространства и передавать ему физическую память, которая не выделяется из страничного файла, а берется из файла, уже находящегося на диске. Как только файл спроецирован в память, к нему можно обращаться так, будто он целиком в нее загружен. Это позволяет обойтись без операций файлового ввода-вывода и буферизации его содержимого, а также разделить данные между несколькими процессами, выполняемыми на одной машине.

#include <iostream>

#include "VM.h"

using namespace std;

int menu();

int main() {

setlocale(0, ".1251");

int notExit;

do {

switch (notExit = menu())

{

case 1:

systemInfo();

break;

case 2:

virtualMemoryStatus();

break;

case 3:

virtualPageStatus(0);

break;

case 4:

separateReserveCommit();

break;

case 5:

simultaneousReserveCommit();

break;

case 6:

writeData();

break;

case 7:

protectVirtualPage();

break;

case 8:

freeVirtualPage(0);

break;

case 0:

break;

default:

if (notExit)

cout << "Error" << endl;

}

if (notExit)

system("pause");

} while (notExit);

return 0;

}

int menu()

{

system("cls");

int point;

do {

cin.clear();

cin.sync();

cout << "Select menu item" << endl;

cout << "1 - About system" << endl;

cout << "2 - Memory status" << endl;

cout << "3 - State of the virtual memory area" << endl;

cout << "4 - Separate region redundancy and physical memory transfer" << endl;

cout << "5 - Simultaneous reservation of a region and transfer of physical memory" << endl;

cout << "6 - Write data" << endl;

cout << "7 - Memory region access protection" << endl;

cout << "8 - Clear memory" << endl;

cout << "0 - Exit" << endl;

cout << "> ";

cin >> point;

if (cin.fail())

cout << "Error" << endl;

} while (cin.fail());

system("cls");

return point;

}

#include "VM.h"

using namespace std;

void systemInfo() {

_SYSTEM_INFO systemInfo;

//GetSystemInfo(&systemInfo); // GetSystemInfo

GetNativeSystemInfo(&systemInfo);

cout << "About system:" << endl;

cout << "Architecture: ";

switch (systemInfo.wProcessorArchitecture)

{

case 5:

cout << "ARM" << endl;

break;

case 6:

cout << "Intel Itanium-based" << endl;

break;

case PROCESSOR_ARCHITECTURE_AMD64:

cout << "x64 (AMD or Intel)" << endl;

break;

case PROCESSOR_ARCHITECTURE_INTEL:

cout << "Intel x86" << endl;

break;

default:

cout << "Non" << endl;

break;

}

cout << "Cores: " << systemInfo.dwNumberOfProcessors << endl;

cout << "Type of proc: ";

switch (systemInfo.dwProcessorType)

{

case 386:

cout << "Intel 386" << endl;

break;

case 486:

cout << "Intel 486" << endl;

break;

case 586:

cout << "Intel Pentium" << endl;

break;

case 2200:

cout << "Intel IA64" << endl;

break;

case 8664:

cout << "AMD x8664" << endl;

break;

default:

cout << "ARM" << endl;

break;

}

cout << "Proc level (CPU vendor): " << systemInfo.wProcessorLevel << endl;

cout << "Page size: " << systemInfo.dwPageSize << endl;

cout << "Min address for app: " << systemInfo.lpMinimumApplicationAddress << endl;

cout << "Max address for app: " << systemInfo.lpMaximumApplicationAddress << endl;

bitset<8> x(systemInfo.dwActiveProcessorMask);

cout << "Active cores: " << x << endl;

}

void virtualMemoryStatus() {

const int divider = 1024;

const int width = 12;

MEMORYSTATUSEX memoryStatusEx;

memoryStatusEx.dwLength = sizeof(memoryStatusEx);

GlobalMemoryStatusEx(&memoryStatusEx); // GlobalMemoryStatus

cout.width(width - 1);

cout << memoryStatusEx.dwMemoryLoad << "% in use\n";

cout.width(width);

cout << memoryStatusEx.ullTotalPhys / divider << " total Kb memory\n";

cout.width(width);

cout << memoryStatusEx.ullAvailPhys / divider << " available Kb memory\n";

cout.width(width);

cout << memoryStatusEx.ullTotalPageFile / divider << " total Kb paged file\n";

cout.width(width);

cout << memoryStatusEx.ullAvailPageFile / divider << " available Kb paged file\n";

cout.width(width);

cout << memoryStatusEx.ullTotalVirtual / divider << " total Kb virtual memory\n";

cout.width(width);

cout << memoryStatusEx.ullAvailVirtual / divider << " available Kb virtual memory\n";

cout.width(width);

cout << memoryStatusEx.ullAvailExtendedVirtual / divider << " availabe Kb extended memory\n";

}

void virtualPageStatus(DWORD address) {

MEMORY_BASIC_INFORMATION memoryInfo;

SYSTEM_INFO systemInfo;

GetSystemInfo(&systemInfo);

if (!address) {

cout << "Enter an address in the range of 0x" << systemInfo.lpMinimumApplicationAddress

<< " before 0x" << systemInfo.lpMaximumApplicationAddress << "): 0x";

cin >> hex >> address;

}

VirtualQuery((LPCVOID)address, &memoryInfo, sizeof(memoryInfo));

cout << "Base address: 0x" << memoryInfo.BaseAddress << endl;

cout << "Base address of allocated memory: 0x" << memoryInfo.AllocationBase << endl;

cout << "Region size: " << memoryInfo.RegionSize << endl;

cout << "Access mode: 0x" << hex << memoryInfo.Protect << endl;

if (memoryInfo.Protect & PAGE_NOACCESS) cout << " PAGE_NOACCESS" << endl;

if (memoryInfo.Protect & PAGE_READONLY) cout << " PAGE_READONLY" << endl;

if (memoryInfo.Protect & PAGE_READWRITE) cout << " PAGE_READWRITE" << endl;

if (memoryInfo.Protect & PAGE_EXECUTE_WRITECOPY) cout << " PAGE_EXECUTE_WRITECOPY" << endl;

if (memoryInfo.Protect & PAGE_EXECUTE) cout << " PAGE_EXECUTE" << endl;

if (memoryInfo.Protect & PAGE_EXECUTE_READ) cout << " PAGE_EXECUTE_READ" << endl;

if (memoryInfo.Protect & PAGE_EXECUTE_READ) cout << " PAGE_EXECUTE_READ" << endl;

if (memoryInfo.Protect & PAGE_EXECUTE_READWRITE) cout << " PAGE_EXECUTE_READWRITE" << endl;

if (memoryInfo.Protect & PAGE_EXECUTE_WRITECOPY) cout << " PAGE_EXECUTE_WRITECOPY" << endl;

if (memoryInfo.Protect & PAGE_GUARD) cout << " PAGE_GUARD" << endl;

if (memoryInfo.Protect & PAGE_NOCACHE) cout << " PAGE_NOCACHE" << endl;

if (memoryInfo.Protect & PAGE_WRITECOMBINE) cout << " PAGE_WRITECOMBINE" << endl;

cout << "Page status: 0x" << hex << memoryInfo.State << endl;

if (memoryInfo.State & MEM_COMMIT) cout << " MEM_COMMIT" << endl;

if (memoryInfo.State & MEM_FREE) cout << " MEM_FREE" << endl;

if (memoryInfo.State & MEM_RESERVE) cout << " MEM_RESERVE" << endl;

cout << "Page type: 0x" << hex << memoryInfo.Type << endl;

if (memoryInfo.Type & MEM_IMAGE) cout << " MEM_IMAGE" << endl;

if (memoryInfo.Type & MEM_MAPPED) cout << " MEM_MAPPED" << endl;

if (memoryInfo.Type & MEM_PRIVATE) cout << " MEM_PRIVATE" << endl;

cout << dec;

}

void separateReserveCommit() {

PVOID pMemory = 0;

PVOID pBaseAddress = 0;

DWORD dwSize = 0;

cout << "Base address (0 to automatically set the address by the system): 0x";

cin >> hex >> pBaseAddress;

cout << "Size (in bytes): ";

cin >> dec >> dwSize;

pMemory = VirtualAlloc(pBaseAddress, dwSize, MEM_RESERVE, PAGE_READWRITE);

if (pMemory != NULL) {

cout << "\n\nMemory reserved: \n";

virtualPageStatus((DWORD)pMemory);

}

else {

cout << "Failed to allocate memory!" << endl;

return;

}

pMemory = VirtualAlloc(pMemory, dwSize, MEM_COMMIT, PAGE_READWRITE);

if (pMemory != NULL) {

cout << "\n\nMemory used:\n";

virtualPageStatus((DWORD)pMemory);

}

else {

cout << "Failed to allocate memory!" << endl;

return;

}

}

void simultaneousReserveCommit() {

PVOID pMemory = 0;

PVOID pBaseAddress = 0;

DWORD dwSize = 0;

cout << "Base address (0 to automatically set the address by the system): 0x";

cin >> hex >> pBaseAddress;

cout << "Размер (в байтах): ";

cin >> dec >> dwSize;

pMemory = VirtualAlloc(pBaseAddress, dwSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

if (pMemory != NULL) {

cout << "\n\nMemory allocated: \n";

virtualPageStatus((DWORD)pMemory);

}

else {

cout << "Failed to allocate memory!" << endl;

return;

}

}

void writeData() {

PVOID pMemory = 0;

PVOID pBaseAddress = 0;

DWORD dwSize = 0;

int data = 0;

cout << "Base address (0 to automatically set the address by the system): 0x";

cin >> hex >> pBaseAddress;

MEMORY_BASIC_INFORMATION memoryInfo;

VirtualQuery((LPCVOID)pBaseAddress, &memoryInfo, sizeof(memoryInfo));

if (memoryInfo.Protect & PAGE_NOACCESS) {

cout << "Memory is protected" << endl;

return;

}

cout << "Data: ";

cin >> dec >> data;

if (pBaseAddress) {

memcpy(pBaseAddress, &data, sizeof(int));

cout << "Memory reading (0x" << hex << pBaseAddress << dec << "): " << (*(PDWORD)pBaseAddress) << endl;

}

else {

pMemory = VirtualAlloc(pBaseAddress, sizeof(int), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

memcpy(pMemory, &data, sizeof(int));

cout << "Memory reading (0x" << hex << pMemory << dec << "): " << (*(PDWORD)pMemory) << endl;

}

}

void protectVirtualPage() {

PVOID pMemory = 0;

PVOID pBaseAddress = 0;

DWORD dwSize = 0;

cout << "Base address (0 to automatically set the address by the system): 0x";

cin >> hex >> pBaseAddress;

if (pBaseAddress) {

DWORD flOldProtect = 0;

VirtualProtect(pBaseAddress, sizeof(int), PAGE_NOACCESS, &flOldProtect);

cout << "\n\nMemory is protected: \n";

virtualPageStatus((DWORD)pBaseAddress);

}

else {

pMemory = VirtualAlloc(pBaseAddress, sizeof(int), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

if (pMemory != NULL) {

cout << "\n\nMemory allocated: \n";

virtualPageStatus((DWORD)pMemory);

}

DWORD flOldProtect = 0;

VirtualProtect(pMemory, sizeof(int), PAGE_NOACCESS, &flOldProtect);

cout << "\n\nMemory is protected: \n";

virtualPageStatus((DWORD)pMemory);

VirtualFree(pMemory, 0, MEM_RELEASE);

}

}

void freeVirtualPage(DWORD address) {

PVOID pMemory = 0;

if (!address) {

SYSTEM_INFO systemInfo;

GetSystemInfo(&systemInfo);

cout << "Enter an address in the range of 0x" << systemInfo.lpMinimumApplicationAddress

<< " before 0x" << systemInfo.lpMaximumApplicationAddress << "): 0x";

cin >> hex >> address;

}

VirtualFree((LPVOID)address, 0, MEM_RELEASE);

cout << "\n\nMemory cleared: \n";

virtualPageStatus((DWORD)address);

}

#pragma once

#define WINVER 0x0500

#include <iostream>

#include <windows.h>

#include <winbase.h>

#include <io.h>

#include <stdio.h>

#include <tchar.h>

#include <string>

#include <bitset>

void systemInfo();

void virtualMemoryStatus();

void virtualPageStatus(DWORD address);

void separateReserveCommit();

void simultaneousReserveCommit();

void writeData();

void protectVirtualPage();

void freeVirtualPage(DWORD address);

#include <iostream>

#include <windows.h>

#include <stdio.h>

using namespace std;

int main()

{

setlocale(0, ".1251");

HANDLE hFile;

HANDLE hMapFile;

LPVOID lpMapAddress;

LPCSTR filename = "file.txt";

char data[1024];

DWORD fSize;

DWORD bytesToMap;

system("pause");

cout << "Create file" << endl;

hFile = CreateFileA(filename, GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile != INVALID_HANDLE_VALUE)

cout << "File file.txt created successfully" << endl;

else

cout << "Error! The file was not created." << endl;

cout << "Size of file: ";

cin >> fSize;

hMapFile = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, 0, fSize, "mapFile");

if (hMapFile != INVALID_HANDLE_VALUE)

cout << "Object mapping created" << endl;

else

cout << "Error! The object mapping was not created." << endl;

system("pause");

cout << "Projecting file in memory" << endl;

cout << "Enter the number of bytes.: ";

cin >> bytesToMap;

lpMapAddress = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, bytesToMap);

cout << "Projecting completed" << endl;

system("pause");

cout << "Recording data to file" << endl;

cout << "Enter data: ";

cin >> data;

memcpy(lpMapAddress, data, strlen(data));

cout << "Projection Address: " << lpMapAddress << endl;

system("pause");

UnmapViewOfFile(lpMapAddress);

CloseHandle(hMapFile);

CloseHandle(hFile);

return 0;

}

#include <iostream>

#include <windows.h>

using namespace std;

int main()

{

setlocale(0, ".1251");

HANDLE hMapFile;

PVOID lpMapAddress;

char data[1024];

system("pause");

cout << "Opening file" << endl;

hMapFile = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "mapFile");

if (hMapFile != INVALID_HANDLE_VALUE)

cout << "The projected file is open.\n";

else

cout << "Error! The projected file was not open\n";

system("pause");

cout << "Projection of memory file fragment" << endl;

lpMapAddress = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);

if (lpMapAddress == 0) {

cerr << "Unable to open file projection\n";

system("pause");

return 1;

}

else

cout << "Projection is complete." << endl;

system("pause");

cout << "Read file" << endl;

memcpy(data, (char*)lpMapAddress, 1024);

cout << "Data at address " << lpMapAddress << ": " << data << endl;

system("pause");

UnmapViewOfFile(lpMapAddress);

CloseHandle(hMapFile);

return 0;

}

Соседние файлы в папке Тимофеев 2018