ssdt学习笔记.docx

上传人:b****7 文档编号:9766831 上传时间:2023-02-06 格式:DOCX 页数:20 大小:21.38KB
下载 相关 举报
ssdt学习笔记.docx_第1页
第1页 / 共20页
ssdt学习笔记.docx_第2页
第2页 / 共20页
ssdt学习笔记.docx_第3页
第3页 / 共20页
ssdt学习笔记.docx_第4页
第4页 / 共20页
ssdt学习笔记.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

ssdt学习笔记.docx

《ssdt学习笔记.docx》由会员分享,可在线阅读,更多相关《ssdt学习笔记.docx(20页珍藏版)》请在冰豆网上搜索。

ssdt学习笔记.docx

ssdt学习笔记

标题:

【原创】shadowssdt学习笔记

(一)

(二)

作者:

zhuwg

时间:

2007-12-22,22:

01:

29

链接:

1。

取得shadowssdt真实地址

系统只提供了KeServiceDescriptorTable导出

KeServiceDescriptorTableShadow是个未导出结构

定义

Copycode

typedefstruct_SYSTEM_SERVICE_TABLE

{

PNTPROCServiceTable;//arrayofentrypoints

PDWORDCounterTable;//arrayofusagecounters

DWORDServiceLimit;//numberoftableentries

PBYTEArgumentTable;//arrayofbytecounts

}

SYSTEM_SERVICE_TABLE,

*PSYSTEM_SERVICE_TABLE,

**PPSYSTEM_SERVICE_TABLE;

//-----------------------------------------------------------------------------------------------------------

typedefstruct_SERVICE_DESCRIPTOR_TABLE

{

SYSTEM_SERVICE_TABLEntoskrnl;//ntoskrnl.exe(nativeapi)

SYSTEM_SERVICE_TABLEwin32k;//win32k.sys(gdi/usersupport)

SYSTEM_SERVICE_TABLETable3;//notused

SYSTEM_SERVICE_TABLETable4;//notused

}

SYSTEM_DESCRIPTOR_TABLE,

*PSYSTEM_DESCRIPTOR_TABLE,

**PPSYSTEM_DESCRIPTOR_TABLE;

其实KeServiceDescriptorTableShadow包含4个子结构,其中第一个就是ntoskrnl.exe(nativeapi),和KeServiceDescriptorTable指向一样我们真正需要获得的是第二个win32k.sys(gdi/usersupport),第三个和第四个一般不使用

定位方法

1。

硬编码

Copycode

//forxp

if(gKernelVersion==WINXP)

KeServiceDescriptorTableShadow=KeServiceDescriptorTable-0x40;

//for2k

if(gKernelVersion==WIN2K)

KeServiceDescriptorTableShadow=KeServiceDescriptorTable+0xE0;

2。

搜索KeAddSystemServiceTable

反汇编代码可以看出

Copycode

lkd>uKeAddSystemServiceTablel40

nt!

KeAddSystemServiceTable:

805ba5898bffmovedi,edi

805ba58b55pushebp

805ba58c8becmovebp,esp

805ba58e837d1803cmpdwordptr[ebp+18h],3

805ba592774ejant!

KeAddSystemServiceTable+0x6b(805ba5e2)

805ba5948b4518moveax,dwordptr[ebp+18h]

805ba597c1e004shleax,4

805ba59a83b880a6558000cmpdwordptrnt!

KeServiceDescriptorTable(8055a680)[eax],0

805ba5a1753fjnent!

KeAddSystemServiceTable+0x6b(805ba5e2)

805ba5a38d8840a65580leaecx,nt!

KeServiceDescriptorTableShadow(8055a640)[eax]

805ba5a9833900cmpdwordptr[ecx],0

805ba5ac7534jnent!

KeAddSystemServiceTable+0x6b(805ba5e2)

805ba5ae837d1801cmpdwordptr[ebp+18h],1

805ba5b28b5508movedx,dwordptr[ebp+8]

805ba5b556pushesi

805ba5b68b7510movesi,dwordptr[ebp+10h]

805ba5b957pushedi

805ba5ba8b7d14movedi,dwordptr[ebp+14h]

805ba5bd8911movdwordptr[ecx],edx

805ba5bf8b4d0cmovecx,dwordptr[ebp+0Ch]

805ba5c2898844a65580movdwordptrnt!

KeServiceDescriptorTableShadow+0x4(8055a644)[eax],ecx

805ba5c889b048a65580movdwordptrnt!

KeServiceDescriptorTableShadow+0x8(8055a648)[eax],esi

805ba5ce89b84ca65580movdwordptrnt!

KeServiceDescriptorTableShadow+0xc(8055a64c)[eax],edi

805ba5d40f855a3e0300jnent!

KeAddSystemServiceTable+0x4d(805ee434)

805ba5da5fpopedi

805ba5dbb001moval,1

805ba5dd5epopesi

805ba5de5dpopebp

805ba5dfc21400ret14h

805ba5e232c0xoral,al

805ba5e4ebf8jmpnt!

KeAddSystemServiceTable+0x6d(805ba5de)

