Win64 驱动内核编程-28.枚举消息钩子「建议收藏」

Win64 驱动内核编程-28.枚举消息钩子「建议收藏」枚举消息钩子 简单粘贴点百度的解释,科普下消息钩子:钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。 钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

枚举消息钩子

 简单粘贴点百度的解释,科普下消息钩子:

钩子是WINDOWS中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目标窗口程序之前处理它们。 钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。

 

钩子的类型:

1) 键盘钩子和低级键盘钩子可以监视各种键盘消息。

2) 鼠标钩子和低级鼠标钩子可以监视各种鼠标消息。

3) 外壳钩子可以监视各种 Shell 事件消息。比如启动和关闭应用程序。

4) 日志钩子可以记录从系统消息队列中取出的各种事件消息。

5) 窗口过程钩子监视所有从系统消息队列发往目标窗口的消息。

此外,还有一些特定事件的钩子提供给我们使用,不一一列举。

 

常用的 Hook 类型:

1WH_CALLWNDPROC 和 WH_CALLWNDPROCRET Hooks

WH_CALLWNDPROC 和 WH_CALLWNDPROCRET Hooks 使你可以监视发送到窗口过程的消息。系统在消息发送到接

收窗口过程之前调用 WH_CALLWNDPROC Hook 子程,并且在窗口过程处理完消息之后调用 WH_CALLWNDPRO

CRET Hook 子程。WH_CALLWNDPROCRET Hook 传递指针到 CWPRETSTRUCT 结构,再传递到 Hook 子程。

CWPRETSTRUCT 结构包含了来自处理消息的窗口过程的返回值,同样也包括了与这个消息关联的消息参数。

2WH_CBT Hook

在以下事件之前,系统都会调用 WH_CBT Hook 子程,这些事件包括:

1. 激活,建立,销毁,最小化,最大化,移动,改变尺寸等窗口事件;

2. 完成系统指令;

3. 来自系统消息队列中的移动鼠标,键盘事件;

4. 设置输入焦点事件;

5. 同步系统消息队列事件。

Hook 子程的返回值确定系统是否允许或者防止这些操作中的一个。

3WH_DEBUG Hook

在系统调用系统中与其他 Hook 关联的 Hook 子程之前,系统会调用 WH_DEBUG Hook 子程。你可以使用这个

Hook 来决定是否允许系统调用与其他 Hook 关联的 Hook 子程。

4WH_FOREGROUNDIDLE Hook

当应用程序的前台线程处于空闲状态时,可以使用 WH_FOREGROUNDIDLE Hook 执行低优先级的任务。当应用

程序的前台线程大概要变成空闲状态时,系统就会调用 WH_FOREGROUNDIDLE Hook 子程。

5WH_GETMESSAGE Hook

应用程序使用 WH_GETMESSAGE Hook 来监视从 GetMessage 或 PeekMessage 函数返回的消息。你可以使用

WH_GETMESSAGE Hook 去监视鼠标和键盘输入,以及其他发送到消息队列中的消息。

6、WH_JOURNALPLAYBACK Hook

    WH_JOURNALPLAYBACK Hook 使应用程序可以插入消息到系统消息队列。可以使用这个 Hook 回放通过使用WH_JOURNALRECORD Hook 记录下来的连续的鼠标和键盘事件。只要 WH_JOURNALPLAYBACK Hook 已经安装,正常的鼠标和键盘事件就是无效的。WH_JOURNALPLAYBACK Hook 是全局 Hook,它不能象线程特定 Hook 一样

使用。WH_JOURNALPLAYBACK Hook 返回超时值,这个值告诉系统在处理来自回放 Hook 当前消息之前需要等待多长时间(毫秒)。这就使 Hook 可以控制实时事件的回放。WH_JOURNALPLAYBACK 是 system-wide localhooks,它们不会被注射到任何进程地址空间。(估计按键精灵是用这个 hook 做的)

7WH_JOURNALRECORD Hook

WH_JOURNALRECORD Hook 用来监视和记录输入事件。典型的,可以使用这个 Hook 记录连续的鼠标和键盘事件,然后通过使用 WH_JOURNALPLAYBACK Hook 来回放。WH_JOURNALRECORD Hook 是全局 Hook,它不能象线程特定 Hook 一样使用。WH_JOURNALRECORD 是 system-wide local hooks,它们不会被注射到任何进程地址空间。

 

枚举内核消息钩子  

    枚举消息钩子的总体思路。首先获得名为 gSharedInfo的全局变量的地址(此变量在 user32.dll 里被导出),它的值其实是一个内核结构体 win32k!tagsharedinfo 的地址:

Win64 驱动内核编程-28.枚举消息钩子「建议收藏」

接下来 tagSERVERINFO.cHandleEntries 的值,这个值记录了当前消息钩子的数目(记为 count):

Win64 驱动内核编程-28.枚举消息钩子「建议收藏」

    然后读取 gSharedInfo+8 的值,获得 aheList 的值(记为 phe),此值为 首个

HANDLEENTRY 结构体的地址:

Win64 驱动内核编程-28.枚举消息钩子「建议收藏」

    接下来,从 phe 首地址开始,获得【count-1】个的 HANDLEENTRY 结构体的指针,HANDLEENTRY.phead 记录的值指向一个 HEAD 结构体,HEAD 结构体才记录了

