· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Как удолить самого себя?????

. 1 . 2 . >>

Посл.отвђт Сообщенiе


Дата: Мар 1, 2003 15:32:13

Есть ли у кого нибудь исходника как при работе приложения удольть самого себя?????


Дата: Мар 1, 2003 17:43:15

А что будет если приложение запущено с CD-R? :)
---------------------------
Извините... не удержался. Можно закрыть приложение и удалить его позже посредством другого приложения (например, при следующей загрузке Windows). А ещё, можно запускать приложение через BAT-файл и удалять его делетом:
prog.exe
del prog.exe
Правда, парсер BAT'ов ведёт себя по-разному на разных виндах, т.е. CMD на XP ждёт завершения prog.exe перед тем как запустить del, а COMSPEC на 9x выполняет del сразу. (Или всё наоборот... :)


Дата: Мар 1, 2003 19:23:56

Можно создать тред в другом процессе и вызвать в нем функцию WaitForSingleObject с параметром - хэндлом процесса. После завершения можно удалять.


Дата: Мар 1, 2003 19:59:36

Можно проще: в куче (спокойней как-то) написать свое имя, потом подготовить стек, чтоб после возврата из FreeLibrary (на себя) мы приехали на DeleteFile и потом - ExitProcess или что-там-нужно.
Или можно исполняться прям в стеке. Вариантов - масса.


Дата: Мар 2, 2003 00:35:57

Songoku->
90210: Так кинь исходник!!!!


Дата: Мар 2, 2003 13:37:59


Дата: Мар 3, 2003 08:01:57

По просьбам трудящихся.

#include <windows.h>

void main(int argc, char *argv[])
{
HMODULE kernel=GetModuleHandle("kernel32.dll");

DWORD fl=(DWORD)GetProcAddress(kernel,"FreeLibrary");
DWORD df=(DWORD)GetProcAddress(kernel,"DeleteFileA");
DWORD ep=(DWORD)GetProcAddress(kernel,"ExitProcess");

char mynameis[MAX_PATH];

DWORD wearedata=(DWORD)GetModuleHandle(0);
GetModuleFileName((HMODULE)wearedata,mynameis,sizeof mynameis);

CloseHandle((HANDLE)4); //close section object
wearedata++; //dirty trick - say we are dll loaded
//with LOAD_LIBRARY_AS_DATAFILE :)
__asm {
lea eax,mynameis
push 0
push 0
push eax
push ep
push wearedata
push df
push fl
ret
}
}


Дата: Мар 3, 2003 11:25:11

Плиз можна пару слов по поводу CloseHandle(4)
Со стеком все понятно - у Гарри Неббета вместо трика с FreeLibrary
стоит UnmapViewOfFile.
А шо такое CloseHandle(4) непонятно


Дата: Мар 3, 2003 14:36:00

Когда создается процесс, то первым делом создается объект "раздел" (section object), для того чтобы спроецировать туда исполняемый файл. Это самый первый объект в процессе, поэтому его хэндл равен 4 (все хэндлы кратны 4, хэндла 0 не существует - его место зарезервировано). Вот CloseHandle(4) именно и закрывает раздел.


Дата: Мар 15, 2003 01:29:55

Я еще немного по-надоедаю :) теперь уже в этой ветке. Вот какие три вопроса вызвал у меня вышеизложенный материал:

1)В тексте примера программы от 90210 есть строчка wearedata++. А для чего она нужна? Ну будет в большинстве случаев wearedata сначала 40000h, а потом 40001h - и что? Зачем это надо?

2)Теперь ключевой момент программы по ссылке "Self-Deleting Executables"(см. выше):

char buf[MAX_PATH];
....
lea eax, buf
push 0
push 0
push eax
push ExitProcess
push module
push DeleteFile
push UnmapViewOfFile
ret

Я переписал все это на асме и... не работает! И правильно не работает, по-моему. Вот смотрите, если разложить последний фрагмент "по-полчкам":
A)Мы размэппируем наш экзешник вызовом UnmapViewOfFile с параметром module(хэндл). Тут все отлично, выгрузили файл.
B)Вызываем ф-ию DeleteFile с параметром eax==>buf(т.е. eax кажет на некий буфер). Так ведь этот буфер - участок памяти нашего УЖЕ ВЫГРУЖЕННОГО!!! файла. И вполне резонно моя прога говорит: память по адресу buf "can't be reading" - читать-то уже нечего! Вот если бы DeleteFile то же принимал хэндл(число в регистре) то да, все работало бы. А так...
Вопрос простой - чего я не допонял. :)

3)В заключении статьи по вышеупомянутой ссылке говорится:"This snippet ONLY works under Windows NT". Почему же ONLY? Правда в хелпе по UnmapViewOfFile в WinAPI32.hlp говорится:

Windows 95: Files for which the last view has not yet been unmapped are held open with the same sharing restrictions as the original file handle.
*****
Windows NT: Files for which the last view has not yet been unmapped are held open with no sharing restrictions.

Но ведь вызовом UnmapViewOfFile мы "unmapped last view", так? Или дело совсем-совсем не в этом?


Дата: Мар 15, 2003 23:25:44

1. Это для обмана FreeLibrary - чтоб вместо LdrUnloadDll вызывалось LdrUnloadAlternateResourceModule сотоварищи.
2. Ты абсолютно прав насчет выгруженной памяти. Поэтому надо использовать или кучу, или стек. Стек проще - сишные компилеры автоматом суют локальные переменные в стек процедуры. char buf[MAX_PATH], например.


Дата: Мар 16, 2003 14:42:52 · Поправил: Four-F

К сказанному выше могу добавить, что на асме это должно выглядеть так (инклуды стандартные, которые с jump-table):

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

.code

start proc

option EPILOGUE:NONE

local buf[MAX_PATH]:CHAR

invoke GetModuleFileName, NULL, addr buf, sizeof buf
invoke CloseHandle, 4

lea eax, buf
push 0
push 0
push eax

mov eax, ExitProcess
mov eax, [eax+2]
push [eax] ; push ExitProcess

invoke GetModuleHandle, NULL
push eax

mov eax, DeleteFile
mov eax, [eax+2]
push [eax] ; push DeleteFile

mov eax, UnmapViewOfFile
mov eax, [eax+2]
push [eax] ; push UnmapViewOfFile

ret

start endp

end start


На ХР скорее всего работать не будет из-за CloseHandle, 4.
Что-то M$ там переделала: то ли хендл секции не равен 4, то ли она вообще хендла не имеет.
Щас возможности протестить под ХР нет. Прогоните у кого хрюша.


Дата: Мар 16, 2003 19:05:10

To:Four-F
Что-то не работает пример на 98-ом.


Дата: Мар 16, 2003 23:46:41

Тэк-с, что могу сказать:

1)Идея, что для буфера с именем файла под удаление надо использовать стек - то, что надо. Теперь ошибки "can't be reading" нет.

2)Легче от этого не стало. :) Теперь ф-ия DeleteFile "нормально" отрабатывает(т.е. нет упомянутой выше ошибки), но в EAX возвращается 0, а последующий вызов GetLastError говорит об этом:
// MessageId: ERROR_SHARING_VIOLATION
//
// MessageText:
//
// The process cannot access the file because it is being used by another process.
//
#define ERROR_SHARING_VIOLATION 32L

3)CloseHandle,4 отрабатывается на ура, EAX=1. Так что что-то такое под номером 4 мы закрываем. Но что именно?

4)Если предположить, что п.3 закрывает все-таки section object, то есть такая мысль(возможно ересь):наш процесс самоудаления(назовем его SelfDestroy.exe) порождается кернелом при помощи CreateProcess. При этом создаюся:объект ядра ПРОЦЕСС+объект ядра ВЕТВЬ.
Хэндлы этих объектов должны быть закрыты(помимо всего прочего) и самим кернелом иначе ядро эти объекты не разрушит. Так вот если кернел закрывает эти хэндлы только ПОСЛЕ возврата из SelfDestroy.exe(а наверное так оно и есть) то мы никак эти объекты удалить не сможем. А ересь заключается в том, что вполне возможно наличие объекта ПРОЦЕСС НЕ ПРЕПЯТСТВУЕТ удалению файла содержащего код этого процесса(разумеется файл должен быть размэппирован). Вот, тут у меня пробел в знаниях. :(

P.S. Все опыты из данной мессаги проводились как-раз под XP. Хотя выше сказано, что и в 98-м картина столь же безрадостна. :) Просто какой-то фантомный код - работать должен(судя по публикациям), но никто его работающим не видел. :)


Дата: Мар 17, 2003 01:30:24 · Поправил: Four-F

[ Asterix: Что-то не работает пример на 98-ом. ]

Оно и не задумывалось под 9x. Только NT, 2000 и очень маловероятно ХР.
Этот код придумал Гари Неббет (автор книги "Windows NT-2000 Native API Reference").
Придуман он во времена, когда 2000 только появилась (или где-то около того).
И работать он будет только на клоне NT. У мя под 2000 Pro работает.


Smarty, все твои траблы под ХР, IMHO, потому, что M$ изменила что-то.
То что "CloseHandle,4 отрабатывается на ура" совсем не значит, то закрывается именно хендл секции образа. И скорее всего именно так. Поэтому видимо и после DeleteFile возвращается такая ошибка, т.е. хэндл секции не закрыт.

Я даже думаю, что хэндла секции вообще не создается, т.к. юзерному процессу он не за чем.
Косвенно об этом мне говорит тот факт, что в 2000 в структуре EPROCESS поле SectionHandle равно 4 для всех процессов.

; w2k
EPROCESS STRUCT
. . .
SectionHandle PVOID ? ; 1ACh
. . .
SectionBaseAddress PVOID ? ; 1B4h
. . .
EPROCESS ENDS

А в ХР в структуре EPROCESS вместо SectionHandle появилось SectionObject (указатель на SECTION_OBJECT). Т.е. ядро просто не делится с юзером хендлом.

; xp
EPROCESS STRUCT
. . .
SectionObject PVOID ? ; 0138h
SectionBaseAddress PVOID ? ; 013ch
. . .
EPROCESS ENDS

Но это все мои догадки. Будет возможность гляну под ХР.
Что касается всех незакрытых хендлов и удаления созданных CreateProcess объектов, то это работа для ExitProcess.
И никакой прямой связи с секцией образа тут нет. Просто при загрузке образа в память работает механизм проецирования файлов.
Такая память должна быть поддержана либо файлом подкачки, либо (в нашем случае) самим образом exe, лежащим на диске.
Из-за этого-то и нельзя удалить запущенный экзешник. Как только объект секция исчезает сразу становится возможным удалить файл образа с диска - в этом "CloseHandle, 4" вся соль этого кода, остальное ерунда.

. 1 . 2 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.133