自删除程序技术

2024-02-26 20:58
文章标签 技术 删除程序

本文主要是介绍自删除程序技术,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

'自删除程序
sub main()
dim w_s
w_s= WScript.ScriptFullName
set fso = CreateObject("Scripting.FileSystemObject")
fso.DeleteFile w_s
End Sub
exe程序的自删除 
 

程序的自删除已经不是什么新鲜的话题了,它广泛运用于木马、病毒中。试想想,当你的程序还在运行中(通常是完成了驻留、感染模块),它就自动地把自己从磁盘中删掉,这样一来,就做到了神不知鬼不觉,呵呵,是不是很cool呢?

自删除(Self Deleting)最早的方法是由 Gary Nebbett 大虾写的,太经典了,不能不提。程序如下:

#include "windows.h"

int main(int argc, char *argv[])
{
    char    buf[MAX_PATH];
    HMODULE module;
   
    module = GetModuleHandle(0);
    GetModuleFileName(module, buf, MAX_PATH);
    CloseHandle((HANDLE)4);
   
    __asm
    {
      lea     eax, buf
      push    0
      push    0
      push    eax
      push    ExitProcess
      push    module
      push    DeleteFile
      push    UnmapViewOfFile
      ret
    }
    
    return 0;
}

试试编译它,运行。怎么样?从你的眼皮底下消失了吧?是不是很神奇?

Gary Nebbett 钻了系统的一个漏洞,他的程序是关闭了 exe 文件的 IMAGE(硬编码为4),然后用 UnmapViewOfFile 解除了 exe 文件在内存中的映象,接着通过堆栈传递当前程序的路径名缓冲区指针给 DeleteFile() ,实现了程序的自删除。

Gary Nebbett 果然不愧为 WIN 系统下顶尖的底层高手。那么是否还有其他的方法实现程序的自删除呢?答案是肯定的。

在 Win9x/ME 下,还可以利用 WININIT.INI 的一些特性。在 WININIT.INI 文件里面有一个节 [Rename] ,只要在里面写入要 “Nul=要删除的文件”,那么下次系统重新启动的时候,该文件就会被自动删除了。以下是一个例子:

[Rename]
NUL=c:/SelfDelete.exe

利用这个特性,我们就可以在程序中对这个 ini 文件进行操作。值得注意的是,当需要自删除的文件多于一个的时候,就不能使用 WritePrivateProfileString 来实现,因为这个 API 会阻止多于一个“NUL=”这样的入口在同一个节里面出现,所以最好还是自己手动实现。

第三种方法是利用批处理文件。先让我们做一个试验:

创建一个 a.bat ,给它写入以下内容:

del %0.bat

现在运行它吧,屏幕一闪而过,最后留下一串字符:“The batch file cannot be found”。这时候它已经从你的硬盘中消失了。

这说明,批处理文件是可以删除自己的,于是我们可以把这个小技巧运用在自己的程序当中:

:Repeat
del "C:/MYDIR/SelfDelete.exe"
if exist "SelfDelete.exe" goto Repeat
rmdir "C:/MYDIR"
del "/DelUS.bat"

它会重复不断地搜索是否有 SelfDelete.exe 这个文件,直到删除了它为止;当删除完毕后,这个批处理文件就会把自己删除。
(注:本方法可以支持所有的 Windows 版本,即 Win9x/Me/NT/2000/XP)

用批处理文件的方法有一个缺陷,就是会突然弹出一个 DOS 窗,冷不防的吓人一跳,不过据我所知这是目前唯一可以在 WinXP 下起作用的方法。当然,最理想的方法是用 Gary Nebbett 的那种,不过它的缺陷是没法在 WinXP 下起作用。

(注:Gary Nebbett 的方法,hume已经给出了例子,所以我就不重复了,请到他的网站 http://humeasm.yeah.net 下载。)


以上的方法都是前辈高人的研究总结,可不是我原创的,不过最后我给出一个 Win32ASM 例子,演示一下用批处理文件删除程序自身的方法。


;******************************************************
;程序名称:程序自删除示例,适用于Win9x/WinMe/Win2000/WinXP
;作者:罗聪
;日期:2002-10-23
;出处:http://www.luocong.com(老罗的缤纷天地)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自“老罗的缤纷天地”(http://www.luocong.com)
;******************************************************

.386
.model flat, stdcall
option casemap:none

include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/shell32.inc
include /masm32/include/user32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/shell32.lib

DeleteExecutableBF        PROTO

.code
main:
    invoke DeleteExecutableBF
    invoke ExitProcess, NULL

;********************************************
; 模块功能:用批处理文件删除自身
; 入口参数:无
; 出口参数:无
;********************************************
DeleteExecutableBF    proc
    LOCAL    hFile                :DWORD
    LOCAL    len                  :DWORD
    LOCAL    hHeap                :DWORD   
    LOCAL    pszUnsetupPathname   :DWORD
    LOCAL    pszUnsetupPath       :DWORD
    LOCAL    pszBatFilePathname   :DWORD
    LOCAL    pBatFile             :DWORD

    jmp nextcode

    szBatFileName                 BYTE    "DelUS.bat", 0
    szOpen                        BYTE    "open", 0
    szBKSlash                     BYTE    "/", 0
    L1                            BYTE    ":Repeat", 13, 10, 0
    L2A                           BYTE    "del """, 0
    L2B                           BYTE    """", 0
    L3A                           BYTE    13, 10, "if exist """, 0
    L3B                           BYTE    """ goto Repeat", 13, 10, 0
    L4                            BYTE    "rmdir """, 0
    L5                            BYTE    """",13, 10, "del """, 0
    L6                            BYTE    """",13, 10, 0
   
nextcode:
    ; 为字符串分配堆:
    invoke GetProcessHeap
    mov hHeap, eax
    invoke HeapAlloc, hHeap, NULL, 4 * MAX_PATH + 1000
    mov pszUnsetupPath, eax
    add eax, MAX_PATH
    mov pszUnsetupPath, eax
    add eax, MAX_PATH
    mov pszUnsetupPathname, eax
    add eax, MAX_PATH   
    mov pszBatFilePathname, eax
    add eax, MAX_PATH       
    mov pBatFile, eax

    ; 创建一个批处理文件,用于删除我们的exe文件。当exe文件被删除后,这个批处理文件会自动删除自己,以及它所在的目录。

    ; 得到 temp 目录的路径:
    invoke GetTempPath, MAX_PATH, pszBatFilePathname

    invoke lstrcat, pszBatFilePathname, addr szBatFileName
    invoke CreateFile, pszBatFilePathname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                   FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, NULL
    mov hFile, eax
    .if (hFile != INVALID_HANDLE_VALUE)

    ; 得到我们的 exe 文件的全路径(包括文件名):
    invoke GetModuleFileName, NULL, pszUnsetupPathname, MAX_PATH

    ; 得到我们的 exe 文件的路径(不包括文件名):
    invoke lstrcpy, pszUnsetupPath, pszUnsetupPathname

    ; 找到路径最后的 ’/’ 并把它改成0
    mov edx, pszUnsetupPath
    mov ecx, edx
    .repeat
        mov al, byte ptr [edx]
        .if al == 92 ; "/"
            mov ecx, edx
        .endif
       inc edx
    .until al == 0
        mov byte ptr [ecx+1], 0  

        ; Bat 文件的内容:
        ; :Repeat
        ; del "C:/Win95ADG/DelSelf.exe"
        ; if exist "DelSelf.exe" goto Repeat
        ; rmdir "C:/Win95ADG"
        ; del "c:/%temppath%/DelUS.bat"
        invoke lstrcat, pBatFile, addr L1
        invoke lstrcat, pBatFile, addr L2A
        invoke lstrcat, pBatFile, pszUnsetupPathname
        invoke lstrcat, pBatFile, addr L2B
        invoke lstrcat, pBatFile, addr L3A
        invoke lstrcat, pBatFile, pszUnsetupPathname
        invoke lstrcat, pBatFile, addr L3B
        invoke lstrcat, pBatFile, addr L4
        invoke lstrcat, pBatFile, pszUnsetupPath
        invoke lstrcat, pBatFile, addr L5
        invoke lstrcat, pBatFile, pszBatFilePathname
        invoke lstrcat, pBatFile, addr L6

        ; 创建 bat 文件:
        invoke lstrlen, pBatFile
        mov len, eax
        invoke WriteFile, hFile, pBatFile, len, addr len, NULL
        invoke CloseHandle, hFile

        ; 现在在后台执行我们的 bat 文件:
        invoke ShellExecute, NULL, addr szOpen, pszBatFilePathname, NULL, NULL, SW_HIDE

    .endif
   
    ; 释放堆:
    invoke HeapFree, hHeap, NULL, pszUnsetupPath
return:
    ; 结束啦!
    ret

DeleteExecutableBF    endp

end main
;********************    over    ********************
;by LC
 
 
 
    一、问题的提出

在VC++编写程序的过程中,有时可能会遇到可执行文件加载到内存中运行,在结束返回时需要删除该文件自身的情况。一般情况下,因为可执行文件的映像还在内存中,删除该文件会导致“无法删除文件:拒绝访问。源文件可能正被使用”的错误提示,所以用常规方法不能实现这个功能。


二、解决原理

可以通过多进程的方法解决这个问题。可执行文件在结束返回前,创建一个运行命令窗口的新进程,当然该命令窗口以隐藏方式执行,并通过传递参数执行删除功能。为了避免可执行文件的映像还在内存中就执行删除,需要把当前进程设置为实时优先级,而命令窗口进程设置为很低的IDLE优先级,这样首先可执行文件结束返回,再运行命令窗口的删除命令,就实现了该文件自身的删除功能。


三、关键函数的调用

SelfDelete()完成的功能是可执行文件在运行中删除本文件,实现方法是调用命令窗口来删除运行的文件。命令窗口程序是由环境变量COMSPEC定义的,Win9x/ME使用COMMAND.COM,WinNT/2K/XP使用CMD.COM。程序把命令字符串“/c del filename > nul”传递给命令窗口,其中filename是需要删除文件的全路径文件名,文件名需要转换为8.3格式;/c开关用于命令窗口退出。

命令窗口通过调用ShellExecuteEx()函数以单独的进程运行,它的窗口句柄在SHELLEXECTUEINFO结构中的成员变量hProcess定义。自删除需要解决一个特殊的问题,即主程序必须在命令窗口删除它之前退出并关闭其打开的文件句柄。为了做到这一点,我们必须同步两个独立、并行的进程:当前程序进程和命令窗口进程。这可以通过操作CPU资源优先级来临时降低命令窗口的运行优先级别。这样,主程序将分配到CPU的所有资源直到其正常退出,而阻塞其它任何命令窗口的执行直到主程序结束。设置REALTIME_PRIORITY_CLASS和THREAD_PRIORITY_TIME_CRITICAL优先级会引起窗口悬挂状态,为了避免出现该问题,自删除应用必须通过返回TRUE来彻底退出。程序员需要确定在删除文件执行前完成所有进程和线程和关闭所有句柄。SelfDelete()一定要在程序的main函数中调用。

一些限制:

1、出现错误时命令窗口不能删除文件,但程序没有错误检查,因此确认需要删除的文件没有设置为隐藏、系统和只读属性;

2、尽管出现错误时命令窗口并没有真正删除文件,但是资源浏览器还是会删除程序图标,这时可按F5键更新文件夹以显示正确的文件列表;

3、命令窗口只能运行一个命令,多个文件删除命令和以及删除其所在的目录需要使用命令描述文件。


四、主要代码

以下代码在VC++6.0通过编译链接。

INT APIENTRY WinMain(...)

{

...


// on program exit

// close all handles etc.

if(!SelfDelete())

{

// add error messaging

}

return 0; // WinMain exit

}


#include

#include


BOOL SelfDelete()

{

SHELLEXECUTEINFO sei;


TCHAR szModule [MAX_PATH],

szComspec[MAX_PATH],

szParams [MAX_PATH];


// get file path names:

if((GetModuleFileName(0,szModule,MAX_PATH)!=0) &&

(GetShortPathName(szModule,szModule,MAX_PATH)!=0) &&

(GetEnvironmentVariable("COMSPEC",szComspec,MAX_PATH)!=0))

{

// set command shell parameters

lstrcpy(szParams,"/c del ");

lstrcat(szParams, szModule);

lstrcat(szParams, " > nul");


// set struct members

sei.cbSize = sizeof(sei);

sei.hwnd = 0;

sei.lpVerb = "Open";

sei.lpFile = szComspec;

sei.lpParameters = szParams;

sei.lpDirectory = 0;

sei.nShow = SW_HIDE;

sei.fMask = SEE_MASK_NOCLOSEPROCESS;


// invoke command shell

if(ShellExecuteEx(&sei))

{

// suppress command shell process until program exits

SetPriorityClass(sei.hProcess,IDLE_PRIORITY_CLASS);

SetPriorityClass(GetCurrentProcess(),

REALTIME_PRIORITY_CLASS);

SetThreadPriority(GetCurrentThread(),

THREAD_PRIORITY_TIME_CRITICAL);


// notify explorer shell of deletion

SHChangeNotify(SHCNE_DELETE,SHCNF_PATH,szModule,0);

return TRUE;

}

}

return FALSE;

}

 


<script type="text/javascript"> google_ad_client = "pub-2416224910262877"; google_ad_width = 728; google_ad_height = 90; google_ad_format = "728x90_as"; google_ad_channel = ""; google_color_border = "E1771E"; google_color_bg = "FFFFFF"; google_color_link = "0000FF"; google_color_text = "000000"; google_color_url = "008000"; </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

这篇关于自删除程序技术的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/750139

相关文章

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

系统架构设计师: 信息安全技术

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师: 信息安全技术前言信息安全的基本要素:信息安全的范围:安全措施的目标:访问控制技术要素:访问控制包括:等保

前端技术(七)——less 教程

一、less简介 1. less是什么? less是一种动态样式语言,属于css预处理器的范畴,它扩展了CSS语言,增加了变量、Mixin、函数等特性,使CSS 更易维护和扩展LESS 既可以在 客户端 上运行 ,也可以借助Node.js在服务端运行。 less的中文官网:https://lesscss.cn/ 2. less编译工具 koala 官网 http://koala-app.

Spring的设计⽬标——《Spring技术内幕》

读《Spring技术内幕》第二版,计文柯著。 如果我们要简要地描述Spring的设计⽬标,可以这么说,Spring为开发者提供的是⼀个⼀站式的轻量级应⽤开发框架(平台)。 作为平台,Spring抽象了我们在 许多应⽤开发中遇到的共性问题;同时,作为⼀个轻量级的应⽤开发框架,Spring和传统的J2EE开发相⽐,有其⾃⾝的特点。 通过这些⾃⾝的特点,Spring充分体现了它的设计理念:在

java线程深度解析(六)——线程池技术

http://blog.csdn.net/Daybreak1209/article/details/51382604 一种最为简单的线程创建和回收的方法: [html]  view plain copy new Thread(new Runnable(){                @Override               public voi

java线程深度解析(二)——线程互斥技术与线程间通信

http://blog.csdn.net/daybreak1209/article/details/51307679      在java多线程——线程同步问题中,对于多线程下程序启动时出现的线程安全问题的背景和初步解决方案已经有了详细的介绍。本文将再度深入解析对线程代码块和方法的同步控制和多线程间通信的实例。 一、再现多线程下安全问题 先看开启两条线程,分别按序打印字符串的

SSM项目使用AOP技术进行日志记录

本步骤只记录完成切面所需的必要代码 本人开发中遇到的问题: 切面一直切不进去,最后发现需要在springMVC的核心配置文件中中开启注解驱动才可以,只在spring的核心配置文件中开启是不会在web项目中生效的。 之后按照下面的代码进行配置,然后前端在访问controller层中的路径时即可观察到日志已经被正常记录到数据库,代码中有部分注释,看不懂的可以参照注释。接下来进入正题 1、导入m

嵌入式技术的核心技术有哪些?请详细列举并解释每项技术的主要功能和应用场景。

嵌入式技术的核心技术包括处理器技术、IC技术和设计/验证技术。 1. 处理器技术    通用处理器:这类处理器适用于不同类型的应用,其主要特征是存储程序和通用的数据路径,使其能够处理各种计算任务。例如,在智能家居中,通用处理器可以用于控制和管理家庭设备,如灯光、空调和安全系统。    单用途处理器:这些处理器执行特定程序,如JPEG编解码器,专门用于视频信息的压缩或解压。在数字相机中,单用途