diff --git a/CMakeLists.txt b/CMakeLists.txt index bcc03d2..c5cef2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,7 @@ add_library(LLVMObfuscator SHARED Plugin.cpp) target_include_directories(LLVMObfuscator PRIVATE ${CMAKE_SOURCE_DIR}) target_include_directories(LLVMObfuscator PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -target_link_libraries(LLVMObfuscator LLVMCore LLVMSupport) +target_link_libraries(LLVMObfuscator LLVMCore LLVMSupport LLVMAnalysis LLVMTransformUtils) option(BUILD_DUMMY "Build dummy plugin" OFF) if(BUILD_DUMMY) diff --git a/utils/CryptoUtils.cpp b/utils/CryptoUtils.cpp index a7c947f..994d47c 100644 --- a/utils/CryptoUtils.cpp +++ b/utils/CryptoUtils.cpp @@ -610,26 +610,80 @@ void CryptoUtils::populate_pool() { idx = 0; } +#if defined(_WIN64) || defined(_WIN32) +// sic! don't change include order +#include +#include + +struct WinDevRandom { + WinDevRandom() : m_hcryptProv{0}, m_last_read{0} { + assert(!m_hcryptProv); + if (!CryptAcquireContext(&m_hcryptProv, nullptr, nullptr, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + errs() << "CryptAcquireContext failed (LastError: " << GetLastError() + << ")\n"; + } else { + assert(m_hcryptProv); + } + } + + ~WinDevRandom() { close(); } + + std::size_t read(char *key, std::size_t sz) { + assert(m_hcryptProv); + if (!CryptGenRandom(m_hcryptProv, sz, reinterpret_cast(key))) { + errs() << "CryptGenRandom failed (LastError: " << GetLastError() << ")\n"; + } + m_last_read = sz; + return sz; + } + + void close() { + if (m_hcryptProv && !CryptReleaseContext(m_hcryptProv, 0)) { + errs() << "CryptReleaseContext failed (LastError: " << GetLastError() + << ")\n"; + } + m_hcryptProv = 0; + assert(!m_hcryptProv); + } + + std::size_t gcount() { return m_last_read; } + + explicit operator bool() { return true; } + + bool good() const { return m_hcryptProv; } + +private: + HCRYPTPROV m_hcryptProv; + std::size_t m_last_read; +}; +#endif + bool CryptoUtils::prng_seed() { #if defined(__linux__) - std::ifstream devrandom("/dev/urandom"); + std::string const dev = "/dev/urandom"; + std::ifstream devrandom(dev); +#elif defined(_WIN64) || defined(_WIN32) + std::string const dev = "CryptGenRandom"; + WinDevRandom devrandom; #else - std::ifstream devrandom("/dev/random"); + std::string const dev = "/dev/random"; + std::ifstream devrandom(dev); #endif - if (devrandom) { + if (devrandom.good()) { devrandom.read(key, 16); if (devrandom.gcount() != 16) { - errs() << "Cannot read enough bytes in /dev/random\n"; + errs() << "Cannot read enough bytes in " << dev << "\n"; return false; } devrandom.close(); DEBUG_WITH_TYPE("cryptoutils", - dbgs() << "cryptoutils seeded with /dev/random\n"); + dbgs() << "cryptoutils seeded with " << dev << "\n"); memset(ctr, 0, 16); @@ -639,7 +693,7 @@ bool CryptoUtils::prng_seed() { seeded = true; } else { - errs() << "Cannot open /dev/random\n"; + errs() << "Cannot open " << dev << "\n"; return false; } return true; diff --git a/utils/CryptoUtils.h b/utils/CryptoUtils.h index 8964c41..ca5d46b 100644 --- a/utils/CryptoUtils.h +++ b/utils/CryptoUtils.h @@ -32,13 +32,18 @@ extern ManagedStatic cryptoutils; #define BYTE(x, n) (((x) >> (8 * (n))) & 0xFF) #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(INTEL_CC) + defined(INTEL_CC) || defined(_WIN64) || defined(_WIN32) #ifndef ENDIAN_LITTLE #define ENDIAN_LITTLE #endif #define ENDIAN_32BITWORD + +#if !defined(_WIN64) || !defined(_WIN32) +#ifndef UNALIGNED #define UNALIGNED +#endif +#endif #elif defined(__alpha)