IPB

Добро пожаловать, гость ( Вход | Регистрация )

 
Reply to this topicStart new topic
> Самоудаляющийся .EXE файл, Self-Deleting Executable
-=CHE@TER=-
Jun 23 2007, 10:13
Сообщение #1


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Вот, есть такая статья: Self-Deleting Executables.
Она рассказывает о нелёгких поисках способа удалить программно .EXE файл изнутри. Т.е. написать такую программу, которая сможет себя удалить, когда вы её запустите. Как известно в DOS такой проблемы не существует и я, в своё время, делал Uninstall'ер для своей программы, который удалял всё, включая и себя самого, ибо после запуска .EXE файл уже был не нужен. В Windows .EXE файл недоступен (занят системой) до тех пор, пока запущенная программа не прекратила работать, в частности удалить его тоже нельзя.
Из данной статьи я взял универсальный способ-пример, довольно оригинального решения, файл "selfdel05.c" и попытался переписать его на Delphi (оригинал можно взять по ссылке выше - см. Download source).
CODE
//
//  selfdel.c
//
//  Self deleting executable for Win9x/WinNT (all versions)
//
//  J Brown 1/10/2003
//
//  This source file must be compiled with /GZ turned OFF
//  (basically, disable run-time stack checks)
//
//  Under debug build this is always on (MSVC6)
//
//
Uses Windows;
// #pragma pack(push, 1)
// #define
Const CODESIZE = $200;
//
//  Structure to inject into remote process. Contains
//  function pointers and code to execute.
//
Type
     PSELFDEL = ^TSELFDEL;
     TSELFDEL = Packed Record
            ARG0: PSELFDEL; // pointer to self
         opCodes: Array[0..CODESIZE-1] Of Byte; // code
         hParent: THandle; // parent process handle
      fnWaitForSingleObject: Function(hHandle: THandle; dwMilliseconds: DWORD): DWORD; stdcall;
              fnCloseHandle: Function(hObject: THandle): BOOL; stdcall;
               fnDeleteFile: Function(lpFileName: PChar): BOOL; stdcall;
                    fnSleep: Procedure(dwMilliseconds: DWORD); stdcall;
              fnExitProcess: Procedure(uExitCode: UINT); stdcall;
          fnRemoveDirectory: Function(lpPathName: PChar): BOOL; stdcall;
             fnGetLastError: Function: DWORD; stdcall;
                    fRemDir: LongBool;
                 szFileName: Array[0..MAX_PATH-1] Of Char; // file to delete
     End;

//#pragma pack(pop)

{$ifdef _DEBUG}
//{$define FUNC_ADDR(func) (PVOID)(*(DWORD *)((BYTE *)func + 1) + (DWORD)((BYTE *)func + 5))}
{$else}
//{$define FUNC_ADDR(func) func}
{$endif}

//
//  Routine to execute in remote process.
//
procedure remote_thread(remote: PSELFDEL); stdcall;
Begin
  // wait for parent process to terminate
  remote^.fnWaitForSingleObject(remote^.hParent, INFINITE);
  remote^.fnCloseHandle(remote^.hParent);
  // try to delete the executable file
  while (not remote^.fnDeleteFile(remote^.szFileName)) Do
  Begin
    // failed - try again in one second's time
    remote^.fnSleep(1000);
  End;
  // finished! exit so that we don't execute garbage code
  remote^.fnExitProcess(0);
End;

//
//  Delete currently running executable and exit
//  
Function SelfDelete(fRemoveDirectory: LongBool): Boolean;
Var
    si: STARTUPINFO;
    pi: PROCESS_INFORMATION;
    context: TContext;
    oldProt: DWORD;
    local: TSELFDEL;
    entrypoint: DWORD;
    szExe: Array[0..MAX_PATH-1] Of Char;

    remdel: Pointer;
    dummy: dword;
Begin
  result:=FALSE;
  szExe:='explorer.exe'#0;
  //
  //  Create executable suspended
  //
  ZeroMemory(@si, SizeOf(si));
  si.cb:=SizeOf(si);
  if CreateProcess(Nil, szExe, Nil, Nil, False, CREATE_SUSPENDED Or IDLE_PRIORITY_CLASS, Nil, Nil, si, pi) Then
  Begin
    local.fnWaitForSingleObject := @WaitForSingleObject;
    local.fnCloseHandle         := @CloseHandle;
    local.fnDeleteFile          := @DeleteFile;
    local.fnSleep               := @Sleep;
    local.fnExitProcess         := @ExitProcess;
    local.fnRemoveDirectory     := @RemoveDirectory;
    local.fnGetLastError        := @GetLastError;

    local.fRemDir               := fRemoveDirectory;

    // Give remote process a copy of our own process handle
    DuplicateHandle(GetCurrentProcess, GetCurrentProcess, pi.hProcess, @local.hParent, 0, FALSE, 0);
    GetModuleFileName(0, local.szFileName, MAX_PATH);

    // copy in binary code
    remdel:=@remote_thread;
    move(remdel, local.opCodes, CODESIZE); //move(local.opCodes, @remdel, CODESIZE); {!}

    //
    // Allocate some space on process's stack and place
    // our SELFDEL structure there. Then set the instruction pointer
    // to this location and let the process resume
    //
    context.ContextFlags := CONTEXT_INTEGER Or CONTEXT_CONTROL;
    GetThreadContext(pi.hThread, context);

    // Allocate space on stack (aligned to cache-line boundary)
    entrypoint := (context.Esp - sizeof(TSELFDEL)) And Cardinal(Not $1F);
    
    //
    // Place a pointer to the structure at the bottom-of-stack
    // this pointer is located in such a way that it becomes
    // the remote_thread's first argument!!
    //
    local.Arg0:=Ptr(entrypoint); // local.Arg0 := TSELFDEL(entrypoint);

    context.Esp := entrypoint - 4; // create dummy return address
    context.Eip := entrypoint + 4; // offset of opCodes within structure

    // copy in our code+data at the exe's entry-point
    VirtualProtectEx(pi.hProcess, Ptr(entrypoint), sizeof(local), PAGE_EXECUTE_READWRITE, Ptr(oldProt));
    WriteProcessMemory(pi.hProcess, Ptr(entrypoint), Pointer(@local), sizeof(local), dummy);

    FlushInstructionCache(pi.hProcess, Ptr(entrypoint), sizeof(local));

    SetThreadContext(pi.hThread, context);

    // Let the process continue
    ResumeThread(pi.hThread);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);

    result:=TRUE;
  End;
