目录
进程的遍历
CreateToolhelp32Snapshot
Process32First
Process32Next
文件加密 使用openssl库进行DES加密
进程的遍历
什么是快照:虚拟中的快照: 我们在分析病毒,分析木马的时候,不能在真机分析,在虚拟机中分析,把病毒丢到虚拟机中,分析之前把环境配好,拍照保存;然后进行分析,分析过后,想从头再分析,就把快照一恢复,就可以恢复成刚配好环境的虚拟机;
快照遍历进程的思路:
我们遍历进程也是通过快照的方式,把当前的系统的信息创建一份快照——(创建快照的)那一刻所有进程的信息,到快照里面浏览这些信息;
CreateToolhelp32Snapshot
CreateToolhelp32Snapshot是Windows操作系统中的一个函数,用于创建一个系统快照,其中包含当前运行的进程和模块的信息。
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
参数解释如下:
-
dwFlags:指定要创建快照的类型。常见的取值包括:
- TH32CS_SNAPPROCESS:创建包含当前运行进程的快照。
- TH32CS_SNAPTHREAD:创建包含当前运行线程的快照。
- TH32CS_SNAPMODULE:创建包含当前加载模块的快照。
- TH32CS_SNAPMODULE32:创建包含当前加载模块的快照,返回32位模块结构。
- TH32CS_SNAPALL:创建包含当前运行进程、线程和模块的快照。
-
th32ProcessID:指定要创建快照的进程ID,通常为0表示当前进程。
CreateToolhelp32Snapshot函数会返回一个句柄,用于表示创建的系统快照。这个句柄可以用于后续的遍历操作,通过调用其他函数(如Process32First、Process32Next、Module32First等)来获取系统快照中的进程和模块信息。
这个函数通常用于获取系统中运行的进程和模块的信息,例如获取进程列表、查找特定进程、遍历模块信息等。通过遍历系统快照,可以获得进程、线程和模块的详细信息,进而进行相应的操作和分析。
Process32First
Process32First是Windows操作系统中的一个函数,用于在通过CreateToolhelp32Snapshot函数创建的进程快照中获取第一个进程的信息。
函数原型如下:
BOOL Process32First(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
);
参数解释如下:
-
hSnapshot:通过CreateToolhelp32Snapshot函数创建的进程快照的句柄。
-
lppe:指向PROCESSENTRY32结构的指针,用于接收第一个进程的信息。
Process32First函数会将第一个进程的信息填充到lppe指向的PROCESSENTRY32结构中,并返回一个布尔值来指示操作是否成功。如果函数返回TRUE,则表示成功获取第一个进程的信息,如果返回FALSE,则表示获取失败。
PROCESSENTRY32结构定义如下:
typedef struct tagPROCESSENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
ULONG_PTR th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
LONG pcPriClassBase;
DWORD dwFlags;
TCHAR szExeFile[MAX_PATH];
} PROCESSENTRY32;
这个结构包含了进程的各种信息,包括进程ID、父进程ID、线程数量、进程优先级等。
Process32First函数通常与Process32Next函数一起使用,用于遍历进程快照中的所有进程。首先使用Process32First获取第一个进程的信息,然后使用Process32Next依次获取后续进程的信息,直到遍历完整个进程列表。
Process32Next
Process32Next是Windows操作系统中的一个函数,用于在通过CreateToolhelp32Snapshot函数创建的进程快照中获取下一个进程的信息。
函数原型如下:
BOOL Process32Next(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
);
参数解释如下:
-
hSnapshot:通过CreateToolhelp32Snapshot函数创建的进程快照的句柄。
-
lppe:指向PROCESSENTRY32结构的指针,用于接收下一个进程的信息。
Process32Next函数会将下一个进程的信息填充到lppe指向的PROCESSENTRY32结构中,并返回一个布尔值来指示操作是否成功。如果函数返回TRUE,则表示成功获取下一个进程的信息,如果返回FALSE,则表示获取失败。
需要注意的是,在使用Process32Next函数之前,必须先调用一次Process32First函数来获取第一个进程的信息。然后,通过反复调用Process32Next函数来遍历进程快照中的所有进程。
Process32First和Process32Next函数结合使用,可以遍历进程快照中的所有进程,并获取它们的详细信息,比如进程ID、父进程ID、线程数量等。这对于进程管理、进程监控和诊断等场景非常有用。
测试代码
#include <tlhelp32.h>
void CProcessDlg::OnBnClickedButton6()
{
BOOL bRet = FALSE;
PROCESSENTRY32 pe32 = {0};
//创建快照
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
//从快照中获取进程信息
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
do
{
CString strFmt;
strFmt.Format("[proc] PID: %d [path:%s", pe32.th32ProcessID, pe32.szExeFile);
OutputDebugString(strFmt);
} while (Process32Next(hProcessSnap, &pe32));
}
CloseHandle(hProcessSnap);
}
修改一下
// Travel.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//遍历当前进程信息
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
int main()
{
HANDLE hProcessSnap = NULL;
//创建,获取进程的信息
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return (FALSE);
//结构体
PROCESSENTRY32 pe32 = { 0 };
//填写结构体中的第一个成员
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
//First成功之后,进入循环
//循环的时候调一下next,通过xxx拿一下进程的信息
do
{
printf("pid:%d\t name:%s\r\n", pe32.th32ProcessID, pe32.szExeFile);
} while (Process32Next(hProcessSnap, &pe32));
}
CloseHandle(hProcessSnap);
}
注意:
- 和资源管理器中进程对比是一样的;
- 和Process Hacker 中进程对比少,我们的进程是三环下的,Process Hacker是可以拿到内核进程的;
文件加密 使用openssl库进行DES加密
下载地址:Win32/Win64 OpenSSL Installer for Windows - Shining Light Productions
创建一个多字节控制台项目
把include
和 lib
文件放在项目目录中。
附加包含目录
附加包含库目录
测试代码
// Encripte.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "include/openssl/des.h"
#pragma comment(lib,"libcrypto.lib")
#pragma comment(lib,"Crypt32.lib")
#pragma comment(lib,"ws2_32.lib")
//#pragma warning(disable:4996)
int main()
{
// 使用DES_cblock定义一个密钥变量key,并使用DES_random_key生成一个随机密钥。
DES_cblock key;
DES_random_key(&key);
// 使用DES_key_schedule定义一个密钥调度变量schedule,并使用DES_set_key_checked函数将生成的密钥设置到调度中。
DES_key_schedule schedule;
DES_set_key_checked(&key, &schedule);
// 定义输入明文input,并将其加密后存放到output中,使用DES_ecb_encrypt函数进行加密操作。
const_DES_cblock input = "hello";
DES_cblock output;
DES_ecb_encrypt(&input, &output, &schedule,DES_ENCRYPT);
printf("Encrypted!\n");
// 打印加密后的密文。
printf("ciphertext: ");
int i;
for (i = 0; i < sizeof(input); i++)
printf("%02x", output[i]);
printf("\n");
// 使用DES_ecb_encrypt函数将密文output解密,解密后的明文存放在input中。
DES_ecb_encrypt(&output, &input, &schedule, DES_DECRYPT);
printf("Decrypted!\n");
printf("cleartext:%s\n", input);
}
加密文件 解密文件
//
#include <iostream>
#include <windows.h>
#include "include/openssl/des.h"
#pragma comment(lib,"libcrypto.lib")
#pragma comment(lib,"Crypt32.lib")
#pragma comment(lib,"ws2_32.lib")
//#pragma warning(disable:4996)
//解密
#define ENCRIPT
#ifdef ENCRIPT
#define DES_FUNC DES_ENCRYPT
#else
#define DES_FUNC DES_DECRYPT
#endif
using namespace std;
int main()
{
// 定义一个密钥key,并使用DES_set_key_checked函数将密钥设置到调度中。
DES_cblock key =
{ '\x8a','\xf4', '\x19', '\x04', '\x51', '\x13', '\x67', '\x15' };
/*DES_random_key(&key);*/
DES_key_schedule schedule;
DES_set_key_checked(&key, &schedule);
// 创建源文件和目标文件的句柄,分别用于读取源文件和写入目标文件。
const char* szSrcFile = "E:\\CR41\\第2阶段\\Windows\\08-管道\\OpenSSL-Win32_3 - 副本.zip";
const char* szDstFile = "E:\\CR41\\第2阶段\\Windows\\08-管道\\OpenSSL-Win32_3 - 副本00.zip";
// 创建源文件和目标文件的映射,用于分块读取和写入数据。
HANDLE hSrcFile = CreateFile
(
szSrcFile,
GENERIC_READ,
0, NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hSrcFile == INVALID_HANDLE_VALUE)
{
cout << "文件打开失败:" << hSrcFile << endl;
return 0;
}
HANDLE hDstFile = CreateFile
(
szDstFile,
GENERIC_WRITE | GENERIC_READ,
0, NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hDstFile == INVALID_HANDLE_VALUE)
{
cout << "文件打开失败:" << hDstFile << endl;
CloseHandle(hDstFile);
return 0;
}
HANDLE hSrcMapFile = CreateFileMapping
(
hSrcFile,
NULL,
PAGE_WRITECOPY,
0, 0,
NULL
);
if (hSrcMapFile == NULL)
{
cout << "文件映射失败:" << szSrcFile << endl;
CloseHandle(hSrcMapFile);
CloseHandle(hSrcFile);
CloseHandle(hDstFile);
return 0;
}
DWORD dwFileSize = GetFileSize(hSrcFile, NULL);
HANDLE hDstMapFile = CreateFileMapping
(
hDstFile,
NULL,
PAGE_READWRITE,
0, dwFileSize,
NULL
);
if (hDstMapFile == NULL)
{
cout << "文件映射失败:" << hDstFile << endl;
CloseHandle(hDstMapFile);
CloseHandle(hSrcFile);
CloseHandle(hDstFile);
return 0;
}
//循环映射
DWORD dwCount = dwFileSize / 0x10000;
for (DWORD dwIdx = 0; dwIdx < dwCount; ++dwIdx)
{
LPBYTE pSrcData = (LPBYTE)MapViewOfFile
(
hSrcMapFile,
FILE_MAP_READ,
0, 0x10000 * dwIdx,
0x10000
);
LPBYTE pDstData = (LPBYTE)MapViewOfFile
(
hDstMapFile,
FILE_MAP_WRITE,
0, 0x10000 * dwIdx,
0x10000
);
//循环加密
for (
DWORD dwOfSet = 0;
dwOfSet < 0x10000;
dwOfSet += sizeof(const_DES_cblock)
)
{
DES_ecb_encrypt(
(const_DES_cblock*)(pSrcData + dwOfSet),
(DES_cblock*)(pDstData + dwOfSet),
&schedule, DES_FUNC
);
}
//取消映射
UnmapViewOfFile(pDstData);
UnmapViewOfFile(pSrcData);
}
//判断有没有不够0x10000的数据
if (dwFileSize % 0x10000 > 0)
{
DWORD dwAvail = dwFileSize % 0x10000;
LPBYTE pSrcData = (LPBYTE)MapViewOfFile
(
hSrcMapFile,
FILE_MAP_READ,
0, (dwFileSize / 0x10000) * 0x10000,
dwAvail
);
LPBYTE pDstData = (LPBYTE)MapViewOfFile
(
hDstMapFile,
FILE_MAP_WRITE,
0, (dwFileSize / 0x10000) * 0x10000,
dwAvail
);
// 加密
DWORD dwCount = dwAvail % sizeof(const_DES_cblock) == 0
? dwAvail / sizeof(const_DES_cblock)
: dwAvail / sizeof(const_DES_cblock) + 1;
for (size_t i = 0; i < dwCount; i++)
{
//不足以8个字节的不加密
//最后一次 不加密了
if ((dwAvail % sizeof(const_DES_cblock) != 0)
&& (i == dwCount - 1))
{
memcpy(pDstData + i * sizeof(const_DES_cblock),
pSrcData + i * sizeof(const_DES_cblock),
dwAvail % sizeof(const_DES_cblock));
break;
}
DES_ecb_encrypt
(
(const_DES_cblock*)(pSrcData + i * sizeof(const_DES_cblock)),
(DES_cblock*)(pDstData + i * sizeof(const_DES_cblock)),
&schedule,
DES_FUNC
);
}
}
cout << "结束" << endl;
}