TwitterTwitter FacebookFacebook FlickrFlickr RSSRSS

20100513

让bsodhook检查任意hook

bsodhook检查任意hook

BSODHOOK非要开个驱动检查SHADOW TABLEssdt table
没有HOOK的就不让检查,于是写了个驱动让他能检查任意SSDT/SHADOW HOOK~
先打开bsodhook,load driver,再加载这个驱动即可

要检查的HOOK ID请在need_check_ssdt_id need_check_shadow_id里填写~
已测试版本 2.0.0.0

代码:
=================================


#include "ntddk.h"
#include "stdafx.h"
#include "zwfunc.h"
#include "ntifs_48.h"

ULONG oldBsodHookDevCtl ;
ULONG need_check_ssdt_id[] = {0x1 , 0xffffffff};

ULONG need_check_shadow_id[] = {0x1001,0xffffffff };

NTSTATUS NewBsodHookDevCtl(PDEVICE_OBJECT devobj , PIRP irp)
{
NTSTATUS stat ;
PIO_STACK_LOCATION irpstack = IoGetCurrentIrpStackLocation(irp);
ULONG iocontrolcode = irpstack->Parameters.DeviceIoControl.IoControlCode;
PVOID userbuffer = irp->UserBuffer;
ULONG len = irpstack->Parameters.DeviceIoControl.InputBufferLength ;


__asm
{
push irp
push devobj
call oldBsodHookDevCtl
mov stat ,eax
}

if (!NT_SUCCESS(stat))
{
return stat ;
}

//irp
已经完成了~

//
这里是get ssdt
if (iocontrolcode == 0xB50D800B)
{
__try
{
ULONG i = 0 ;
while(need_check_ssdt_id[i] != 0xffffffff)
{
*(ULONG*)((ULONG)userbuffer + need_check_ssdt_id[i] * 4 + 4 ) = 0xffffffff;
i++;
}

}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return stat ;
}
}
//
这里是get shadow ssdt
else if (iocontrolcode == 0xB50D800F)
{
__try
{
ULONG i = 0 ;
while(need_check_shadow_id[i] != 0xffffffff)
{
*(ULONG*)((ULONG)userbuffer + (need_check_shadow_id[i] - 0x1000) * 4 + 4) = 0xffffffff;
i++;
}

}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return stat ;
}
}

return stat ;

}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistry )
{
UNICODE_STRING Name ;
PDRIVER_OBJECT DriverObject ;
NTSTATUS stat ;


RtlInitUnicodeString(&Name , L"\\Driver\\BSODhook");

stat = ObReferenceObjectByName(&Name ,
OBJ_CASE_INSENSITIVE,
NULL,
0,
*IoDriverObjectType ,
KernelMode ,
NULL,
&DriverObject
);

if (!NT_SUCCESS(stat))
{
return STATUS_UNSUCCESSFUL ;
}

oldBsodHookDevCtl = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
InterlockedExchangePointer(&DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] , NewBsodHookDevCtl);

ObfDereferenceObject(DriverObject);

return STATUS_SUCCESS ;

 

20100511

Implementing thread-safe unordered sets without reducers

 

Implementing thread-safe unordered sets without reducers

Submit New Article


by Alex Zatsman

Races and Reducers: the Risks and Rewards

One of the biggest challenges in building a parallel program is dealing with data races. Cilk++ offers several tools and techniques to find and eliminate races from your program. Reducers provide a a powerful mechanism for eliminating races, but as Spiderman said, "with great power comes great responsibility."

The Problem

I recently looked at a customer problem that at first looked like an obvious application for reducers.  Briefly, the task was to sort a collection of objects into separate bins based on certain properties of the objects. The simplest parallel implementation, converting the for loop to a cilk_for loop, introduces data races on the bins if two or more objects can be put into the same bin.

At first look, this seemed like a good opportunity to use reducers.  The contents of each bin is a list of elements, so why not just have each bin hold a list reducer?  Reducers are extremely efficient when used sparingly, but unfortunately can become expensive if you create thousands or even millions of reducers, as would be needed in this case.

The other safe approach to handling races is to use locks to protect access to the shared memory locations.  In this case, that would either mean using a single lock to protect the entire collection (safe, but bad because the high contention on this lock would eliminate all advantages of parallelism) or to create and acquire a lock for each bin (also safe, but bad because it requires thousands or millions of expensive locks.)

Luckily, there is another way.

The Approach

Mutex locks provided by the operating system are expensive to create and acquire, and are generally more heavy weight than is required for this problem. However, there is a much lower-cost alternative. The underlying hardware offers atomic instructions, which are effectively locks around single hardware instructions. These are the same instructions that are used to implement mutexes, but we can use them directly to save a significant amount of overhead for our problem at hand. It is important to note that there is no free lunch - atomic instructions require a memory barrier that can cost 40 or more instruction cycles.  This is far more expensive than the few cycles used by an unlocked read/write, but still much less than the thousands required to create and acquire mutexes. You can think of these as small locks that lock just the read/write hardware operation to ensure that no other processor can race on the memory between the read and the write.

My approach is to use the atomic instruction to safely update the bins in a way that will not create data races. As with any use of locks, this approach prevents data races, but does not guarantee a deterministic result.  In this case, each bin will hold the correct list of elements, but the order of the elements in the list is indeterminate.

The Solution

An atomic swap operation for pointers is available under different names in both Gnu and Windows C/C++ compilers:

GNU: __sync_lock_test_and_set
MSVC: InterlockedExchangePointer

An implementation of a thread-safe sets can be implemented as a template with the class C of the set element as the template parameter:

#ifdef __GNUC__
#include
#define AtomicSwap(A,X) __sync_lock_test_and_set (A, X)

[How to solve the linking errors when using the ATOMIC functions?]

[How to solve the linking errors when using the ATOMIC functions?]

When some new atomic functions of GCC are used in the i386 platform, the linking errors maybe take place. It takes me troubles in some time even if I have updated GCC to the latest version (GCC-4.3.3). Herein, I will give my solution to overcome it, and share the experience with you in the Linux OS.

<!--[if !supportEmptyParas]--> <!--[endif]-->

[How to know whether your machine is i386?]

Please use 'uname' command to disclose your hardware platform.

$ uname -i

i386

<!--[if !supportEmptyParas]--> <!--[endif]-->

[What are the atomic functions?]

1. __sync_add_and_fetch()

2. __sync_sub_and_fetch()

3. __sync_lock_test_and_set()

4. __sync_add_and_fetch()

<!--[if !supportEmptyParas]--> <!--[endif]-->

[How to compile your source codes in the i386?]

It is a critical stage to get rid of the linking errors. Maybe you have known, these functions are provided by GCC (Not glibc), so the special compiling option must be added at the compile step. For example:

gcc -o atomic.o -c -fvisibility=hidden -march=i486 -Wall -pthread -O3 -fPIC atomic.c

Do you find the RED-BOLD part? Yes, it is a key option! If you have met troubles to link these files using atomic functions, please confirm whether '-march=i486' has been added.

<!--[if !supportEmptyParas]--> <!--[endif]-->

After compiling, are you happy? I guess that it is true! Haha!.

<!--[if !supportEmptyParas]--> <!--[endif]-->

[Summarization]

Open-Source is a big platform including huge information/tools…, so the accumulation plays very important role in the daily activities. The trivial points of knowledge should be tidied when you have spent much time in finding the root causes. Meanwhile, if it can help freshmen touching this field, its value is represented.

<!--[if !supportEmptyParas]--> <!--[endif]-->

 
PUMA螢光夜跑