分类: 内核探究 |

win32下内核与用户层的同步[转]

在驱动程序中常常需要与用户层程序进行同步,但是由于ring0与ring3之间的天然壁障,导致它们不能使用通常的方法。比如在用户层CreateEvent得到的句柄无法在内核之中使用。

查看更多...

Tags: 同步 内核 win32

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 11720

一段搜索EPROCESS来列进程的代码

//findprocess.c
//        by uty@uaty
//
#include <ntddk.h>

#define PDE_INVALID 2
#define PTE_INVALID 1
#define VALID        0

#define PEB_OFFSET                    0x1b0
#define OBJECT_HEADER_SIZE            0x18
#define OBJECT_TYPE_OFFSET            0x8
#define EPROCESS_NAME_OFFSET        0x174

查看更多...

Tags: EPROCESS 列进程 代码

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 9977

KeUserModeCallback用法详解[转]

ring0调用ring3早已不是什么新鲜事,除了APC,我们知道还有KeUserModeCallback.其原型如下:
NTSTATUS
KeUserModeCallback (
     IN ULONG ApiNumber,
     IN PVOID InputBuffer,
     IN ULONG InputLength,
     OUT PVOID *OutputBuffer,
     IN PULONG OutputLength
     );

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 12304

发IRP强制删除文件

学习了下,顺便加点注释。这个程序比较简单,主要练习了两个点:
(1)模拟发送IRP
(2)使用内核事件对象同步IRP的执行

强制删除文件的思路很简单,把SECTION_OBJECT_POINTERS结构的DataSectionObject和ImageSectionObject两个域清空即可删除正在运行的文件。如果不清空就不能删除运行中的文件。正在运行的文件的这两个域值不为0而文件系统正在根据这两个域决定该文件是否可以删除。如果文件系统检测这两个值为0,就理解为文件没有被使用,可以删除。接下去,就是直接发IRP。

测试时,在C盘目录下放一个test.exe并执行,然后加载驱动即可。
强制删除文件功能在ForceDeleteFile中实现,DriverEntry中只需要简单调用即可。具体实现如下

查看更多...

Tags: 发irp 强制删除 删除文件

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 11662

驱动和应用层的三种通信方式

原文:sislcb(http://bbs.pediy.com/showthread.php?p=446641),表示感谢!

驱动程序和客户应用程序经常需要进行数据交换,但我们知道驱动程序和客户应用程序可能不在同一个地址空间,因此操作系统必须解决两者之间的数据交换。
驱动层和应用层通信,主要是靠DeviceIoControl函数,下面是该函数的原型:
BOOL DeviceIoControl ( 
HANDLE hDevice, // 设备句柄 
DWORD dwIoControlCode, // IOCTL请求操作代码 
LPVOID lpInBuffer, // 输入缓冲区地址 
DWORD nInBufferSize, // 输入缓冲区大小 
LPVOID lpOutBuffer, // 输出缓冲区地址 
DWORD nOutBufferSize, // 输出缓冲区大小 
LPDWORD lpBytesReturned, // 存放返回字节数的指针 
LPOVERLAPPED lpOverlapped // 用于同步操作的Overlapped结构体指针 
);

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 14245

完整的分发函数

NTSTATUS ccpDispatch(PDEVICE_OBJECT device,PIRP irp)
{
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp);
NTSTATUS status;
ULONG i,j;
    // 首先要知道发送给了哪个设备。设备最多一共有CCP_MAX_COM_ID
// 个,是前面的代码保存好的,都在s_fltobj中
for(i=0;i<CCP_MAX_COM_ID;i++)
{
if(s_fltobj[i] == device)
{   
// 所有电源操作,全部直接放过
if(irpsp->MajorFunction == IRP_MJ_POWER)
{
// 直接发送,然后返回说已经被处理了
PoStartNextPowerIrp(irp);
IoSkipCurrentIrpStackLocation(irp);
return PoCallDriver(s_nextobj[i],irp);
}
// 此外我们只过滤写请求。写请求,获得缓冲区及其长度
// 然后打印
if(irpsp->MajorFunction == IRP_MJ_WRITE)
{
// 如果是写,先获得长度
ULONG len = irpsp->Parameters.Write.Length;
// 然后获得缓冲区
PUCHAR buf = NULL;
if(irp->MdlAddress != NULL)
buf =
(PUCHAR)MmGetSystemAddressForMdlSafe(
irp->MdlAddress,NormalPagePriority);
else
buf = (PUCHAR)irp->UserBuffer;
if(buf == NULL)
buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer;
                // 打印内容
for(j=0;j<len;++j)
{
DbgPrint("comcap: Send Data: %2x\r\n",
buf[j]);
}
}
            // 这些请求直接下发执行即可,我们并不禁止或者改变它
IoSkipCurrentIrpStackLocation(irp);
return IoCallDriver(s_nextobj[i],irp);
}
}
    // 如果根本就不在被绑定的设备中,那是有问题的,直接返回参数错误
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS; 
}

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 11200

