分享
 
 
 

Windows NT/2000内部数据结构探究

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Windows NT/2000内部数据结构探究

WebCrazy(tsu00@263.net)

注:本文最初见于www.nsfocus.com

WINDOWS系统隐含了不少内部数据结构,其记录着与系统相关的所有重要信息如线程、进程、内核调用等等,具体如Windows NT/2000模块ntoskrnl.exe中的NtBuildNumber与KeServiceDescriptorTable等(用SoftICE或Visual Studio所带的Dependency Walker之类的可以看到),前者只是指出当前Windows的Build号(如SoftICE下可用dw命令查出我的机器中为0893h 即十进制2195);后者是指向如下数据结构的指针:

struct _ServiceDescriptorEntry {

unsigned int *ServiceTableBase;

unsigned int *ServiceCounterTableBase;

unsigned int NumberOfServices;

unsigned char *ParamTableBase;

}ServiceDescriptorTableEntry

其典型应用为Mark Russinovich与Bryce Cogswell的Regmon,具体可以参阅www.sysinternals.com.

本文仅在Intel i386的Windows 2000 Server(Build 2195)中对TEB(Thread Environment Block)作初步介绍.

TEB在Windows 9x系列中称为TIB(Thread Information Block),她纪录着线程的重要信息,每一个线程对应一个TEB结构。其格式如下(摘自Matt Pietrek的Under the Hood专栏-MSJ 1996):

typedef struct _TIB

{

PEXCEPTION_REGISTRATION_RECORD pvExcept; // 00h Head of exception record list

PVOID pvStackUserTop; // 04h Top of user stack

PVOID pvStackUserBase; // 08h Base of user stack

union // 0Ch (NT/Win95 differences)

{

struct // Win95 fields

{

WORD pvTDB; // 0Ch TDB

WORD pvThunkSS; // 0Eh SS selector used for thunking to 16 bits

DWORD unknown1; // 10h

} WIN95;

struct // WinNT fields

{

PVOID SubSystemTib; // 0Ch

ULONG FiberData; // 10h

} WINNT;

} TIB_UNION1;

PVOID pvArbitrary; // 14h Available for application use

struct _tib *ptibSelf; // 18h Linear address of TIB structure

union // 1Ch (NT/Win95 differences)

{

struct // Win95 fields

{

WORD TIBFlags; // 1Ch

WORD Win16MutexCount; // 1Eh

DWORD DebugContext; // 20h

DWORD pCurrentPriority; // 24h

DWORD pvQueue; // 28h Message Queue selector

} WIN95;

struct // WinNT fields

{

DWORD unknown1; // 1Ch

DWORD processID; // 20h

DWORD threadID; // 24h

DWORD unknown2; // 28h

} WINNT;

} TIB_UNION2;

PVOID* pvTLSArray; // 2Ch Thread Local Storage array

union // 30h (NT/Win95 differences)

{

struct // Win95 fields

{

PVOID* pProcess; // 30h Pointer to owning process database

} WIN95;

} TIB_UNION3;

} TIB, *PTIB;

在Windows 2000 DDK中定义为:

typedef struct _NT_TIB

{

struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;

PVOID StackBase;

PVOID StackLimit;

PVOID SubSystemTib;

union {

PVOID FiberData;

ULONG Version;

};

PVOID ArbitraryUserPointer;

struct _NT_TIB *Self;

} NT_TIB;

庆幸的是,Windows在调入进程,创建线程时,操作系统均会为每个线程分配TEB,而且都将FS段选择器(i386)指向当前线程的TEB数据(单CPU机器在任何时刻系统中只有一条线程在执行),这就为我们提供了存取TEB数据的途径。实际上Windows都是通过这种方法来为你的应用程序提供信息的,让我们来看一个例子吧!大家都知道用GetCurrentThreadID API来获得当前线程ID的,其在Kernel32.dll是如下实现的:

GetCurrentThreadID:

mov eax, FS:[00000018] ; 18h Linear address of TIB structure(TIB结构线性地址)

mov eax, [eax+24] ; 24h ThreadID

ret ; 将EAX中的值返回给调用者

由于TEB结构过于庞大,我现在只来谈谈偏移量为00h的struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList,并结合CIH 1.3源码来说说它具体用处。ExceptionList主要用于处理SEH(Structured Exception Handling)的。如果你连C语言中新增的_try,_except与_finally也不熟悉的话,建议请先看看Jeffery Richter的<<Advanced Windows NT>>或之类的。

首先让我们来看看_EXCEPTION_REGISTRATION_RECORD结构,在CRT(C++ RunTime library)源码中它如下定义:

// Exsup.INC ---Microsoft Visual C++ CRT 源文件

