• 网络学院
  • IT资讯
  • 操作系统
  • 网络技术
  • 软件应用
  • 办公软件
  • 编程技术
  • 网站架设
  • 数据库类
  • 平面设计
  • 多媒体类
  • 游戏资讯
  • 教学论文
  • 认证考试
在Win2000/XP上安静地替换正在使用的系统文件
  站点:
  • 首 页
  • 最新软件
  • 文章教程
  • 国内软件
  • 国外软件
  • 绿色软件
  • 源码下载
  • 字体下载
在Win2000/XP上安静地替换正在使用的系统文件
软件发布 在Win2000/XP上安静地替换正在使用的系统文件
网络软件 系统工具 应用软件 联络聊天 图形图像 多媒体类 行业软件 游戏娱乐 编程开发 安全相关 教育教学 数码软件 绿软下载
热门软件: QQ 瑞星 pplive e话通 木马克星 千千静听 office2000 五笔字根 Photoshop 视频分割
返回文章教程首页 >> 操作系统 >> WINDOWS >> Windows XP >> 在Win2000/XP上安静地替换正在使用的系统文件

在Win2000/XP上安静地替换正在使用的系统文件

添加时间: 2005-6-4 4:59:22  作者: 网络收集  阅读次数:66   来源: http://d9soft.com

       

    总是索而不敷总有些过意不去.另外在安焦上灌了两年水竟然安焦文档还找不到一个我的名字. 灌不出篇精华帖子还回复不到别人灌的精华贴. 也算得上是个奇迹了.

  要安静地替换正在使用的系统文件要解决两个问题:
  1. 替换正在使用的文件.
  2. 在替换系统文件时不显示插CD的对话框.

  微软有两个工具可以替换正在使用的文件,zap和inuse. 不过都没有源代码, 只好逆向分析了. inuse比较大40K, zap很小7K. 就分析zap了.

用ida打开zap. 就有一个核心函数, 原来它的工作原理是把这个文件移了下位置, 因为比较简单就直接贴上代码.

-------------------cut zap.c---------
#include <Windows.h>

BOOL ZapDelFile(char *szFileToDel)
{
    char cTempFileName[0x80];
    char cTempPathName[0x100];
    char cFileName[0x100];

    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, 1) == 0){
        return FALSE;
    }

    if(MoveFileEx(cTempFileName, NULL, 4) == 0){
        return FALSE;
    }

    return TRUE;
}

void usage(char *n) {
    printf("usage: %s fileNeedToDeln", n);
    exit(0);
}

int main(int argc, char* argv[])
{

    printf("Zap programed by bgate. :) *nn");

    if (argc != 2)
        usage(argv[0]);

    if(ZapDelFile(argv[1]) == TRUE){
        printf("OK");
    }
    else{
        printf("error %d", GetLastError());
    }
    return 0;
}

-------------------end cat-----------

现在你已经可以用它去删除正在使用的系统文件了, 不过删除之后会弹出让你插入Windows CD对话框.
注意: 删系统文件前做好备份, 在重启前恢复, 另外删系统文件前还需要把dllcache中相应的备份删除. 否则系统会自动恢复.

接下来就想办法去掉这个对话框, 拿出我的法宝--google. 胡乱地搜了一气. 搜到两条有用信息.
1.Windows 2000下执行系统文件保护的代码在sfc.dll中, Xp系统下在sfc_os.dll中.
2.注册表中把一个叫SfcDisable的键设为FFFFFF9D能在下次启动时让文件保护功能失效.

下面的分析是在Win2K sp4+上进行的. 其中分析的sfc.dll版本是5.0.2195.6673

    用ida打开sfc.dll在string中找sfcdisable, 没找到! 让string显示Unicode. 这下看到了. 找到对SfcDisable引用的一个地方.代码如下