End;

Begin
  SelfDelete(False);
End.

Однако, где-то я чего-то упустил, ибо программа запускается, но ничего не делает.
Кто-нибудь может помочь?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jun 23 2007, 16:27
Сообщение #2


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Немного поправил исходный код с move() и ещё пара ошибок зафиксено.
По прежнему ничего не делает, причём, похоже, remote_thread() вообще управление не передаётся.
Кто-нибудь может помочь?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Jun 24 2007, 10:50
Сообщение #3


Advanced Member
***

Группа: CTPAX-X
Сообщений: 537
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



А не проще сделать генералицю .bat'ника с командой удаления .exe и его исполнение?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jun 24 2007, 13:43
Сообщение #4


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(Siberian GRemlin @ Jun 24 2007, 10:50 AM) *
А не проще сделать генералицю .bat'ника с командой удаления .exe и его исполнение?
Это не спортивно. (*улыбается*)
Хочется аккуратное решение.
Думаю, что тут скорее всего нужно будет сделать код на асме, там править адреса и уже его инжектировать в процесс "explorer.exe" (как только это делать - пока что х.з.). Потому что, как мне кажется, расколбас идёт из-за того, что код на Delphi занимает больше, чем на C++ (CODESIZE = $200;).


Добавлено:
Пытаюсь через Assembler работать - вот, пока что получилось адрес заменить:
CODE
Uses Windows;
{$APPTYPE CONSOLE}

Procedure SelfDel; Assembler;
Asm
  jmp @code
  @pExitProcess: dd 00
  @code:
  xor eax,eax
  push eax
  call Cardinal(@pExitProcess)
  retn
End;

procedure DeleteSelf;
var
  pExitProcess: pointer;
            pt: PByte;
         dummy: cardinal;
begin
  pt:=@selfdel;
  Inc(pt, 2);
  pExitProcess:=@ExitProcess;
  WriteProcessMemory(GetCurrentProcess, pt, @pExitProcess, 4, dummy);
end;

Begin
  DeleteSelf;
  SelfDel;
  WriteLn('failed');
End.

Думаю по-позже с "explorer.exe" попробовать. Только за адреса вызова не ручаюсь... У меня сомнения есть + непонятно, как EntryPoint указывать. В общем, буду рад любой помощи.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jun 25 2007, 12:30
Сообщение #5


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Гм, так и знал. EntryPoint от explorer.exe я получил, но вот вживить приведённый выше код SelfDel туда не получается - адреса у API функций другие... Кто-нибудь знает, как получить адреса необходимых API функций у запущенного процесса? Что-нибудь типа GetProcAddress(hHandle, 'ExitProcess'); только в Suspended процессе?..
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Heim
Jun 28 2007, 11:29
Сообщение #6


Незарегистрирован









Заменил

CODE
local.fnWaitForSingleObject        = (FARPROC)WaitForSingleObject;
        local.fnCloseHandle            = (FARPROC)CloseHandle;
        local.fnDeleteFile                = (FARPROC)DeleteFile;
        local.fnSleep                = (FARPROC)Sleep;
        local.fnExitProcess                = (FARPROC)ExitProcess;
        local.fnRemoveDirectory            = (FARPROC)RemoveDirectory;
        local.fnGetLastError            = (FARPROC)GetLastError;


на:
CODE
HMODULE    hMod    = LoadLibrary(_T("Kernel32.dll"));
        if( hMod )
        {
            local.fnWaitForSingleObject        = GetProcAddress( hMod, "WaitForSingleObject" );//(FARPROC)WaitForSingleObject;
            local.fnCloseHandle                = GetProcAddress( hMod, "CloseHandle" );//(FARPROC)CloseHandle;
            local.fnDeleteFile                = GetProcAddress( hMod, "DeleteFileW" );//(FARPROC)DeleteFile;
            local.fnSleep                    = GetProcAddress( hMod, "Sleep" );//(FARPROC)Sleep;
            local.fnExitProcess                = GetProcAddress( hMod, "ExitProcess" );//(FARPROC)ExitProcess;
            local.fnRemoveDirectory            = GetProcAddress( hMod, "RemoveDirectoryW" );//(FARPROC)RemoveDirectory;
            local.fnGetLastError            = GetProcAddress( hMod, "GetLastError" );//(FARPROC)GetLastError;
            FreeLibrary( hMod );
        }


Работает... Может тебе поможет????
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jun 28 2007, 11:45
Сообщение #7


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



Heim!
Неа, не работает. Мне нужны адреса функций именно из адресного пространства другого процесса.
Вот код, который я сделал:
CODE
Uses Windows;
{$APPTYPE CONSOLE}

Type
     TInitStruct = Packed Record
                      pExitProcess: Pointer;
                      pWaitForSingleObject: Pointer;
                      pSleep: Pointer;
                      pDeleteFile: Pointer;
                      pCloseHandle: Pointer;
                      hParent: THandle;
                      szFileName: Array[0..MAX_PATH-1] Of Char;
                   End;

