標籤:使用 strong 檔案 2014 for 代碼
基於驅動遍曆的一種OD檢測方案
Kido[C.L.G][4.s.T]
好久沒寫過文章了,這次寫一篇關於OD檢測方面的科普文。
個人淺薄之見,不喜勿噴。
眾所周知,OllyDbg是一款普及度很高的Windows下32位免費Ring3層級的調試工具。
以其外掛程式豐富,操作便捷,功能強大深受廣大程式猿,灰客,安全磚家等各種生物喜愛。
自有了軟體開發這個概念伊始,調試器就一直存在。隨著時代的進步,眾多鄉非青年對灰客技術的嚮往,軟體安全、加密解密也越來越受眾人注視。
人們為了最佳化,逆向,二次開發,找尋漏洞,修改,破解某一程式,而對其進行的猥瑣動作就被叫做調試。
調試又分為黑盒、白盒兩種,不過有時候也會引出灰盒這種概念。
所謂黑盒就是去調戲一個不認識的小姑娘。白盒就是夫妻之間恩恩愛愛。灰盒是一種置中的概念,大概就是情人之間那些神奇的事情了。
本文因為筆者的個人興趣,主要著重探討調戲陌生小姑娘(Debugee)的事情。
人們為了調試陌生小姑娘,開發了各式各樣的調試器(調戲器? Debugger),本文重點關注OllyDbg這個調戲必備神器。而並不是每個小姑娘都是金蓮,有些就會自備一些很NB的防狼工具(Anti-Debug)。
例如IsDebuggerPresent是一個通過光明正大觀察調戲器是否存在來防止被調戲的方法。
猥瑣的二次元人類為了成功的調戲,對目標進行完整的瞭解,自然也有一些反防狼手段(Anti-Anti-Debug),其中最高端洋氣上檔次的就屬一款叫做StrongOD的工具了。為了少打幾個字,人們通常親切的稱呼它為SOD。
SOD不僅從使用者層對OD進行了一系列的改造升級,在驅動層也對OD進行了一些保護。例如:隱藏術(隱藏OD進程),易容術(Hook 函數使得Debugee對Debugger的檢測顯示為正常啟動並執行狀態)等等。
SOD對自身的驅動也進行了一些保護,使得該驅動檔案不可見,且除非暴力窮舉不可被識別。
所幸我們利用XT還是可以對他進行觀察的:
File Not Found代表驅動檔案已經被隱藏起來,看不到了。
我的OD被我改名叫做HolyShit了。紅色代表著他已經被隱藏起來了。
Ring3 Access State是Deny代表不可被操作。
讓我們看看SOD對驅動層做了一些什麼操作把!
SSDT hook了10個函數。
ShadowSSDT hook了6個函數。
正是這些鉤子保證了OD不可被通過hwnd遍曆出來,並且OD進程不可被操作。
保證了調試器的地位。
本文要介紹的這個方法其實是一個老生常談的東西。一個很老的手段。
通過暴力擷取驅動,判斷是否為StrongOD驅動來進行是否被調試的判斷。
筆者是一個文藝裝逼小青年,花了一天時間下載了VS2013。
下面上代碼:
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <tchar.h>
include <Shlwapi.h>
#include <Psapi.h>
#pragma comment(lib,"psapi")
#define ARRAY_SIZE 1024
int _tmain(int argc, _TCHAR* argv[])
{
LPVOID drivers[ARRAY_SIZE];
DWORD cbNeeded;
int cDrivers, i;
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded)
&& cbNeeded < sizeof(drivers))
{
CHAR szDriver[ARRAY_SIZE];
CHAR szPath[ARRAY_SIZE];
CHAR szDbgHelp[ARRAY_SIZE];
CHAR szSystem[ARRAY_SIZE];
size_t len = 0;
BOOL file = false;
GetSystemDirectory(szSystem, sizeof(szSystem));
strcat_s(szSystem, "\\dbghelp.dll");
cDrivers = cbNeeded / sizeof(drivers[0]);
for (i = 0; i < cDrivers; i++)
{
if (GetDeviceDriverBaseName(drivers[i], szDriver, sizeof(szDriver) / sizeof(szDriver[0])))
{
GetDeviceDriverFileName(drivers[i], szPath, sizeof(szPath));
if (szPath[1] == ‘?‘)
{
len = strlen(szPath);
do{
len--;
} while (szPath[len] != ‘\\‘);
do{
len--;
} while (szPath[len] != ‘\\‘);
szPath[len + 1] = 0;
for (UINT i = 0; i < len; i++)
{
szPath[i] = szPath[i + 4];
}
sprintf_s(szDbgHelp, "%sdbghelp.dll", szPath);
if (PathFileExists(szDbgHelp))
{
if (strcmp(szSystem, szDbgHelp) == 0)
{
continue;
}
printf_s("OllyDbg Detected:\n"
"Path:%s\n"
"StrongOD Driver Name:%s\n", szPath, szDriver);
}
}
}
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
上面的代碼主要是利用EnumDeviceDrivers 擷取出來所有的驅動
然後利用GetDeviceDriverFileName暴力取出驅動路徑
去掉開頭的”\\??\”之後,去掉驅動名並向上退一個目錄。
然後檢測該目錄下是否存在dbghelp.dll檔案
如果存在 且 該目錄不為 %system%目錄 那麼就判定這是個調試器。
然後輸出檢測到的OD路徑以及SOD的驅動名(ollydbg.ini中可自訂)。
:
一旦擷取到了OD目錄。SOD驅動名,那麼卸載驅動,破壞OD,利用CMD調用OD來附加現在的這個調試器,恢複SSDT鉤子等等。這就不是本文所關注的內容了。
注意:使用VS2012/VS2013編譯時間需要進行的修改:
相容XP且試用Ansi模式
添加必要的靜態庫。
這樣就可以了。
本文略水。
看官見諒。