para linux, la cual consta de 3 partes:
2 drivers(1 en modo ring0 y el otro en el de espacio de usuario).
la 3º parte es la interfaz grafica, que, además de presentar una GUI es la encargada de comunicarse
con el driver de usuario y este a la vez se comunica con el driver que interactúa con el kernel.
Logre entender y desarrollar un mecanismo por medio de netlink sockets optimizados(en vez de usar pipes)
que se comunican entre si (kernel y usuario), y así hay una retroalimentacion en la información de ambos,
claro que esto es una beta y que MUCHO por optimizar/agregar/mejorar la GUI esta hecha en Pascal, mientras
que los drivers en C, y la GUI se "comunica" con C gracias a librerias compartidas (.o y .ko).
Éste código esta hecho 100% por mi, no hay rips, ni nada por el estilo...
Por esto le pido a los ripers que tengan consideración y respeto por el esfuerzo
y que si van a tomar este código por lo menos den creditos...
Este sistema se compone de algunas de las siguientes características :
[+]Matar procesos en ring0
[+]congelar procesos.
[+]refrigerar procesos, que han sido congelado o bien estan congelados(no funciona con todos).
[+]poner toda esa info en colas(Queues) para tener un registro.
[+]Informacion de procesos, consumo virtual, Shared memory, RSS, Boot time, flags, y muchos mas.
[+]Debugear el kernel (para ver los logs del kernel)
[+]Listar procesos por alto consumo virtual
[+]Configurar el driver, para que si un determinado proceso alcanze un consumo alto de memoria ocurra
un determinado evento.
Espero tener más tiempo y seguir mejorando cosas y demás, debo decir que esta aplicacion contiene algunos
bugs que espero solucionar... por esto la lanzo como beta y POR FAVOR les pido que la TESTEN y COMENTEN
que costo muchas horas de desarrollo y asumir conceptos.
Aca les dejos el link de la aplicacion: [Enlace externo eliminado para invitados]
a continuación dejaré parte del código(por lo menos el del driver principal) y algunas imagenes.
Mañana en la seccion C lo pongo completo, como respaldo por las dudas...
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <net/net_namespace.h>
/* si quires debuggear descomenta esta de lo contrario comentala */
#define DEBUG_ANTIFREEZE_DRIVER
/* Necesaria para interactuar con el espacio de usuario y kernel */
#define NETLINK_KERNEL_GROUP 30
#define REFRIGERATE_PROCESS 18
#define FREEZE_PROCESS 19
#define KILL_PROCESS 15
#define _KILL_PROCESS "[KILL_SIGNAL]"
#define _FREEZE_PROCESS "[FREEZE_SIGNAL]"
#define _REFRIGERATE_PROCESS "[REFRIGERATE_SIGNAL]"
#define PID_EX "[PID_EX]"
#define EZOMBIE "EXIT_ZOMBIE|"
#define EDEAD "EXIT_DEAD|"
#define TDEAD "TASK_DEAD|"
#define TKILL "TASK_KILLABLE|"
#define TTRACED "TASK_TRACED|"
#define TSTOP "TASK_STOPPED|"
#define TWAKEKILL "TASK_WAKEKILL|"
#define TWAKING "TASK_WAKING|"
#define TINTRPT "TASK_INTERRUPTIBLE|"
#define TUNINTERPT "TASK_UNINTERRUPTIBLE|"
#define TRUNN "TASK_RUNNING|"
#define TMAX "TASK_STATE_MAX|"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NvK");
MODULE_DESCRIPTION("Modulo para controlar y obtener el consumo de procesos, pudiendolos optimizar y evitar posibles latencias");
static struct sock *nl_sk= NULL;
static struct task_struct *ktask;
static struct mm_struct *MMU;
static struct vm_area_struct *VMA;
static struct pid *pid_struct;
struct nlmsghdr *nlh= NULL;
struct sk_buff *sk_ob;
/* con un ushort basta y sobra (congela/descongela/mata un proceso en modo ring0) */
static uint8_t frozen_process_r0(__u32 _pid,
struct pid *pid_struct,
struct task_struct *_ktask,
__u8 _signal)
{
atomic_t pid_status;
pid_struct= task_pid(_ktask);
if (((*_ktask).pid==_pid)&&(pid_struct!=NULL)){
_ktask->state= TASK_INTERRUPTIBLE;
kill_pid(pid_struct, _signal, TASK_INTERRUPTIBLE); //kill_pid(pid_struct, SIGSTOP, TASK_INTERRUPTIBLE);
atomic_set(&pid_status, SIGHUP);
}else
{
atomic_set(&pid_status, SIGABRT);
}
return atomic_read(&pid_status);
}
static uint8_t __attribute__((__section__(".text.init") ))
nl_KernelSend(char *Message, int nl_pid)
{
/* Necesario para enviar un mensaje */
sk_ob= nlmsg_new(strlen(Message), 0);
nlh= nlmsg_put(sk_ob, 0, 0, NLMSG_DONE, strlen(Message), 0); // escribo la estructura
NETLINK_CB(sk_ob).dst_group= 0;
strncpy(NLMSG_DATA(nlh), Message , strlen(Message));
nlmsg_unicast(nl_sk, sk_ob, nl_pid);
return 1;
}
/* Convierto la cadena de texto en integro */
static int32_t __attribute__((__section__(".text.init") ))
strcpysignal(char nl_buf[], char *type_signal)
{
int base_int;
char signal[1040];
strncpy(signal, nl_buf+strlen(type_signal), strlen(nl_buf)-1);
return simple_strtol((const char *)signal, NULL, base_int);
}
// sysctl -w vm.drop_caches=3
static void __attribute__((__section__(".text.init") ))
netlink_recv(struct sk_buff *skb)
{
int pid, pid_signal, type_signal;
char *sbuff;
char nl_buf[1024];
unsigned long get_mm, hiwater_vm,
total_vm, hiwater_rss, total_rss,
swap, size_kb;
if (skb!=NULL)
{
// Reservo el tamaño de una pagina de memoria
sbuff= (char *)vmalloc(sizeof(char)*PAGE_SIZE + 1);
memset(sbuff, 0x0000, sizeof(sbuff));
memset(nl_buf, 0x0000, sizeof(nl_buf));
nlh= (struct nlmsghdr *)skb->data;
sprintf(nl_buf, "%s", (char *)NLMSG_DATA(nlh));
#ifdef DEBUG_ANTIFREEZE_DRIVER
printk(KERN_INFO "<SEÑAL> %s\n", nl_buf);
#endif
pid_signal= -1;
if (strstr(nl_buf, _KILL_PROCESS)!=NULL)
{
pid_signal= strcpysignal(nl_buf, _KILL_PROCESS);
#ifdef DEBUG_ANTIFREEZE_DRIVER
printk(KERN_INFO "\n<PID_SIGNAL> %d (KILL_PROCESS)\n", pid_signal);
#endif
type_signal= KILL_PROCESS;
}
if (strstr(nl_buf, _FREEZE_PROCESS)!=NULL)
{
pid_signal= strcpysignal(nl_buf, _FREEZE_PROCESS);
#ifdef DEBUG_ANTIFREEZE_DRIVER
printk(KERN_INFO "\n<PID_SIGNAL> %d (FREEZE_PROCESS)\n", pid_signal);
#endif
type_signal= FREEZE_PROCESS;
}
if (strstr(nl_buf, _REFRIGERATE_PROCESS)!=NULL)
{
pid_signal= strcpysignal(nl_buf, _REFRIGERATE_PROCESS);
#ifdef DEBUG_ANTIFREEZE_DRIVER
printk(KERN_INFO "\n<PID_SIGNAL> %d (REFRIGERATE_PROCESS)\n", pid_signal);
#endif
type_signal= REFRIGERATE_PROCESS;
}
pid= nlh->nlmsg_pid;
printk(KERN_INFO "----------------------------------------------");
for(ktask= &init_task; (ktask= next_task(ktask))!=&init_task;)
{
memset(sbuff, 0x0000, sizeof(sbuff));
if (pid_signal!=-1)
frozen_process_r0((int)pid_signal, pid_struct, ktask, type_signal);
sprintf(sbuff, "(PAR)%s|",(char *)ktask->parent->comm); //(*pktask).utime
sprintf(sbuff+strlen(sbuff), "(PID)%d|", (int *)ktask->pid);
/*
if (strstr(nl_buf, "[PID_EX]")!=NULL){
if(ktask->pid==simple_strtol((const char *)strstr(nl_buf,PID_EX)+strlen(PID_EX), NULL, type_signal)){
printk("PID_EX RECIBIDO [%s]", strstr(nl_buf, PID_EX)+strlen(PID_EX));
sprintf(sbuff+strlen(sbuff), "[PID_EX]__%d__|", (int *)ktask->pid);
}
}*/
MMU= ktask->mm;
if (MMU!=0x0)
{
hiwater_vm = total_vm = MMU->total_vm;
if (hiwater_vm < MMU->hiwater_vm)
hiwater_vm = MMU->hiwater_vm;
hiwater_rss = total_rss = atomic_long_read(&MMU->rss_stat.count[MM_FILEPAGES]) + atomic_long_read(&MMU->rss_stat.count[MM_ANONPAGES]);
if (hiwater_rss < MMU->hiwater_rss)
hiwater_rss = MMU->hiwater_rss;
swap= atomic_long_read(&MMU->rss_stat.count[MM_SWAPENTS]);
sprintf(sbuff+strlen(sbuff), "(VIRT)%lu|", (unsigned long *)(MMU->total_vm<<(PAGE_SHIFT-0x0A)));
sprintf(sbuff+strlen(sbuff), "(RSS)%lu|", (unsigned long *)(total_rss << (PAGE_SHIFT - 0xA)));
sprintf(sbuff+strlen(sbuff), "(ShrVM)%lu|", (unsigned long *)(MMU->shared_vm));
sprintf(sbuff+strlen(sbuff), "(VMPeak)%lu|", (unsigned long *)(MMU->hiwater_vm<<(PAGE_SHIFT-0x0A)));
sprintf(sbuff+strlen(sbuff), "(VMHWM)%lu|", (unsigned long *)(MMU->hiwater_rss<<(PAGE_SHIFT-0x0A)));
sprintf(sbuff+strlen(sbuff), "(VmPTE)%lu|", (unsigned long *)(((PTRS_PER_PTE*sizeof(pte_t)*MMU->nr_ptes) >> 0xA)) );
sprintf(sbuff+strlen(sbuff), "(VData)%lu|", (unsigned long *)((MMU->total_vm - MMU->shared_vm - MMU->stack_vm)<<(PAGE_SHIFT-0x0A)) );
sprintf(sbuff+strlen(sbuff), "(VStack)%lu|", (unsigned long *)(MMU->stack_vm<<(PAGE_SHIFT-0x0A)) );
sprintf(sbuff+strlen(sbuff), "(VmSwap)%lu|", (unsigned long *)(swap << (PAGE_SHIFT - 0xa)) );
sprintf(sbuff+strlen(sbuff), "(VmPin)%lu|", (unsigned long *)(MMU->pinned_vm << (PAGE_SHIFT-0xA)));
sprintf(sbuff+strlen(sbuff), "(VmLib)%lu|", (unsigned long *)( ((MMU->exec_vm << (PAGE_SHIFT-0xA)) - (PAGE_ALIGN(MMU->end_code) - (MMU->start_code & PAGE_MASK)) >> 0xA)) );
VMA= MMU->mmap;
if (VMA!=0x0){
size_kb= (VMA->vm_end - VMA->vm_start)>>0x0A;
sprintf(sbuff+strlen(sbuff), "(Sz)%lu|", (unsigned long *)size_kb);
}
}
switch((*ktask).state) {
case EXIT_ZOMBIE: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", EZOMBIE); break;
case EXIT_DEAD: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", EDEAD); break;
case TASK_DEAD: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TDEAD); break;
case TASK_KILLABLE: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TKILL); break;
case TASK_STOPPED: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TSTOP); break;
case TASK_WAKEKILL: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TWAKEKILL); break;
case TASK_WAKING: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TWAKING); break;
case TASK_INTERRUPTIBLE: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TINTRPT); break;
case TASK_UNINTERRUPTIBLE: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TUNINTERPT); break;
case TASK_RUNNING: sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TRUNN); break;
case TASK_STATE_MAX : sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TMAX); break;
case TASK_TRACED : sprintf(sbuff+strlen(sbuff), "(FLAG)%s", TTRACED); break;
}
if (ktask->prio>=0 && ktask->prio<=99)
sprintf(sbuff+strlen(sbuff), "(PRIO)REALTIME|");
if (ktask->prio>=100)
sprintf(sbuff+strlen(sbuff), "(PRIO)NORMAL|");
//printk(KERN_INFO "priority: %d ", (int *)ktask->prio);
//printk(KERN_INFO "policy: %lu ", (unsigned long *)ktask->policy);
if (ktask->policy==0)
sprintf(sbuff+strlen(sbuff), "(PLY)SCHED_OTHER|");
if (ktask->policy==1)
sprintf(sbuff+strlen(sbuff), "(PLY)SCHED_FIFO|");
if (ktask->policy==2)
sprintf(sbuff+strlen(sbuff), "(PLY)SCHED_RR|");
sprintf(sbuff+strlen(sbuff), "(UT)%lu|", (unsigned long *)ktask->utime);
sprintf(sbuff+strlen(sbuff), "(ST)%lu|", (unsigned long *)ktask->stime);
sprintf(sbuff+strlen(sbuff), "(BT)%i64|", ktask->real_start_time);
nl_KernelSend(sbuff, pid);
}
nl_KernelSend("KERN_TC", pid);
if(sbuff) vfree(sbuff);
}
}
static int __section(.init.text) __cold notrace
__INIT_KERNEL(void)
{
printk(KERN_ALERT "Driver inicializado correctamente (esperando señal).");
nl_sk= netlink_kernel_create((struct net *)&(init_net),
NETLINK_KERNEL_GROUP,
0,
netlink_recv,
NULL,
THIS_MODULE);
return 0;
}
static void __section(.exit.data)
__EXIT_KERNEL(void)
{
//free_task((struct task_struct *)ktask);
sock_release(nl_sk->sk_socket);
}
module_init(__INIT_KERNEL);
module_exit(__EXIT_KERNEL);






Saludos NvK.