.text:769269F9                 call     _SfcQueryRegDwordWithAlternate@16 ; SfcQueryRegDwordWithAlternate(x,x,x,x)
.text:769269FE                 push     ebx
.text:769269FF                 push     offset ??_C@_1BG@HOGG@?$AAS?$AAf?$AAc?$AAD?; "SfcDisable"
.text:76926A04                 push     edi
.text:76926A05                 push     esi
.text:76926A06                 mov     _SFCDebug, eax
.text:76926A0B                 call     _SfcQueryRegDwordWithAlternate@16 ; SfcQueryRegDwordWithAlternate(x,x,x,x)
.text:76926A10                 push     ebx
.text:76926A11                 push     offset ??_C@_1BA@HLJH@?$AAS?$AAf?$AAc?$AAS?$AAc?$AAa?$AAn?$AA?$AA@ ; "SfcScan"
.text:76926A16                 push     edi
.text:76926A17                 push     esi
.text:76926A18                 mov     _SFCDisable, eax
.text:76926A1D                 call     _SfcQueryRegDwordWithAlternate@16 ; SfcQueryRegDwordWithAlternate(x,x,x,x)
.text:76926A22                 push     ebx
.text:76926A23                 push     offset ??_C@_1BC@KFAJ@?$AAS?$AAf?$AAc?$AAQ?$AAu?$AAo?$AAt?$AAa?$AA?$AA@ ; "SfcQuota"
.text:76926A28                 push     edi
.text:76926A29                 push     esi
.text:76926A2A                 mov     _SFCScan, eax

    其中_SfcQueryRegDwordWithAlternate@16是读注册表的函数. 很明显, 它把注册表中SfcDisable的值读到了_SFCDisable中. 好, 调出softice. 在_SFCDisable上设断点. 我们又用刚写的zap去删系统文件, softice弹出来了. 断到了下面这个地方, eip为7692A326, _SFCDisable为2.
.text:7692A319                 push     ecx
.text:7692A31A                 and     [esp+4+var_4], 0
.text:7692A31F                 cmp     _SFCDisable, 3
.text:7692A326                 push     ebx
.text:7692A327                 push     ebp
.text:7692A328                 push     esi
.text:7692A329                 push     edi
.text:7692A32A                 jnz     short loc_7692A333
.text:7692A32C                 xor     eax, eax
.text:7692A32E                 jmp     loc_7692A459
    F5退出, 一会儿对话框弹了出来, 就对这儿引用了一次. 很好, 看看上面这段代码"cmp _SFCDisable, 3". 此时_SFCDisable为2弹出了对话框, 那么我就把它改为3又用zap删系统文件试试. 哈, 运气很好, 这次没出现让插CD的对话框了. 也就是说只要我们把_SFCDisable改为3就能偷偷地替换系统文件了. 不过不同版本这个地址是不一样的, 用switch来做这个活总是不好. 得写个有通用性的代码.

    开始我想它的工作原理大概是Winlogon发现了有对系统文件进行操作. 便调用sfc.dll中的输出函数进行检查. 我们就只需得到这个输出函数入口然后把这个函数"注释"掉就可以了.跟着上面这段代码逆流而上, 找到最后由76924544输出, 又在76924544上加个断点, 继续去删文件. softice跳出来了, 不过不在函数的入口, 反倒在刚才设置的对_SFCDisable的读取上, 没运行函数的入口就运行了函数体中的代码, 看来遇到高人了. 非得逼我出必杀技, 打开2000源代码 : ). 找了半天没找到相应代码又只得退回来看汇编, 最后发现了这个函数NtWaitForMultipleObjects. 呵, 难怪没中断在函数的入口上, 原来早运行了函数的入口然后在函数体里一直没退出. 注释函数的方法不行了.

    这时我想它的工作原理大概是winlogon调用sfc.dll中的输出函数在系统启动时创建了一系列事件. 既然winlogon创建了, 那么它也应该得撤销. 用depends打开winlogon. 果然从sfc.dll中输入了两个函数. 一个是刚才分析的那个, 创建了一系列事件. 看看另一个, 输出地址是76926869, 不出所料, 关闭了一系列事件. 现在我们只要向winlogon中注入代码调用"另一个"函数就能取消文件保护功能了. 不过winlogon不能随便注入代码. 26A杂志第六期上有篇文章提到了注入方法:"adjust debugger access rightz to our process". 那也是一篇SFCDisable的文章, 他用的方法是在内存中搜索特征码, 然后修改. 通用性应该没这么好.

    下面的注入方法是从crazylord的代码中拷过来的, 不过方法不是. :), 写完后就懒得检查了, 加之水平有限, 写的不过优雅的地方就将就着看.

-----------------cut antisfc.c-----------

#include <stdlib.h>
#include "Windows.h"
#include "Tlhelp32.h"
#pragma comment( lib, "Advapi32.lib" )

typedef void (_stdcall * CLOSEEVENTS)(void);
typedef unsigned long DWORD;
typedef DWORD ANTISFC_ACCESS;

/*
* ANTISFC structures
*/

typedef struct _ANTISFC_PROCESS {
    DWORD     Pid;                 // process pid
    HANDLE ProcessHandle;       // process handle
    char   ImageName[MAX_PATH]; // image name (not full path)
} ANTISFC_PROCESS, *PANTISFC_PROCESS;

