阻止删除文件(文件占坑)+nevergone逆向代码一份

文章来源:http://forum.eviloctal.com/thread-32738-1-3.html
信息来源:邪恶八进制信息安全团队( www.eviloctal.com)

逆向作者:nevergone

作者:Written by 风泽(EvilHsu)[E.S.T] 真正的 技术作者是DebugMan上《ring3文件占坑大法》的作者。



介绍:
dhfile是参考《ring3文件占坑大法》一文制造出的一款利用DuplicateHandle函数防止文件被删除、改名等操作的软件,同时也提供卸载、查找、搜索打开的文件句柄。当程序运行后,再使用这款工具将程序句柄复制到其他进程中,达到防删除目的,不影响正在运行程序的正常运行。至于这款软件想怎么去利用,就要看你们的想象力了。

注:
感谢《ring3文件占坑大法》的作者。

用法: 
dhfile.exe [ /p | /f | /c | /l ] [PID] [FileName]

例子:
1. dhfile.exe /l 868
   搜索PID为868的进程打开的所有文件
2. dhfile.exe /f text.exe
   搜索打开text.exe句柄的进程
3. dhfile.exe /c 868 text.exe
   卸载进程ID为868中text.exe文件句柄
4. dhfile.exe /p 868 c:\text.exe
   将text.exe句柄复制到PID为868的进程中,达到防止删除text.exe文件的目的。

关键代码
复制内容到剪贴板
代码:
BOOL DupFile( LPCTSTR lpFileName , int pid )
{
    BOOL    bRedup;
    HANDLE  hFile,hProcess;
    HANDLE  hTargetHandle;
    
    EnablePrivilege(SE_DEBUG_NAME,TRUE);

    if(ProcessList(pid)) printf("Process Name: %s\n",szProcessName);

    hProcess = OpenProcess( PROCESS_DUP_HANDLE, FALSE, pid);

    if ( hProcess == NULL )
       {
           printf("PROCESS_DUP_HANDLE Error\n");     
           return FALSE;
       }

    hFile = CreateFile( lpFileName,
                      GENERIC_READ, 
                      0,
                      NULL,
                      OPEN_ALWAYS,
                      FILE_ATTRIBUTE_NORMAL, 
                      NULL); 

    if ( hFile == INVALID_HANDLE_VALUE )
    {
        printf("CreateFile Error\n");
        CloseHandle( hProcess );
        return FALSE;
    }

    bRedup = DuplicateHandle( GetCurrentProcess(), 
                              hFile, 
                              hProcess, 
                              &hTargetHandle, 
                              0, 
                              FALSE,
                              DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE);

    CloseHandle( hProcess );

    return bRedup;
}
  dhfile.rar (2.94 KB) 程序如有BUG请提示,如果有空偶会修改滴!


以下是nevergone逆向代码,其中软件存在的BUG已经提示并做了修改。(特别感谢nevergone能给予指正)
复制内容到剪贴板
代码:
/********************************************************************
        filename:         e:\C++\VS2008\dhfile_MY\dhfile_MY\dhfile.cpp
        file path:        e:\C++\VS2008\dhfile_MY\dhfile_MY
        file base:        dhfile
        file ext:        cpp
        completed:        7.7 0:15
        author:                nevergone
                
        purpose:        practice for reverseing
                                original author : 风泽
*********************************************************************/

#include
#include
#include
#include
#include "ntdll/ntdll.h"
#pragma comment(lib, "ntdll.lib")

#pragma warning(disable : 4996)

using namespace std;

#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)

char g_szProcessName[MAX_PATH];
HANDLE g_hProcessHeap;

struct HANDLE_NAME
{
        HANDLE hFile;
        FILE_NAME_INFORMATION file_info;
};

//
// this function come from KILL_KIS8
//
PVOID GetSystemInformation(SYSTEM_INFORMATION_CLASS iSystemInformationClass)
{
        ULONG                ulSize = 0x8000;
        ULONG                ulRequired;
        LPVOID                pvBuffer;
        NTSTATUS        Status;

        do {
                pvBuffer = HeapAlloc(GetProcessHeap(), 0, ulSize);

                if (!pvBuffer)
                        return NULL;

                Status = NtQuerySystemInformation(iSystemInformationClass,
                                                                                        pvBuffer,
                                                                                        ulSize,
                                                                                        &ulRequired);

                if (Status == STATUS_INFO_LENGTH_MISMATCH)
                {
                        HeapFree(GetProcessHeap(), 0, pvBuffer);
                        ulSize *= 2;
                }
        } while(Status == STATUS_INFO_LENGTH_MISMATCH);

        if (NT_SUCCESS(Status))
                return pvBuffer;

        HeapFree(GetProcessHeap(), 0, pvBuffer);
        return NULL;
}

