用远线程实现文件自删除(代码)

#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;
}

原文地址:https://www.cnblogs.com/flying_bat/p/977168.html