基础功能

TAB控件的封装与使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//封装的Tab控件函数
void CMyTabDlg::InitTab(int nCount, ...)
{
va_list vl;
va_start(vl, nCount);

for (int i = 0; i < nCount; i++)
{
//1 获取这一个选项,需要的数据
wchar_t* szTabItemName = va_arg(vl, wchar_t*);
CDialogEx* pDlg = va_arg(vl, CDialogEx*);
DWORD dwId = va_arg(vl, DWORD);
//2 创建选项,创建子窗口
InsertItem(i, szTabItemName);
pDlg->Create(dwId, this);
//3 将子窗口移动合适的位置上
CRect rc = {};
GetClientRect(&rc);
//4 将矩形框,缩小一下,能够把Tab的表头 显示出来
rc.DeflateRect(1, 23, 1, 1);
//5 移动
pDlg->MoveWindow(rc);
m_vecDlg.push_back(pDlg);
}

m_vecDlg[0]->ShowWindow(SW_SHOW);
va_end(vl);
}

//消息映射
ON_NOTIFY_REFLECT(TCN_SELCHANGE, &CMyTabDlg::OnTcnSelchange)
//类中声明
afx_msg void OnTcnSelchange(NMHDR* pNMHDR, LRESULT* pResult);
//响应Tab控件的切换
void CMyTabDlg::OnTcnSelchange(NMHDR* pNMHDR, LRESULT* pResult)
{

int nSel = GetCurSel();

for (int i = 0; i < m_vecDlg.size(); i++)
{
if (i == nSel)
{
m_vecDlg[i]->ShowWindow(SW_SHOW);

continue;
}
m_vecDlg[i]->ShowWindow(SW_HIDE);
}

*pResult = 0;
}

//主类中的绑定
CMyTabDlg m_objTabDlg;//主类中控件的声明定义
DDX_Control(pDX, IDC_TAB1, m_objTabDlg);//控件的绑定
//主类的调用
m_objTabDlg.InitTab(7,
L"我的电脑", new CMyComputerDlg(), IDD_COMPUTER,
L"LOAD_PE",new CMyLoadPeDlg(),IDD_LOADPE,
L"清理", new CMySystemDlg(), IDD_SYSTEMINFO,
L"程序", new CMyInstallDlg(), IDD_INSTALL,
L"服务", new CMyServicesDlg(), IDD_SERVICES,
L"启动项", new CMyStartItemDlg(), IDD_STARTITEM,
L"查杀", new CMyAntivirusDlg(), IDD_ANTIVIRUS
);

关机、注销、锁屏、重启

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
case ID_32784://关机
SetSystem();
ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, SHTDN_REASON_FLAG_USER_DEFINED);
break;
case ID_32785://重启
SetSystem();
ExitWindowsEx(EWX_REBOOT | EWX_FORCE, SHTDN_REASON_FLAG_USER_DEFINED);
break;
case ID_32786://注销
ExitWindowsEx(EWX_LOGOFF | EWX_FORCE, SHTDN_REASON_FLAG_USER_DEFINED);
break;
case ID_32787://锁屏
LockWorkStation();




//关机、重启所需要调用的提权函数
void CSecurityguardDlg::SetSystem()
{
HANDLE hTOken = NULL;
HANDLE hProcess = GetCurrentProcess();//获取进程伪句柄
OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hTOken);
TOKEN_PRIVILEGES tp = { 0 };
LookupPrivilegeValue(0, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//
AdjustTokenPrivileges(hTOken, FALSE, &tp, sizeof(tp), NULL, NULL);
}

CPU、内存的占有率获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//用于辅助CPU的获取(时间换算)
double FILETIME2Double(const _FILETIME& filetime)
{
return double(filetime.dwHighDateTime * 4.294967296e9)
+ double(filetime.dwLowDateTime);
}
//CPU占用率获取
int CSecurityguardDlg::GetCpusage()
{
// 空闲时间 内核时间 用户时间
_FILETIME idleTime, kernelTime, userTime;
//获取时间
GetSystemTimes(&idleTime, &kernelTime, &userTime);

HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//等待1000毫秒
WaitForSingleObject(hEvent, 50);
//获取新时间
_FILETIME newTime, newKerneTime, newUserTime;
GetSystemTimes(&newTime, &newKerneTime, &newUserTime);
//将各个时间转换
double dOldIdleTime = FILETIME2Double(idleTime);
double dNewIdleTime = FILETIME2Double(newTime);
double dOldKernelTime = FILETIME2Double(kernelTime);
double dNewKernelTime = FILETIME2Double(newKerneTime);
double dOldUserTime = FILETIME2Double(userTime);
double dNewUserTime = FILETIME2Double(newUserTime);

return int(100.0 - (dNewIdleTime - dOldIdleTime) / (dNewKernelTime - dOldKernelTime + dNewUserTime - dOldUserTime) * 100);
}

//内存占用率获取
void CSecurityguardDlg::GetMemsage()
{
MEMORYSTATUS memStatus;
GlobalMemoryStatus(&memStatus);
CString strmery;
strmery.Format(L"内存占用率: %d%%", memStatus.dwMemoryLoad);
m_strMem.SetString(strmery);//在文本上显示
UpdateData(FALSE);
}

老板键的注册与响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ON_WM_HOTKEY()//消息映射
//类中声明
afx_msg void OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2);
//注册老板键//响应注册的按键Ctrl + Shift + Z
::RegisterHotKey(
m_hWnd, //响应热键的窗口句柄
0x1234, //热键ID,自定义ID值
MOD_CONTROL | MOD_SHIFT, //辅助按键
'Z' //键值,按键码
);


//老板键的响应
void CSecurityguardDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
static int i = 0;
if (i == 0)
{
ShowWindow(SW_HIDE);//隐藏
i = 1;
}
else
{
ShowWindow(SW_SHOW);//显示
}
CDialogEx::OnHotKey(nHotKeyId, nKey1, nKey2);
}

程序的自我复制

1
2
3
4
5
6
7
8
9
10
11
12
13
// 复制到开机启动路径
LPCTSTR targetPath = _T("C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\StartUp\\安全卫士.exe");
CopyMyselfTo(targetPath);

//自我复制
void CSecurityguardDlg::CopyMyselfTo(LPCTSTR targetPath)
{
TCHAR tcBuf[_MAX_PATH]; // 缓冲区
// 取自己程序的程序名
::GetModuleFileName(NULL, tcBuf, sizeof(tcBuf));
// 复制文件
::CopyFile(tcBuf, targetPath, FALSE);
}

计时器的设置与响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ON_WM_TIMER()//消息映射
//类中声明
afx_msg void OnTimer(UINT_PTR nIDEvent);
// 设置计时器
SetTimer(
1, //自定义的Timer的ID
1000, //间隔的毫秒数
NULL //回调函数,如果设置了,每隔500毫秒调这个回调函数
); //如果没有设置,就是给主窗口发WM_TIMER消息
SetTimer(
2, //自定义的Timer的ID
1000, //间隔的毫秒数
NULL //回调函数,如果设置了,每隔500毫秒调这个回调函数
);

//响应计时器
void CSecurityguardDlg::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1)
{
CString str;
str.Format(L"CPU占用率:%d%%", GetCpusage());
m_strCpu.SetString(str);
UpdateData(FALSE);
}
if (nIDEvent == 2)
{
GetMemsage();
}
CDialogEx::OnTimer(nIDEvent);
}

右击菜单的响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//消息映射
ON_NOTIFY(NM_RCLICK, IDC_SERVICES, &CMyServicesDlg::OnRclickServices)
//类中声明
afx_msg void OnRclickServices(NMHDR* pNMHDR, LRESULT* pResult);
//右击弹出菜单
void CMyServicesDlg::OnRclickServices(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

// 需要载入菜单资源
CMenu obj;
obj.LoadMenuW(IDR_MENU3);
//坐标转换
POINT pt = { pNMItemActivate->ptAction.x,pNMItemActivate->ptAction.y};
ClientToScreen(&pt);

// 获取一个下拉菜单
CMenu* pSubMenu1 = obj.GetSubMenu(0);

// 弹出菜单
pSubMenu1->TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, this);
//获取ID(选择的进程)
int item = pNMItemActivate->iItem; //LPNMITEMACTIVATF 这个结构体 iItem 有列表框记录的信息
strName = m_objServices.GetItemText(item, 0); //获取文本框

*pResult = 0;
}


//消息映射
ON_COMMAND_RANGE(ID_32789, ID_32790, &CMyServicesDlg::OnRangeCmds1)
//类中声明
afx_msg void OnRangeCmds1(UINT nMenuID);
//响应弹出菜单
void CMyServicesDlg::OnRangeCmds1(UINT nMenuID)
{
//获取服务的开启与结束需要的相应权限的句柄
SC_HANDLE hScMess = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
SC_HANDLE hService = OpenService(hScMess,strName,SC_MANAGER_ALL_ACCESS
);
switch (nMenuID)
{
case ID_32789://开启服务
StartService(hService, NULL, NULL);
break;
case ID_32790://结束服务
SERVICE_STATUS_PROCESS ssp;
ControlService(hService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp);
break;
default:
break;
}
}

管理员运行无法拖拽

1
2
3
//解决管理员无法拖拽
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
ChangeWindowMessageFilter(0x0049, MSGFLT_ADD);

响应拖拽

1
2
3
4
5
6
7
8
9
10
11
12
13
//响应文件拖拽
void CMyLoadPeDlg::OnDropFiles(HDROP hDropInfo)
{
// 存放文件路径
wchar_t filePath[MAX_PATH] = {};

// 获取拖拽文件的路径
DragQueryFile(hDropInfo, 0, filePath, MAX_PATH);



CDialogEx::OnDropFiles(hDropInfo);
}

进程遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//遍历进程
void CMyLoadPeDlg::EnumProcess()
{
m_vecProcess.clear();
CString cs;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { sizeof(pe) };
if (Process32First(hSnap, &pe))
{
int i = 0;
do
{
PROCESS* stcPro = new PROCESS;

GetPathByProcessId(pe.th32ProcessID, stcPro);
cs = szPath;//WCHAR*[MAX+PATH]无法直接与L""比较(类型不符),所以这里需要转换一下
if (cs==L"")//如果路径为空直接输出进程名
{
m_objProcessList.InsertItem(i, pe.szExeFile, i);
}
else
{
SHFILEINFO info = { 0 };
CString temp = szPath;
SHGetFileInfo(temp, 0, &info, sizeof(&info), SHGFI_DISPLAYNAME | SHGFI_ICON);
m_ImageList.Add(info.hIcon);
if (info.hIcon == NULL)//如果图标没有获取到,则直接输出进程名
{
m_objProcessList.InsertItem(i, pe.szExeFile, i);
}
else
{
m_objProcessList.InsertItem(i, info.szDisplayName, i);
}
}
// 转换成字符串格式
wchar_t tmp[100] = {};
wsprintf(tmp, L"%d", pe.th32ProcessID);

m_objProcessList.SetItemText(i, 1, tmp);

cs.Format(L"%d", pe.cntThreads);
m_objProcessList.SetItemText(i, 2, cs);

m_objProcessList.SetItemText(i, 3, L"正在运行");
//使用vector保存进程名和id
cs = szPath;
m_objProcessList.SetItemText(i, 4, cs);
stcPro->csProcessName = pe.szExeFile;
stcPro->dwProcessId = pe.th32ProcessID;
stcPro->csProcessPath = szPath;
m_vecProcess.push_back(stcPro);
i++;

} while (Process32Next(hSnap, &pe));
}
}

循环遍历进程

查找是否由黑名单进程,既然是循环肯定要开线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//循环遍历进程,查看是否由黑名单程序运行
void CMyLoadPeDlg::WhileProcessEunm()
{
while (true)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
// 判断快照句柄是否有效
if (hSnapshot != INVALID_HANDLE_VALUE)
{
//定义进程结构体,第一个元素必须赋值为结构体大小
PROCESSENTRY32 stcPe32 = { sizeof(PROCESSENTRY32) };
//查找第一个进程
Process32First(hSnapshot, &stcPe32);
do
{ // 如果进程名一致,返回进程id

for (int i = 0; i < m_vecHeiName.size(); i++)
{
if (stcPe32.szExeFile == m_vecHeiName[i])
{
HANDLE Process = OpenProcess(PROCESS_TERMINATE, FALSE, stcPe32.th32ProcessID);
TerminateProcess(Process, 0);
//CloseHandle(Process);
}
}
//查找下一个进程
} while (Process32Next(hSnapshot, &stcPe32));
}
//关闭快照句柄
CloseHandle(hSnapshot);
Sleep(1000);
}

}

守护进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#define DLLPATH "C:\\xxx\\InlineHook.dll"


//守护进程的回调函数
WORD WINAPI ThreadGuardianProcessBack(LPARAM lparam)
{
CMyLoadPeDlg* pObj = (CMyLoadPeDlg*)lparam;

// 1.获取目标进程句柄
// 1.1 获取指定进程id
DWORD dwPid = GetPid(L"Taskmgr.exe");
// 1.2 打开进程(注入OD需要以管理员身份运行vs,否则无法打开进程)
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
// 1.3 检测进程句柄
if (hProcess == INVALID_HANDLE_VALUE)
ThreadGuardianProcessBack((LPARAM)pObj);

// 2.1 计算dll路径长度
DWORD dwSize = strlen(DLLPATH) + 1;
// 2.在目标进程申请一段空间
LPVOID lpAddr = VirtualAllocEx(
hProcess, 0, dwSize, MEM_COMMIT, PAGE_READWRITE);

if (!WriteProcessMemory(hProcess, lpAddr, DLLPATH, dwSize, NULL))
ThreadGuardianProcessBack((LPARAM)pObj);

// 4.创建远程线程
HANDLE hRtThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)LoadLibraryA, lpAddr, NULL, NULL);


Sleep(1000000);
// 5.等待执行结果
WaitForSingleObject(hRtThread, -1);

// 6.获取线程退出码
DWORD dwExitCode = 0;
GetExitCodeThread(hRtThread, &dwExitCode);
// 6.1 退出码也就是LoadLibrary的返回值(如果执行成功,就是dll的模块句柄)
HMODULE hModule = (HMODULE)dwExitCode;