__inline void ErrorMessageBox(char *szAdditionInfo)
{
    printf("error on %s, error code %d. n", szAdditionInfo, GetLastError());
}

void usage(char *n) {
    printf("usage: %s [/d]n", n);
    printf("t/d: disable sfc file protecte fuction.n");
    exit(0);
}

DWORD Init() {
    DWORD   Ret = 0;
    HANDLE hToken;
    LUID sedebugnameValue;
    TOKEN_PRIVILEGES tkp;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES TOKEN_QUERY, &hToken)) {
        ErrorMessageBox("OpenProcessToken");
    } else {

        if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
            ErrorMessageBox("LookupPrivilegeValue");
        } else {

            tkp.PrivilegeCount = 1;
            tkp.Privileges[0].Luid = sedebugnameValue;
            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

            if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL)) {
                ErrorMessageBox("AdjustTokenPrivileges");
            } else {
                Ret = 1;
            }
        }
        CloseHandle(hToken);
    }

    return(Ret);
}

DWORD GetPidEx(char *proc_name, char *full_path) {
    DWORD             dwPid=0;
    HANDLE             hSnapshot;
    PROCESSENTRY32     pe;
    BOOL               Ret;
   
  if (isdigit(proc_name[0]))
      dwPid = strtoul(proc_name, NULL, 0);
  else
      dwPid = -1;
     
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == (HANDLE) -1){
        ErrorMessageBox("CreateToolhelp32Snapshot");
        return(0);
    }

    pe.dwSize = sizeof(PROCESSENTRY32);
    Ret = Process32First(hSnapshot, &pe);

    while (Ret) {
          if((strncmp(strlwr(pe.szExeFile), strlwr(proc_name), strlen(proc_name)) == 0)
            (pe.th32ProcessID == dwPid)) {
                dwPid = pe.th32ProcessID;
                strcpy(full_path, pe.szExeFile);
                break;
        }
        pe.dwSize = sizeof(PROCESSENTRY32);
        Ret = Process32Next(hSnapshot, &pe);
    }

    CloseHandle(hSnapshot);
    if (dwPid == -1)
      dwPid = 0;
    return(dwPid);
}

DWORD InitProcess(PANTISFC_PROCESS Process, char *proc_name, ANTISFC_ACCESS access) {
    DWORD Ret=0;

    Process->Pid = GetPidEx(proc_name, Process->ImageName);
    if (Process->Pid != 0 && Process->ImageName[0] != 0) {
        Process->ProcessHandle = OpenProcess(access, FALSE, Process->Pid);
        if (Process->ProcessHandle == NULL)
            ErrorMessageBox("OpenProcess");
        else
            Ret = 1;
    }

    return(Ret);
}

DWORD InjectThread(PANTISFC_PROCESS Process,
                PVOID function) {
    HANDLE     hThread;
    DWORD     dwThreadPid = 0, dwState;

    hThread = CreateRemoteThread(Process->ProcessHandle,
                                NULL,
                                0,
                                (DWORD (__stdcall *) (void *)) function,
                                NULL,
                                0,
                                &dwThreadPid);
    if (hThread == NULL) {
        ErrorMessageBox("CreateRemoteThread");
        goto cleanup;
    }

    dwState = WaitForSingleObject(hThread, 4000); // attends 4 secondes

    switch (dwState) {
    case WAIT_TIMEOUT:
    case WAIT_FAILED:
        ErrorMessageBox("WaitForSingleObject");
        goto cleanup;

    case WAIT_OBJECT_0:
        break;

    default:
        ErrorMessageBox("WaitForSingleObject");
        goto cleanup;
    }

    CloseHandle(hThread);
    return dwThreadPid;
   
cleanup:
    CloseHandle(hThread);

    return 0;
}