805ba5e690nop

805ba5e790nop

805ba5e890nop

805ba5e990nop

805ba5ea90nop

搜索办法很简单

就是找到

805ba5a38d8840a65580leaecx,nt!

KeServiceDescriptorTableShadow(8055a640)[eax]

的8d8840a65580leaecx,nt!

KeServiceDescriptorTableShadow

代码如下

Copycode

voidGetKeServiceDescriptorTableShadow()

{

PUCHARcPtr,pOpcode;

ULONGLength;

for(cPtr=(PUCHAR)KeAddSystemServiceTable;

cPtr<(PUCHAR)KeAddSystemServiceTable+PAGE_SIZE;

cPtr+=Length)

{

if(!

MmIsAddressValid(cPtr))break;

Length=SizeOfCode(cPtr,&pOpcode);

if(!

Length||(Length==1&&*pOpcode==0xC3))break;

if(*(PUSHORT)pOpcode==0x888D)

{

KeServiceDescriptorTableShadow=*(PVOID*)(pOpcode+2);

break;

}

}

}

3。

从KTHREAD.ServiceTable里面搜索

如果是GUI线程那么就是指向ServiceDescriptorTableShadow

其实个人更加倾向这个办法稳定安全可靠,上面那个代码也许会受到以后系统代码变化影响但是这个肯定不会

Copycode

GetServiceDescriptorTableShadowAddressprocusesesiediebx

localdwThreadId:

DWORD

xorebx,ebx;=NULL.AssumeServiceDescriptorTableShadowwillbenotfound

moveax,KeServiceDescriptorTable

movesi,[eax]

;FindKTHREAD.ServiceTablefield

;Fornon-GUIthreadsthisfield==KeServiceDescriptorTable

;anditpointstoServiceDescriptorTable

;ForGUIthreads

;ServiceDescriptorTableShadow

invokeKeGetCurrentThread

movedi,200h-4

.whileedi

.break.ifdwordptr[eax][edi]==esi

decedi

.endw

.ifedi!

=0

;edi=offsettoServiceTablefieldinKTHREADstructure

movdwThreadId,080h

.whiledwThreadId<400h

pusheax;reserveDWORDonstack

invokePsLookupThreadByThreadId,dwThreadId,esp

popecx;->ETHREAD/KTHREAD

.ifeax==STATUS_SUCCESS

pushdwordptr[ecx][edi]

fastcallObfDereferenceObject,ecx

popeax

.ifeax!

=esi

movedx,MmSystemRangeStart

movedx,[edx]

movedx,[edx]

.ifeax>edx;somestupiderrorchecking

movebx,eax

