PdbLib/PdbChecker/_helper.h
2025-06-05 10:51:52 +08:00

462 lines
11 KiB
C++

#pragma once
#include <Windows.h>
#include <vector>
#include "zlib\zlib.h"
#include <WinInet.h>
#include <sstream>
#include <string>
#include <urlmon.h>
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "Wininet.lib")
using namespace std;
#ifndef _IMAGE_DEBUG_DIRECTORY_RAW_
#define _IMAGE_DEBUG_DIRECTORY_RAW_
typedef struct _IMAGE_DEBUG_DIRECTORY_RAW {
uint8_t format[4];
uint8_t PdbSignature[16];
uint32_t PdbDbiAge;
uint8_t ImageName[256];
const char* GuidString()
{
char* buf = new char[128];
sprintf(buf, "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X",
this->PdbSignature[3], this->PdbSignature[2],
this->PdbSignature[1], this->PdbSignature[0],
this->PdbSignature[5], this->PdbSignature[4],
this->PdbSignature[7], this->PdbSignature[6],
this->PdbSignature[8], this->PdbSignature[9],
this->PdbSignature[10], this->PdbSignature[11],
this->PdbSignature[12], this->PdbSignature[13],
this->PdbSignature[14], this->PdbSignature[15]
);
return buf;
}
} IMAGE_DEBUG_DIRECTORY_RAW, * PIMAGE_DEBUG_DIRECTORY_RAW;
#endif
static vector<BYTE> Compress(BYTE* buffer, int len)
{
vector<BYTE> result = vector<BYTE>();
uLong destLen = compressBound(len);
unsigned char* ostream = (unsigned char*)malloc(destLen);
int res = compress(ostream, &destLen, (const unsigned char*)buffer, len);
if (res == Z_BUF_ERROR) {
return result;
}
if (res == Z_MEM_ERROR) {
return result;
}
int ldx = result.size();
result.resize(destLen);
memcpy(&result.operator[](ldx), ostream, destLen);
return result;
}
static vector<BYTE> Decompress(BYTE* buffer, int len, int maxlen)
{
uLong destLen = maxlen;
vector<BYTE> result = vector<BYTE>();
BYTE* o2stream = new BYTE[maxlen];
int des = uncompress(o2stream, &destLen, buffer, len);
result.resize(destLen);
memcpy(result.data(), o2stream, destLen);
return result;
}
static vector<BYTE> GDecompress(vector<BYTE> compressedBytes) {
vector<BYTE> uncompressedBytes = vector<BYTE>();
if (compressedBytes.size() == 0)return uncompressedBytes;
unsigned full_length = compressedBytes.size();
unsigned half_length = compressedBytes.size() / 2;
unsigned uncompLength = full_length;
char* uncomp = (char*)calloc(sizeof(char), uncompLength);
z_stream strm;
strm.next_in = (Bytef*)compressedBytes.data();
strm.avail_in = compressedBytes.size();
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
bool done = false;
if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) {
free(uncomp);
return uncompressedBytes;
}
while (!done) {
if (strm.total_out >= uncompLength) {
char* uncomp2 = (char*)calloc(sizeof(char), uncompLength + half_length);
memcpy(uncomp2, uncomp, uncompLength);
uncompLength += half_length;
free(uncomp);
uncomp = uncomp2;
}
strm.next_out = (Bytef*)(uncomp + strm.total_out);
strm.avail_out = uncompLength - strm.total_out;
int err = inflate(&strm, Z_SYNC_FLUSH);
if (err == Z_STREAM_END) done = true;
else if (err != Z_OK) {
break;
}
}
if (inflateEnd(&strm) != Z_OK) {
free(uncomp);
return uncompressedBytes;
}
for (size_t i = 0; i < strm.total_out; ++i) {
uncompressedBytes.push_back(uncomp[i]);
}
free(uncomp);
return uncompressedBytes;
}
static vector<BYTE> GCompress(vector<BYTE> input)
{
vector<BYTE> res = vector<BYTE>();
res.resize(input.size());
z_stream zs;
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = Z_NULL;
zs.avail_in = (uInt)input.size();
zs.next_in = (Bytef*)input.data();
zs.avail_out = (uInt)input.size();
zs.next_out = (Bytef*)res.data();
deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | 16, 8, Z_DEFAULT_STRATEGY);
deflate(&zs, Z_FINISH);
deflateEnd(&zs);
res.resize(zs.total_out);
return res;
}
static vector<BYTE> GDecompress(BYTE* compressedBytes,ULONG len) {
vector<BYTE> uncompressedBytes = vector<BYTE>();
if (len == 0)return uncompressedBytes;
unsigned full_length = len;
unsigned half_length = len / 2;
unsigned uncompLength = full_length;
char* uncomp = (char*)calloc(sizeof(char), uncompLength);
z_stream strm;
strm.next_in = compressedBytes;
strm.avail_in = len;
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
bool done = false;
if (inflateInit2(&strm, (16 + MAX_WBITS)) != Z_OK) {
free(uncomp);
return uncompressedBytes;
}
while (!done) {
if (strm.total_out >= uncompLength) {
char* uncomp2 = (char*)calloc(sizeof(char), uncompLength + half_length);
memcpy(uncomp2, uncomp, uncompLength);
uncompLength += half_length;
free(uncomp);
uncomp = uncomp2;
}
strm.next_out = (Bytef*)(uncomp + strm.total_out);
strm.avail_out = uncompLength - strm.total_out;
int err = inflate(&strm, Z_SYNC_FLUSH);
if (err == Z_STREAM_END) done = true;
else if (err != Z_OK) {
break;
}
}
if (inflateEnd(&strm) != Z_OK) {
free(uncomp);
return uncompressedBytes;
}
for (size_t i = 0; i < strm.total_out; ++i) {
uncompressedBytes.push_back(uncomp[i]);
}
free(uncomp);
return uncompressedBytes;
}
static vector<BYTE> GCompress(BYTE* input,ULONG len)
{
vector<BYTE> res = vector<BYTE>();
res.resize(len);
z_stream zs;
zs.zalloc = Z_NULL;
zs.zfree = Z_NULL;
zs.opaque = Z_NULL;
zs.avail_in = (uInt)len;
zs.next_in = (Bytef*)input;
zs.avail_out = (uInt)len;
zs.next_out = (Bytef*)res.data();
deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 | 16, 8, Z_DEFAULT_STRATEGY);
deflate(&zs, Z_FINISH);
deflateEnd(&zs);
res.resize(zs.total_out);
return res;
}
static vector<BYTE> GCompress(initializer_list<BYTE> input)
{
return GCompress((BYTE*)input.begin(), input.size());
}
static vector<BYTE> GCompress(initializer_list<BYTE>* input)
{
return GCompress((BYTE*)input->begin(), input->size());
}
static char* ToHex(const char* data, size_t len)
{
const char* key = "0123456789ABCDEF";
char* result = new char[len * 2];
for (int i = 0; i < len; i++)
{
result[i * 2] = key[(BYTE)(data[i] >> 4)];
result[(i * 2) + 1] = key[(BYTE)((BYTE)(data[i] << 4) >> 4)];
}
return result;
}
static char* ToHex(const BYTE* data, size_t len)
{
const char* key = "0123456789ABCDEF";
char* result = new char[(len * 2) + 1];
for (int i = 0; i < len; i++)
{
result[i * 2] = key[(BYTE)(data[i] >> 4)];
result[(i * 2) + 1] = key[(BYTE)((BYTE)(data[i] << 4) >> 4)];
}
result[len * 2] = '\0';
return result;
}
static vector<BYTE> ParseHex(const char* hex)
{
vector<BYTE> result = vector<BYTE>();
int len = strlen(hex);
BYTE* buffer = new BYTE[len];
bool ish = true;
BYTE val = 0;
for (int i = 0; i < len; i++)
{
bool isval = false;
BYTE v = 0;
if (hex[i] >= '0' && hex[i] <= '9')
{
v = (hex[i] - '0');
isval = true;
}
else if (hex[i] >= 'A' && hex[i] <= 'F')
{
v = 10 + (hex[i] - 'A');
isval = true;
}
else if (hex[i] >= 'a' && hex[i] <= 'f')
{
v = 10 + (hex[i] - 'a');
isval = true;
}
if (isval)
{
if (ish)
{
val = (v << 4) | val;
}
else
{
val = v | val;
result.push_back(val);
val = 0;
}
ish = !ish;
}
}
return result;
}
static initializer_list<BYTE>* ReadAllBytes(const char* filePath)
{
HANDLE pFile;
DWORD fileSize;
char* buffer, * tmpBuf;
DWORD dwBytesRead, dwBytesToRead, tmpLen;
pFile = CreateFileA(filePath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (pFile == INVALID_HANDLE_VALUE)
{
CloseHandle(pFile);
return nullptr;
}
fileSize = GetFileSize(pFile, NULL);
buffer = (char*)malloc(fileSize);
if (!buffer)
{
return nullptr;
}
ZeroMemory(buffer, fileSize);
dwBytesToRead = fileSize;
dwBytesRead = 0;
tmpBuf = buffer;
do {
if (!ReadFile(pFile, tmpBuf, dwBytesToRead, &dwBytesRead, NULL) || dwBytesRead == 0)
break;
dwBytesToRead -= dwBytesRead;
tmpBuf += dwBytesRead;
} while (dwBytesToRead > 0);
CloseHandle(pFile);
return new initializer_list<BYTE>((BYTE*)&buffer[0], (BYTE*)&buffer[fileSize]);
}
static BOOL WriteAllBytes(const char* filePath, char* buffer, int len)
{
HANDLE pFile;
char* tmpBuf;
DWORD dwBytesWrite, dwBytesToWrite;
pFile = CreateFileA(filePath,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (pFile == INVALID_HANDLE_VALUE)
{
CloseHandle(pFile);
return FALSE;
}
dwBytesToWrite = len;
dwBytesWrite = 0;
tmpBuf = buffer;
do {
WriteFile(pFile, tmpBuf, dwBytesToWrite, &dwBytesWrite, NULL);
dwBytesToWrite -= dwBytesWrite;
tmpBuf += dwBytesWrite;
} while (dwBytesToWrite > 0);
CloseHandle(pFile);
return TRUE;
}
static BOOL WriteAllBytes(const char* filePath, BYTE* buffer, int len)
{
return WriteAllBytes(filePath,(char*)buffer,len);
}
static BOOL WriteAllBytes(const char* filePath, vector<BYTE> buffer)
{
return WriteAllBytes(filePath, (char*)buffer.data(), buffer.size());
}
static BOOL WriteAllBytes(const char* filePath, initializer_list<BYTE> buffer)
{
return WriteAllBytes(filePath, (char*)buffer.begin(), buffer.size());
}
static BOOL WriteAllBytes(const char* filePath, initializer_list<BYTE>* buffer)
{
return WriteAllBytes(filePath, (char*)buffer->begin(), buffer->size());
}
static BOOL WriteAllBytes(const char* filePath, initializer_list<char> buffer)
{
return WriteAllBytes(filePath, (char*)buffer.begin(), buffer.size());
}
static BOOL WriteAllText(const char* filePath, const char* text)
{
return WriteAllBytes(filePath, (char*)text, strlen(text));
}
static vector<BYTE> HttpRequest(const char* url)
{
#define MAXSIZE 4096
vector<BYTE> result = vector<BYTE>();
BYTE* val = new BYTE[MAXSIZE];
ULONG len = 1;
HINTERNET hSession = InternetOpenA(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hSession != NULL)
{
HINTERNET hHttp = InternetOpenUrlA(hSession, url, NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);
if (hHttp != NULL)
{
while (len > 0)
{
InternetReadFile(hHttp, val, MAXSIZE - 1, &len);
if (len > 0)
{
int ldx = result.size();
result.resize(result.size() + len);
memcpy(&result.operator[](ldx), &val[0], len);
}
}
InternetCloseHandle(hHttp);
hHttp = NULL;
}
InternetCloseHandle(hSession);
hSession = NULL;
}
return result;
}
static string GetPathFolder(const char* path)
{
int len = strlen(path);
char* res = new char[len];
strcpy(res, path);
for (int i = len - 1; i >= 0; i--)
{
if (res[i] == '\\')
{
res[i] = '\0';
break;
}
}
return res;
}
static string GetFileNameByPath(const char* path)
{
int len = strlen(path);
char* res = new char[len];
strcpy(res, path);
for (int i = len - 1; i >= 0; i--)
{
if (res[i] == '\\')
{
return &res[i+1];
}
}
return res;
}
static string WebRequest(const char* url)
{
IStream* stream;
HRESULT result = URLOpenBlockingStreamA(0, url, &stream, 0, 0);
if (result != 0)
{
return "";
}
char buffer[4096];
unsigned long bytesRead;
stringstream ss;
stream->Read(buffer, 4096, &bytesRead);
while (bytesRead > 0U)
{
ss.write(buffer, (long long)bytesRead);
stream->Read(buffer, 4096, &bytesRead);
}
stream->Release();
return ss.str();
}