_EXCEPTION_REGISTRATION struc

prev dd ?

handler dd ?

_EXCEPTION_REGISTRATION ends

其中prev是指向前一_EXCEPTION_REGISTRATION的指针,形成一链状结构,这样才会在EXCPT.H中有EXCEPTION_CONTINUE_SEARCH这样的定义(参阅&t;<Advanced Windows NT>>);handler指向异常处理代码。

CIH正是利用了这一机制,将handler指向它自己程序中。在它入口处有如下代码:

.

.

.

; *********************************************************

; * Ring3 Virus Game Initial Program *

; *********************************************************

MyVirusStart: ; Ring3代码入口点

push ebp

; *************************************

; * Let's Modify Structured Exception *

; * Handing, Prevent Exception Error *

; * Occurrence, Especially in NT. *

; *************************************

lea eax, [esp-04h*2] ;在栈中分配8字节存放_EXCEPTION_REGISTRATION结构

;相当于C中基于栈的数据,即局部变量(C编译器中完成)

;这样EAX即指向_EXCEPTION_REGISTRATION的指针,但此时

;_EXCEPTION_REGISTRATION结构未初始化

;具体实现机制可翻阅编译原理书籍和Matt Pietrek大师文章

xor ebx, ebx ;0->EBX

xchg eax, fs:[ebx] ;FS:[0]<->EAX ;此时EAX存放的是原来异常处理代码,FS:[0]指向TEB中

;ExceptionList(FS指向TEB,ExceptionList偏移为0,即FS:[0])

call @0

@0:

pop ebx ;此三行计算代码入口,此时ebx就是@0的地址

lea ecx, StopToRunVirusCode-@0[ebx] ;将ecx指向自己内部代码处

push ecx ;填充_EXCEPTION_REGISTRATION结构的handler

;在发生异常时,操作系统会自动调用,此时为CIH代码

push eax ;EAX为原来异常处理代码

;填充_EXCEPTION_REGISTRATION结构的prev

.

.

.

这其后CIH调用int 3使系统发生异常,仍能进入自已的代码,这可从CIH源代码中的如下注释得到证实:

; *************************************

; * Generate Exception to Get Ring0 *

; *************************************

int HookExceptionNumber ; GenerateException

HookExceptionNumber定义为3,此段代码会产生异常,具体请参阅CIH源代码。

因为如上代码比较抽象,我特意将它稍加修改,以便于理解(PE格式可直接在Windows下执行):

// TestCIH.C 有任何问题联系tsu00@263.net

#include <windows.h>

#include <stdio.h>

EXCEPTION_DISPOSITION __cdecl _except_handler( //异常处理程序段

struct _EXCEPTION_RECORD *ExceptionRecord,

void * EstablisherFrame,

struct _CONTEXT *ContextRecord,

void * DispatcherContext )

{

printf( "CIH Run Here...\n" );

exit(0); //由于堆栈已被程序打乱,有兴趣的可以自己将它恢复,这儿我只简单的退出

}

void main(void)

{

_asm

{

push ebp

mov eax, esp

sub eax, 8 //这两行相当于lea eax, [esp-04h*2]

xor ebx, ebx

xchg eax, fs:[ebx]

call next

next:

pop ebx //这三行在这没实在意义,只是为了与CIH对比

lea ecx, _except_handler //将_except_handler设为异常处理入口

push ecx

push eax

}

_asm

{

mov eax,0

mov [eax],0 //发生STATUS_ACCESS_VIOLATION异常让操作系统调用_except_handler

}

}

_except_handler回调函数原形可参阅EXCPT.H

在main函数中第一个_asm段与前面讨论的CIH代码基本一致,而第二个_asm段则试图写系统保留内存地址,发生异常。

使用Visual C++如下编译:

c:>Cl testCIH.c

c:>testCIH

CIH Run Here...

在Windows 2000中,运行此段代码时,出现异常后操作系统将控制权交给_except_handler执行,这样CIH代码在NT/2000环境下在系统修改被其保护的内存地址时(IDT区域),不至于出现非法操作等提示,以达到保护自己的目的!

我总觉得了解系统安全,首先必须对这个系统有足够的了解,就像了解CIH病毒一样,而目前国内在这方面的资料可真谓少之又少,本文仅在这方面说出我自己的一些切身实践,错误之处,在所难免。如果您有任何发现,如果您对这方面有比较有兴趣,请联系tsu00@263.net.

最后很感谢绿盟高手的指点与帮助!

参考文献:

1.Jeffrey Richter <<Advanced Windows NT>>

2.Matt Pietrek <<A Crash Course on the Depths of Win32 Structured Exception Handling>>

3.CIH 1.3源代码

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有