LDR_MODULE结构

typedef struct _LDR_MODULE {


LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;


} LDR_MODULE, *PLDR_MODULE;

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 12582

PEB_LDR_DATA结构

typedef struct _PEB_LDR_DATA {



ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;



} PEB_LDR_DATA, *PPEB_LDR_DATA;

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 12633

TEB结构

typedef struct _TEB {


NT_TIB Tib;
PVOID EnvironmentPointer;
CLIENT_ID Cid;
PVOID ActiveRpcInfo;
PVOID ThreadLocalStoragePointer;
PPEB Peb;
ULONG LastErrorValue;
ULONG CountOfOwnedCriticalSections;
PVOID CsrClientThread;
PVOID Win32ThreadInfo;
ULONG Win32ClientInfo[0x1F];
PVOID WOW32Reserved;
ULONG CurrentLocale;
ULONG FpSoftwareStatusRegister;
PVOID SystemReserved1[0x36];
PVOID Spare1;
ULONG ExceptionCode;
ULONG SpareBytes1[0x28];
PVOID SystemReserved2[0xA];
ULONG GdiRgn;
ULONG GdiPen;
ULONG GdiBrush;
CLIENT_ID RealClientId;
PVOID GdiCachedProcessHandle;
ULONG GdiClientPID;
ULONG GdiClientTID;
PVOID GdiThreadLocaleInfo;
PVOID UserReserved[5];
PVOID GlDispatchTable[0x118];
ULONG GlReserved1[0x1A];
PVOID GlReserved2;
PVOID GlSectionInfo;
PVOID GlSection;
PVOID GlTable;
PVOID GlCurrentRC;
PVOID GlContext;
NTSTATUS LastStatusValue;
UNICODE_STRING StaticUnicodeString;
WCHAR StaticUnicodeBuffer[0x105];
PVOID DeallocationStack;
PVOID TlsSlots[0x40];
LIST_ENTRY TlsLinks;
PVOID Vdm;
PVOID ReservedForNtRpc;
PVOID DbgSsReserved[0x2];
ULONG HardErrorDisabled;
PVOID Instrumentation[0x10];
PVOID WinSockData;
ULONG GdiBatchCount;
ULONG Spare2;
ULONG Spare3;
ULONG Spare4;
PVOID ReservedForOle;
ULONG WaitingOnLoaderLock;
PVOID StackCommit;
PVOID StackCommitMax;
PVOID StackReserved;


} TEB, *PTEB;

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 12719

peb结构

虽然之前的某篇文章里有写过peb的结构,但我觉得还是有必要把peb的结构清晰的列出来。这样方便我以后用到这个结构的时候查找,也方便其他人搜索。

typedef struct _PEB {


BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;//
Pointer to RTL_USER_PROCESS_PARAMETERS
structure
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PPEBLOCKROUTINE FastPebLockRoutine;
PPEBLOCKROUTINE FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PPVOID KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PPEB_FREE_BLOCK FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PPVOID ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PPVOID *ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;


} PEB, *PPEB;

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 13826

HOOK_SYSCALL 和 UNHOOK_SYSCALL宏

HOOK_SYSCALL 和 UNHOOK_SYSCALL宏采用被勾住的Zw*函数的地址,获取器索引号,并自动讲SSDT中该索引的相应地址与_Hook函数的地址进行交换。

#define HOOK_SYSCALL(_Function,_Hook,_Orig)\
_Orig=(PVOID)InterlockedExchange((PLONG)\
&MappedSystemCallTable[SYSCALL_INDEX(_Function)],(LONG)_Hook)

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 11970

SYSCALL_INDEX宏

SYSCALL_INDEX宏采用Zw*函数地址并返回它在SSDT中相应的索引号。

#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 10158

SYSTEMSERVICE()宏

SYSTEMSERVICE()宏采用ntoskrnl.exe导出的Zw*函数的地址,并返回相应的Nt*函数在SSDT中的地址。

#define SYSTEMSERVICE(_func)\
KeSerViceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_func+1)]

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 9648

IO_STACK_LOCATION 结构

struct _IO_STACK_LOCATION (sizeof=36)
00 byte MajorFunction
01 byte MinorFunction
02 byte Flags
03 byte Control

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 9664

