自删除技术详解( 二 )


::wsprintf(szBat, "%s\test.bat", szPath);然后调用cmd命令行
::wsprintf(szCmd, "cmd /c call "%s"", szBat);再调用之前编写的CreateBat创建批处理文件
bRet = CreateBat(szBat);最后就是使用CreateProcess创建进程 , 但是这里有一个比较特殊的地方 , 就是我们需要隐蔽执行 , 那么我们就可以使用不显示执行程序窗口的模式 , 这个参数在CreateProcess的第九个参数 , 首先看一下CreateProcess的结构
BOOL CreateProcessA([in, optional]LPCSTRlpApplicationName,[in, out, optional] LPSTRlpCommandLine,[in, optional]LPSECURITY_ATTRIBUTES lpProcessAttributes,[in, optional]LPSECURITY_ATTRIBUTES lpThreadAttributes,[in]BOOLbInheritHandles,[in]DWORDdwCreationFlags,[in, optional]LPVOIDlpEnvironment,[in, optional]LPCSTRlpCurrentDirectory,[in]LPSTARTUPINFOAlpStartupInfo,[out]LPPROCESS_INFORMATION lpProcessInformation);就是LPSTARTUPINFOA这个参数 , 这个参数决定了新进程的主窗体如何显示的STARTUPINFO结构体 , 我们继续跟到STARTUPINFO结构体里面
typedef struct _STARTUPINFOA {DWORDcb;LPSTRlpReserved;LPSTRlpDesktop;LPSTRlpTitle;DWORDdwX;DWORDdwY;DWORDdwXSize;DWORDdwYSize;DWORDdwXCountChars;DWORDdwYCountChars;DWORDdwFillAttribute;DWORDdwFlags;WORDwShowWindow;WORDcbReserved2;LPBYTE lpReserved2;HANDLE hStdInput;HANDLE hStdOutput;HANDLE hStdError;} STARTUPINFOA, *LPSTARTUPINFOA;若要隐藏窗口 , 则dwFlags的值需要设置为STARTF_USESHOWWINDOW , wShowWindow的值设置为false即可

自删除技术详解

文章插图
 

自删除技术详解

文章插图
 
STARTUPINFO si = { 0 };si.dwFlags = STARTF_USESHOWWINDOW;si.wShowWindow = FALSE;然后调用CreateProcess启动进程
BOOL bRet = CreateProcess(NULL,szCmd, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL,NULL, &si, &pi);这里编译一下看看效果 , 这里直接退出了 , 什么也没有 , 证明是对的 , 因为我们隐藏了cmd的窗口
自删除技术详解

文章插图
 
这里我们把wShowWindow的值改为TRUE再查看一下效果
自删除技术详解

文章插图
 

自删除技术详解

文章插图
 
这里看起来效果还是不明显 , 我们再换种方式 , 直接运行exe , 发现在同目录下生成了test.bat
自删除技术详解

文章插图
 
10s过后发现exe跟bat都已经删除 , 证明我们的自删除成功
自删除技术详解

文章插图
 
上面提到 , 在xp是没有choice的命令的 , 那么可以用ping命令代替 , bat的代码如下
@echo offping 127.0.0.1 -n 10del *.exedel %0与choice相似 , 这里就不细说了 , 直接改一下代码就可以
BOOL CreateBat(char *pszBatFileName){int time = 5;char szBat[MAX_PATH] = { 0 };::wsprintf(szBat, "@echo offnping 127.0.0.1 -n %dndel *.exendel %%0n", time);FILE *fp = NULL;fopen_s(&fp, pszBatFileName, "w+");if (NULL == fp){return FALSE;}fwrite(szBat, (1 + ::lstrlen(szBat)), 1, fp);fclose(fp);return TRUE;}这里再提一个小tips , 这里我们实现的是cmd.exe的自启动与删除 , 那么在实战过程中能否写成cs的上线exe的自删除呢?答案是肯定的 , 这里就不拓展了 。
MoveFileEx方式我们首先看一下MoveFileEx这个api
BOOL MoveFileExA([in]LPCSTR lpExistingFileName,[in, optional] LPCSTR lpNewFileName,[in]DWORDdwFlags);
dwFlags:设置移动标志 , 指明要怎样操作文件或者目录 。
MOVEFILE_COPY_ALLOWED:当需要移动文件到不同的盘符时需要指定此值 , 不然会失败 , 这个值不能和MOVEFILE_DELAY_UNTIL_REBOOT一起用
MOVEFILE_DELAY_UNTIL_REBOOT:文件并不立即移动 , 当下一次机器重启时文件才执行移动  , 不能和MOVEFILE_COPY_ALLOWED同时用
【自删除技术详解】MOVEFILE_FAIL_IF_NOT_TRACKABLE:当源文件是连接资源时会移动失败 。
MOVEFILE_REPLACE_EXISTING:当目的文件已经存在时,要将lpExistingFileName的内容替换掉以前的内容,此时要检查ACL权限,可能会失败


推荐阅读