Добавил:
Kaz
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лаба 1-6 Системное программирование для ОС Windows [Вариант отсутствует, общий] / Лаба 6 / Code / MyUserModeApp / MyUserModeApp
.cpp// MyUserModeApp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#pragma comment(lib,"Psapi.lib")
TCHAR ProcessName[MAX_PATH] = L"\\Device\\HarddiskVolume1\\WINDOWS\\system32\\notepad.exe";
SC_HANDLE m_hSCM;
SC_HANDLE m_hDriver;
BOOL m_bDriverStarted;
BOOL m_bErrorOnStart;
TCHAR m_szName[MAX_PATH];
TCHAR m_szInfo[MAX_PATH];
TCHAR m_szFullFileName[MAX_PATH];
HANDLE m_hDriverFile;
HANDLE hEvent;
BOOL InstallAndStart();
BOOL WaitForState(DWORD dwDesiredState, SERVICE_STATUS* pss);
BOOL GetProcessHostFullName(TCHAR* pszFullFileName);
BOOL ReplaceFileName(TCHAR* pszOldFileName,TCHAR* pszBaseNewFileName,TCHAR* pszNewFileName);
BOOL GetProcessName(DWORD dwProcessId,LPTSTR lpFileName, DWORD dwLen);
typedef struct _ProcessCallbackInfo
{
DWORD hParentId;
DWORD hProcessId;
BOOLEAN bCreate;
} PROCESS_CALLBACK_INFO, *PPROCESS_CALLBACK_INFO;
#define FILE_DEVICE_UNKNOWN 0x00000022
#define IOCTL_UNKNOWN_BASE FILE_DEVICE_UNKNOWN
#define IOCTL_PROCOBSRV_ACTIVATE_MONITORING \
CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_PROCOBSRV_GET_PROCINFO \
CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
int _tmain(int argc, _TCHAR* argv[])
{
m_hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);//устанавливает связь с диспетчером управления службами на указанном компьютере и открывает указанную базу данных диспетчера управления службами.
_tcscpy(m_szName, TEXT("ProcObsrv")); //копирует данные в буфер с указанным его размером во втором параметре -чтобы избежать переполнения
_tcscpy(m_szInfo, TEXT("Process creation detector."));
TCHAR szFullFileName[MAX_PATH];
GetProcessHostFullName(szFullFileName);//Получите Полное имя Хозяина Процесса
if ( TRUE == ReplaceFileName(szFullFileName, TEXT("ProcObsrv.sys"), m_szFullFileName) ) //заменить
{
InstallAndStart ();
}
m_hDriverFile = ::CreateFile(
TEXT("\\\\.\\ProcObsrv"),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0, // Default security
OPEN_EXISTING,
0, // Perform synchronous I/O
0); // No template
hEvent = ::OpenEvent(SYNCHRONIZE, FALSE, TEXT("ProcObsrvProcessEvent") );
if (hEvent == INVALID_HANDLE_VALUE)
{
MessageBoxA (0,"Error","Error",0);
}
bool bReturnCode;
OVERLAPPED ov = { 0 };
DWORD dwBytesReturned;
PROCESS_CALLBACK_INFO callbackInfo;
TCHAR szFileName[MAX_PATH];
while (true)
{
SwitchToThread(); //Переключитесь На Нить
WaitForSingleObject (hEvent,INFINITE);
bReturnCode = ::DeviceIoControl(//Функция DeviceIoControl отправляет управляющий код непосредственно указанному драйверу устройства, заставляя соответствующее устройство выполнить соответствующую операцию.
m_hDriverFile,
IOCTL_PROCOBSRV_GET_PROCINFO,
0,
0,
&callbackInfo, sizeof(callbackInfo),
&dwBytesReturned,
&ov
);
/*
BOOL DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
);
*/
bReturnCode = ::GetOverlappedResult( //будет дожидаться завершения выполнения операции
m_hDriverFile,
&ov,
&dwBytesReturned,
TRUE
);
GetProcessName(
callbackInfo.hProcessId,
szFileName,
MAX_PATH
);
if (wcscmp (szFileName,ProcessName)== 0) //Функция wcscmp является эквивалентом функции strcmp для широких символов. Она сравнивает строку широких символов, на которую указывает s1, со строкой широких символов, на которую указывает s2.
{
if (callbackInfo.bCreate == true)
{
MessageBoxA (0,"Калькулятор запущен","",0);
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(NULL, TEXT("WINMINE"), NULL, NULL, FALSE, 0, NULL. NULL, &si, &pi);
}
else
{
MessageBoxA (0,"Калькулятор закрыт","",0);
}
}
}
return 0;
}
BOOL InstallAndStart()
{
BOOL bResult = FALSE;
if (NULL != m_hSCM)
{
m_hDriver = ::CreateService(// создаёт объект сервиса и добавляет его в базу данных менеджера управления сервисами
m_hSCM,
m_szName,
m_szInfo,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
m_szFullFileName,
NULL,
NULL,
NULL,
NULL,
NULL
);
if (NULL == m_hDriver)
{
if ( (::GetLastError() == ERROR_SERVICE_EXISTS) ||
(::GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE) )
m_hDriver = ::OpenService(
m_hSCM,
m_szName,
SERVICE_ALL_ACCESS
);
}
if (NULL != m_hDriver)
{
SERVICE_STATUS serviceStatus = { 0 };
bResult = ::StartService(m_hDriver, 0, NULL);
if (bResult)
bResult = WaitForState(SERVICE_RUNNING, &serviceStatus);//Ожидает достижения службой заданного состояния или истечения заданного тайм-аута.
else
bResult = (::GetLastError() == ERROR_SERVICE_ALREADY_RUNNING);
// We should call DeleteService() if the SCM reports an error
// on StartService(). Otherwise, the service will remain loaded
// in an undesired state
if (!bResult)
{
// Mark the service for deletion.
::DeleteService(m_hDriver);
if (m_hDriver != NULL)
{
::CloseServiceHandle(m_hDriver);
m_hDriver = NULL;
}
m_bErrorOnStart = TRUE;
}
} // if
} // if
return bResult;
}
//
// Wait until driver reaches desired state or error occurs
BOOL WaitForState(DWORD dwDesiredState, SERVICE_STATUS* pss)
{
BOOL bResult = FALSE;
if (NULL != m_hDriver)
{
// Loop until driver reaches desired state or error occurs
//Петля, пока водитель не достигает желаемого государства или ошибки, происходит
while (1)
{
// Get current state of driver
bResult = ::QueryServiceStatus(m_hDriver, pss);
// If we can't query the driver, we're done
if (!bResult)
break;
// If the driver reaches the desired state
if (pss->dwCurrentState == dwDesiredState)
break;
// We're not done, wait the specified period of time
DWORD dwWaitHint = pss->dwWaitHint / 10; // Poll 1/10 of the wait hint Опрос 1/10 ждать намека
if (dwWaitHint < 1000) dwWaitHint = 1000; // At most once a second Самое большее однажды секунда
if (dwWaitHint > 10000) dwWaitHint = 10000; // At least every 10 seconds По крайней мере, каждые 10 секунд
::Sleep(dwWaitHint);
} // while
} // if
return bResult;
}
BOOL GetProcessHostFullName(TCHAR* pszFullFileName)
{
DWORD dwResult = 0;
::ZeroMemory((PBYTE)pszFullFileName, MAX_PATH);
dwResult = ::GetModuleFileName(
NULL, // handle to module обращайтесь к модулю
pszFullFileName, // file name of module имя файла модуля
MAX_PATH // size of buffer размер буфера
);
return (dwResult != 0);
}
BOOL ReplaceFileName(TCHAR* pszOldFileName,TCHAR* pszBaseNewFileName,TCHAR* pszNewFileName)
{
BOOL bResult = TRUE;
TCHAR *pdest;
_TINT ch = TEXT('\\');
::ZeroMemory((PBYTE)pszNewFileName, sizeof(MAX_PATH));
_tcscpy(pszNewFileName, pszOldFileName);
// Search backward and replaces the dll name with the hook one
pdest = _tcsrchr(pszNewFileName, ch);
if( pdest != NULL )
_tcscpy(&pdest[1], pszBaseNewFileName);
else
_tcscpy(pszNewFileName, pszBaseNewFileName);
return bResult;
}
BOOL GetProcessName(DWORD dwProcessId,LPTSTR lpFileName, DWORD dwLen)
{
HANDLE hProcess;
hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
dwProcessId
);
GetProcessImageFileName (hProcess,lpFileName,dwLen);
return true;
}
bool fake()
{
return true;
}
Соседние файлы в папке MyUserModeApp