ssdt学习笔记Word文件下载.docx
《ssdt学习笔记Word文件下载.docx》由会员分享,可在线阅读,更多相关《ssdt学习笔记Word文件下载.docx(20页珍藏版)》请在冰豆网上搜索。
SYSTEM_SERVICE_TABLEntoskrnl;
//ntoskrnl.exe(nativeapi)
SYSTEM_SERVICE_TABLEwin32k;
//win32k.sys(gdi/usersupport)
SYSTEM_SERVICE_TABLETable3;
//notused
SYSTEM_SERVICE_TABLETable4;
SYSTEM_DESCRIPTOR_TABLE,
*PSYSTEM_DESCRIPTOR_TABLE,
**PPSYSTEM_DESCRIPTOR_TABLE;
其实KeServiceDescriptorTableShadow包含4个子结构,其中第一个就是ntoskrnl.exe(nativeapi),和KeServiceDescriptorTable指向一样我们真正需要获得的是第二个win32k.sys(gdi/usersupport),第三个和第四个一般不使用
定位方法
硬编码
//forxp
if(gKernelVersion==WINXP)
KeServiceDescriptorTableShadow=KeServiceDescriptorTable-0x40;
//for2k
if(gKernelVersion==WIN2K)
KeServiceDescriptorTableShadow=KeServiceDescriptorTable+0xE0;
2。
搜索KeAddSystemServiceTable
反汇编代码可以看出
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!
805ba5a38d8840a65580leaecx,nt!
KeServiceDescriptorTableShadow(8055a640)[eax]
805ba5a9833900cmpdwordptr[ecx],0
805ba5ac7534jnent!
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
搜索办法很简单
就是找到
的8d8840a65580leaecx,nt!
KeServiceDescriptorTableShadow
代码如下
voidGetKeServiceDescriptorTableShadow()
PUCHARcPtr,pOpcode;
ULONGLength;
for(cPtr=(PUCHAR)KeAddSystemServiceTable;
cPtr<
(PUCHAR)KeAddSystemServiceTable+PAGE_SIZE;
cPtr+=Length)
if(!
MmIsAddressValid(cPtr))break;
Length=SizeOfCode(cPtr,&
pOpcode);
Length||(Length==1&
&
*pOpcode==0xC3))break;
if(*(PUSHORT)pOpcode==0x888D)
KeServiceDescriptorTableShadow=*(PVOID*)(pOpcode+2);
break;
3。
从KTHREAD.ServiceTable里面搜索
如果是GUI线程那么就是指向ServiceDescriptorTableShadow
其实个人更加倾向这个办法稳定安全可靠,上面那个代码也许会受到以后系统代码变化影响但是这个肯定不会
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]
.ifeax>
edx;
somestupiderrorchecking
movebx,eax
invokeDbgPrint,$CTA0("
FindShadowTable:
FoundinthreadwithID:
%X\n"
),dwThreadId
.break
.endif
adddwThreadId,4
moveax,ebx
ret
GetServiceDescriptorTableShadowAddressendp
4.mj0011所说的搜索有效内存地址的办法
/*
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
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
//otherwise,thereisavalidaddress!
Soreturnit!
returnrc;
二。
函数名定位
这个似乎没有多少好办法,解析pdb可以是可以但是很麻烦
不过还好的是同一个版本的系统调用号一样
所以只需要3套2kxp2k3的调用号就可以完成hook
pdb办法
SymInitialize初始化
SymSetSearchPath“srv**symbols*
SymLoadModule
SymGetSymFromName
老v曾经发出1个获取shadow地址和函数名称的工具使用他可以很方便的获取
具体代码可以F5查看
以上读取pdb的方法测试使用的可以的
但是实际使用很麻烦
经过分析我找到了1个比较好的定位办法
我们以SetWindowsHookExA为例子
.text:
77D311D1;
HHOOK__stdcallSetWindowsHookExA(intidHook,HOOKPROClpfn,HINSTANCEhmod,DWORDdwThreadId)
77D311D1public_SetWindowsHookExA@16
77D311D1_SetWindowsHookExA@16procnear
77D311D1
77D311D1idHook=dwordptr8
77D311D1lpfn=dwordptr0Ch
77D311D1hModule=dwordptr10h
77D311D1dwThreadId=dwordptr14h
77D311D1movedi,edi
77D311D3pushebp
77D311D4movebp,esp
77D311D6push2;
int
77D311D8push[ebp+dwThreadId];
77D311DBpush[ebp+hModule];
hModule
77D311DEpush[ebp+lpfn];
77D311E1push[ebp+idHook];
77D311E4call_SetWindowsHookExAW@20;
SetWindowsHookExAW(x,x,x,x,x)
77D311E9popebp
77D311EAretn10h
77D311EA_SetWindowsHookExA@16endp
77D2DCFD;
int__stdcallSetWindowsHookExAW(int,int,HMODULEhModule,int,int)
77D2DCFD_SetWindowsHookExAW@20procnear;
CODEXREF:
SetWindowsHookExW(x,x,x,x)+13p
SetWindowsHookExA(x,x,x,x)+13p
77D2DCFD
77D2DCFDFilename=wordptr-20Ch
77D2DCFDvar_4=dwordptr-4
77D2DCFDarg_0=dwordptr8
77D2DCFDarg_4=dwordptr0Ch
77D2DCFDhModule=dwordptr10h
77D2DCFDarg_C=dwordptr14h
77D2DCFDarg_10=dwordptr18h
77D2DCFDmovedi,edi
77D2DCFFpushebp
77D2DD00movebp,esp
77D2DD02subesp,20Ch
77D2DD08moveax,___security_cookie
77D2DD0Dpushesi
77D2DD0Emovesi,[ebp+hModule]
77D2DD11testesi,esi
77D2DD13pushedi
77D2DD14movedi,[ebp+arg_4]
77D2DD17mov[ebp+var_4],eax
77D2DD1Ajzshortloc_77D2DD33
77D2DD1Cpush104h;
nSize
77D2DD21leaeax,[ebp+Filename]
77D2DD27pusheax;
lpFilename
77D2DD28pushesi;
77D2DD29callds:
__imp__GetModuleFileNameW@12;
GetModuleFileNameW(x,x,x)
77D2DD2Ftesteax,eax
77D2DD31jzshortloc_77D2DD52
77D2DD33
77D2DD33loc_77D2DD33:
;
SetWindowsHookExAW(x,x,x,x,x)+1Dj
77D2DD33push[ebp+arg_10]
77D2DD36moveax,esi
77D2DD38pushedi
77D2DD39push[ebp+arg_0]
77D2DD3Cnegeax
77D2DD3Epush[ebp+arg_C]
77D2DD41sbbeax,eax
77D2DD43leaecx,[ebp+Filename]
77D2DD49andeax,ecx
77D2DD4Bpusheax
77D2DD4Cpushesi
77D2DD4Dcall__SetWindowsHookEx@24;
_SetWindowsHookEx(x,x,x