// 7.释放空间
if (!VirtualFreeEx(hProcess, lpAddr, dwSize, MEM_DECOMMIT))
return -1;
CloseHandle(hProcess);


return 0;
}

所用dll

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <TlHelp32.h>

// 通过进程名获取进程id
DWORD GetPid(const wchar_t* filePath);
// 获取被保护程序pid
DWORD g_dwPid = GetPid(L"FileCleaner2.0.exe");
// 旧的函数地址
DWORD* g_pOldAddr = (DWORD*)OpenProcess;
// 旧的函数数据
char g_oldCode[5] = {};

void OnHook();
void UnHook();

// 编写自己的OpenProcess函数
HANDLE WINAPI MyOpenProcess(
_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ DWORD dwProcessId
)
{
// 比对pid是否与helloworld程序相等
if (dwProcessId == g_dwPid)
{
MessageBox(0,L"进程被保护",L"提示",0);
}
else
{
// 如果不相等,重新调用原来的OpenProcess函数
// 先恢复原来函数数据
UnHook();
HANDLE hProcess = OpenProcess(
dwDesiredAccess, bInheritHandle, dwProcessId);
// 调用完之后重新hook
OnHook();
return hProcess;
}
}

BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
OnHook();
MessageBox(NULL, L"注入成功", L"提示", NULL);
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

void OnHook()
{
// 1.先保存OpenProcess原来的数据
memcpy(g_oldCode, g_pOldAddr, 5);

// 2.设置新的指令,jmp
char opcode[5] = { 0xE9 };
// 2.1 计算偏移并赋值
*(DWORD*)(opcode + 1) = (DWORD)MyOpenProcess - (DWORD)OpenProcess - 5;

// 3.修改保护属性
DWORD dwOldProtect = 0;
VirtualProtect(g_pOldAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);

// 4.写入跳转指令
memcpy(g_pOldAddr, opcode, 5);

// 5.还原保护属性
VirtualProtect(g_pOldAddr, 5, dwOldProtect, &dwOldProtect);
}

void UnHook()
{
// 1.修改保护属性
DWORD dwOldProtect = 0;
VirtualProtect(g_pOldAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
// 2.还原旧的指令数据
memcpy(g_pOldAddr, g_oldCode, 5);
// 3.还原保护属性
VirtualProtect(g_pOldAddr, 5, dwOldProtect, &dwOldProtect);
}

DWORD GetPid(const wchar_t* szExeName)
{
// 创建进程快照
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
// 判断快照句柄是否有效
if (hSnapshot != INVALID_HANDLE_VALUE)
{
//定义进程结构体,第一个元素必须赋值为结构体大小
PROCESSENTRY32 stcPe32 = { sizeof(PROCESSENTRY32) };
//查找第一个进程
Process32First(hSnapshot, &stcPe32);
do
{ // 如果进程名一致,返回进程id
if (!wcscmp(stcPe32.szExeFile, szExeName))
return stcPe32.th32ProcessID;

//查找下一个进程
} while (Process32Next(hSnapshot, &stcPe32));
//关闭快照句柄
CloseHandle(hSnapshot);
}
return -1;
}

遍历窗口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//枚举窗口
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
static int i = 0;
CMyLoadPeDlg* t = (CMyLoadPeDlg*)lParam;
TCHAR buff[200];
TCHAR ClassName[200];
GetWindowText(hWnd, buff, 200);
GetClassName(hWnd, ClassName,200 );
//HICON hIcon = (HICON)GetClassLongPtr(hWnd, GCLP_HICON);
static HICON hIcon = LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));//加载本地自己的图标
CString cs;
if (hIcon != 0)
{
t->m_vecIcon.push_back(hIcon);
}

if (IsWindowVisible(hWnd) == TRUE && wcslen(buff) != 0)
{

cs.Format(L"%s", buff);
t->m_objEMWNDLope.InsertItem(i, cs , i);
t->m_objEMWNDLope.SetItemText(i, 1, ClassName);
}
//cs=ClassName;

i++;
return TRUE;
}

获取进程PID

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DWORD GetPid(const wchar_t* szExeName)
{
// 创建进程快照
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
// 判断快照句柄是否有效
if (hSnapshot != INVALID_HANDLE_VALUE)
{
//定义进程结构体,第一个元素必须赋值为结构体大小
PROCESSENTRY32 stcPe32 = { sizeof(PROCESSENTRY32) };
//查找第一个进程
Process32First(hSnapshot, &stcPe32);
do
{ // 如果进程名一致,返回进程id
if (!wcscmp(stcPe32.szExeFile, szExeName))
return stcPe32.th32ProcessID;

//查找下一个进程
} while (Process32Next(hSnapshot, &stcPe32));
//关闭快照句柄
CloseHandle(hSnapshot);
}
return -1;
}

将wchar_t类型转换为整形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
CString strPid = m_objProcessList.GetItemText(item, 1);  //获取文本框
DWORD dwPID = _wtoi(strPid);//转换为整型




//将字符串转换为整数

//(1).转换函数
// 双精度函数
double atof(
const char *string
);
double _wtof(
const wchar_t *string
);
// 自适应
TCHAR: _tstof 、 _ttof
VS2005:_atof_l 、_wtof_l 、 _atodbl 、 _atodbl_l

// 整型函数
int atoi(
const char *string
);
_int64 _atoi64(
const char *string
);
int _wtoi(
const wchar_t *string
);
_int64 _ wtoi64(
const char *string
);
// 自适应
TCHAR:_tstoi 、 _ttoi 、_tstoi64 、_ttoi64
VS2005:_atoi_l 、 _wtoi_l 、_atoi64_l 、_wtoi64_l

//长整形函数
long atol(
const char * string
);
long _wtol(
const wchar_t *string
);
//自适应
TCHAR:_tstoi 、_ttoi
VS2005:_atoi_l 、_wtoi_l


//将整数转换为字符串
itoa、_itoa、ltoa、_ltoa、ultoa、_ultoa、_i64toa、_ui64toa、_itow、_ltow、_ultow、_i64tow、_ui64tow

WCHAR* 转char*

1
2
3
4
5
6
7
//wchar* 转到 char*
  
#include <comdef.h> // you will need this
const WCHAR* wc = L"Hello World" ;
_bstr_t b(wc);
const char* c = b;
printf("Output: %s\n", c);

安装程序的遍历及卸载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//,需要开线程不然很卡
HANDLE hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadPro, this->m_objInstallList, NULL, NULL);

//已安装程序的获取(回调函数)
DWORD WINAPI ThreadPro(CListCtrl Soft)
{
//CImageList m_objIma;
//m_objIma.Create(16, 16, ILC_COLOR32, 4, 1); //创建图像序列CImageList对象
//Soft.SetImageList(&m_objIma, LVSIL_SMALL);
struct _SoftInfo
{
// 软件名
WCHAR m_strSoftName[50];
// 软件版本号
WCHAR m_strSoftVersion[50];
// 软件安装目录
WCHAR m_strInstallLocation[MAX_PATH];
// 软件发布厂商
WCHAR m_strPublisher[50];
// 主程序所在完整路径
WCHAR m_strMainProPath[MAX_PATH];
// 卸载exe所在完整路径
WCHAR m_strUninstallPth[MAX_PATH];
}SoftInfo;
// 主键
HKEY RootKey;
// 子键名称
LPCTSTR lpSubKey;
// 将要打开键的句柄
HKEY hkResult;
// 记录读取注册表是否成功
LONG lReturn;
CString strBuffer;
CString strMidReg;
int i = 0;
DWORD index = 0;
TCHAR szKeyName[255] = { 0 }; // 注册表项名称
TCHAR szBuffer[255] = { 0 };
DWORD dwKeyLen = 255;
DWORD dwNameLen = 255;
DWORD dwType = REG_BINARY | REG_DWORD | REG_EXPAND_SZ | REG_MULTI_SZ | REG_NONE | REG_SZ;
CString* name = new CString;
RootKey = HKEY_LOCAL_MACHINE;
lpSubKey = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall");

bool isOK = false;
lReturn = RegOpenKeyEx(RootKey, lpSubKey, 0, KEY_ALL_ACCESS, &hkResult);
DWORD dwIndex = 0;
while (true)
{
DWORD dwKeyLen = 255;
WCHAR szNewKeyName[MAX_PATH] = {};
LONG lReturn = RegEnumKeyEx(hkResult, dwIndex, szNewKeyName, &dwKeyLen, 0, NULL, NULL, NULL);
OutputDebugString(szNewKeyName);
WCHAR strMidReg[MAX_PATH] = {};
swprintf_s(strMidReg, L"%s%s%s", lpSubKey, L"\\", szNewKeyName);
HKEY hkValueKey = 0;
RegOpenKeyEx(RootKey, strMidReg, 0, KEY_QUERY_VALUE, &hkValueKey);

DWORD dwNameLen = 255;
RegQueryValueEx(hkValueKey, L"DisplayName", 0, &dwType, (LPBYTE)SoftInfo.m_strSoftName, &dwNameLen);
dwNameLen = 255;

if (SoftInfo.m_strSoftName == name[0])//去除重复
{
dwIndex++;
continue;
}
name[0] = SoftInfo.m_strSoftName;

Soft.InsertItem(i, L"");
//名字
Soft.InsertItem(i, SoftInfo.m_strSoftName);
// 厂商
RegQueryValueEx(hkValueKey, L"Publisher", 0, &dwType, (LPBYTE)SoftInfo.m_strPublisher, &dwNameLen);
dwNameLen = 255;
Soft.SetItemText(i, 1, SoftInfo.m_strPublisher);


//安装路径
RegQueryValueEx(hkValueKey, L"InstallLocation", 0, &dwType, (LPBYTE)SoftInfo.m_strInstallLocation, &dwNameLen);
dwNameLen = 255;
Soft.SetItemText(i, 2, SoftInfo.m_strInstallLocation);

//卸载路径
RegQueryValueEx(hkValueKey, L"UninstallString", 0, &dwType, (LPBYTE)SoftInfo.m_strUninstallPth, &dwNameLen);
dwNameLen = 255;
Soft.SetItemText(i, 3, SoftInfo.m_strUninstallPth);//

i++;
dwIndex++;
if (lReturn == ERROR_NO_MORE_ITEMS)
{
break;
}
}

return 0;
}

//消息映射
ON_NOTIFY(NM_DBLCLK, IDC_INSTALL, &CMyInstallDlg::OnDblclkInstall)
//类中声明
afx_msg void OnDblclkInstall(NMHDR* pNMHDR, LRESULT* pResult);
//双击响应卸载
void CMyInstallDlg::OnDblclkInstall(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

int Value = MessageBox(L"请再次确定卸载该程序", L"警告!", MB_OK | MB_OKCANCEL);
if (Value == IDCANCEL)
{
return;
}
CString Path = m_objInstallList.GetItemText(pNMItemActivate->iItem, 3);

ShellExecute(NULL, NULL, _T("explorer"), Path, NULL, SW_SHOW);


*pResult = 0;
}

服务的遍历与开关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//状态赋值
void CMyServicesDlg::ServiceStaus()
{
mapServiceStaus[1] = "服务已停止";
mapServiceStaus[2] = "服务正在启动";
mapServiceStaus[3] = "服务正在停止";
mapServiceStaus[4] = "服务正在运行";
mapServiceStaus[5] = "该服务将继续";
mapServiceStaus[6] = "服务正在暂停";
mapServiceStaus[7] = "服务已暂停";

}

//遍历服务
void CMyServicesDlg::EnumServices()
{
ServiceStaus();
//打开远程计算机服务控制管理器
SC_HANDLE hscm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
//第一次调用,获取内容大小
DWORD dwServiceNum = 0;
DWORD dwSize = 0;
EnumServicesStatusEx(
hscm,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
SERVICE_STATE_ALL,//所有服务状态
NULL, //缓冲区大小
0, //缓冲区大小
&dwSize, //需要大小
&dwServiceNum, //缓冲区服务个数
NULL, NULL
);
//3.申请需要的内存,第二次调用
LPENUM_SERVICE_STATUS_PROCESS pEnumService = (LPENUM_SERVICE_STATUS_PROCESS)new char[dwSize];
//4.第二次枚举
bool bStatus = FALSE;
bStatus = EnumServicesStatusEx(
hscm,
SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
SERVICE_STATE_ALL,//所有服务状态
(PBYTE)pEnumService, //缓冲区大小
dwSize, //缓冲区大小
&dwSize, //需要大小
&dwServiceNum, //缓冲区服务个数
NULL, NULL
);
//遍历信息
CString cs;
for (DWORD i = 0; i < dwServiceNum; i++)
{
cs = pEnumService[i].lpServiceName;
m_objServices.InsertItem(i, cs);
cs.Format(L"%d", pEnumService[i].ServiceStatusProcess.dwProcessId);
m_objServices.SetItemText(i, 1, cs);
cs = pEnumService[i].lpDisplayName;
m_objServices.SetItemText(i, 2, cs);
cs = mapServiceStaus[pEnumService[i].ServiceStatusProcess.dwCurrentState];
m_objServices.SetItemText(i, 3, cs);
}
}

系统、CPU、内存网卡信息的获取

我直接在网上找到的零散代码,给他整合封装成了一个类

.h文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#pragma once

#include <iostream>
#include <string>
#include <string.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <windows.h>
#include <intrin.h>
#pragma comment(lib, "iphlpapi.lib")
//去掉警告信息
#pragma warning(disable: 4996)

//保存获取到信息的结构体
typedef struct _SYSTEMINFO
{
//OS INFO
CString OS_NAME;
CString OS_VERSION;
//CPU INFO
LONG CPU_FREQUENCY;
CString CPU_MANUFACTURE;
CString CPU_TYPE;
//MEMORY INFO
CString MEMORY_INFO;
//DISK
CString HardDisk;
//NETWORK
CString NET_CARD;
CString NET_CARD_NAME;
CString NET_CARD_DECS;
CString NET_IP;
CString NET_MAC;
//PROCESS
CString PID;

}SYSTEMINFO,*PSYSTEMINFO;



