|
最近讨论的热火朝天,网警都开始关注了,
哈哈哈,其实搞过逆向的都知道在内存中搜字符串来找明文,并不是什么发明,github上搜相关的源码,十几年前的代码都有,
这不我让gpt写了个 速度还行,这玩意容易写,主要是怎么提速,要是有ce那么快就好咯
[C++] 纯文本查看 复制代码
#include "test.h"
std::mutex resultMutex; // 用于保护结果输出
std::atomic<bool> found{ false }; // 用于标记是否已经找到目标字符串
// 创建进程内存转储
bool CreateMemoryDump(DWORD pid, const std::string& dumpFilePath) {
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcess == NULL) {
std::cerr << "Failed to open process." << std::endl;
return false;
}
HANDLE hFile = CreateFile(dumpFilePath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to create dump file." << std::endl;
CloseHandle(hProcess);
return false;
}
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = NULL;
exceptionInfo.ClientPointers = FALSE;
BOOL success = MiniDumpWriteDump(
hProcess,
pid,
hFile,
MiniDumpWithFullMemory,
&exceptionInfo,
NULL,
NULL
);
CloseHandle(hFile);
CloseHandle(hProcess);
if (!success) {
std::cerr << "Failed to write dump file." << std::endl;
return false;
}
return true;
}
// 加载内存转储文件
bool LoadMemoryDump(const std::string& dumpFilePath, std::vector<char>& dumpData) {
HANDLE hFile = CreateFile(dumpFilePath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open dump file." << std::endl;
return false;
}
DWORD fileSize = GetFileSize(hFile, NULL);
dumpData.resize(fileSize);
DWORD bytesRead;
if (!ReadFile(hFile, dumpData.data(), fileSize, &bytesRead, NULL) || bytesRead != fileSize) {
std::cerr << "Failed to read dump file." << std::endl;
CloseHandle(hFile);
return false;
}
CloseHandle(hFile);
return true;
}
//宏获取openssl的版本
#if OPENSSL_VERSION_NUMBER > 0x1010107fL
//evp实现md5
std::string CalculateMD5(const std::string& str) {
EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;
EVP_MD_CTX_create(&mdctx);
EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
EVP_DigestUpdate(mdctx, str.c_str(), str.length());
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);
char md5String[33];
for (int i = 0; i < md_len; i++) {
sprintf(&md5String[i * 2], "%02x", (unsigned int)md_value);
}
md5String[32] = '\0'; // 确保字符串以空字符结尾
return std::string(md5String);
}
#else
// 计算字符串的MD5
std::string CalculateMD5(const std::string& str) {
unsigned char md5Digest[MD5_DIGEST_LENGTH];
MD5((unsigned char*)str.c_str(), str.length(), md5Digest);
char md5String[33];
for (int i = 0; i < 16; ++i)
sprintf(&md5String[i * 2], "%02x", (unsigned int)md5Digest);
return std::string(md5String);
}
#endif
// 搜索内存中的字符串
void SearchStrings(const std::vector<char>& data, size_t start, size_t end, size_t minLength, const std::string& targetMD5) {
std::string currentString;
for (size_t i = start; i < end && !found.load(); ++i) {
char c = data;
if (c >= 32 && c <= 126) { // 可打印字符
currentString += c;
}
else {
if (currentString.length() >= minLength) {
std::string md5 = CalculateMD5(currentString);
if (md5 == targetMD5) {
std::lock_guard<std::mutex> lock(resultMutex);
std::cout << "Found matching string: " << currentString << std::endl;
found.store(true);
return;
}
}
currentString.clear();
}
}
if (currentString.length() >= minLength && !found.load()) {
std::string md5 = CalculateMD5(currentString);
if (md5 == targetMD5) {
std::lock_guard<std::mutex> lock(resultMutex);
std::cout << "Found matching string: " << currentString << std::endl;
found.store(true);
}
}
}
int test_mumu(DWORD pid, std::string targetStr) {
std::string dumpFilePath = "process_dump.dmp";
// 创建内存转储
if (!CreateMemoryDump(pid, dumpFilePath)) {
std::cerr << "Failed to create memory dump." << std::endl;
return 1;
}
// 加载内存转储数据
std::vector<char> dumpData;
if (!LoadMemoryDump(dumpFilePath, dumpData)) {
std::cerr << "Failed to load memory dump." << std::endl;
return 1;
}
// 并行搜索内存中的字符串
const size_t numThreads = std::thread::hardware_concurrency();
std::vector<std::thread> threads;
size_t chunkSize = dumpData.size() / numThreads;
for (size_t i = 0; i < numThreads; ++i) {
size_t start = i * chunkSize;
size_t end = (i == numThreads - 1) ? dumpData.size() : start + chunkSize;
threads.emplace_back(SearchStrings, std::ref(dumpData), start, end, 4, std::ref(targetStr));
}
for (auto& t : threads) {
t.join();
}
if (!found.load()) {
std::cout << "No matching string found." << std::endl;
}
return 0;
}
|
|