diff --git a/WinArk/GotoKeyDlg.cpp b/WinArk/GotoKeyDlg.cpp index 07a3e66..1b2e29c 100644 --- a/WinArk/GotoKeyDlg.cpp +++ b/WinArk/GotoKeyDlg.cpp @@ -73,6 +73,7 @@ LRESULT CGotoKeyDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPa { L"DisablePath",LR"(HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers\0\Paths)"}, { L"Internet Settings",LR"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings)"}, { L"Session Manager",LR"(HKLM\System\CurrentControlSet\Control\Session Manager)"}, + { L"NetworkCards",LR"(HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards)"}, }; for (const auto& [name, path] : locations) { diff --git a/WinArk/ImportsHandling.cpp b/WinArk/ImportsHandling.cpp index 41d2c36..f88736f 100644 --- a/WinArk/ImportsHandling.cpp +++ b/WinArk/ImportsHandling.cpp @@ -100,7 +100,7 @@ void ImportsHandling::UpdateImportInTreeView(const ImportThunk* pImportThunk, CT } void ImportsHandling::UpdateModuleInTreeView(const ImportModuleThunk* importThunk, CTreeItem item) { - swprintf_s(Text, L"%s (%d) FThunk: " PRINTF_DWORD_PTR_HALF, importThunk->m_ModuleName, importThunk->m_ThunkMap.size(), importThunk->m_FirstThunk); + swprintf_s(Text, L"%s (%lld) FThunk: " PRINTF_DWORD_PTR_HALF, importThunk->m_ModuleName, importThunk->m_ThunkMap.size(), importThunk->m_FirstThunk); item.SetText(Text); int icon = (int)GetAppropiateIcon(importThunk->IsValid()); diff --git a/WinArk/ObjectCallbackTable.cpp b/WinArk/ObjectCallbackTable.cpp index a0b3894..5bf082f 100644 --- a/WinArk/ObjectCallbackTable.cpp +++ b/WinArk/ObjectCallbackTable.cpp @@ -120,11 +120,17 @@ PCWSTR CObjectCallbackTable::TypeToString(ObjectCallbackType type) { CString CObjectCallbackTable::DecodeOperations(ULONG operations) { CString result; + bool needSeparator = false; + if ((operations & OB_OPERATION_HANDLE_CREATE) == OB_OPERATION_HANDLE_CREATE) { - result += L"HANDLE_CREATE" + CString(L" | "); + result += L"HANDLE_CREATE"; + needSeparator = true; } if ((operations & OB_OPERATION_HANDLE_DUPLICATE) == OB_OPERATION_HANDLE_DUPLICATE) { + if (needSeparator) { + result += L" | "; + } result += L"HANDLE_DUPLICATE"; } diff --git a/WinArk/SymbolFileInfo.cpp b/WinArk/SymbolFileInfo.cpp index 406d338..7c25974 100644 --- a/WinArk/SymbolFileInfo.cpp +++ b/WinArk/SymbolFileInfo.cpp @@ -3,30 +3,15 @@ #include #include #include +#include +#include -using Poco::URIStreamOpener; -using Poco::StreamCopier; -using Poco::Path; -using Poco::Exception; -using Poco::Net::HTTPStreamFactory; -using Poco::Net::FTPStreamFactory; -using Poco::SharedPtr; -using Poco::Net::HTTPSStreamFactory; -using Poco::Net::SSLManager; -using Poco::Net::Context; -using Poco::Net::InvalidCertificateHandler; -using Poco::Net::ConsoleCertificateHandler; -using Poco::Net::HTTPSClientSession; -using Poco::Net::HTTPRequest; -using Poco::Net::HTTPMessage; -using Poco::Net::HTTPResponse; -using Poco::Net::HTTPClientSession; - #pragma comment(lib,"Ws2_32") #pragma comment(lib,"Iphlpapi") #pragma comment(lib,"Crypt32") + bool SymbolFileInfo::SymDownloadSymbol(std::wstring localPath) { std::wstring path = localPath + L"\\" + _path.GetString(); std::filesystem::create_directories(path); @@ -113,90 +98,239 @@ bool SymbolFileInfo::GetPdbSignature(ULONG_PTR imageBase,PIMAGE_DEBUG_DIRECTORY } downslib_error SymbolFileInfo::Download(std::string url, std::wstring fileName, std::string userAgent, - unsigned int timeout,downslib_cb cb, void* userdata){ - std::ofstream fileStream; - fileStream.open(fileName, std::ios::out | std::ios::trunc | std::ios::binary); - - SharedPtr pCertHandler = new ConsoleCertificateHandler(false); // ask the user via console - Context::Ptr pContext = new Context(Context::CLIENT_USE, "", Context::VerificationMode::VERIFY_NONE); - SSLManager::instance().initializeClient(0, pCertHandler, pContext); - Poco::URI uri(url); - if (uri.getScheme() == "http") { - try - { - std::string path(uri.getPathAndQuery()); - if (path.empty()) path = "/"; - HTTPClientSession session(uri.getHost(), uri.getPort()); - HTTPRequest request(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); - session.sendRequest(request); - HTTPResponse response; - session.peekResponse(response); - if (response.getStatus() == HTTPResponse::HTTPStatus::HTTP_FOUND) { - uri = response.get("Location"); - } - } - catch (Poco::Exception& exc) - { - fileStream << exc.displayText() << std::endl; - return downslib_error::incomplete; - } - } - else if (uri.getScheme() == "https") { - try - { - HTTPSClientSession session(uri.getHost(), uri.getPort()); - std::string path(uri.getPathAndQuery()); - if (path.empty()) path = "/"; - HTTPRequest request(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); - session.sendRequest(request); - HTTPResponse response; - session.peekResponse(response); - if (response.getStatus() == HTTPResponse::HTTPStatus::HTTP_FOUND) { - uri = response.get("Location"); - } - } - catch (Poco::Exception& exc) - { - fileStream << exc.displayText() << std::endl; - return downslib_error::incomplete; - } - - } - downslib_error ret = PdbDownLoader(uri, fileStream); - cb(userdata, 100, 100); - fileStream.close(); - return ret; -} + unsigned int timeout, downslib_cb cb, void* userdata) { + std::ofstream fileStream(fileName, std::ios::out | std::ios::trunc | std::ios::binary); + if (!fileStream) { + return downslib_error::incomplete; + } -unsigned long long SymbolFileInfo::GetPdbSize(std::string url, std::wstring fileName, std::string userAgent, - unsigned int timeout) { - + using tcp = asio::ip::tcp; + namespace ssl = asio::ssl; + + try { + asio::io_context ioc; + ssl::context ctx(ssl::context::sslv23_client); + + int redirect_count = 0; + const int max_redirects = 5; + + while (redirect_count < max_redirects) { + std::string protocol, host, path; + + if (url.substr(0, 8) == "https://") { + protocol = "https"; + url = url.substr(8); + } + else if (url.substr(0, 7) == "http://") { + protocol = "http"; + url = url.substr(7); + } + else { + throw std::runtime_error("Invalid URL protocol"); + } + + size_t path_pos = url.find('/'); + host = (path_pos == std::string::npos) ? url : url.substr(0, path_pos); + path = (path_pos == std::string::npos) ? "/" : url.substr(path_pos); + + tcp::resolver resolver(ioc); + auto const results = resolver.resolve(host, protocol); + + std::string request = "GET " + path + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: " + userAgent + "\r\n" + "Accept: */*\r\n" + "Connection: close\r\n\r\n"; + + if (protocol == "https") { + ssl::stream stream(ioc, ctx); + SSL_set_tlsext_host_name(stream.native_handle(), host.c_str()); + + asio::connect(stream.next_layer(), results.begin(), results.end()); + stream.handshake(ssl::stream_base::client); + asio::write(stream, asio::buffer(request)); + + asio::streambuf response; + asio::error_code header_ec; + asio::read_until(stream, response, "\r\n\r\n", header_ec); + if (header_ec) { + throw asio::system_error(header_ec); + } + + std::istream response_stream(&response); + std::string http_version; + unsigned int status_code; + std::string status_message; + + response_stream >> http_version >> status_code; + std::getline(response_stream, status_message); + + if (status_code == 301 || status_code == 302 || status_code == 307 || status_code == 308) { + std::string header; + while (std::getline(response_stream, header) && header != "\r") { + if (header.substr(0, 9) == "Location:") { + std::string new_url = header.substr(10); + new_url.erase(0, new_url.find_first_not_of(" \t")); + new_url.erase(new_url.find_last_not_of(" \r\n") + 1); + + if (new_url[0] == '/') { + new_url = protocol + "://" + host + new_url; + } + url = new_url; + redirect_count++; + goto continue_redirect; + } + } + } + + if (status_code != 200) { + return downslib_error::incomplete; + } - return 0; + // Skip remaining headers + std::string header; + while (std::getline(response_stream, header) && header != "\r"); + + // Write any data that was already read along with the headers + if (response.size() > 0) { + fileStream << &response; + } + + // Read the response body in chunks + const size_t chunk_size = 8192; + std::vector buffer(chunk_size); + asio::error_code ec; + size_t bytes_transferred = 0; + + while (true) { + bytes_transferred = stream.read_some(asio::buffer(buffer), ec); + + if (ec) { + // Check if this is a normal end of stream + if (ec == asio::error::eof || + ec.value() == 1 || // stream_truncated + ec == asio::ssl::error::stream_truncated) { + break; // Normal termination + } + throw asio::system_error(ec); + } + + if (bytes_transferred > 0) { + fileStream.write(buffer.data(), bytes_transferred); + if (!fileStream) { + throw std::runtime_error("Failed to write to file"); + } + } + + if (bytes_transferred == 0) { + break; + } + } + break; + } + else { // HTTP + tcp::socket socket(ioc); + asio::connect(socket, results.begin(), results.end()); + asio::write(socket, asio::buffer(request)); + + asio::streambuf response; + asio::error_code header_ec; + asio::read_until(socket, response, "\r\n\r\n", header_ec); + if (header_ec) { + throw asio::system_error(header_ec); + } + + std::istream response_stream(&response); + std::string http_version; + unsigned int status_code; + std::string status_message; + + response_stream >> http_version >> status_code; + std::getline(response_stream, status_message); + + if (status_code == 301 || status_code == 302 || status_code == 307 || status_code == 308) { + std::string header; + while (std::getline(response_stream, header) && header != "\r") { + if (header.substr(0, 9) == "Location:") { + std::string new_url = header.substr(10); + new_url.erase(0, new_url.find_first_not_of(" \t")); + new_url.erase(new_url.find_last_not_of(" \r\n") + 1); + + if (new_url[0] == '/') { + new_url = protocol + "://" + host + new_url; + } + url = new_url; + redirect_count++; + goto continue_redirect; + } + } + } + + if (status_code != 200) { + return downslib_error::incomplete; + } + + // Skip remaining headers + std::string header; + while (std::getline(response_stream, header) && header != "\r"); + + // Write any data that was already read along with the headers + if (response.size() > 0) { + fileStream << &response; + } + + // Read the response body in chunks + const size_t chunk_size = 8192; + std::vector buffer(chunk_size); + asio::error_code ec; + size_t bytes_transferred = 0; + + while (true) { + bytes_transferred = socket.read_some(asio::buffer(buffer), ec); + + if (ec) { + if (ec == asio::error::eof || ec.value() == 1) { + break; // Normal termination + } + throw asio::system_error(ec); + } + + if (bytes_transferred > 0) { + fileStream.write(buffer.data(), bytes_transferred); + if (!fileStream) { + throw std::runtime_error("Failed to write to file"); + } + } + + if (bytes_transferred == 0) { + break; + } + } + break; + } + + continue_redirect: + continue; + } + + if (redirect_count >= max_redirects) { + throw std::runtime_error("Too many redirects"); + } + } + catch (std::exception&) { + fileStream.close(); + return downslib_error::incomplete; + } + + if (cb) { + cb(userdata, 100, 100); + } + fileStream.close(); + return downslib_error::ok; } SymbolFileInfo::SymbolFileInfo() { - Poco::Net::initializeSSL(); - HTTPStreamFactory::registerFactory(); - HTTPSStreamFactory::registerFactory(); - FTPStreamFactory::registerFactory(); } SymbolFileInfo::~SymbolFileInfo() { - FTPStreamFactory::unregisterFactory(); - HTTPSStreamFactory::unregisterFactory(); - HTTPStreamFactory::unregisterFactory(); - Poco::Net::uninitializeSSL(); -} - -downslib_error SymbolFileInfo::PdbDownLoader(Poco::URI& uri, std::ostream& ostr) { - try { - std::unique_ptr pStr(URIStreamOpener::defaultOpener().open(uri)); - StreamCopier::copyStream(*pStr.get(), ostr); - return downslib_error::ok; - } - catch (Exception& exc) { - ostr << exc.displayText() << std::endl; - return downslib_error::incomplete; - } } \ No newline at end of file diff --git a/WinArk/SymbolFileInfo.h b/WinArk/SymbolFileInfo.h index cd48387..a5792c1 100644 --- a/WinArk/SymbolFileInfo.h +++ b/WinArk/SymbolFileInfo.h @@ -1,18 +1,5 @@ #pragma once -#include -#include -#include -#include -#include -#include "Poco/Net/HTTPSStreamFactory.h" -#include -#include -#include -#include -#include -#include -#include -#include + struct CV_HEADER { DWORD Signature; @@ -60,11 +47,6 @@ struct SymbolFileInfo { downslib_error Download(std::string url, std::wstring fileName, std::string userAgent, unsigned int timeout,downslib_cb = nullptr, void* userdata = nullptr); - unsigned long long GetPdbSize(std::string url, std::wstring fileName, std::string userAgent, - unsigned int timeout); - - downslib_error PdbDownLoader(Poco::URI& uri, std::ostream& ostr); - CString _pdbSignature; CString _pdbFile; PdbValidationData _pdbValidation; diff --git a/WinArk/SystemUsersView.cpp b/WinArk/SystemUsersView.cpp index 681a27a..bae3e8c 100644 --- a/WinArk/SystemUsersView.cpp +++ b/WinArk/SystemUsersView.cpp @@ -2,10 +2,6 @@ #include "SystemUsersView.h" #include #include "SortHelper.h" -#include -#include -#include -#include #include #include #include @@ -13,17 +9,23 @@ std::string CSystemUsersView::GetReadableTime(DWORD time) const { - Poco::Int64 timestamp = time; - if (timestamp == 0) { + if (time == 0) { return std::string("Never"); } - Poco::Timestamp ts(timestamp * Poco::Timestamp::resolution()); - Poco::DateTime utcDateTime(ts); - int timeZoneOffset = Poco::Timezone::utcOffset(); - Poco::DateTime localDateTime = utcDateTime + Poco::Timespan(timeZoneOffset, 0); - std::string readableTime = Poco::DateTimeFormatter::format(localDateTime, "%Y-%m-%d %H:%M:%S"); - return readableTime; + // Convert DWORD time to std::chrono::system_clock::time_point + std::chrono::system_clock::time_point tp = std::chrono::system_clock::from_time_t(time); + + // Convert to time_t for localtime conversion + std::time_t tt = std::chrono::system_clock::to_time_t(tp); + + // Convert to local time + std::tm local_tm = *std::localtime(&tt); + + // Format the time as a string + std::ostringstream oss; + oss << std::put_time(&local_tm, "%Y-%m-%d %H:%M:%S"); + return oss.str(); } diff --git a/WinArk/WinArk.vcxproj b/WinArk/WinArk.vcxproj index ef2c4e2..c3a4df7 100644 --- a/WinArk/WinArk.vcxproj +++ b/WinArk/WinArk.vcxproj @@ -110,7 +110,7 @@ stdcpplatest ..\PEParser;..\WinSysCore;..\PdbParser;..\Utils true - false + Sync false diff --git a/WinArk/stdafx.h b/WinArk/stdafx.h index 5591b10..4322b06 100644 --- a/WinArk/stdafx.h +++ b/WinArk/stdafx.h @@ -13,7 +13,6 @@ #define _WIN32_WINNT 0x0601 #define _WIN32_IE 0x0700 #define _RICHEDIT_VER 0x0500 -#define _HAS_EXCEPTIONS 0 // 解决标准库std::min与min宏冲突 #define NOMINMAX diff --git a/doc/build-winark.md b/doc/build-winark.md index 96ce010..29831cd 100644 --- a/doc/build-winark.md +++ b/doc/build-winark.md @@ -9,8 +9,8 @@ ``` vcpkg install capstone[x86]:x86-windows-static vcpkg install capstone[x86]:x64-windows-static -vcpkg install poco[netssl]:x86-windows-static -vcpkg install poco[netssl]:x64-windows-static +vcpkg install asio[openssl]:x86-windows-static +vcpkg install asio[openssl]:x64-windows-static ``` ## Compiling