From f824a732f93cbe12151bcef3a85533af9129b7a7 Mon Sep 17 00:00:00 2001 From: Ave <112294121+ave9858@users.noreply.github.com> Date: Sat, 6 Apr 2024 23:33:58 +0000 Subject: [PATCH] initial commit --- .gitignore | 1 + Cargo.lock | 76 +++++++++++++++++++++++++++++ Cargo.toml | 21 ++++++++ LICENSE | 18 +++++++ README.md | 10 ++++ build.rs | 5 ++ sppc.def | 72 ++++++++++++++++++++++++++++ src/lib.rs | 87 +++++++++++++++++++++++++++++++++ src/sppcs.rs | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/win32.rs | 72 ++++++++++++++++++++++++++++ 10 files changed, 494 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 build.rs create mode 100644 sppc.def create mode 100644 src/lib.rs create mode 100644 src/sppcs.rs create mode 100644 src/win32.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..dca3cca --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,76 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "shook" +version = "0.1.0" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..38248dd --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "shook" +version = "0.1.0" +edition = "2021" +rust-version = "1.77.1" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +windows-sys = "0.52" + +[profile.dev] +lto = true +opt-level = 1 +panic = "abort" + +[profile.release] +lto = true +panic = "abort" +strip = true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..36d788f --- /dev/null +++ b/LICENSE @@ -0,0 +1,18 @@ +Copyright 2023-2024 asdcorp, Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a04c81a --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# ohook.rs + +A rewrite of [ohook](https://github.com/asdcorp/ohook) in Rust for decreased size, easier building, and better reproducibility. For more information on ohook check the original repo. + +## Building +Rust 1.77.1 and [Visual Studio Build Tools 2022 LTSC 17.6](https://download.visualstudio.microsoft.com/download/pr/a851fc84-7739-4b67-a7da-2c8564e30b38/b4133f16d790c3ee7325fff80c47094d94dff44b426b86db9013b200bb669ce2/vs_BuildTools.exe) running on Windows is required if you want to build binaries bit-for-bit identical to the release. To build x64, run `cargo build --release`, and for x86 run `cargo build --release --target i686-pc-windows-msvc`. + +## License + +The project is licensed under the terms of the MIT License. diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..c4f29a1 --- /dev/null +++ b/build.rs @@ -0,0 +1,5 @@ +fn main() { + println!("cargo::rustc-cdylib-link-arg=/DEF:sppc.def"); + println!("cargo::rustc-cdylib-link-arg=/Brepro"); + println!("cargo::rustc-cdylib-link-arg=/emittoolversioninfo:no"); +} diff --git a/sppc.def b/sppc.def new file mode 100644 index 0000000..eb24488 --- /dev/null +++ b/sppc.def @@ -0,0 +1,72 @@ +LIBRARY sppc.dll +EXPORTS +;hooked function +SLGetLicensingStatusInformation = SLGetLicensingStatusInformationHook + +;everything else +SLCallServer = SPPCS.SLCallServer +SLpAuthenticateGenuineTicketResponse = SPPCS.SLpAuthenticateGenuineTicketResponse +SLpBeginGenuineTicketTransaction = SPPCS.SLpBeginGenuineTicketTransaction +SLpClearActivationInProgress = SPPCS.SLpClearActivationInProgress +SLpDepositDownlevelGenuineTicket = SPPCS.SLpDepositDownlevelGenuineTicket +SLpDepositTokenActivationResponse = SPPCS.SLpDepositTokenActivationResponse +SLpGenerateTokenActivationChallenge = SPPCS.SLpGenerateTokenActivationChallenge +SLpGetGenuineBlob = SPPCS.SLpGetGenuineBlob +SLpGetGenuineLocal = SPPCS.SLpGetGenuineLocal +SLpGetLicenseAcquisitionInfo = SPPCS.SLpGetLicenseAcquisitionInfo +SLpGetMSPidInformation = SPPCS.SLpGetMSPidInformation +SLpGetMachineUGUID = SPPCS.SLpGetMachineUGUID +SLpGetTokenActivationGrantInfo = SPPCS.SLpGetTokenActivationGrantInfo +SLpIAActivateProduct = SPPCS.SLpIAActivateProduct +SLpIsCurrentInstalledProductKeyDefaultKey = SPPCS.SLpIsCurrentInstalledProductKeyDefaultKey +SLpProcessVMPipeMessage = SPPCS.SLpProcessVMPipeMessage +SLpSetActivationInProgress = SPPCS.SLpSetActivationInProgress +SLpTriggerServiceWorker = SPPCS.SLpTriggerServiceWorker +SLpVLActivateProduct = SPPCS.SLpVLActivateProduct +SLClose = SPPCS.SLClose +SLConsumeRight = SPPCS.SLConsumeRight +SLDepositMigrationBlob = SPPCS.SLDepositMigrationBlob +SLDepositOfflineConfirmationId = SPPCS.SLDepositOfflineConfirmationId +SLDepositOfflineConfirmationIdEx = SPPCS.SLDepositOfflineConfirmationIdEx +SLDepositStoreToken = SPPCS.SLDepositStoreToken +SLFireEvent = SPPCS.SLFireEvent +SLGatherMigrationBlob = SPPCS.SLGatherMigrationBlob +SLGatherMigrationBlobEx = SPPCS.SLGatherMigrationBlobEx +SLGenerateOfflineInstallationId = SPPCS.SLGenerateOfflineInstallationId +SLGenerateOfflineInstallationIdEx = SPPCS.SLGenerateOfflineInstallationIdEx +SLGetActiveLicenseInfo = SPPCS.SLGetActiveLicenseInfo +SLGetApplicationInformation = SPPCS.SLGetApplicationInformation +SLGetApplicationPolicy = SPPCS.SLGetApplicationPolicy +SLGetAuthenticationResult = SPPCS.SLGetAuthenticationResult +SLGetEncryptedPIDEx = SPPCS.SLGetEncryptedPIDEx +SLGetGenuineInformation = SPPCS.SLGetGenuineInformation +SLGetInstalledProductKeyIds = SPPCS.SLGetInstalledProductKeyIds +SLGetLicense = SPPCS.SLGetLicense +SLGetLicenseFileId = SPPCS.SLGetLicenseFileId +SLGetLicenseInformation = SPPCS.SLGetLicenseInformation +SLGetPKeyId = SPPCS.SLGetPKeyId +SLGetPKeyInformation = SPPCS.SLGetPKeyInformation +SLGetPolicyInformation = SPPCS.SLGetPolicyInformation +SLGetPolicyInformationDWORD = SPPCS.SLGetPolicyInformationDWORD +SLGetProductSkuInformation = SPPCS.SLGetProductSkuInformation +SLGetSLIDList = SPPCS.SLGetSLIDList +SLGetServiceInformation = SPPCS.SLGetServiceInformation +SLInstallLicense = SPPCS.SLInstallLicense +SLInstallProofOfPurchase = SPPCS.SLInstallProofOfPurchase +SLInstallProofOfPurchaseEx = SPPCS.SLInstallProofOfPurchaseEx +SLIsGenuineLocalEx = SPPCS.SLIsGenuineLocalEx +SLLoadApplicationPolicies = SPPCS.SLLoadApplicationPolicies +SLOpen = SPPCS.SLOpen +SLPersistApplicationPolicies = SPPCS.SLPersistApplicationPolicies +SLPersistRTSPayloadOverride = SPPCS.SLPersistRTSPayloadOverride +SLReArm = SPPCS.SLReArm +SLRegisterEvent = SPPCS.SLRegisterEvent +SLRegisterPlugin = SPPCS.SLRegisterPlugin +SLSetAuthenticationData = SPPCS.SLSetAuthenticationData +SLSetCurrentProductKey = SPPCS.SLSetCurrentProductKey +SLSetGenuineInformation = SPPCS.SLSetGenuineInformation +SLUninstallLicense = SPPCS.SLUninstallLicense +SLUninstallProofOfPurchase = SPPCS.SLUninstallProofOfPurchase +SLUnloadApplicationPolicies = SPPCS.SLUnloadApplicationPolicies +SLUnregisterEvent = SPPCS.SLUnregisterEvent +SLUnregisterPlugin = SPPCS.SLUnregisterPlugin diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..fdead5b --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,87 @@ +#![no_std] + +mod sppcs; +mod win32; + +use core::{ffi::c_void, ptr::null_mut}; +use win32::{LocalFree, StrStrNIW, SL_LICENSING_STATUS}; +use win32::{SLGetLicensingStatusInformation, SLGetProductSkuInformation}; + +use windows_sys::{ + core::{GUID, PCWSTR}, + w, +}; + +unsafe fn is_grace_period_product(hslc: *const c_void, pproductskuid: *const GUID) -> bool { + let mut p_buffer = null_mut(); + let mut cb_size = 0; + + if SLGetProductSkuInformation( + hslc, + pproductskuid, + w!("Name"), + null_mut(), + &mut cb_size, + &mut p_buffer, + ) != 0 + { + LocalFree(p_buffer as *mut c_void); + return false; + } + + if !StrStrNIW(p_buffer as *const u16, w!("Grace"), cb_size).is_null() { + LocalFree(p_buffer as *mut c_void); + return true; + } + + LocalFree(p_buffer as *mut c_void); + false +} + +#[no_mangle] +unsafe extern "system" fn SLGetLicensingStatusInformationHook( + hslc: *const c_void, + pappid: *const GUID, + pproductskuid: *const GUID, + pwszrightname: PCWSTR, + pnstatuscount: *mut u32, + pplicensingstatus: *mut *mut SL_LICENSING_STATUS, +) -> i32 { + let result = SLGetLicensingStatusInformation( + hslc, + pappid, + pproductskuid, + pwszrightname, + pnstatuscount, + pplicensingstatus, + ); + if result != 0 { + return result; + } + for i in 0..(*pnstatuscount as usize) { + let status = (*pplicensingstatus).add(i); + if (*status).eStatus == 0 { + continue; + } + if is_grace_period_product(hslc, &(*status).SkuId) { + continue; + } + (*status).eStatus = 1; + (*status).dwGraceTime = 0; + (*status).dwTotalGraceDays = 0; + (*status).hrReason = 0; + (*status).qwValidityExpiration = 0; + } + result +} + +#[no_mangle] +extern "system" fn _DllMainCRTStartup(_: *const u8, _: u32, _: *const u8) -> u32 { + 1 +} + +#[cfg(not(test))] +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + panic!() +} diff --git a/src/sppcs.rs b/src/sppcs.rs new file mode 100644 index 0000000..4b4a1f6 --- /dev/null +++ b/src/sppcs.rs @@ -0,0 +1,132 @@ +#![allow(non_snake_case)] + +#[no_mangle] +fn SLCallServer() {} +#[no_mangle] +fn SLpAuthenticateGenuineTicketResponse() {} +#[no_mangle] +fn SLpBeginGenuineTicketTransaction() {} +#[no_mangle] +fn SLpClearActivationInProgress() {} +#[no_mangle] +fn SLpDepositDownlevelGenuineTicket() {} +#[no_mangle] +fn SLpDepositTokenActivationResponse() {} +#[no_mangle] +fn SLpGenerateTokenActivationChallenge() {} +#[no_mangle] +fn SLpGetGenuineBlob() {} +#[no_mangle] +fn SLpGetGenuineLocal() {} +#[no_mangle] +fn SLpGetLicenseAcquisitionInfo() {} +#[no_mangle] +fn SLpGetMSPidInformation() {} +#[no_mangle] +fn SLpGetMachineUGUID() {} +#[no_mangle] +fn SLpGetTokenActivationGrantInfo() {} +#[no_mangle] +fn SLpIAActivateProduct() {} +#[no_mangle] +fn SLpIsCurrentInstalledProductKeyDefaultKey() {} +#[no_mangle] +fn SLpProcessVMPipeMessage() {} +#[no_mangle] +fn SLpSetActivationInProgress() {} +#[no_mangle] +fn SLpTriggerServiceWorker() {} +#[no_mangle] +fn SLpVLActivateProduct() {} +#[no_mangle] +fn SLClose() {} +#[no_mangle] +fn SLConsumeRight() {} +#[no_mangle] +fn SLDepositMigrationBlob() {} +#[no_mangle] +fn SLDepositOfflineConfirmationId() {} +#[no_mangle] +fn SLDepositOfflineConfirmationIdEx() {} +#[no_mangle] +fn SLDepositStoreToken() {} +#[no_mangle] +fn SLFireEvent() {} +#[no_mangle] +fn SLGatherMigrationBlob() {} +#[no_mangle] +fn SLGatherMigrationBlobEx() {} +#[no_mangle] +fn SLGenerateOfflineInstallationId() {} +#[no_mangle] +fn SLGenerateOfflineInstallationIdEx() {} +#[no_mangle] +fn SLGetActiveLicenseInfo() {} +#[no_mangle] +fn SLGetApplicationInformation() {} +#[no_mangle] +fn SLGetApplicationPolicy() {} +#[no_mangle] +fn SLGetAuthenticationResult() {} +#[no_mangle] +fn SLGetEncryptedPIDEx() {} +#[no_mangle] +fn SLGetGenuineInformation() {} +#[no_mangle] +fn SLGetInstalledProductKeyIds() {} +#[no_mangle] +fn SLGetLicense() {} +#[no_mangle] +fn SLGetLicenseFileId() {} +#[no_mangle] +fn SLGetLicenseInformation() {} +#[no_mangle] +fn SLGetPKeyId() {} +#[no_mangle] +fn SLGetPKeyInformation() {} +#[no_mangle] +fn SLGetPolicyInformation() {} +#[no_mangle] +fn SLGetPolicyInformationDWORD() {} +#[no_mangle] +fn SLGetSLIDList() {} +#[no_mangle] +fn SLGetServiceInformation() {} +#[no_mangle] +fn SLInstallLicense() {} +#[no_mangle] +fn SLInstallProofOfPurchase() {} +#[no_mangle] +fn SLInstallProofOfPurchaseEx() {} +#[no_mangle] +fn SLIsGenuineLocalEx() {} +#[no_mangle] +fn SLLoadApplicationPolicies() {} +#[no_mangle] +fn SLOpen() {} +#[no_mangle] +fn SLPersistApplicationPolicies() {} +#[no_mangle] +fn SLPersistRTSPayloadOverride() {} +#[no_mangle] +fn SLReArm() {} +#[no_mangle] +fn SLRegisterEvent() {} +#[no_mangle] +fn SLRegisterPlugin() {} +#[no_mangle] +fn SLSetAuthenticationData() {} +#[no_mangle] +fn SLSetCurrentProductKey() {} +#[no_mangle] +fn SLSetGenuineInformation() {} +#[no_mangle] +fn SLUninstallLicense() {} +#[no_mangle] +fn SLUninstallProofOfPurchase() {} +#[no_mangle] +fn SLUnloadApplicationPolicies() {} +#[no_mangle] +fn SLUnregisterEvent() {} +#[no_mangle] +fn SLUnregisterPlugin() {} diff --git a/src/win32.rs b/src/win32.rs new file mode 100644 index 0000000..65995a3 --- /dev/null +++ b/src/win32.rs @@ -0,0 +1,72 @@ +use core::ffi::c_void; +use windows_sys::core::{GUID, PCWSTR}; + +#[allow(non_snake_case)] +#[allow(non_camel_case_types)] +#[repr(C)] +pub struct SL_LICENSING_STATUS { + pub SkuId: GUID, + pub eStatus: i32, + pub dwGraceTime: u32, + pub dwTotalGraceDays: u32, + pub hrReason: i32, + pub qwValidityExpiration: u64, +} + +#[cfg_attr( + target_arch = "x86", + link(name = "sppcs", kind = "raw-dylib", import_name_type = "undecorated") +)] +#[cfg_attr(not(target_arch = "x86"), link(name = "sppcs", kind = "raw-dylib"))] +extern "system" { + pub fn SLGetLicensingStatusInformation( + hslc: *const c_void, + pappid: *const GUID, + pproductskuid: *const GUID, + pwszrightname: PCWSTR, + pnstatuscount: *mut u32, + pplicensingstatus: *mut *mut SL_LICENSING_STATUS, + ) -> i32; +} + +#[cfg_attr( + target_arch = "x86", + link(name = "sppcs", kind = "raw-dylib", import_name_type = "undecorated") +)] +#[cfg_attr(not(target_arch = "x86"), link(name = "sppcs", kind = "raw-dylib"))] +extern "system" { + pub fn SLGetProductSkuInformation( + hslc: *const c_void, + pproductskuid: *const GUID, + pwszvaluename: PCWSTR, + pedatatype: *mut u32, + pcbvalue: *mut u32, + ppbvalue: *mut *mut u8, + ) -> i32; +} + +#[cfg_attr( + target_arch = "x86", + link( + name = "KERNEL32", + kind = "raw-dylib", + import_name_type = "undecorated" + ) +)] +#[cfg_attr(not(target_arch = "x86"), link(name = "KERNEL32", kind = "raw-dylib"))] +extern "system" { + pub fn LocalFree(hmem: *mut c_void) -> *mut c_void; +} + +#[cfg_attr( + target_arch = "x86", + link(name = "SHLWAPI", kind = "raw-dylib", import_name_type = "undecorated") +)] +#[cfg_attr(not(target_arch = "x86"), link(name = "SHLWAPI", kind = "raw-dylib"))] +extern "system" { + pub fn StrStrNIW( + pszfirst: ::windows_sys::core::PCWSTR, + pszsrch: ::windows_sys::core::PCWSTR, + cchmax: u32, + ) -> ::windows_sys::core::PWSTR; +}