int main(int argc, char* argv[])
{
    ANTISFC_PROCESS     Process;
    HMODULE hSfc;
    DWORD     dwThread;
    CLOSEEVENTS pfnCloseEvents;
    DWORD dwVersion;

    printf("AntiSfc programed by bgate. :) *nn");

    if (argc != 2)
        usage(argv[0]);

    if (strcmp(argv[1], "/d") != 0) {
        usage(argv[0]);
    }

    if (Init()) {
        printf("debug privilege setn");
    } else {
        printf("error on get debug privilegen");
        return(0);
    }

    if(InitProcess(&Process, "winlogon.exe", PROCESS_ALL_ACCESS) == 0) {
        printf("error on get process info. n");
        return(0);
    }

    dwVersion = GetVersion();
    if ((DWORD)(LOBYTE(LOWORD(dwVersion))) == 5){                 // Windows 2000/XP
        if((DWORD)(HIBYTE(LOWORD(dwVersion))) == 0){             //Windows 2000
            hSfc = LoadLibrary("sfc.dll");
            printf("Win2000n");
        }
        else {//if((DWORD)(HIBYTE(LOWORD(dwVersion))) = 1)             //Windows XP
            hSfc = LoadLibrary("sfc_os.dll");
            printf("Windows XPn");
        }
    }    
    //else if ()   //2003?
    else {
        printf("unsupported versionn");
    }

    pfnCloseEvents = (CLOSEEVENTS)GetProcAddress(hSfc,
                                                MAKEINTRESOURCE(2));
    if(pfnCloseEvents == NULL){
        printf("Load the sfc fuction failedn");
        FreeLibrary(hSfc);
        return(0);
    }

    FreeLibrary(hSfc);

    dwThread = InjectThread(&Process,
                            pfnCloseEvents);
   
    if(dwThread == 0){
        printf("failedn");
    }
    else{
        printf("OKn");
    }

    CloseHandle(Process.ProcessHandle);
    return(0);

}


------------------end cut---------
    在运行zap替换系统文件前运行一下antisfc就行了, 你也可以把它们写到一起. 理论上他能在2000, xp, 2003?的任何版本上使用. 不过我只在Win2K sp4+, WinXP sp1+上测试过.
    本文的缺点是替换的系统文件只能在重启后生效, 写完了.

 

上下文章:

 

上一篇文章: 手把手教你做WindowsXP登录界面 下一篇文章: 更改XP、2003终端客户端连接端口(有别于WIN2000)

相关文章:

  • 让Windows XP操作系统运行效率更高
  • 汇丰银行启用新身份验证系统 防范网络诈骗
  • 谷歌SEC文件证明裁减大量合同工
  • 有效管理 Windows系统帐户权限
  • 活用卡巴斯基"系统恢复" 消除恶意程序

相关软件:

  • 一键清除垃圾(系统垃圾清理软件) 2.8
  • 定位系统GPS软件图标
  • 时代骄阳餐饮管理信息系统 V3.8 单机版
  • 恒杰通用机器设备管理系统 V3.50
  • XP系统标志图标
  • 系统垃圾清理王 5.65 钛金版

 

快速导航

  • 网络学院
  • 精品汇聚
  • 字体下载
  • 教程下载
  • ASP源码
  • PHP源码
  • Net源码
  • JSP 源码

WINDOWS分类导航

  • Windows 2000
  • Windows 9.x
  • Windows XP
  • Windows 2003
  • Windows Me
  • 注 册 表
  • windows Vista
  • Windows 7
  • Win 2008

本类经典文章推荐

  • 是时候告别系统白屏 让窗口背景靓...
  • 系统更安全 停用XP十项不必要服务
  • 教你三招拿下WindowsXP下顽固视频
  • 保证Win XP远程控制时安全的方法
  • 二招搞定Windows XP系统关机故障
  • Windows Embedded为XP带来新官方主...
  • 与众不同 Windows XP开始菜单也要...
  • 二招搞定XP系统关机故障(图)
  • XP教程:让Windows系统跑得更快更...
  • WIN系统中的XP/2003等:“查看”选...

Windows XP阅读排行

  • 着手教你去优化XP系统
  • 全面深入认识WindowsXP激活
  • 系统激活篇:激活WinXP sp2前要了...
  • 秘笈篇:将OEM XP变成零售正版XP
  • 运用XP SP2仿2003远程多用户登录
  • 清理系统垃圾问件:Windows XP的另...
  • 一位强人总结的Win XP实用技巧45条
  • WindowsXP局域网多用户互访的实现
  • 番茄花园 WinXP安装盘集成技术分析...
  • 速度性-手动清除XP系统临时文件

WINDOWS阅读总排行

  • 如何打开注册表编辑器
  • 着手教你去优化XP系统
  • 操作系统常见问题:这些.TMP文件可...
  • 全面深入认识WindowsXP激活
  • 系统激活篇:激活WinXP sp2前要了...
  • 秘笈篇:将OEM XP变成零售正版XP
  • ECHO命令的使用
  • MMC不能打开文件MSC文件
  • 着手一步步教你如何优化 Windows ...
  • WINdows 2K/XP系统优化大攻略

广告位置

字母检索 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 回到顶部

关于我们 | 版权声明 | 免责条款 | 广告联系 | 软件发布 | 下载帮助 | 下载排行 | 网站地图 | 特别鸣谢 | 友情连接

copyright; 2005-2008 D9soft.com 第九软件网 版权所有