class DiySystemInfo
{
public:
void GetInfo();
private:
void getOsInfo();
#ifdef _WIN64
void getCpuInfo();

#else

void initCpu(DWORD veax);
long getCpuFreq();
CString getManufactureID();
CString getCpuType();
void getCpuInfo();
#endif

void getMemoryInfo();
CString execCmd(const char* cmd);
void getHardDiskInfo();
void getNetworkInfo();
void getProcessInfo();

public:
SYSTEMINFO m_SystemInfo;

};

.cpp文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#include "pch.h"
#include "DiySystemInfo.h"


//字节转换的宏定义
static const int kMaxInfoBuffer = 256;
#define GBYTES 1073741824
#define MBYTES 1048576
#define KBYTES 1024
#define DKBYTES 1024.0






// 系统版本的获取
void DiySystemInfo::getOsInfo()
{
// get os name according to version number
OSVERSIONINFO osver = { sizeof(OSVERSIONINFO) };
GetVersionEx(&osver);
CString os_name;
if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0)
os_name = "Windows 2000";
else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 1)
os_name = "Windows XP";
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0)
os_name = "Windows 2003";
else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2)
os_name = "windows vista";
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1)
os_name = "windows 7";
else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2)
os_name = "windows 10";

m_SystemInfo.OS_NAME = os_name;
m_SystemInfo.OS_VERSION.Format(L"%d.%d", osver.dwMajorVersion, osver.dwMinorVersion);

}



#ifdef _WIN64

// 当程序是64位时CPU的初始化和获取

void DiySystemInfo::getCpuInfo()
{
int cpuInfo[4] = { -1 };
char cpu_manufacture[32] = { 0 };
char cpu_type[32] = { 0 };
char cpu_freq[32] = { 0 };

__cpuid(cpuInfo, 0x80000002);
memcpy(cpu_manufacture, cpuInfo, sizeof(cpuInfo));

__cpuid(cpuInfo, 0x80000003);
memcpy(cpu_type, cpuInfo, sizeof(cpuInfo));

__cpuid(cpuInfo, 0x80000004);
memcpy(cpu_freq, cpuInfo, sizeof(cpuInfo));

m_SystemInfo.CPU_FREQUENCY = cpu_freq;
m_SystemInfo.CPU_MANUFACTURE = cpu_manufacture;
m_SystemInfo.CPU_TYPE = cpu_type;
}

#else

DWORD deax;
DWORD debx;
DWORD decx;
DWORD dedx;
// 使用汇编初始化CPU
void DiySystemInfo::initCpu(DWORD veax)
{
__asm
{
mov eax, veax
cpuid
mov deax, eax
mov debx, ebx
mov decx, ecx
mov dedx, edx
}
}
//频率
long DiySystemInfo::getCpuFreq()
{
int start, over;
_asm
{
RDTSC
mov start, eax
}
Sleep(50);
_asm
{
RDTSC
mov over, eax
}
return (over - start) / 50000;
}

//制造商
CString DiySystemInfo::getManufactureID()
{
char manuID[25];
memset(manuID, 0, sizeof(manuID));

initCpu(0);
memcpy(manuID + 0, &debx, 4);
memcpy(manuID + 4, &dedx, 4);
memcpy(manuID + 8, &decx, 4);

CString cs;
cs.Format(L"%S", manuID);
return cs;
}
//CPU的类型
CString DiySystemInfo::getCpuType()
{
const DWORD id = 0x80000002; // start 0x80000002 end to 0x80000004
char cpuType[49];
memset(cpuType, 0, sizeof(cpuType));

for (DWORD t = 0; t < 3; t++)
{
initCpu(id + t);

memcpy(cpuType + 16 * t + 0, &deax, 4);
memcpy(cpuType + 16 * t + 4, &debx, 4);
memcpy(cpuType + 16 * t + 8, &decx, 4);
memcpy(cpuType + 16 * t + 12, &dedx, 4);
}
CString cs;
cs.Format(L"%S", cpuType);
return cs;
}
//CPU的调用
void DiySystemInfo::getCpuInfo()
{
m_SystemInfo.CPU_FREQUENCY = getCpuFreq();
m_SystemInfo.CPU_MANUFACTURE = getManufactureID();
m_SystemInfo.CPU_TYPE = getCpuType();
}

#endif

// 获取存信息
void DiySystemInfo::getMemoryInfo()
{
std::string memory_info;
MEMORYSTATUSEX statusex;
statusex.dwLength = sizeof(statusex);
if (GlobalMemoryStatusEx(&statusex))
{
unsigned long long total = 0, remain_total = 0, avl = 0, remain_avl = 0;
double decimal_total = 0, decimal_avl = 0;
remain_total = statusex.ullTotalPhys % GBYTES;
total = statusex.ullTotalPhys / GBYTES;
avl = statusex.ullAvailPhys / GBYTES;
remain_avl = statusex.ullAvailPhys % GBYTES;
if (remain_total > 0)
decimal_total = (remain_total / MBYTES) / DKBYTES;
if (remain_avl > 0)
decimal_avl = (remain_avl / MBYTES) / DKBYTES;

decimal_total += (double)total;
decimal_avl += (double)avl;
char buffer[kMaxInfoBuffer];
sprintf_s(buffer, kMaxInfoBuffer, "total %.2f GB (%.2f GB available)", decimal_total, decimal_avl);
memory_info.append(buffer);
}

m_SystemInfo.MEMORY_INFO.Format(L"%S",memory_info.c_str());
}


CString DiySystemInfo::execCmd(const char* cmd)
{
char buffer[128] = { 0 };
CString result;
FILE* pipe = _popen(cmd, "r");
if (!pipe) throw std::runtime_error("_popen() failed!");
while (!feof(pipe))
{
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
_pclose(pipe);

return result;
}
// 获取序列号
void DiySystemInfo::getHardDiskInfo()
{
CString hd_seiral = execCmd("wmic path win32_physicalmedia get SerialNumber");

m_SystemInfo.HardDisk = hd_seiral;
}

//获取网卡信息
void DiySystemInfo::getNetworkInfo()
{
PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
unsigned long adapter_size = sizeof(IP_ADAPTER_INFO);
int ret = GetAdaptersInfo(pIpAdapterInfo, &adapter_size);

if (ret == ERROR_BUFFER_OVERFLOW)
{

delete pIpAdapterInfo;
pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[adapter_size];
ret = GetAdaptersInfo(pIpAdapterInfo, &adapter_size);
}

if (ret == ERROR_SUCCESS)
{
int card_index = 0;


while (pIpAdapterInfo)
{
pIpAdapterInfo->Description << std::endl;
m_SystemInfo.NET_CARD.Format(L"%d", ++card_index);
m_SystemInfo.NET_CARD_NAME = pIpAdapterInfo->AdapterName;
m_SystemInfo.NET_CARD_DECS = pIpAdapterInfo->Description;


PIP_ADDR_STRING pIpAddr = &(pIpAdapterInfo->IpAddressList);
while (pIpAddr)
{
char local_ip[128] = { 0 };
strcpy(local_ip, pIpAddr->IpAddress.String);

m_SystemInfo.NET_IP.Format(L"%S",local_ip);
pIpAddr = pIpAddr->Next;
}

char local_mac[128] = { 0 };
int char_index = 0;
for (int i = 0; i < pIpAdapterInfo->AddressLength; i++)
{
char temp_str[10] = { 0 };
sprintf(temp_str, "%02X-", pIpAdapterInfo->Address[i]);
strcpy(local_mac + char_index, temp_str);
char_index += 3;
}
local_mac[17] = '\0';


m_SystemInfo.NET_MAC.Format(L"%S",local_mac);

break;

}
}

if (pIpAdapterInfo)
delete pIpAdapterInfo;
}

// 进程ID的获取 //
void DiySystemInfo::getProcessInfo()
{
int pid = GetCurrentProcessId();

m_SystemInfo.PID.Format(L"Current Pid:%d",pid);
}
//对外调用的接口
void DiySystemInfo::GetInfo()
{
//系统信息
getOsInfo();

//CPU信息
getCpuInfo();

//内存信息
getMemoryInfo();

//序列号
getHardDiskInfo();

//网卡信息
getNetworkInfo();

//进程ID
getProcessInfo();

}

调用与输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//获取系统信息
void CMyComputerDlg::GetSystemInfo()
{
CString cs;
DiySystemInfo system;
system.GetInfo();
m_strOsName.SetString(system.m_SystemInfo.OS_NAME);
m_strOsVersion.SetString(system.m_SystemInfo.OS_VERSION);
cs.Format(L"%dHZ", system.m_SystemInfo.CPU_FREQUENCY);
m_strCpuFre.SetString(cs);
m_strCpuManuFac.SetString(system.m_SystemInfo.CPU_MANUFACTURE);
m_strCpuType.SetString(system.m_SystemInfo.CPU_TYPE);
m_strMemory.SetString(system.m_SystemInfo.MEMORY_INFO);
m_strDisk.SetString(system.m_SystemInfo.HardDisk);
m_strNetCard.SetString(system.m_SystemInfo.NET_CARD);
m_strNetCardName.SetString(system.m_SystemInfo.NET_CARD_NAME);
m_strNetCardDecs.SetString(system.m_SystemInfo.NET_CARD_DECS);
m_strNetIp.SetString(system.m_SystemInfo.NET_IP);
m_strNetMac.SetString(system.m_SystemInfo.NET_MAC);

UpdateData(FALSE);
}

文件的遍历与树控件

初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//计算机界面的初始化
BOOL CMyComputerDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

//初始化Tree控件风格
DWORD dwStyle = GetWindowLong(m_objComTree.m_hWnd, GWL_STYLE);
dwStyle |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
SetWindowLong(m_objComTree.m_hWnd, GWL_STYLE, dwStyle);

m_objComList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );//更改风格
// 添加列
m_objComList.InsertColumn(0, L"文件名", 0, 150);
m_objComList.InsertColumn(1, L"类型", 0, 80);
m_objComList.InsertColumn(2, L"大小", 0, 50);
m_objComList.InsertColumn(3, L"修改日期", 0, 200);
m_objComList.InsertColumn(4, L"属性", 0, 100);
m_objComList.InsertColumn(5, L"路径", 0, 200);
//列表图片
m_ImageList.Create(16, 16, ILC_COLOR32, 4, 1); //创建图像序列CImageList对象
m_objComList.SetImageList(&m_ImageList, LVSIL_SMALL); //为树形控件设置图像序列
//树控件图片
m_DirImage.Create(16, 16, ILC_COLOR32, 4, 4);
CBitmap ComPuter;
ComPuter.LoadBitmap(IDB_BITMAP3);
//m_ComputerImage
m_DirImage.Add(&ComPuter, RGB(0, 0, 0));

m_Root = m_objComTree.InsertItem(L"此电脑",0,0);
//遍历磁盘
GetDistHeadInfo();
//插入磁盘分区
for (unsigned int i = 0; i < Disk.size(); i++)
{
SHFILEINFO info = { 0 };
CString temp = Disk[i]->csDiskHead;
SHGetFileInfo(temp, 0, &info, sizeof(&info), SHGFI_DISPLAYNAME | SHGFI_ICON);
int b = m_DirImage.Add(info.hIcon);
//Disk[i]->csDiskHead += Disk[i]->attribute;
temp += Disk[i]->attribute;
HTREEITEM hDiskHead = m_objComTree.InsertItem(Disk[i]->csDiskHead, b, b, m_Root);

}
m_objComTree.SetImageList(&m_DirImage, LVSIL_NORMAL);
return TRUE;
}

获取分区盘符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//遍历盘符
void CMyComputerDlg::GetDistHeadInfo()
{
//1. 获取驱动器名称
TCHAR buf[100] = {};
TCHAR* pTemp = buf;

DWORD 总容量;
DWORD 空闲容量;
GetLogicalDriveStrings(100, buf);
// 把语言设置为中文
setlocale(LC_ALL, "chs");
int Flag = 0;


while (pTemp[0] != 0)
{
MyDiskHeadInfo* pds = new MyDiskHeadInfo;
//2. 获取驱动器类型
DWORD dwType = GetDriveType(pTemp);
switch (dwType)
{
case DRIVE_REMOVABLE:
//..ListView_SetItemText(hListCtrl, Flag, 1, (TCHAR*)_T("可移动设备"));
pds->attribute = L"可移动设备";

break;
case DRIVE_FIXED:
//ListView_SetItemText(hListCtrl, Flag, 1, (TCHAR*)_T("硬盘"));
pds->attribute = L"硬盘";

break;
case DRIVE_REMOTE:
//ListView_SetItemText(hListCtrl, Flag, 1, (TCHAR*)_T("远程设备"));
pds->attribute = L"远程设备";

break;
case DRIVE_CDROM:
// ListView_SetItemText(hListCtrl, Flag, 1, (TCHAR*)_T("光驱"));
pds->attribute = L"光驱";

break;
default:
break;
}
//3. 驱动器的空间信息
DWORD 每簇的扇区数量 = 0;
DWORD 每个扇区的容量 = 0;
DWORD 空闲簇的总量 = 0;
DWORD 全部簇的总量 = 0;
GetDiskFreeSpace(pTemp,
&每簇的扇区数量,
&每个扇区的容量,
&空闲簇的总量,
&全部簇的总量
);

pds->uAllSize = (((全部簇的总量 / 1024.0) * 每簇的扇区数量 * 每个扇区的容量) / 1024) / 1024;
pds->uAbouleSize = (((空闲簇的总量 / 1024.0) * 每簇的扇区数量 * 每个扇区的容量) / 1024) / 1024;
pds->uUsed = pds->uAllSize - pds->uAbouleSize;


pds->csDiskHead = pTemp;
Disk.push_back(pds);
pTemp += wcslen(buf) + 1;

Flag++;

}

}

