Lo modifique para que proteja un solo proceso, ahora NADA y repito NADA podrá cerrar ese proceso pues lo estarán cuidando desde el otro lado :3
Para eso primero se necesita un "mensajero" es el que trabaja del lado del usuario se encarga de instalar, ejecutar, mandar el PID a proteger o desproteger, detener y eliminar el driver.
Codigo del driver:
#include <ntddk.h>
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
#define Block CTL_CODE(FILE_DEVICE_UNKNOWN, 0x00000001, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
#define Unblock CTL_CODE(FILE_DEVICE_UNKNOWN, 0x00000002, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
typedef DWORD (ULONG);
PMDL g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig ) \
_Orig = (PVOID) InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
#define UNHOOK_SYSCALL(_Function, _Hook, _Orig ) \
InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
//Declaramos la API para poder trabajar con ella.
NTSYSAPI NTSTATUS NTAPI ZwOpenProcess (OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
typedef NTSTATUS (*TypZwOpenProc)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
TypZwOpenProc ZwOpenProcessIni;
const WCHAR Device[]=L"\\device\\driverpid";
const WCHAR sLink[]=L"\\??\\driverpid";
UNICODE_STRING Dev, lnk;
int ListPID;
NTSTATUS IOControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){
PIO_STACK_LOCATION Stack;
int *oBuffer;
int *iBuffer;
NTSTATUS Status = STATUS_SUCCESS;
Stack = IoGetCurrentIrpStackLocation(Irp);
DbgPrint("Accesando a bloqueo de PID");
DbgPrint("Asociando buffers...");
iBuffer = oBuffer = Irp->AssociatedIrp.SystemBuffer;
if (oBuffer && iBuffer){
if(Stack->Parameters.DeviceIoControl.InputBufferLength == sizeof(int)){
DbgPrint("Peticion recibida a PID: %d", *iBuffer);
if(Stack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(int)){
DbgPrint("Revisando estado de lista.");
Irp->IoStatus.Information = sizeof(int);
switch(Stack->Parameters.DeviceIoControl.IoControlCode){
case Block:
{
if (ListPID == 0){
DbgPrint("Protegiendo PID %d.", *iBuffer);
ListPID = *iBuffer;
*oBuffer = 1;
} else {
*oBuffer = 0;
DbgPrint("No hay espacio para proteger.");
}
break;
}
case Unblock:
{
DbgPrint("Eliminando proteccion");
if (ListPID != 0){
DbgPrint("Liberando PID %d.", *iBuffer);
ListPID = 0;
*oBuffer = 1;
} else {
*oBuffer = 0;
DbgPrint("No hay procesos protegidos.");
}
}
} //Switch
} else {
Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
} //Buffer Small
} //In buffer
} //Asociar buffer
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS NewZwOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL)
{
HANDLE PID;
__try //Utilizamos el bloque try para evitar BSOD
{
PID = ClientId->UniqueProcess;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return STATUS_INVALID_PARAMETER; //Regresamos un estado invalido para que la aplicación se ocupe
}
//Verificamos el pid
if (PID == (HANDLE)ListPID){
DbgPrint("PID: 0x%x", PID);
return STATUS_ACCESS_DENIED; //Retornamos acceso denegado
}
else return ZwOpenProcessIni(ProcessHandle, DesiredAccess,ObjectAttributes, ClientId); //Llamamos a la API nativa y retornamos el resultado correcto
}
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("Descargando driver...");
//Unhookeamos
UNHOOK_SYSCALL( ZwOpenProcess, ZwOpenProcessIni, NewZwOpenProcess );
//Eliminamos la MDL
if(g_pmdlSystemCall)
{
MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
IoFreeMdl(g_pmdlSystemCall);
}
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath)
{
int i;
NTSTATUS Status;
DriverObject->DriverUnload = OnUnload;
for(i=0; i<IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = IOControl;
RtlInitUnicodeString(&Dev,Device);
RtlInitUnicodeString(&lnk,sLink);
//Creamos la MDL para deshabilitar la protección de memoria
//g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);
g_pmdlSystemCall = IoAllocateMdl(KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4, FALSE, FALSE, NULL);
if(!g_pmdlSystemCall)
return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
Status = IoCreateDevice(DriverObject,0,&Dev,FILE_DEVICE_UNKNOWN,0,0,&DriverObject->DeviceObject);
if (NT_SUCCESS(Status)){
Status =IoCreateSymbolicLink(&lnk,&Dev);
DbgPrint("Creando device...");
if(!NT_SUCCESS(Status)){
IoDeleteDevice(DriverObject->DeviceObject);
DbgPrint("Error creando link simbolico");
}else
DbgPrint("SymbolicLink creado y cargado.");
}else
DbgPrint("Error creando el device.");
DbgPrint("Driver cargado.");
ZwOpenProcessIni =(TypZwOpenProc)(SYSTEMSERVICE(ZwOpenProcess));
DbgPrint("Hookeando...");
HOOK_SYSCALL( ZwOpenProcess, NewZwOpenProcess, ZwOpenProcessIni );
return Status;
}
#include <string.h>
#include <windows.h>
#include <winioctl.h>
#define Block CTL_CODE(FILE_DEVICE_UNKNOWN, 0x00000001, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
#define Unblock CTL_CODE(FILE_DEVICE_UNKNOWN, 0x00000002, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
void Usage(char *name);
char *ExtractFileName(char *Name);
void SendPID(int PID, int bBlock);
int main(int argc, char *argv[])
{
int i = 1;
if (argc == 1) {
Usage(argv[0]);
return 0;
}
if (strlen(argv[1]) != 2){
Usage(argv[0]);
return 0;
}
switch (argv[1][1]){
case 'i' :
{
//Se abre el administrador de servicios con la flag CREATE_SERVICE
SC_HANDLE SCMan = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (SCMan == NULL){
printf("No se tienen los permisos necesarios para acceder a los servicios\n");
return 0;
}
//Crea el servicio tipo Driver, que inicie con el sistema
SC_HANDLE Serv = CreateService(SCMan, argv[2], argv[2],
SERVICE_ALL_ACCESS, // Desired Access
SERVICE_KERNEL_DRIVER, // Service Type
SERVICE_DEMAND_START, // Start Type
SERVICE_ERROR_NORMAL, // Error Controle
argv[3], NULL, NULL, NULL, NULL, NULL);
printf("Ruta: %s\n", argv[3]);
if (Serv == NULL){
if (GetLastError() == 1073){ //El error 0x431 significa que ya existe el servico
Serv = OpenService(SCMan, argv[2], SERVICE_ALL_ACCESS); //Simplemente obtenemos el handle
if (Serv == NULL){
printf("No se puede abrir el servicio\n");
printf("Error 0x%x", GetLastError());
return 0;
}
} else {
printf("No se puede crear el servicio\n");
printf("Error 0x%x", GetLastError());
return 0;
}
}
if (!StartService(Serv, 0, NULL)){ //Iniciamos el servicio
printf("No se puede iniciar el servicio\n");
printf("Error 0x%x", GetLastError());
return 0;
}
printf("El servicio %s se ha instalado e iniciado...", argv[2]);
CloseServiceHandle(Serv); //Cerramos el handle del servicio
CloseServiceHandle(SCMan); //Cerramos el handle del administrador de servcios
break;
}
case 'd':{
//Abrimos el admin de servicios
SC_HANDLE SCMan = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (SCMan == NULL){
printf("No se tienen los permisos necesarios para acceder a los servicios\n");
return 0;
}
//Se obtiene un handle del servicio
SC_HANDLE Serv = OpenService(SCMan, argv[2], SERVICE_ALL_ACCESS);
if (Serv == NULL){
printf("Error abriendo el servicio %d\n", GetLastError());
return 0;
}
SERVICE_STATUS servStatus; //Enviamos la señal STOP_SERVICE
BOOL bRet = ControlService(Serv, SERVICE_CONTROL_STOP, &servStatus);
if (!bRet && (GetLastError() != ERROR_SERVICE_NOT_ACTIVE)){ //Este error significa que ya esta detenido
printf("No se ha podido detener el servicio\nError: %d", GetLastError());
return 0;
}
if (!DeleteService(Serv)){ //Lo eliminamos
printf("Error eliminando el servicio %d", GetLastError());
return 0;
}
printf("Servicio %s detenido y desinstalado", argv[2]);
CloseServiceHandle(Serv); //Cerramos el handle del servicio
CloseServiceHandle(SCMan); //Cerramos el handle del administrador de servcios
break;
}
case 'h':{
printf("Proteccion de PID\n");
SendPID(atoi(argv[2]), 1);
break;
}
case 'u':{
printf("Liberación de PID\n");
SendPID(atoi(argv[2]), 0);
break;
}
}
//system("PAUSE");
return 0;
}
void Usage(char *name){
printf("%s [opciones] [parametros]\n", ExtractFileName(name));
printf(" -i [Nombre] [Ruta] Carga y crea el servicio del driver.\n");
printf(" -d [Nombre] Detiene y elimina en servicio del driver.\n");
printf(" -h [PID] Protege un proceso.\n");
printf(" -u [PID] Libera un proceso.\n");
}
char *ExtractFileName(char *name){
int len = strlen(name);
while (len > 0){
if ((int)name[len] != 92)
len--;
else {
len++;
break;
}
}
int iname = strlen(name) - len;
char *ret = malloc((iname + 1)*sizeof(char));
strcpy(ret, name + len);
return ret;
}
void SendPID(int PID, int bBlock){
HANDLE hDevice;
BOOL bRet;
DWORD a, dwState;
int iBuffer, oBuffer;
//iBuffer = PID;
hDevice = CreateFile("\\\\.\\driverpid", GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
if (hDevice != INVALID_HANDLE_VALUE)
{
printf("Handle Device: %d\n", hDevice);
if (bBlock)
dwState = (DWORD)Block;
else
dwState = (DWORD)Unblock;
printf("Enviando peticion\n");
bRet = DeviceIoControl(hDevice, dwState, &PID, sizeof(int), &oBuffer, sizeof(int), &a, NULL);
if (bRet)
printf("PID: %d se respondio %d\n", iBuffer, oBuffer);
} else {
printf("No se puede establecer conexion\n");
printf("0x%08x\n",GetLastError());
}
}






Descarga de binarios: [Enlace externo eliminado para invitados]
Cualquier duda o pregunta no duden en hacerla.
Saludos!