首页
社区
课程
招聘
[旧帖] 如何使用native api 删除正在运行进程的文件? 0.00雪花
发表于: 2013-8-17 20:50 9839

[旧帖] 如何使用native api 删除正在运行进程的文件? 0.00雪花

2013-8-17 20:50
9839
如何使用native api 删除正在运行进程的文件?不能使用注入、驱动等方法。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (17)
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
UnmapViewOfSection好像可以
2013-8-17 22:55
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
三步走
先把所有句柄复制到本进程
枚举占用文件的所有句柄
关闭
2013-8-17 23:01
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼主想删的是进程的可执行文件,还是打开的数据文件呢
2013-8-17 23:10
0
雪    币: 4
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
还不知道,学习学习。。
2013-8-18 00:09
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
都是一样的三步走
2013-8-18 00:28
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
模块根本就没有句柄,怎么关闭?
2013-8-18 00:53
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
唉……你去仔细看看书吧……
我指的是关闭被独占的文件句柄

这个跟是不是模块无关
2013-8-18 20:33
0
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
关闭可执行文件
2013-8-19 13:28
0
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
UnmapViewOfSection  需要执行远程线程。不行啊
2013-8-19 13:54
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
        DWORD dwPid = 8972;
        ZwUnmapViewOfSection = (PZwUnmapViewOfSection)GetProcAddress( GetModuleHandle("ntdll.dll"), "ZwUnmapViewOfSection");
        HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, false, dwPid);
        ZwUnmapViewOfSection( hProcess, (PVOID)0x400000);

卸载过后进程会出错哦
2013-8-19 14:39
0
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
问题是我要删除这个进程的可执行文件,之后NtDeleteFile可以?
2013-8-20 13:56
0
雪    币: 0
活跃值: (255)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
将文件解锁就行了,关键字:文件解锁
2013-8-22 10:47
0
雪    币: 4
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
unlocker
貌似有开源的unlocker,你可以看看怎么弄的
2013-8-22 21:54
0
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
谢谢各位 题目可能没说清楚,应该是正在运行的进程删除自己  自删除技术
2013-8-23 05:24
0
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
这是我从查找资料得到的信息
1.得到目标进程的pid(这个容易吧?),然后ZwQuerySystemInformation枚举系统中所有句柄,然后判断类型是文件且属于目标进程的(由pid判断)
2.判断是否独占我不清楚,强行关闭可以ZwDuplicateObject,注意最后一个参数使用DUPLICATE_CLOSE_SOURCE,到本进程以后再ZwClose就可以了。

ps:最近在玩Native API,所以前面提到的函数都是Native的~~

通过ZwCreateFile把文件锁定;删除时报告“文件正在使用,禁止删除”,具体原理自己摸索吧,反正是通过ZwCreateFile实现的!

有什么方法可以删除呢?
   step1 :通过QuerySystemInformation(SystemHandleInformation)得到当前系统的所有句柄信息
   step2 :遍历当前所有进程,根据进程ID,得到此进程打开的所有句柄信息
   Step3 :把句柄发送给我们的驱动程序,驱动程序根据ObQueryNameString得到句柄的路径信息,然后再传给我们的应用程序
Step4 :如果是我们要删除文件的路径,应用程序调用DuplicateHandle(DUPLICATE_CLOSE_SOURCE),句柄被关闭了,现在可以删除文件了!
   注:QuerySystemInformation的使用说明见The Undocumented Functions,或者http://undocumented.ntinternals.net,第三种解除文件锁定的方法是我反汇编Unlock软件学习到的

好了UnlockerHook.dll的代码就分析到这里,为了把问题说清楚还是贴了不少的汇编代码,真是占篇幅啊。总结一下UnlockerHook.dll的功能就是通过CBT钩子来植入每个进程的方式来打入exploer.exe,通过inlinehook SHFileOperationW的方式来挂钩,只要该函数执行返回错误,通过识别不同的错误码来判断是否需要调用unlocker程序,并通过ShellExecuteExW的方式来触发unlocker程序。
说了半天我们还是没有触及unlocker的核心功能,下面我们就来分析。
Unlocker.EXE的工作原理
对于该程序的工作原理,这里先概述一下,首先通过ZwQuerySystemInformation函数得到系统内所有的句柄信息以及其所在的进程信息,然后通过NtLoaddriver来加载驱动(UnlokerDriver5.sys),并写入注册表信息等,使用驱动在内核层得到句柄的名字,并和目标文件命核对,最终定位到占有该句柄,也就是占有该文件的进程;而进程的名字是通过toolhelp类函数,并辅以EnumProcessModules来得到(枚举的第一个模块句柄就是进程自身,再通过GetModuleFileNameEx来得到全路径名)。
好了,只要找到了占用文件的进程,事情就好办了。对于"过程结束"命令,就是使用TerminateProcess来干掉进程。对于解锁,分为两类,如果是DLL文件,则通过远程线程注入来FreeLibrary而解锁文件;否则更简单,通过Duplicatehandle,使用参数DUPLICATE_CLOSE_SOURCE来关闭目标进程里的句柄,这样文件就解锁了。对于拷贝的操作,则是通过远程线程注入,在目标进程里读写文件来完成的。值得一提的是,这种方式是有问题的,因为远程线程和本地线程使用同一个文件句柄操作文件,这样文件指针就会乱掉,虽然远程线程使用OVERLAPPED结构来指定文件偏移避免了拷贝数据乱的情况,从而保证了自己的拷贝工作能顺利完成,但是本地线程的指针是肯定要乱掉的,这对本地线程是致命的!!
移动文件是通过MoveFileEx来实现,如果不能成功则会提示是否在下次启动系统后移动,这是通过MOVEFILE_DELAY_UNTIL_REBOOT标志来实现的,其它文件操作则是通过SHFileOperationW来实现的。