添加目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//添加子目录
void CMyComputerDlg::AddSubDir(HTREEITEM hParent)
{
CString strPath = GetFullPath(hParent); //获取全路径
if (strPath.Right(1) != "\\")
strPath += "\\";
strPath += "*.*";
CFileFind file;
BOOL bContinue = file.FindFile(strPath); //查找包含字符串的文件

while (bContinue)
{
bContinue = file.FindNextFile(); //查找下一个文件
if (file.IsDirectory() && !file.IsDots())
{

SHFILEINFO info = { 0 };
CString temp = strPath;
int index = temp.Find(L"*.*");
temp.Delete(index, 3);
SHGetFileInfo(temp + file.GetFileName(), 0, &info, sizeof(&info), SHGFI_DISPLAYNAME | SHGFI_ICON);
int i = m_DirImage.Add(info.hIcon);
//m_objComList.InsertItem(i, info.szDisplayName, i);
m_objComTree.InsertItem(file.GetFileName(),i,i, hParent);
}

}
}

获取全路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//获取树项目全根路径
CString CMyComputerDlg::GetFullPath(HTREEITEM hCurrent)
{
CString strTemp;
CString strReturn = L"";
while (hCurrent != m_Root)
{
strTemp = m_objComTree.GetItemText(hCurrent); //检索列表中项目文字
if (strTemp.Right(1) != "\\")
strTemp += "\\";
strReturn = strTemp + strReturn;
hCurrent = m_objComTree.GetParentItem(hCurrent); //返回父项目句柄
}
csPath = strReturn;
return strReturn;
}

在List控件中显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//在右侧列表响应子文件图标
void CMyComputerDlg::OnSelchangedTree1(NMHDR* pNMHDR, LRESULT* pResult)
{
int Const = 0;

m_objComList.DeleteAllItems();
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
TVITEM item = pNMTreeView->itemNew;
if (item.hItem == m_Root)
return;
CString str = GetFullPath(item.hItem);
if (str.Right(1) != "\\")
str += "\\";
str += "*.*";
CFileFind file;
BOOL bContinue = file.FindFile(str);
while (bContinue)
{
bContinue = file.FindNextFile();

if (!file.IsDirectory() && !file.IsDots())
{
SHFILEINFO info = {0};
CString temp = str;
int index = temp.Find(L"*.*");
temp.Delete(index, 3);
SHGetFileInfo(temp + file.GetFileName(), 0, &info, sizeof(&info), SHGFI_DISPLAYNAME | SHGFI_ICON);
int i = m_ImageList.Add(info.hIcon);
m_objComList.InsertItem(i, info.szDisplayName, i);
CString filePath;
filePath.Format(temp+ file.GetFileName());
ShowFileInfo(filePath,Const);
Const++;
}
}

*pResult = 0;
}

获取文件的信息并输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//显示文件信息
void CMyComputerDlg::ShowFileInfo(CString filePath,int i)
{

FILEINFO* fileInfo = new FILEINFO;
CString buf;//缓冲区
// 筛选处指定后缀名的文件
if (wcscmp(L".sLn", PathFindExtension(filePath)) == 0 ||
wcscmp(L".obj", PathFindExtension(filePath)) == 0 ||
wcscmp(L".tlog", PathFindExtension(filePath)) == 0 ||
wcscmp(L".idb", PathFindExtension(filePath)) == 0 ||
wcscmp(L".pdb", PathFindExtension(filePath)) == 0 ||
wcscmp(L".pch", PathFindExtension(filePath)) == 0 ||
wcscmp(L".res", PathFindExtension(filePath)) == 0 ||
wcscmp(L".ilk", PathFindExtension(filePath)) == 0 ||
wcscmp(L".sdf", PathFindExtension(filePath)) == 0 ||
wcscmp(L".ipch", PathFindExtension(filePath)) == 0 ||
wcscmp(L".lastbuildstate", PathFindExtension(filePath)) == 0
)
{
buf.Format(L"VS工程文件");
m_objComList.SetItemText(i, 1, buf);
//wcscmp(L".exe", PathFindExtension(filePath)) == 0 ||
fileInfo->TYPE = buf;
}
else if (wcscmp(L".cpp", PathFindExtension(filePath)) == 0 ||
wcscmp(L".h", PathFindExtension(filePath)) == 0
)
{
buf.Format(L"C++代码");
m_objComList.SetItemText(i, 1, buf);
fileInfo->TYPE = buf;
}
else if (wcscmp(L".exe", PathFindExtension(filePath)) == 0

)
{
buf.Format(L"应用程序");
m_objComList.SetItemText(i, 1, buf);
fileInfo->TYPE = buf;
}
else if (
wcscmp(L".dll", PathFindExtension(filePath)) == 0
)
{
buf.Format(L"应用程序扩展");
m_objComList.SetItemText(i, 1, buf);
fileInfo->TYPE = buf;
}
else if (wcscmp(L".msi", PathFindExtension(filePath)) == 0

)
{
buf.Format(L"Windows安装程序包");
m_objComList.SetItemText(i, 1, buf);
fileInfo->TYPE = buf;
}
else if (wcscmp(L".html", PathFindExtension(filePath)) == 0||
wcscmp(L".js", PathFindExtension(filePath)) == 0 ||
wcscmp(L".css", PathFindExtension(filePath)) == 0 ||
wcscmp(L".htm", PathFindExtension(filePath)) == 0
)
{
buf.Format(L"网页文件");
m_objComList.SetItemText(i, 1, buf);
fileInfo->TYPE = buf;
}
else if (
wcscmp(L".rar", PathFindExtension(filePath)) == 0||
wcscmp(L".7z", PathFindExtension(filePath)) == 0 ||
wcscmp(L".zip", PathFindExtension(filePath)) == 0
)
{
buf.Format(L"压缩文件");
m_objComList.SetItemText(i, 1, buf);
fileInfo->TYPE = buf;
}
else if (
wcscmp(L".log", PathFindExtension(filePath)) == 0
)
{
buf.Format(L"日志文件");
m_objComList.SetItemText(i, 1, buf);
fileInfo->TYPE = buf;
}
else
{
CString cs;
cs = filePath;
buf= cs.Right(3);
cs.Format(L"%s文件",buf);
m_objComList.SetItemText(i, 1, cs);
fileInfo->TYPE = buf;
}
HANDLE hFile = CreateFile(filePath, GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
CHAR Buffer[10] = { 0 };
DWORD Read = 0;
ReadFile(hFile, Buffer, 3, &Read, NULL);
CString cs;
DWORD dwRealSize = 0;
if (hFile != INVALID_HANDLE_VALUE)
{

//获取文件大小,申请相应的缓冲区空间
DWORD dwSize = GetFileSize(hFile, NULL);
dwRealSize = dwSize;
//char* pbuf = new char[dwSize] {0};

CloseHandle(hFile);
}

//文件扩展属性
DWORD dwAttribute = GetFileAttributes(filePath);
if (dwAttribute & FILE_ATTRIBUTE_HIDDEN)
{

buf.Format(L"隐藏文件");
m_objComList.SetItemText(i, 4, buf);//
fileInfo->PROPERTY = buf;
}
if (dwAttribute & FILE_ATTRIBUTE_READONLY)
{
buf.Format(L"只读文件");
m_objComList.SetItemText(i, 4, buf);//
fileInfo->PROPERTY = buf;
}
WIN32_FILE_ATTRIBUTE_DATA wfad = {};//创建时间
// WIN32_FILE_ATTRIBUTE_DATA ftLastAccessTime;
// WIN32_FILE_ATTRIBUTE_DATA ftLastWriteTime;
GetFileAttributesEx(filePath, GetFileExInfoStandard, &wfad);
//5.2 扩展属性
//wfad.ftCreationTime;//这里获取到的是时间戳
//存放创建时间
FILETIME fi = { 0 };
SYSTEMTIME st = { 0 };
//wfad.ftLastAccessTime;
//修改时间
FILETIME fix = { 0 };
SYSTEMTIME stx = { 0 };
//最后的访问时间
FILETIME fiw = { 0 };
SYSTEMTIME stw = { 0 };
//将标准时间转换为本地时间
FileTimeToLocalFileTime(&wfad.ftCreationTime, &fi);//创建时间
FileTimeToLocalFileTime(&wfad.ftLastAccessTime, &fix);//访问时间
FileTimeToLocalFileTime(&wfad.ftLastAccessTime, &fiw);//写入时间
//将时间戳转为能够看懂的时间
FileTimeToSystemTime(&fi, &st);
FileTimeToSystemTime(&fix, &stx);
FileTimeToSystemTime(&fiw, &stw);


//创建时间
buf.Format(L"%d年%d月%d日-%d时%d分%d秒", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
//m_objComList.SetItemText(i, 3, buf);
fileInfo->CREATEDATE = buf;
buf.Format(L"%d年%d月%d日-%d时%d分%d秒", stx.wYear, stx.wMonth, stx.wDay, stx.wHour, stx.wMinute, stx.wSecond);
m_objComList.SetItemText(i, 3, buf);//修改时间
fileInfo->MODIFYDATE = buf;
//访问时间
buf.Format(L"%d年%d月%d日-%d时%d分%d秒", stw.wYear, stw.wMonth, stw.wDay, stw.wHour, stw.wMinute, stw.wSecond);
fileInfo->ACCESSDATE = buf;

//文件大小转换字节转换KB
CString csSize;
int Size = dwRealSize / 1024;
if (Size < 1)
{
csSize.Format(L"1 Kb");
m_objComList.SetItemText(i, 2, csSize);
fileInfo->SIZE = Size;
}
else if((Size/1024))
{

csSize.Format(L"%d Kb", Size);
m_objComList.SetItemText(i, 2, csSize);
fileInfo->SIZE = Size;
}
m_objComList.SetItemText(i,5, filePath);
fileInfo->PATH = filePath;
vecFileInfo.push_back(fileInfo);
}

双击list控件中的文件并执行

1
2
3
4
5
6
7
8
9
10
11
12
//双击运行
void CMyComputerDlg::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);


CString Path = m_objComList.GetItemText(pNMItemActivate->iItem, 5);

ShellExecute(NULL, NULL, _T("explorer"), Path, NULL, SW_SHOW);

*pResult = 0;
}

右击文件列表(List)弹窗显示详细信息

响应右击并弹窗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//右击列表的响应
void CMyComputerDlg::OnRclickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

CString Name = m_objComList.GetItemText(pNMItemActivate->iItem, 0);
CString Path = m_objComList.GetItemText(pNMItemActivate->iItem, 5);
//
for (int i = 0; i < vecFileInfo.size(); i++)
{
if (vecFileInfo[i]->PATH == Path)
{
CMyFileSelectDlg* FileDlg = new CMyFileSelectDlg;
FileDlg->Create(IDD_FILESELECT,this);
FileDlg->ShowWindow(SW_SHOW);
FileDlg->GetFileInfo(vecFileInfo[i]->TYPE, vecFileInfo[i]->SIZE, vecFileInfo[i]->CREATEDATE,
vecFileInfo[i]->MODIFYDATE, vecFileInfo[i]->ACCESSDATE, vecFileInfo[i]->PROPERTY, vecFileInfo[i]->PATH
,Name);
}
}

*pResult = 0;
}

输出信息及线程的调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
DWORD WINAPI MD5Call(LPARAM lparam)
{
CMyFileSelectDlg* pObj =(CMyFileSelectDlg*)lparam;
pObj->MD5(pObj->m_Path);
return 0;
}




void CMyFileSelectDlg::GetFileInfo(CString TYPE, DWORD SIZE, CString CREATEDATE,
CString MODIFYDATE, CString ACCESSDATE, CString PROPERTY, CString PATH,CString Name
)
{
m_Path = PATH;
m_strFileName.SetString(Name);
CString cs;
cs.Format(L"%dKB", SIZE);
m_strFileSize .SetString(cs);
m_strFileType .SetString(TYPE);
m_strFileProperty.SetString(PROPERTY);
m_strCreateDate .SetString(ACCESSDATE);
m_strModifyDate .SetString(MODIFYDATE);
m_strAccessDate .SetString(CREATEDATE);
m_strFilePath.SetString(PATH);
UpdateData(FALSE);
if(!(SIZE >(1.5*1025*1024)))
{
HANDLE ThreadT = CreateThread(
NULL, // 线程的安全属性
NULL, // 默认栈的大小(局部变量、参数、返回地址)
(LPTHREAD_START_ROUTINE)MD5Call, // 线程代码的起始位置
this, // 线程函数的参数,如果传递的是地址,那么需要保证这块内存地址的生命周期(不能是局部变量)
NULL, // 创建标志
NULL); // 传出的线程ID


WaitForSingleObject(ThreadT,-1);
m_strMd5.SetString(m_chex);
UpdateData(FALSE);
}
else
{
m_strMd5.SetString(L"文件过大,无法计算");
UpdateData(FALSE);
}
}

计算MD5值(需要保护openssl)

#include <openssl/md5.h>
#pragma comment(lib,”res/libcrypto.lib”)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//计算md5
int CMyFileSelectDlg::md5_Value(const void* data, size_t len, unsigned char* md5)
{
// 初始化保存 md5 信息的结构体
MD5_CTX ctx = { 0 };
MD5_Init(&ctx);

// 将需要计算的数据传入到对应的结构中
MD5_Update(&ctx, data, len);

// 从结构中获取计算后的结果
MD5_Final(md5, &ctx);

return 0;
}

转换成我们看的懂的16进制

1
2
3
4
5
6
7
8
9
10
11
12
//转换为大端16进制
void CMyFileSelectDlg::show_hex(const char* n, unsigned char* hex, size_t length)
{
CString cs;
m_chex = L"";
for (int i = 0; i < length; ++i)
{
cs.Format(L"%2X", hex[i]);
m_chex += cs;

}
}

文件清理

清空活回收站

1
2
3
4
5
6
7
8
9
//清空回收站
void CMySystemDlg::Recycle()
{
SHQUERYRBINFO Recycle = {};
Recycle.cbSize = sizeof(Recycle);
SHQueryRecycleBin(NULL,&Recycle);
SHEmptyRecycleBin(NULL,NULL,SHERB_NOCONFIRMATION|SHERB_NOPROGRESSUI|SHERB_NOSOUND);

}

