首页
社区
课程
招聘
[原创]初步实现系统级拦截应用程序取硬盘物理序列号
发表于: 2006-11-29 12:09 56521

[原创]初步实现系统级拦截应用程序取硬盘物理序列号

2006-11-29 12:09
56521
【文章标题】: 初步实现系统级拦截应用程序取硬盘物理序列号
【文章作者】: rockhard
【作者邮箱】: wnh1@sohu.com
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  以前想模拟某个程序取硬盘系列号,就将一个DLL注入进去,拦截DeviceIoControl的返回值,将其修改为目标硬盘的值。
  后来看到REGMON 从SSDT着手拦截注册表操作,可以看到任何程序的读写操作,就仿着改了一下程序。经测试可以欺骗相当
  一部分程序读硬盘序列号,包括ASPROTECT及用其加密算法的子孙:)。
  
  我的思路是这样的:
   
  1、首先用程序取自己的真正的硬盘序列号,假设为XXXX
  
  2、拦截系统的ZwDeviceIoControlFile,并判断入口参数中的IoControlCode ,只有某几个特定的值用来取序列号的,
     目前在所有的程序中取硬盘序列号的,我只发现两个值,一个是0x7c088,另外一个是什么忘了。
     
     如果IoControlCode为上面的值,读取系统原有的ZwDeviceIoControlFile返回BUFFER,并用串匹配方法查找这个返回值中存在
     不存在XXXX,如果存在,替换为你要欺骗的值.
  
  代码很简单:
  
  UCHAR __DiskSerial[DISK_SERIAL_BUFF_LENGTH]={0};
  UCHAR __ChangeTo  [DISK_SERIAL_BUFF_LENGTH]={0};
  
  //一个简单的低率串匹配算法 ,判断一个串S1是不是另外一个串S2的子串
  PUCHAR IsSubString(PUCHAR String, PUCHAR SubString ,ULONG StringLength ,ULONG SubStringLength)
  {
      ULONG i,j;
      for(i=0;i<StringLength - SubStringLength +1 ;i++){
          for(j=0;j<SubStringLength;j++){
              if(String[i+j]!=SubString[j])
                  break;
          }
          if(j==SubStringLength)  //match a substring
              return String+i;
      }
      return NULL;
  }
  
  //----------------------------------------------------------------------
  //
  //  Our own routine for ZwDeviceIocontrolFile
  //  We change the hard disk serial number value requested by user
  //
  //----------------------------------------------------------------------
  NTSTATUS HookZwDeviceIoControlFile(
                                    IN HANDLE FileHandle,
                                    IN HANDLE Event OPTIONAL,
                                    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
                                    IN PVOID ApcContext OPTIONAL,
                                    OUT PIO_STATUS_BLOCK IoStatusBlock,
                                    IN ULONG IoControlCode,
                                    IN PVOID InputBuffer OPTIONAL,
                                    IN ULONG InputBufferLength,
                                    OUT PVOID OutputBuffer OPTIONAL,
                                    IN ULONG OutputBufferLength
                                    )
  {
      NTSTATUS rc;
  
      rc = RealZwDeviceIoControlFile (
          FileHandle,
          Event,
          ApcRoutine,
          ApcContext,
          IoStatusBlock,
          IoControlCode,
          InputBuffer,
          InputBufferLength,
          OutputBuffer,
          OutputBufferLength
      );
      //判断IoControlcode是不是取序列号的值
      if((0x7c088 ==IoControlCode) && OutputBufferLength >DISK_SERIAL_BUFF_LENGTH){
  
          //判断返回值中是否包含当前的硬盘序列号,是的话用假的替换
          PUCHAR Locate = IsSubString(OutputBuffer,__DiskSerial,OutputBufferLength,DISK_SERIAL_BUFF_LENGTH);
          if(Locate){
              UCHAR i;
              for(i=0;i<20;i++){
                  Locate[i]= __ChangeTo[i];
              }
          }
      }
      return(rc);
  }
  
  
  目前,驱动只处理了简单的几个应用层的消息,包括停止欺骗,开始欺骗,设置新的欺骗值。
  
  BOOLEAN  HDHookDeviceControl( IN PFILE_OBJECT FileObject, IN BOOLEAN Wait,
                                IN PVOID InputBuffer, IN ULONG InputBufferLength,
                                OUT PVOID OutputBuffer, IN ULONG OutputBufferLength,
                                IN ULONG IoControlCode, OUT PIO_STATUS_BLOCK IoStatus,
                                IN PDEVICE_OBJECT DeviceObject ) {
      BOOLEAN                 retval = FALSE;
      ULONG i;
  
      // Its a message from our GUI!
      IoStatus->Status      = STATUS_SUCCESS; // Assume success
      IoStatus->Information = 0;              // Assume nothing returned
  
  
      switch ( IoControlCode ) {
  
      //  开始欺骗
  
      case HDHOOK_HOOK:
          HookStart();
          break;
  
      // 停止欺骗
  
      case HDHOOK_UNHOOK:
          HookStop();
          break;
  
      // 告诉驱动当前自己硬盘的序列号值为多少
  
      case HDHOOK_SETSELFVALUE:
        if( InputBufferLength < DISK_SERIAL_BUFF_LENGTH || InputBuffer == NULL){
          IoStatus->Status = STATUS_INVALID_PARAMETER;
          break;
        }
        for(i=0; i< DISK_SERIAL_BUFF_LENGTH ;i++)
          __DiskSerial[i] = ((UCHAR *)InputBuffer)[i];
  
          break;
  
      // 设置新的欺骗的硬盘序列号
  
      case HDHOOK_SETEMULABLEVALUE:
        if( InputBufferLength < DISK_SERIAL_BUFF_LENGTH || InputBuffer == NULL){
          IoStatus->Status = STATUS_INVALID_PARAMETER;
          break;
        }
  
        for(i=0;i< DISK_SERIAL_BUFF_LENGTH ;i++)
          __ChangeTo[i] = ((UCHAR *)InputBuffer)[i];
  
          break;
  
    //返回驱动的版本号
  
    case HDHOOK_VERSION:
          if ( OutputBufferLength < sizeof(ULONG) ||
               OutputBuffer == NULL ) {
              IoStatus->Status = STATUS_INVALID_PARAMETER;
              break;
          }
  
          *(ULONG *)OutputBuffer = REGMONVERSION;
          IoStatus->Information = sizeof(ULONG);
          break;
  
      default:
          IoStatus->Status = STATUS_INVALID_DEVICE_REQUEST;
          break;
      }
      return TRUE;
  }
  
  
  ////////////////////////////////////////////////
  应用层程序可以通过如下简单代码与驱动进行通信:
  
  #define HDHOOK_HOOK                  (ULONG) CTL_CODE( FILE_DEVICE_REGMON, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS )
  #define HDHOOK_UNHOOK                (ULONG) CTL_CODE( FILE_DEVICE_REGMON, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS )
  #define HDHOOK_VERSION               (ULONG) CTL_CODE( FILE_DEVICE_REGMON, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS )
  #define HDHOOK_SETSELFVALUE          (ULONG) CTL_CODE( FILE_DEVICE_REGMON, 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS )
  #define HDHOOK_SETEMULABLEVALUE      (ULONG) CTL_CODE( FILE_DEVICE_REGMON, 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS )
  
  #define DISK_SERIAL_BUFF_LENGTH      20
  
  //设置新的序列号模拟值
  DeviceIoControl(__SysHandle,HDHOOK_SETEMULABLEVALUE,szEmulSerial,DISK_SERIAL_BUFF_LENGTH, NULL, 0, &dwDummy, NULL) ;
  
  //告诉驱动自己的硬盘序列号
  DeviceIoControl(__SysHandle,HDHOOK_SETSELFVALUE,szBuffer,DISK_SERIAL_BUFF_LENGTH, NULL, 0, &dwDummy, NULL) ;
  
  //开始拦截
  DeviceIoControl(__SysHandle,HDHOOK_HOOK,NULL,0,NULL,0,&dwDummy,NULL) ;
  
  
  //停止拦截
  DeviceIoControl(__SysHandle,HDHOOK_UNHOOK,NULL,0,NULL,0,&dwDummy,NULL) ;
  
  其中__SysHandle是安装驱动的句柄
  
  
  这篇文章的思路来自regmon(regmon版权申明我保留在文件中),写出来是方便调试那些有正版注册号且以硬盘序列号生成注册码的程序,方便一下大家。
  
  附件中包含我写的一个简单的UI,用来与驱动通信。
  
  如果你觉得有用,希望有人能完成如下功能:
  1、进程过滤功能,只对特定程序拦截。
  2、考虑将上面的那个串匹配算法改得高效些,数据结构教材上有现成的:)
  3、那个返回值中有硬盘厂家,磁道数等信息,完成完全模拟,还有IoControlCode 的完善。
  
  若改好了希望能传一份给我 :)
  
  
  
  
  
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年11月29日 12:03:24

