仿照SirCAM病毒控制EXE进程(5)
Chapter
5
将要插入的DLL的制造过程(2)
如果用户说我不想看你的破封面,说你是在强奸民意,我们也应该给他们一条生路:
用户点击封面窗口或者按键都可以立即杀死该窗口。
加入下列代码:
// Override GetDialogProc to provide our own DialogProc.
WNDPROC GetDialogProc()
{
return MyDialogProc;
}
// Our own dialog procedure that is mostly copied from
// CAxDialogImpl<>::DialogProc() in Atlwin.h.
static LRESULT CALLBACK MyDialogProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
CSplasher* pThis = (CSplasher*)hWnd;
// Set a ptr to this message and save the old value.
MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
const MSG* pOldMsg = pThis->m_pCurrentMsg;
pThis->m_pCurrentMsg = &msg;
// Pass to the message map to process.
LRESULT lRes;
BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam,
lParam, lRes, 0);
// If window has been destroyed and this is the last message,
// then delete ourselves.
if (DEFERDELETE == pThis->m_bAutoDelete && pOldMsg == NULL)
{
delete pThis;
return FALSE;
}
// Restore saved value for the current message.
ATLASSERT(pThis->m_pCurrentMsg == &msg);
pThis->m_pCurrentMsg = pOldMsg;
// ================= Kernel Code ========================
//
// If we get a keyboard or mouse message, hide the splash screen.
//
if (uMsg == WM_KEYDOWN ||
uMsg == WM_SYSKEYDOWN ||
uMsg == WM_LBUTTONDOWN ||
uMsg == WM_RBUTTONDOWN ||
uMsg == WM_MBUTTONDOWN ||
uMsg == WM_NCLBUTTONDOWN ||
uMsg == WM_NCRBUTTONDOWN ||
uMsg == WM_NCMBUTTONDOWN)
{
// 关闭Splash Screen:
pThis->EndDialog(0);
pThis->UpdateWindow();
}
//
// ================= Kernel Code ========================
if(uMsg == WM_NCDESTROY)
{
// Clear out window handle.
HWND hWnd = pThis->m_hWnd;
pThis->m_hWnd = NULL;
// Clean up after dialog box is destroyed.
pThis->OnFinalMessage(hWnd);
// If we want to automatically delete ourselves...
if (pThis->m_bAutoDelete)
{
// If no outstanding messages to process in call stack,
// m_pCurrentMsg will be NULL so we can delete ourselves.
if (pThis->m_pCurrentMsg == NULL)
delete pThis;
// Else set a flag so we can delete ourselves later.
else
pThis->m_bAutoDelete = DEFERDELETE;
}
}
return FALSE;
}
终于构造好了,接下来,我们将在DllMain中显示它了。
简单的实现,就不再说什么了:
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init(ObjectMap, hInstance, &LIBID_INJECTSPLASHLib);
DisableThreadLibraryCalls(hInstance);
// ======= Added for Splash ========
//
CSplasher::EnableSplashScreen(TRUE);
CSplasher::ShowSplashScreen();
// 现在知道为什么定义这两个方法为Static了吧
// 当然你new一个Csplasher object也可以
//
// =========== Added for Splash ============
}
else if (dwReason == DLL_PROCESS_DETACH)
{
_Module.Term();
}
return TRUE; // ok
}
对了,别忘了给你的对话框上加一个图片!
千万别硬放BITMAP资源,那样编译出的DLL会很大!
全部完成了!
你现在编译一下看看,如果编译结束显示注册组件时,你的对话框没有弹出来的话,那就是哪里错了!
如果你看到:
RegSvr32: LoadLibrary(".\Debug\InjectProcess.dll") failed.
GetLastError returns 0x000003e9.
提示,不用理会,“递归太深;栈溢出”而已。
好了,现在把前面的BeforeExecute.exe和这个InjectProcess.Dll复制到%System32%下面,运行一下BeforeExecute.exe,你将会看到启动封面,然后再运行其他的程序(Explore除外),看看效果吧。
流程你清楚了吗?
来,让我们总结一下:
BeforeExecute:
程序目的:仿照SirCAM蠕虫病毒的程序BeforeExecute:
Author: zhengyun_ustc
程序描述:
先试图改写注册表,
然后接过命令行传过来的用户要启动的EXE程序的路径,用CreateProcess起这个新进程;
但是让新起的进程并不马上运行,这是通过设置creation flags为CREATE_SUSPENDED
来实现的。
然后我们往新建进程中用远程进程插入DLL;
这个DLL中我们可以在它的DllMain中作我们想做的事情,诸如用MAPI或者CDO发送邮件,监视用户动作等等;
成功插入DLL之后,我们结束当前自己的进程,只让新建的进程继续跑,这样用户不会怀疑!
这种思路的优点是用户很难察觉,而SirCAM病毒却是让每起一个新进程,就伴随一个SirC32进程,这样很容易被发现。
我猜测它的破坏动作是在SirC32.exe中执行的,而我们的程序可以把这些动作放在DLL中,这个DLL是在进程的地址空间中的,执行起来很方便。
而且插入的InjectProcess.Dll是可互换的,比如你今天做了一个Splasher的DLL,明天做了一个MAPI的DLL,都可以叫做“InjectProcess.dll”,随时更换,加载无影响。荷荷,爽了吧。
下期我们将如是做一个“InjectProcess.Dll”来监视键盘动作,然后存成文件,最后在DLL_PROCESS_DETACH消息到来之际调用MAPI发送出去,你说这好不好玩,荷荷,诶,没想到那个小孩的口水会这么多,打扰了,借面纸用一下…….
你说发邮件还是只有少数人能看到,那么我们可以用XML2::IXMLHTTPRequest把这个键盘监视记录文件的内容POST给CSDN的某个ASP页面上,让大家都可以看到,…….,诶,不要激动吗,我只是跟你研究一下而已啦。
请看下回分解。
-----To be continued------