VS工程清理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//vs工程查找
void CMySystemDlg::OnBnClickedCleanbuttonvs()
{

if (filePath != L"")
{

char pDecs1[][20] = {
".exe",
".obj",
".tlog",
".idb",
".pdb",
".pch",
".res",
".ilk",
".sdf",
".ipch",
".log",
".lastbuildstate"
};
for (int i = 0; i < 0xc; i++)
{

for (int j = 0; j < sizeof(pDecs[i]); j++)
{
pDecs[i][j] = pDecs1[i][j];
}
}
EnumFile(filePath);
}
else
{
MessageBox(L"请先把需要清理的VS工程文件拖入本程序",L"提示");
}

}

文件遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//文件遍历
void CMySystemDlg::EnumFile(CString filePath)
{
CString csPath;
int i = 1;
CString cs;

// 拼接完整路径
CString fullPath = filePath + L"\\*";
// 查找第一个文件
WIN32_FIND_DATA fileData = {};
HANDLE hFile = FindFirstFile(fullPath, &fileData);
if (hFile != INVALID_HANDLE_VALUE)
{
do
{
// 输出文件的信息,
// 过滤两个文件夹……
if (wcscmp(fileData.cFileName, L".") == 0 ||
wcscmp(fileData.cFileName, L"..") == 0)
continue;

// 如果找到的是目录,递归遍历目录中的其他文件
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
EnumFile(filePath + L"\\" + fileData.cFileName);
continue;
}

// 获取文件大小
DWORD dwSize = (fileData.nFileSizeHigh * (MAXDWORD + 1))
+ fileData.nFileSizeLow;
// 转换成字符串格式

for (int j = 0; j < sizeof(pDecs); j++)
{
cs = pDecs[j];
if (wcscmp(cs, PathFindExtension(fileData.cFileName)) == 0
)
{
//保存路径到vector中
csPath.Format(L"%s\\%s", filePath, fileData.cFileName);

vecPath.push_back(csPath);//将路径加入vector
m_objInputInfo.InsertItem(i, L"");
m_objInputInfo.SetItemText(i, 1, filePath + L"\\" + fileData.cFileName);
}
}
i++;
// 继续遍历下一个文件
} while (FindNextFile(hFile, &fileData));
}
}

文件删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//Vs文件删除
void CMySystemDlg::OnBnClickedButton1()
{
if (!(vecPath.size() == 0))
{
int Error;
// TODO: 在此添加控件通知处理程序代码
for (unsigned int i = 0; i < vecPath.size(); i++)
{
//1. 删除文件
Error = DeleteFile(vecPath[i]);//error等于0说明清理成功
}
if (Error)
{
//m_FileList2.SetItemText(i, 1, L"清理成功");
for (int i = 0; i < vecPath.size(); i++)
{
m_objInputInfo.DeleteItem(1);
Sleep(30);
}

vecPath.empty();
m_objInputInfo.InsertItem(1, L"");
m_objInputInfo.SetItemText(1, 1, L"清理成功");
}
}
else
{
MessageBox(L"请先点击VS工程获取按钮", L"提示");
}
}

系统缓存

缓存查找

我这里就使用了三个路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//系统缓存查找
void CMySystemDlg::OnBnClickedCleanbuttonsy()
{

CString sPath;
CString csCleanPath;

//获取//L"C:\\Users\\hugan\\AppData\\Local\\Temp"路径 (用户临时文件)
SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, sPath.GetBuffer());//L"C:\\Users\\hugan\\AppData\\Local"

csCleanPath.Format(L"%s%s", sPath, L"\\Temp");

csSystem[0] = csCleanPath;

csCleanPath.Format(L"%s%s", sPath, L"\\Microsoft\\Windows\\WER\\ReportQueue");
csSystem[1] = csCleanPath;//Windows错误报告
sPath.ReleaseBuffer();
//获取L"C:\\WINDOWS\\Temp"路径 (系统临时文件)
SHGetFolderPath(NULL, CSIDL_WINDOWS, NULL, 0, sPath.GetBuffer(MAX_PATH));//L"C:\\WINDOWS"

csCleanPath.Format(L"%s%s", sPath, L"\\Temp");
csSystem[2] = csCleanPath;
sPath.ReleaseBuffer();

// 创建线程
HANDLE Thread = CreateThread(
NULL, // 线程的安全属性
NULL, // 默认栈的大小(局部变量、参数、返回地址)
(LPTHREAD_START_ROUTINE)SystemCleanBack, // 线程代码的起始位置
this, // 线程函数的参数,如果传递的是地址,那么需要保证这块内存地址的生命周期(不能是局部变量)
NULL, // 创建标志
NULL); // 传出的线程ID

}

回调函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//系统缓存回调函数所用参数
CString csSystem[3];
vector<CString>vecCleanPath;
//系统缓存回调函数
DWORD WINAPI SystemCleanBack(LPARAM lparam)
{
CMySystemDlg* pObj = (CMySystemDlg*)lparam;

for (size_t i = 0; i < 2; i++)
{
pObj->SystemClean(csSystem[i]);
}

return 0;
}

文件遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void CMySystemDlg::SystemClean(CString csPath)
{
CString csFilePath;

static int i = 0;

CString fullPath = csPath + L"\\*";
// 查找第一个文件
WIN32_FIND_DATA fileData = {};
HANDLE hFile = FindFirstFile(fullPath, &fileData);
if (hFile != INVALID_HANDLE_VALUE)
{
do
{
// 输出文件的信息,
// 过滤两个文件夹……
if (wcscmp(fileData.cFileName, L".") == 0 ||
wcscmp(fileData.cFileName, L"..") == 0)
continue;

// 如果找到的是目录,递归遍历目录中的其他文件
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{

SystemClean(csPath + L"\\" + fileData.cFileName);
continue;
}
//保存路径到vector中
csFilePath = csPath + L"\\" + fileData.cFileName;
//csPath.Format(L"%s%s", csSystem[j], fileData.cFileName);
vecCleanPath.push_back(csFilePath);//将路径加入vector
//cs.Format(L"%d", i);
m_objInputInfo.InsertItem(i, L"");
m_objInputInfo.SetItemText(i, 1, csFilePath);
i++;
// 继续遍历下一个文件
} while (FindNextFile(hFile, &fileData));
}
}

内存优化(类似于一键加速)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//内存优化
void CMySystemDlg::GetMemStatus()
{
MEMORYSTATUSEX stcMemStatusEx = { 0 };
stcMemStatusEx.dwLength = sizeof(stcMemStatusEx);
GlobalMemoryStatusEx(&stcMemStatusEx);
DWORDLONG preUsedMem = stcMemStatusEx.ullTotalPhys - stcMemStatusEx.ullAvailPhys;

//2.清理内存

DWORD dwPIDList[1000] = { 0 };
DWORD bufSize = sizeof(dwPIDList);
DWORD dwNeedSize = 0;

EnumProcesses(dwPIDList, bufSize, &dwNeedSize);

for (DWORD i = 0; i < dwNeedSize / sizeof(DWORD); i++)
{
HANDLE hProcess = OpenProcess(PROCESS_SET_QUOTA, false, dwPIDList[i]);

SetProcessWorkingSetSize(hProcess, -1, -1);
}
//3.获取清理后的内存状态

GlobalMemoryStatusEx(&stcMemStatusEx); DWORDLONG afterCleanUsedMem;

stcMemStatusEx.ullTotalPhys - stcMemStatusEx.ullAvailPhys;
}

LOAD_PE解析

初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/响应文件拖拽
void CMyLoadPeDlg::OnDropFiles(HDROP hDropInfo)
{
// 存放文件路径
wchar_t filePath[MAX_PATH] = {};

// 获取拖拽文件的路径
DragQueryFile(hDropInfo, 0, filePath, MAX_PATH);

WCHAR* wFilePath = filePath;

//1 打开文件
HANDLE hFile = CreateFile(
wFilePath,
GENERIC_ALL,
NULL,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
//2 获取文件大小
DWORD dwFileSize = GetFileSize(hFile, NULL);

//3 申请空间并初始化
buf = new char[dwFileSize] {0};
//4 读取文件
DWORD dwRealSize = 0;
ReadFile(hFile, buf, dwFileSize, &dwRealSize, NULL);
CloseHandle(hFile);
//5 判断是不是PE文件
if (IsPE_File(buf) == TRUE)
{
//AnalyzeNTHeader(buf);
CMyPeShowDlg* CMyShowDlg = new CMyPeShowDlg;
//
CMyShowDlg->Create(IDD_PESHOWND,this);
CMyShowDlg->ShowWindow(SW_SHOW);
CMyShowDlg->GetFilePath(buf);
}
else
{
MessageBox(L"别瞎搞");
}

CDialogEx::OnDropFiles(hDropInfo);
}

判断文件是否为PE文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 判断是不是PE文件
BOOL CMyLoadPeDlg::IsPE_File(char* lpImage)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
if (pDos->e_magic != IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + lpImage);

if (pNt->Signature != IMAGE_NT_SIGNATURE)
{
return FALSE;
}
return TRUE;
}

位置计算器

通过VA计算RVA、FOA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//VA
void CMyClacDlg::OnBnClickedButton1()
{

UpdateData(TRUE);
CString svPid = m_strEditVA.GetString();
DWORD dwVa = _tcstoul(svPid, NULL, 16);
//1 获取区段表的起始位置
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)m_buff;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + m_buff);
PIMAGE_SECTION_HEADER pHeader = IMAGE_FIRST_SECTION(pNt);
PIMAGE_OPTIONAL_HEADER pOption = &pNt->OptionalHeader;

DWORD Rva = dwVa - pOption->ImageBase;
CString rva;
rva.Format(L"%08x", Rva);
m_strEditRVA.SetString(rva);
//2 循环判断RVA落在了哪个区段中
for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++)
{
DWORD dwSectionRva = pHeader[i].VirtualAddress;
DWORD dwSectionEndRva = dwSectionRva + pHeader[i].SizeOfRawData;
DWORD dwSectionFOA = pHeader[i].PointerToRawData;

if (Rva >= dwSectionRva && Rva <= dwSectionEndRva)
{
DWORD dwFOA = Rva - dwSectionRva + dwSectionFOA;
CString foa;
foa.Format(L"%08x", dwFOA);
m_strEditFOA.SetString(foa);
//区段名

CString name;
name.Format(L"%S", pHeader[i].Name);
m_strEditName.SetString(name);

UpdateData(FALSE);
return;
}

}
MessageBox(L"无法计算_请重新输入");
}

通过RVA计算VA、FOA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//RVA
void CMyClacDlg::OnBnClickedButton17()
{
UpdateData(TRUE);
CString svPid = m_strEditRVA.GetString();
DWORD dwRva = _tcstoul(svPid, NULL, 16);
//1 获取区段表的起始位置
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)m_buff;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + m_buff);
PIMAGE_SECTION_HEADER pHeader = IMAGE_FIRST_SECTION(pNt);
PIMAGE_OPTIONAL_HEADER pOption = &pNt->OptionalHeader;

if (dwRva < pNt->OptionalHeader.SizeOfHeaders)
{
CString cd;
cd.Format(L"%08x", dwRva);
m_strEditFOA.SetString(cd);
UpdateData(FALSE);
return;
}
//2 循环判断RVA落在了哪个区段中
for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++)
{
DWORD dwSectionRva = pHeader[i].VirtualAddress;
DWORD dwSectionEndRva = dwSectionRva + pHeader[i].SizeOfRawData;
DWORD dwSectionFOA = pHeader[i].PointerToRawData;
if (dwRva >= dwSectionRva && dwRva <= dwSectionEndRva)
{
pHeader[i].VirtualAddress;

//FOA = RVA - RVA区段 + FOA区段
DWORD dwFOA = dwRva - dwSectionRva + dwSectionFOA;
CString foa;
foa.Format(L"%08x", dwFOA);
m_strEditFOA.SetString(foa);

//va虚拟地址= InmageBase(加载基址) + RVA(相对虚拟地址)
DWORD dwVA = pOption->ImageBase + dwRva;
CString va;
va.Format(L"%08x", dwVA);
m_strEditVA.SetString(va);

//区段名
CString name;
name.Format(L"%S", pHeader[i].Name);
m_strEditName.SetString(name);

UpdateData(FALSE);
return;
}
}
MessageBox(L"无法计算_请重新输入");
}

通过FOA计算VA、RVA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//FOA
void CMyClacDlg::OnBnClickedButton18()
{
UpdateData(TRUE);
CString svPid = m_strEditFOA.GetString();
DWORD dwFoa = _tcstoul(svPid, NULL, 16);
//1 获取区段表的起始位置
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)m_buff;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + m_buff);
PIMAGE_SECTION_HEADER pHeader = IMAGE_FIRST_SECTION(pNt);
PIMAGE_OPTIONAL_HEADER pOption = &pNt->OptionalHeader;


if (dwFoa < pNt->OptionalHeader.SizeOfHeaders)
{
CString cd;
cd.Format(L"%08x", dwFoa);
m_strEditRVA.SetString(cd);
UpdateData(FALSE);
return;
}
//2 循环判断FOA落在了哪个区段中
for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++)
{
DWORD dwSectionRva = pHeader[i].VirtualAddress;
DWORD dwSectionEndRva = dwSectionRva + pHeader[i].SizeOfRawData;
DWORD dwSectionFOA = pHeader[i].PointerToRawData;

pHeader[i].VirtualAddress;

//FOA = RVA - RVA区段 + FOA区段
//DWORD dwFOA = dwFoa - dwSectionRva + dwSectionFOA;
DWORD Rva = dwFoa + dwSectionRva - dwSectionFOA;
CString rva;
rva.Format(L"%08x", Rva);
m_strEditRVA.SetString(rva);
//va虚拟地址= InmageBase(加载基址) + RVA(相对虚拟地址)
DWORD dwVA = pOption->ImageBase + Rva;
CString va;
va.Format(L"%08x", dwVA);
m_strEditVA.SetString(va);
if (Rva >= dwSectionRva && Rva <= dwSectionEndRva)
{
//区段名
CString name;
name.Format(L"%S", pHeader[i].Name);
m_strEditName.SetString(name);

UpdateData(FALSE);
return;
}
}
MessageBox(L"无法计算_请重新输入");
}

RVA转换FOA(函数封装)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//RVA转换FOA
DWORD CMyExPortTabDlg::RvaToFoa(DWORD dwRva, char* buf)
{
//1 获取区段表的起始位置
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)buf;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + buf);
PIMAGE_SECTION_HEADER pHeader = IMAGE_FIRST_SECTION(pNt);

