Банк рефератов содержит более 364 тысяч рефератов, курсовых и дипломных работ, шпаргалок и докладов по различным дисциплинам: истории, психологии, экономике, менеджменту, философии, праву, экологии. А также изложения, сочинения по литературе, отчеты по практике, топики по английскому.
Полнотекстовый поиск
Всего работ:
364150
Теги названий
Разделы
Авиация и космонавтика (304)
Административное право (123)
Арбитражный процесс (23)
Архитектура (113)
Астрология (4)
Астрономия (4814)
Банковское дело (5227)
Безопасность жизнедеятельности (2616)
Биографии (3423)
Биология (4214)
Биология и химия (1518)
Биржевое дело (68)
Ботаника и сельское хоз-во (2836)
Бухгалтерский учет и аудит (8269)
Валютные отношения (50)
Ветеринария (50)
Военная кафедра (762)
ГДЗ (2)
География (5275)
Геодезия (30)
Геология (1222)
Геополитика (43)
Государство и право (20403)
Гражданское право и процесс (465)
Делопроизводство (19)
Деньги и кредит (108)
ЕГЭ (173)
Естествознание (96)
Журналистика (899)
ЗНО (54)
Зоология (34)
Издательское дело и полиграфия (476)
Инвестиции (106)
Иностранный язык (62792)
Информатика (3562)
Информатика, программирование (6444)
Исторические личности (2165)
История (21320)
История техники (766)
Кибернетика (64)
Коммуникации и связь (3145)
Компьютерные науки (60)
Косметология (17)
Краеведение и этнография (588)
Краткое содержание произведений (1000)
Криминалистика (106)
Криминология (48)
Криптология (3)
Кулинария (1167)
Культура и искусство (8485)
Культурология (537)
Литература : зарубежная (2044)
Литература и русский язык (11657)
Логика (532)
Логистика (21)
Маркетинг (7985)
Математика (3721)
Медицина, здоровье (10549)
Медицинские науки (88)
Международное публичное право (58)
Международное частное право (36)
Международные отношения (2257)
Менеджмент (12491)
Металлургия (91)
Москвоведение (797)
Музыка (1338)
Муниципальное право (24)
Налоги, налогообложение (214)
Наука и техника (1141)
Начертательная геометрия (3)
Оккультизм и уфология (8)
Остальные рефераты (21697)
Педагогика (7850)
Политология (3801)
Право (682)
Право, юриспруденция (2881)
Предпринимательство (475)
Прикладные науки (1)
Промышленность, производство (7100)
Психология (8694)
психология, педагогика (4121)
Радиоэлектроника (443)
Реклама (952)
Религия и мифология (2967)
Риторика (23)
Сексология (748)
Социология (4876)
Статистика (95)
Страхование (107)
Строительные науки (7)
Строительство (2004)
Схемотехника (15)
Таможенная система (663)
Теория государства и права (240)
Теория организации (39)
Теплотехника (25)
Технология (624)
Товароведение (16)
Транспорт (2652)
Трудовое право (136)
Туризм (90)
Уголовное право и процесс (406)
Управление (95)
Управленческие науки (24)
Физика (3463)
Физкультура и спорт (4482)
Философия (7216)
Финансовые науки (4592)
Финансы (5386)
Фотография (3)
Химия (2244)
Хозяйственное право (23)
Цифровые устройства (29)
Экологическое право (35)
Экология (4517)
Экономика (20645)
Экономико-математическое моделирование (666)
Экономическая география (119)
Экономическая теория (2573)
Этика (889)
Юриспруденция (288)
Языковедение (148)
Языкознание, филология (1140)

Статья: Работа с процессами в С/С++. Основные приемы

Название: Работа с процессами в С/С++. Основные приемы
Раздел: Рефераты по информатике, программированию
Тип: статья Добавлен 01:29:06 19 марта 2007 Похожие работы
Просмотров: 227 Комментариев: 2 Оценило: 0 человек Средний балл: 0 Оценка: неизвестно     Скачать

Тимур Хабибуллин

Данная статья рассказывает о работе с процессами, модулями, кучами и потоками при помощи билиотеки TOOLHELP

