IPB

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

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


Walter Sullivan
***

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



Вот, есть такая статья: 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=-   Самоудаляющийся .EXE файл   Jun 23 2007, 10:13
-=CHE@TER=-   Немного поправил исходный код с move() и ещё пара ...   Jun 23 2007, 16:27
Siberian GRemlin   А не проще сделать генералицю .bat'ника с кома...   Jun 24 2007, 10:50
-=CHE@TER=-   А не проще сделать генералицю .bat'ника с кома...   Jun 24 2007, 13:43
-=CHE@TER=-   Гм, так и знал. EntryPoint от explorer.exe я получ...   Jun 25 2007, 12:30
Heim   Заменил local.fnWaitForSingleObject = (FAR...   Jun 28 2007, 11:29
-=CHE@TER=-   Heim! Неа, не работает. Мне нужны адреса функц...   Jun 28 2007, 11:45
Xplorer   Исправленный код: Procedure SelfDel; Assembler; As...   Jun 28 2007, 13:32
-=CHE@TER=-   Исправленный код: <cut> Адреса в kernel32.d...   Jun 28 2007, 13:56
nickolayer   Ох ты. Потрясающе. Я честно скажу, последние три с...   Jun 30 2007, 09:50
Axsis   Чё-то я не совсем понял принцип работы этого кода....   Jul 3 2007, 07:17
-=CHE@TER=-   Чё-то я не совсем понял принцип работы этого кода....   Jul 3 2007, 08:47
Axsis   Сразу со 2-го пункта: ругаться могут не столько ан...   Jul 4 2007, 17:16
-=CHE@TER=-   Сразу со 2-го пункта: ругаться могут не столько ан...   Jul 5 2007, 09:23
Axsis   Я не знаю ни одного трейнера который бы патчил ко...   Jul 5 2007, 15:38
-=CHE@TER=-   Я не знаю ни одного трейнера который бы патчил код...   Jul 5 2007, 17:00
Axsis   Хех, конечно я не вручную его проверял, есть тако...   Jul 5 2007, 20:25
-=CHE@TER=-   Хех, конечно я не вручную его проверял, есть такой...   Jul 5 2007, 21:35


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

 



Упрощённая версия Сейчас: 28th April 2024 - 13:09