commit f824a732f93cbe12151bcef3a85533af9129b7a7 Author: Ave <112294121+ave9858@users.noreply.github.com> Date: Sat Apr 6 23:33:58 2024 +0000 initial commit 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; +}