每个消息钩子的具体信息。当然也不是每个 HANDLEENTRY 都是消息钩子,只有当

HANDLEENTRY.bType 为 时才是消息钩子。

 

然后就是把资料上的那个写的比较精简的函数拿出来,枚举消息钩子:

注意这个函数实在R3里面:

void EnumMsgHook()
{
int i=0;
UINT64 pgSharedInfo=0;
pgSharedInfo = (UINT64)GetProcAddress(GetModuleHandleA("user32.dll"), "gSharedInfo");
UINT64 phe = GetQWORD(pgSharedInfo+8);
UINT64 count = GetQWORD(GetQWORD(pgSharedInfo)+8);
HANDLEENTRY heStruct={0};
HOOK_INFO Hook={0};
for(i=0;i<count;i++)
{
memcpy(&heStruct,(PVOID)(phe + i*sizeof(HANDLEENTRY)),sizeof(HANDLEENTRY));
if(heStruct.bType==5)
{
RKM(heStruct.phead,&Hook,sizeof(HOOK_INFO));
printf("hHandle: 0x%llx\n",Hook.hHandle);
printf("iHookFlags: %s\n",GetHookFlagString(Hook.iHookFlags));
printf("iHookType: %s\n",GetHookType(Hook.iHookType));
printf("OffPfn: 0x%llx\n",Hook.OffPfn);
printf("ETHREAD: 0x%llx\n",GetQWORD((UINT64)(Hook.Win32Thread)));
printf("ProcessName: %s\n\n",GetPNbyET(GetQWORD((UINT64)(Hook.Win32Thread))));
}
}
}

 接下来是驱动部分代码,感觉里面的那些读写内存什么的写的比较归整(来源于资料,胡文亮),这里也整理下方便以后使用:

先是内存拷贝:

BOOLEAN VxkCopyMemory( PVOID pDestination, PVOID pSourceAddress, SIZE_T SizeOfCopy )
{
    PMDL pMdl = NULL;
    PVOID pSafeAddress = NULL;
    pMdl = IoAllocateMdl( pSourceAddress, (ULONG)SizeOfCopy, FALSE, FALSE, NULL );
    if( !pMdl ) return FALSE;
    __try
    {
        MmProbeAndLockPages( pMdl, KernelMode, IoReadAccess );
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        IoFreeMdl( pMdl );
        return FALSE;
    }
    pSafeAddress = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority );
    if( !pSafeAddress ) return FALSE;
    RtlCopyMemory( pDestination, pSafeAddress, SizeOfCopy );
    MmUnlockPages( pMdl );
    IoFreeMdl( pMdl );
    return TRUE;
}
ULONG64 rwkm_adr=0, rwkm_len=0;

然后是内存读写—R3

DWORD CTL_CODE_GEN(DWORD lngFunction)
{
return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED;
}
 
BOOL IoControl(HANDLE hDrvHandle, DWORD dwIoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize)
{
DWORD lDrvRetSize;
return DeviceIoControl(hDrvHandle, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, &lDrvRetSize, 0);
}
 
void RKM(UINT64 Address, PVOID Buffer, SIZE_T Length)
{
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x809), &Address, 8, NULL, 0);	//address
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x80A), &Length, 8, NULL, 0);	//length
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x804), NULL, 0, Buffer, Length);	//get buffer
}
 
void WKM(UINT64 Address, PVOID Buffer, SIZE_T Length)
{
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x809), &Address, 8, NULL, 0);	//address
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x80A), &Length, 8, NULL, 0);	//length
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x805), Buffer, Length, NULL, 0);	//set buffer
}
 
UINT64 GetQWORD(UINT64 address)
{
UINT64 y = 0;
RKM(address, &y, 8);
return y;
}
 
UINT32 GetDWORD(UINT64 address)
{
UINT32 y = 0;
RKM(address, &y, 4);
return y;
}
 
PUCHAR GetPNbyET(UINT64 ethread)
{
PUCHAR y = (PUCHAR)malloc(16);
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x7FF), ðread, 8, y, 16);
return y;
}
 

然后是内存读写—R0

#define IOCTL_READ_KRNL_MM	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)	//read kernel
#define IOCTL_MODIFY_KN_MM	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)	//write kernel
#define IOCTL_SET_RWKM_ADR	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED, FILE_ANY_ACCESS)	//set address
#define IOCTL_SET_RWKM_LEN	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80A, METHOD_BUFFERED, FILE_ANY_ACCESS)	//set length
#define IOCTL_GET_PN_BY_ET	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x7FF, METHOD_BUFFERED, FILE_ANY_ACCESS)	//set length
 
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode)
{
case IOCTL_SET_RWKM_ADR:
{
rwkm_adr=*(UINT64 *)pIoBuffer;
DbgPrint("rwkm_adr: %lld\n",rwkm_adr);
status = STATUS_SUCCESS;
break;
}
case IOCTL_SET_RWKM_LEN:
{
rwkm_len=*(UINT64 *)pIoBuffer;
DbgPrint("rwkm_len: %lld\n",rwkm_len);
status = STATUS_SUCCESS;
break;
}
case IOCTL_READ_KRNL_MM:
{
VxkCopyMemory(pIoBuffer,(PVOID)rwkm_adr,(SIZE_T)rwkm_len);
status = STATUS_SUCCESS;
break;
}
case IOCTL_MODIFY_KN_MM:
{
VxkCopyMemory((PVOID)rwkm_adr,pIoBuffer,(SIZE_T)rwkm_len);
status = STATUS_SUCCESS;
break;
}
case IOCTL_GET_PN_BY_ET:
{
PETHREAD et;
PEPROCESS ep;
PUCHAR pn;
et=*(PETHREAD *)pIoBuffer;
ep=IoThreadToProcess(et);
pn=PsGetProcessImageFileName(ep);
memcpy(pIoBuffer,pn,16);
status = STATUS_SUCCESS;
break;
}
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}

