diff --git a/CMakeLists.txt b/CMakeLists.txt index 5094d7d..14f5432 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,6 @@ FetchContent_MakeAvailable(mimalloc) include_directories(.) add_executable(wibo dll/advapi32.cpp - dll/advapi32/internal.cpp dll/advapi32/processthreadsapi.cpp dll/advapi32/securitybaseapi.cpp dll/advapi32/winbase.cpp diff --git a/dll/advapi32/internal.cpp b/dll/advapi32/internal.cpp deleted file mode 100644 index d46c627..0000000 --- a/dll/advapi32/internal.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "internal.h" - -#include -#include -#include - -namespace { - -constexpr DWORD SECURITY_LOCAL_SYSTEM_RID = 18; - -constexpr BYTE kNtAuthority[6] = {0, 0, 0, 0, 0, 5}; - -std::mutex privilegeMapMutex; -std::unordered_map privilegeLuidCache; - -LUID generateDeterministicLuid(const std::string &normalizedName) { - uint32_t hash = 2166136261u; - for (unsigned char ch : normalizedName) { - hash ^= ch; - hash *= 16777619u; - } - if (hash == 0) { - hash = 1; - } - LUID luid{}; - luid.LowPart = hash; - luid.HighPart = 0; - return luid; -} - -} // namespace - -namespace advapi32 { - -bool isLocalSystemSid(const Sid *sid) { - if (!sid) { - return false; - } - if (sid->Revision != 1 || sid->SubAuthorityCount != 1) { - return false; - } - for (size_t i = 0; i < std::size(kNtAuthority); ++i) { - if (sid->IdentifierAuthority.Value[i] != kNtAuthority[i]) { - return false; - } - } - return sid->SubAuthority[0] == SECURITY_LOCAL_SYSTEM_RID; -} - -bool writeLocalSystemSid(Sid *sid) { - if (!sid) { - return false; - } - sid->Revision = 1; - sid->SubAuthorityCount = 1; - SidIdentifierAuthority authority{}; - for (size_t i = 0; i < std::size(kNtAuthority); ++i) { - authority.Value[i] = kNtAuthority[i]; - } - sid->IdentifierAuthority = authority; - sid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID; - return true; -} - -std::string normalizePrivilegeName(const std::string &name) { - std::string normalized; - normalized.reserve(name.size()); - for (unsigned char ch : name) { - normalized.push_back(static_cast(std::tolower(ch))); - } - return normalized; -} - -LUID lookupOrGeneratePrivilegeLuid(const std::string &normalizedName) { - std::lock_guard lock(privilegeMapMutex); - static const std::unordered_map predefined = { - {"se_debug_name", 0x14}, - {"se_shutdown_name", 0x13}, - }; - auto it = privilegeLuidCache.find(normalizedName); - if (it != privilegeLuidCache.end()) { - return it->second; - } - LUID luid{}; - auto predefinedIt = predefined.find(normalizedName); - if (predefinedIt != predefined.end()) { - luid.LowPart = predefinedIt->second; - luid.HighPart = 0; - } else { - luid = generateDeterministicLuid(normalizedName); - } - privilegeLuidCache[normalizedName] = luid; - return luid; -} - -void releaseToken(void *tokenPtr) { delete reinterpret_cast(tokenPtr); } - -} // namespace advapi32 diff --git a/dll/advapi32/internal.h b/dll/advapi32/internal.h index 9dba424..8f390ff 100644 --- a/dll/advapi32/internal.h +++ b/dll/advapi32/internal.h @@ -3,9 +3,9 @@ #include "common.h" #include "securitybaseapi.h" -#include +constexpr DWORD SECURITY_LOCAL_SYSTEM_RID = 18; -namespace advapi32 { +constexpr BYTE kNtAuthority[6] = {0, 0, 0, 0, 0, 5}; struct TokenObject { HANDLE processHandle; @@ -20,11 +20,3 @@ struct Sid { SidIdentifierAuthority IdentifierAuthority; DWORD SubAuthority[1]; }; - -bool isLocalSystemSid(const Sid *sid); -bool writeLocalSystemSid(Sid *sid); -std::string normalizePrivilegeName(const std::string &name); -LUID lookupOrGeneratePrivilegeLuid(const std::string &normalizedName); -void releaseToken(void *tokenPtr); - -} // namespace advapi32 diff --git a/dll/advapi32/securitybaseapi.cpp b/dll/advapi32/securitybaseapi.cpp index dfd4f7f..7191993 100644 --- a/dll/advapi32/securitybaseapi.cpp +++ b/dll/advapi32/securitybaseapi.cpp @@ -10,8 +10,6 @@ namespace { -using advapi32::Sid; - constexpr size_t kAceAlignment = 4; constexpr DWORD ERROR_REVISION_MISMATCH = 1306; constexpr DWORD ERROR_INVALID_ACL = 1336; @@ -19,6 +17,32 @@ constexpr DWORD ERROR_INVALID_SID = 1337; constexpr DWORD ERROR_ALLOTTED_SPACE_EXCEEDED = 1344; constexpr DWORD ERROR_INVALID_SECURITY_DESCR = 1338; +struct SidAndAttributes { + Sid *SidPtr; + DWORD Attributes; +}; + +struct TokenUserData { + SidAndAttributes User; +}; + +struct TokenStatisticsData { + LUID tokenId{}; + LUID authenticationId{}; + LARGE_INTEGER expirationTime{}; + DWORD tokenType = 0; + DWORD impersonationLevel = 0; + DWORD dynamicCharged = 0; + DWORD dynamicAvailable = 0; + DWORD groupCount = 0; + DWORD privilegeCount = 0; + LUID modifiedId{}; +}; + +struct TokenPrimaryGroupStub { + Sid *PrimaryGroup; +}; + size_t alignToDword(size_t value) { return (value + (kAceAlignment - 1)) & ~(kAceAlignment - 1); } size_t sidLength(const Sid *sid) { @@ -57,31 +81,20 @@ bool computeAclUsedSize(const ACL *acl, size_t capacity, size_t &used) { return true; } -struct SidAndAttributes { - Sid *SidPtr; - DWORD Attributes; -}; - -struct TokenUserData { - SidAndAttributes User; -}; - -struct TokenStatisticsData { - LUID tokenId{}; - LUID authenticationId{}; - LARGE_INTEGER expirationTime{}; - DWORD tokenType = 0; - DWORD impersonationLevel = 0; - DWORD dynamicCharged = 0; - DWORD dynamicAvailable = 0; - DWORD groupCount = 0; - DWORD privilegeCount = 0; - LUID modifiedId{}; -}; - -struct TokenPrimaryGroupStub { - Sid *PrimaryGroup; -}; +bool writeLocalSystemSid(Sid *sid) { + if (!sid) { + return false; + } + sid->Revision = 1; + sid->SubAuthorityCount = 1; + SidIdentifierAuthority authority{}; + for (size_t i = 0; i < std::size(kNtAuthority); ++i) { + authority.Value[i] = kNtAuthority[i]; + } + sid->IdentifierAuthority = authority; + sid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID; + return true; +} } // namespace diff --git a/dll/advapi32/winbase.cpp b/dll/advapi32/winbase.cpp index b937554..5c2aa44 100644 --- a/dll/advapi32/winbase.cpp +++ b/dll/advapi32/winbase.cpp @@ -6,12 +6,77 @@ #include #include +#include namespace { constexpr WCHAR kAccountSystem[] = {u'S', u'Y', u'S', u'T', u'E', u'M', u'\0'}; constexpr WCHAR kDomainNtAuthority[] = {u'N', u'T', u' ', u'A', u'U', u'T', u'H', u'O', u'R', u'I', u'T', u'Y', u'\0'}; +std::mutex g_privilegeMapMutex; +std::unordered_map g_privilegeLuidCache; + +bool isLocalSystemSid(const Sid *sid) { + if (!sid) { + return false; + } + if (sid->Revision != 1 || sid->SubAuthorityCount != 1) { + return false; + } + for (size_t i = 0; i < std::size(kNtAuthority); ++i) { + if (sid->IdentifierAuthority.Value[i] != kNtAuthority[i]) { + return false; + } + } + return sid->SubAuthority[0] == SECURITY_LOCAL_SYSTEM_RID; +} + +std::string normalizePrivilegeName(const std::string &name) { + std::string normalized; + normalized.reserve(name.size()); + for (unsigned char ch : name) { + normalized.push_back(static_cast(std::tolower(ch))); + } + return normalized; +} + +LUID generateDeterministicLuid(const std::string &normalizedName) { + uint32_t hash = 2166136261u; + for (unsigned char ch : normalizedName) { + hash ^= ch; + hash *= 16777619u; + } + if (hash == 0) { + hash = 1; + } + LUID luid{}; + luid.LowPart = hash; + luid.HighPart = 0; + return luid; +} + +LUID lookupOrGeneratePrivilegeLuid(const std::string &normalizedName) { + std::lock_guard lock(g_privilegeMapMutex); + static const std::unordered_map predefined = { + {"se_debug_name", 0x14}, + {"se_shutdown_name", 0x13}, + }; + auto it = g_privilegeLuidCache.find(normalizedName); + if (it != g_privilegeLuidCache.end()) { + return it->second; + } + LUID luid{}; + auto predefinedIt = predefined.find(normalizedName); + if (predefinedIt != predefined.end()) { + luid.LowPart = predefinedIt->second; + luid.HighPart = 0; + } else { + luid = generateDeterministicLuid(normalizedName); + } + g_privilegeLuidCache[normalizedName] = luid; + return luid; +} + } // namespace namespace advapi32 { @@ -25,7 +90,7 @@ BOOL WIN_FUNC LookupAccountSidW(LPCWSTR lpSystemName, PSID Sid, LPWSTR Name, LPD wibo::lastError = ERROR_INVALID_PARAMETER; return FALSE; } - auto *sidStruct = reinterpret_cast(Sid); + auto *sidStruct = reinterpret_cast(Sid); if (!isLocalSystemSid(sidStruct)) { wibo::lastError = ERROR_NONE_MAPPED; return FALSE; diff --git a/dll/kernel32/fileapi.cpp b/dll/kernel32/fileapi.cpp index 90e69c7..86ba717 100644 --- a/dll/kernel32/fileapi.cpp +++ b/dll/kernel32/fileapi.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/dll/kernel32/handleapi.cpp b/dll/kernel32/handleapi.cpp index bd77f76..1932699 100644 --- a/dll/kernel32/handleapi.cpp +++ b/dll/kernel32/handleapi.cpp @@ -150,7 +150,7 @@ BOOL WIN_FUNC CloseHandle(HANDLE hObject) { } else if (data.type == handles::TYPE_PROCESS) { delete reinterpret_cast(data.ptr); } else if (data.type == handles::TYPE_TOKEN) { - advapi32::releaseToken(data.ptr); + delete reinterpret_cast(data.ptr); } else if (data.type == handles::TYPE_MUTEX) { releaseMutexObject(reinterpret_cast(data.ptr)); } else if (data.type == handles::TYPE_EVENT) { diff --git a/dll/kernel32/internal.h b/dll/kernel32/internal.h index 74c27b2..c6fbca3 100644 --- a/dll/kernel32/internal.h +++ b/dll/kernel32/internal.h @@ -9,20 +9,20 @@ namespace kernel32 { struct ThreadObject { - pthread_t thread; + pthread_t thread{}; bool finished = false; bool joined = false; bool detached = false; bool synthetic = false; DWORD exitCode = 0; int refCount = 1; - pthread_mutex_t mutex; - pthread_cond_t cond; + pthread_mutex_t mutex{}; + pthread_cond_t cond{}; unsigned int suspendCount = 0; }; struct MutexObject { - pthread_mutex_t mutex; + pthread_mutex_t mutex{}; bool ownerValid = false; pthread_t owner = 0; unsigned int recursionCount = 0; @@ -31,8 +31,8 @@ struct MutexObject { }; struct EventObject { - pthread_mutex_t mutex; - pthread_cond_t cond; + pthread_mutex_t mutex{}; + pthread_cond_t cond{}; bool manualReset = false; bool signaled = false; std::u16string name; @@ -40,8 +40,8 @@ struct EventObject { }; struct SemaphoreObject { - pthread_mutex_t mutex; - pthread_cond_t cond; + pthread_mutex_t mutex{}; + pthread_cond_t cond{}; LONG count = 0; LONG maxCount = 0; std::u16string name;