Procedure SelfDel; Assembler;
Asm
  jmp @code
  @pExitProcess: dd 00
  @pWaitForSingleObject: dd 00
  @pSleep: dd 00
  @pDeleteFile: dd 00
  @pCloseHandle: dd 00
  @hParent: dd 00
  // MAX_PATH = 260 { windows.pas }
  @szFileName: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  nop
  nop
  nop
  nop
  @code:
  // ******************************
  // full injection code:
  lea eax, @hParent
  push eax
  push INFINITE
  call DWORD(@pWaitForSingleObject)
  lea eax, @hParent
  push eax
  call DWORD(@pCloseHandle)
  @delfile:
    push 03E8h // 1 sec
    call DWORD(@pSleep)
    lea eax, @szFileName
    push eax
    call DWORD(@pDeleteFile)
    test eax, eax
  jz @delfile
  xor eax,eax
  push eax
  call DWORD(@pExitProcess)
End;

Function GetCodeSize(P: PByte): Cardinal; Assembler;
Asm
  mov ebx, eax
  mov cl, 0C3h
  @loop:
  inc eax
  cmp [eax], cl
  jnz @loop
  sub eax, ebx
  inc eax
End;

{
used links:
http://www.codeproject.com/useritems/selfdel.asp
http://undocumented.ntinternals.net/
}
Function GetProcessEntryPointAddress(hProcess, hThread: THandle): Cardinal;
Var
    context: TContext;
    entry: LDT_ENTRY;
    read, dwFSBase, dwImageBase, dwOffset, dwOptHeaderOffset: Cardinal;
      dd: cardinal;
Begin
  //
  // get the current thread context
  //
  context.ContextFlags:=CONTEXT_FULL Or CONTEXT_DEBUG_REGISTERS;
  GetThreadContext(hThread, context);
  //
  // use the segment register value to get a pointer to
  // the TEB
  //
  GetThreadSelectorEntry(hThread, context.SegFs, entry);
  dwFSBase:=(entry.BaseHi ShL 24) Or (entry.BaseMid ShL 16) Or (entry.BaseLow);
  //
  // read the teb
  //
  WriteLn(ReadProcessMemory(hProcess, Ptr(dwFSBase + 48), @dd, 4, read)); {1}
  //
  // read the peb from the location pointed at by the teb
  //
  WriteLn(ReadProcessMemory(hProcess, Ptr(dd + 8), @dwImageBase, 4, read)); {2}
  //
  // figure out where the entry point is located;
  //
  WriteLn(ReadProcessMemory(hProcess, Ptr(dwImageBase + $3C), @dwOffset, 4, read)); {3}

  dwOptHeaderOffset:=(dwImageBase + dwOffset + 4 + 20);

  WriteLn(ReadProcessMemory(hProcess, Ptr(dwOptHeaderOffset + 16), @dd, 4, read)); {4}

  result:=dwImageBase + dd;
End;

Function DeleteSelf: Boolean;
Var
    InitStruct: TInitStruct;
       hKrnl32: HModule;
         dummy: Cardinal;
            St: String;
            Pt: PByte;
{---}
            si: STARTUPINFO;
            pi: PROCESS_INFORMATION;
      CodeSize, oldprot, entrypoint: Cardinal;
Begin
  result:=False;
  With InitStruct Do
    Begin
      hKrnl32:=GetModuleHandle('kernel32');
      pExitProcess:=GetProcAddress(hKrnl32, 'ExitProcess');
      pWaitForSingleObject:=GetProcAddress(hKrnl32, 'WaitForSingleObject');
      pSleep:=GetProcAddress(hKrnl32, 'Sleep');
      pDeleteFile:=GetProcAddress(hKrnl32, 'DeleteFileA');
      pCloseHandle:=GetProcAddress(hKrnl32, 'CloseHandle');
      FillChar(szFileName, MAX_PATH, 0);
      St:=ParamStr(0);
      Move(St[1], szFileName, Length(St));
      hParent:=0;
    End;

  ZeroMemory(@si, SizeOf(si));
  si.cb:=SizeOf(si);
  If CreateProcess(Nil, PChar('explorer.exe'), Nil, Nil, False, CREATE_SUSPENDED Or IDLE_PRIORITY_CLASS, Nil, Nil, si, pi) Then
    Begin
      DuplicateHandle(GetCurrentProcess, GetCurrentProcess, pi.hProcess, @InitStruct.hParent, 0, FALSE, 0);
      Pt:=@selfdel;
      Inc(Pt, 5); // offset to structure
      WriteLn(WriteProcessMemory(GetCurrentProcess, Pt, @InitStruct, SizeOf(InitStruct), dummy));
      Dec(Pt, 5); // restore offset to program start
      CodeSize:=GetCodeSize(Pt);

      entrypoint:=GetProcessEntryPointAddress(pi.hProcess, pi.hThread);

      oldprot:=0;
      VirtualProtectEx(pi.hProcess, Ptr(entrypoint), CodeSize, PAGE_EXECUTE_READWRITE, oldProt);
      WriteLn(WriteProcessMemory(pi.hProcess, Ptr(entrypoint), Pt, CodeSize, dummy));
      FlushInstructionCache(pi.hProcess, Ptr(entrypoint), CodeSize);
      ResumeThread(pi.hThread);
      CloseHandle(pi.hThread);
      CloseHandle(pi.hProcess);
      result:=True;
    End;
End;

Begin
  DeleteSelf;
  WriteLn('ready');
End.


При запуске, если в код, сразу вставить C3, чтобы процесс завершил работу - то всё ок.
А вот адреса API функций - левые. Их нужно именно как-то получить из запущенного процесса.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Xplorer
Jun 28 2007, 13:32
Сообщение #8


Advanced Member
***

Группа: CTPAX-X
Сообщений: 52
Регистрация: 4-February 08
Пользователь №: 8
Спасибо сказали: 30 раз(а)



