热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

PASSTesSafe

#includentddk.h#defineThreadLength0x190要保存的NtOpenThread原代码的长度#defineProcessLength0x184要保存的NtOpenProcess原代码的长度#defineDeviceLinkL\Device\DNFCracker#defineSymbolicLinkL\DosDevices\DNFCracker#def

#include ntddk.h #define ThreadLength 0x190 //要保存的 NtOpenThread 原代码的长度 #define ProcessLength 0x184 //要保存的 NtOpenProcess 原代码的长度 #define DeviceLink L\\Device\\DNFCracker #define SymbolicLink L\\DosDevices\\DNFCracker #def

#include "ntddk.h"

#define ThreadLength 0x190 //要保存的 NtOpenThread 原代码的长度

#define ProcessLength 0x184 //要保存的 NtOpenProcess 原代码的长度

#define DeviceLink L"\\Device\\DNFCracker"

#define SymbolicLink L"\\DosDevices\\DNFCracker"

#define IOCTL_RESTORE (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, 0x886, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef NTSTATUS (* NTOPENTHREAD)(

OUT PHANDLE ThreadHandle,

IN ACCESS_MASK DesiredAccess,

IN POBJECT_ATTRIBUTES ObjectAttributes,

IN OPTIONAL PCLIENT_ID ClientId

);

typedef NTSTATUS (* NTOPENPROCESS)(

OUT PHANDLE ProcessHandle,

IN ACCESS_MASK DesiredAccess,

IN POBJECT_ATTRIBUTES ObjectAttributes,

IN PCLIENT_ID ClientId

);

typedef struct _SERVICE_DESCRIPTOR_TABLE

{

PVOID ServiceTableBase;

PULONG ServiceCounterTableBase;

ULONG NumberOfService;

ULONG ParamTableBase;

}

SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;

extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

VOID Hook();

VOID Unhook();

NTOPENTHREAD OldThread;

NTOPENPROCESS OldProcess;

ULONG AddrRead, AddrWrite;

//原 NtReadVirtualMemory/NtWriteVirtualMemory 的前 16 字节代码

ULONG OrgRead[2], OrgWrite[2];

//保存 NtOpenThread/NtOpenProcess 代码

UCHAR MyThread[ThreadLength], MyProcess[ProcessLength];

NTSTATUS MyNtOpenThread(

PHANDLE ThreadHandle,

ACCESS_MASK DesiredAccess,

POBJECT_ATTRIBUTES ObjectAttributes,

PCLIENT_ID ClientId)

{

ACCESS_MASK oDA;

OBJECT_ATTRIBUTES oOA;

CLIENT_ID oCID;

NTSTATUS statusF, statusT;

oDA = DesiredAccess;

oOA = *ObjectAttributes;

oCID = *ClientId;

statusF = OldThread(ThreadHandle, oDA, &oOA, &oCID);

statusT = ((NTOPENTHREAD)MyThread)(ThreadHandle, DesiredAccess, ObjectAttributes, ClientId);

return statusT;

}

NTSTATUS MyNtOpenProcess(

PHANDLE ProcessHandle,

ACCESS_MASK DesiredAccess,

POBJECT_ATTRIBUTES ObjectAttributes,

PCLIENT_ID ClientId)

{

ACCESS_MASK oDA;

OBJECT_ATTRIBUTES oOA;

CLIENT_ID oCID;

NTSTATUS statusF, statusT;

oDA = DesiredAccess;

oOA = *ObjectAttributes;

oCID = *ClientId;

statusF = OldProcess(ProcessHandle, oDA, &oOA, &oCID);

statusT = ((NTOPENPROCESS)MyProcess)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);

return statusT;

}

NTSTATUS DispatchIoCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

ULONG ioControlCode;

ULONG inBufLength, outBufLength;

//PUCHAR InputBuffer, OutputBuffer;

NTSTATUS status = STATUS_SUCCESS;

PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;

outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

ioCOntrolCode= irpStack->Parameters.DeviceIoControl.IoControlCode;

switch (ioControlCode)

{

case IOCTL_RESTORE:

//InputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;

//OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;

//恢复 NtReadVirtualMemory/NtWriteVirtualMemory 前 16 字节

*(PULONG)(*(PULONG)AddrRead) = OrgRead[0];

*(PULONG)(*(PULONG)AddrRead + 4) = OrgRead[1];

*(PULONG)(*(PULONG)AddrWrite) = OrgWrite[0];

*(PULONG)(*(PULONG)AddrWrite + 4) = OrgWrite[1];

Irp->IoStatus.Information = outBufLength;

break;

default:

DbgPrint("Unknown IOCTL: 0x%X (%04X)",

ioControlCode, IoGetFunctionCodeFromCtlCode(ioControlCode));

status = STATUS_INVALID_PARAMETER;

Irp->IoStatus.Information = 0;

}

//完成 IRP

Irp->IoStatus.Status = status;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return status;

}

NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

Irp->IoStatus.Status = STATUS_SUCCESS;

Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return Irp->IoStatus.Status;

}

VOID OnUnload(IN PDRIVER_OBJECT DriverObject)