Работа с процессами - основа, без которой заниматься системным программированием так же бессмысленно, как без знания структуры PE-файлов или организации памяти. Поэтому я поднимаю эту тему вновь и расскажу о работе с процессами посредством функций TOOLHELP.

Язык программирования: я выбрал C (без плюсиков, т.к. работы с классами в этой статье не будет - после прочтения вы сможете их без труда составить сами) по многим причинам и в первую очередь из-за его низкоуровнего взаимодействия с памятью...записал-считал, все просто и понятно.

Перечислить запущенные в системе процессы можно по-разному, я привык пользоваться функциями TOOLHELP. Общая последовательность действий при работе с этой библиотекой: делаем "снимок" (Snapshot) системной информации, которая нам необходима, потом бегаем по процессам (а также модулям и кучам). Поэтому начнем с простого - перечислим все процессы.

//Перечисление процессов

int EnumerateProcs(void)

{

//создаем "снимок" информации о процессах

//первый параметр функции - константа, определяющая,

//какую информацию нам нужно "снять", а второй -

//идентификатор процесса, к которому относится эта

//информация. В данном случае это 0 т.к. мы делаем

//снимоквсехпроцессов

HANDLE pSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

bool bIsok = false;

//Структура, в которую будут записаны данные процесса

PROCESSENTRY32 ProcEntry;

//установим ее размер, это необходимое действие

ProcEntry.dwSize = sizeof(ProcEntry);

//теперь определим первый процесс

//первый параметр функции - хэндл "снимка" информации

//второй - адрес структуры PROCESSENTRY32

//true - в случае удачи, false - в случае неудачи

bIsok = Process32First(pSnap, &ProcEntry);

//здесь можно было вставить роскошный цикл for(....) но это

//не совсем удобочитаемо

//так что цикл while

while(bIsok)

{

//печатаем имя процесса, его идентификатор

//теперь, когда у нас есть структура ProcEntry

//То, какую информацию вы из нее возьмете, зависит

//толькоотзадачи ))

printf("%s %un", ProcEntry.szExeFile, ProcEntry.th32ProcessID);

bIsok = Process32Next(pSnap, &ProcEntry);

}

//чистимпамять!

CloseHandle(pSnap);

return 1;

}

Вуаля, список всех процессов, аки в диспетчере задач. Теперь мы сделаем кое-что, чего в диспетчере нет! В адресном пространстве каждого процесса (в области памяти, выделенной ему системой) находятся различные библиотеки, которые, собственно, состовляют ПРИЛОЖЕНИЕ. Это и Kernel32 и GDI и еще множество различных. Наша задача - их все пересчитать и переписать! Для этого действа напишем небольшую функцию.

//Перечисление модулей процесса

int EnumerateModules(DWORD PID)

{

//Входной параметр - идентификатор процесса, чьи модули мы собираемся

//перечислять. Во первых создадим snapshot информации о модулях

//теперь нам нужна информация о конкретном процессе - процессе

//сидентификатором PID

HANDLE pMdlSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PID);

bool bIsok = false;

//структура с информацией о модуле

MODULEENTRY32 MdlEntry;

//зададимразмер

MdlEntry.dwSize = sizeof(MODULEENTRY32);

//инайдемпервыймодуль

bIsok = Module32First(pMdlSnap, &MdlEntry);

//и далее, как и с процессами

while(bIsok)

{

//печатаем имя модуля

printf(" %s n", MdlEntry.szModule);

//и переходим к следующему

bIsok = Module32Next(pMdlSnap, &MdlEntry);

}

//чистимпамять!

CloseHandle(pMdlSnap);

return 1;

}

А теперь немного притормозим и посмотрим, какую еще информацию о процессах и модулях мы получаем:

