462 lines
11 KiB
C++
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();
|
|
} |