VOID CloseMyHandles(ULONG ProcessId)
{
    NTSTATUS ntStatus;
    BOOLEAN wasEnabled;
    PVOID Buffer = NULL;
    DWORD BufferSize = 0x10000, NeedSize = 0;
    HANDLE TargetProcess = INVALID_HANDLE_VALUE;
    HANDLE hOwnerProcess;
    HANDLE hProcess;
    PSYSTEM_HANDLE_INFORMATION Handles = NULL;
    PSYSTEM_HANDLE_TABLE_ENTRY_INFO HandleEntry = NULL;
    OBJECT_ATTRIBUTES objatr = {sizeof(OBJECT_ATTRIBUTES), 0, NULL, NULL};
    CLIENT_ID ClientId;

    RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &wasEnabled);

    ClientId.UniqueProcess = (HANDLE)ProcessId;
    ClientId.UniqueThread  = 0;

_Retry:
    Buffer = GlobalAlloc(GPTR, BufferSize);
    if (Buffer == NULL)  return ;
    ntStatus = ZwQuerySystemInformation(SystemHandleInformation,
                                        Buffer,
                                        BufferSize,
                                        &NeedSize);

    if (ntStatus == STATUS_INFO_LENGTH_MISMATCH) {
        GlobalFree(Buffer);
        BufferSize = NeedSize;
        goto _Retry;
    }

    Handles = (PSYSTEM_HANDLE_INFORMATION)Buffer;
    HandleEntry = &(Handles->Handles[0]);

    for (ULONG i = 0; i < Handles->NumberOfHandles; i++, HandleEntry++)
    {
        if (HandleEntry->ObjectTypeIndex != OB_TYPE_PROCESS)  continue;

        ClientId.UniqueProcess = (HANDLE)HandleEntry->UniqueProcessId;
        ClientId.UniqueThread  = 0;

        ntStatus = ZwOpenProcess(&hOwnerProcess,
                                 PROCESS_DUP_HANDLE,
                                 &objatr,
                                 &ClientId);

        if (!NT_SUCCESS(ntStatus))  continue;

        ntStatus = ZwDuplicateObject(hOwnerProcess,
                                     (HANDLE)HandleEntry->HandleValue,
                                     NtCurrentProcess(),
                                     &hProcess,
                                     PROCESS_ALL_ACCESS,
                                     FALSE,
                                     DUPLICATE_SAME_ACCESS);

        if (NT_SUCCESS(ntStatus)) {

            PROCESS_BASIC_INFORMATION BasicInfo = {0};
            ntStatus = ZwQueryInformationProcess(hProcess,
                                                 ProcessBasicInformation,
                                                 &BasicInfo,
                                                 sizeof(BasicInfo),
                                                 NULL);
            if (NT_SUCCESS(ntStatus)) {

                if (BasicInfo.UniqueProcessId == ProcessId) {

                    ntStatus = ZwDuplicateObject(hOwnerProcess,
                                                 (HANDLE)HandleEntry->HandleValue,
                                                 NtCurrentProcess(),
                                                 &TargetProcess,
                                                 PROCESS_ALL_ACCESS,
                                                 FALSE,
                                                 DUPLICATE_CLOSE_SOURCE);

                    if (NT_SUCCESS(ntStatus))  ZwClose(TargetProcess);
                }
            }
            ZwClose(hProcess);
        }
        ZwClose(hOwnerProcess);
    }
    if (Buffer)  GlobalFree(Buffer);
}
我的终极目标是进程a.exe 删除文件C:\a.exe,不实用批处理、驱动、线程注入,就用native api
2013-8-23 05:47
0
雪    币: 19
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
不行吧  所有句柄不包含可执行文件打开的句柄吧
2013-8-28 14:44
0
雪    币: 11
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
包括的

你自己获取一下所有句柄然后把他们的句柄名打印出来就知道了
2013-8-28 14:53
0
游客
登录 | 注册 方可回帖
返回
//