邪恶八进制信息安全团队技术讨论组's Archiver

zshoucheng 2007-5-30 02:38

[原创]汇编实现程序自删除(非批处理方式)

文章作者:zshoucheng
信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])

程序自删除的方法有很多种
这里提供利用汇编编写的非批处理方式实现程序自删除
喜欢汇编的朋友交流下吧
[code]
.586
.model flat,stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc
include macros.asm

includelib kernel32.lib
includelib user32.lib

SelfDelete proto

.data
cmd1 db ' /c del ',0
cmd2 db ' >nul',0
.data?
dwResult1 dd ?
dwResult2 dd ?
dwResult3 dd ?

.code
start:
invoke SelfDelete
invoke ExitProcess,0

SelfDelete proc
LOCAL szModule[MAX_PATH]:TCHAR,szComspec[MAX_PATH]:TCHAR,szParams[MAX_PATH]:TCHAR
LOCAL sinfo:STARTUPINFO,pi:PROCESS_INFORMATION
invoke RtlZeroMemory,addr sinfo,sizeof sinfo  
mov sinfo.cb,sizeof sinfo
mov sinfo.dwFlags,STARTF_USESHOWWINDOW
mov sinfo.wShowWindow,SW_HIDE
invoke RtlZeroMemory,addr pi,sizeof pi

mov dwResult1,$invoke(GetModuleFileName,0,addr szModule,MAX_PATH)
mov dwResult2,$invoke(GetShortPathName,addr szModule,addr szModule,MAX_PATH)
mov dwResult3,$invoke(GetEnvironmentVariable,sa('COMSPEC'),addr szComspec,MAX_PATH)
.if dwResult1 && dwResult2 && dwResult3
invoke lstrcpy,addr szParams,addr cmd1
invoke lstrcat,addr szParams,addr szModule
invoke lstrcat,addr szParams,addr cmd2
invoke lstrcat,addr szComspec,addr szParams

invoke SetPriorityClass,$invoke(GetCurrentProcess),REALTIME_PRIORITY_CLASS
invoke SetThreadPriority,$invoke(GetCurrentThread),THREAD_PRIORITY_TIME_CRITICAL
invoke CreateProcess,0,addr szComspec,0,0,0,CREATE_SUSPENDED or DETACHED_PROCESS,0,0,addr sinfo,addr pi
.if eax
invoke SetPriorityClass,pi.hProcess,IDLE_PRIORITY_CLASS
invoke SetThreadPriority,pi.hThread,THREAD_PRIORITY_IDLE
invoke ResumeThread,pi.hThread
ret
.elseif
invoke SetPriorityClass,$invoke(GetCurrentProcess),NORMAL_PRIORITY_CLASS
invoke SetThreadPriority,$invoke(GetCurrentThread),THREAD_PRIORITY_NORMAL
.endif
.endif
ret  
SelfDelete endp
end start
[/code]

asm 2007-5-31 12:03

macros.asm


这个宏不错,能否丢上来?

zshoucheng 2007-5-31 12:46

只用了两个宏:
$invoke: 取得它所调用的函数的返回值
sa:String Address 用在Invoke中取得字符串地址,相当于SADD

这两个宏都不难写吧~ [s:265]

virvir 2007-5-31 22:50

#include <windows.h>
void main()
{
  char cmdline[1024];
  GetEnvironmentVariable("ComSpec",cmdline,1024);
  GetModuleFileName(GetModuleHandle(0),cmdline+lstrlen(lstrcat(cmdline," /c del \"")),512);
  WinExec(cmdline,0);
}
不就是这个么……

81635631 2007-6-1 14:49

就是批处理自删除嘛

asm 2007-6-1 15:01

[quote]引用第2楼zshoucheng于2007-05-31 12:46发表的 :
只用了两个宏:
$invoke: 取得它所调用的函数的返回值
sa:String Address 用在Invoke中取得字符串地址,相当于SADD

这两个宏都不难写吧~ [s:265][/quote]


把 macros.asm 文件丢上来吧 懒得去写 [s:269]

zshoucheng 2007-6-1 16:10

在附件里自己提取吧
因为用的编辑器不同对应的宏可能要作相应修改

$invoke宏可以从 函数嵌套调用宏 中提取
用宏就是为了方便自己
比如我把SADD宏改成了sa 简单

zshoucheng 2007-6-1 16:12

[quote]引用第4楼81635631于2007-06-01 14:49发表的 :
就是批处理自删除嘛[/quote]

阁下你写过批处理吗?
这个程序里有写批处理的过程吗?

starsunyzl 2007-6-13 04:49

[quote]引用第5楼asm于2007-06-01 15:01发表的 :



把 macros.asm 文件丢上来吧 懒得去写 [s:269][/quote]
????masm32 9里不是有吗???

81635631 2007-8-6 21:43

[quote]引用第7楼zshoucheng于2007-06-01 16:12发表的 :


阁下你写过批处理吗?
这个程序里写批处理的过程吗?[/quote]

[s:269]
我看了这个就没看了
.data
cmd1 db &#39; /c del &#39;,0
cmd2 db &#39; >nul&#39;,0

evilsir 2007-8-7 07:46