执行结果:

Win64 驱动内核编程-28.枚举消息钩子「建议收藏」

下面是备份上资料里的整体代码(部分已经被我改过)

MyDriver.h—–r0

#include <ntddk.h>
#define dprintf	DbgPrint
#define	DEVICE_NAME	L"\\Device\\MyDriver"
#define LINK_NAME	L"\\DosDevices\\MyDriver"
#define LINK_GLOBAL_NAME	L"\\DosDevices\\Global\\MyDriver"
 
#define IOCTL_READ_KRNL_MM	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)	//read kernel
#define IOCTL_MODIFY_KN_MM	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)	//write kernel
#define IOCTL_SET_RWKM_ADR	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED, FILE_ANY_ACCESS)	//set address
#define IOCTL_SET_RWKM_LEN	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80A, METHOD_BUFFERED, FILE_ANY_ACCESS)	//set length
#define IOCTL_GET_PN_BY_ET	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x7FF, METHOD_BUFFERED, FILE_ANY_ACCESS)	//set length


MyDriver.c—–r0

#include <ntddk.h>
#include "MyDriver.h"
#include "rwkm.h"
 
NTKERNELAPI PUCHAR PsGetProcessImageFileName( IN PEPROCESS Process );
NTKERNELAPI PEPROCESS IoThreadToProcess( IN PETHREAD Thread );
 
VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverObj->DeviceObject);
}
 
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
 
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
 
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode)
{
case IOCTL_SET_RWKM_ADR:
{
rwkm_adr=*(UINT64 *)pIoBuffer;
DbgPrint("rwkm_adr: %lld\n",rwkm_adr);
status = STATUS_SUCCESS;
break;
}
case IOCTL_SET_RWKM_LEN:
{
rwkm_len=*(UINT64 *)pIoBuffer;
DbgPrint("rwkm_len: %lld\n",rwkm_len);
status = STATUS_SUCCESS;
break;
}
case IOCTL_READ_KRNL_MM:
{
VxkCopyMemory(pIoBuffer,(PVOID)rwkm_adr,(SIZE_T)rwkm_len);
status = STATUS_SUCCESS;
break;
}
case IOCTL_MODIFY_KN_MM:
{
VxkCopyMemory((PVOID)rwkm_adr,pIoBuffer,(SIZE_T)rwkm_len);
status = STATUS_SUCCESS;
break;
}
case IOCTL_GET_PN_BY_ET:
{
PETHREAD et;
PEPROCESS ep;
PUCHAR pn;
et=*(PETHREAD *)pIoBuffer;
ep=IoThreadToProcess(et);
pn=PsGetProcessImageFileName(ep);
memcpy(pIoBuffer,pn,16);
status = STATUS_SUCCESS;
break;
}
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
 
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustrLinkName;
UNICODE_STRING ustrDevName;  
PDEVICE_OBJECT pDevObj;
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
status = IoCreateDevice(pDriverObj, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj);
if(!NT_SUCCESS(status))	return status;
if(IoIsWdmVersionAvailable(1, 0x10))
RtlInitUnicodeString(&ustrLinkName, LINK_GLOBAL_NAME);
else
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);  
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj); 
return status;
}
return STATUS_SUCCESS;
}
 
 

Rwkm.h—–r0

BOOLEAN VxkCopyMemory( PVOID pDestination, PVOID pSourceAddress, SIZE_T SizeOfCopy )
{
    PMDL pMdl = NULL;
    PVOID pSafeAddress = NULL;
    pMdl = IoAllocateMdl( pSourceAddress, (ULONG)SizeOfCopy, FALSE, FALSE, NULL );
    if( !pMdl ) return FALSE;
    __try
    {
        MmProbeAndLockPages( pMdl, KernelMode, IoReadAccess );
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        IoFreeMdl( pMdl );
        return FALSE;
    }
    pSafeAddress = MmGetSystemAddressForMdlSafe( pMdl, NormalPagePriority );
    if( !pSafeAddress ) return FALSE;
    RtlCopyMemory( pDestination, pSafeAddress, SizeOfCopy );
    MmUnlockPages( pMdl );
    IoFreeMdl( pMdl );
    return TRUE;
}
 
ULONG64 rwkm_adr=0, rwkm_len=0;

ScmDrvCtrl.h----r3
/*============================
Drvier Control Class (SCM way)
============================*/
 
#pragma comment(lib,"advapi32.lib")
 
