能力值:
( LV4,RANK:50 )
|
-
-
2 楼
我就当一把沙发吧,虽然看不懂,但是顶起来吧
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
还没见过win8啥样子了
下个 学习下新系统的HOOK
|
能力值:
( LV13,RANK:1760 )
|
-
-
4 楼
没装过win8系统的飘过...
|
能力值:
(RANK:50 )
|
-
-
5 楼
粗看一下没明白。
win32k.sys因为会话空间的原因直接在非GUI线程下访问可能未在地址空间中被映射到问题是老生常谈了,XP下也得这样处理呀
|
能力值:
( LV3,RANK:20 )
|
-
-
6 楼
但是在使用KeAddSystemServiceTable函数搜索shadow地址在win8中不成功了。
这个方法是全新的,根据系统定位shadow方法,搜索线程来定位shadow。全新方法。
|
能力值:
(RANK:50 )
|
-
-
7 楼
粗看一下没明白。就是取SSDT Shadow的方式不一样。
而且……规范的做法是通过调试符号寻找win32k!W32pServiceTable
win32k.sys因为会话空间的原因直接在非GUI线程下访问可能未在地址空间中被映射到问题是老生常谈了,XP下也得这样处理呀
|
能力值:
( LV3,RANK:20 )
|
-
-
8 楼
我在KiFastCallEntry函数中看系统是,查找KTHREAD!ServiceTable成员得到shadow地址的。
我这个方法模仿了系统的查找方法。
|
能力值:
(RANK:50 )
|
-
-
9 楼
额,一开始看标题还以为win8 32位里有PG还是啥的
|
能力值:
( LV3,RANK:30 )
|
-
-
10 楼
mark
|
能力值:
( LV9,RANK:610 )
|
-
-
11 楼
从线程KTHREAD里找服务表的方法早就有了啊,只不过大家一般都用别的方法了,这种用得少而已,XP里也是这么干的,真不是什么新方法。。。。至少四年前在DebugMan就看过了
还有win32k.sys访问的问题,与GUI无关,是Session的原因,只要不是smss.exe或System,其它进程都可以访问的
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
感谢楼主分享好方法!
|
能力值:
( LV4,RANK:50 )
|
-
-
13 楼
粗略的看了下,说了KeServiceDescriptorTableShadow 在win8 x86中位置变了。不过有多少人用win8 x86呢?
|
能力值:
( LV3,RANK:20 )
|
-
-
14 楼
从GUI ethread的ServiceTable取这个方法不是一直都有??只不过在之前的系统上。。不如搜索出来的好罢了。。ethread的servicetable毕竟是可以被很简单的就改了的。。
|
能力值:
( LV3,RANK:20 )
|
-
-
15 楼
这个是我自己研究的,从来没看见谁公布过。系统取SSDT或者ssdt shadow 基地址 并不是搜索KeAddSystemServiceTable函数。 哈哈
|
能力值:
( LV3,RANK:20 )
|
-
-
16 楼
为什么我在同一个session下,换一个带GUI的线程就可以在内存空间中访问到Win32k?
看来session不是必要条件,带GUI的进程,线程才是必要条件。
系统在查找Shadow时,也是先看KTHREAD的 Win32Thread成员,确定其是否是gui线程。然后才取得ServiceTable成员。
非GUI线程的Win32Thread成员是0,当然ServiceTable指向的是SSDT,而非Shadow。 这个可以请各位自行验证。
|
能力值:
( LV12,RANK:400 )
|
-
-
17 楼
顶大牛
|
能力值:
( LV9,RANK:610 )
|
-
-
18 楼
这个我早就验证过了,不然不会随便说这些~
你确定你切换进程之前不是在System进程里? 要不你切换到csrss看看? 切换到lsass看看? 或者随便哪个你认为没有GUI的看看? 看到底能不能访问?
|
能力值:
( LV3,RANK:20 )
|
-
-
19 楼
我以前也在这方面有疑惑,能详细介绍一下Session吗
|
能力值:
( LV9,RANK:610 )
|
-
-
20 楼
另外你说的系统取服务表的过程,跟GUI不GUI的只不过是巧合而已吧,因为System和smss这两个Session之外的进程根本不会调用Shadow表里的服务,而其它进程的线程才区分这两种情况,但是那都是在Session内的进程~ 另外,我觉得系统完全可以不必要在KTHREAD里区分SSDT和SSDT Shadow,统一换成SSDT Shadow就可以了,反正调用的时候有索引可以判断来使用哪张表~
|
能力值:
( LV9,RANK:610 )
|
-
-
21 楼
刚又看了下KiFastCallEntry的代码,证实了我刚才的说法~
一、系统创建线程时,默认Thread->ServiceTable填充的都是KeServiceDescriptorTable,具体可参考KeInitThread函数
二、在KeFastCallEntry中,系统根本不是在判断这个线程是不是GUI线程,它只是判断这个服务的Index是不是超出了SSDT表的范围而已,因为SSDT Shadow的服务项数比SSDT多,所以如果发现服务的Index超出了SSDT表的范围,就认为这是一个SSDT Shadow的调用,然后调用PsConvertToGuiThread把Thread->ServiceTable切换为KeServiceDescriptorTableShadow,另外就是切换一下内核栈,使线程可以使用更大的内核栈空间,就这两个动作~
所以,理论上来讲,如果系统创建线程的时候就把Thread->ServiceTable填充为KeServiceDescriptorTableShadow并且使用更大的内核栈,完全不会有问题,因为GUI线程和非GUI线程需要的条件都满足了~ 只不过这样做会消耗更大的内核空间,所以才做了GUI线程和非GUI线程的区分,只给GUI线程以必要的资源,但是对于访问win32k.sys这个,GUI和非GUI并没有不同~~
所以,你首先确认下win32k.sys的访问问题,到底是除smss和System外的所有进程都可以访问,还是只有GUI进程可以访问,这个不难吧?
|
能力值:
( LV9,RANK:610 )
|
-
-
22 楼
发现几篇不错的文章,关于Session Space的
http://www.cnblogs.com/kkindof/archive/2012/07/01/2571538.html
http://www.cnblogs.com/kkindof/archive/2012/07/01/2571782.html
http://www.cnblogs.com/kkindof/archive/2012/07/01/2571799.html
http://www.blogbus.com/debug-sai-logs/109178332.html
初始情况下,smss不属于任何session,然后它自己创建了一个Session,然后创建csrss和winlogon继承了该Session,之后加载win32k.sys,最后又调用NtSetSystemInformation从Session中Detach了,而win32k.sys加载的位置是在MmSessionSpace范围内的(32位系统的SessionSpace范围是bc000000到c0000000,这就是为什么win32k.sys的默认基址是bf800000),所以从Session中脱离之后就访问不到SessionSpace范围内的内存了~~
由于SmpStartCsr是在SmpApiLoop中被调用的,所以从理论上分析,smss继续创建一个新的Session的时候(比如另一个用户登录到系统),依然会重复“创建Session”->"启动csrss、winlogon和加载win32k.sys"->“从Session中脱离”这个动作,只不过win32k.sys也是有加载记数的,后面再加载和卸载的时候只会改变记数(这是MmLoadSystemImage内部处理的),从Session中脱离的时候就会把SessionSpace对应的PTE清零,所以访问不到win32k了~
以下是xp的smss.exe中的部分代码:
int __stdcall SmpStartCsr(int a1, int a2, int a3)
{
signed int v3; // ebx@1
int v4; // esi@1
int v5; // ecx@1
int v6; // eax@1
int v8; // eax@3
int v9; // edi@3
__int16 *v10; // eax@5
int v11; // eax@7
CHAR *v12; // [sp-Ch] [bp-34h]@4
int v13; // [sp-8h] [bp-30h]@4
char v14; // [sp+8h] [bp-20h]@3
__int16 v15; // [sp+10h] [bp-18h]@1
__int16 v16; // [sp+12h] [bp-16h]@1
int v17; // [sp+14h] [bp-14h]@1
int v18; // [sp+18h] [bp-10h]@12
int v19; // [sp+1Ch] [bp-Ch]@3
int v20; // [sp+20h] [bp-8h]@7
int v21; // [sp+24h] [bp-4h]@7
v4 = a1;
v5 = *(_DWORD *)(a1 + 32);
v3 = 0;
v15 = *(_WORD *)(a1 + 36);
v16 = v15;
v6 = a1 + 40;
a1 = v5;
v17 = v6;
if ( !v5 )
{
*(_DWORD *)(v4 + 300) = SmpWindowsSubSysProcessId;
*(_DWORD *)(v4 + 296) = SmpInitialCommandProcessId;
return 0;
}
v19 = 0;
//下面这个函数启动csrss等进程和加载win32k.sys
[COLOR="Red"]v8 = SmpLoadSubSystemsForMuSession(&a1, (int)&v19, (int)&v14);[/COLOR]
v9 = v8;
if ( v8 )
{
v13 = v8;
v12 = "SMSS: SmpStartCsr, SmpLoadSubSystemsForMuSession Failed. Status=%x\n";
}
else
{
v10 = (__int16 *)&v14;
if ( v15 )
v10 = &v15;
v11 = SmpExecuteInitialCommand(a1, v10, &v21, &v20);
v9 = v11;
if ( v11 >= 0 )
{
NtClose(v21);
*(_DWORD *)(v4 + 296) = v20;
*(_DWORD *)(v4 + 300) = v19;
*(_DWORD *)(v4 + 32) = a1;
goto LABEL_11;
}
v13 = v11;
v3 = 1;
v12 = "SMSS: SmpStartCsr, SmpExecuteInitialCommand Failed. Status=%x\n";
}
DbgPrint(v12, v13);
LABEL_11:
if ( AttachedSessionId != -1 )
{
[COLOR="red"]if ( SmpAcquirePrivilege(10, &v18) >= 0 )
{
if ( NtSetSystemInformation(48, &AttachedSessionId, 4) >= 0 )
AttachedSessionId = -1;
SmpReleasePrivilege(v18);
}[/COLOR]
}
if ( v3 == 1 )
SmpTerminateCSR(a1);
return v9;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
23 楼
你这个方法,至少6年前debugman上就公布了,我记得当时公布了大概有3~4种方法取shadow table。
你这个方法也不是什么大不了的东西,Ida看一下交叉引用3秒内就能想出来的。
另外,代码搜索法也不是不行,按版本换个特征码就可以了,更简单
|
能力值:
( LV3,RANK:20 )
|
-
-
24 楼
首先你说的那个帖子我没有看到过。你可以找出来看看它是怎么讲得?
|
能力值:
( LV3,RANK:30 )
|
-
-
25 楼
win8 32不会PG吗?我还以为win7 64之后都不能再用ssdt了。
|
|
|