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(eHdc()), 0);

// 使图标在工作矩形中居中

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(m_hIcon);

}

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