IRP结构详解

IRP结构


图5-1显示了IRP的数据结构,阴影部分代表不透明域。下面是该结构中重要域的简要描述。


MdlAddress(PMDL)域指向一个内存描述符表(MDL),该表描述了一个
与该请求关联的用户模式缓冲区。如果顶级设备对象的Flags域为DO_DIRECT_IO,则I/O管理器为IRP_MJ_READ或
IRP_MJ_WRITE请求创建这个MDL。如果一个IRP_MJ_DEVICE_CONTROL请求的控制代码指定METHOD_IN_DIRECT
或METHOD_OUT_DIRECT操作方式,则I/O管理器为该请求使用的输出缓冲区创建一个MDL。MDL本身用于描述用户模式虚拟缓冲区,但它同
时也含有该缓冲区锁定内存页的物理地址。为了访问用户模式缓冲区,驱动程序必须做一点额外工作。


查看更多精彩图片


图5-1. I/O请求包数据结构


查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 14338

EPROCESS结构

EPROCESS的结构定义
typedef struct _EPROCESS {
KPROCESS Pcb;
NTSTATUS ExitStatus;
KEVENT LockEvent;

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 12117

修改内核对象隐藏进程

修改内核对象隐藏进程
Windows NT/2000/XP/2003操作系统具有描述了进程的可执行对象。Taskmgr.exe列出机器上运行的进程。 ZwQuerySystemInformation 也使用这 些 对象列出运行的进程,修改这 些 对象,可以隐藏进程。
通过遍历 在每 个进程的EPROCESS结构中引用的一个双向链表,EPROCESS结构包含一个具有指针成员FLINK和BLINK的lLIST_ENTRY结构。这两个指针分别指向当前进程描述符的前方和后方进程,通过修改这 两个指针可以隐藏指定进程。
(EPROCESS结构请看http://www.zeroplace.cn/article.asp?id=401)

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 8273

内核级HOOK的几种实现与应用

实现内核级 HOOK 对于拦截、分析、跟踪系统内核起着致关重要的作用。实现的方法不同意味着应用侧重点的不同。如想要拦截 NATIVE API 那么可能常用的就是 HOOK SERVICE TABLE 的方法。如果要分析一些系统调用,那么可能想到用 HOOK INT 2E 中断来实现。如果想要拦截或跟踪其他内核 DRIVER 的调用,那么就要用到HOOK PE 的方法来实现。这里我们更注重的是实现,原理方面已有不少高手在网上发表过文章。大家可以结合起来读。下面以我写的几个实例程序来讲解一下各种方法的实现。错误之处还望各位指正。


1、HOOK SERVICE TABLE 方法:
  这种方法对于拦截 NATIVE API 来说用的比较多。原理就是通过替换系统导

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 9732

Rootkit技术之内核钩子原理[4]

四、内核函数系列 
经过上面的介绍,我们已经了解了系统调用表有关知识,也已知道如何拦截系统调用表中的函数,下面,我们再来了解一下我们要钩取的函数:目标函数。这方面,如果我们不仅了解系统调用表中有哪些函数,还知道这些函数的工作机制就最好了。但实际上,ntdll.dll 中的导出函数有好几百个,别说一个一个的探究,就是把它们都列出来,看着看着头都大了。幸运的是,我们不必了解每个函数,只要了解其所在的系列就行了。为什么这么说?因为微软已经按照函数的功能对Ntdll.dll的导出函数进行了分组,并冠以意义明确的前缀,所以根据函数系列的前缀就能明白它们的大体功能了。下面对这些函数系列进行简单的介绍:

1.KiEtw系列:本系列内核函数用于系统内核,这些函数只能从内核的内部进行调用,常用的有:KiUserCallbackDispatcher、KiRaiseUserExceptionDispatcher、KiUserApcDispatcher、KiUserExceptionDispatcher等。

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 9063

Rootkit技术之内核钩子原理[3]

三、定义钩子函数 
内核钩子主要有三部分组成:要钩取的函数(在下文中称为目标函数)、替代要钩取的函数的函数(在下文中成为钩子函数)和系统调用表。前面部分介绍了系统调用表的问题,下面开始介绍钩子函数。一般说来,当定义自己的钩子函数时,可以先到DDK 的头文件中找到所想要的函数的原型,然后,稍加修改就能把目标函数变成钩子函数了。

例如,ZwMapViewOfSection 是一个内核函数,允许应用程序把从动态链接库导出的函数映射至内存。如果我们想要钩住这个内核函数,那么可以到ntddk.h头文件中查看其函数原型,如下所示:

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 10093