Исправленный код:
CODE
Procedure SelfDel; Assembler;
Asm
  call @code
  @pExitProcess: dd 0
  @pWaitForSingleObject: dd 0
  @pSleep: dd 0
  @pDeleteFile: dd 0
  @pCloseHandle: dd 0
  @hParent: dd 0
  // MAX_PATH = 260 { windows.pas }
  @szFileName: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  nop
  nop
  nop
  nop
  @code:
  // ******************************
  // full injection code:
  pop ebp

  push INFINITE
  mov ebx, TInitStruct(ebp).hParent
  push ebx
  call TInitStruct(ebp).pWaitForSingleObject

  mov ebx, TInitStruct(ebp).hParent
  push ebx
  call TInitStruct(ebp).pCloseHandle

  @delfile:
    lea ebx, TInitStruct(ebp).szFileName
    push ebx
    call TInitStruct(ebp).pDeleteFile
    or eax, eax
    jne @exit

    push 500
    call TInitStruct(ebp).pSleep
  jmp @delfile

  @exit:
  push 0
  call TInitStruct(ebp).pExitProcess
End;

QUOTE(-=CHE@TER=- @ Jun 28 2007, 03:45 PM) *
А вот адреса API функций - левые. Их нужно именно как-то получить из запущенного процесса.
Адреса в kernel32.dll для всех процессов одинаковые, т.к. это DLL (в памяти находится только один экземпляр кода).
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jun 28 2007, 13:56
Сообщение #9


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(Xplorer @ Jun 28 2007, 01:32 PM) *
Исправленный код:
<cut>

Адреса в kernel32.dll для всех процессов одинаковые, т.к. это DLL (в памяти находится только один экземпляр кода).
О!!! Спасибо большое, ты гигант!!!
Я не знал про общий адрес, спасибо за справку и разъяснение!
Только я не понял пару моментов:
1) На что указывает ebp, когда ты сделал команду pop ebp (он чему вообще равен был?) Я так понял, что ты его из стэка вытащил, а кто туда его сложил и с каким значением?
2) call @code - почему именно call, а не jmp? Это как раз связано с ebp?

А! До меня, кажется, допёрло - ebp - это адрес возврата из call и он автоматически при вызове call ложится в стэк?.. (*улыбается*) Значит он должен как раз указывать на следующую инструкцию, после call - как раз на структуру. Тогда, и правда, простое и элегантное решение!
Это так? (*улыбается*)


Вот полный, причёсанный код (для тех, кто будет компилировать - нули справа от @szFileName: должны быть на ОДНОЙ встрочке!):
CODE
//
//  DSelfDel.dpr
//
//  Self deleting executable for Win9x/WinNT (all versions)
//  URL: http://www.catch22.net/tuts/selfdel.asp
//
//  Idea: J Brown 1/10/2003
//  Delphi/ASM code by: -=CHE@TER=- / Xplorer
//
Program DSelfDel;
Uses Windows;

{
Few more ways to go:
1. Self-deleting .BAT file
2. Create temporary file using CreateFile() with FILE_FLAG_DELETE_ON_CLOSE flag.

URL: http://forum.vingrad.ru/act-ST/f-1/t-12088/unread-1/anchor-entry77762/0.html
}

Type
     TInitStruct = Packed Record
                     pExitProcess: Pointer;
                     pWaitForSingleObject: Pointer;
                     pSleep: Pointer;
                     pDeleteFile: Pointer;
                     pCloseHandle: Pointer;
                     hParent: THandle;
                     szFileName: Array[0..MAX_PATH-1] Of Char;
                   End;

Procedure SelfDel; Assembler;
Asm
  call @code
  @pExitProcess: dd 0
  @pWaitForSingleObject: dd 0
  @pSleep: dd 0
  @pDeleteFile: dd 0
  @pCloseHandle: dd 0
  @hParent: dd 0
  // MAX_PATH = 260 { windows.pas }
  @szFileName: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

  @code:
  // ******************************
  // full injection code:
  pop ebp

  push INFINITE
  mov ebx, TInitStruct(ebp).hParent
  push ebx
  call TInitStruct(ebp).pWaitForSingleObject

  mov ebx, TInitStruct(ebp).hParent
  push ebx
  call TInitStruct(ebp).pCloseHandle

  @delfile:
    lea ebx, TInitStruct(ebp).szFileName
    push ebx
    call TInitStruct(ebp).pDeleteFile
    or eax, eax
    jne @exit

    push 500
    call TInitStruct(ebp).pSleep
  jmp @delfile

  @exit:
  push 0
  call TInitStruct(ebp).pExitProcess
End;

Function GetCodeSize(P: PByte): Cardinal; Assembler;
Asm
  mov ebx, eax
  mov cl, 0C3h
  @loop:
  inc eax
  cmp [eax], cl
  jnz @loop
  sub eax, ebx
  inc eax
End;

{
used links:
http://www.codeproject.com/useritems/selfdel.asp
http://undocumented.ntinternals.net/
}
Function GetProcessEntryPointAddress(hProcess, hThread: THandle): Cardinal;
Var
    read, dwFSBase, dwImageBase, dwOffset, dwOptHeaderOffset, dd: Cardinal;
                                                         context: TContext;
                                                           entry: LDT_ENTRY;
Begin
  //
  // get the current thread context
  //
  context.ContextFlags:=CONTEXT_FULL Or CONTEXT_DEBUG_REGISTERS;
  GetThreadContext(hThread, context);
  //
  // use the segment register value to get a pointer to
  // the TEB
  //
  GetThreadSelectorEntry(hThread, context.SegFs, entry);
  dwFSBase:=(entry.BaseHi ShL 24) Or (entry.BaseMid ShL 16) Or (entry.BaseLow);
  //
  // read the teb
  //
  ReadProcessMemory(hProcess, Ptr(dwFSBase + 48), @dd, 4, read); {1}
  //
  // read the peb from the location pointed at by the teb
  //
  ReadProcessMemory(hProcess, Ptr(dd + 8), @dwImageBase, 4, read); {2}
  //
  // figure out where the entry point is located;
  //
  ReadProcessMemory(hProcess, Ptr(dwImageBase + $3C), @dwOffset, 4, read); {3}

  dwOptHeaderOffset:=(dwImageBase + dwOffset + 4 + 20);

  ReadProcessMemory(hProcess, Ptr(dwOptHeaderOffset + 16), @dd, 4, read); {4}
  result:=dwImageBase + dd;