if (dwRva < pNt->OptionalHeader.SizeOfHeaders)
{
return dwRva;
}
//2 循环判断RVA落在了哪个区段中
for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++)
{
DWORD dwSectionRva = pHeader[i].VirtualAddress;
DWORD dwSectionEndRva = dwSectionRva + pHeader[i].SizeOfRawData;
DWORD dwSectionFOA = pHeader[i].PointerToRawData;
if (dwRva >= dwSectionRva && dwRva <= dwSectionEndRva)
{
pHeader[i].VirtualAddress;
DWORD dwFOA = dwRva - dwSectionRva + dwSectionFOA;
return dwFOA;
}
}
return -1;
}

目录表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
//输出目录表
void CMyDirTabDlg::GetPath(int i, PIMAGE_DATA_DIRECTORY pExportDir, char* buf)
{
m_Filebuff = buf;
CString Address;
CString Size;
switch (i)
{
case 0://导出表
m_pExportDir = pExportDir;
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditOutTabRVA.SetString(Address);
m_dwSize = pExportDir->Size;//保存导出表大小,可做判断
Size.Format(L"%08x", pExportDir->Size);
m_strEditOutTabSIZE.SetString(Size);

UpdateData(FALSE);
break;
case 1://导入表
m_pInportDir = pExportDir;

Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditInTabRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditInTabSIZE.SetString(Size);

UpdateData(FALSE);
break;
case 2://资源表
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditResourcesRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditResourcesSIZE.SetString(Size);

UpdateData(FALSE);
break;
case 3://异常表Abnormal
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditAbnormalRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditAbnormalSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 4://安全security
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditSecurityRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditSecuritySIZE.SetString(Size);
UpdateData(FALSE);

break;
case 5://重定位Basereloc
m_pReLocaTionDir = pExportDir;
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditBaserelocRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditBaserelocSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 6://调试Debug
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditDebugRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditDebugSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 7://版权Architecture
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditArchitectureRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditArchitectureSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 8://全局指针Glpbalptr
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditGlpbalptrRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditGlpbalptrSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 9://线程局部TLS
m_pTlsTab = pExportDir;
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditTlsRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditTlsSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 10://载入配置Config
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditConfigRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditConfigSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 11://绑定输出Importll
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditImportllRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditImportllSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 12://导入地址表IAT
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditIatRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditIatSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 13://延迟载入Import
m_pUnloadTab = pExportDir;
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditImportRVA.SetString(Address);
m_dwYanchiSize = pExportDir->Size;
Size.Format(L"%08x", pExportDir->Size);
m_strEditImportSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 14://COM信息
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditComRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditComSIZE.SetString(Size);
UpdateData(FALSE);

break;
case 15://保留
Address.Format(L"%08x", pExportDir->VirtualAddress);
m_strEditRVA.SetString(Address);

Size.Format(L"%08x", pExportDir->Size);
m_strEditSIZE.SetString(Size);
UpdateData(FALSE);

break;
default:
break;
}

}

导出表

1
2
3
4
5
6
7
8
9
10
11
12
13
//导出表
void CMyDirTabDlg::OnBnClickedButton1()
{
if (m_dwSize==0)//如果导出表大小为0,直接退出
{
MessageBox(L"导出表为空");
return;
}
CMyExPortTabDlg* pExPortTab = new CMyExPortTabDlg;
pExPortTab->Create(IDD_EXPROTTAB, this);
pExPortTab->ShowWindow(SW_SHOW);
pExPortTab->ShowPortTab(m_pExportDir, m_Filebuff);
}

导出表的解析与输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
void CMyExPortTabDlg::ShowPortTab(PIMAGE_DATA_DIRECTORY pExportDir, char* buff)
{
//初始化列表框
m_objExPortList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);//更改风格
// 添加列
m_objExPortList.InsertColumn(0, L"序号", 0, 120);
m_objExPortList.InsertColumn(1, L"RVA", 0, 120);
m_objExPortList.InsertColumn(2, L"偏移", 0, 120);
m_objExPortList.InsertColumn(3, L"函数名", 0, 120);

//通过导出的目录结构里的相对虚拟地址RVA给转换成FOA
DWORD dwportFOA = RvaToFoa(pExportDir->VirtualAddress, buff);

//得到FOA后,文件基址加上FOA 就找到了导出表
PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)(buff + dwportFOA);
DWORD dwBase = pExport->Base;

// 2 得到地址表,名称表,序号表的 FOA
DWORD EatFoa = RvaToFoa( pExport->AddressOfFunctions, buff);
DWORD EntFoa = RvaToFoa( pExport->AddressOfNames, buff);
DWORD EotFoa = RvaToFoa( pExport->AddressOfNameOrdinals, buff);

//3 得到地址表,名称表,序号表在文件中的位置
PDWORD pEat = (PDWORD)(buff + EatFoa);
PDWORD pEnt = (PDWORD)(buff + EntFoa);
PWORD pEot = (PWORD)(buff + EotFoa);

//4 开始解析
for (int i = 0; i < pExport->NumberOfFunctions; i++)
{
//4.1 无效地址
if (pEat[i] == 0)
{
continue;
}
//4.2 有效地址将下标放到序号表中去寻找
int j = 0;
int nSign = FALSE;
for (; j < pExport->NumberOfNames; j++)
{
if (i == pEot[j])
{
nSign = TRUE;
break;
}
}
//名称表中,存储的是RVA,需要转为FOA
DWORD dwFunNameFOA = RvaToFoa( pEnt[j], buff);
char* pFunName = buff + dwFunNameFOA;


CString cs;
cs.Format(L"%08x", dwportFOA);
m_strExPort1.SetString(cs);
cs.Format(L"%08x", 0x00000000);
m_strExPort2.SetString(cs);
cs.Format(L"%08x", dwBase);
m_strExPort3.SetString(cs);
cs.Format(L"%08x", dwFunNameFOA);
m_strExPort4.SetString(cs);
cs.Format(L"%08x", 0x00000000);
m_strExPort5.SetString(cs);

cs.Format(L"%08d", pExport->NumberOfFunctions);
m_strExPort6.SetString(cs);
cs.Format(L"%08d", pExport->NumberOfNames);
m_strExPort7.SetString(cs);
cs.Format(L"%08x", pExport->AddressOfFunctions);
m_strExPort8.SetString(cs);
cs.Format(L"%08x",pEat[i]);
m_strExPort9.SetString(cs);
cs.Format(L"%08x", pExport->AddressOfNameOrdinals);
m_strExPort10.SetString(cs);

//列表控件的输出
cs.Format(L"%04x", i + dwBase);
m_objExPortList.InsertItem(i, cs);
cs.Format(L"%08x", pEat[i]);
m_objExPortList.SetItemText(i,1,cs);

cs.Format(L"%08x", RvaToFoa(pEat[i], buff));
m_objExPortList.SetItemText(i, 2, cs);

cs.Format(L"%S", pFunName);
m_objExPortList.SetItemText(i, 3, cs);


UpdateData(FALSE);
}
}

导入表

1
2
3
4
5
6
7
8
//导入表
void CMyDirTabDlg::OnBnClickedButton4()
{
CMyPortTabDlg* pPortTab = new CMyPortTabDlg;
pPortTab->Create(IDD_PORTTAB, this);
pPortTab->ShowWindow(SW_SHOW);
pPortTab->ShowPortTab(m_pInportDir, m_Filebuff);
}

初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//初始化导入表窗口及控件
BOOL CMyPortTabDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

//初始化列表框LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES
m_objProtTabList1.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES);//更改风格
// 添加列
m_objProtTabList1.InsertColumn(0, L"MoudleName", 0, 100);
m_objProtTabList1.InsertColumn(1, L"OriginalFirstThunk", 0, 100);
m_objProtTabList1.InsertColumn(2, L"TimeDatestamp", 0, 100);
m_objProtTabList1.InsertColumn(3, L"Name", 0, 100);
m_objProtTabList1.InsertColumn(4, L"FirstThunk", 0, 120);

// 初始化列表框LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES
m_objProtTabList2.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES);//更改风格
m_objProtTabList2.InsertColumn(0, L"ThunkRVA", 0, 100);
m_objProtTabList2.InsertColumn(1, L"ThunkOffset", 0, 100);
m_objProtTabList2.InsertColumn(2, L"ThunkValue", 0, 100);
m_objProtTabList2.InsertColumn(3, L"Hint", 0, 100);
m_objProtTabList2.InsertColumn(4, L"ApiName", 0, 120);

return TRUE;
}

导入表的解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//显示导入表
void CMyPortTabDlg::ShowPortTab(PIMAGE_DATA_DIRECTORY pExportDir, char* buff)
{
//通过导出的目录结构里的相对虚拟地址RVA给转换成FOA
DWORD dwportFOA = RvaToFoa(pExportDir->VirtualAddress, buff);

//得到FOA后,文件基址加上FOA 就找到了导入表
PIMAGE_IMPORT_DESCRIPTOR pInportTab = (PIMAGE_IMPORT_DESCRIPTOR)(buff + dwportFOA);

//保存一下,为了给解析名字使用
m_cFilePath = buff;
int i = 0;
while (pInportTab->Name != 0)
{
//保存被点击的行内容
vecInPort.push_back(pInportTab);
//2.1 先解析DLL的名字
DWORD dwNameFoa = RvaToFoa(pInportTab->Name, buff);
char* pDllName = (char*)(dwNameFoa + buff);

CString temp;
temp.Format(L"%S", pDllName);
m_objProtTabList1.InsertItem(i, temp);

temp.Format(L"%08x", pInportTab->OriginalFirstThunk);
m_objProtTabList1.SetItemText(i, 1, temp);

temp.Format(L"%08x", pInportTab->TimeDateStamp);
m_objProtTabList1.SetItemText(i, 2, temp);

temp.Format(L"%08x", pInportTab->ForwarderChain);
m_objProtTabList1.SetItemText(i, 2, temp);

temp.Format(L"%08x", pInportTab->Name);
m_objProtTabList1.SetItemText(i, 3, temp);

temp.Format(L"%08x", pInportTab->FirstThunk);
m_objProtTabList1.SetItemText(i, 4, temp);
i++;
pInportTab++;
}
}

导入表的输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//单机显示详情
void CMyPortTabDlg::OnClickPortabtlist1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码

int iItem = pNMItemActivate->iItem;
if (iItem < 0)//点击的地方为空iItem的值会小于0,然后导致程序出错
{
return;
}
m_objProtTabList2.DeleteAllItems();

CString temp;
int i = 0;
if (vecInPort[iItem]->Name)
{
//2.2 解析函数名字,选择用什么去解析
DWORD oFoa = RvaToFoa(vecInPort[iItem]->OriginalFirstThunk, m_cFilePath);
PIMAGE_THUNK_DATA32 pNameTable = (PIMAGE_THUNK_DATA32)(m_cFilePath + oFoa);



m_objProtTabList2.InsertItem(i, temp);
while (pNameTable->u1.Ordinal != 0)
{
//2.3.1 判断最高位是不是1
if (IMAGE_SNAP_BY_ORDINAL32(pNameTable->u1.Ordinal) == 1)
{
//只有序号
//printf(" 序号:%x,名称:NULL\n", pNameTable->u1.Ordinal & 0x7FFFFFFF);
temp.Format(L"%04x", pNameTable->u1.Ordinal & 0x7FFFFFFF);
m_objProtTabList2.InsertItem(i, temp);
temp.Format(L"NULL");
m_objProtTabList2.SetItemText(i, 4, temp);
}
else
{
//既有名字,又有序号
DWORD dwNameFoa = RvaToFoa(pNameTable->u1.AddressOfData, m_cFilePath);
PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)(dwNameFoa + m_cFilePath);

temp.Format(L"%08x", vecInPort[iItem]->OriginalFirstThunk + (i * 4));
m_objProtTabList2.InsertItem(i, temp);

DWORD ThunkFOV = RvaToFoa(vecInPort[iItem]->OriginalFirstThunk + (i * 4), m_cFilePath);
temp.Format(L"%08x", ThunkFOV);
m_objProtTabList2.SetItemText(i, 1, temp);

temp.Format(L"%08x", pNameTable->u1.AddressOfData);
m_objProtTabList2.SetItemText(i, 2, temp);

temp.Format(L"%04x", pName->Hint);
m_objProtTabList2.SetItemText(i, 3, temp);

temp.Format(L"%S", pName->Name);
m_objProtTabList2.SetItemText(i, 4, temp);
}
i++;
pNameTable++;
}

}

*pResult = 0;
}

重定位表

1
2
3
4
5
6
7
8
//重定位表
void CMyDirTabDlg::OnBnClickedButton8()
{
CMyRecationTabDlg* pRecationTab = new CMyRecationTabDlg;
pRecationTab->Create(IDD_RELOCATIONTAB,this);
pRecationTab->ShowWindow(SW_SHOW);
pRecationTab->ShowReTab(m_pReLocaTionDir,m_Filebuff);
}

初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//初始化重定位表列表框,并获取文件基址
void CMyRecationTabDlg::ShowReTab(PIMAGE_DATA_DIRECTORY pReLocaTionDir,char* Filebuff)
{
m_FilePath = Filebuff;
m_pReLocaTionDir = pReLocaTionDir;
//初始化列表框LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES
m_objQuDuan.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);//更改风格
m_objKuai.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);//更改风格
// 添加列
m_objQuDuan.InsertColumn(0, L"Index", 0, 50);
m_objQuDuan.InsertColumn(1, L"Section", 0, 100);
m_objQuDuan.InsertColumn(2, L"RVA", 0, 100);
m_objQuDuan.InsertColumn(3, L"Item", 0, 100);

m_objKuai.InsertColumn(0, L"Index", 0, 50);
m_objKuai.InsertColumn(1, L"RVA", 0, 100);
m_objKuai.InsertColumn(2, L"Offset", 0, 100);
m_objKuai.InsertColumn(3, L"Type", 0, 50);
m_objKuai.InsertColumn(4, L"Far Address", 0, 100);
m_objKuai.InsertColumn(5, L"Data Interpretation", 0, 200);
EnumRecationTabQuduan();
}