DWORD WINAPI GetFileNameThreadProc(LPVOID pvParam)
{
        IO_STATUS_BLOCK io_status;

        HANDLE hFile = *(LPHANDLE)pvParam;
        PVOID pvBuffer = (PVOID)((DWORD)pvParam + sizeof(HANDLE));

        NtQueryInformationFile(hFile,
                                                        &io_status,
                                                        pvBuffer,
                                                        528,
                                                        FileNameInformation);
        return 0;
}


INT GetFileNameByHandle(HANDLE hFile, LPSTR lpMultiByteStr)
{
        PVOID pvBuffer = HeapAlloc(g_hProcessHeap, HEAP_ZERO_MEMORY, 532);

        *((LPDWORD)pvBuffer) = (DWORD)hFile;

        HANDLE hThread = CreateThread(NULL, 
                                                                        0, 
                                                                        GetFileNameThreadProc, 
                                                                        pvBuffer, 
                                                                        0, 
                                                                        NULL);

        //
        // 100 may be too short for some slow machine~
        //
        DWORD dwRet = WaitForSingleObject(hThread, 100);

        if (dwRet == WAIT_TIMEOUT)
                TerminateThread(hThread, 0);

        CloseHandle(hThread);

        PFILE_NAME_INFORMATION pFileNameInfo = (PFILE_NAME_INFORMATION)((DWORD)pvBuffer + sizeof(HANDLE));
        
        WideCharToMultiByte(CP_ACP,
                                                0,
                                                pFileNameInfo->FileName,
                                                pFileNameInfo->FileNameLength / 2,
                                                lpMultiByteStr,
                                                MAX_PATH,
                                                NULL,
                                                NULL);

        HeapFree(g_hProcessHeap, 0, pvBuffer);
        return 0;
}


UCHAR GetFileObjectTypeNumber()
{
        UCHAR uchar_ObjectTypeNumber = 0;

        HANDLE hFile = CreateFileA("NUL",
                                                                GENERIC_READ,
                                                                0,
                                                                NULL,
                                                                OPEN_EXISTING,
                                                                0,
                                                                0);

        if (hFile == INVALID_HANDLE_VALUE)
                return 0;
        
        LPVOID pvBuffer = GetSystemInformation(SystemHandleInformation);
        if (pvBuffer == NULL)
        {
                CloseHandle(hFile);
                return 0;
        }

        DWORD dwCount = ((PSYSTEM_HANDLE_INFORMATION_EX)pvBuffer)->NumberOfHandles;

        if (!dwCount)
        {
                HeapFree(g_hProcessHeap, 0, pvBuffer);
                CloseHandle(hFile);
                return 0;
        }

        PSYSTEM_HANDLE_INFORMATION pHandleInfo = ((PSYSTEM_HANDLE_INFORMATION_EX)pvBuffer)->Information;

        for (DWORD i = 0; i < dwCount; ++i)
        {
                if (pHandleInfo[i].Handle == (USHORT)hFile &&
                        pHandleInfo[i].ProcessId == GetCurrentProcessId())
                {
                        uchar_ObjectTypeNumber = pHandleInfo[i].ObjectTypeNumber;
                        HeapFree(g_hProcessHeap, 0, pvBuffer);
                        CloseHandle(hFile);
                        return uchar_ObjectTypeNumber;
                }
        }

        return 0;
}

BOOL EnableDebugPrivilge(LPCSTR lpName, BOOL fEnable)
{
        HANDLE                                hObject;
        LUID                                Luid;
        TOKEN_PRIVILEGES        NewStatus;

        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hObject))
                return FALSE;

        if (LookupPrivilegeValue(NULL, lpName, &Luid))
        {
                NewStatus.Privileges[0].Luid = Luid;
                NewStatus.PrivilegeCount = 1;
                NewStatus.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;

                AdjustTokenPrivileges(hObject, FALSE, &NewStatus, 0, 0, 0);
                
                CloseHandle(hObject);
                return TRUE;
        }
        
        return FALSE;
}

