首页
社区
课程
招聘
[求助]XP关闭SFC出错
发表于: 2008-2-11 15:42 9159

[求助]XP关闭SFC出错

2008-2-11 15:42
9159

看了一篇XP SP2关闭SFC的DEPHI代码,就用VC改写了下,编译运行发现根本没有关闭文件保护,调试下看了看,发现是CreateRemoteThread出错,返回错误代码5,Access Denied.

不明白为什么,网上找了下,似乎都是这么写的,不知道别的环境下是否可以实现关闭SFC的功能.下面是我的出错代码:

        if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hProcessToken))
        {
                CloseHandle(hMutex);
                return FALSE;
        }

        if(!SetPrivilege(hProcessToken, SE_DEBUG_NAME, TRUE))
        {
                CloseHandle(hProcessToken);
                CloseHandle(hMutex);
                return FALSE;
        }

        DWORD dwPid = GetPidByName(szExeName); // szExeName = "winlogon.exe"
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,
                                                                FALSE, dwPid);

        HMODULE hSFC = LoadLibrary("sfc_os.dll");

        PTHREAD_START_ROUTINE pfnCloseEvent = (PTHREAD_START_ROUTINE)GetProcAddress(hSFC, MAKEINTRESOURCE(2));

        if(hSFC)
                FreeLibrary(hSFC);

        HANDLE hCloseEvent = CreateRemoteThread(hProcess, NULL, 0, pfnCloseEvent,
                                                                                NULL, 0, NULL);

        if(hCloseEvent)
        {
                WaitForSingleObject(hCloseEvent, INFINITE);
                CloseHandle(hCloseEvent);
        }
        else
                DWORD dwRetValue = GetLastError(); // 返回错误代码为5


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (9)
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
2
汗,找的代码都不全。 注入Winlogon要提升权限的。

这个远程线程不好使,直接调用sfc_os.dll的5号函数就可以了.

#include <windows.h>
#include <assert.h>
#include <stdio.h>

typedef DWORD (* SFPEXC)(DWORD, wchar_t *, DWORD);

void wmain(int argc, wchar_t **argv)
{
  HMODULE sfc_os;
  SFPEXC sfp_exc;

  assert(argc==2);
  assert(sfc_os=LoadLibrary("sfc_os.dll"));
  assert(sfp_exc=(SFPEXC) GetProcAddress(sfc_os, (char *) 5));

  assert(!sfp_exc(0, argv[1], -1));
  wprintf(L"File %s should now be unprotected for 1 minute", argv[1]);
}
2008-2-11 21:35
0
雪    币: 390
活跃值: (571)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习了!!!
2008-2-11 21:47
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
4
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Shlwapi.h>
#include <sfc.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <tlhelp32.h>
#pragma comment(lib,"sfc.lib")
#pragma comment(lib,"shlwapi.lib")

#pragma check_stack (off)
DWORD thread_func (FARPROC sfc_terminate)
{
    sfc_terminate();
    return 0;
}
void after_thread_func(void)
{
}
#pragma check_stack

//调整权限
int AdjustPrivileges(void)
{
    HANDLE token_handle;
    int ret=0;

    if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token_handle))
    {
        LUID luid;
        if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
        {
            TOKEN_PRIVILEGES tk_priv;

            tk_priv.PrivilegeCount=1;
            tk_priv.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
            tk_priv.Privileges[0].Luid=luid;

            if(AdjustTokenPrivileges(token_handle,FALSE,&tk_priv,0,NULL,NULL)) ret=1;
        }
        CloseHandle(token_handle);
    }
    return ret;
}

//根据取得进程号
DWORD GetProcessID(const char* pname)
{
    HANDLE         hProcessSnap = NULL;
    DWORD           bRet      = 0;
    PROCESSENTRY32 pe32      = {0};

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hProcessSnap == INVALID_HANDLE_VALUE)
        return (FALSE);

    pe32.dwSize = sizeof(PROCESSENTRY32);

    if (Process32First(hProcessSnap, &pe32))
    {

        do
        {
            if (stricmp(pe32.szExeFile, pname) == 0) {
                bRet = pe32.th32ProcessID;
                break;
            }
        }while (Process32Next(hProcessSnap, &pe32));
    }
    CloseHandle (hProcessSnap);
    return (bRet);
}

//关闭windows文件保护
void TerminateSfc()
{
    DWORD wpid = 0;
    wpid = GetProcessID("winlogon.exe");
    HANDLE remote_thread;
    HMODULE sfc=LoadLibrary("SFC_OS.DLL");

    FARPROC sfc_terminate=GetProcAddress(sfc, (char *) 2);

    if (!AdjustPrivileges()) {
        MessageBox(NULL, "调整权限错误", "", MB_OK);
        exit(0);
    }

    HANDLE process=OpenProcess(PROCESS_ALL_ACCESS, FALSE, wpid);
    if(!process)
    {
        exit(0);
    }

    LPVOID remote_mem=VirtualAllocEx(process,NULL,(SIZE_T) ((char *)after_thread_func-(char *)thread_func),MEM_COMMIT,PAGE_READWRITE);
    if(!remote_mem)
    {
        printf("Error while commiting memory in the remote process\n");
        goto clean_up;
    }

    if(!WriteProcessMemory(process,remote_mem,(char *) thread_func,(SIZE_T) ((char *)after_thread_func-(char *)thread_func),(SIZE_T *) 0))
    {
        printf("Error %d while writing to the remote process\n", GetLastError());
        goto clean_up;
    }

    remote_thread=CreateRemoteThread(process,NULL,0,(LPTHREAD_START_ROUTINE) remote_mem,(LPVOID) sfc_terminate,0,NULL);
    if(!remote_thread)
    {
        printf("Error while creating remote thread in the process\n");
        goto clean_up;
    }

    if(WaitForSingleObject(remote_thread, 10*1000)==WAIT_TIMEOUT)
        printf("Timeout occured while waiting for the remote thread\n");

    CloseHandle(remote_thread);

clean_up:
    if(remote_mem) VirtualFreeEx(process, remote_mem, 0, MEM_RELEASE);
    CloseHandle(process);
}
2008-2-11 23:44
0
雪    币: 235
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
sudami没看清楚吧,我传的是部分代码.
// 这里是提升Debug权限
if(!SetPrivilege(hProcessToken, SE_DEBUG_NAME, TRUE))
  {
    CloseHandle(hProcessToken);
    CloseHandle(hMutex);
    return FALSE;
  }

