首页
社区
课程
招聘
[旧帖] [交流]Shadow ssdt hook of NtUserCallOneParam function。 0.00雪花
发表于: 2010-11-13 11:02 2087

[旧帖] [交流]Shadow ssdt hook of NtUserCallOneParam function。 0.00雪花

2010-11-13 11:02
2087
代码修改自某位大牛的.不知道能不能搞个邀请码.
#include <ntddk.h>
#include <windef.h>
#include <stdio.h>
#include <string.h>


#define		HIDE_PROCESS_WIN32_DEV_NAME    L"\\Device\\HookShadowSSDT"
#define		HIDE_PROCESS_DEV_NAME	      L"\\DosDevices\\HookShadowSSDT"
#define		FILE_DEVICE_HIDE_PROCESS		 0x00008811
#define		IO_PROTECT          		(ULONG) CTL_CODE(FILE_DEVICE_HIDE_PROCESS, 0x808, METHOD_NEITHER, FILE_ANY_ACCESS)
VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject);
PVOID GetInfoTable(ULONG ATableType);
HANDLE GetCsrPid();
VOID InitCallNumber();


NTSTATUS PsLookupProcessByProcessId(IN ULONG ulProcId, OUT PEPROCESS * pEProcess);
                                               

///////////////声明Native API///////////////////////////////////////





typedef ULONG (*NTUSERCALLONEPARAM)
(
	 IN ULONG Param,
	 IN ULONG Routine
);

typedef struct _SYSTEM_HANDLE_INFORMATION 
{
	ULONG ProcessId;
	UCHAR ObjectTypeNumber;
	UCHAR Flags;
	USHORT Handle;
	PVOID Object;
	ACCESS_MASK GrantedAccess;
} _SYSTEM_HANDLE_INFORMATION, *P_SYSTEM_HANDLE_INFORMATION;

typedef struct _SYSTEM_HANDLE_INformATION_EX {
	ULONG NumberOfHandles;
	_SYSTEM_HANDLE_INFORMATION Information[1];
} _SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;

typedef struct ServiceDescriptorEntry {
	PVOID *ServiceTableBase;
	ULONG *ServiceCounterTableBase; //Used only in checked build
	ULONG NumberOfServices;
	PVOID *ParamTableBase;
} ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;

PServiceDescriptorTableEntry KeServiceDescriptorTableShadow;


NTSTATUS ZwQuerySystemInformation( 
		IN ULONG SystemInformationClass, 
		IN PVOID SystemInformation, 
		IN ULONG SystemInformationLength, 
		OUT PULONG ReturnLength);

NTSTATUS ZwDuplicateObject(
                 IN HANDLE                 SourceProcessHandle,
                 IN PHANDLE                 SourceHandle,
                 IN HANDLE                 TargetProcessHandle,
                 OUT PHANDLE               TargetHandle,
                 IN ACCESS_MASK             DesiredAccess OPTIONAL,
                 IN BOOLEAN                 InheritHandle,
                 IN ULONG                   Options );

NTSTATUS ZwQueryObject(
				IN HANDLE                ObjectHandle,
				IN ULONG                 ObjectInformationClass,
				OUT PVOID                ObjectInformation,
				IN ULONG                 ObjectInformationLength,
				OUT PULONG               ReturnLength OPTIONAL);


NTSTATUS PsLookupProcessByProcessId(
	   IN ULONG               ulProcId, 
	   OUT PEPROCESS *        pEProcess);


NTSTATUS KeAttachProcess(PEPROCESS pPeb);
NTSTATUS KeDetachProcess();

//------------------------------定义函数-------------------------

ULONG MyNtUserCallOneParam(
	   IN ULONG Param,
	   IN ULONG Routine);
  





__declspec(dllimport) _stdcall KeAddSystemServiceTable(PVOID, PVOID, PVOID, PVOID, PVOID);

////////////////////定义所用到的全局变量///////////////
__declspec(dllimport)  ServiceDescriptorTableEntry KeServiceDescriptorTable;

unsigned long OldCr0;
UNICODE_STRING DeviceNameString;
UNICODE_STRING LinkDeviceNameString;


//----------原函数-----------------

NTUSERCALLONEPARAM          g_OriginalNtUserCallOneParam;
//----------------------
PEPROCESS crsEProc;

CCHAR     outBuf[1024];                        //输入缓冲区大小


ULONG NtUserCallOneParam_callnumber = 0;   //服号
ULONG Counter = 0;
ULONG LastForegroundWindow;

unsigned int getAddressOfShadowTable()
{
    unsigned int i;
    unsigned char *p;
    unsigned int dwordatbyte;

    p = (unsigned char*) KeAddSystemServiceTable;

    for(i = 0; i < 4096; i++, p++)
    {
        __try
        {
            dwordatbyte = *(unsigned int*)p;
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            return 0;
        }

        if(MmIsAddressValid((PVOID)dwordatbyte))
        {
            if(memcmp((PVOID)dwordatbyte, &KeServiceDescriptorTable, 16) == 0)
            {
                if((PVOID)dwordatbyte == &KeServiceDescriptorTable)
                {
                    continue;
                }

                return dwordatbyte;
            }
        }
    }

    return 0;
}