BOOL GetProcessNameById(DWORD dwProcessId)
{
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,
                                                                                                0);
        //
        // add by nevergone
        //
        if (hSnapshot == INVALID_HANDLE_VALUE)
        {
           printf("CreateToolhelp32Snapshot error\n");
           return 0;
        }
        
        PROCESSENTRY32 pe;
        PCHAR pProcessName = NULL;

        //
        // add by nevergone. Process32First may be failed if without setting the size
        //
        pe.dwSize = sizeof(pe);
        
        if (!Process32First(hSnapshot, &pe))
        {
                CloseHandle(hSnapshot);
                return FALSE;
        }

        do {
                pProcessName = strrchr(pe.szExeFile, '\\');

                if (pProcessName)
                        pProcessName++;
                else
                        pProcessName = pe.szExeFile;

                if (pe.th32ProcessID == dwProcessId)
                {
                        ZeroMemory(g_szProcessName, sizeof(g_szProcessName));
                        strncpy(g_szProcessName, pProcessName, lstrlen(pProcessName));

                        //
                        //add by nevergone
                        //
                        CloseHandle(hSnapshot);
                        return TRUE;
                }
        } while(Process32Next(hSnapshot, &pe));

        CloseHandle(hSnapshot);
        return FALSE;
}

BOOL ProtectFile(LPCSTR lpFileName, DWORD dwProcessId)
{
        HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);

        if (!hProcess)
        {
                printf("PROCESS_DUP_HANDLE Error\n");
                return FALSE;
        }

        HANDLE hFile = CreateFile(lpFileName,
                                                                GENERIC_READ,
                                                                0,
                                                                NULL,
                                                                /*OPEN_ALWAYS*/OPEN_EXISTING,                // OPEN_EXISTING may be better [nevergone]
                                                                FILE_ATTRIBUTE_NORMAL,
                                                                NULL
                                                                );

        if (hFile == INVALID_HANDLE_VALUE)
        {
                printf("CreateFile Error\n");
                CloseHandle(hFile);
                return FALSE;
        }

        BOOL fOk = DuplicateHandle(GetCurrentProcess(),
                                                                hFile,
                                                                hProcess,
                                                                NULL,
                                                                0,
                                                                FALSE,
                                                                DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

        CloseHandle(hProcess);

        return fOk;
}

int Process(int iUnknown, char *pString1, char *pString2)
{
        UCHAR uchar_FileTypeNumber;
        PVOID pvoid_HandleInfo;
        DWORD dwHandleCount;
        PSYSTEM_HANDLE_INFORMATION pHandleInfo;
        HANDLE hProcess;
        HANDLE hTarget;
        PCHAR pszPath;
        DWORD dwCount = 0;
        CHAR szFilePath[MAX_PATH] = { 0 };
        
        g_hProcessHeap = GetProcessHeap();
        uchar_FileTypeNumber = GetFileObjectTypeNumber();
        pvoid_HandleInfo = GetSystemInformation(SystemHandleInformation);
        
        if (pvoid_HandleInfo == NULL)
                return 0;
        

        dwHandleCount = *(LPDWORD)pvoid_HandleInfo;
        pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)((DWORD)pvoid_HandleInfo + sizeof(HANDLE));

        if (!dwHandleCount)
        {
                HeapFree(g_hProcessHeap, 0, pvoid_HandleInfo);
                printf("Not found File %s \n", pString1);
                return 0;
        }

        for (DWORD i = 0; i < dwHandleCount; ++i)
        {
                if (pHandleInfo[i].ObjectTypeNumber != uchar_FileTypeNumber)
                        continue;

                if (iUnknown == pHandleInfo[i].ProcessId ||
                        _strnicmp(pString2, "/f", 2) == 0)
                {
                        // ToDo:
                        hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pHandleInfo[i].ProcessId);

                        if (hProcess == NULL)
                                continue;

                        BOOL fOk = DuplicateHandle(hProcess,
                                                                                (HANDLE)pHandleInfo[i].Handle,
                                                                                GetCurrentProcess(),
                                                                                &hTarget,
                                                                                0,
                                                                                FALSE,
                                                                                DUPLICATE_SAME_ACCESS);
                        if (!fOk)
                        {
                                CloseHandle(hProcess);
                                continue;
                        }
                        
                        //
                        // add by nevergone, this is important. if GetFileNameThreadProc failed to 
                        // get the file path, then WideCharToMultiByte do nothing with 
                        // lpMultiByteStr parameter[see Test Project for detail],
                        // but lpMultiBytePtr is set by the previous GetFileNameByHandle. so must zero szFilePath.
                        //
                        ZeroMemory(szFilePath, sizeof(szFilePath));

                        GetFileNameByHandle(hTarget, szFilePath);

                        pszPath = szFilePath;

                        if (pszPath = strrchr(szFilePath, '\\'))
                                pszPath++;
                        else
                                pszPath = szFilePath;

                        if (_strnicmp(pString2, "/l", 2) == 0)
                        {
                                ++dwCount;
                                printf("Handle: %d .... FileName: %s\n", pHandleInfo[i].Handle, szFilePath);
                                CloseHandle(hTarget);
                                CloseHandle(hProcess);
                                continue;
                        }

                        if (_strnicmp(pString1, pszPath, lstrlen(pString1)) == 0)
                        {
                                ++dwCount;
                                printf("Process:%d Handle: %d .... FileName: %s\n",  pHandleInfo[i].ProcessId, pHandleInfo[i].Handle, szFilePath);

                                if (_strnicmp(pString2, "/c", 2) == 0)
                                {
                                        BOOL fOk = DuplicateHandle(hProcess,
                                                                                                (HANDLE)pHandleInfo[i].Handle,
                                                                                                GetCurrentProcess(),
                                                                                                NULL,
                                                                                                0,
                                                                                                FALSE,
                                                                                                DUPLICATE_CLOSE_SOURCE);

                                        if (fOk)
                                                printf("Close Files Handle....Success\n");
                                        else
                                                printf("Close Files Handle....Failure\n");
                                }
                        }

                        CloseHandle(hTarget);
                        CloseHandle(hProcess);
                }
        }
        
        HeapFree(g_hProcessHeap, 0, pvoid_HandleInfo);

        if (dwCount == 0)
        {
                printf("Not found File: %s \n", pString1);
        }

        return 0;
}

