FAQ по C/C++/Visual C++
![]() Работа с сетью![]() ![]() Как создать ярлык![]() ![]() ![]() Вариант Yura Nev |
Составители: SUnteXx, Leprecon |
| Как удалить прогу из самой себя | |||
|
Суть в следующем. Пока библиотека загружена в память хоть одним процессом, писать в нее или удалить не получится, поскольку файл открыт. Следовательно, его надо закрыть. Для этого используем FreeLibrary, но она (насколько я понимаю) перед выходом проверяет адрес возврата (на входе это dword ptr [esp]) на валидность (что-нибудь вроде IsBadCodePtr) и если адрес плохой, завершает весь процесс. Eсли просто написать FreeLibarary(GetModuleHandle(0)); RETADDR: DeleteFile();то адресом возврата будет RETADDR, который находится как раз в нашем файле, а поскольку мы его выгрузили из процесса, то к нему обратиться нельзя и FreeLibrary завершит процесс, и все что после RETADDR не выполнится. Поэтому адресом возврата из FreeLibrary мы делаем DeleteFile, а оттуда - ExitProcess. // File "Suicide.cpp" by YuraN
#ifndef _INC_WINDOWS
#include <windows.h> //Требуется Виндовс.аш
#endif
void __fastcall Suicide(UINT);
void __declspec(naked) __fastcall Suicide(UINT exitcode)
{
__asm{
mov ebp,esp // char name[127];
sub esp,127-4 // 4 байта это адрес возврата, он нам не нужен
xor ebx,ebx // ebx = 0
push 127 // 127 // nSize
push ebp // dword ptr [name] // lpFilename
push ebx // 0 // hModule
call dword ptr [GetModuleFileName] // GetModuleFileName(0,m,127);
push ecx // exitcode // Параметр uExitCode для ExitProcess
push ebx // 0 // Адрес выхода из ExitProcess (он не используется системой)
push ebp // dword ptr [name] // Параметр lpFileName для DeleteFile
push dword ptr [ExitProcess] // Адрес выхода из DeleteFile
push ebx // 0 // Параметр lpModuleName для GetModuleHandle
call dword ptr [GetModuleHandle] // GetModuleHandle(0) как
push eax // HMODULE // Параметр hLibModule для FreeLibrary
push dword ptr [DeleteFile] // Адрес выхода из FreeLibrary
jmp dword ptr [FreeLibrary] // Вместо call используем jmp
}
}В этом коде делается следующее:Первые две строки - выделяем в стеке 127 байт для name Третья - для оптимизации :) Следующие четыре - GetModuleFileName(0,name,127); Остальные - FreeLibrary(GetModuleHandle(0)); DeleteFile(name); ExitProcess(0); - не передавая управление в наш модуль. | |||
|
|
FAQ составлен по материалам Форума на Исходниках.Ру. Copyright © 2002 by Sources.ru. All rights reserved. |