C++ 自定义url下载数据类

url下载文件类

主要是常见代码做个整理

AutoString iutiltools 都是自定义的类型.和本类无关.

code

.h

#pragma once
#include "IUtileTools.h"
#include <UrlMon.h>//download file   URLDownloadToFile
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib,"Wininet.lib")
//URLDownloadToFile(NULL, url, filename, 0, NULL);//download with the second way

class CUrls : public IUtileTools
{

public :
	CUrls();
	~CUrls();
public:

	

	
	bool downloadToMemory(AutoString Url, OUT char*& ptrData, OUT int& ptrdata_size);
	/*
	参数1: 下载的url
	参数2: 下载到的文件路径 给全路径 如: c:xxx	empabc 那么下载的数据就是此文件
	*/
	bool downloadToFile(wstring url, wstring fileName);
	
	//解密数据并且写入到指定文件中
	bool WriteFileToSpecialFilePath(
		AutoString FileName, 
		void* writeBuffer, 
		int buffersize,
		bool isEntry);
private:
	//下载到文件
	/*
	参数1: 要下载的url链接
	参数2: 下载到哪里,给一个全路径的文件名。
	*/
	bool download(AutoString Url, AutoString filename);
	bool downloadToFileByWinapi(wstring url, wstring fileName);
	//下载到内存
	/*
	参数1,要下载数据的url
	参数2,下载的数据内存,数据下载好之后会存放到内存中.
	*/
	bool downloadToBuffer(AutoString Url, OUT char*& ptrData, OUT int& ptrdata_size);
	bool downloadToFileStream(wstring Url, OUT char*& ptrData, OUT int& ptrdata_size);
};

.cpp

#include "CUrls.h"
#include <Windows.h>
#include <wininet.h>
#include <iostream>
#include "base64.h"
#include <fstream>
#include <Urlmon.h>
//#pragma comment(lib,"Winhttp.lib")
#pragma comment(lib, "Urlmon.lib")


using namespace std;
CUrls::CUrls()
{
}
CUrls::~CUrls()
{
}