int main(int argc, char *argv[])
{
        if (argc < 2 ||
                lstrcmpi(argv[1], "/?") == 0 ||
                lstrcmpi(argv[1], "-?") == 0 ||
                lstrcmpi(argv[1], "-h") == 0 ||
                lstrcmpi(argv[1], "/help") == 0 ||
                lstrcmpi(argv[1], "-help") == 0)
        {
                //ShowHelp(argv[0]);
                exit(0);
        }

        EnableDebugPrivilge("SeDebugPrivilege", TRUE);

        if (argc < 3) 
        {
                printf("参数不正确!\n");
                //ShowHelp(argv[0]);
                exit(0);
        }

        if (lstrcmpi(argv[1], "/f") == 0)
        {
                Process(-1, argv[2], argv[1]);
                return 0;
        }
        
        // 
        // if argv[3] is absolute path, operation will failed.
        // but i don't want to solve this problem.
        // 风泽 take responsibility for this bug,
        // HA HA HA....
        //
        if (lstrcmpi(argv[1], "/c") == 0)
        {
                int dwProcessId = atoi(argv[2]);
                if (dwProcessId > 0xFFFF ||
                        dwProcessId < 4)
                {
                        printf("参数不正确!\n");
                        //ShowHelp(argv[0]);
                        exit(0);
                }

                if (!GetProcessNameById(dwProcessId))
                {
                        printf("Not found process : %d\n\n", dwProcessId);
                        exit(0);
                }

                printf("Process Name: %s \n\n", g_szProcessName);

                Process(dwProcessId, argv[3], argv[1]);
                return 0;
        }

        if (lstrcmpi(argv[1], "/l") == 0)
        {
                int dwProcessId = atoi(argv[2]);

                if (dwProcessId > 0xFFFF ||
                        argc > 3)
                {
                        printf("参数不正确!\n");
                        //ShowHelp(argv[0]);
                        exit(0);
                }

                if (!GetProcessNameById(dwProcessId))
                {
                        printf("Not found process : %d\n\n", dwProcessId);
                        exit(0);
                }

                printf("process name: %s \n\n", g_szProcessName);

                Process(dwProcessId, NULL, argv[1]);
                return 0;
        }

        if (lstrcmpi(argv[1], "/p") == 0)
        {
                int dwProcessId = atoi(argv[2]);
                if (dwProcessId > 0xFFFF ||
                        argc < 3)
                {
                        printf("参数不正确!\n");
                        //ShowHelp(argv[0]);
                        exit(0);
                }

                if (!GetProcessNameById(dwProcessId))
                {
                        printf("Not found process : %d\n\n", dwProcessId);
                        exit(0);
                }

                printf("Process Name: %s \n\n", g_szProcessName);

                if (ProtectFile(argv[3], dwProcessId))
                {
                        printf("\n...Success!\n");
                }

                return 0;
        }
}
[  本帖最后由 风泽 于 2008-7-7 13:11 编辑 ]

附件

  dhfile_MY.rar  (122.91 KB)

2008-7-7 12:56, 下载次数: 1568

nevergone提供的完整逆向

你可能感兴趣的:(C/C++)