End;

Function DeleteSelf: Boolean;
Var
    CodeSize, EntryPoint, dummy: Cardinal;
                     InitStruct: TInitStruct;
                        hKrnl32: HModule;
                             St: String;
                             Pt: PByte;
                             si: STARTUPINFO;
                             pi: PROCESS_INFORMATION;
Begin
  result:=False;
  ZeroMemory(@si, SizeOf(si));
  si.cb:=SizeOf(si);
  If CreateProcess(Nil, PChar('explorer.exe'), Nil, Nil, False, CREATE_SUSPENDED Or IDLE_PRIORITY_CLASS, Nil, Nil, si, pi) Then
    Begin
      With InitStruct Do
        Begin
          DuplicateHandle(GetCurrentProcess, GetCurrentProcess, pi.hProcess, @hParent, 0, FALSE, 0);
          hKrnl32:=GetModuleHandle('kernel32');
          pExitProcess:=GetProcAddress(hKrnl32, 'ExitProcess');
          pWaitForSingleObject:=GetProcAddress(hKrnl32, 'WaitForSingleObject');
          pSleep:=GetProcAddress(hKrnl32, 'Sleep');
          pDeleteFile:=GetProcAddress(hKrnl32, 'DeleteFileA');
          pCloseHandle:=GetProcAddress(hKrnl32, 'CloseHandle');
          FillChar(szFileName, MAX_PATH, 0);
          St:=ParamStr(0);
          Move(St[1], szFileName, Length(St));
        End;
      Pt:=@SelfDel;
      Inc(Pt, 5); // offset to structure
      WriteProcessMemory(GetCurrentProcess, Pt, @InitStruct, SizeOf(InitStruct), dummy);
      Dec(Pt, 5); // restore offset to program start
      CodeSize:=GetCodeSize(Pt);

      EntryPoint:=GetProcessEntryPointAddress(pi.hProcess, pi.hThread);

      VirtualProtectEx(pi.hProcess, Ptr(entrypoint), CodeSize, PAGE_EXECUTE_READWRITE, dummy);
      WriteProcessMemory(pi.hProcess, Ptr(entrypoint), Pt, CodeSize, dummy);
      FlushInstructionCache(pi.hProcess, Ptr(entrypoint), CodeSize);
      ResumeThread(pi.hThread);
      CloseHandle(pi.hThread);
      CloseHandle(pi.hProcess);
      result:=True;
    End;
End;

Begin
  DeleteSelf;
End.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
nickolayer
Jun 30 2007, 09:50
Сообщение #10


Member
**

Группа: Delegated
Сообщений: 23
Регистрация: 4-February 08
Пользователь №: 1,698
Спасибо сказали: 1 раз(а)



Ох ты. Потрясающе. Я честно скажу, последние три строчки поражают своей простотой. А все остальное просто поражает.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Axsis
Jul 3 2007, 07:17
Сообщение #11


Advanced Member
***

Группа: CTPAX-X
Сообщений: 121
Регистрация: 6-February 08
Пользователь №: 374
Спасибо сказали: 149 раз(а)



Чё-то я не совсем понял принцип работы этого кода... Вы создаёте процесс explorer.exe, усыпляете его и копируете в него свой код? =( ) Если так, то мне интересно, как отнесутся антивирусы и всякие системы проактивной защиты к такому действию? Представьте, что человек слил прогу с инета, запустил, а антивирь написал, что так и так, предотвращена попытка вклиниться в аднесное пространство explorer.exe! А если после этого ещё и оригинальный exe'шник удалится... Да чел в жизни отсюда ничего больше не скачает! Если я всё провильно понял, то подобный код допустим только для личного использования, в публичные проги его пихать нельзя! Или, может, я что-то пропустил и -=CHE@TER=- переключился на написание троянов? =)
ЗЫ: если я неправильно понял, плиз напишите принцип работы ЭТОГО smile.gif
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 3 2007, 08:47
Сообщение #12


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(Axsis @ Jul 3 2007, 07:17 AM) *
Чё-то я не совсем понял принцип работы этого кода... Вы создаёте процесс explorer.exe, усыпляете его и копируете в него свой код? =( ) Если так, то мне интересно, как отнесутся антивирусы и всякие системы проактивной защиты к такому действию? Представьте, что человек слил прогу с инета, запустил, а антивирь написал, что так и так, предотвращена попытка вклиниться в аднесное пространство explorer.exe! А если после этого ещё и оригинальный exe'шник удалится... Да чел в жизни отсюда ничего больше не скачает! Если я всё провильно понял, то подобный код допустим только для личного использования, в публичные проги его пихать нельзя! Или, может, я что-то пропустил и -=CHE@TER=- переключился на написание троянов? =)
ЗЫ: если я неправильно понял, плиз напишите принцип работы ЭТОГО smile.gif
Ок, давайте по порядку:
1) Вопрос первый:
QUOTE
Вы создаёте процесс explorer.exe, усыпляете его и копируете в него свой код? =( )
Совершенно точно (поправочка: Explorer.exe создаётся усыплённым). Находится EntryPoint, откуда Explorer.exe начинает работать (стартовая точка) и в это место всовывается код.

2) Вопрос второй:
QUOTE
Если так, то мне интересно, как отнесутся антивирусы и всякие системы проактивной защиты к такому действию?
Насчёт антивирусов - не знаю, у меня стоит Symantec с последними базами - он к этому спокойно относится. (*улыбается*) Если у тебя другой - можешь у себя скомпилировать Си или Delphi вариант и проверить. (*улыбается*) Сообщи, пожалуйста, о результатах, тоже интересно.
Кстати, вот что ещё сейчас в голову пришло: получается, что все трейнеры и прочие ArtMoney - это тоже вирусы, т.к. они тоже пишут в адресное пространство другого процесса. (*улыбается*)

