首页
社区
课程
招聘
[讨论]一张图说明我的问题,请高人帮我看一下GetWin32kBase为什么有的机器出错有的机器正常,百撕不得其解
发表于: 2013-4-26 12:29 5923

[讨论]一张图说明我的问题,请高人帮我看一下GetWin32kBase为什么有的机器出错有的机器正常,百撕不得其解

2013-4-26 12:29
5923
首先,我不是标题党,我只是遇到问题了,我想尽可能用最简单的语言描绘我的错误;

网上找了份关于恢复Shadow的代码,其中里面有个函数“GetWin32kBase”,
为什么有的机器运行正常,有的机器运行不正常,和别人的代码无差;
结果同样的GHOST系统,做到同样2台配置一样的机器上,
一台蓝屏,一台正常,请高人帮我看一下,下面附上代码就直接出图片了






[课程]Linux pwn 探索篇!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 12
活跃值: (767)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
调试基本靠猜...
2013-4-26 12:48
0
雪    币: 88
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
_wcsicmp的问题,Buffer可能没那么长
2013-4-26 12:57
0
雪    币: 121
活跃值: (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
不知道是不是你说的问题,发帖之后我全部自己用记事本敲了一次代码,这回编译之后2台电脑都可以用了,
感谢大家的围观,我估计是VC编译的参数什么的命运设置好,反正借上楼那位仁兄说的话,
测试基本靠猜,我这回是蒙对了
2013-4-26 16:19
0
雪    币: 121
活跃值: (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
附上我的代码。结贴

#include "ntddk.h"
#include "main.h"
#include "LDasm.h"

PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow = NULL;
PVOID pWin32kBase = NULL;
ULONG g_NtUserSendInput = 0;

VOID GetWin32kBase(PDRIVER_OBJECT pDriverObj)
{
PLIST_ENTRY pList = NULL;
//InitializeListHead(&pList);

PLDR_DATA_TABLE_ENTRY Ldr = NULL;

pList = ( (PLIST_ENTRY)pDriverObj->DriverSection )->Flink;
do {
Ldr = CONTAINING_RECORD(pList,LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (Ldr->EntryPoint &&Ldr->FullDllName.Buffer)
{
//DbgPrint(Ldr->FullDllName.Buffer);

if ( !_wcsicmp(Ldr->FullDllName.Buffer, L"\\systemroot\\system32\\win32k.sys") )
{
//比较模块名字,应该比较FullDllName,单单比较BaseDllName很可能会遇到同名文件。
pWin32kBase = Ldr->DllBase;//保存模块基址
break;
}
}
pList = pList->Flink;//下一个链表
} while ( pList != ((LIST_ENTRY*)pDriverObj->DriverSection)->Flink );
}


VOID GetSSDTShadowBase()
{
UCHAR *cPtr;
UCHAR *pOpcode;
ULONG Length;
for (cPtr = (PUCHAR)KeAddSystemServiceTable;
cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);

if (!Length) break;

if ( *(PUSHORT)cPtr == 0x888D )
{
KeServiceDescriptorTableShadow = (PKSERVICE_TABLE_DESCRIPTOR)(*(ULONG *)((ULONG)pOpcode + 2));
break;
}
}
}


NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
if (g_NtUserSendInput==0)
{
GET_INPUT();
if (g_NtUserSendInput!=0)
{
DbgPrint("Get OK\n");
}
}
else
{
//在这里恢复?创建的时候?
RestoreShadow();
DbgPrint("hook OK\n");
}

RestoreShadow();
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
DbgPrint("IRP_MJ_CREATE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
DbgPrint("IRP_MJ_CLOSE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{
DeleteDrive(pDriverObj);
DbgPrint("Unload");
}

NTSTATUS DeleteDrive(PDRIVER_OBJECT pDriverobj)
{
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverobj->DeviceObject);
DbgPrint("Unloaded\n");
return STATUS_SUCCESS;
}
NTSTATUS Createdrive(PDRIVER_OBJECT pDriverobj)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustrLinkName;
UNICODE_STRING ustrDevName;
PDEVICE_OBJECT pDevObj;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);

status = IoCreateDevice(pDriverobj,
0,
&ustrDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj);

DbgPrint("Device Name %S", ustrDevName.Buffer);

if (!NT_SUCCESS(status))
{
DbgPrint("IoCreateDevice = 0x%x\n", status);
return status;
}

RtlInitUnicodeString(&ustrLinkName, LINK_NAME);

status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if (!NT_SUCCESS(status))
{
DbgPrint("IoCreateSymbolicLink = 0x%x\n", status);
IoDeleteDevice(pDevObj);
return status;
}

DbgPrint("SymbolicLink:%S", ustrLinkName.Buffer);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObj->DriverUnload = DriverUnload;

if(Createdrive(pDriverObj)==STATUS_SUCCESS)
{
GetWin32kBase(pDriverObj);
DbgPrint("Win32Base:%X",pWin32kBase);
GetSSDTShadowBase();
DbgPrint("KeServiceDescriptorTableShadow:%X",KeServiceDescriptorTableShadow);
}
return STATUS_SUCCESS;
}



