⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpip_patcher.c

📁 Last change: 2008-02-03 This is the source code of KCeasy。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * This file is part of KCeasy (http://www.kceasy.com)
 * Copyright (C) 2002-2005 Markus Kern <mkern@kceasy.com>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
/*****************************************************************************/

#define DRIVER_CODE
#include "tcpip_patcher.h"
#include <wdmsec.h>    /* IoCreateDeviceSecure */
#include <ntstrsafe.h> /* RtlStringCbPrintfExA */

/*****************************************************************************/
/* Debugging/logging stuff */

typedef struct
{
	LPSTR Buffer;
	size_t Remaining;
} LOG_DATA;

#define LOG_0(fmt) \
	RtlStringCbPrintfExA (pLogData->Buffer, pLogData->Remaining, \
	                      &pLogData->Buffer, &pLogData->Remaining, \
	                      0, fmt);

#define LOG_1(fmt,a1) \
	RtlStringCbPrintfExA (pLogData->Buffer, pLogData->Remaining, \
	                      &pLogData->Buffer, &pLogData->Remaining, \
	                      0, fmt, a1);

#define LOG_2(fmt,a1,a2) \
	RtlStringCbPrintfExA (pLogData->Buffer, pLogData->Remaining, \
	                      &pLogData->Buffer, &pLogData->Remaining, \
	                      0, fmt, a1, a2);

#if DBG
# define PATCHER_DBG(_x_)         DbgPrint("TCPIP_PATCHER: "); DbgPrint _x_;
# define PATCHER_LOG_0(fmt)       PATCHER_DBG((fmt));       LOG_0(fmt);
# define PATCHER_LOG_1(fmt,a1)    PATCHER_DBG((fmt,a1));    LOG_1(fmt,a1);
# define PATCHER_LOG_2(fmt,a1,a2) PATCHER_DBG((fmt,a1,a2)); LOG_2(fmt,a1,a2);
#else
# define PATCHER_DBG(_x_)
# define PATCHER_LOG_0(fmt)       LOG_0(fmt);
# define PATCHER_LOG_1(fmt,a1)    LOG_1(fmt,a1);
# define PATCHER_LOG_2(fmt,a1,a2) LOG_2(fmt,a1,a2);
#endif
/*****************************************************************************/
/* PE file structs from around the web */

typedef UCHAR BYTE;
typedef USHORT WORD;
typedef ULONG DWORD;
typedef ULONG BOOL; 

typedef struct _IMAGE_DOS_HEADER
{
    WORD e_magic;
    WORD e_cblp;
    WORD e_cp;
    WORD e_crlc;
    WORD e_cparhdr;
    WORD e_minalloc;
    WORD e_maxalloc;
    WORD e_ss;
    WORD e_sp;
    WORD e_csum;
    WORD e_ip;
    WORD e_cs;
    WORD e_lfarlc;
    WORD e_ovno;
    WORD e_res[4];
    WORD e_oemid;
    WORD e_oeminfo;
    WORD e_res2[10];
    LONG e_lfanew;
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

typedef struct _IMAGE_FILE_HEADER
{
    WORD    Machine;         
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;           
    DWORD   NumberOfSymbols; 
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16

typedef struct _IMAGE_DATA_DIRECTORY
{
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
    
typedef struct _IMAGE_OPTIONAL_HEADER
{
    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;
    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef struct _IMAGE_NT_HEADERS
{
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; 

#define IMAGE_SIZEOF_SHORT_NAME 8

typedef struct _IMAGE_SECTION_HEADER
{
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
    union
	{
        DWORD   PhysicalAddress;
		DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

/*****************************************************************************/
/* The kernel oracle */

typedef enum _SYSTEM_INFORMATION_CLASS
{
	SystemModuleInformation = 11
} SYSTEM_INFORMATION_CLASS;

typedef struct _SYSTEM_MODULE_INFORMATION
{
	ULONG Reserved[2];
	PVOID Base;
	ULONG Size;
	ULONG Flags;
	USHORT Index;
	USHORT Unknown;
	USHORT LoadCount;
	USHORT ModuleNameOffset;
	CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;

NTSYSAPI NTSTATUS NTAPI
ZwQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
                          OUT PVOID SystemInformation,
                          IN ULONG SystemInformationLength,
                          OUT PULONG ReturnLength OPTIONAL);

/*****************************************************************************/
/* Various internal helpers */

/* Returns base address of module (e.g. "tcpip.sys") */
PVOID FindModuleBase (const char *module, LOG_DATA *pLogData);

/* Returns RVA and size of code and data sections */
BOOL FindPESections (PVOID ImageBase,
                     ULONG *CodeRVA, ULONG *CodeSize,
                     ULONG *DataRVA, ULONG *DataSize,
                     LOG_DATA *pLogData);

/* Returns address of DWORD containing half-open connections limit and
 * optionally address of current half-open connections */
ULONG* FindLimitPosition (PVOID CodeStart, ULONG CodeSize,
                          ULONG **CurrentHalfOpenAddress, LOG_DATA *pLogData);

/* Find needle with mask */
PVOID FindMemWithMask (const PVOID Start, ULONG Size, const PCHAR NeedleData,
                       const PCHAR NeedleMask, ULONG NeedleSize);

/*****************************************************************************/
/* Driver control functions */

NTSTATUS DriverEntry (IN PDRIVER_OBJECT  DriverObject,
                      IN PUNICODE_STRING registryPath);

VOID PatcherUnload (IN PDRIVER_OBJECT DriverObject);

NTSTATUS PatcherDispatch (IN PDEVICE_OBJECT DeviceObject, 
                          IN PIRP Irp);

NTSTATUS PatcherDeviceControl (IN PDEVICE_OBJECT pDeviceObject,
                               IN ULONG IoControlCode, 
                               IN PVOID InputBuffer, 
                               IN ULONG InputBufferLength, 
                               OUT PVOID OutputBuffer, 
                               IN ULONG OutputBufferLength, 
                               OUT PIO_STATUS_BLOCK IoStatus);

/*****************************************************************************/
/* Driver loading/unloading/control */

NTSTATUS DriverEntry (IN PDRIVER_OBJECT  DriverObject,
                      IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS            status;
    UNICODE_STRING      unicodeDeviceName;   
    UNICODE_STRING      unicodeDosDeviceName;  
    PDEVICE_OBJECT      deviceObject;

    UNREFERENCED_PARAMETER (RegistryPath);

    PATCHER_DBG(("DriverEntry Enter\n"));  
   
    RtlInitUnicodeString (&unicodeDeviceName, PATCHER_DEVICE_PATH);
    RtlInitUnicodeString (&unicodeDosDeviceName, PATCHER_DOS_DEVICE_PATH);

	/* create device which only SYSTEM and Administrators can access */
	status = IoCreateDeviceSecure (DriverObject,
                                   0,
	                               &unicodeDeviceName,
	                               FILE_DEVICE_PATCHER,
	                               FILE_DEVICE_SECURE_OPEN,
	                               FALSE,
	                               &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
	                               &PATCHER_DEVICE_GUID,
	                               &deviceObject);

    if (!NT_SUCCESS(status))
    {
	    PATCHER_DBG(("IoCreateDeviceSecure() failed\n"));
        return status;
    }
  
    status = IoCreateSymbolicLink (&unicodeDosDeviceName, &unicodeDeviceName);

    if (!NT_SUCCESS(status))
    {
	    PATCHER_DBG(("IoCreateSymbolicLink() failed\n"));
        IoDeleteDevice(deviceObject);
        return status;
    }
  
    DriverObject->MajorFunction[IRP_MJ_CREATE]          =
	DriverObject->MajorFunction[IRP_MJ_CLEANUP]         =
    DriverObject->MajorFunction[IRP_MJ_CLOSE]           =
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = PatcherDispatch;
	
	DriverObject->DriverUnload = PatcherUnload;


    PATCHER_DBG(("DriverEntry Exit\n"));
    return STATUS_SUCCESS;
}

VOID PatcherUnload (IN PDRIVER_OBJECT DriverObject)
{
    PDEVICE_OBJECT    deviceObject = DriverObject->DeviceObject;
    UNICODE_STRING    uniWin32NameString;

    PATCHER_DBG(("PatcherUnload Enter\n"));

    RtlInitUnicodeString (&uniWin32NameString,PATCHER_DOS_DEVICE_PATH);
    IoDeleteSymbolicLink (&uniWin32NameString);
    IoDeleteDevice (deviceObject);
 
    PATCHER_DBG(("PatcherUnload Exit\n"));
    return;
}

NTSTATUS PatcherDispatch (IN PDEVICE_OBJECT DeviceObject, 
                          IN PIRP Irp)
{
    PIO_STACK_LOCATION      irpStack;
	NTSTATUS				status = STATUS_SUCCESS;
    PVOID                   InputBuffer;
    PVOID                   OutputBuffer;
    ULONG                   InputBufferLength;
    ULONG                   OutputBufferLength;
    ULONG                   IoControlCode;

    irpStack = IoGetCurrentIrpStackLocation (Irp);   

    InputBuffer        = Irp->AssociatedIrp.SystemBuffer;
    InputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    OutputBuffer       = Irp->AssociatedIrp.SystemBuffer;
    OutputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    IoControlCode      = irpStack->Parameters.DeviceIoControl.IoControlCode;

    switch (irpStack->MajorFunction) {
    case IRP_MJ_CREATE:
		PATCHER_DBG(("IRP_MJ_CREATE\n"));
	    Irp->IoStatus.Information = 0;
        break;

    case IRP_MJ_CLEANUP:
		PATCHER_DBG(("IRP_MJ_CLEANUP\n"));
        Irp->IoStatus.Information = 0;
		break;

    case IRP_MJ_CLOSE:
		PATCHER_DBG(("IRP_MJ_CLOSE\n"));
        Irp->IoStatus.Information = 0;
        break;

    case IRP_MJ_DEVICE_CONTROL:
		PATCHER_DBG(("IRP_MJ_DEVICE_CONTROL\n"));
       
		__try
		{
			status = PatcherDeviceControl (DeviceObject, IoControlCode,
				                           InputBuffer, InputBufferLength, 
				                           OutputBuffer, OutputBufferLength,
			                               &Irp->IoStatus);
		}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{
			PATCHER_DBG (("Caught exception in PatcherDeviceControl\n"));
			status = STATUS_DRIVER_INTERNAL_ERROR;
	        Irp->IoStatus.Information = 0;
		}

        break;

	default:
		PATCHER_DBG(("Invalid PatcherDispatch parameter\n"));
        status = STATUS_INVALID_PARAMETER;
        break;
    }

    Irp->IoStatus.Status = status;
	IoCompleteRequest (Irp, IO_NO_INCREMENT);

    return status;   
}

NTSTATUS PatcherDeviceControl (IN PDEVICE_OBJECT pDeviceObject,
                               IN ULONG IoControlCode, 
                               IN PVOID InputBuffer, 
                               IN ULONG InputBufferLength, 
                               OUT PVOID OutputBuffer, 
                               IN ULONG OutputBufferLength, 
                               OUT PIO_STATUS_BLOCK IoStatus) 
{
	PATCHER_LIMIT_DATA *LimitData;
	LOG_DATA LogData, *pLogData = &LogData;
	ULONG RequestedLimit;

	IoStatus->Status = STATUS_SUCCESS;
    IoStatus->Information = 0;

    switch (IoControlCode) 
	{
	case IOCTL_PATCHER_GET_LIMIT:
		/* supplied buffer must be big enough to contain our response */
		if ((OutputBufferLength < sizeof (PATCHER_LIMIT_DATA)) ||
		    (OutputBuffer == NULL))
		{
			PATCHER_DBG(("Wrong output buffer size for IOCTL_PATCHER_GET_LIMIT\n"));
			IoStatus->Status = STATUS_INVALID_BUFFER_SIZE;
			break;	
		}

		/* Prepare our result data */
		LimitData = (PATCHER_LIMIT_DATA*) OutputBuffer;
		LimitData->HalfOpenLimit = 0;
		LimitData->CurrentHalfOpen = 0;
		LimitData->ErrorCode = PATCHER_ERROR_FAILURE;

		LogData.Buffer = LimitData->LogString;
		LogData.Remaining = OutputBufferLength - sizeof(PATCHER_LIMIT_DATA);
		if (LogData.Remaining > 0)
			LogData.Buffer[0] = 0;
		
		__try
		{
			PVOID TcpIpBase, DataStart, DataEnd;
			ULONG CodeSecRVA, CodeSecSize;
			ULONG DataSecRVA, DataSecSize;
			ULONG *LimitAddress, *CurrentHalfOpenAddress;

			TcpIpBase = FindModuleBase ("tcpip.sys", &LogData);
			if (TcpIpBase != NULL)
			{
				if (FindPESections (TcpIpBase, &CodeSecRVA, &CodeSecSize,
				                    &DataSecRVA, &DataSecSize, &LogData))
				{
					LimitAddress = FindLimitPosition (((PCHAR)TcpIpBase) + CodeSecRVA,
					                                  CodeSecSize,												  
					                                  &CurrentHalfOpenAddress,
					                                  &LogData);

					if (LimitAddress != NULL && CurrentHalfOpenAddress != NULL)
					{
						/* addresses must be in data section */
						DataStart = ((PCHAR)TcpIpBase) + DataSecRVA;
						DataEnd = ((PCHAR)DataStart) + DataSecSize;

						if ((PVOID)LimitAddress > DataStart &&
						    (PVOID)LimitAddress < DataEnd &&
						    (PVOID)CurrentHalfOpenAddress > DataStart &&
						    (PVOID)CurrentHalfOpenAddress < DataEnd)
						{
							/* return requested data */
							LimitData->HalfOpenLimit = *LimitAddress;
							LimitData->CurrentHalfOpen = *CurrentHalfOpenAddress;
							LimitData->ErrorCode = PATCHER_ERROR_SUCCESS; 
							PATCHER_LOG_0("Successfully retrieved current half open connections and their limit\n");
						}
						else
						{
							PATCHER_LOG_0("Address of limit or current half open not in data section\n");
						}
					}
				}
			}
		}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{
			LimitData->ErrorCode = PATCHER_ERROR_FAILURE; 
			PATCHER_LOG_0("Caught exception during IOCTL_PATCHER_GET_LIMIT\n");
		}

		/* Make the IOManager copy everything */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -