我以前发现一些EXE文件在运行时,可以让其文件本身消失(全是病毒EXE)从进程来看,文件名与路径还是那个,不过文件本身已经没了.我想过可能是对显示的一种欺骗,也有可能是真的"一次性运行".但水平真的非常有限,所以也没去管它.后来自己写了一个游戏更新软件,使用ISCSI协议,客户端是直接在服务器上共享运行的.有一次,主机死了机.可是我正好开着这个软件,发现一个问题:它还是在正常运行!只是一点读取游戏,就报错退出了.后来想想,就试验了一下,共享一个文件夹,并放入一个EXE文件,再在自己机器上用网络路径运行它.如\\127.0.0.1\dir\1.exe然后把这个共享文件夹强行解除共享.此时,只要这个1.EXE不读写硬盘,可以正常地运行.现在想与大家讨论一下,这个过程中,是怎么回事?WINDOWS是如何处理这个问题的?好象系统在网络上运行EXE时,已经把它放在了一个特殊的地方,当有读写硬盘请求时,再映射到网络地址上去的.如果真是这样,有什么办法可以把它利用到程序中来呢?并且WINDOWS自己好象很简单就实现了一样....讨论吧....吃饭了.......

解决方案 »

  1.   

    印象中当初在看WinXP的一些资料时,就看到在WinXP及其以上版本的操作系统当中带有这一功能,并且支持如DLL文件的随时更新.建议还是找一些相关操作系统的资料看一下吧,特别是MS Windows相关的一些技术方档.
      

  2.   

    这和删除运行中的EXE文件好象并不是一回事情。W系统允许你强制关闭服务器也是合理的,否则只要有活动客户就不能关闭服务那就是主宾颠倒了。
      

  3.   

    这也不太对头.如果是:"你已经将数据读到你的内存中了,目前运行的数据内存中有,自然不读原文件,读的数据内存中没有时才读文件,这时程序才发觉没了文件,才报错,这是很正常的。"这样的话,为什么本地文件不是这样的?你直接运行一个EXE,系统会让你删除它吗?你没有注意我所说的一句话:"好象系统在网络上运行EXE时,已经把它放在了一个特殊的地方,当有读写硬盘请求时,再映射到网络地址上去的."我的意思是说,"直接在本地运行EXE"与"在网络上运行EXE"中,它们的运行原理分别是什么?如果能在本地运行时也模拟出网络上运行的环境,并让系统把本地文件以后者的方式运行,那么就非常的方便了!!(比如更新自己)这么说,大家明白了吗?希望继续讨论~~~~~
      

  4.   

    我认为应该是读取到内存,再在在内存运行,取数据时候,内存中没有的才到硬盘取。但是win为了保护正在运行的exe不能出差错,所以对正在运行的exe进行保护。
    好像内存中正在运行的exe和硬盘中的exe文件 之间有个关联。
    所以单机要实现打破这个关联 ,可能不容易。
    但是网络就容易了, 你断网的时候,通常都会提醒“有其他用户连接到本机”,你可以强行断开这个关联的。其实要实现是不难,用新建其他文件,再运行他,来删除自己。 更新的软件都是专门有更新的程序的,更新的时候必须关闭主程序。比如tm。
    如果更新的时候可以不用关闭主程序,则可能更新的是其他的一些部件把。
      

  5.   

    总的说来还是不太容易那么要在本地运行时模拟出这个网络运行的状态,有可能吗?WINDOWS内部是如何处理这个机制的?也许有一种内存访问方式,可以不建立EXE与进程间的联系?
      

  6.   

    以前讨论过好多次了,最后还是用的Bat文件法.最稳定可靠.
      

  7.   

    BAT文件法是"在EXE运行结束后删除自身"时非常有效但我这次要实现的是---------"在EXE文件还在运行时,就删除硬盘上的EXE文件."也就是说,进程还在,相应的EXE文件已经没了.用我的那个网络共享法可以实现,只是有点绕路.我想,WINDOWS应该有这种机制在里面的,只是没有去注意!如果哪位对系统底层及系统原理研究得比较透的朋友可以注意一下的话,也许能写出比较简单的方案来实现这个功能也说不定!!
      

  8.   

    大概不管这方法怎么做,都很容易出问题吧。
    事实上windows有个叫做dllcache的文件夹,作用就是缓冲加载中的dll和程序,不过仅仅是猜测windows XP通过这种方法使得“无文件运行”可行。所以也猜测,只要能够欺骗windows关于程序文件宿主的检测,令windows以为文件没有被引用就可以了。具体的需要查资料,而且可以肯定的是用这种方法是不能成功地在2000下实现的,若要保证在2000下也能实现一样的效果可能必须使用驱动程序进入ring3大肆修改了,大概。
      

  9.   

    也有一种可能性,exe产生的进程完全读取进内存之后就可以安定,在这个状态下只要没有发生对宿主exe的访问就不会破坏这个安定状态。如果是这样的情况,那么创造无文件的程序可能很简单:载体程序产生主功能线程,并将其插入某个系统进程-〉载体与线程脱离关系(这种方法我不知道要怎么做)-〉线程删除载体,或者将其移动到某个新位置-〉线程通过自身代码创建进程,并初始化、伪造文件宿主
    大概是这样的思路吧。
      

  10.   

    其实要在程序还运行的时候就删除exe文件,要在底层入手,不可能再利用windows提供的api另外把程序完全载入内存,再执行内存里面的那个程序,也是一个办法。
      

  11.   

    #include <windows.h>
    #include <shellapi.h>
    #include <stdio.h>
    #include <wchar.h>int DeleteMyExe();int main()
    {
    MessageBox(NULL,"a","b",MB_OK);
    DeleteMyExe();
    return 0;
    }
    int DeleteMyExe()
    {
    TCHAR tcsExename[MAX_PATH];
    TCHAR tcsParam[MAX_PATH * 2];
    TCHAR tcsCmd[MAX_PATH];
    HANDLE hProcess = NULL; // get exe filename and command shell program
    GetModuleFileName(NULL, tcsExename, MAX_PATH); 
    GetEnvironmentVariable(("COMSPEC"), tcsCmd, MAX_PATH); // get short filename for command shell program
    GetShortPathName(tcsExename, tcsExename, MAX_PATH);

    // create a command process, set its priority, then start it.
    STARTUPINFO si;
    PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) );
    si.cb          = sizeof(si);
    si.dwFlags     = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    ZeroMemory( &pi, sizeof(pi) ); sprintf(tcsParam, ("%s /c del %s"), tcsCmd, tcsExename);
    if(!CreateProcess(NULL,
      tcsParam,
      NULL,
      NULL,
      FALSE,
      CREATE_SUSPENDED,
      NULL,
      NULL,
      &si,
      &pi))
    {
    return GetLastError();
    } // heigthen priority of the current process
    SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);     // set file attribute to normal 
    SetFileAttributes(tcsExename, FILE_ATTRIBUTE_NORMAL); // depress priority of command process, then start it
    SetPriorityClass(pi.hProcess, IDLE_PRIORITY_CLASS);
    ResumeThread(pi.hThread);
        return 0;
    }
    这是我用的自己删除自己
      

  12.   

    但是使用"共享删除法"(暂时这样叫吧)时,却是可以在任何有共享功能的WINDOWS系统上使用成功的.我的意思是,在"共享运行程序"时,也许WINDOWS有另一套机制来处理这种情况的.....这种机制要是能在"磁盘运行程序"时,也能模拟出来,就太好了!!不知道大家觉得我这个思路是否正确?我觉得应该是有这样一个东西在里面!!你们看.磁盘运行时,是这样:      硬盘---->内存而在网络共享里运行时,多了几个环节:      硬盘---->文件共享服务+网络----->内存在前者方式下运行时,想要切断"运行中EXE文件"的硬盘与内存间的联系的话,也许很困难;可是在后一种方式下,只要让文件共享服务或网络间任意一个失效,就可以切断这两者的联系了---而这并不难(相比前者)那么,如果我们能搞清楚网络运行时WINDOWS处理EXE的机制的话,就可以写出"无EXE文件运行"的程序!!大家觉得呢?
      

  13.   

    你已经将数据读到你的内存中了,目前运行的数据内存中有,自然不读原文件,读的数据内存中没有时才读文件,这时程序才发觉没了文件,才报错,这是很正常的。这个说的很对,程序本身虽然不大,但他调用的东西太多,涉及方方面面,一个过程结束后,他占用的内存也随之over了,那么再次调用这个过程的时候,程序会首先检查源数据,检查不到自然会报错,没什么大惊小怪程序运行后,如果没有任何操作,那么他占用的内存只可能越来越少,不可能越来越多双机互连的情况下,程序数据虽然突然中断,但程序本身没有进行什么操作,或者进行这一些少量的
    重复性操作(基于windows的缓存机制,可能一时半会还是不会报错的)但只要执行新的任务肯定就报错,因为程序需要读取源代码进行执行//...找不到了自然错了
      

  14.   

    劝楼主用Bat法算了,可靠又方便,何必给自己找麻烦呢?PS.那个C++的方法见过,好像是利用文件的硬件句柄实现的,不过在Win9x下不行.
      

  15.   

    好象灰鸽子病毒运行了以后就找不到它本来的EXE文件
    不知道它是设置了隐藏还是把文件给删除了
    好象听说可以把文件写到内存里   然后在内存里运行
    这样就可以把文件给删除了   不然的话   程序运行中怎么可以把文件给删除了呢
    单单要删除程序本身的话可以用BAT文件来删除嘛
    这个问题讨论的很好    大家继续讨论呀
      

  16.   

    呵呵,不是一般的"如何删除自身",而是:"如何在运行时,删除自身"在NTFS下,好象可以运行一个文件,再把它的文件改名的功能.但还是不能删除的.我主要就是想要知道如何在EXE运行时,让它的硬盘文件已经被删除.这个方法我认为是比较值得讨论的......
      

  17.   

    自己COPY 自己的一个副本,变成TMP文件,然后创建新进程(就是自己第副本),然后关闭自己。这个新的进程打开之后删除原来的母本文件。
       需要参数来确定哪个是副本那个是母本,需要用事件等待母本关闭,然后副本删除。