typedef struct tagPROCESSENTRY32 {

DWORD dwSize; //Рамерструктуры

DWORD cntUsage; //Число ссылк на процесс. Процесс уничтожается, //когда число ссылок становится 0

DWORD th32ProcessID; //Идентификатор процесса - необходим

//во многих функциях

DWORD th32DefaultHeapID; //Идентификатор основной кучи - имеет

//смысл только в функциях toolhelp

DWORD th32ModuleID; //идентификатор модуля - имеет

//смысл только в функциях toolhelp

DWORD cntThreads; //Число потоков

DWORD th32ParentProcessID; //Идентификатор родителя - возвращается

//Даже если родителя уже нет

LONG pcPriClassBase; //приоритет по умолчанию всех //создаваемых процессом потоков

DWORD dwFlags; //Зарезервировано

CHAR szExeFile[MAX_PATH]; //Собственно имя процесса

} PROCESSENTRY32,*PPROCESSENTRY32,*LPPROCESSENTRY32;

typedef struct tagMODULEENTRY32 {

DWORD dwSize; //размерструктуры

DWORD th32ModuleID; //идентификатормодуля

DWORD th32ProcessID; //идентификатор процесса, к которому относится

//модуль

DWORD GlblcntUsage; //общее число ссылок на этот модуль

DWORD ProccntUsage; //число ссылко в контексте процесса,

//по идентификатору которого был создан

//снэпшот. Если равен 65535 - модуль подгружен

//неявно

BYTE *modBaseAddr; //адрес модуля в контексте процесса

DWORD modBaseSize; //размер проекции

HMODULE hModule; //ссылка на модуль

char szModule[MAX_MODULE_NAME32 + 1]; //Имямодуля

char szExePath[MAX_PATH]; //Полныйпутькмодулю

} MODULEENTRY32,*PMODULEENTRY32,*LPMODULEENTRY32;

Обратитевнмание: ссылканамодуль (параметр hModule) - этопервыйбайтДОС-заголовка! Таким образом, мы получаем возможность работать с проекцией при некотором знании структуры PE-файлов. В частности мы можем прочиатать таблицу импорта, и, как правило, - даже переписать ее (это используется при перехвате АПИ). Параметр szExePath имеет свой "заскок" - иногда полный путь к модулю возвращается со странными вставками и, например, всесто "c:windowssystem32advapi32.dll" я иногда получаю "c:x86_proc_winsyspathadvapi32.dll". Как правило для системных задач средней сложности (перехват апи, или, наоборот, перехват стелсов) всего вышеописанного хватает. Но на этом возможности toolhelp не исчерпываются и теперь мы побегаем по потокам! Работа с потоками несколько отличается от работы с модулями - даже если мы сделаем снимок, задав идентификатор какого-либо процесса, функция Thread32Next не остановится, пока не пробежится по ВСЕМ потокам в системе. Поэтому мы должны проверять, к какому процессу принадлежит поток - благо, в структуре THREADENTRY32 есть член th32OwnerProcessID - идентификатор породившего поток процесса. Таким образом:

int EnumerateThreads(DWORD PID)

{

//Начнем с создания снимка

HANDLE pThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, PID);

bool bIsok = false;

//Структура, описывающая поток

THREADENTRY32 ThrdEntry;

//ставимразмер

ThrdEntry.dwSize = sizeof(THREADENTRY32);

//Беремпервыйпоток

bIsok = Thread32First(pThreadSnap, &ThrdEntry);

//и бегаем по всем потокам...

while (bIsok)

{

//проверяем, тому ли процессу принадлежит поток

if (ThrdEntry.th32OwnerProcessID == PID)

{

//Если да, то выводим некотурую информацию...

//Хоть она никому нафиг не нужна :о)

printf("%u %un", ThrdEntry.th32OwnerProcessID, ThrdEntry.th32ThreadID);

}

bIsok = Thread32Next(pThreadSnap, &ThrdEntry);

}

//незабываемчиститьпамять

CloseHandle(pThreadSnap);

return 1;

}

Ну вот, у нас есть потоки. Что еще осталось? Правильно, остались кучи. Здесь тоже все очень просто:

int EnumerateHeaps(DWORD PID)

{

//Первый параметр - идентификатор процесса

//а второй - основная куча

//Теперь делаем снимок, чтоб перечислить кучки...

HANDLE pSnapHeaps = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, PID);

bool bIsok = false;

bool bIsokHeap = false;

//Структура, в которую будут записываться данные списка кучи

HEAPLIST32 HpLst;

//Структура, в которую будут записываться данные