区段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//显示重定位表 区段
void CMyRecationTabDlg::EnumRecationTabQuduan()
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)m_FilePath;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + m_FilePath);
//Nt头下一个头文件就是区段头
PIMAGE_SECTION_HEADER pQuHead = IMAGE_FIRST_SECTION(pNt);
//扩展头是nt头的第三个数据
PIMAGE_OPTIONAL_HEADER pOption = (PIMAGE_OPTIONAL_HEADER)&pNt->OptionalHeader;
//文件头是nt头的第二个数据
PIMAGE_FILE_HEADER pFileHead = (PIMAGE_FILE_HEADER)&pNt->FileHeader;
//重定位表是扩展头最后一个数据字段(目录表)中的下表为5的字段数据
PIMAGE_BASE_RELOCATION pDataDir = (PIMAGE_BASE_RELOCATION)&pOption->DataDirectory[5];
//
//PIMAGE_BASE_RELOCATION pReloc =
// (PIMAGE_BASE_RELOCATION)
// (RvaToFoa(m_FilePath, pDataDir->VirtualAddress) + m_FilePath);

DWORD dwBeginRva = 0x1000;
//2 循环判断RVA落在了哪个区段中
//文件头的NumberOfSections字段表示区段头的数量
int nNum = 0;
for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++)
{
DWORD dwSectionRva = pQuHead[i].VirtualAddress;
DWORD dwSectionEndRva = dwSectionRva + pQuHead[i].SizeOfRawData;
DWORD dwSectionFOA = pQuHead[i].PointerToRawData;

while (dwBeginRva >= dwSectionRva && dwBeginRva <= dwSectionEndRva)
{
CString cs;
//序号
cs.Format(L"%d", nNum);
m_objQuDuan.InsertItem(nNum, cs);
//区段名
cs.Format(L"%S", pQuHead[i].Name);
m_objQuDuan.SetItemText(nNum, 1, cs);
//RVA
cs.Format(L"%08x", dwBeginRva);
m_objQuDuan.SetItemText(nNum, 2, cs);
//Item
DWORD dwCount = ((pDataDir->SizeOfBlock - 8) / 2);
cs.Format(L"%04x", dwCount);
m_objQuDuan.SetItemText(nNum, 3, cs);


m_vecRva.push_back(dwBeginRva);
dwBeginRva += 0x1000;
nNum++;
}

}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//显示重定位表 块项目
void CMyRecationTabDlg::EnumRecationTabKuai(DWORD dwRVA,DWORD dwClistItem)
{
m_objKuai.DeleteAllItems();
int Const = 0;
CString Temp;
//重定位表
PIMAGE_BASE_RELOCATION pReloc = (PIMAGE_BASE_RELOCATION)(RvaToFoa(m_FilePath, m_pReLocaTionDir->VirtualAddress) + m_FilePath);
//3. 开始解析重定位

//1 获取区段表的起始位置
//Dos头
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)m_FilePath;
//Nt头
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + m_FilePath);
//区段头
PIMAGE_SECTION_HEADER pHeader = IMAGE_FIRST_SECTION(pNt);
//扩展头
PIMAGE_OPTIONAL_HEADER pOption = &pNt->OptionalHeader;

//如果重定位表有数据(SizeOfBlock这个字段表示重定位表的结构大小)
while (pReloc->SizeOfBlock != 0)
{

//得到描述每一个位置偏移的数组
//重定位表+1表示第一个数据
TYPEOFFSET* typeoffset = (TYPEOFFSET*)(pReloc + 1);
//重定位结构体大小减去8后除以2就等于重定位地址的数量
DWORD dwCount = (pReloc->SizeOfBlock - 8) / 2;

DWORD dwBeginRva = pReloc->VirtualAddress;

while (pReloc->SizeOfBlock != 0)
{
//得到描述每一个位置偏移的数组
TYPEOFFSET* typeoffset = (TYPEOFFSET*)(pReloc + 1);
DWORD dwCount = (pReloc->SizeOfBlock - 8) / 2;
DWORD dwBeginRva = pReloc->VirtualAddress;

//dwBeginRva *= dwClistItem + 1;
for (int i = 0; i < dwCount; i++)
{
if (typeoffset[i].TYPE == 3)
{
DWORD dwRelocRva = (dwRVA + typeoffset[i].OFFSET);
if (m_vecRva.size() > 1)
{
if (dwRelocRva >= m_vecRva[dwClistItem] && dwRelocRva < m_vecRva[dwClistItem + 1])
{
//序号
Temp.Format(L"%d", i);
m_objKuai.InsertItem(i, Temp);
//RVA
Temp.Format(L"%08x", dwRelocRva);
m_objKuai.SetItemText(i, 1, Temp);
//printf("要重定位的位置RVA:%p\n", dwRelocRva);
//RVA对应的数据
//类型
Temp.Format(L"%02x", typeoffset[i].TYPE);
m_objKuai.SetItemText(i, 3, Temp);

PDWORD offset = (PDWORD)RvaToFoa(m_FilePath, dwRelocRva);
Temp.Format(L"%08x", offset);
m_objKuai.SetItemText(i, 2, Temp);
PDWORD pRelocData = (PDWORD)(RvaToFoa(m_FilePath, dwRelocRva) + m_FilePath);
Temp.Format(L"%08x", pRelocData);
m_objKuai.SetItemText(i, 4, Temp);
//printf("要重定位的数据:%p\n", *pRelocData);

unsigned char* pRec = (unsigned char*)
(RvaToFoa(m_FilePath, *pRelocData) + m_FilePath);
Temp = L"";
for (size_t m = 0; m < 20; m++)
{
Temp += pRec[m];
}
m_objKuai.SetItemText(i, 5, Temp);
}

}
else
{

Temp.Format(L"%d", i);
m_objKuai.InsertItem(i, Temp);
//RVA
Temp.Format(L"%08x", dwRelocRva);
m_objKuai.SetItemText(i, 1, Temp);
//printf("要重定位的位置RVA:%p\n", dwRelocRva);
//RVA对应的数据
//类型
Temp.Format(L"%02x", typeoffset[i].TYPE);
m_objKuai.SetItemText(i, 3, Temp);

PDWORD offset = (PDWORD)RvaToFoa(m_FilePath, dwRelocRva);
Temp.Format(L"%08x", offset);
m_objKuai.SetItemText(i, 2, Temp);
PDWORD pRelocData = (PDWORD)(RvaToFoa(m_FilePath, dwRelocRva) + m_FilePath);
Temp.Format(L"%08x", pRelocData);
m_objKuai.SetItemText(i, 4, Temp);
//printf("要重定位的数据:%p\n", *pRelocData);

unsigned char* pRec = (unsigned char*)
(RvaToFoa(m_FilePath, *pRelocData) + m_FilePath);
Temp = L"";
for (size_t m = 0; m < 20; m++)
{
Temp += pRec[m];
}
m_objKuai.SetItemText(i, 5, Temp);
}
}
}
return;
}
}
}

点击区段响应块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//点击区段列表响应
void CMyRecationTabDlg::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

m_objKuai.DeleteAllItems();


CString RVA = m_objQuDuan.GetItemText(pNMItemActivate->iItem, 2);
DWORD dwVa = _tcstoul(RVA, NULL, 16);
EnumRecationTabKuai(dwVa, pNMItemActivate->iItem);
*pResult = 0;
}

TLS表

1
2
3
4
5
6
7
8
//TLS表
void CMyDirTabDlg::OnBnClickedButton12()
{
CMyTlsTabDlg* pTlsTab = new CMyTlsTabDlg;
pTlsTab->Create(IDD_TLSTAB,this);
pTlsTab->ShowWindow(SW_SHOW);
pTlsTab->GetInfo(m_pTlsTab,m_Filebuff);
}

TLS表的输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void CMyTlsTabDlg::GetInfo(PIMAGE_DATA_DIRECTORY m_pTlsTab, char* m_Filebuff)
{
DWORD dwLtsFOA = RvaToFoa(m_pTlsTab->VirtualAddress, m_Filebuff);
PIMAGE_TLS_DIRECTORY32 pTls = (PIMAGE_TLS_DIRECTORY32)(dwLtsFOA + m_Filebuff);



CString cs;
cs.Format(L"%08x", pTls->StartAddressOfRawData);
m_strEdit1.SetString(cs);
cs.Format(L"%08x", pTls->EndAddressOfRawData);
m_strEdit2.SetString(cs);
cs.Format(L"%08x", pTls->AddressOfIndex);
m_strEdit3.SetString(cs);
cs.Format(L"%08x", pTls->AddressOfCallBacks);
m_strEdit4.SetString(cs);
cs.Format(L"%08x", pTls->SizeOfZeroFill);
m_strEdit5.SetString(cs);
cs.Format(L"%08x", pTls->Characteristics);
m_strEdit6.SetString(cs);

UpdateData(FALSE);
}

延迟输入表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//延迟输入表
void CMyDirTabDlg::OnBnClickedButton16()
{
if (m_dwYanchiSize == 0)
{
MessageBox(L"延迟表为空");
return;
}

CMyUnloadTabDlg* pUnloadTab = new CMyUnloadTabDlg;
pUnloadTab->Create(IDD_DECSRIPTORTAB, this);
pUnloadTab->ShowWindow(SW_SHOW);
pUnloadTab->GetUnloadTabInfo(m_pUnloadTab, m_Filebuff);
}

延迟输入表的输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void CMyUnloadTabDlg::GetUnloadTabInfo(PIMAGE_DATA_DIRECTORY m_pUnloadTab, char* m_Filebuff)
{
DWORD pUnloadFov = RvaToFoa((DWORD)(m_pUnloadTab->VirtualAddress), m_Filebuff);
PIMAGE_DELAYLOAD_DESCRIPTOR pUnload = (PIMAGE_DELAYLOAD_DESCRIPTOR)(pUnloadFov + m_Filebuff);
CString cs;
cs.Format(L"%08x", pUnload->DllNameRVA);
m_strEdit1.SetString(cs);
cs.Format(L"%08x", pUnload->ModuleHandleRVA);
m_strEdit2.SetString(cs);
cs.Format(L"%08x", pUnload->ImportAddressTableRVA);
m_strEdit3.SetString(cs);
cs.Format(L"%08x", pUnload->ImportNameTableRVA);
m_strEdit4.SetString(cs);
cs.Format(L"%08x", pUnload->BoundImportAddressTableRVA);
m_strEdit5.SetString(cs);
cs.Format(L"%08x", pUnload->UnloadInformationTableRVA);
m_strEdit6.SetString(cs);
UpdateData(FALSE);
}

区段表

初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
//初始化区段表
void CMyQuDuanDlg::InitQuDuanTable(char* buff)
{
m_objQuDuanList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);//更改风格
// 添加列
m_objQuDuanList.InsertColumn(0, L"名称", 0, 100);
m_objQuDuanList.InsertColumn(1, L"相对偏移", 0, 100);
m_objQuDuanList.InsertColumn(2, L"区段大小", 0, 100);
m_objQuDuanList.InsertColumn(3, L"文件偏移", 0, 100);
m_objQuDuanList.InsertColumn(4, L"区段文件大小", 0, 100);
m_objQuDuanList.InsertColumn(5, L"标志", 0, 100);
AnalyzeQuDuan(buff);
}

解析与输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//解析区段表
void CMyQuDuanDlg::AnalyzeQuDuan(char* buff)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)buff;
PIMAGE_NT_HEADERS pNtHead = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + buff);
PIMAGE_FILE_HEADER FileHead = (PIMAGE_FILE_HEADER)(&pNtHead->FileHeader);
PIMAGE_SECTION_HEADER pQuDuan = IMAGE_FIRST_SECTION(pNtHead);
CString cs;
for (int i = 0 ; i< FileHead->NumberOfSections; i++)
{
//区段名
cs.Format(L"%S", pQuDuan[i].Name);
m_objQuDuanList.InsertItem(i, cs);

//相对偏移
cs.Format(L"%p", pQuDuan[i].VirtualAddress);
m_objQuDuanList.SetItemText(i,1, cs);

//区段大小
cs.Format(L"%p", pQuDuan[i].Misc);
m_objQuDuanList.SetItemText(i,2, cs);

//文件偏移
cs.Format(L"%p", pQuDuan[i].PointerToRawData);
m_objQuDuanList.SetItemText(i,3, cs);

//区段文件大小
cs.Format(L"%p", pQuDuan[i].SizeOfRawData);
m_objQuDuanList.SetItemText(i,4, cs);

//标志
cs.Format(L"%p", pQuDuan[i].Characteristics);
m_objQuDuanList.SetItemText(i,5, cs);
}


}

查杀

MD5

启动MD5查杀

#include <openssl/md5.h>
#pragma comment(lib,”res/libcrypto.lib”)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//MD5按钮
void CMyAntivirusDlg::OnBnClickedButton1()
{
//m_strFilePath = L"";
UpdateData(TRUE);
if (m_strFilePath==L"")
{
MessageBox(L"请先输入文件路径",L"提示!");
return;
}
m_objOutList.DeleteAllItems();

//打开文件属性
WIN32_FIND_DATA fileData = {};
HANDLE hFile = FindFirstFile(m_strFilePath, &fileData);
if (!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
MD5_First();
return;
}
//显示进度条
m_objProcessT.ShowWindow(SW_SHOW);
m_strTishiText.SetString(L"查杀中...");
UpdateData(FALSE);
m_objTishiText.ShowWindow(SW_SHOW);
// 创建线程
Thread = CreateThread(
NULL, // 线程的安全属性
NULL, // 默认栈的大小(局部变量、参数、返回地址)
(LPTHREAD_START_ROUTINE)MD5_CallBack, // 线程代码的起始位置
this, // 线程函数的参数,如果传递的是地址,那么需要保证这块内存地址的生命周期(不能是局部变量)
NULL, // 创建标志
NULL); // 传出的线程ID

HANDLE ThreadT = CreateThread(
NULL, // 线程的安全属性
NULL, // 默认栈的大小(局部变量、参数、返回地址)
(LPTHREAD_START_ROUTINE)Process, // 线程代码的起始位置
this, // 线程函数的参数,如果传递的是地址,那么需要保证这块内存地址的生命周期(不能是局部变量)
NULL, // 创建标志
NULL); // 传出的线程ID

}