[课程]Linux pwn 探索篇!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (65)
雪    币: 452
活跃值: (72)
能力值: ( LV9,RANK:330 )
在线值:
发帖
回帖
粉丝
2
好文!支持一下!
2006-11-29 12:12
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
fxb
3
好文!支持一下!
2006-11-29 12:55
0
雪    币: 210
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
这个学习下
2006-11-29 13:10
0
雪    币: 461
活跃值: (93)
能力值: ( LV9,RANK:1170 )
在线值:
发帖
回帖
粉丝
5
好文,支持一下,拦截应用程序取硬盘物理序列号
2006-11-29 19:40
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢,支持发贴

破分透彻
2006-11-29 20:12
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
好文,学习中。。
2006-11-29 23:58
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
支持高手可以开发出来一个这样的程序。
2006-11-30 08:22
0
雪    币: 405
活跃值: (10)
能力值: ( LV9,RANK:1130 )
在线值:
发帖
回帖
粉丝
9
嘿嘿,很多软件都以硬盘序号为基础做保密工作。如果楼主这个功能能集成在OD里面。那不就....
2006-11-30 09:09
0
雪    币: 441
活跃值: (149)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
10
最初由 binbinbin 发布
嘿嘿,很多软件都以硬盘序号为基础做保密工作。如果楼主这个功能能集成在OD里面。那不就....