NTSTATUS GET_INPUT()
{
NTSTATUS status;
HANDLE hFile;//文件句柄
OBJECT_ATTRIBUTES ObjAttr;
UNICODE_STRING ustrWin32k;
IO_STATUS_BLOCK ioStatus;
ULONG ulShadowRaw = 0;
ULONG ulShadowBase = 0;
PVOID PoolArea = NULL;
FILE_POSITION_INFORMATION fpi;
LARGE_INTEGER Offset;
ULONG OrigAddress = 0;
ULONG CurAddress = 0;
ULONG i = 0;
ULONG ulCount = 0;
PULONG pAddr;
ULONG hookAddr=0;

if ( pWin32kBase == NULL ||
KeServiceDescriptorTableShadow == NULL)
{
DbgPrint("Error.");
return STATUS_UNSUCCESSFUL;
}
//索引为1的项目?

ulCount = KeServiceDescriptorTableShadow[1].Limit;//Linit就是表中函数的个数

DbgPrint("Count Of Shadow : %d\n", ulCount );

ulShadowBase = *(ULONG*)&KeServiceDescriptorTableShadow[1].Base;//得到基址

DbgPrint("ulShadowBase = 0x%X\n",ulShadowBase);
//镜像中的偏移,file offset???
ulShadowRaw = ulShadowBase - (ULONG)pWin32kBase;
//ulShadowRaw = RVAToRaw(pWin32kBase,ulShadowBase);

DbgPrint("ulShadowRaw = 0x%X\n",ulShadowRaw);

RtlInitUnicodeString(&ustrWin32k, L"\\SystemRoot\\System32\\win32k.sys");
//分配空间
PoolArea = ExAllocatePool( PagedPool, sizeof(ULONG) * ulCount );
//分配空间,用于保存读取到的数据,因为每个地址的长度sizeof(ULONG),个数是ulCount,所以相乘

if (!PoolArea) {
DbgPrint("PoolArea is null\n");
return STATUS_UNSUCCESSFUL;
}

RtlZeroMemory(&ObjAttr, sizeof(ObjAttr) );
//获取Win32k.sys的属性
InitializeObjectAttributes(
&ObjAttr,
&ustrWin32k,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
//打开文件win32K.SYS
status = IoCreateFile(
&hFile,
FILE_READ_ATTRIBUTES,
&ObjAttr,
&ioStatus,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
0,
NULL,
0,
CreateFileTypeNone,
NULL,
IO_NO_PARAMETER_CHECKING);

if ( !NT_SUCCESS(status) ) {
DbgPrint("IoCreateFile Error : 0x%X", status);
goto __exit;
}

//设置文件偏移
Offset.LowPart = ulShadowRaw;
Offset.HighPart = 0;
//开始读取数据
status = ZwReadFile (
hFile,
NULL,
NULL,
NULL,
&ioStatus,
//从文件读出到分配空间
PoolArea,
ulCount*sizeof(ULONG),
//偏移
&Offset,
NULL);

if ( !NT_SUCCESS(status) ) {
DbgPrint("ZwReadFile Error : 0x%X");
goto __exit;
}
//改变指针类型
pAddr = (PULONG)PoolArea;
//比较原始地址与当前的地址并且输出调试
_asm
{
CLI
MOV EAX,CR0
AND EAX,NOT 10000H
MOV CR0,EAX
}

OrigAddress = *pAddr;//指向原始地址
CurAddress = KeServiceDescriptorTableShadow[1].Base[502];//读取当前地址

if (g_NtUserSendInput==0)
{
__asm
{
MOV EAX,g_NtUserSendInput
CMP EAX,0
JNE L_Get1
MOV EAX,CurAddress
MOV BX,WORD PTR DS:[EAX]
CMP BX,0x186A
JNE L_Get1
MOV EAX,DWORD PTR DS:[EAX+3]
MOV g_NtUserSendInput,EAX
L_Get1:
}
DbgPrint("获取SendInput:%X\r\n",g_NtUserSendInput);
}




_asm
{
MOV EAX,CR0
OR EAX,10000h
MOV CR0,EAX
STI
}

__exit:
if (PoolArea) {
ExFreePool(PoolArea);
//释放空间
}
if (hFile) {
ZwClose(hFile);
//关闭句柄
}
return status;
}

NTSTATUS RestoreShadow()
{
NTSTATUS status;
HANDLE hFile;//文件句柄
OBJECT_ATTRIBUTES ObjAttr;
UNICODE_STRING ustrWin32k;
IO_STATUS_BLOCK ioStatus;
ULONG ulShadowRaw = 0;
ULONG ulShadowBase = 0;
PVOID PoolArea = NULL;
FILE_POSITION_INFORMATION fpi;
LARGE_INTEGER Offset;
ULONG OrigAddress = 0;
ULONG CurAddress = 0;
ULONG i = 0;
ULONG ulCount = 0;
PULONG pAddr;
ULONG hookAddr=0;

if ( pWin32kBase == NULL ||
KeServiceDescriptorTableShadow == NULL)
{
DbgPrint("Error.");
return STATUS_UNSUCCESSFUL;
}
//索引为1的项目?

ulCount = KeServiceDescriptorTableShadow[1].Limit;//Linit就是表中函数的个数

DbgPrint("Count Of Shadow : %d\n", ulCount );

ulShadowBase = *(ULONG*)&KeServiceDescriptorTableShadow[1].Base;//得到基址

DbgPrint("ulShadowBase = 0x%X\n",ulShadowBase);
//镜像中的偏移,file offset???
ulShadowRaw = ulShadowBase - (ULONG)pWin32kBase;
//ulShadowRaw = RVAToRaw(pWin32kBase,ulShadowBase);

DbgPrint("ulShadowRaw = 0x%X\n",ulShadowRaw);

RtlInitUnicodeString(&ustrWin32k, L"\\SystemRoot\\System32\\win32k.sys");
//分配空间
PoolArea = ExAllocatePool( PagedPool, sizeof(ULONG) * ulCount );
//分配空间,用于保存读取到的数据,因为每个地址的长度sizeof(ULONG),个数是ulCount,所以相乘

if (!PoolArea) {
DbgPrint("PoolArea is null\n");
return STATUS_UNSUCCESSFUL;
}

RtlZeroMemory(&ObjAttr, sizeof(ObjAttr) );
//获取Win32k.sys的属性
InitializeObjectAttributes(
&ObjAttr,
&ustrWin32k,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
//打开文件win32K.SYS
status = IoCreateFile(
&hFile,
FILE_READ_ATTRIBUTES,
&ObjAttr,
&ioStatus,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
0,
NULL,
0,
CreateFileTypeNone,
NULL,
IO_NO_PARAMETER_CHECKING);

if ( !NT_SUCCESS(status) ) {
DbgPrint("IoCreateFile Error : 0x%X", status);
goto __exit;
}

//设置文件偏移
Offset.LowPart = ulShadowRaw;
Offset.HighPart = 0;
//开始读取数据
status = ZwReadFile (
hFile,
NULL,
NULL,
NULL,
&ioStatus,
//从文件读出到分配空间
PoolArea,
ulCount*sizeof(ULONG),
//偏移
&Offset,
NULL);

if ( !NT_SUCCESS(status) ) {
DbgPrint("ZwReadFile Error : 0x%X");
goto __exit;
}
//改变指针类型
pAddr = (PULONG)PoolArea;
//比较原始地址与当前的地址并且输出调试
_asm
{
CLI
MOV EAX,CR0
AND EAX,NOT 10000H
MOV CR0,EAX
}

//OrigAddress = *pAddr;//指向原始地址
CurAddress = KeServiceDescriptorTableShadow[1].Base[502];//读取当前地址


_asm
{
MOV EAX,CR0
OR EAX,10000h
MOV CR0,EAX
STI
}

__exit:
if (PoolArea) {
ExFreePool(PoolArea);
//释放空间
}
if (hFile) {
ZwClose(hFile);
//关闭句柄
}
return status;
}
2013-4-26 16:21
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
6
if ( !_wcsicmp(Ldr->FullDllName.Buffer, L"\\systemroot\\system32\\win32k.sys") )

好蛋碎。。干嘛不用RtlCompareUnicodeString
2013-4-26 17:25
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
7
好高级
2013-4-27 13:46
0
游客
登录 | 注册 方可回帖
返回
//