www.pudn.com > hookN.zip > func.cpp
extern "C"
{
#include
#include "func.h"
#include "debug.h"
PFUNC_RULE func_find_rule(PDEVICE_EXTENSION dev_ext,ULONG type,ULONG id);
int func_add_rule(PDEVICE_EXTENSION dev_ext,PFUNC_RULE rule);
int func_del_rule(PDEVICE_EXTENSION dev_ext,PFUNC_RULE rule);
int func_free_list(PDEVICE_EXTENSION dev_ext);
#ifdef DEBUG
void func_print_rules(PDEVICE_EXTENSION dev_ext);
#endif
int func_protect_process(PDEVICE_EXTENSION dev_ext,ULONG pid,int enable);
int func_is_good_read_ptr(PVOID buf,ULONG size);
} //extern "C"
/*
find rule returns pointer to rule object in the list of rules if appropriate
rule with given type and id is found
*/
PFUNC_RULE func_find_rule(PDEVICE_EXTENSION dev_ext,ULONG type,ULONG id)
{
DbgMsg("func.cpp: func_find_rule(dev_ext:0x%.8X,type:0x%.8X,id:0x%.8X)",dev_ext,type,id);
PFUNC_RULE item=dev_ext->first_rule,res=NULL;
while (item)
{
if ((item->type==type) && (item->process.pid==id))
{
res=item;
break;
}
item=item->next;
}
DbgMsg("func.cpp: func_find_rule(-):0x%.8X",res);
return res;
}
/*
add rule adds rule to the end of the list
*/
int func_add_rule(PDEVICE_EXTENSION dev_ext,PFUNC_RULE rule)
{
DbgMsg("func.cpp: func_add_rule(dev_ext:0x%.8X,rule:0x%.8X)",dev_ext,rule);
if (dev_ext->last_rule) dev_ext->last_rule->next=rule;
else dev_ext->first_rule=rule;
rule->prev=dev_ext->last_rule;
rule->next=NULL;
dev_ext->last_rule=rule;
DbgMsg("func.cpp: func_add_rule(-):TRUE");
return TRUE;
}
/*
del rule deletes rule from the list
*/
int func_del_rule(PDEVICE_EXTENSION dev_ext,PFUNC_RULE rule)
{
DbgMsg("func.cpp: func_del_rule(dev_ext:0x%.8X,rule:0x%.8X)",dev_ext,rule);
if (rule->next) rule->next->prev=rule->prev;
else dev_ext->last_rule=rule->prev;
if (rule->prev) rule->prev->next=rule->next;
else dev_ext->first_rule=rule->next;
ExFreePool(rule);
DbgMsg("func.cpp: func_del_rule(-):TRUE");
return TRUE;
}
/*
free list deletes whole rule list and frees memory
*/
int func_free_list(PDEVICE_EXTENSION dev_ext)
{
DbgMsg("func.cpp: func_free_list(dev_ext:0x%.8X)",dev_ext);
/*
write access to the shared memory always requires protection
we will use mutex to make such synchronization here
*/
NTSTATUS status=KeWaitForMutexObject(&dev_ext->rules_mutex,Executive,KernelMode,FALSE,NULL);
if (!NT_SUCCESS(status))
{
DbgMsg("func.cpp: func_free_list error: KeWaitForMutexObject failed with status 0x%.8X",status);
DbgMsg("func.cpp: func_free_list(-):FALSE");
return FALSE;
}
while (dev_ext->first_rule)
func_del_rule(dev_ext,dev_ext->first_rule);
KeReleaseMutex(&dev_ext->rules_mutex,FALSE);
DbgMsg("func.cpp: func_free_list(-):TRUE");
return TRUE;
}
#ifdef DEBUG
/*
print rules prints all rules as debug messages
*/
void func_print_rules(PDEVICE_EXTENSION dev_ext)
{
DbgMsg("func.cpp: func_print_rules(dev_ext:0x%.8X)",dev_ext);
PFUNC_RULE rule=dev_ext->first_rule;
int i=0;
while (rule)
{
switch (rule->type)
{
case RULE_TYPE_PROCESS_PROTECTION:DbgMsg("%.3d) addr:0x%.8X, type:PROC PROT, pid:%d",i,rule,rule->process.pid); break;
default:DbgMsg("%.3d) unknown rule",i);
}
rule=rule->next;
i++;
}
DbgMsg("func.cpp: func_print_rules(-)");
return;
}
#endif
/*
protect process manages list of rules
it enables/disables protection rule for specific process id
*/
int func_protect_process(PDEVICE_EXTENSION dev_ext,ULONG pid,int enable)
{
DbgMsg("func.cpp: func_protect_process(dev_ext:0x%.8X,pid:0x%.8X,enable:%d)",
dev_ext,pid,enable);
/*
write access to the shared memory always requires protection
we will use mutex to make such synchronization here
*/
NTSTATUS status=KeWaitForMutexObject(&dev_ext->rules_mutex,Executive,KernelMode,FALSE,NULL);
if (!NT_SUCCESS(status))
{
DbgMsg("func.cpp: func_protect_process error: KeWaitForMutexObject failed with status 0x%.8X",status);
DbgMsg("func.cpp: func_protect_process(-):FALSE");
return FALSE;
}
int res=FALSE;
ULONG type=RULE_TYPE_PROCESS_PROTECTION;
PFUNC_RULE rule=func_find_rule(dev_ext,type,pid);
if (enable)
{
if (!rule)
{
rule=(PFUNC_RULE)ExAllocatePool(PagedPool,sizeof(FUNC_RULE));
if (rule)
{
rule->type=type;
rule->process.pid=pid;
res=func_add_rule(dev_ext,rule);
} else DbgMsg("func.cpp: func_protect_process error: ExAllocatePool failed");
} else
{
DbgMsg("func.cpp: func_protect_process error: rule exists");
res=ERROR_RULE_EXISTS;
}
} else
{
if (!rule)
{
DbgMsg("func.cpp: func_protect_process error: rule does not exist");
res=ERROR_RULE_DOES_NOT_EXIST;
} else res=func_del_rule(dev_ext,rule);
}
#ifdef DEBUG
func_print_rules(dev_ext);
#endif
KeReleaseMutex(&dev_ext->rules_mutex,FALSE);
DbgMsg("func.cpp: func_protect_process(-):%d",res);
return res;
}
/*
this function checks user buffer for read access
returns true if the buffer is ok
*/
int func_is_good_read_ptr(PVOID buf,ULONG size)
{
DbgMsg("func.cpp: func_is_good_read_ptr(buf:0x%.8X;size:0x%.8X)",buf,size);
int res=TRUE;
__try
{
ProbeForRead(buf,size,sizeof(char));
ULONG sum=0;
PULONG p=(PULONG)buf;
int i;
for (i=0;i<(int)(size/sizeof(ULONG));i++) sum+=p[i];
for (int j=0;j<(int)(size%sizeof(ULONG));j++) sum+=*((UCHAR*)&p[i]+j);
} __except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("func.cpp: func_is_good_read_ptr error: exception occurred");
res=FALSE;
}
DbgMsg("func.cpp: func_is_good_read_ptr(-):%d",res);
return res;
}