invokeDbgPrint,$CTA0("FindShadowTable:

FoundinthreadwithID:

%X\n"),dwThreadId

.break

.endif

.endif

.endif

adddwThreadId,4

.endw

.endif

moveax,ebx

ret

GetServiceDescriptorTableShadowAddressendp

4.mj0011所说的搜索有效内存地址的办法

Copycode

/*

definestructureforthesystemservicetable

*/

structSYS_SERVICE_TABLE{

void**ServiceTable;

unsignedlongCounterTable;

unsignedlongServiceLimit;

void**ArgumentsTable;

};

SYSTEM_DESCRIPTOR_TABLEKeServiceDescriptorTableShadow;

/*

DefineKeServiceDescriptorTablebasedontheSSTstructure

*/

externstructSYS_SERVICE_TABLE*KeServiceDescriptorTable;

/*

DeclarefunctionGetServiceDescriptorShadowTableAddress()

*/

//structSYS_SERVICE_TABLE*GetServiceDescriptorShadowTableAddress();

/*

DeclaretheKeAddSystemServiceTable.Thisisjusta

handletothecallfunction,itwillbeusedbythefunction

abovetoobtainthecorrectaddressoftheKeServiceDescriptorShadowTable

*/

__declspec(dllimport)KeAddSystemServiceTable(ULONG,ULONG,ULONG,ULONG,ULONG);

structSYS_SERVICE_TABLE*GetServiceDescriptorShadowTableAddress()

{

//First,obtainapointertoKeAddSystemServiceTable

unsignedchar*check=(unsignedchar*)KeAddSystemServiceTable;

inti;

//InitializeaninstanceofSystemServiceTable,willbeusedto

//obtainanaddressfromKeAddSystemServiceTable

structSYS_SERVICE_TABLE*rc=0;

//Make100attemptstomatchavalidaddresswiththatofKeServiceDescriptorTable

for(i=0;i<=99;i++){

__try{

//trytoobtainanaddressfromKeAddSystemServiceTable

rc=*(structSYS_SERVICE_TABLE**)check;

//ifthisaddressisNOTvalidORititselfistheaddressof

//KeServiceDescriptorTableORitsfirstentryisNOTequal

//tothefirstentryofKeServiceDescriptorTable

if(!

MmIsAddressValid(rc)||(rc==KeServiceDescriptorTable)

||(memcmp(rc,KeServiceDescriptorTable,sizeof(*rc))!

=0)){

//Proceedwiththenextaddress

check++;

//don'tforgettoresettheoldaddress

rc=0;

}

}__except(EXCEPTION_EXECUTE_HANDLER){rc=0;}

//whentheloopiscompleted,checkifitproducedavalidaddress

if(rc)

//becauseifitdidn't,wefailedtofindtheaddressofKeServiceDescriptorTableShadow

break;

}

//otherwise,thereisavalidaddress!

Soreturnit!

returnrc;

}

二。

函数名定位

这个似乎没有多少好办法,解析pdb可以是可以但是很麻烦

不过还好的是同一个版本的系统调用号一样

所以只需要3套2kxp2k3的调用号就可以完成hook

pdb办法

SymInitialize初始化

SymSetSearchPath“srv**symbols*

SymLoadModule

SymGetSymFromName

老v曾经发出1个获取shadow地址和函数名称的工具使用他可以很方便的获取

具体代码可以F5查看

以上读取pdb的方法测试使用的可以的

但是实际使用很麻烦

经过分析我找到了1个比较好的定位办法

我们以SetWindowsHookExA为例子

Copycode

.text:

77D311D1;HHOOK__stdcallSetWindowsHookExA(intidHook,HOOKPROClpfn,HINSTANCEhmod,DWORDdwThreadId)

.text:

77D311D1public_SetWindowsHookExA@16

.text:

77D311D1_SetWindowsHookExA@16procnear

.text:

77D311D1

.text:

77D311D1idHook=dwordptr8

.text:

77D311D1lpfn=dwordptr0Ch

.text:

77D311D1hModule=dwordptr10h

.text:

77D311D1dwThreadId=dwordptr14h

.text:

77D311D1

.text:

77D311D1movedi,edi

.text:

77D311D3pushebp

.text:

77D311D4movebp,esp

.text:

77D311D6push2;int

.text:

77D311D8push[ebp+dwThreadId];int

.text:

77D311DBpush[ebp+hModule];hModule

.text:

77D311DEpush[ebp+lpfn];int

.text:

77D311E1push[ebp+idHook];int

.text:

77D311E4call_SetWindowsHookExAW@20;SetWindowsHookExAW(x,x,x,x,x)

.text:

77D311E9popebp

.text:

77D311EAretn10h

.text:

77D311EA_SetWindowsHookExA@16endp

.text:

77D2DCFD;int__stdcallSetWindowsHookExAW(int,int,HMODULEhModule,int,int)

.text:

77D2DCFD_SetWindowsHookExAW@20procnear;CODEXREF:

SetWindowsHookExW(x,x,x,x)+13p

.text:

77D2DCFD;SetWindowsHookExA(x,x,x,x)+13p

.text:

77D2DCFD

.text:

77D2DCFDFilename=wordptr-20Ch

.text:

77D2DCFDvar_4=dwordptr-4

.text:

77D2DCFDarg_0=dwordptr8

.text:

77D2DCFDarg_4=dwordptr0Ch

.text:

77D2DCFDhModule=dwordptr10h

.text:

77D2DCFDarg_C=dwordptr14h

.text:

77D2DCFDarg_10=dwordptr18h

.text:

77D2DCFD

.text:

77D2DCFDmovedi,edi

.text:

77D2DCFFpushebp

.text:

77D2DD00movebp,esp

.text:

77D2DD02subesp,20Ch

.text:

77D2DD08moveax,___security_cookie

.text:

77D2DD0Dpushesi

.text:

77D2DD0Emovesi,[ebp+hModule]

.text:

77D2DD11testesi,esi

.text:

77D2DD13pushedi

.text:

77D2DD14movedi,[ebp+arg_4]

.text:

77D2DD17mov[ebp+var_4],eax

.text:

77D2DD1Ajzshortloc_77D2DD33

.text:

77D2DD1Cpush104h;nSize

.text:

77D2DD21leaeax,[ebp+Filename]

.text:

77D2DD27pusheax;lpFilename

.text:

77D2DD28pushesi;hModule

.text:

77D2DD29callds:

__imp__GetModuleFileNameW@12;GetModuleFileNameW(x,x,x)

.text:

77D2DD2Ftesteax,eax

.text:

77D2DD31jzshortloc_77D2DD52

.text:

77D2DD33

.text:

77D2DD33loc_77D2DD33:

;CODEXREF:

SetWindowsHookExAW(x,x,x,x,x)+1Dj

.text:

77D2DD33push[ebp+arg_10]

.text:

77D2DD36moveax,esi

.text:

77D2DD38pushedi

.text:

77D2DD39push[ebp+arg_0]

.text:

77D2DD3Cnegeax

.text:

77D2DD3Epush[ebp+arg_C]

.text:

77D2DD41sbbeax,eax

.text:

77D2DD43leaecx,[ebp+Filename]

.text:

77D2DD49andeax,ecx

.text:

77D2DD4Bpusheax

.text:

77D2DD4Cpushesi

.text:

77D2DD4Dcall__SetWindowsHookEx@24;_SetWindowsHookEx(x,x,x

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1