首页
论坛
专栏
课程

[原创]ring3 下挂钩Native API 简单实现文件防删除

2007-6-1 09:48 17191

[原创]ring3 下挂钩Native API 简单实现文件防删除

2007-6-1 09:48
17191
简单实现文件防删除,说简单是因为没有用很底层的技术,例如文件驱动之类。我只用最简单的方法实现了, 使用 ring3 的API hook 技术。
随着技术的发展这种技术已经过不了很多的主动防御技术了。主要是思路和方法和分析过程。(高手飘过)

ring3 下挂钩 API 基本上也就是修改导入表,和Inline hook 修改前5个字节这几种方法。挂钩Native API 没有什么区别,也就是多声明几个结构和变量类型。关于挂钩API 请参见:www.xfocus.net/articles/200403/681.html

文件删除的ring3 API 是DeleteFile, 此API 存在于kernel32.dll 中,用OD分析一下。(哪个都可以,IDA更不用说)

DeleteFileA 的反汇编代码:

7C80D2FB >/$  8BFF          mov     edi, edi
7C80D2FD  |.  55            push    ebp
7C80D2FE  |.  8BEC          mov     ebp, esp
7C80D300  |.  FF75 08       push    dword ptr [ebp+8]
7C80D303  |.  E8 17790100   call    7C824C1F
7C80D308  |.  85C0          test    eax, eax
7C80D30A  |.  74 08         je      short 7C80D314
7C80D30C  |.  FF70 04       push    dword ptr [eax+4]                ; /FileName
7C80D30F  |.  E8 3D170000   call    DeleteFileW                      ; \DeleteFileW
7C80D314  |>  5D            pop     ebp
7C80D315  \.  C2 0400       retn    4

可以得到一个流程 DeleteFileA --> DeleteFileW

DeleteFileW 的反汇编代码:

7C80EA51 > $  8BFF          mov     edi, edi
7C80EA53   .  55            push    ebp
7C80EA54   .  8BEC          mov     ebp, esp
7C80EA56   .  83EC 50       sub     esp, 50
7C80EA59   .  56            push    esi
7C80EA5A   .  8D45 C8       lea     eax, dword ptr [ebp-38]
7C80EA5D   .  50            push    eax
7C80EA5E   .  33F6          xor     esi, esi
7C80EA60   .  56            push    esi
7C80EA61   .  8D45 E0       lea     eax, dword ptr [ebp-20]
7C80EA64   .  50            push    eax
7C80EA65   .  FF75 08       push    dword ptr [ebp+8]
7C80EA68   .  C645 FF 00    mov     byte ptr [ebp-1], 0
7C80EA6C   .  FF15 5411807C call    dword ptr [<&ntdll.RtlDosPathNam>;  ntdll.RtlDosPathNameToRelativeNtPathName_U
7C80EA72   .  84C0          test    al, al
7C80EA74   .  0F84 FBCC0200 je      7C83B775
7C80EA7A   .  8B45 E4       mov     eax, dword ptr [ebp-1C]
7C80EA7D   .  8945 F4       mov     dword ptr [ebp-C], eax
7C80EA80   .  8B45 C8       mov     eax, dword ptr [ebp-38]
7C80EA83   .  66:3BC6       cmp     ax, si
7C80EA86   .  0F85 E9660200 jnz     7C835175
7C80EA8C   .  8975 D0       mov     dword ptr [ebp-30], esi
7C80EA8F   >  8B45 D0       mov     eax, dword ptr [ebp-30]
7C80EA92   .  53            push    ebx
7C80EA93   .  57            push    edi
7C80EA94   .  8945 B4       mov     dword ptr [ebp-4C], eax
7C80EA97   .  8D45 E0       lea     eax, dword ptr [ebp-20]
7C80EA9A   .  8945 B8       mov     dword ptr [ebp-48], eax
7C80EA9D   .  BF 40402000   mov     edi, 204040
7C80EAA2   .  57            push    edi
7C80EAA3   .  6A 07         push    7
7C80EAA5   .  8D45 E8       lea     eax, dword ptr [ebp-18]
7C80EAA8   .  50            push    eax
7C80EAA9   .  8D45 B0       lea     eax, dword ptr [ebp-50]
7C80EAAC   .  50            push    eax
7C80EAAD   .  68 80000100   push    10080                            ;  UNICODE "ocuments and
7C80EAB2   .  8D45 F8       lea     eax, dword ptr [ebp-8]
7C80EAB5   .  8975 C0       mov     dword ptr [ebp-40], esi
7C80EAB8   .  8975 C4       mov     dword ptr [ebp-3C], esi
7C80EABB   .  8B35 1410807C mov     esi, dword ptr [<&ntdll.NtOpenFi>;  ntdll.ZwOpenFile
7C80EAC1   .  50            push    eax
7C80EAC2   .  C745 B0 18000>mov     dword ptr [ebp-50], 18
7C80EAC9   .  C745 BC 40000>mov     dword ptr [ebp-44], 40
7C80EAD0   .  FFD6          call    esi                              ;  <&ntdll.NtOpenFile>
7C80EAD2   .  8BD8          mov     ebx, eax
7C80EAD4   .  85DB          test    ebx, ebx
7C80EAD6   .^ 0F8C F5F4FFFF jl      7C80DFD1
7C80EADC   .  6A 23         push    23                               ; /InfoClass = FileAttributeTagInformation
7C80EADE   .  6A 08         push    8                                ; |Bufsize = 8
7C80EAE0   .  8D45 D8       lea     eax, dword ptr [ebp-28]          ; |
7C80EAE3   .  50            push    eax                              ; |Buffer
7C80EAE4   .  8D45 E8       lea     eax, dword ptr [ebp-18]          ; |
7C80EAE7   .  50            push    eax                              ; |pStatusBlock
7C80EAE8   .  FF75 F8       push    dword ptr [ebp-8]                ; |hFile
7C80EAEB   .  FF15 1810807C call    dword ptr [<&ntdll.NtQueryInform>; \ZwQueryInformationFile
7C80EAF1   .  8BD8          mov     ebx, eax
7C80EAF3   .  85DB          test    ebx, ebx
7C80EAF5   .  0F8C D5CC0200 jl      7C83B7D0
7C80EAFB   .  8B45 D8       mov     eax, dword ptr [ebp-28]
7C80EAFE   .  25 00040000   and     eax, 400
7C80EB03   .  0F85 0ECD0200 jnz     7C83B817
7C80EB09   >  85C0          test    eax, eax
7C80EB0B   .  0F85 1CCD0200 jnz     7C83B82D
7C80EB11   >  8D45 C8       lea     eax, dword ptr [ebp-38]
7C80EB14   .  50            push    eax
7C80EB15   .  FF15 5011807C call    dword ptr [<&ntdll.RtlReleaseRel>;  ntdll.RtlReleaseRelativeName
7C80EB1B   .  FF75 F4       push    dword ptr [ebp-C]
7C80EB1E   .  64:A1 1800000>mov     eax, dword ptr fs:[18]
7C80EB24   .  8B40 30       mov     eax, dword ptr [eax+30]
7C80EB27   .  6A 00         push    0
7C80EB29   .  FF70 18       push    dword ptr [eax+18]
7C80EB2C   .  FF15 1010807C call    dword ptr [<&ntdll.RtlFreeHeap>] ;  ntdll.RtlFreeHeap
7C80EB32   .  6A 0D         push    0D                               ; /InfoClass = FileDispositionInformation
7C80EB34   .  6A 01         push    1                                ; |Bufsize = 1
7C80EB36   .  8D45 0B       lea     eax, dword ptr [ebp+B]           ; |
7C80EB39   .  50            push    eax                              ; |Buffer
7C80EB3A   .  8D45 E8       lea     eax, dword ptr [ebp-18]          ; |
7C80EB3D   .  50            push    eax                              ; |pStatusBlock
7C80EB3E   .  FF75 F8       push    dword ptr [ebp-8]                ; |hFile
7C80EB41   .  C645 0B 01    mov     byte ptr [ebp+B], 1              ; |
7C80EB45   .  FF15 3010807C call    dword ptr [<&ntdll.NtSetInformat>; \ntdll.ZwSetInformationFile
7C80EB4B   .  FF75 F8       push    dword ptr [ebp-8]                ; /Handle
7C80EB4E   .  8BF0          mov     esi, eax                         ; |
7C80EB50   .  FF15 3810807C call    dword ptr [<&ntdll.NtClose>]     ; \ZwClose
7C80EB56   .  85F6          test    esi, esi
7C80EB58   .^ 0F8C 1F91FFFF jl      7C807C7D
7C80EB5E   .  33C0          xor     eax, eax
7C80EB60   .  40            inc     eax
7C80EB61   >  5F            pop     edi
7C80EB62   .  5B            pop     ebx
7C80EB63   >  5E            pop     esi
7C80EB64   .  C9            leave
7C80EB65   .  C2 0400       retn    4

得到一个流程 DeleteFileA --> DeleteFileW --> ntdll.ZwSetInformationFile,因此我们只要挂钩了ZwSetInformationFile 就可以简单实现目标了。这里写出了新的 ZwSetInformationFile 函数。

typedef LONG NTSTATUS;
#define STATUS_SUCCESS               ((NTSTATUS)0x00000000L)
#define STATUS_ACCESS_DENIED         ((NTSTATUS)0xC0000022L)
#define STATUS_INFO_LENGTH_MISMATCH  ((NTSTATUS)0xC0000004L)

typedef struct _IO_STATUS_BLOCK {
DWORD Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef enum _FILE_INFORMATION_CLASS {
// end_wdm
   FileDirectoryInformation       = 1,
   FileFullDirectoryInformation, // 2
   FileBothDirectoryInformation, // 3
   FileBasicInformation,         // 4  wdm
   FileStandardInformation,      // 5  wdm
   FileInternalInformation,      // 6
   FileEaInformation,            // 7
   FileAccessInformation,        // 8
   FileNameInformation,          // 9
   FileRenameInformation,        // 10
   FileLinkInformation,          // 11
   FileNamesInformation,         // 12
   FileDispositionInformation,   // 13
   FilePositionInformation,      // 14 wdm
   FileFullEaInformation,        // 15
   FileModeInformation,          // 16
   FileAlignmentInformation,     // 17
   FileAllInformation,           // 18
   FileAllocationInformation,    // 19
   FileEndOfFileInformation,     // 20 wdm
   FileAlternateNameInformation, // 21
   FileStreamInformation,        // 22
   FilePipeInformation,          // 23
   FilePipeLocalInformation,     // 24
   FilePipeRemoteInformation,    // 25
   FileMailslotQueryInformation, // 26
   FileMailslotSetInformation,   // 27
   FileCompressionInformation,   // 28
   FileObjectIdInformation,      // 29
   FileCompletionInformation,    // 30
   FileMoveClusterInformation,   // 31
   FileQuotaInformation,         // 32
   FileReparsePointInformation,  // 33
   FileNetworkOpenInformation,   // 34
   FileAttributeTagInformation,  // 35
   FileTrackingInformation,      // 36
   FileMaximumInformation
// begin_wdm
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;

typedef struct _FILE_NAME_INFORMATION {  
        ULONG  FileNameLength;  
        WCHAR  FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;

typedef NTSTATUS (__stdcall *ZWQUERYINFORMATIONFILE)(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass
);

ZWQUERYINFORMATIONFILE ZwQueryInformationFile;

NTSTATUS __stdcall Hook_ZwSetInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG FileInformationLength,
IN FILE_INFORMATION_CLASS FileInformationClass)
{
        NTSTATUS ntstatus = STATUS_ACCESS_DENIED;

        HMODULE hNtdll = GetModuleHandle("ntdll.dll");
        ZwQueryInformationFile = (ZWQUERYINFORMATIONFILE)GetProcAddress(hNtdll, "ZwQueryInformationFile");

        IO_STATUS_BLOCK  ioStatus;
        FILE_NAME_INFORMATION * psi = {0};

        psi = (FILE_NAME_INFORMATION*)new WCHAR[sizeof(FILE_NAME_INFORMATION) + 1024];
        memset(psi, 0, (sizeof(FILE_NAME_INFORMATION) + 1024)*2);
        psi->FileNameLength = 1024;

        ntstatus = ZwQueryInformationFile(FileHandle, &ioStatus, psi, sizeof(FILE_NAME_INFORMATION) + 1024 * sizeof(WCHAR), FileNameInformation);

        if (ntstatus != STATUS_SUCCESS)
                PrintZwError("ZwQueryInformationFile", ntstatus);

        ntstatus = STATUS_ACCESS_DENIED;
       
        if( wcsstr(psi->FileName, L"b.txt") == NULL)
     ntstatus = ((PFZWSETINFORMATIONFILE)(PROC)g_ZwSetInformationFile)(FileHandle,IoStatusBlock,FileInformation,FileInformationLength,FileInformationClass);

        delete psi;
        return ntstatus;

}

这只是一个证明性代码,要实战的兄弟自己动点手吧。

[公告][征集寄语] 看雪20周年年会(12.28上海) | 感恩有你,一路同行

最新回复 (15)
NaX 2007-6-1 11:55
2
0
文章不错 支持一下
foxabu 13 2007-6-2 01:03
3
0
换作我 直接以独占方式打开  就无法删除了。
xPLK 3 2007-6-2 10:49
4
0
值得我这样的菜鸟学习。
rick 7 2007-6-2 11:31
5
0
ring 3 下全局 hook?
只hook 一个程序没有效吧
llydd 9 2007-6-2 11:33
6
0
学习了,,,,,,,,,,,
点点 2007-6-3 01:23
7
0
ring3下??可是hook native api不就得用到驱动了吗?
bithaha 5 2007-6-3 13:28
8
0
文件夹加密超级大师 他安装目录下的所有文件都不能删除,不能重命名,但是能改pe文件。
fhwclq 2007-6-4 17:22
9
0
很多V用了以上的所有方法以,但还 是可以用I/O操删。
lmgz 2007-6-18 23:38
10
0
俺不知道用vb怎么hook啊,谁可以赐教啊?
Skyforce 2007-6-19 17:04
11
0
很是受益,多谢楼主的分享。
vfer 2007-6-20 21:43
12
0
这不是RING3吧   都用到驱动了
王仁军 10 2007-9-18 09:35
13
0
学习学习        
kagayaki 2007-9-20 17:23
14
0
收藏了!!!!
小覃 2 2011-5-3 19:33
15
0
学习下,谢谢分享!
Tensm 1 2013-3-15 12:01
16
0
mark,谢谢楼主分享!
游客
登录 | 注册 方可回帖
返回