class cDrvCtrl
{
public:
cDrvCtrl()
{
m_pSysPath = NULL;
m_pServiceName = NULL;
m_pDisplayName = NULL;
m_hSCManager = NULL;
m_hService = NULL;
m_hDriver = INVALID_HANDLE_VALUE;
}
~cDrvCtrl()
{
if (m_hService) {
CloseServiceHandle(m_hService);
}
if (m_hSCManager) {
CloseServiceHandle(m_hSCManager);
}
if (m_hDriver) {
CloseHandle(m_hDriver);
}
}
public:
DWORD m_dwLastError;
PCHAR m_pSysPath;
PCHAR m_pServiceName;
PCHAR m_pDisplayName;
HANDLE m_hDriver;
SC_HANDLE m_hSCManager;
SC_HANDLE m_hService;
public:
BOOL Install(PCHAR pSysPath,PCHAR pServiceName,PCHAR pDisplayName);
BOOL Start();
BOOL Stop();
BOOL Remove();
BOOL Open(PCHAR pLinkName);
BOOL IoControl(DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen, DWORD *RealRetBytes);
BOOL IoControl(HANDLE hDrvHandle, DWORD dwIoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize);
private:
BOOL GetSvcHandle(PCHAR pServiceName);
DWORD CTL_CODE_GEN(DWORD lngFunction);
protected:
//null
};
 