[quote]引用第3楼virvir于2007-05-31 22:50发表的 :
#include <windows.h>
void main()
{
  char cmdline[1024];
  GetEnvironmentVariable("ComSpec",cmdline,1024);
.......[/quote]

确实就是这些代码.
而且这种方法有个问题,要处理同步问题.考虑先阻塞CMD进程.

sudami 2007-12-2 14:43

MS马说的BLOG里面也有一篇关于此的,老话题了哦。创建远程线程自删除。 摘录之[偶可没侵权] [s:265]

[code]
#include <windows.h>
#include <tchar.h>
#include <TLHELP32.H>
#include <stddef.h>

/*
push dwTime
call Sleep

mov eax, [esp + 4]
push eax
call DeleteFileA
ret 4
*/

#pragma pack(push, 1)
typedef struct _tagDeleteStruct {
  BYTE byPush;
  DWORD dwTime;
  BYTE wCall1;
  DWORD dwSleep;
  DWORD dwMov;
  BYTE byPushEax;
  BYTE wCall2;
  DWORD dwDeleteFileA;
  BYTE byRet;
  WORD w4;
  CHAR szFile[1];
} DELETESTRUCT, *PDELETESTRUCT;
#pragma pack(pop)

void EnablePrivilege(void)
{
  HANDLE      hToken;
  TOKEN_PRIVILEGES tp = { 0 };

  HANDLE hProcess = GetCurrentProcess();

  if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
    &hToken))
    return;

  if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid))
  {
    CloseHandle(hToken);
    return;
  }

  tp.PrivilegeCount = 1;
  tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
    NULL, NULL);
  CloseHandle(hToken);
}

DWORD FindTarget(LPCTSTR lpszProcess)
{
  DWORD dwRet   = 0;
  HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

  PROCESSENTRY32 pe32;
  pe32.dwSize = sizeof( PROCESSENTRY32 );
  Process32First(hSnapshot, &pe32);
  do
  {
    if (0 == lstrcmpi(pe32.szExeFile, lpszProcess))
    {
      dwRet = pe32.th32ProcessID;
      break;
    }
  } while (Process32Next(hSnapshot, &pe32));
  CloseHandle(hSnapshot);
  return dwRet;
}

DWORD WINAPI DelProc(LPVOID lpParam)
{
  Sleep(50);
  DeleteFileA((LPCSTR)lpParam);
  return 0;
}

BOOL RemoteDel(DWORD dwProcessID, LPCSTR lpszFileName, DWORD dwTime)
{
  // 打开目标进程
  HANDLE hProcess = OpenProcess(
    PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE,
    dwProcessID);
  if (NULL == hProcess)
    return FALSE;

  // 向目标进程地址空间写入删除信息
  DWORD     dwSize = sizeof(DELETESTRUCT) + lstrlenA(lpszFileName);
  PDELETESTRUCT pDel  = (PDELETESTRUCT)GlobalAlloc(GPTR, dwSize);

  HMODULE hKernel32 = GetModuleHandle(_T("kernel32.dll"));
  // push dwTime
  pDel->byPush = 0x68;
  pDel->dwTime = dwTime;
  // call Sleep
  pDel->wCall1 = 0xe8;
  pDel->dwSleep = (DWORD)GetProcAddress(hKernel32, "Sleep");
  // mov eax, [esp + 4]
  pDel->dwMov = 0x0424448b;
  // push eax
  pDel->byPushEax = 0x50;
  // call DeleteFileA
  pDel->wCall2    = 0xe8;
  pDel->dwDeleteFileA = (DWORD)GetProcAddress(hKernel32, "DeleteFileA");
  // ret 4
  pDel->byRet = 0xc2;
  pDel->w4  = 0x0004;
  lstrcpyA(pDel->szFile, lpszFileName);

  LPVOID lpBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT,
    PAGE_READWRITE);
  if (NULL == lpBuf)
  {
    GlobalFree((HGLOBAL)pDel);
    CloseHandle(hProcess);
    return FALSE;
  }

  // 修正近调用
  pDel->dwSleep    -= (DWORD)lpBuf + offsetof(DELETESTRUCT, dwMov);
  pDel->dwDeleteFileA -= (DWORD)lpBuf + offsetof(DELETESTRUCT, byRet);
  DWORD dwWritten;
  WriteProcessMemory(hProcess, lpBuf, (LPVOID)pDel, dwSize, &dwWritten);

  // 创建线程,远程删除!
  DWORD dwID;
  HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
    (LPTHREAD_START_ROUTINE)lpBuf,
    (LPVOID)((DWORD)lpBuf + offsetof(DELETESTRUCT, szFile)), 0, &dwID);

  GlobalFree((HGLOBAL)pDel);
  CloseHandle(hThread);
  CloseHandle(hProcess);
  return TRUE;
}

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
           LPTSTR lpCmdLine, int nShowCmd)
{
  EnablePrivilege();

  CHAR szMe[MAX_PATH];
  GetModuleFileNameA(NULL, szMe, MAX_PATH);

  DWORD dwId = FindTarget(_T("explorer.exe"));
  RemoteDel(dwId, szMe, 50);
  return 0;
}

[/code]

zshoucheng 2007-12-4 11:51

To 楼上:

Console ----> Windows

mixia_studio 2008-5-9 14:24

为什么我一运行用汇编的deletefile写的代码就报错哦!说应用程序错误!请指教

死妖 2008-5-11 12:45

MS老马的太长啦~~~
我不认为我有可以花这么长时间写自删程序的功夫~~~
我支持
GetEnvironmentVariable
GetModuleFileName

页: [1]
© 1999-2008 EvilOctal Security Team