5号函数我也知道,但只能针对一个文件,真晕~

感谢combojiang的回复, 我也觉得应该是要写入进程内存空间再执行, 但看了不少代码, 有asm的, Delphi的, 也有C++的, 都宣称在XP SP2下调试通过, 但都没有这部分调用.我先试试.再次感谢!
2008-2-12 10:14
0
雪    币: 235
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
看了下,combojiang这样应该能行,我转份我下载的代码,为什么它能测试通过?

关闭SFC[文件保护]的源代码
WindowsXP Professional SP2测试通过.

.386
.Model Flat,StdCall
Option CaseMap :None

Include \Masm32\Include\Windows.inc
Include \Masm32\Include\User32.inc
Include \Masm32\Include\Shell32.inc
Include \Masm32\Include\Kernel32.inc
Include \Masm32\Include\Advapi32.inc

IncludeLib \Masm32\Lib\User32.lib
IncludeLib \Masm32\Lib\Shell32.lib
IncludeLib \Masm32\Lib\Kernel32.lib
IncludeLib \Masm32\Lib\Advapi32.lib

.Data
stProcess db "winlogon.exe",0

.Data?
hFile dd ?
dwProcessID dd ?
hProcess dd ?
lpLoadLibrary dd ?
lpDllName dd ?
szDllPath db 260 dup(?)
szSysPath db 260 dup(?)
hToken dd ?
tkp TOKEN_PRIVILEGES<>
sdnv LUID <>

.Code
EnableDebugPriv Proc
invoke GetCurrentProcess
invoke OpenProcessToken,eax,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,addr hToken
invoke LookupPrivilegeValue,0,CTEXT("SeDebugPrivilege"),addr sdnv
mov tkp.PrivilegeCount,1
m2m tkp.Privileges.Luid.LowPart,sdnv.LowPart
m2m tkp.Privileges.Luid.HighPart,sdnv.HighPart
mov tkp.Privileges.Attributes,SE_PRIVILEGE_ENABLED
invoke AdjustTokenPrivileges,hToken,FALSE,addr tkp,sizeof tkp,0,0
invoke CloseHandle,hToken
ret
EnableDebugPriv EndP

CloseSFC Proc
Local @stProcess:PROCESSENTRY32
Local @hSnapShot
Local @hProcess
Local @hSfc

invoke RtlZeroMemory,addr @stProcess,sizeof @stProcess
mov @stProcess.dwSize,sizeof @stProcess
invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,0
mov @hSnapShot,eax
invoke Process32First,@hSnapShot,addr @stProcess
.While eax
invoke lstrcmpi,addr @stProcess.szExeFile,addr stProcess
.if eax == 0
invoke OpenProcess,PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE,FALSE,@stProcess.th32ProcessID
.if eax
mov @hProcess,eax
invoke LoadLibrary,CTEXT("sfc.dll")
mov @hSfc,eax
invoke GetProcAddress,eax,2
push eax
invoke FreeLibrary,@hSfc
pop eax
.if eax
invoke CreateRemoteThread,@hProcess,0,0,eax,0,0,0
.if eax
invoke CloseHandle,eax
ret
.endif
.endif
.endif
.endif
invoke Process32Next,@hSnapShot,addr @stProcess
.EndW
invoke CloseHandle,@hSnapShot
ret

CloseSFC EndP

Start:
Call EnableDebugPriv
Call CloseSFC
invoke ExitProcess,0
End Start
2008-2-12 10:22
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
7
因为你的代码中木有调用 AdjustTokenPrivileges 去调整权限啊.

远线程不好使, 还没运行就被主防扼杀了~~
2008-2-12 14:56
0
雪    币: 235
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
找到原因了,sudami,不好意思,是我代码上传的不完整.

if(!SetPrivilege(hProcessToken, SE_DEBUG_NAME, TRUE))
  {
    CloseHandle(hProcessToken);
    CloseHandle(hMutex);
    return FALSE;
  }

SetPrivilege是我自定义的函数,用于调整权限.呵呵:0
2008-2-12 15:07
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
9
哈哈, 外国人写了篇文章,关于sfc的. 5种方法...

其实都差不多.俺把附件传上来吧, 给没有学习的同学一个参考,老技术了啊
上传的附件:
2008-2-12 15:21
0
雪    币: 235
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
哈哈

原来就是杀毒软件的主动防御作怪,亏得sudami的提醒.本来一个简单的东西被搞复杂了.
2008-2-12 19:38
0
游客
登录 | 注册 方可回帖
返回
//