MD5—CallBack回调

1
2
3
4
5
6
7
8
//MD5计算回调函数
DWORD WINAPI MD5_CallBack(LPARAM lparam)
{
CMyAntivirusDlg* pObj = (CMyAntivirusDlg*)lparam;
pObj->GetFilePath(pObj->m_strFilePath);
pObj->MD5_ANT(true);
return 0;
}

获取需要查杀的目录及文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//文件遍历
CString CMyAntivirusDlg::GetFilePath(CString FilePath)
{
CString strTemp;
CString strReturn = L"";
int i = 0;
// 拼接完整路径
CString fullPath = FilePath + L"\\*";
// 查找第一个文件
WIN32_FIND_DATA fileData = {};
HANDLE hFile = FindFirstFile(fullPath, &fileData);
if (hFile != INVALID_HANDLE_VALUE)
{
do
{
// 输出文件的信息,
// 过滤两个文件夹……
if (wcscmp(fileData.cFileName, L".") == 0 ||
wcscmp(fileData.cFileName, L"..") == 0)
continue;

// 如果找到的是目录,递归遍历目录中的其他文件
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
GetFilePath(FilePath + L"\\" + fileData.cFileName);
continue;
}
CString csPath;//保存路径到vector中
csPath.Format(L"%s\\%s", FilePath, fileData.cFileName);
vecPath.push_back(csPath);//将路径加入vector
m_objOutList.InsertItem(i, fileData.cFileName);

i++;
// 继续遍历下一个文件
} while (FindNextFile(hFile, &fileData));
}

return strReturn;
}

验证MD5值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//MD5校验
void CMyAntivirusDlg::MD5_ANT(BOOL b = true)
{
CString cs;
if (vecPath.size() != 0)
{
//打开存储在文件中的md5值
HANDLE hFile = CreateFile(L"res\\MD5.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
//定义缓冲去
char md5[100] = {};
DWORD dwRead;
//读取文件内容到缓冲区
ReadFile(hFile, md5, 100, &dwRead, NULL);

//定义缓冲区
unsigned char hex[100] = { 0 };
for (int i = 0; i < vecPath.size(); i++)
{
m_objOutList.SetItemText(i,4,vecPath[i]);
//计算md5值
//_bstr_t b(vecPath[i]);
HANDLE hFilePath = CreateFile(vecPath[i], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD FileSize=GetFileSize(hFilePath,NULL);
DWORD dwReadPath;
char* md5Path = new char[FileSize];
ReadFile(hFilePath, md5Path, FileSize, &dwReadPath, NULL);

md5_Value(md5Path, FileSize,hex);
//换算成大端16进制
show_hex("md5: ", hex, 16);
cs.Format(L"%S", md5);
vecMd5.push_back(m_chex);
m_objOutList.SetItemText(i,1, m_chex);
if(b)//如果是云查杀就不输出库MD5
m_objOutList.SetItemText(i, 2, cs);
//比较文件MD5值是否相等
if (!(wcscmp(cs, m_chex)))
{
if(b)
m_objOutList.SetItemText(i, 3,L"是");
BinDuFile.push_back(vecPath[i]);
}
else
{
if (b)
m_objOutList.SetItemText(i, 3, L"否");
}
for (int i = 0; i < sizeof(hex); i++)
{
hex[i] = 0;
}
CloseHandle(hFilePath);
delete md5Path;
}
CloseHandle(hFile);
}
}

验证MD5所用的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//计算md5
int CMyAntivirusDlg::md5_Value(const void* data, size_t len, unsigned char* md5)
{
// 初始化保存 md5 信息的结构体
MD5_CTX ctx = { 0 };
MD5_Init(&ctx);

// 将需要计算的数据传入到对应的结构中
MD5_Update(&ctx, data, len);

// 从结构中获取计算后的结果
MD5_Final(md5, &ctx);

return 0;
}
//转换为大端16进制
void CMyAntivirusDlg::show_hex(const char* n, unsigned char* hex, size_t length)
{
CString cs;
m_chex = L"";
for (int i = 0; i < length; ++i)
{
cs.Format(L"%2X", hex[i]);
m_chex += cs;

}
}

异常文件的删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//判断MD5值结构异常的文件处理
void CMyAntivirusDlg::FileDelete()
{
if (!(BinDuFile.size() == 0))
{

for (int i = 0; i < BinDuFile.size(); i++)
{
//shDelFile.fFlags |= FOF_ALLOWUNDO; //删除到回收
DeleteFile(BinDuFile[i]);
}
MessageBox(L"删除成功",L"提示");
}
else
{
MessageBox(L"没有找到病毒文件",L"提示");
}
}

云端查杀

开启线程

1
2
3
4
5
6
7
//网络客户端回调函数
DWORD WINAPI Cilent(LPARAM lparam)
{
CMyAntivirusDlg* pObj = (CMyAntivirusDlg*)lparam;
pObj->GetClienObj();//调用
return 0;
}

调用本地的文件遍历及MD5计算及启动客户端

1
2
3
4
5
6
7
8
9
10
//获取网络客户端对象并调用客户端入口
void CMyAntivirusDlg::GetClienObj()
{
GetFilePath(filePath);
MD5_ANT(false);
NetWorkClient obj;

obj.NetWorkClientMain(this);
}

客户端

包含所需的文件

#include <WinSock2.h>

#include <ws2tcpip.h>

#pragma comment(lib, “ws2_32.lib”)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
void NetWorkClient::NetWorkClientMain(LPVOID obj)
{
CMyAntivirusDlg* pObj = (CMyAntivirusDlg*)obj;

//SendMessage(UM_MYMESSAGE,1,2);
// 1. 初始化套接字模块,必须是网络程序中第一个调用的函数(搜索信号)
WSADATA wsadata = { 0 };
int result = WSAStartup(MAKEWORD(2, 2), &wsadata);
check_result(!result && wsadata.wVersion == 0x0202, "套接字环境初始化失败!");

// 2. 创建一个套接字,应该保存[IP:PORT](买一部手机)
// 参数分别是使用的协议种类,数据传输方式以及协议类型
SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
check_result(client != INVALID_SOCKET, "套接字创建失败!");

// 3. 将套接字绑定到指定的 ip 地址和端口(安装手机卡)
SOCKADDR_IN server_addr = { 0 };
server_addr.sin_family = AF_INET; // 协议
server_addr.sin_port = htons(0x1515); // 端口
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
result = connect(client, (SOCKADDR*)&server_addr, sizeof(server_addr));
check_result(result != SOCKET_ERROR, "套接字连接失败!");

CString cs;
pObj->m_objAccept.ShowWindow(SW_SHOW);
char buff[100] = {0};

while (true)
{
for (int i =0 ; i<vecMd5.size();i++)
{
if ((i + 1) == vecMd5.size())
{
send(client, "T", 1, 0);//发送完成后发送T表示结束了
return;
}


_bstr_t b(vecMd5[i]);
send(client,b , 32, 0);
recv(client, buff, 100, 0);

if (strcmp(buff, "a") == 0)
{
pObj->m_objOutList.SetItemText(i, 3, L"否");

}
else if (strcmp(buff, "b") == 0)
{
pObj->m_objOutList.SetItemText(i, 3, L"是");

}
}
}

// 6. 当数据处理结束之后,需要断开连接
closesocket(client);

// 7. 清理套接字模块坏境
WSACleanup();

system("pause");
}

// 检查函数的执行结果是否正确
void NetWorkClient::check_result(bool result, const char* msg)
{
// 如果传入的表达式位假,意味着出错
if (result == false)
{
MessageBox((CString)msg);
printf("error: %s\n", msg);
system("pause"); exit(0);
}
}

服务端

服务端入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "NetWorkClient.h"

int main(int argc, char* argv[])
{
NetWorkClient obj;
obj.m_argc = argc;
for (int i = 0; i < sizeof(argv); i++)
{
obj.m_argv[i] = argv[i];
}
obj.NetMain();

return 0;
}

.h文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#pragma once
#include <vector>
#include <WinSock2.h>
#include <stdio.h>
#include <string>
#include <algorithm>
#include <ws2tcpip.h>
#include "include/mysql.h"
#pragma comment(lib, "libmysql.lib")
#pragma comment(lib, "ws2_32.lib")
using std::vector;



class NetWorkClient
{
public:
void NetMain();
void MysqlInit(int argc, char* argv[]);
void sql_insert(MYSQL* mysql, const char* sql);
void sql_check_result(MYSQL* mysql);
void sql_select(MYSQL* mysql, const char* sql, char* filemd5);
void MysqlSelect(char* Filemd5);

SOCKET client;
MYSQL mysql;
//vector<char*>vecChar;
public :
int m_argc;
char* m_argv[];
};

.cpp文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// 0. 添加必要的头文件,并且链接到相应的静态库
#include "NetWorkClient.h"

using namespace std;

// 用于保存当前连接到服务器的所有客户端
map<SOCKET, string> clients;

// 检查函数的执行结果是否正确
void check_result(bool result, const char* msg)
{
// 如果传入的表达式位假,意味着出错
if (result == false)
{
printf("error: %s\n", msg);
system("pause"); exit(0);
}
}

//服务器入口(套接字初始化)
void NetWorkClient::NetMain()
{
// 1. 初始化套接字模块,必须是网络程序中第一个调用的函数(搜索信号)
WSADATA wsadata = { 0 };
int result = WSAStartup(MAKEWORD(2, 2), &wsadata);
check_result(!result && wsadata.wVersion == 0x0202, "套接字环境初始化失败!");

// 2. 创建一个套接字,应该保存[IP:PORT](买一部手机)
// 参数分别是使用的协议种类,数据传输方式以及协议类型
SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
check_result(server != INVALID_SOCKET, "套接字创建失败!");

// 3. 将套接字绑定到指定的 ip 地址和端口(安装手机卡)
SOCKADDR_IN server_addr = { 0 };
server_addr.sin_family = AF_INET; // 协议
server_addr.sin_port = htons(0x1515); // 端口
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
result = bind(server, (SOCKADDR*)&server_addr, sizeof(server_addr));
check_result(result != SOCKET_ERROR, "套接字绑定失败!");

// 4. 开启套接字的监听状态,第二个参数是同一时刻可以等待的客户端数量(开机)
result = listen(server, SOMAXCONN);
check_result(result != SOCKET_ERROR, "套接字监听失败!");

// 5. 等待客户端的连接,返回值是连接到的客户端(等接电话)
int size = sizeof(SOCKADDR_IN);
SOCKADDR_IN client_addr = { 0 }; // 用于接收客户端信息(来电显示)
client = accept(server, (SOCKADDR*)&client_addr, &size);
check_result(client != INVALID_SOCKET, "客户端接收失败!");
//char buff[10] = { 0 };
//recv(client, buff, 10, 0);
MysqlInit(m_argc, m_argv);
int T = 1;
while (T)
{
char nickname[0x100] = { 0 };

recv(client, nickname, 0x100, 0);

if ((strcmp(nickname, "T") == 0))//如果客户端发过来的消息时T,就结束循环
{
T = 0;
}
MysqlSelect(nickname);


}
mysql_library_end();
// 8. 当数据处理结束之后,需要断开连接
closesocket(server);

// 9. 清理套接字模块坏境
WSACleanup();

system("pause");
}



//////////////////////SQL///////////////////////
//初始化mysql
void NetWorkClient::MysqlInit(int argc, char* argv[])
{
// 1. 初始化 mysql 模块
mysql_library_init(argc, argv, nullptr);

// 2. 创建一个 mysql 对象并初始化
mysql = { 0 };
mysql_init(&mysql);

// 3. 通过指定的函数提供用户名密码和主机信息连接到数据库
mysql_real_connect(&mysql, "127.0.0.1", "root",
"123456", "md5_value", 3306, nullptr, 0);
sql_check_result(&mysql);

// 设置字符编码为 GB2312
sql_insert(&mysql, "SET NAMES GB2312");

// 4. 向数据库中添加指定的内容(先测试sql指令,在放到代码中)


}
//查询数据库存放的md5值
void NetWorkClient::MysqlSelect(char* Filemd5)
{
// 5. sql_select
sql_select(&mysql, "SELECT md5 FROM md5_table;", Filemd5);



}


// 封装添加内容的函数
void NetWorkClient::sql_insert(MYSQL* mysql, const char* sql)
{
// 通过 mysql_query 可以执行所有的 sql 操作
mysql_query(mysql, sql);

// 由于操作可能出现错误,所以需要判断是否成功
sql_check_result(mysql);
}

// 封装查询内容的函数
void NetWorkClient::sql_select(MYSQL* mysql, const char* sql,char* filemd5)
{
// 通过 mysql_query 可以执行所有的 sql 操作
mysql_query(mysql, sql);
sql_check_result(mysql);

// 通过函数从 sql 对象中接收查询到的结果
MYSQL_RES* res = mysql_use_result(mysql);
sql_check_result(mysql);

// 获取到查询到的结果的列数
int count = mysql_num_fields(res);




int Flag = 1;
//// 从结果集中循环获取到下一项并输出
MYSQL_ROW row = nullptr;
while (row = mysql_fetch_row(res))
{ // 获取每一行的信息
for (int i = 0; i < count; ++i)
{ // 需要提防产生空指针的情况
if ((strcmp(row[i], filemd5) == 0) && row[i] != nullptr)
{
printf("%s\n", filemd5);
send(client,"b",1, 0);
Flag = 0;
break;
}
}

}
if (Flag == 1)
{
send(client, "a", 1, 0);
printf("%s\n", filemd5);
}


}

// 检查数据库操作是否成功
void NetWorkClient::sql_check_result(MYSQL* mysql)
{
// 如果 mysql 操作出现了问题,就返回非 0 值
if (mysql_errno(mysql) != 0)
{
// 通过 mysql_error 获取到具体的错误信息
printf("连接数据库出错: %s\n", mysql_error(mysql));
system("pause"); exit(0);
}
}