Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Самоуничтожающийся проект


Автор: New Neon 1.8.2004, 21:45
Доброго всем времени суток. Дорогие програмисты не подскажете можноли создать самоудоляющиеся приложение (не исользуя реестр). Тоесть нужно создать прогу которая будет выполнятся только один раз (вроде тестового примера), а затем самоуничтожатся по её закрытии.

Примечание: проект состоит из одного исполняемого файла.

Автор: p0s0l 1.8.2004, 22:27
Создай bat-файл и запусти его, чтобы не было видно в таскбаре...
bat-файл должен пытаться удалять экзешник, при неудачных удалениях повторять попытку. А потом и себя должен удалить...
Есть и другие более изощренные методы... Когда-то в разделе C mr.Duda писал пример самоудаления через создание потока в процессе Explorer'а...

Автор: Illusion Dolphin 1.8.2004, 23:05
Код
procedure SelfDel;
var
  f : textFile;
  FileName : String;
begin
 FileName:=changefileext(paramstr(0),'.bat');
 AssignFile(f,FileName);
 Rewrite(f);
 writeln(f,':1');
 writeln(f,format('Erase "%s"',[paramstr(0)]));
 writeln(f,format('If exist "%s" Goto 1',[paramstr(0)]));
 writeln(f,format('Erase "%s"',[FileName]));
 CloseFile(f);
 ShellExecute(Application.Handle, 'Open', PChar(FileName), nil, nil, sw_hide);
 Halt;
end;

Автор: Akella 2.8.2004, 10:05
в nt такое не пройдет, т.к. bat-файл будет дочерним процессом, и пока он не завершится, родительское приложение не будет выгружено. Не зря ведь народ пытается создать отдельный поток в процессе Проводника

Автор: Illusion Dolphin 2.8.2004, 23:00
dsergey, а примерчик простой найдётся?

Автор: Akella 3.8.2004, 12:39
это к господину p0s0l

Автор: p0s0l 3.8.2004, 16:54
Цитата
в nt такое не пройдет, т.к. bat-файл будет дочерним процессом, и пока он не завершится, родительское приложение не будет выгружено. Не зря ведь народ пытается создать отдельный поток в процессе Проводника

Ну по-крайней мере в XP это пашет, хоть и дочерний процесс создаётся...

Автор: Illusion Dolphin 3.8.2004, 18:29
Цитата
Ну по-крайней мере в XP это пашет, хоть и дочерний процесс создаётся...

А в win2000 это вроде не работает... Знает ли кто-нибудь решения (только не теоретически - этого добра навалом, а кусок практики 8) )?

Автор: p0s0l 3.8.2004, 20:28
По просьбе трудящихся накатал самоудаление через CreateRemoteThread:
Код
uses TlHelp32;

function GetExplorerID : DWORD;
var
 hSnap : THandle;
 pe32 : TProcessEntry32;

begin
 Result := DWORD(-1);
 hSnap := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 pe32.dwSize := SizeOf(pe32);
 if Process32First(hSnap, pe32) then
   repeat
     if LowerCase(pe32.szExeFile) = 'explorer.exe' then
     begin
       Result := pe32.th32ProcessID;
       Break;
     end;
   until not Process32Next(hSnap, pe32);

 CloseHandle (hSnap);
end;

type
 TInjectCode = packed record
   PushOpcode : byte; // push FileName
   PushOperand : DWORD;
   CallOpcode : word; // call [DeleteFileA]
   CallOperand : DWORD;
   JzOpcode : byte; // jz @InjectCode
   JzOperand : byte;
   RetOpcode : byte; // ret
   AdrDeleteFile : DWORD; // адрес DeleteFileA
   FileName : array [0..4095] of char; // имя файла для удаления
 end;

var
 InjectCode : TInjectCode =
 (PushOpcode : $68;
  CallOpcode : $15FF;
  JzOpcode : $74;
  RetOpcode : $C3;
 );

procedure TForm1.Button1Click(Sender: TObject);
var
 hExplorer, hThread : THandle;
 adrThread : pointer;
 Delta, tmp : DWORD;

begin
 hExplorer := OpenProcess (PROCESS_ALL_ACCESS, False, GetExplorerID);

 adrThread := VirtualAllocEx (hExplorer, nil, SizeOf(InjectCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 Delta := DWORD(adrThread) - DWORD(@InjectCode);
 InjectCode.PushOperand := Delta + DWORD(@InjectCode.FileName);
 InjectCode.CallOperand := Delta + DWORD(@InjectCode.AdrDeleteFile);
 InjectCode.JzOperand := DWORD(@InjectCode) - DWORD(@InjectCode.RetOpcode);
 InjectCode.AdrDeleteFile := DWORD(GetProcAddress(LoadLibrary('kernel32.dll'), 'DeleteFileA'));
 CopyMemory (@InjectCode.FileName, PChar(Application.ExeName), Length(Application.ExeName));
 WriteProcessMemory (hExplorer, adrThread, @InjectCode, SizeOf(InjectCode), tmp);

 hThread := CreateRemoteThread (hExplorer, nil, 0, adrThread, nil, 0, tmp);
 CloseHandle (hThread);
 CloseHandle (hExplorer);
end;

Добавлено @ 20:30
Теперь, при выполнении этой процедурины в explorer'е создастся поток, который будет всё время пытаться удалить наш .exe-шник. Это ему удастся после того, как будет завершена наша прога...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)