3) Ну и насчёт третьего пункта приводить цитату целиком не буду - а просто отвечу:
мне данный код нужен был для апдейта моей программы. Вместо DeleteFileA() я использую MoveFileExA(), т.е. конечный у меня алгоритм такой:
1) Человек запускает прогу
2) Прога долбится искать обновление
3) Если обновление есть, то оно скачивает во временный каталог
4) Создаётся усыплённый Explorer.exe, и в него вклинивается код с двумя путями: ParamStr(0) (имя текущей программы) и путь до временного файла в темпе (назовём его TEMPFileName)
5) Текущий процесс завершает свою работу, размораживая Explorer.exe
6) Внедрённый код в Explorer.exe делает следующее:
- ждёт, пока завершит работу родительский процесс
- затем, через MoveFileExA() перемещает TEMPFileName заместо ParamStr(0) (на его место)
- снова запускает ParamStr(0) (уже проапдейтеную версию)
- и завершает работу

Т.е. в итоге программа обновилась, а ты даже этого не заметил - работаешь, как работал. (*улыбается*)

Скажу сразу - вирусы, трояны и прочую хрень никогда не писал и не собираюсь.
Просто мне нравится элегантное и красивое решение, когда не создаёт 200 файлов, один из которых обновляет первый, третий - четвёртый и т.д. Хочу, чтобы моя программа была в одном файле.
Вариант совать в ресур .EXE Updater'а, и создавать его в TEMP'е с флагом FILE_FLAG_DELETE_ON_CLOSE у CreateFile() мне тоже не очень нравится, потому что .EXE файл будет так или иначе больше жрать, чем приведённый выше код.

P.S. Пишу вполне легальную программу. На данный момент ей пользуется ~ 30 человек. (*улыбается*)
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Axsis
Jul 4 2007, 17:16
Сообщение #13


Advanced Member
***

Группа: CTPAX-X
Сообщений: 121
Регистрация: 6-February 08
Пользователь №: 374
Спасибо сказали: 149 раз(а)



Сразу со 2-го пункта: ругаться могут не столько антивири, сколько системы проактивной защиты, типа тех что в Outpost Firewall и Kaspersky Internet Security. ArtMoney и прочие трейнеры не пишут в область кода другого процесса, поэтому тут надо будет проверять работу с такими прогами. Дома смогу проверить работоспособность с Аутпостом, тока дельфя не установлена - выкладывай откомпиленный tongue.gif

3. Для обновления можно юзать ещё такой алгоритм:
- при запуске прога проверяет обновление
- скачивает его и сохраняет во временный файл с произвольным именем
- запускает временный файл на исполнение (можно с параметром, указывающим что это первый запуск новой версии)
- оригинал завершает работу
- временный файл после проверки что оригинал завершился переименовывает себя в нормальное имя (на сколько я знаю, переименование запущенных файлов в винде допускается) и продолжает нормально выполняться

Если прога ходит за обновлениями в инет, то надо особенно тщательно проверить работоспособность этого алгоритма с разными системами защиты (антивирями, проактивками), потому что если сначала будет предупреждение о модификации explorer.exe, а потом ещё и в инет прога полезет, то опытного пользователя будет очень нелегко убедить что она за обновлением полезла smile.gif))

ЗЫ: про вирусы-трояны я конечно пошутил, но среди этих зверьков попадаются настоящие произведения программерского искусства, которые писались явно не дураками =)
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 5 2007, 09:23
Сообщение #14


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(Axsis @ Jul 4 2007, 05:16 PM) *
Сразу со 2-го пункта: ругаться могут не столько антивири, сколько системы проактивной защиты, типа тех что в Outpost Firewall и Kaspersky Internet Security. ArtMoney и прочие трейнеры не пишут в область кода другого процесса, поэтому тут надо будет проверять работу с такими прогами. Дома смогу проверить работоспособность с Аутпостом, тока дельфя не установлена - выкладывай откомпиленный tongue.gif
Насчёт области кода и области данных... х.з. Есть же трейнеры, которые память патчат, чтобы жизнь вообще не отнималась (*улыбается*).

QUOTE
- временный файл после проверки что оригинал завершился переименовывает себя в нормальное имя (на сколько я знаю, переименование запущенных файлов в винде допускается) и продолжает нормально выполняться
Тоже, в принципе, "с боку припёка". (*улыбается*)

QUOTE
Если прога ходит за обновлениями в инет, то надо особенно тщательно проверить работоспособность этого алгоритма с разными системами защиты (антивирями, проактивками), потому что если сначала будет предупреждение о модификации explorer.exe, а потом ещё и в инет прога полезет, то опытного пользователя будет очень нелегко убедить что она за обновлением полезла smile.gif))
Не так - сначала ищется обновление, затем скачивается. И только потом Explorer.exe модифицируется. Нет обновления - нет запуска Explorer.exe и модификации.

QUOTE
ЗЫ: про вирусы-трояны я конечно пошутил, но среди этих зверьков попадаются настоящие произведения программерского искусства, которые писались явно не дураками =)
Я не говорил, что они дураки. Однако, назвать их "умными" было бы тоже неправильно.
Есть люди, которые просто ездят в автобусах, а есть такие, которые при этом ещё лазят по чужим карманам. Раз ты так не хочешь делать - значит они "не дураки", а ты дурак?..
ИМХО, вирусы, трояны и прочую лабудень может и пишут "не дураки", но уж точно не от большого ума.


Добавлено:
Блин, торможу - вот, лови. (*улыбается*)
dselfdel.zip
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Axsis
Jul 5 2007, 15:38
Сообщение #15


Advanced Member
***

Группа: CTPAX-X
Сообщений: 121
Регистрация: 6-February 08
Пользователь №: 374
Спасибо сказали: 149 раз(а)



QUOTE
Насчёт области кода и области данных... х.з. Есть же трейнеры, которые память патчат, чтобы жизнь вообще не отнималась (*улыбается*).

