Código de EXE
#include#include #include #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()); } }
Código del SYS
#includetypedef 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 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; }
En esta imagen se demuestra como se regresa un acceso denegado al intentar cerrar el proceso.
Saludos!
interesante!!!, igual estoy empezando con estos temas cuesta entender pero vamos haciendole la lucha :)
ResponderEliminar