2024年1月20日发(作者:)
课 程 设 计
题 目:
自动内存驻留程序
院、 系:计算机科学与技术学院 网络工程系
班 级:
学 号:
姓 名:
同组成员:
指导教师:
成 绩:
2014年06月27日
一.系统设计的目标
编写程序,把指定代码注入相应程序中,达到操作简单,并且容易实现驻留在内存的目的,另一个目的是使注入程序在管理员不注意下不会轻易被发现,有一定的隐藏性。
二.系统原理:
采用远程注入和动态链接库技术,把动态链接库注入到目标进程,让动态链接库在目标进程的内存中运行,从而达到驻留在内存的效果。
三. 系统功能分析:
这个程序较小,操作简单,非计算机专业的人员也容易执行,占用内存少,运行速度较快,方便对内存的注入,暂无发现不能容忍的bug,一般情况下能够正常运行,但是缺点在于容易被发现。
四.系统实现:
详细设计
首先先编译动态链接库:
然后编译mfc:
2
最后先选择动态链接库的路径,然后选择相应的进程,双击它,再选择注入:
附录:
源程序代码:
//动态链接库中的代码:
3
DllProcess.h
#pragma once
#ifndef DEF_DLL_PORT
#define DEF_DLL_PORT _declspec(dllimport)
#endif
// : 定义 DLL 应用程序的入口点。
//
#include "stdafx.h"
#define DEF_DLL_PORT _declspec(dllexport)
#include "DllProcess.h"
#include
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL __stdcall MyCreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
return TRUE;
}
4
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL, _T("注入成功····~!"), 0, 0);
//自己想要运行的程序
//···············
//··············
//„„„„„„„
break;
case DLL_PROCESS_DETACH:
MessageBox(NULL, _T("卸载成功``````````````````````~!"), 0, 0);
break;
}
return TRUE;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
//源程序代码:
1. MFCEnter.h
// MFCEnter.h : PROJECT_NAME 应用程序的主头文件
//
#pragma once
#ifndef __AFXWIN_H__
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif
#include "resource.h" // 主符号
// CMFCEnterApp:
5
// 有关此类的实现,请参阅
//
class CMFCEnterApp : public CWinApp
{
public:
CMFCEnterApp();
// 重写
public:
virtual BOOL InitInstance();
// 实现
DECLARE_MESSAGE_MAP()
};
extern CMFCEnterApp theApp;
2. MFCEnterDlg.h
// MFCEnterDlg.h : 头文件
//
#pragma once
#include "afxwin.h"
#include
#include "afxcmn.h"
#include
#pragma comment(lib, "")
#pragma comment(lib, "")
// CMFCEnterDlg 对话框
class CMFCEnterDlg : public CDialog
{
// 构造
public:
CMFCEnterDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_MFCENTER_DIALOG };
6
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedEnter();
public:
CEdit m_ediProcessID;
public:
CEdit m_edtDllPath;
public:
afx_msg void OnBnClickedGetdllPath();
public:
afx_msg void OnBnClickedUnist();
afx_msg void GetToolShot();
afx_msg void InitList();
public:
CListCtrl m_ListProcess;
public:
afx_msg void OnBnClickedOpenprocess();
public:
afx_msg void OnNMClickListProcess(NMHDR *pNMHDR, LRESULT *pResult);
public:
afx_msg void OnNMDblclkListProcess(NMHDR *pNMHDR, LRESULT *pResult);
};
3.
// : 定义应用程序的类行为。
//
#include "stdafx.h"
#include "MFCEnter.h"
7
#include "MFCEnterDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMFCEnterApp
BEGIN_MESSAGE_MAP(CMFCEnterApp, CWinApp)
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()
// CMFCEnterApp 构造
CMFCEnterApp::CMFCEnterApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CMFCEnterApp 对象
CMFCEnterApp theApp;
// CMFCEnterApp 初始化
BOOL CMFCEnterApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
= sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
// 公共控件类。
= ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
8
}
4.
AfxEnableControlContainer();
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
CMFCEnterDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = l();
if (nResponse == IDOK)
{
// TODO: 在此处放置处理何时用“确定”来关闭
// 对话框的代码
}
else if (nResponse == IDCANCEL)
{
// TODO: 在此放置处理何时用“取消”来关闭
// 对话框的代码
}
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
// 而不是启动应用程序的消息泵。
return FALSE;
// : 实现文件
//
#include "stdafx.h"
#include "MFCEnter.h"
#include "MFCEnterDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
9
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CMFCEnterDlg 对话框
CMFCEnterDlg::CMFCEnterDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMFCEnterDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMFCEnterDlg::DoDataExchange(CDataExchange* pDX)
{
10
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PROCESS_ID, m_ediProcessID);
DDX_Control(pDX, IDC_DLL_PATH, m_edtDllPath);
DDX_Control(pDX, IDC_LIST_PROCESS, m_ListProcess);
}
BEGIN_MESSAGE_MAP(CMFCEnterDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_ENTER, &CMFCEnterDlg::OnBnClickedEnter)
ON_BN_CLICKED(IDC_GETDLL_PATH, &CMFCEnterDlg::OnBnClickedGetdllPath)
ON_BN_CLICKED(IDC_UNIST, &CMFCEnterDlg::OnBnClickedUnist)
ON_BN_CLICKED(IDC_OPENPROCESS, &CMFCEnterDlg::OnBnClickedOpenprocess)
//ON_NOTIFY(HDN_ITEMDBLCLICK, 0, &CMFCEnterDlg::OnHdnItemdblclickListProcess)
//ON_NOTIFY(LVN_COLUMNCLICK, IDC_LIST_PROCESS,
&CMFCEnterDlg::OnLvnColumnclickListProcess)
ON_NOTIFY(NM_CLICK, IDC_LIST_PROCESS, &CMFCEnterDlg::OnNMClickListProcess)
ON_NOTIFY(NM_DBLCLK, IDC_LIST_PROCESS, &CMFCEnterDlg::OnNMDblclkListProcess)
END_MESSAGE_MAP()
// CMFCEnterDlg 消息处理程序
BOOL CMFCEnterDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
ring(IDS_ABOUTBOX);
if (!y())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
11
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
InitList();
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CMFCEnterDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
l();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CMFCEnterDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast
// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
12
int x = (() - cxIcon + 1) / 2;
int y = (() - cyIcon + 1) / 2;
// 绘制图标
on(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
//
HCURSOR CMFCEnterDlg::OnQueryDragIcon()
{
return static_cast
}
void CMFCEnterDlg::OnBnClickedEnter()
{
// TODO: 在此添加控件通知处理程序代码
//获得目标进程句柄
//1.获得目标进程的ID
HANDLE hProcess = NULL;
HMODULE hDll = NULL;
HANDLE hRemoteThread = NULL;
CString strDllPath;
CString strProcessID;
DWORD dwID = 0;
m_dowText(strProcessID);
dwID = _ttoi(strProcessID);
if (dwID <= 0)
{
MessageBox(_T("进程ID有误~!"));
return;
}
//2.通过进程ID获得进程句柄
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ
, FALSE, dwID);
if (NULL == hProcess)
{
13
MessageBox(_T("进程句柄获取失败~!"));
return;
}
//获得线程函数(LoadLibrary)的地址
//1.得到 的句柄
hDll = GetModuleHandle(_T(""));
if (NULL == hDll)
{
CloseHandle(hProcess);
MessageBox(_T("获得线程函数句柄失败~!"));
return;
}
//2.通过句柄获得函数的地址
#ifdef _UNICODE
LPTHREAD_START_ROUTINE farProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hDll,
"LoadLibraryW");
#else
LPTHREAD_START_ROUTINE farProc = GetProcAddress(hDll, "LoadLibraryA");
#endif
if (NULL == farProc)
{
CloseHandle(hProcess);
MessageBox(_T("获取进程函数失败~!"));
return;
}
//3.获得动态链接库的路径,把他写入目标进程的内存中
m_dowText(strDllPath);
DWORD dwSize = (gth()+1)*sizeof(TCHAR);
//3.1 在目标进程中申请空间
LPVOID lpStart = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT,
PAGE_READWRITE);
if (NULL == lpStart)
{
CloseHandle(hProcess);
MessageBox(_T("申请空间失败~!"));
return;
}
//3.2 把动态链接库的地址写入申请的空间中
if (0 == WriteProcessMemory(hProcess, lpStart, strDllPath, dwSize, NULL))
{
VirtualFreeEx(hProcess, lpStart, dwSize, MEM_COMMIT);
CloseHandle(hProcess);
14
MessageBox(_T("写入失败~!"));
}
//执行远程线程
hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, farProc, lpStart, 0, NULL);
if (NULL == hRemoteThread)
{
int iError = GetLastError();
VirtualFreeEx(hProcess, lpStart, dwSize, MEM_COMMIT);
CloseHandle(hProcess);
MessageBox(_T("创建执行远程线程失败~!"));
return;
}
WaitForSingleObject(hRemoteThread, INFINITE);
CloseHandle(hRemoteThread);
VirtualFreeEx(hProcess, lpStart, dwSize, MEM_COMMIT);
CloseHandle(hProcess);
return;
}
void CMFCEnterDlg::OnBnClickedGetdllPath()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog fileDialog(TRUE);
if (IDOK == l())
{
m_dowText(hName());
}
}
void CMFCEnterDlg::OnBnClickedUnist()
{
// TODO: 在此添加控件通知处理程序代码
//目标进程的句柄 hProcess
HANDLE hProcess = NULL;
HMODULE hDll = NULL;
HANDLE hRemoteThread = NULL;
CString strDllPath;
CString strProcessID;
DWORD dwID = 0;
15
m_dowText(strProcessID);
dwID = _ttoi(strProcessID);
if (dwID <= 0)
{
MessageBox(_T("进程ID有误~!"));
return;
}
//2.通过进程ID获得进程句柄
hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ
, FALSE, dwID);
if (NULL == hProcess)
{
MessageBox(_T("进程句柄获取失败~!"));
return;
}
//获得线程函数(FreeLibrary)的地址
//1.得到 的句柄
hDll = GetModuleHandle(_T(""));
if (NULL == hDll)
{
CloseHandle(hProcess);
MessageBox(_T("获得线程函数句柄失败~!"));
return;
}
//2.通过句柄获得函数的地址
LPTHREAD_START_ROUTINE farProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hDll,
"FreeLibrary");
if (NULL == farProc)
{
CloseHandle(hProcess);
MessageBox(_T("获取进程函数失败~!"));
return;
}
//3.获得动态链接库的路径
m_dowText(strDllPath);
DWORD dwSize = (gth()+1)*sizeof(TCHAR);
//获得动态链接库的句柄,通过进程快照
HANDLE handleProcess = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwID);
16
if (INVALID_HANDLE_VALUE == handleProcess)
{
CloseHandle(hProcess);
MessageBox(_T("获取快照失败~!"));
return;
}
//获取进程快照的第一行
MODULEENTRY32 o_Module32;
//给结构体初始化
memset(&o_Module32, 0, sizeof(o_Module32));
o_ = sizeof(o_Module32);
if (FALSE == Module32First(handleProcess, &o_Module32))
{
CloseHandle(hProcess);
CloseHandle(handleProcess);
MessageBox(_T("获取第一行进程快照失败~!"));
return;
}
do
{
//取出结构体里面的路径,看是不是和m_dowtext相等
CString strtemp = o_ath;
if (strtemp == strDllPath)
{
hDll = o_e;
break;
}
} while (Module32Next(handleProcess, &o_Module32));
hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, farProc, hDll, 0, NULL);
if (NULL == hRemoteThread)
{
CloseHandle(hProcess);
CloseHandle(handleProcess);
MessageBox(_T("远程线程失败~!"));
return;
}
WaitForSingleObject(hRemoteThread, INFINITE);
17
//关闭句柄
CloseHandle(hProcess);
CloseHandle(handleProcess);
CloseHandle(hRemoteThread);
return;
}
void CMFCEnterDlg::GetToolShot()
{
m_AllItems();
HANDLE HandleProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
CString strvalue;
DWORD ProcessID;
TCHAR ProcessPath[MAX_PATH];
if (INVALID_HANDLE_VALUE == HandleProcess)
{
MessageBox(_T("获取进程快照失败"));
return;
}
//取出进程快照第一行
PROCESSENTRY32 process32;
memset(&process32,0,sizeof(process32));
= sizeof(process32);
Process32First(HandleProcess,&process32);
if (FALSE == Process32First(HandleProcess,&process32))
{
MessageBox(_T("获取快照第一行失败"));
return;
}
//取出下一行
do
{
//获取ID
(_T("%d"),32ProcessID);
m_Item(0,strvalue);
//获取名字
m_mText(0,1,ile);
//获取路径
//通过进程的ID获得进程的句柄
HANDLE Proces = ::OpenProcess(PROCESS_QUERY_INFORMATION
PROCESS_VM_READ,FALSE,32ProcessID);
if (NULL == Proces)
18
|
{
memset(&process32,0,sizeof(process32));
= sizeof(process32);
continue;
}
if(0 == GetModuleFileNameEx(Proces,NULL,ProcessPath,MAX_PATH))
{
memset(&process32,0,sizeof(process32));
= sizeof(process32);
CloseHandle(Proces);
continue;
}
//显示路径
m_mText(0,2,ProcessPath);
//关闭句柄
memset(&process32,0,sizeof(process32));
= sizeof(process32);
CloseHandle(Proces);
} while (Process32Next(HandleProcess,&process32));
return;
}
void CMFCEnterDlg::InitList()
{
m_endedStyle(LVS_LIST|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);
CRect rect;
CString strValue;
m_entRect(&rect);
UINT Column[][3] = {
PROCESS_ID,LVCFMT_LEFT,(UINT)(30.0*(()/100.00)),
PROCESS_NAME,LVCFMT_LEFT,(UINT)(30.0*(()/100.00)),
PROCESS_PATH,LVCFMT_CENTER,(UINT)(41.0*(()/100.00)),
};
for (int i = 0;i<3;i++)
{
ring(Column[i][0]);
m_Column(i,strValue,Column[i][1],Column[i][2]);
}
return;
19
}
void CMFCEnterDlg::OnBnClickedOpenprocess()
{
// TODO: 在此添加控件通知处理程序代码
GetToolShot();
}
void CMFCEnterDlg::OnNMClickListProcess(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
}
void CMFCEnterDlg::OnNMDblclkListProcess(NMHDR *pNMHDR, LRESULT *pResult) //双击鼠标
{
// TODO: 在此添加控件通知处理程序代码
LPNMITEMACTIVATE pNMListView = (LPNMITEMACTIVATE)pNMHDR;
CString strValue;
if (-1 != pNMListView->iItem)
{
//获得进程ID
strValue = m_mText(pNMListView->iItem,0);
m_dowText(strValue);
}
*pResult = 0;
}
五.总结:
提出问题:
1.什么是内存驻留程序
2.为什么用动态链接库能让指定的代码驻留在指定的进程的内存中?
解决问题:
1.内存驻留程序是指某一正在运行的软件程序在结束之后,仍有部分残留程序在内存中运行. 一般是软件所带的附加插件或者是流氓软件。
20
2.因为动态链接库是在内核态运行的,也就是在系统内核的那2G 空间运行,这2G空间
属于所有进程共有的,属于进程的空间,所以也就相当于在进程的内存中运行了。
六.心得体会:
在这次的课程设计中不仅检验了我所学习的知识,也培养了我如何去把握一件事情,如何去做一件事情,又如何完成一件事情。在设计过程中,与同学分工设计,和同学们相互探讨,相互学习,相互监督。学会了合作,学会了运筹帷幄,学会了宽容,学会了理解,也学会了做人与处世。 课程设计是我们专业课程知识综合应用的实践训练,着是我们迈向社会,从事职业工作前一个必不少的过程.”千里之行,始于足下”,通过这次课程设计,我深深体会到这句千古名言的真正含义.我今天认真的进行课程设计,学会脚踏实地迈开这一步,就是为明天能稳健地在社会大潮中奔跑打下坚实的基础.
七.致谢:
感谢郭锦兰老师对我们组的课程设计的指导,以及任课老师对我们的悉心教导,还有同学们的帮助。
八.参考文献:
[1] 梁亚声等.计算机网络安全教程.第2版.北京:机械工业出版社,2008
[2] 刘文涛.网络安全编程技术与实例.北京:机械工业出版社2008
21
发布评论