Я не знаю ни одного трейнера который бы патчил код игры, там принцип такой, что каждые несколько милисекунд трейнер восстанавливает значение в памяти на прежнее, то есть жизни отнимаются, но через несколько мс восстанавливаются, для игрока это незаметно просто smile.gif
Вот ещё отчёт с ВирусТотала для твоего файла:
CODE
Complete scanning result of "DSelfDel.exe", received in VirusTotal at 07.05.2007, 16:29:41 (CET).
Antivirus    Version    Update    Result
AhnLab-V3    2007.7.5.0    07.05.2007    no virus found
AntiVir    7.4.0.37    07.05.2007    HEUR/Malware <<<<<<<<<<<<<<<
Authentium    4.93.8    07.04.2007    no virus found
Avast    4.7.997.0    07.04.2007    no virus found
AVG    7.5.0.476    07.04.2007    no virus found
BitDefender    7.2    07.05.2007    no virus found
CAT-QuickHeal    9.00    07.05.2007    no virus found
ClamAV    devel-20070416    07.05.2007    no virus found
DrWeb    4.33    07.05.2007    no virus found
eSafe    7.0.15.0    07.05.2007    suspicious Trojan/Worm <<<<<<<<<<<<<<<
eTrust-Vet    30.8.3765    07.05.2007    no virus found
Ewido    4.0    07.05.2007    no virus found
FileAdvisor    1    07.05.2007    no virus found
Fortinet    2.91.0.0    07.05.2007    no virus found
F-Prot    4.3.2.48    07.04.2007    no virus found
F-Secure    6.70.13260.0    07.05.2007    Possibly malicious <<<<<<<<<<<<<<<
Ikarus    T3.1.1.8    07.05.2007    no virus found
Kaspersky    4.0.2.24    07.05.2007    no virus found
McAfee    5067    07.04.2007    no virus found
Microsoft    1.2701    07.05.2007    no virus found
NOD32v2    2379    07.04.2007    no virus found
Norman    5.80.02    07.04.2007    no virus found
Panda    9.0.0.4    07.05.2007    no virus found
Sophos    4.19.0    06.24.2007    no virus found
Sunbelt    2.2.907.0    07.04.2007    no virus found
Symantec    10    07.05.2007    no virus found
TheHacker    6.1.6.142    07.04.2007    no virus found
VBA32    3.12.0.2    07.05.2007    no virus found
VirusBuster    4.3.23:9    07.05.2007    no virus found
Webwasher-Gateway    6.0.1    07.05.2007    Heuristic.Malware <<<<<<<<<<<<<<<

Aditional Information
File size: 9728 bytes
MD5: 20a3c83a74dd2aeb9f64bfe4894998c0
SHA1: 416ef725c4a8837e3a19c5e74bba2b46318dca5d
packers: UPX

Как видишь, эвристические движки 4 антивирей сочли этот код потенциально опасным. Да, это редкие (очень редкие wink.gif) антивирусы, но тем не менее...
Дома ещё с аутпостом проверю, глянем на его реакцию. Ещё бы с KIS проверить, тока нету его у меня tongue.gif
QUOTE
Тоже, в принципе, "с боку припёка". (*улыбается*)

На самом деле отличие от твоей версии лишь в том что файл заменяет себя сам а не из внедрённого кода, а в остальном... тот же временный файл, та же прозрачность для пользователя, та же реализация в виде 1-го exe...
QUOTE
Не так - сначала ищется обновление, затем скачивается. И только потом Explorer.exe модифицируется. Нет обновления - нет запуска Explorer.exe и модификации.

Ну так всё-таки лучше smile.gif
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 5 2007, 17:00
Сообщение #16


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(Axsis @ Jul 5 2007, 03:38 PM) *
Я не знаю ни одного трейнера который бы патчил код игры, там принцип такой, что каждые несколько милисекунд трейнер восстанавливает значение в памяти на прежнее, то есть жизни отнимаются, но через несколько мс восстанавливаются, для игрока это незаметно просто smile.gif
Просто есть моменты, когда игра резко обнуляет жизнь и тяжко успеть восстановить значение до того, как придёт надпись "Game Over".

QUOTE
Вот ещё отчёт с ВирусТотала для твоего файла:
Ого! Моё почтение! Ты, наверное, тестированием антивирусных систем занимаешься? (*улыбается*) Спасибо тебе большое за отчёт! На самом деле были у меня подозрения, но ты их развеял. (*улыбается*) Спасибо! И правда, антивирусов, которые считают программу трояном - мало. И к тому же они все (ИМХО) аутсайдеры - т.е. их мало кто использует.

QUOTE
Как видишь, эвристические движки 4 антивирей сочли этот код потенциально опасным. Да, это редкие (очень редкие wink.gif) антивирусы, но тем не менее...
Понимаю, но мне очень хочется, чтобы всё было "красиво". (*улыбается*)

QUOTE
Дома ещё с аутпостом проверю, глянем на его реакцию. Ещё бы с KIS проверить, тока нету его у меня tongue.gif
Я даже слов таких не знаю. (*улыбается*) А KIS - это что?

QUOTE
На самом деле отличие от твоей версии лишь в том что файл заменяет себя сам а не из внедрённого кода, а в остальном... тот же временный файл, та же прозрачность для пользователя, та же реализация в виде 1-го exe...
Понимаешь, с ключом-параметром, ты даёшь (теоретически) возможность пользователю самому этот ключ использовать. Он может например даже другим пользователям какую-нибудь гадость сделать. Например, запустить с этим ключом программу так, что она себя чем-нибудь другим заменит. ИМХО, чем меньше прав у пользователя - тем лучше. Он может делать всё, что не запрещено. А если есть что-то, что ему нельзя делать, но он это может - то это уже плохо. Программа должна быть кондовой: пользователь может хоть головой об компьютер долбиться, но она должна работать как надо. (*улыбается*)
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Axsis
Jul 5 2007, 20:25
Сообщение #17