ULONG getShadowTable()
{
    KeServiceDescriptorTableShadow = (PServiceDescriptorTableEntry) getAddressOfShadowTable();

    if(KeServiceDescriptorTableShadow == NULL)
    {
        DbgPrint("hooker.sys: Couldnt find shadowtable!");
        
        return FALSE;
    }
    else
    {
        DbgPrint("hooker.sys: Shadowtable has been found!");
        
        DbgPrint("hooker.sys: Shadowtable entries: %d", KeServiceDescriptorTableShadow[1].NumberOfServices);
        return TRUE;
    }
} 

//定义服务号(只对应XP系统.....)
VOID InitCallNumber()
{
	ULONG majorVersion, minorVersion;
	PsGetVersion( &majorVersion, &minorVersion, NULL, NULL );
    if ( majorVersion == 5 && minorVersion == 2 )
    {
	  DbgPrint("comint32: Running on Windows 2003");


	  NtUserCallOneParam_callnumber = 0x143;
	}
	else if ( majorVersion == 5 && minorVersion == 1 )
	{
	  DbgPrint("comint32: Running on Windows XP");


	  NtUserCallOneParam_callnumber = 0x143;
	}
	else if ( majorVersion == 5 && minorVersion == 0 )
	{
	  DbgPrint("comint32: Running on Windows 2000");


	  NtUserCallOneParam_callnumber = 0x143;
	}
}

PVOID GetInfoTable(ULONG ATableType)
{
  ULONG mSize = 0x4000;
  PVOID mPtr = NULL;
  NTSTATUS St;
  do
  {
     mPtr = ExAllocatePool(PagedPool, mSize);
     memset(mPtr, 0, mSize);
     if (mPtr)
     {
        St = ZwQuerySystemInformation(ATableType, mPtr, mSize, NULL);
     } else return NULL;
     if (St == STATUS_INFO_LENGTH_MISMATCH)
     {
        ExFreePool(mPtr);
        mSize = mSize * 2;
     }
  } while (St == STATUS_INFO_LENGTH_MISMATCH);
  if (St == STATUS_SUCCESS) return mPtr;
  ExFreePool(mPtr);
  return NULL;
}

HANDLE GetCsrPid()
{
	HANDLE Process, hObject;
	HANDLE CsrId = (HANDLE)0;
	OBJECT_ATTRIBUTES obj;
	CLIENT_ID cid;
	UCHAR Buff[0x100];
	POBJECT_NAME_INFORMATION ObjName = (PVOID)&Buff;
	PSYSTEM_HANDLE_INFORMATION_EX Handles;
	ULONG r;

	Handles = GetInfoTable(0x10); //SystemHandleInformation =  0x10

	if (!Handles) return CsrId;

	for (r = 0; r < Handles->NumberOfHandles; r++)
	{
		if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
		{
			InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

			cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
			cid.UniqueThread = 0;

			if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
			{
				if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information[r].Handle,NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS)))
				{
					if (NT_SUCCESS(ZwQueryObject(hObject, 1, ObjName, 0x100, NULL))) //ObjectNameInformation == 1
					{
						if (ObjName->Name.Buffer && !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
						{
						  CsrId = (HANDLE)Handles->Information[r].ProcessId;
						} 
					}

					ZwClose(hObject);
				}

				ZwClose(Process);
			}
		}
	}

	ExFreePool(Handles);
	return CsrId;
}

