2006年8月底,偶然用了360安全卫士,觉得很不错。以前自己也有写过小工具来除去那些可恶的流氓软件,所以就去申请加入他们的程序员志愿者。结果没有选上... 编写一个程序,在此程序中运行a.exe,并使得a.exe认为是由explorer.exe运行它的。 ================================================================
下面是他们当时发给我的考核题目
================================================================
最近无意间看到了一个解决方法,很不错,先特意贴出来向360安全卫士的程序员志愿者致敬!
==================================================================================================
假设我写的程序名为ddd.exe
在这里,我将使用CreateProcess函数来启动 a.exe ,
如果不进行任何操作而直接使用CreateProcess函数来运行 a.exe的话,
它默认的父进程将为ddd.exe.
在XP/NT系统中CreateProcess函数的调用过程为
1:CreateProcessInternalW
1:CreateProcessInternalW
2:NtCreateProcessEx/NtCreateProcess
3:PspCreateProcess
其中NtCreateProcessEx/NtCreateProcess函数的
参数ParentProcess的handle指明谁是父进程
所以我要做的就是 在函数CreateProcess函数的调用NtCreateProcessEX/NtCreatProcess时拦截它,
并且把CreateProcess函数传递的ParentProcess参数值 改为explorer.exe的句柄 既可实现目的。
步骤1:使用HOOK拦截NtCreateProcess函数
步骤2:取得进程explorer.exe的句柄 更换ParentProcess参数值后,
继续调用NtCreateProcess函数
关键代码段1:取进程explorer.exe的句柄
HANDLE hExplorer; //保存explorer.exe的句柄变量
......
......
......
......
//取所有系统进程
BOOL Status=Process32First(SnapShot,&ProcessInfo);
int m_nProcess=0;
while(Status)
{
CString str1;
str1.Format("%s",ProcessInfo.szExeFile);
ProcessID[m_nProcess]=ProcessInfo.th32ProcessID;
if(str1=="explorer.exe") //表明匹配到explorer.exe
{
hExplorer=OpenProcess (PROCESS_ALL_ACCESS,FALSE,ProcessID[m_nProcess]);
BOOL Status=Process32First(SnapShot,&ProcessInfo);
int m_nProcess=0;
while(Status)
{
CString str1;
str1.Format("%s",ProcessInfo.szExeFile);
ProcessID[m_nProcess]=ProcessInfo.th32ProcessID;
if(str1=="explorer.exe") //表明匹配到explorer.exe
{
hExplorer=OpenProcess (PROCESS_ALL_ACCESS,FALSE,ProcessID[m_nProcess]);
//保存explorer.exe句柄到hExplorer
break; //跳出while
}
Status=Process32Next(SnapShot,&ProcessInfo);
m_nProcess++;
} // end while
break; //跳出while
}
Status=Process32Next(SnapShot,&ProcessInfo);
m_nProcess++;
} // end while
......
......
......
关键代码段2:拦截NtCreateProcess函数,并处理
dll关键代码:(注:......为代码省略)
//替换函数定义申明
int _stdcall hook_NtCreateProcess( PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ParentProcess, //就修改这个参数值
BOOLEAN InheritHandles,
HANDLE SectionHandle,
HANDLE DebugPort,
HANDLE ExceptionPort
)
{
......
...... //这里为关键代码段1:取进程explorer.exe的句柄并保存给hExplorer
......
NtCreateProcess(ProcessHandle,DesiredAccess,ObjectAttributes,
hExplorer, // hExplorer为explorer.exe的句柄
InheritHandles,SectionHandle,DebugPort,ExceptionPort);
......
......
......
}
int _stdcall hook_NtCreateProcess( PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ParentProcess, //就修改这个参数值
BOOLEAN InheritHandles,
HANDLE SectionHandle,
HANDLE DebugPort,
HANDLE ExceptionPort
)
{
......
...... //这里为关键代码段1:取进程explorer.exe的句柄并保存给hExplorer
......
NtCreateProcess(ProcessHandle,DesiredAccess,ObjectAttributes,
hExplorer, // hExplorer为explorer.exe的句柄
InheritHandles,SectionHandle,DebugPort,ExceptionPort);
......
......
......
}
//DLLMain 函数中关键代码
HMODULE m_hNtCP = LoadLibrary( "ntdll.dll" );
g_pNtCP = ( DWORD )GetProcAddress( m_hNtCP, "NtCreateProcess" );
g_pNtCP = ( DWORD )GetProcAddress( m_hNtCP, "NtCreateProcess" );
ReadProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pNtCP,
( void * )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );
( void * )g_dwOldBytes[0], sizeof( DWORD )*2, NULL );
//将00400000改写为我们函数的地址
*( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )hook_NtCreateProcess;
*( DWORD* )( g_btNewBytes + 1 ) = ( DWORD )hook_NtCreateProcess;
WriteProcessMemory( INVALID_HANDLE_VALUE, ( void * )g_pNtCP,
( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );
( void * )g_btNewBytes, sizeof( DWORD )*2, NULL );