bool CUrls::downloadToBuffer(AutoString Url,OUT char *&ptrData,OUT int &ptrdata_size)
{
	byte Temp[4096];
	memset(Temp, 0, 4096);
	ULONG Number = 1;


	int BufferSize = 0;
	char* recvdata = nullptr;
	memset(recvdata, 0, BufferSize); 
	//INTERNET_FLAG_ASYNC
	//INTERNET_FLAG_FROM_CACHE
	
	HINTERNET hSession = InternetOpen(TEXT("RookIE/1.0"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	HINTERNET handle2 = nullptr;
	if (hSession != NULL)
	{
		handle2 = InternetOpenUrl(hSession, Url.c_str(), NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);
		if (handle2 != NULL)
		{
			vector<char*> Memary;
			while (Number > 0)
			{
				char* TempBuffer = new char[4096]();
				InternetReadFile(handle2, TempBuffer, 4096, &Number);  
				Memary.push_back(TempBuffer);
			} 
			//合并内存
			DWORD  MmearySize = Memary.size();
			DWORD  AllocSize = MmearySize * 4096; 
			recvdata = (char*)VirtualAlloc(0, AllocSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
			if (recvdata != nullptr)
			{
				char* pstart = recvdata;
				for (DWORD i = 0; i < Memary.size(); i++)
				{
					if (recvdata != 0)
					{
						memcpy(recvdata, Memary[i], 4096);
					}

					recvdata += 4096;
				}

				//释放内存
				for (DWORD i = 0; i < Memary.size(); i++)
				{
					delete[] Memary[i];
				}
				ptrData = pstart;
				ptrdata_size = AllocSize;
			}
		}
		else
		{
			goto ERROR_OPT;
		}
	}
	else
	{
		goto ERROR_OPT;
	}

	if (handle2 != NULL)
	{
		InternetCloseHandle(handle2);
		handle2 = NULL;
	}
	else
	{
		handle2 = NULL;
	}

	if (hSession != NULL)
	{

		InternetCloseHandle(hSession);
		hSession = NULL;
	}
	else
	{
		hSession = NULL;
	}

	return true;

ERROR_OPT:

	if (handle2 != NULL)
	{
		InternetCloseHandle(handle2);
		handle2 = NULL;
	}
	else
	{
		handle2 = NULL;
	}

	if (hSession != NULL)
	{

		InternetCloseHandle(hSession);
		hSession = NULL;
	}
	else
	{
		hSession = NULL;
	}
	return false;
}
bool CUrls::download(AutoString Url, AutoString filename)
{


	/*
	每次下载之前判断是否下载过了.或者说删除cfg文件来达到命令只执行一次
	*/
	byte Temp[1024];
	ULONG Number = 1;

	FILE* stream;

	HINTERNET hSession = InternetOpen(TEXT("RookIE/1.0"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	HINTERNET handle2 = nullptr;
	if (hSession != NULL)
	{
		handle2 = InternetOpenUrl(hSession, Url.c_str(), NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);
		if (handle2 != NULL)
		{

#ifdef _UNICODE
			if ((stream = _wfopen(filename.c_str(), TEXT("wb"))) != NULL)
#else
			if ((stream = fopen(filename.c_str(), "wb")) != NULL)
#endif
			{
				while (Number > 0)
				{
					InternetReadFile(handle2, Temp, 1024, &Number);  //每次读取1024个字节并且写入到文件

					fwrite(Temp, sizeof(char), Number, stream);
				}
				fclose(stream);
			}
		}
		else
		{
			goto ERROR_OPT;
		}
	}
	else
	{

		goto ERROR_OPT;
	}


	if (handle2 != NULL)
	{
		InternetCloseHandle(handle2);
		handle2 = NULL;
	}
	else
	{
		handle2 = NULL;
	}

	if (hSession != NULL)
	{

		InternetCloseHandle(hSession);
		hSession = NULL;
	}
	else
	{
		hSession = NULL;
	}
	return true;
ERROR_OPT:

	if (handle2 != NULL)
	{
		InternetCloseHandle(handle2);
		handle2 = NULL;
	}
	else
	{
		handle2 = NULL;
	}

	if (hSession != NULL)
	{

		InternetCloseHandle(hSession);
		hSession = NULL;
	}
	else
	{
		hSession = NULL;
	}
	return false;

	
}

bool CUrls::downloadToFileByWinapi(wstring url, wstring fileName)
{
	HRESULT ret = URLDownloadToFileW(
		nullptr,
		url.c_str(),
		fileName.c_str(),
		0,
		nullptr
	);

	if (ret != S_OK)
		return false;
	return true;
}

bool CUrls::downloadToMemory(AutoString Url, OUT char*& ptrData, OUT int& ptrdata_size)
{
	bool bRet = false;
	char* pdata = nullptr;
	int pdatasize = 0;
	bRet = downloadToFileStream(Url, ptrData, ptrdata_size);
	if (bRet)
	{
		
		return true;
	}
	bRet = downloadToBuffer(Url, ptrData, ptrdata_size);
	if (bRet)
	{
		
		return true;
	}

	return false;
}

bool CUrls::downloadToFile(wstring url,wstring fileName)
{
	bool bRet = false;
	bRet = downloadToFileByWinapi(url,fileName);
	if (bRet != false)
	{
		return true;
	}
	bRet = this->download(url, fileName);
	if (bRet != false)
	{
		return true;
	}
	return false;

}

bool CUrls::downloadToFileStream(wstring Url, OUT char*& ptrData, OUT int& ptrdata_size)
{
	IStream* stream; // 存后面的流

	HRESULT ret = URLOpenBlockingStreamW(
		nullptr,
		Url.c_str(),
		&stream,
		0,
		nullptr
	);

	if (ret != S_OK)
		return false;

	char buffer[4096] = { 0 };
	vector<char*> ptr_vec;
	DWORD readBytes = 0;
	do
	{
		stream->Read(   // 读取流中的数据
			buffer,     // 缓冲区
			4096,       // 缓冲区大小
			&readBytes  // 用来存储读取到的字节数。
		);
		char* ReadBuffer = new char[4096]();
		RtlCopyMemory(ReadBuffer, buffer, 4096);
		ptr_vec.push_back(ReadBuffer);
	} while (readBytes > 0); // 直到读取完毕(读取字节数为 0)
	DWORD Memorysize = ptr_vec.size();
	DWORD allocSize = Memorysize * 4096;
	char* ptrReadData = (char *)VirtualAlloc(0, allocSize, MEM_COMMIT, PAGE_READWRITE);
	char* pStart = nullptr;
	if (ptrReadData != nullptr)
	{
		pStart = ptrReadData; // 记录起始位置
	}
	for (DWORD i = 0; i < Memorysize; i++)
	{
		RtlCopyMemory(ptrReadData, ptr_vec[i], 4096);
		ptrReadData += 4096;
	}
	//释放掉ptr_vec的内存.拷贝过的内存不需要了.
	for (DWORD i = 0; i < Memorysize; i++)
	{
		if (ptr_vec[i] != nullptr)
		{
			delete[] ptr_vec[i];
			ptr_vec[i] = 0;
		}
	}
	stream->Release(); // 释放掉

	ptrData = pStart;
	ptrdata_size = allocSize;
	return true;
}

bool CUrls::WriteFileToSpecialFilePath(
	AutoString FileName,
	void* writeBuffer,
	int buffersize,
	bool isEntry)
{
	if (isEntry)
	{
		//解密数据写入到本地
		int outlen = 0;
		unsigned char *decryptBuffer = base64_decode((const char *)writeBuffer, buffersize, &outlen);

		FILE* pFile = NULL;
#ifdef _UNICODE
		_wfopen_s(&pFile, FileName.c_str(), L"wb");
#else
		fopen_s(&pFile, FileName.c_str(), "wb");
#endif
		if (pFile != NULL)
		{
			fwrite(decryptBuffer, outlen, 1, pFile);
			if (pFile != NULL)
			{
				fclose(pFile);
				pFile = NULL;
				if (decryptBuffer != NULL)
				{
					free(decryptBuffer);
					decryptBuffer = NULL;

				}
				return true;
			}
			if (decryptBuffer != NULL)
			{
				free(decryptBuffer);
				decryptBuffer = NULL;

			}
			return false;
		}
	}
	return false;
}

作者:IBinary


坚持两字,简单,轻便,但是真正的执行起来确实需要很长很长时间.当你把坚持两字当做你要走的路,那么你总会成功. 想学习,有问题请加群.群号:725864912(收费)群名称: 逆向学习小分队 群里有大量学习资源. 以及定期直播答疑.有一个良好的学习氛围. 涉及到外挂反外挂病毒 司法取证加解密 驱动过保护 VT 等技术,期待你的进入。

详情请点击链接查看置顶博客 https://www.cnblogs.com/iBinary/p/7572603.html
原文地址:https://www.cnblogs.com/iBinary/p/15428628.html