Advanced Member
***

Группа: CTPAX-X
Сообщений: 121
Регистрация: 6-February 08
Пользователь №: 374
Спасибо сказали: 149 раз(а)



QUOTE
Ого! Моё почтение! Ты, наверное, тестированием антивирусных систем занимаешься? (*улыбается*) Спасибо тебе большое за отчёт! На самом деле были у меня подозрения, но ты их развеял. (*улыбается*) Спасибо! И правда, антивирусов, которые считают программу трояном - мало. И к тому же они все (ИМХО) аутсайдеры - т.е. их мало кто использует.

Хех, конечно я не вручную его проверял, есть такой замечательный сайтик http://www.virustotal.com/ на котором можно через форму загрузить свой файл и он проверится всеми этими антивирусами, всё это разумеется халявное, но вот в зависимости от загруженности сервера придётся подождать от 1 до 30 минут в очереди (+ 1-2 минуты на проверку) Поэтому когда нужно что-либо быстро проверить обхожусь онлайн-сканером каспера - http://www.kaspersky.ru/scanforvirus/ . Я думал ты слышал о вирустотал'е rolleyes.gif
QUOTE
QUOTE
Дома ещё с аутпостом проверю, глянем на его реакцию. Ещё бы с KIS проверить, тока нету его у меня

Я даже слов таких не знаю. (*улыбается*) А KIS - это что?

Аутпост - это Agnitum Outpost Firewall - фаервол, как и следует из названия smile.gif
KIS - это Kaspersky Internet Security, в который входят Kasp. AntiVirus и Kasp. AntiHacker (последнее - тоже фаервол smile.gif)
Так вот у обеих прог с некоторых пор есть проактивная защита, которая отслеживает всякие действия, которые в основном используются вредоносным ПО, такие как внедрение в адресное пространство другого процеса, установка перехватчиков нажатий клавиш, модификация критических ключей реестра и т.д.
Результатом работы этой защиты у аутпоста является вот такое окошко (как я и предполагал) :

Если нажать "Allow Once" то файл удаляется, а если "Block Once" то память не модифицируется и просто запускается проводник, то есть оригинальный explorer.exe smile.gif
Даю 99% что КИС отреагирует точно так.
QUOTE
Понимаешь, с ключом-параметром, ты даёшь (теоретически) возможность пользователю самому этот ключ использовать. Он может например даже другим пользователям какую-нибудь гадость сделать.

Помню ты упоминал что работал бета-тестером smile.gif Про параметр можно нигде не упоминать пользователи не будут даже знать о нем (кому надо тот конечно найдёт). А можно и вовсе обойтись без передачи параметра - например сделать проверку на имя exe-шника, например так (допустим у нас будет prog.exe):
- запускаем оригинал prog.exe (или prog.tmp)
- prog.exe (prog.tmp) проверяет своё расширение
если exe:
- проверка и загрузка обновления в prog.tmp, если обновления нет - продолжаем нормально работать
- prog.exe запускает prog.tmp а сам завершается
иначе:
- ждём завершения prog.exe и переименовываем себя (prog.tmp) в prog.exe
надеюсь ты поймёшь что я имел ввиду wink.gif если нет - напишу в виде норм. алгоритма а не такого бреда smile.gif
вариантов решения для конкретно этого случая (когда надо не удалить а обновить) много и ИМХО код без внедрения будет безопаснее, ведь в твоём случае, код, записываемый в explorer, "злодеи" тоже могут подправить tongue.gif и кстати, а будет ли это работать под ограниченной учётной записью? или тока с правами админа? huh.gif
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 5 2007, 21:35
Сообщение #18


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,361
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 314 раз(а)



QUOTE(Axsis @ Jul 5 2007, 08:25 PM) *
Хех, конечно я не вручную его проверял, есть такой замечательный сайтик http://www.virustotal.com/ на котором можно через форму загрузить свой файл и он проверится всеми этими антивирусами, всё это разумеется халявное, но вот в зависимости от загруженности сервера придётся подождать от 1 до 30 минут в очереди (+ 1-2 минуты на проверку) Поэтому когда нужно что-либо быстро проверить обхожусь онлайн-сканером каспера - http://www.kaspersky.ru/scanforvirus/ . Я думал ты слышал о вирустотал'е rolleyes.gif
Теперь - слышал. Ещё раз спасибо! (*улыбается*)

QUOTE(Axsis @ Jul 5 2007, 08:25 PM) *
KIS - это Kaspersky Internet Security, в который входят Kasp. AntiVirus и Kasp. AntiHacker (последнее - тоже фаервол smile.gif)
Аутпост-то я знаю. KIS первый раз слышу. Хотя предпологал, что "K" - от кашпировского.

QUOTE(Axsis @ Jul 5 2007, 08:25 PM) *
Результатом работы этой защиты у аутпоста является вот такое окошко (как я и предполагал) :

Если нажать "Allow Once" то файл удаляется, а если "Block Once" то память не модифицируется и просто запускается проводник, то есть оригинальный explorer.exe smile.gif
Даю 99% что КИС отреагирует точно так.
А-а-а! Засада. (*улыбается*) Заблочили...

QUOTE(Axsis @ Jul 5 2007, 08:25 PM) *
Помню ты упоминал что работал бета-тестером smile.gif
(*слава богу я там больше не работаю*)

QUOTE(Axsis @ Jul 5 2007, 08:25 PM) *
- ждём завершения prog.exe и переименовываем себя (prog.tmp) в prog.exe
У меня было сильно сомнение, но я всё-таки переборол свою лень и проверил твоё предложение из предыдущего поста - действительно, оказывается, во время работы .EXE файл можно переименовывать. Кхех - весело. (*улыбается*) Думаю, что это решает тогда все мои проблемы без внедрения кода. Спасибо за дельный совет (хотя какая идея и реализация были красивые... (*улыбается*))!
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0 -

 



Упрощённая версия Сейчас: 31st October 2024 - 09:29