第二种思路:::
ssdt添加一个表项指向已经被hook的某api,我这例子里是NtOpenProcess
然后ring3 hook ntdll里的ZwOpenProcess.
其中的服务号修改成我们自己添加的 ssdt表项. 就好了
很简单是不是?~ 可是我这问题问了好多地方 没人理我,- - 跟人说吧 人家听不明白我想干啥?
表达能力成这样了~ 真xxx可悲.
//==========================ring3的=================================
#include "stdafx.h"
//copyright by Mink
//blog:
http://hi.baidu.com/Mink__declspec (naked) void WINAPI MyZwOpenProcess(DWORD ProcessHandle,DWORD DesiredAccess,DWORD ObjectAttributes,DWORD ClientId)
{
OutputDebugStringA("被hook了");
__asm
{
mov eax,11ch//服务号,xp sp3下283+1=284
mov edx,7FFE0300h
call dword ptr [edx]
ret 10h
}
}
DWORD GetApiAddress(DWORD imageBase,char* apiName)
//这里是eat 遍历的.跟本文主题没有关系,我原先想eat hook 代码就顺便写这里了
{
PIMAGE_DOS_HEADER pDosHead;
PIMAGE_NT_HEADERS pNtHead;
PIMAGE_DATA_DIRECTORY pDir;
PIMAGE_EXPORT_DIRECTORY pExportTable;
PDWORD AddressOfNames,AddressOfFunctions;
PWORD AddressOfNameOrdinals;//字
DWORD address=NULL;
pDosHead=(PIMAGE_DOS_HEADER)imageBase;
if(pDosHead->e_magic!=IMAGE_DOS_SIGNATURE)
{
goto err;
}
pNtHead=(PIMAGE_NT_HEADERS)((DWORD)pDosHead+pDosHead->e_lfanew);
if(pNtHead->Signature!=IMAGE_NT_SIGNATURE)
{
goto err;
}
pDir=(PIMAGE_DATA_DIRECTORY)&(pNtHead->OptionalHeader.DataDirectory);
pExportTable=(PIMAGE_EXPORT_DIRECTORY)((DWORD)pDosHead+pDir->VirtualAddress);
AddressOfNames=(PDWORD)((DWORD)pDosHead+pExportTable->AddressOfNames);
AddressOfNameOrdinals=(PWORD)((DWORD)pDosHead+pExportTable->AddressOfNameOrdinals);
AddressOfFunctions=(PDWORD)((DWORD)pDosHead+pExportTable->AddressOfFunctions);
for(int i=0;i<pExportTable->NumberOfNames;i++)
{
address=(DWORD)AddressOfFunctions[AddressOfNameOrdinals
];
//printf("apiName is: %s\t apiAddress is:0x%x\n",(char*)((DWORD)pDosHead+AddressOfNames),address);
if(!lstrcmpA((char*)((DWORD)pDosHead+AddressOfNames),apiName))
{
//printf("%s\n",(char*)((DWORD)pDosHead+AddressOfNames));
//printf("0x%x\n",imageBase);
address+=imageBase;
//printf("0x%x\n",address);
break;
}
}
err:
return address;
}
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE hMod;
HANDLE hand;
hMod=GetModuleHandle(L"ntdll.dll");
FARPROC openAddress;
DWORD dwOldProtect;
openAddress=GetProcAddress(hMod,"ZwOpenProcess");
VirtualProtect(openAddress, 5, PAGE_READWRITE, &dwOldProtect);
*(PBYTE)openAddress = 0xe9;
*(PDWORD)((PBYTE)openAddress + 1) = ((DWORD)MyZwOpenProcess - (DWORD)openAddress) - 5;
hand=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessId());
GetLastError();
if(hand)
{
printf("调用成功\n");
}
else
{
printf("调用失败!\n");
}
getchar();
return 0;
}
//========================ring3的===================================
//=====至于ring0 不敢说原创,undocument windows nt里的代码稍微改了下=========
#include <ntddk.h>
#define UCHAR unsigned char
#define PUCHAR unsigned char*
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName;
UNICODE_STRING ustrSymLinkName;
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;
typedef struct ServiceDescriptorEntry {
PULONG ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfServices;
PUCHAR ParamTableBase;
} ServiceDescriptorTableEntry , *PServiceDescriptorTableEntry;
NTSTATUS CreateDevice(IN PDRIVER_OBJECT);
NTSTATUS MinkAddServices();
void MinkUnloadDriver(IN PDRIVER_OBJECT);
//=====至于ring0 不敢说原创,undocument windows nt里的代码稍微改了下=========
//=====至于ring0 不敢说原创,undocument windows nt里的代码稍微改了下=========
#include "AddSSDT.h"
/*
copyright by Mink
blog:http://hi.baidu.com/mink_
*/
PULONG NewServiceTableBase;
PUCHAR NewParamTableBase;
ULONG NewNumberOfServices;
ULONG StartServiceid;
ULONG TheServiceid;
ULONG AddrOfNtWriteVirtualMemory=0;
extern PServiceDescriptorTableEntry KeServiceDescriptorTable;
__declspec(dllimport) __stdcall KeAddSystemServiceTable(ULONG, ULONG, ULONG, ULONG, ULONG);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegisteryPath)
{
NTSTATUS status=STATUS_SUCCESS;
status=CreateDevice(pDriverObject);
pDriverObject->DriverUnload=MinkUnloadDriver;
//pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=MinkControl;
MinkAddServices();
return status;
}
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDeviceObject;
PDEVICE_EXTENSION pDeviceExten;
UNICODE_STRING deviceName;
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&deviceName,L"\\Device\\MinkSSDT");
status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&deviceName,FILE_DEVICE_UNKNOWN,0,TRUE,&pDeviceObject);
if(!NT_SUCCESS(status))
{
goto err;
}
pDeviceObject->Flags|=DO_BUFFERED_IO;
pDeviceExten=(PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
pDeviceExten->pDevice=pDeviceObject;
pDeviceExten->ustrDeviceName=deviceName;
RtlInitUnicodeString(&symLinkName,L"\\??\\MinkDeSSDT");
pDeviceExten->ustrSymLinkName=symLinkName;
status=IoCreateSymbolicLink(&symLinkName,&deviceName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pDeviceObject);
goto err;
}
status=STATUS_SUCCESS;
err:
return status;
}
void MinkUnloadDriver(IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("开始卸载\n"));
pNextObj=pDriverObject->DeviceObject;
while(pNextObj!=NULL)
{
PDEVICE_EXTENSION pDevExt=(PDEVICE_EXTENSION)pNextObj->DeviceExtension;
UNICODE_STRING pLinkName=pDevExt->ustrSymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pNextObj=pNextObj->NextDevice;
IoDeleteDevice(pDevExt->pDevice);
}
KdPrint(("卸载完成\n"));
}
ULONG GetShadowTableAddress()
{
int i;
PUCHAR p;
ULONG temp;
p=(PUCHAR)KeAddSystemServiceTable;
for(i=0;i<4096;i++,p++)
{
__try
{
temp=*(PULONG)p;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("发生异常!!\n"));
goto err;
}
if(MmIsAddressValid((PVOID)temp))
{
if(!RtlCompareMemory((PVOID)temp,KeServiceDescriptorTable,16))
{
if((PVOID)temp==KeServiceDescriptorTable)
{
continue;
}
return temp;
}
}
}
err:
return 0;
}
NTSTATUS MinkAddServices()
{
NTSTATUS status;
PServiceDescriptorTableEntry KeServiceDescriptorTableShadow;
ULONG NtOpenProcessAddress;//NTOPENPROCESS 的函数地址
ULONG argCount=16;
UNICODE_STRING funName;
RtlInitUnicodeString(&funName,L"NtOpenProcess");
NtOpenProcessAddress=(ULONG)MmGetSystemRoutineAddress(&funName);//获取ntopenprocess的函数地址
KeServiceDescriptorTableShadow=(PServiceDescriptorTableEntry)GetShadowTableAddress();//获取shadow ssdt的函数地址
if(!KeServiceDescriptorTableShadow)
{
KdPrint(("没有找到shadow ssdt\n"));
status=STATUS_UNSUCCESSFUL;
goto err;
}
KdPrint(("ShadowTable address is:0x%x\n",KeServiceDescriptorTableShadow));
NewNumberOfServices=KeServiceDescriptorTable->NumberOfServices+1;
NewServiceTableBase=(PULONG)ExAllocatePool(PagedPool,NewNumberOfServices*sizeof(ULONG));
if(!NewServiceTableBase)
{
status=STATUS_INSUFFICIENT_RESOURCES;
goto err;
}
NewParamTableBase=(PUCHAR)ExAllocatePool(PagedPool,NewNumberOfServices);
if(!NewParamTableBase)
{
ExFreePool(NewServiceTableBase);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyMemory(NewServiceTableBase,KeServiceDescriptorTable->ServiceTableBase,KeServiceDescriptorTable->NumberOfServices*sizeof(ULONG));
RtlCopyMemory(NewParamTableBase,KeServiceDescriptorTable->ParamTableBase,KeServiceDescriptorTable->NumberOfServices);
RtlCopyMemory(NewServiceTableBase+KeServiceDescriptorTable->NumberOfServices,&NtOpenProcessAddress,sizeof(ULONG));
RtlCopyMemory(NewParamTableBase+KeServiceDescriptorTable->NumberOfServices,&argCount,sizeof(ULONG));
//更新ssdt跟shadow ssdt
KeServiceDescriptorTable->ServiceTableBase=NewServiceTableBase;
KeServiceDescriptorTable->ParamTableBase=NewParamTableBase;
KeServiceDescriptorTable->NumberOfServices=NewNumberOfServices;
//............................................................................................................................................
KeServiceDescriptorTableShadow->ServiceTableBase=NewServiceTableBase;
KeServiceDescriptorTableShadow->ParamTableBase=NewParamTableBase;
KeServiceDescriptorTableShadow->NumberOfServices=NewNumberOfServices;
status=STATUS_SUCCESS;
err:
return status;
}