是哦,做个插件什么的,可能蛮有意义的
2006-11-30 10:55
0
雪    币: 442
活跃值: (1216)
能力值: ( LV12,RANK:1130 )
在线值:
发帖
回帖
粉丝
11
不错不错,放一个编译好的上来
2006-11-30 11:52
0
雪    币: 67
活跃值: (66)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
12
好东西 编译通过
2006-11-30 12:19
0
雪    币: 441
活跃值: (149)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
13
最初由 baby2008 发布
不错不错,放一个编译好的上来


Driver目录下的源文件要安装DDK,
不过已有编译好的 hdhook.sys在里面,可以不再编译了
2006-11-30 14:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
好东西,试试
2006-11-30 14:31
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jbg
15
好文章,支持楼主
2006-11-30 15:21
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
16
最近在学习逆向分析R0的东西,谢谢楼主的SYS了

既然楼主开源了,某年之后假如我成功逆向分析,楼主不会介意我发篇分析文章吧
2006-11-30 15:22
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
我朋友发了个软件给我,以为俺是个无所不能的电脑高手,其实俺只对电脑应用故障排除在行,根本不会编程。

这个软件由两部分组成 序列号收集器.exe 和 主体.exe

收集器生成一串号码,发给软件作者,作者发送序列号给你,将序列号输入收集器,生成REG.reg注册文件

然后主体检测REG.reg是否正确,如果错误就删除该目录下的全部文件。

架不住朋友的苦苦哀求,只好苦苦哀求各位帮忙看看这种自杀式的注册方式如何破解。

软件下载网址:http://down.880y.com/ShowSoftDown.asp?UrlID=1&SoftID=61
卡巴斯基已经扫描过,没有病毒。
产品信息
产品版本: 6.0.0.307
病毒库发布日期: 06-11-30 12:49:14
病毒库数量: 246832

有需要兄弟帮忙的也请尽管开口,俺是做网页设计工作的,做个主页设计个图片弄个flash都行。

请帮帮忙,我不知道该发到哪里求助!
2006-11-30 19:58
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
楼主看到楼上的回帖请帮忙!

我今天的发帖权都用完了~~

我看你应该能做到吧,这么有难度的技术都能研究肯定对硬盘序列号算注册码有能力做到。

看到就顶一下哦
2006-11-30 20:02
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
看到一定要顶一下告诉我能否轻而易举搞定
2006-11-30 20:04
0
雪    币: 441
活跃值: (149)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
20
最初由 笨笨雄 发布
最近在学习逆向分析R0的东西,谢谢楼主的SYS了

既然楼主开源了,某年之后假如我成功逆向分析,楼主不会介意我发篇分析文章吧


祝逆向早日成功,发出来我们也好学习学习!
2006-11-30 22:04
0
雪    币: 146
活跃值: (72)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
支持开源!期待早日弄出OD插件.
2006-11-30 22:45
0
雪    币: 441
活跃值: (149)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
22
最初由 nixing 发布
看到一定要顶一下告诉我能否轻而易举搞定


没有在网上随便下载的习惯,比较烦各类插件,病毒什么的。一般有垃圾插件我就GHOST恢复。

你那个是加了asprotect壳(Version: ASProtect 2.3 SKE build 06.26 Beta [Extract]) 然后又加了一个压缩壳,压缩壳比较好搞,一路往下走,到401000 DUMP,ASP你可以用volx大侠的脚本试试。

我帮不了忙了
2006-11-30 23:46
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
最初由 rockhard 发布
没有在网上随便下载的习惯,比较烦各类插件,病毒什么的。一般有垃圾插件我就GHOST恢复。

你那个是加了asprotect壳(Version: ASProtect 2.3 SKE build 06.26 Beta [Extract]) 然后又加了一个压缩壳,压缩壳比较好搞,一路往下走,到401000 DUMP,ASP你可以用volx大侠的脚本试试。

我帮不了忙了


首先感谢rockhard回帖和帮助(我不懂编程脱了壳我也搞不定啊)

我也对垃圾插件极其反感,但是你用ghost对付插件的方法我觉得不太好,推荐你使用卡巴斯基和360,卡巴在“设置”→“保护”→“风险软件种类”把两个选项都打√,使用360的插件免疫和插件卸载功能很容易就将插件避之门外(有人说360流氓,但据我的使用感受这个不到1M的小软件没有什么恶行,而且使用一次后卸载即可。)

经常使用电脑肯定经常装一些程序,如果ghost的话又要重装一些设置也无法保留。
2006-12-1 09:52
0
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
24
那我只好写个驱动直接IO了。你不会再去拦截IO吧
2006-12-1 13:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
fxb
25
好文,支持一下,拦截应用程序取硬盘物理序列号
2006-12-1 17:38
0
游客
登录 | 注册 方可回帖
返回
//