|
一、引入
凡事总喜欢刨根问底,一直问自己为什么,问到实在没什么可问了为止,当然也有问到自己是在懒得再问了为止的时候。因为一个软件的自动更新老出问题,有时候出现无法自动更新,分析后发现原来是在替换正在运行的程序时出了问题。无知的我就开始对替换正在运行中的程序的方法进行分析。
虽大言不惭自称深入浅出,其实只不过对一个问题想深入进去,分析到自己因技术不佳无法继续分析的时候,浅浅的出来而已。但是仍旧希望这篇文章能够对和我一样思考这个问题的人有一点点帮助。
言归正传,首先从xfocus的bgate的文章《在Win2000/XP上安静地替换正在使用的系统文件》中获得启发。
他对替换正在使用的系统文件进行了研究,分析了微软的一个工具zap,这个工具可以替换系统文件。经过分析后,这个工具其实是先把正在使用的文件移动到一个临时目录中去,然后再把这个文件删除,但是标记为下次启动的时候删除。此时系统文件目录已经腾出了空间,这样再把新的文件移动过来就可以了。
实现部分代码示意如下:
if(szFileToDel[1] == ’:’){
sprintf(cTempPathName, "%c:\\", szFileToDel[0]);
}
else{
GetModuleFileName(NULL, cFileName, 0x100);
sprintf(cTempPathName, "%c:\\", cFileName[0]);
}
if(GetTempFileName(cTempPathName, "_@", 0, cTempFileName) == 0) return FALSE;
if(MoveFileEx(szFileToDel, cTempFileName, MOVEFILE_REPLACE_EXISTING) == 0) return FALSE;
if(MoveFileEx(cTempFileName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) == 0) return FALSE;
if(MoveFileEx(szSrcFile, cTempPathName) == 0) return FALSE;
其中
winbase.h:
#define MOVEFILE_REPLACE_EXISTING 0x00000001
#define MOVEFILE_COPY_ALLOWED 0x00000002
#define MOVEFILE_DELAY_UNTIL_REBOOT 0x00000004
#define MOVEFILE_WRITE_THROUGH 0x00000008
二、MoveFileEx分析
为了了解MoveFileEx()到底是如何在下次重新启动的时候进行的文件移动操作的,我查阅了操作系统源代码。
1、MoveFileEx()实际上是调用的MoveFileWithProgressW(),只不过NULL了两个回调参数。
2、MoveFileWithProgressW()中针对dwFlag=MOVEFILE_DELAY_UNTIL_REBOOT的,调用了BasepMoveFileDelayed()函数
3、BasepMoveFileDelayed()是通过修改注册表的方法,让操作系统重新启动时进行文件操作的。
它修改的键值是
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations
这是一个REG_MULTI_SZ的键值。
格式是:
szDstFile\0\0
szSrcFile\0szDstFile\0\0
szSrcFile\0!szDstFile\0\0
有些文章中所说的源文件和目标文件中间是换行,这并不是最合理的,虽然也可以,中间是Unicode的\0,也就是 00 00
而且需要注意的是,如果指定了MOVEFILE_REPLACE_EXISTING属性的话,目标文件前会加注一个叹号。
这个键值我是在分析完源代码后,才发现原来MSDN中已经给出这个键值了。
后来我打开我的这个键值,发现里面有一堆,还没有来得及删除的文件,在等着我下一次重新启动的时候删除呢。
根据关于MOVEFILE_DELAY_UNTIL_REBOOT的解释,操作系统会在系统重新启动的时候,在Autochk检查完成后,并且在建立任何PageFile文件之前,立即进行指定的文件移动。而且要确保所要操作的文件能够被LocalSystem或者管理员组所操作。
我同时也注意到了另外一个我不熟悉的问题,就是为什么文件被移动了,但是应用程序还可以继续执行,而删除则不行。我没有细考虑这个问题,但是我感觉一定是有什么东西没有变化,比如某种链接。虽然位置变了,但是链接依旧能够跟踪到映像的位置,所以所有指向该链接的操作都是生效的。但是删除文件的时候,该链接就会被删除,从而会导致操作失败,为了避免这种失败,所以禁止删除正在被占用的文件。
| 没有路由密码权限时的鸽子上线方 | 08-23 |
| 完全解析网页后门和挂马 | 04-02 |
| 真实的网络攻击取证纪实 | 03-27 |
| 利用404错误页面挂马 | 03-21 |
| 解密风暴 | 03-21 |
| 社会工程学在黑客中的应用 | 01-02 |
| 轻轻松松解密各种网页木马 | 12-21 |
| SA权限无xp_cmdshell时取权限又一 | 12-14 |
| sqlserver2005中恢复xp_cmdshell | 11-10 |
| 实现无net.exe和net1.exe添加系统 | 10-26 |
| 用U盘轻松去除XP管理员密码 | 10-26 |
| 教你多种保护措施限用移动硬盘 | 10-09 |