作 者:
gjden
時 間: 2010-03-30,00:12:20
鏈 接:
通過暴搜driver_object列舉驅動
// +0x002 size : int2b
// 0x004 deviceobject : ptr32 _device_object
// 0x008 flags : uint4b
// +0x00c driverstart : ptr32 void
// +0x010 driversize : uint4b
//+0x014 driversection : ptr32 void
// +0x018 driverextension : ptr32 _driver_extension
// +0x01c drivername : _unicode_string
// +0x024 hardwaredatabase : ptr32 _unicode_string
// +0x028 fastiodispatch : ptr32 _fast_io_dispatch
// +0x02c driverinit : ptr32 long
// +0x030 driverstartio : ptr32 void
// +0x034 driverunload : ptr32 void
// +0x038 majorfunction : [28] ptr32 long
既然我們要在記憶體中搜尋驅動物件,那麼我們必須找出幾乎所有驅動的_driver_object都具備的共有特徵,以此來準確地識別出此記憶體段是否是合法的驅動物件。以上用紅色標記的是我們要作為驅動物件標記的成員,我們來看看這些成員:
type:標識物件的型別,其值為04;
size:驅動物件的大小,其值為0xa8;
driverstart:其值表示驅動pe映像的基位址,因為驅動的映像必定處於高階記憶體,所以不能小於0x80000000或空,同時它的值必須是8的倍數;
driversize:表示驅動的大小,其值不能為0;
driversection:驅動節,其實是乙個指向ldr_data_table_entry結構的指標,此結構也必在高階記憶體,也不能小於0x80000000;
就這幾條,足夠我們唯一標示驅動物件了,我想也應該不難的寫出辨別出驅動物件的**來,**如下:
boolean isrealdriver( ulong paddr )
if (ptempdriver->driversize==0)
if (/*ptempdriver->driverstart==null||沒有必要*/(ulong)(ptempdriver->driverstart)<0x80000000)
if ((ulong)ptempdriver->driversection<0x80000000)
if (((ulong)(ptempdriver->driverstart)&7)!=0)
return true;
}很簡單吧,接下來我們應該確定如何來搜尋記憶體,自然我們要從高階記憶體開始搜了。關於搜尋範圍,根據我的觀察,驅動物件幾乎都在0x8000000到0x82000000之間,當然如果要想快速的話,就只搜尋這段記憶體,如果想要保險的話,還是0x8000000-0xfffff000都搜尋下吧,這裡我還是把所有高階記憶體都搜一下。
為了能盡快地進行搜尋,關於位址的驗證,我用了網上的一段用於搜尋隱藏程序的位址驗證**來驗證,另外由於我們的物件的位址是8位元組對齊的,因而可以以8為增量搜尋。當我們搜到了物件,那就好辦了,我原本想直接通過物件中的drivername來顯示驅動名,可是好像大部分的驅動名要麼沒有字尾,要麼名字後面出現亂碼(在我的另乙個檢視系統核心物件的工具中也出現類似的情況,希望哪位大牛有好的解決方法),但是這裡無關緊要,我們還有driversection呢,他指向乙個ldr_data_table_entry的結構,大家也再熟悉不過了,定義在**中,我也不廢話了,估計大家也嫌我囉嗦,再說,就要飛磚頭了
基本的思路就這麼簡單,與菜鳥們共同學習交流,我也是菜菜兒,不足之處望大家指出。
其中的函式
ulong isvalidaddr( ulong uaddr );
是完全照抄過來的,實現**如下(在xp sp3上測試通過):
#include
#define valid_page 1
#define invalid_page 0
#define pdeinvalid 2
#define pteinvalid 3
typedef struct _ldr_data_table_entry ;
};union ;
struct ;
};//struct _activation_context * entrypointactivationcontext;
pvoid entrypointactivationcontext;
pvoid patchinformation;
} ldr_data_table_entry, *pldr_data_table_entry;
typedef struct _driver_array
driver_array,*pdriver_array;
int number=0;
boolean isrealdriver( ulong paddr);
ulong isvalidaddr( ulong uaddr);
void showhideddriver();
void unload( pdriver_object pdriverobject )
ntstatus driverentry( pdriver_object pdriverobject, punicode_string pregpath )
//以下這個函式抄的網上的,直接拿來主義....
ulong isvalidaddr( ulong uaddr )
_asm sti
uinfo = ucr4 & 0x20;
if( uinfo != 0 )
else
updeaddr = (uaddr>>22)*4+0xc0300000;
if( (*(pulong)updeaddr & 0x1) != 0 )
else
else
if( (*(pulong)upteaddr & 0x1) != 0 )
return valid_page;
else
return pteinvalid;}}
else
return pdeinvalid;
}//判定是否是真正的驅動結構
boolean isrealdriver( ulong paddr )
if (ptempdriver->driversize==0)//驅動大小不能為0
if (/*ptempdriver->driverstart==null||可以不要*/(ulong)(ptempdriver->driverstart)<0x80000000)
if ((ulong)ptempdriver->driversection<0x80000000)
if (((ulong)(ptempdriver->driverstart)&7)!=0)
return true;
}void showhideddriver()
ustartaddr+=sizeof(driver_object);}}
else if( uret == pdeinvalid )
else
}dbgprint("driver number %d",count);
}到此,一切都完成了,如果你感覺不保險的話,就驗證一下pe頭,其中driverstart就是基址。
**比較簡單,我都沒有做多少注釋,我想應該講清楚了吧。
迷宮問題BFS暴搜
首先宣告的是這個問題的 並不是本人所做,我只是抱著學習的態度,在此標記如下 迷宮 題 從圖左邊入口處的2011進去,在迷宮裡轉悠,最後變成2012從右邊出來。可以在迷宮裡轉圈,可以重複之前走過的路,但不能回退。include include include define startvalue 201...
暴搜輸出可行解
題目背景 三水和小羽毛玩膩了二十四點,她們決定玩點新東西。小羽毛給出乙個數字和以及n nn個數字,由三水給出這n nn個數字計算得出這個數字和的可能。由於這是乙個新遊戲,為了不讓三水花太多的時間,兩人約定只做加法。題目描述 小羽毛給出乙個數字和sum sum 1000 sum sum 1000 su...
搞不懂的暴搜
暴搜優化.分析 令第 i 種裝備的數量為sum i 顯然如果 sum i 不為 0 那麼這種裝備必選一件,在這時需要考慮的總方案數為 max sum i 1 其中 sum i 50。最壞情況下所有 sum 的值都相同,令它們都等於 k,則方案數為 kn k 當 k 取 3 時取到最大值 3n 3 在...