//непосредствнно БЛОКОВ КУЧИ

HEAPENTRY32 HpEntry;

//Ставим размеры...

HpLst.dwSize = sizeof(HEAPLIST32);

HpEntry.dwSize = sizeof(HEAPENTRY32);

bIsok = Heap32ListFirst(pSnapHeaps, &HpLst);

while (bIsok)

{

//Теперь перечисляем блоки кучи

//этот код я привел, чтобы стало ясно

//как получить данные по блокам

//но он жрет много времени

//так что я его закомментирую - если вам интересно

//можетепогонять...

/*bIsokHeap = Heap32First(&HpEntry, PID, HpLst.th32HeapID);

while(bIsokHeap)

{

//Выводимнемногоинформации

printf("%u n", HpEntry.dwBlockSize);

//Шагаемдальше

bIsokHeap = Heap32Next(&HpEntry);

}*/

//выводим инфу о куче в общем

printf("%u n", HpLst.dwSize);

//шагаемдальше

bIsok = Heap32ListNext(pSnapHeaps, &HpLst);

}

CloseHandle(pSnapHeaps);

return 1;

}

Нувот, теперьтокаосталосьнаписатьоструктурах THREADENTRY32, HEAPENTRY32 и HEAPLIST32:

typedef struct tagTHREADENTRY32{

DWORD dwSize; //размерструктуры

DWORD cntUsage; //числоссылок

DWORD th32ThreadID; //идентификатор

DWORD th32OwnerProcessID; //родительский процесс

LONG tpBasePri; //основной приоритет (при инициализации)

LONG tpDeltaPri; //изменение приоритета

DWORD dwFlags; //зарезервировано

} THREADENTRY32;

typedef THREADENTRY32 * PTHREADENTRY32;

typedef THREADENTRY32 * LPTHREADENTRY32;

typedef struct tagHEAPENTRY32

{

DWORD dwSize; //размерструктуры

HANDLE hHandle; // хэндлэтогоблока

DWORD dwAddress; // линейныйадресначалаблока

DWORD dwBlockSize; // размер блока в байтах

DWORD dwFlags; //флаги

/*

LF32_FIXED Блок памяти имеет фиксированную позицию

LF32_FREE Блок памяти не используется

LF32_MOVEABLE Блок памяти может перемещаться

*/

DWORD dwLockCount; число "замков"

DWORD dwResvd; // зарезервировано

DWORD th32ProcessID; // родительскийпроцесс

DWORD th32HeapID; // идентификаторкучи

} HEAPENTRY32;

typedef HEAPENTRY32 * PHEAPENTRY32;

typedef HEAPENTRY32 * LPHEAPENTRY32;

typedef struct tagHEAPLIST32

{

DWORD dwSize; //размерструктуры

DWORD th32ProcessID; // родительский процесс

DWORD th32HeapID; //куча в контексте процесса

DWORD dwFlags; //флаг. Значение всегда одно:

// HF32_DEFAULT - основная куча процесса

} HEAPLIST32;

вызовы функций EnumerateHeaps, EnumerateThreads и EnumerateModules можно проводить из EnumerateProcs. Все скомпилино в Visual C++ 6.0. В тексте использована информация из MSDN и книги Джеффри Рихтера "Создание эффективных win32 приложений" (имхо эта книга - настольная для системного программиста).

Оценить/Добавить комментарий
Имя
Оценка
Комментарии:
Где скачать еще рефератов? Здесь: letsdoit777.blogspot.com
Евгений21:48:43 18 марта 2016
Кто еще хочет зарабатывать от 9000 рублей в день "Чистых Денег"? Узнайте как: business1777.blogspot.com ! Cпециально для студентов!
15:27:22 24 ноября 2015

Работы, похожие на Статья: Работа с процессами в С/С++. Основные приемы

Назад
Меню
Главная
Рефераты
Благодарности
Опрос
Станете ли вы заказывать работу за деньги, если не найдете ее в Интернете?

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



Результаты(150052)
Комментарии (1830)
Copyright © 2005-2016 BestReferat.ru bestreferat@mail.ru       реклама на сайте

Рейтинг@Mail.ru