BOOLEAN Sleep(ULONG MillionSecond)
{
	NTSTATUS st;
	LARGE_INTEGER DelayTime;
	DelayTime = RtlConvertLongToLargeInteger(-10000*MillionSecond);
	st=KeDelayExecutionThread( KernelMode, FALSE, &DelayTime );
	return (NT_SUCCESS(st));
}

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
  NTSTATUS status;
  PDEVICE_OBJECT   deviceObject;
 
   RtlInitUnicodeString( &DeviceNameString,    HIDE_PROCESS_WIN32_DEV_NAME );
   RtlInitUnicodeString( &LinkDeviceNameString,HIDE_PROCESS_DEV_NAME );

   KdPrint(("DriverEntry Enter............................\n"));
  
   status = IoCreateDevice(
                DriverObject,
                0,                      
                &DeviceNameString,
                FILE_DEVICE_DISK_FILE_SYSTEM,
                FILE_DEVICE_SECURE_OPEN,
                FALSE,
                & deviceObject );

    if (!NT_SUCCESS( status )) 
    {

        KdPrint(( "DriverEntry: Error creating control device object, status=%08x\n", status ));
        return status;
    }

   status = IoCreateSymbolicLink(
                (PUNICODE_STRING) &LinkDeviceNameString,
                (PUNICODE_STRING) &DeviceNameString
                );

   if (!NT_SUCCESS(status))
    {
        IoDeleteDevice(deviceObject);
        return status;
    }
 
  //获得shadow的地址
  getShadowTable();
  //根据不同的系统获得不同的函数服务号
  InitCallNumber();



  DriverObject->DriverUnload=UnloadDriver;

  status = PsLookupProcessByProcessId((ULONG)GetCsrPid(), &crsEProc);
  if (!NT_SUCCESS( status ))
  {
	DbgPrint("PsLookupProcessByProcessId() error\n");
	return status;
  }
  KeAttachProcess(crsEProc);

  __try
  {
	  if ((KeServiceDescriptorTableShadow!=NULL)) 
	  {

      
	    g_OriginalNtUserCallOneParam = (NTUSERCALLONEPARAM)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserCallOneParam_callnumber];	
	  }
	  else
		KeServiceDescriptorTableShadow=NULL;
		

	  _asm
	  {
		CLI                    //dissable interrupt
		MOV    EAX, CR0        //move CR0 register into EAX
		AND EAX, NOT 10000H //disable WP bit 
		MOV    CR0, EAX        //write register back
	  }
	  if ((KeServiceDescriptorTableShadow!=NULL)   && (NtUserCallOneParam_callnumber!=0))
	  {
		
      
	    (NTUSERCALLONEPARAM)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserCallOneParam_callnumber] = MyNtUserCallOneParam;
	  }

	  _asm 
	  {
		MOV    EAX, CR0        //move CR0 register into EAX
		OR     EAX, 10000H        //enable WP bit     
		MOV    CR0, EAX        //write register back        
		STI                    //enable interrupt
	  }
  }
  __finally
  {
      KeDetachProcess(); 
  }

  KdPrint(("Hook ZwQuerySystemInformation'status is Succeessfully "));


  return status ;
}







VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING uniWin32NameString;
    UNICODE_STRING LinkNameString;
    PDEVICE_OBJECT deviceObject;
	NTSTATUS status;

	status = PsLookupProcessByProcessId((ULONG)GetCsrPid(), &crsEProc);
	if (!NT_SUCCESS( status ))
	{
	  DbgPrint("PsLookupProcessByProcessId() error\n");
	  return ;
	}
	KeAttachProcess(crsEProc);

//////////////////////UnHook ZwQuerySystemInformation/////////////////////////////////////////////////
 
	__try
	{
	  _asm
	 {
		CLI                    //dissable interrupt
		MOV    EAX, CR0        //move CR0 register into EAX
		AND EAX, NOT 10000H    //disable WP bit 
		MOV    CR0, EAX        //write register back
	  }

	  if ((KeServiceDescriptorTableShadow!=NULL)   && (NtUserCallOneParam_callnumber!=0)) 
	  {
		
		
		
		(NTUSERCALLONEPARAM)KeServiceDescriptorTableShadow[1].ServiceTableBase[NtUserCallOneParam_callnumber] = g_OriginalNtUserCallOneParam;
	  }

	  _asm 
	  {
		MOV    EAX, CR0        //move CR0 register into EAX
		OR     EAX, 10000H     //enable WP bit     
		MOV    CR0, EAX        //write register back        
		STI                    //enable interrupt
	  }
    }
	__finally
   {
	 KeDetachProcess();
	 Sleep(50);
   }
  
    deviceObject= DriverObject->DeviceObject;
    IoDeleteSymbolicLink(&LinkDeviceNameString);
    ASSERT(!deviceObject->AttachedDevice);
    if ( deviceObject != NULL )
    {
        IoDeleteDevice( deviceObject );
    }
}



//自定义函数
ULONG MyNtUserCallOneParam( IN ULONG Param,IN ULONG Routine)
{
NTSTATUS     retuen;
ULONG        PAR;
    retuen = g_OriginalNtUserCallOneParam(Param,Routine); 
    if( Routine == 0x34 ) 
	{
		retuen = 0;
	}
	return retuen;
}






函数作用:拦截关机/重启/注销。
XUETR里面的一个功能的实现。

[课程]Android-CTF解题方法汇总!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 7992
活跃值: (2566)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
不理解你需要实现什么..

ULONG MyNtUserCallOneParam( IN ULONG Param,IN ULONG Routine)
{
retrun 0;
}

代码有点问题的..
因为很多函数都需要调用这个函数.而直接返回XXX..会令很多软件错误的.
2010-11-13 11:24
0
雪    币: 129
活跃值: (333)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
xed
3
2010-11-13 18:22
0
雪    币: 473
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
看不懂,无语.
2010-11-29 15:16
0
游客
登录 | 注册 方可回帖
返回
//