BOOL cDrvCtrl::GetSvcHandle(PCHAR pServiceName)
{
m_pServiceName = pServiceName;
m_hSCManager = OpenSCManagerA(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (NULL == m_hSCManager)
{
m_dwLastError = GetLastError();
return FALSE;
}
m_hService = OpenServiceA(m_hSCManager,m_pServiceName,SERVICE_ALL_ACCESS);
if (NULL == m_hService)
{
CloseServiceHandle(m_hSCManager);
return FALSE;
}
else
{
return TRUE;
}
}
 
BOOL cDrvCtrl::Install(PCHAR pSysPath,PCHAR pServiceName,PCHAR pDisplayName)
{
m_pSysPath = pSysPath;
m_pServiceName = pServiceName;
m_pDisplayName = pDisplayName;
m_hSCManager = OpenSCManagerA(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (NULL == m_hSCManager)
{
m_dwLastError = GetLastError();
return FALSE;
}
//m_hService = NULL;
//m_hService = OpenServiceA(m_hSCManager, pServiceName, SERVICE_ALL_ACCESS);
if (m_hService != NULL) {
return TRUE;
}
 
m_hService = CreateServiceA(m_hSCManager,m_pServiceName,m_pDisplayName,
                            SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,
                            m_pSysPath,NULL,NULL,NULL,NULL,NULL);
if (NULL == m_hService)
{
m_dwLastError = GetLastError();
if (ERROR_SERVICE_EXISTS == m_dwLastError)
{
m_hService = OpenServiceA(m_hSCManager,m_pServiceName,SERVICE_ALL_ACCESS);
if (NULL == m_hService)
{
CloseServiceHandle(m_hSCManager);
return FALSE;
}
}
else
{
CloseServiceHandle(m_hSCManager);
return FALSE;
}
}
return TRUE;
}
 
BOOL cDrvCtrl::Start()
{
if (!StartServiceA(m_hService,NULL,NULL))
{
m_dwLastError = GetLastError();
return FALSE;
}
return TRUE;
}
 
BOOL cDrvCtrl::Stop()
{
SERVICE_STATUS ss;
GetSvcHandle(m_pServiceName);
if (!ControlService(m_hService,SERVICE_CONTROL_STOP,&ss))
{
m_dwLastError = GetLastError();
return FALSE;
}
return TRUE;
 
}
 
BOOL cDrvCtrl::Remove()
{
GetSvcHandle(m_pServiceName);
if (!DeleteService(m_hService))
{
m_dwLastError = GetLastError();
return FALSE;
}
return TRUE;
}
 
BOOL cDrvCtrl::Open(PCHAR pLinkName)//example: \\\\.\\xxoo
{
if (m_hDriver != INVALID_HANDLE_VALUE)
return TRUE;
m_hDriver = CreateFileA(pLinkName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(m_hDriver != INVALID_HANDLE_VALUE)
return TRUE;
else
return FALSE;
}
 
BOOL cDrvCtrl::IoControl(DWORD dwIoCode, PVOID InBuff, DWORD InBuffLen, PVOID OutBuff, DWORD OutBuffLen, DWORD *RealRetBytes)
{
DWORD dw;
BOOL b=DeviceIoControl(m_hDriver,CTL_CODE_GEN(dwIoCode),InBuff,InBuffLen,OutBuff,OutBuffLen,&dw,NULL);
if(RealRetBytes)
*RealRetBytes=dw;
return b;
}
 
BOOL cDrvCtrl::IoControl(HANDLE hDrvHandle, DWORD dwIoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize)
{
DWORD lDrvRetSize;
return DeviceIoControl(hDrvHandle, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, &lDrvRetSize, 0);
}
 
DWORD cDrvCtrl::CTL_CODE_GEN(DWORD lngFunction)
{
return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED;
}
 

InstallDri.cpp—-r3

 

#include "stdafx.h"
#include <string>
#include <stdio.h>
#include <Windows.h>
#include "ScmDrvCtrl.h"
#include <iostream>
 
#pragma warning(disable:4996)
#pragma comment(lib,"user32.lib")
 
using namespace std;
 
void GetAppPath(char *szCurFile) 
{
GetModuleFileNameA(0, szCurFile, MAX_PATH);
for (SIZE_T i = strlen(szCurFile) - 1; i >= 0; i--)
{
if (szCurFile[i] == '\\')
{
szCurFile[i + 1] = '
#include "stdafx.h"
#include <string>
#include <stdio.h>
#include <Windows.h>
#include "ScmDrvCtrl.h"
#include <iostream>
#pragma warning(disable:4996)
#pragma comment(lib,"user32.lib")
using namespace std;
void GetAppPath(char *szCurFile) 
{
GetModuleFileNameA(0, szCurFile, MAX_PATH);
for (SIZE_T i = strlen(szCurFile) - 1; i >= 0; i--)
{
if (szCurFile[i] == '\\')
{
szCurFile[i + 1] = '\0';
break;
}
}
}
//start********************Dirver*************************
cDrvCtrl dcDirver;
BOOL InstallDriver(char * pSysFileName, char * pServiceName, char * pDisplayName) {
char szSysFile[MAX_PATH] = { 0 };
GetAppPath(szSysFile);
strcat(szSysFile, pSysFileName);
BOOL bInstallSuc = FALSE;
if (dcDirver.Install(szSysFile, pServiceName, pDisplayName)) {
if (dcDirver.Start()) {
char pLink[1024] = "\\\\.\\";
strcat(pLink , pDisplayName);
dcDirver.Open(pLink);
DWORD x = 0, y = 0, z = 0;
dcDirver.IoControl(0x803, &x, sizeof(x), &y, sizeof(y), &z);
bInstallSuc = TRUE;
}
}
return bInstallSuc;
}
VOID UnInstallDriver() {
CloseHandle(dcDirver.m_hDriver);
dcDirver.Stop();
dcDirver.Remove();
}
//end********************Dirver*************************
DWORD CTL_CODE_GEN(DWORD lngFunction)
{
return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED;
}
BOOL IoControl(HANDLE hDrvHandle, DWORD dwIoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize)
{
DWORD lDrvRetSize;
return DeviceIoControl(hDrvHandle, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, &lDrvRetSize, 0);
}
void RKM(UINT64 Address, PVOID Buffer, SIZE_T Length)
{
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x809), &Address, 8, NULL, 0);	//address
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x80A), &Length, 8, NULL, 0);	//length
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x804), NULL, 0, Buffer, Length);	//get buffer
}
void WKM(UINT64 Address, PVOID Buffer, SIZE_T Length)
{
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x809), &Address, 8, NULL, 0);	//address
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x80A), &Length, 8, NULL, 0);	//length
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x805), Buffer, Length, NULL, 0);	//set buffer
}
UINT64 GetQWORD(UINT64 address)
{
UINT64 y = 0;
RKM(address, &y, 8);
return y;
}
UINT32 GetDWORD(UINT64 address)
{
UINT32 y = 0;
RKM(address, &y, 4);
return y;
}
PUCHAR GetPNbyET(UINT64 ethread)
{
PUCHAR y = (PUCHAR)malloc(16);
IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x7FF), ðread, 8, y, 16);
return y;
}
/*
lkd> dt win32k!tagsharedinfo
+0x000 psi              : Ptr64 tagSERVERINFO
+0x008 aheList          : Ptr64 _HANDLEENTRY
+0x010 HeEntrySize      : Uint4B
+0x018 pDispInfo        : Ptr64 tagDISPLAYINFO
+0x020 ulSharedDelta    : Uint8B
+0x028 awmControl       : [31] _WNDMSG
+0x218 DefWindowMsgs    : _WNDMSG
+0x228 DefWindowSpecMsgs : _WNDMSG
lkd> dt win32k!tagSERVERINFO
+0x000 dwSRVIFlags      : Uint4B
+0x008 cHandleEntries   : Uint8B
+0x010 mpFnidPfn        : [32] Ptr64     int64
+0x110 aStoCidPfn       : [7] Ptr64     int64
[省略......]
*/
/*win32k!_HANDLEENTRY
+0x000 phead            : Ptr64 _HEAD
+0x008 pOwner           : Ptr64 Void
+0x010 bType            : UChar
+0x011 bFlags           : UChar
+0x012 wUniq            : Uint2B*/
typedef struct _HANDLEENTRY
{
UINT64	phead;
UINT64	pOwner;
UCHAR	bType;
UCHAR	bFlags;
USHORT	wUniq;
}HANDLEENTRY, *PHANDLEENTRY;
/*
lkd> dt win32k!taghook
+0x000 head             : _THRDESKHEAD
+0x028 phkNext          : Ptr64 tagHOOK
+0x030 iHook            : Int4B
+0x038 offPfn           : Uint8B
+0x040 flags            : Uint4B
+0x044 ihmod            : Int4B
+0x048 ptiHooked        : Ptr64 tagTHREADINFO
+0x050 rpdesk           : Ptr64 tagDESKTOP
+0x058 nTimeout         : Pos 0, 7 Bits
+0x058 fLastHookHung    : Pos 7, 1 Bit
lkd> dt_THRDESKHEAD
win32k!_THRDESKHEAD
+0x000 h                : Ptr64 Void
+0x008 cLockObj         : Uint4B
+0x010 pti              : Ptr64 tagTHREADINFO
+0x018 rpdesk           : Ptr64 tagDESKTOP
+0x020 pSelf            : Ptr64 UChar
*/
typedef struct _HOOK_INFO
{
HANDLE       hHandle;                    //钩子的句柄   句柄是全局的 可以UnhookWindowsHookEx  把钩子卸掉
int          Unknown1;
PVOID        Win32Thread;                 //一个指向 win32k!_W32THREAD 结构体的指针
PVOID        Unknown2;
PVOID        SelfHook;                   //指向结构体的首地址
PVOID        NextHook;                   //指向下一个钩子结构体
int          iHookType;                 //钩子的类型, winuser.h 中有定义
PVOID        OffPfn;                    //钩子函数的地址偏移,相对于所在模块的偏移
int          iHookFlags;
int          iMod;                      //钩子函数做在模块的索引号码,通过查询 WowProcess 结构可以得到模块的基地址。
PVOID        Win32ThreadHooked;         // ???被钩的线程的结构指针,不知道
//下面还有,省略。。。
} HOOK_INFO, *PHOOK_INFO;
char *GetHookType(int Id)
{
char *string;
string = (char*)malloc(32);
switch (Id)
{
case -1:
{
strcpy(string, "WH_MSGFILTER");
break;
}
case 0:
{
strcpy(string, "WH_JOURNALRECORD");
break;
}
case 1:
{
strcpy(string, "WH_JOURNALPLAYBACK");
break;
}
case 2:
{
strcpy(string, "WH_KEYBOARD");
break;
}
case 3:
{
strcpy(string, "WH_GETMESSAGE");
break;
}
case 4:
{
strcpy(string, "WH_CALLWNDPROC");
break;
}
case 5:
{
strcpy(string, "WH_CBT");
break;
}
case 6:
{
strcpy(string, "WH_SYSMSGFILTER");
break;
}
case 7:
{
strcpy(string, "WH_MOUSE");
break;
}
case 8:
{
strcpy(string, "WH_HARDWARE");
break;
}
case 9:
{
strcpy(string, "WH_DEBUG");
break;
}
case 10:
{
strcpy(string, "WH_SHELL");
break;
}
case 11:
{
strcpy(string, "WH_FOREGROUNDIDLE");
break;
}
case 12:
{
strcpy(string, "WH_CALLWNDPROCRET");
break;
}
case 13:
{
strcpy(string, "WH_KEYBOARD_LL");
break;
}
case 14:
{
strcpy(string, "WH_MOUSE_LL");
break;
}
default:
{
strcpy(string, "????");
break;
}
}
return string;
}
char *GetHookFlagString(int Flag)
{
char *string;
string = (char*)malloc(8);
if (Flag == 1 || Flag == 3)
strcpy(string, "Global");
else
strcpy(string, "Local");
return string;
}
void EnumMsgHook()
{
int i = 0;
UINT64 pgSharedInfo = (UINT64)GetProcAddress(LoadLibraryA("user32.dll"), "gSharedInfo");
cout << "user32.dll.gSharedInfo:" << pgSharedInfo << endl;
UINT64 phe = GetQWORD(pgSharedInfo + 8);	//+0x008 aheList          : Ptr64 _HANDLEENTRY
UINT64 count = GetQWORD(GetQWORD(pgSharedInfo) + 8);
HANDLEENTRY heStruct = { 0 };
HOOK_INFO Hook = { 0 };
cout << count << endl;
for (i = 0; i<count; i++)
{
memcpy(&heStruct, (PVOID)(phe + i * sizeof(HANDLEENTRY)), sizeof(HANDLEENTRY));
if (heStruct.bType == 5)
{
RKM(heStruct.phead, &Hook, sizeof(HOOK_INFO));
printf("hHandle:     0x%llx\n", Hook.hHandle);
printf("iHookFlags:  %s\n", GetHookFlagString(Hook.iHookFlags));
printf("iHookType:   %s\n", GetHookType(Hook.iHookType));
printf("OffPfn:      0x%llx\n", Hook.OffPfn);
printf("ETHREAD:     0x%llx\n", GetQWORD((UINT64)(Hook.Win32Thread)));
printf("ProcessName: %s\n\n", GetPNbyET(GetQWORD((UINT64)(Hook.Win32Thread))));
}
}
}
//end********************UnHook*************************
int main()
{
//安装驱动
if (!InstallDriver("Dri.sys", "MyDriver", "MyDriver")) {
printf("LoadDriver=false\n");
return 0;
}
else {
printf("LoadDriver=true\n");
}
getchar();
EnumMsgHook();
getchar();
//getchar();
//getchar();
//卸载驱动
UnInstallDriver();
printf("UninstallDriver=true\n");
return 0;
}
'; break; } } } //start********************Dirver************************* cDrvCtrl dcDirver; BOOL InstallDriver(char * pSysFileName, char * pServiceName, char * pDisplayName) { char szSysFile[MAX_PATH] = { 0 }; GetAppPath(szSysFile); strcat(szSysFile, pSysFileName); BOOL bInstallSuc = FALSE; if (dcDirver.Install(szSysFile, pServiceName, pDisplayName)) { if (dcDirver.Start()) { char pLink[1024] = "\\\\.\\"; strcat(pLink , pDisplayName); dcDirver.Open(pLink); DWORD x = 0, y = 0, z = 0; dcDirver.IoControl(0x803, &x, sizeof(x), &y, sizeof(y), &z); bInstallSuc = TRUE; } } return bInstallSuc; } VOID UnInstallDriver() { CloseHandle(dcDirver.m_hDriver); dcDirver.Stop(); dcDirver.Remove(); } //end********************Dirver************************* DWORD CTL_CODE_GEN(DWORD lngFunction) { return (FILE_DEVICE_UNKNOWN * 65536) | (FILE_ANY_ACCESS * 16384) | (lngFunction * 4) | METHOD_BUFFERED; } BOOL IoControl(HANDLE hDrvHandle, DWORD dwIoControlCode, PVOID lpInBuffer, DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize) { DWORD lDrvRetSize; return DeviceIoControl(hDrvHandle, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, &lDrvRetSize, 0); } void RKM(UINT64 Address, PVOID Buffer, SIZE_T Length) { IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x809), &Address, 8, NULL, 0); //address IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x80A), &Length, 8, NULL, 0); //length IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x804), NULL, 0, Buffer, Length); //get buffer } void WKM(UINT64 Address, PVOID Buffer, SIZE_T Length) { IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x809), &Address, 8, NULL, 0); //address IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x80A), &Length, 8, NULL, 0); //length IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x805), Buffer, Length, NULL, 0); //set buffer } UINT64 GetQWORD(UINT64 address) { UINT64 y = 0; RKM(address, &y, 8); return y; } UINT32 GetDWORD(UINT64 address) { UINT32 y = 0; RKM(address, &y, 4); return y; } PUCHAR GetPNbyET(UINT64 ethread) { PUCHAR y = (PUCHAR)malloc(16); IoControl(dcDirver.m_hDriver, CTL_CODE_GEN(0x7FF), ðread, 8, y, 16); return y; } /* lkd> dt win32k!tagsharedinfo +0x000 psi : Ptr64 tagSERVERINFO +0x008 aheList : Ptr64 _HANDLEENTRY +0x010 HeEntrySize : Uint4B +0x018 pDispInfo : Ptr64 tagDISPLAYINFO +0x020 ulSharedDelta : Uint8B +0x028 awmControl : [31] _WNDMSG +0x218 DefWindowMsgs : _WNDMSG +0x228 DefWindowSpecMsgs : _WNDMSG lkd> dt win32k!tagSERVERINFO +0x000 dwSRVIFlags : Uint4B +0x008 cHandleEntries : Uint8B +0x010 mpFnidPfn : [32] Ptr64 int64 +0x110 aStoCidPfn : [7] Ptr64 int64 [省略......] */ /*win32k!_HANDLEENTRY +0x000 phead : Ptr64 _HEAD +0x008 pOwner : Ptr64 Void +0x010 bType : UChar +0x011 bFlags : UChar +0x012 wUniq : Uint2B*/ typedef struct _HANDLEENTRY { UINT64 phead; UINT64 pOwner; UCHAR bType; UCHAR bFlags; USHORT wUniq; }HANDLEENTRY, *PHANDLEENTRY; /* lkd> dt win32k!taghook +0x000 head : _THRDESKHEAD +0x028 phkNext : Ptr64 tagHOOK +0x030 iHook : Int4B +0x038 offPfn : Uint8B +0x040 flags : Uint4B +0x044 ihmod : Int4B +0x048 ptiHooked : Ptr64 tagTHREADINFO +0x050 rpdesk : Ptr64 tagDESKTOP +0x058 nTimeout : Pos 0, 7 Bits +0x058 fLastHookHung : Pos 7, 1 Bit lkd> dt_THRDESKHEAD win32k!_THRDESKHEAD +0x000 h : Ptr64 Void +0x008 cLockObj : Uint4B +0x010 pti : Ptr64 tagTHREADINFO +0x018 rpdesk : Ptr64 tagDESKTOP +0x020 pSelf : Ptr64 UChar */ typedef struct _HOOK_INFO { HANDLE hHandle; //钩子的句柄 句柄是全局的 可以UnhookWindowsHookEx 把钩子卸掉 int Unknown1; PVOID Win32Thread; //一个指向 win32k!_W32THREAD 结构体的指针 PVOID Unknown2; PVOID SelfHook; //指向结构体的首地址 PVOID NextHook; //指向下一个钩子结构体 int iHookType; //钩子的类型, winuser.h 中有定义 PVOID OffPfn; //钩子函数的地址偏移,相对于所在模块的偏移 int iHookFlags; int iMod; //钩子函数做在模块的索引号码,通过查询 WowProcess 结构可以得到模块的基地址。 PVOID Win32ThreadHooked; // ???被钩的线程的结构指针,不知道 //下面还有,省略。。。 } HOOK_INFO, *PHOOK_INFO; char *GetHookType(int Id) { char *string; string = (char*)malloc(32); switch (Id) { case -1: { strcpy(string, "WH_MSGFILTER"); break; } case 0: { strcpy(string, "WH_JOURNALRECORD"); break; } case 1: { strcpy(string, "WH_JOURNALPLAYBACK"); break; } case 2: { strcpy(string, "WH_KEYBOARD"); break; } case 3: { strcpy(string, "WH_GETMESSAGE"); break; } case 4: { strcpy(string, "WH_CALLWNDPROC"); break; } case 5: { strcpy(string, "WH_CBT"); break; } case 6: { strcpy(string, "WH_SYSMSGFILTER"); break; } case 7: { strcpy(string, "WH_MOUSE"); break; } case 8: { strcpy(string, "WH_HARDWARE"); break; } case 9: { strcpy(string, "WH_DEBUG"); break; } case 10: { strcpy(string, "WH_SHELL"); break; } case 11: { strcpy(string, "WH_FOREGROUNDIDLE"); break; } case 12: { strcpy(string, "WH_CALLWNDPROCRET"); break; } case 13: { strcpy(string, "WH_KEYBOARD_LL"); break; } case 14: { strcpy(string, "WH_MOUSE_LL"); break; } default: { strcpy(string, "????"); break; } } return string; } char *GetHookFlagString(int Flag) { char *string; string = (char*)malloc(8); if (Flag == 1 || Flag == 3) strcpy(string, "Global"); else strcpy(string, "Local"); return string; } void EnumMsgHook() { int i = 0; UINT64 pgSharedInfo = (UINT64)GetProcAddress(LoadLibraryA("user32.dll"), "gSharedInfo"); cout << "user32.dll.gSharedInfo:" << pgSharedInfo << endl; UINT64 phe = GetQWORD(pgSharedInfo + 8); //+0x008 aheList : Ptr64 _HANDLEENTRY UINT64 count = GetQWORD(GetQWORD(pgSharedInfo) + 8); HANDLEENTRY heStruct = { 0 }; HOOK_INFO Hook = { 0 }; cout << count << endl; for (i = 0; i<count; i++) { memcpy(&heStruct, (PVOID)(phe + i * sizeof(HANDLEENTRY)), sizeof(HANDLEENTRY)); if (heStruct.bType == 5) { RKM(heStruct.phead, &Hook, sizeof(HOOK_INFO)); printf("hHandle: 0x%llx\n", Hook.hHandle); printf("iHookFlags: %s\n", GetHookFlagString(Hook.iHookFlags)); printf("iHookType: %s\n", GetHookType(Hook.iHookType)); printf("OffPfn: 0x%llx\n", Hook.OffPfn); printf("ETHREAD: 0x%llx\n", GetQWORD((UINT64)(Hook.Win32Thread))); printf("ProcessName: %s\n\n", GetPNbyET(GetQWORD((UINT64)(Hook.Win32Thread)))); } } } //end********************UnHook************************* int main() { //安装驱动 if (!InstallDriver("Dri.sys", "MyDriver", "MyDriver")) { printf("LoadDriver=false\n"); return 0; } else { printf("LoadDriver=true\n"); } getchar(); EnumMsgHook(); getchar(); //getchar(); //getchar(); //卸载驱动 UnInstallDriver(); printf("UninstallDriver=true\n"); return 0; }

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/159481.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • CSDN更换博客皮肤教程

    CSDN更换博客皮肤教程1.进入博客设置,按F12键打开开发者工具调试页面2.找到博客皮肤的div,鼠标右键编辑HTML3.将checked=“checked”readonly=””剪切到你想要的皮肤里面,这里我是技术黑板的皮肤,之前就改了4.点击左边的页面,可以看到想要的皮肤是选中状态,然后点击保存,皮肤更改成功!…

  • 计算机分子模拟聚乙烯,用“分子模拟”软件构建聚乙烯分子、全同立构聚丙烯分子,并计算它们末端的直线距离-高分子物理-实验1-01…

    计算机分子模拟聚乙烯,用“分子模拟”软件构建聚乙烯分子、全同立构聚丙烯分子,并计算它们末端的直线距离-高分子物理-实验1-01…高分子物理实验。实验一用“分子模拟”(MP)软件构建聚乙烯分子、全同立构聚丙烯,并计算它们末端的直线距离一、实验目的1.了解用计算机软件模拟大分子的“分子模拟”新趋势。2.学会用“分子模拟”软件构造聚乙烯、聚丙烯大分子。3.计算主链含100个碳原子的聚乙烯、聚丙烯分子末端的直线距离。二、实验原理已经知道,C-C单键是σ键,其电子云分布具有轴对称性。因此,σ键相连的两个碳原子可…

  • spawn-fcgi原理及源代码分析

    spawn-fcgi原理及源代码分析spawn-fcgi是一个小程序,作用是管理fast-cgi进程,功能和php-fpm类似,简单小巧,原先是属于lighttpd的一部分。后来因为使用比較广泛。所以就迁移出来作为独立项目了。本文介绍的

  • intellij idea 2021激活码(最新序列号破解)

    intellij idea 2021激活码(最新序列号破解),https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • 三极管典型开关电路

    三极管典型开关电路1.基极必须串接电阻,保护基极,保护CPU的IO口。2.基极根据PNP或者NPN管子加上拉电阻或者下拉电阻。3.集电极电阻阻值根据驱动电流实际情况调整。同样基极电阻也可以根据实际情况调整。4.基极和发射极需要并联电阻,该电阻的作用是在输入呈高阻态时使晶体管可靠截止,极小值是在前级驱动使晶体管饱和时与基极限流电阻分压后能够满足晶体管的临界饱和,实际选择时会大大高于这个极小值,

  • “ORA-01017(:用户名/口令无效; 登录被拒绝)”解决办法「建议收藏」

    “ORA-01017(:用户名/口令无效; 登录被拒绝)”解决办法「建议收藏」报错:ORA-01017(:用户名/口令无效;登录被拒绝)1.打开CMD命令窗,输入sqlplus/assysdba1)修改密码SQL>alteruser用户名identifiedby密码2)用户被锁定,解锁ALTERUSERusernameACCOUNTUNLOCK;再次登录验证,成功…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号