{

UNICODE_STRING usLink;

/*ULONG i;

for (i = 0; i

{

DbgPrint("%02x %02x %02x %02x\n", MyThread[i], MyThread[i + 1], MyThread[i + 2], MyThread[i + 3]);

DbgPrint("%02x %02x %02x %02x\n", MyProcess[i], MyProcess[i + 1], MyProcess[i + 2], MyProcess[i + 3]);

}

*/

Unhook();

DbgPrint("DNF Cracker Unloaded!");

RtlInitUnicodeString(&usLink, SymbolicLink);

IoDeleteSymbolicLink(&usLink);

IoDeleteDevice(DriverObject->DeviceObject);

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

{

NTSTATUS status;

PDEVICE_OBJECT DvcObj;

UNICODE_STRING usDevice, usLink;

PLIST_ENTRY pLE = (PLIST_ENTRY)DriverObject->DriverSection;

//隐藏驱动

pLE->Flink->Blink = pLE->Blink;

pLE->Blink->Flink = pLE->Flink;

DriverObject->DriverUnload = OnUnload;

//创建虚拟设备

RtlInitUnicodeString(&usDevice, DeviceLink);

status = IoCreateDevice(DriverObject, 0, &usDevice, FILE_DEVICE_UNKNOWN, 0, TRUE, &DvcObj);

if (!NT_SUCCESS(status))

{

DbgPrint("Failed to create device!\n");

return status;

}

//创建符号链接

RtlInitUnicodeString(&usLink, SymbolicLink);

status = IoCreateSymbolicLink(&usLink, &usDevice);

if (!NT_SUCCESS(status))

{

IoDeleteDevice(DriverObject->DeviceObject);

DbgPrint("Failed to create symbolic link!\n");

return status;

}

//调度函数分配

DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =

DriverObject->MajorFunction[IRP_MJ_CREATE] =

DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoCtrl;

Hook();

DbgPrint("DNF Cracker Loaded!");

return STATUS_SUCCESS;

}

// OrgRel 原相对跳转地址

// CurAbs 当前代码绝对地址

// MyAbs 替换代码绝对地址

// CodeLen 跳转代码占据的长度

// 返回值 到替换代码的相对地址

LONG GetRelAddr(LONG OrgRel, ULONG CurAbs, ULONG MyAbs) //, ULONG CodeLen)

{

ULONG TrgAbs;

TrgAbs = CurAbs + OrgRel; // + CodeLen; //目的地址

return TrgAbs - MyAbs;

}

// 保存原来整个函数的代码

// pCode 用来保存代码的数组的地址

// TrgAddr 要保存的函数的地址

// BufferLength 整个函数占用的大小

VOID BufferCode(PUCHAR pCode, ULONG TrgAddr, ULONG BufferLength)

{

ULONG cAbs, i;

LONG oRel, cRel;

memset(pCode, 0x90, BufferLength);

for (i = 0; i

{

cAbs = TrgAddr + i;

pCode[i] = *(PUCHAR)cAbs;

switch (*(PUCHAR)cAbs)

{

case 0x0F: //JXX NEAR X

if ((*(PUCHAR)(cAbs + 1) >= 0x80)&&(*(PUCHAR)(cAbs + 1) <= 0x8F))

{

oRel = *(PLONG)(cAbs + 2);

if ((oRel + cAbs + 6 > TrgAddr + BufferLength)||

(oRel + cAbs + 6

{

pCode[i + 1] = *(PUCHAR)(cAbs + 1);

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 2, &cRel, sizeof(LONG));

//DbgPrint("JXX: 0x%08X -> 0x%08X", cAbs, (ULONG)pCode + i);

i += sizeof(LONG) + 1;

}

}

break;

case 0xE8: //CALL

oRel = *(PLONG)(cAbs + 1);

if ((oRel + cAbs + 5 > TrgAddr + BufferLength)||

(oRel + cAbs + 5

{

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 1, &cRel, sizeof(LONG));

//DbgPrint("CALL: 0x%08X -> 0x%08X", cAbs, (ULONG)pCode + i);

i += sizeof(LONG);

}

break;

case 0x80: //CMP BYTE PTR X

if (*(PUCHAR)(cAbs + 1) == 0x7D)

{

memcpy(pCode + i + 1, (PVOID)(cAbs + 1), 3);

i += 3; continue;

}

break;

case 0xC2: //RET X

if (*(PUSHORT)(cAbs +1) == 0x10)

{

memcpy(pCode + i + 1, (PVOID)(cAbs + 1), sizeof(USHORT));

i += sizeof(USHORT);

}

break;

/*case 0xE9: //JMP

oRel = *(PLONG)(cAbs + 1);

if (oRel + cAbs > TrgAddr + BufferLength)

{

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 1, &cRel, sizeof(LONG));

i += 4;

}*/

}

if ((*(PUCHAR)cAbs == 0x39)||(*(PUCHAR)cAbs == 0x89)||(*(PUCHAR)cAbs == 0x8D))

{

memcpy(pCode + i + 1, (PVOID)(cAbs + 1), sizeof(USHORT));

i += sizeof(USHORT); continue;

}

/*if ((*(PUCHAR)cAbs >= 0x70)&&(*(PUCHAR)cAbs <= 0x7F)&&(*(PUCHAR)(cAbs - 1) != 0xFF))

{

oRel = (LONG)(*(PCHAR)(cAbs + 1));

cRel = GetRelAddr(oRel, cAbs, (ULONG)pCode + i);

memcpy(pCode + i + 1, &cRel, 1);

i++; continue;

}*/

}

}

VOID Hook()

{

ULONG AddrProcess, AddrThread;

AddrRead = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xBA * 4;

AddrWrite = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x115 * 4;

AddrThread = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x80 * 4;

AddrProcess = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;

OldThread = (NTOPENTHREAD)(*(PULONG)AddrThread);

OldProcess = (NTOPENPROCESS)(*(PULONG)AddrProcess);

DbgPrint("MyThread:0x%08X OldThread:0x%08X", MyThread, OldThread);

DbgPrint("MyProcess:0x%08X OldProcess:0x%08X", MyProcess, OldProcess);

__asm

{

cli

mov eax,cr0

and eax,not 10000h

mov cr0,eax

}

//记录 NtReadVirtualMemory/NtWriteVirtualMemory 前 16 字节

OrgRead[0] = *(PULONG)(*(PULONG)AddrRead);

OrgRead[1] = *(PULONG)(*(PULONG)AddrRead + 4);

OrgWrite[0] = *(PULONG)(*(PULONG)AddrWrite);

OrgWrite[1] = *(PULONG)(*(PULONG)AddrWrite + 4);

//保存原代码

BufferCode(MyThread, (ULONG)OldThread, ThreadLength);

BufferCode(MyProcess, (ULONG)OldProcess, ProcessLength);

//SSDT Hook

*(PULONG)AddrThread = (ULONG)MyNtOpenThread;

*(PULONG)AddrProcess = (ULONG)MyNtOpenProcess;

__asm

{

mov eax,cr0

or eax,10000h

mov cr0,eax

sti

}

DbgPrint("Hooked!");

}

VOID Unhook()

{

ULONG AddrProcess, AddrThread;

AddrThread = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x80 * 4;

AddrProcess = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;

__asm

{

cli

mov eax,cr0

and eax,not 10000h

mov cr0,eax

}

//恢复 SSDT

*(PULONG)AddrThread = (ULONG)OldThread;

*(PULONG)AddrProcess = (ULONG)OldProcess;

__asm

{

mov eax,cr0

or eax,10000h

mov cr0,eax

sti

}

DbgPrint("Unhooked!");

}

推荐阅读
  • 网络运维工程师负责确保企业IT基础设施的稳定运行,保障业务连续性和数据安全。他们需要具备多种技能,包括搭建和维护网络环境、监控系统性能、处理突发事件等。本文将探讨网络运维工程师的职业前景及其平均薪酬水平。 ... [详细]
  • CentOS 7.2 配置防火墙端口开放
    本文介绍如何在 CentOS 7.2 系统上配置防火墙以开放特定的服务端口,包括 FTP 服务的临时与永久开放方法,以及如何验证配置是否生效。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文将详细介绍在Windows 7环境下,检查U盘启动盘是否制作成功的多种方法,包括通过BIOS设置和使用模拟启动工具。 ... [详细]
  • 本文介绍如何使用 NSTimer 实现倒计时功能,详细讲解了初始化方法、参数配置以及具体实现步骤。通过示例代码展示如何创建和管理定时器,确保在指定时间间隔内执行特定任务。 ... [详细]
  • 本文介绍了在Windows环境下使用pydoc工具的方法,并详细解释了如何通过命令行和浏览器查看Python内置函数的文档。此外,还提供了关于raw_input和open函数的具体用法和功能说明。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 高效解决应用崩溃问题!友盟新版错误分析工具全面升级
    友盟推出的最新版错误分析工具,专为移动开发者设计,提供强大的Crash收集与分析功能。该工具能够实时监控App运行状态,快速发现并修复错误,显著提升应用的稳定性和用户体验。 ... [详细]
  • 本题涉及一棵由N个节点组成的树(共有N-1条边),初始时所有节点均为白色。题目要求处理两种操作:一是改变某个节点的颜色(从白变黑或从黑变白);二是查询从根节点到指定节点路径上的第一个黑色节点,若无则输出-1。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 技术人员转型项目管理:常见思维误区与挑战解析
    本文探讨了技术人员在向项目管理角色转变过程中常见的思维误区和困惑,分析了如何有效管理项目中的事务和人员,提供了实用的解决方案。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 探索1000以内的完美数:因数和等于自身
    本文探讨了如何在1000以内找到所有完美数,即一个数的因数(不包括自身)之和等于该数本身。例如,6是一个完美数,因为1 + 2 + 3 = 6。通过编程实现这一过程,可以更好地理解完美数的特性。 ... [详细]
  • 本文章以 IntelliJ IDEA 为例,详细介绍了如何配置和调试 FlinkX 项目。主要内容包括如何设置运行参数,以便在本地环境中顺利执行 FlinkX 任务。 ... [详细]
author-avatar
好好_haohao_100
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有