fixes
This commit is contained in:
@@ -31,6 +31,7 @@ import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableLongStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
@@ -80,6 +81,10 @@ class HomeAbout : Routes.Route() {
|
||||
val tapCount = remember { mutableIntStateOf(0) }
|
||||
val lastTapTime = remember { mutableLongStateOf(0L) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
context.shortToast("Tap 5 times in this screen to see some magic 😉!")
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
||||
@@ -54,6 +54,7 @@ import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Download
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material.icons.filled.Notifications
|
||||
import androidx.compose.material.icons.filled.Schedule
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material.icons.outlined.Widgets
|
||||
@@ -258,7 +259,8 @@ class HomeRootSection : Routes.Route() {
|
||||
@Composable
|
||||
private fun TopBarActionChip(
|
||||
icon: ImageVector,
|
||||
label: String,
|
||||
label: String? = null,
|
||||
contentDescription: String? = label,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Surface(
|
||||
@@ -274,15 +276,17 @@ class HomeRootSection : Routes.Route() {
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
Icon(icon, contentDescription = label, tint = Color.White)
|
||||
Text(
|
||||
text = label,
|
||||
color = Color.White,
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
Icon(icon, contentDescription = contentDescription, tint = Color.White)
|
||||
label?.let {
|
||||
Text(
|
||||
text = it,
|
||||
color = Color.White,
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -888,18 +892,29 @@ class HomeRootSection : Routes.Route() {
|
||||
.fillMaxWidth()
|
||||
.padding(WindowInsets.statusBars.asPaddingValues())
|
||||
.padding(horizontal = cardMargin, vertical = 8.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
TopBarActionChip(
|
||||
icon = Icons.Filled.Info,
|
||||
label = "Announcements"
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
showAnnouncementsDialog = true
|
||||
loadAnnouncements()
|
||||
TopBarActionChip(
|
||||
icon = Icons.Filled.Notifications,
|
||||
label = null,
|
||||
contentDescription = "Announcements"
|
||||
) {
|
||||
showAnnouncementsDialog = true
|
||||
loadAnnouncements()
|
||||
}
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.wrapContentWidth(Alignment.End),
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
HomeActionChips()
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
HomeActionChips()
|
||||
}
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
HeroSection(
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
## v1.2.0
|
||||
- Fix: Prevent snap replay/missed audio voice call(thanks to RSR)
|
||||
- Fix: Various messaging fixes for newer snap versions(thanks to RSR)
|
||||
- New: Announcements feature(directly view important announcements right through the app!)
|
||||
- Fix: Missing about page
|
||||
- Fix: incorrect snap version instructions
|
||||
|
||||
## v1.1.2
|
||||
- New: Chat Wallpaper Download(upstream commit)
|
||||
- Fix: mappings error
|
||||
|
||||
434
native/rust/Cargo.lock
generated
434
native/rust/Cargo.lock
generated
@@ -4,9 +4,9 @@ version = 4
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.1"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
@@ -21,18 +21,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.4"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android_log-sys"
|
||||
version = "0.3.2"
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_log-sys"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ecc8056bf6ab9892dcd53216c83d1597487d7dacac16c8df6b877d127df9937"
|
||||
|
||||
[[package]]
|
||||
name = "android_logger"
|
||||
@@ -56,9 +62,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
@@ -68,15 +74,15 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.8.3"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
|
||||
checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.10.0"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||
checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
@@ -89,9 +95,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.1"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@@ -101,9 +107,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.0"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
||||
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
@@ -127,11 +133,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.53"
|
||||
version = "1.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932"
|
||||
checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"shlex",
|
||||
@@ -145,9 +150,9 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
@@ -157,13 +162,14 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.43"
|
||||
version = "0.4.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
|
||||
checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"num-traits",
|
||||
"windows-link",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -215,9 +221,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.5.0"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
@@ -262,7 +268,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -337,9 +343,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.4"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2"
|
||||
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
@@ -347,12 +353,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.14"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -361,17 +367,11 @@ version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.8"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369"
|
||||
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
@@ -389,38 +389,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.17"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4db6758c546e6f81f265638c980e5e84dfbda80cfd8e89e02f83454c8e8124bd"
|
||||
dependencies = [
|
||||
"log",
|
||||
"plain",
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goldberg"
|
||||
version = "0.1.0"
|
||||
@@ -451,15 +428,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.64"
|
||||
version = "0.1.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
@@ -484,9 +460,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.17"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
||||
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
@@ -512,19 +488,18 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.34"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.85"
|
||||
version = "0.3.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3"
|
||||
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
@@ -532,9 +507,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.180"
|
||||
version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
@@ -544,24 +519,23 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.29"
|
||||
version = "0.4.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -604,9 +578,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
version = "1.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "password-hash"
|
||||
@@ -649,15 +623,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "plain"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
@@ -667,18 +635,18 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -718,7 +686,6 @@ dependencies = [
|
||||
"crc32fast",
|
||||
"dobby-rs",
|
||||
"ed25519-dalek",
|
||||
"goblin",
|
||||
"goldberg",
|
||||
"jni",
|
||||
"libc",
|
||||
@@ -732,24 +699,18 @@ dependencies = [
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"zip",
|
||||
"zstd 0.13.3",
|
||||
"zstd 0.13.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.43"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@@ -777,14 +738,14 @@ version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.17",
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.12.2"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
|
||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -794,9 +755,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.13"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -805,9 +766,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.8"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
@@ -820,9 +781,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
version = "0.38.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
@@ -833,9 +794,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
@@ -846,26 +813,6 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1257cd4248b4132760d6524d6dda4e053bc648c9070b960929bf50cfb1e7add"
|
||||
dependencies = [
|
||||
"scroll_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scroll_derive"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed76efe62313ab6610570951494bdaa81568026e0318eaa55f167de70eeea67d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.27"
|
||||
@@ -874,45 +821,34 @@ checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
version = "1.0.217"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
version = "1.0.217"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.149"
|
||||
version = "1.0.135"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -952,12 +888,6 @@ dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.7.3"
|
||||
@@ -987,9 +917,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.114"
|
||||
version = "2.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
||||
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1013,27 +943,27 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.45"
|
||||
version = "0.3.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd"
|
||||
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde_core",
|
||||
"serde",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.7"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca"
|
||||
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
@@ -1043,9 +973,9 @@ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
@@ -1065,37 +995,41 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.2+wasi-0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.108"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566"
|
||||
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.96",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.108"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608"
|
||||
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -1103,92 +1037,42 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.108"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55"
|
||||
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
"syn 2.0.96",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.108"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12"
|
||||
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.2"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1209,15 +1093,6 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
@@ -1339,30 +1214,25 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.33"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.33"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1391,12 +1261,6 @@ dependencies = [
|
||||
"zstd 0.11.2+zstd.1.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65"
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.11.2+zstd.1.5.2"
|
||||
@@ -1408,11 +1272,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.13.3"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
|
||||
checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9"
|
||||
dependencies = [
|
||||
"zstd-safe 7.2.4",
|
||||
"zstd-safe 7.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1427,18 +1291,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zstd-safe"
|
||||
version = "7.2.4"
|
||||
version = "7.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
|
||||
checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059"
|
||||
dependencies = [
|
||||
"zstd-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-sys"
|
||||
version = "2.0.16+zstd.1.5.7"
|
||||
version = "2.0.13+zstd.1.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748"
|
||||
checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
|
||||
@@ -27,7 +27,6 @@ sha2 = "0.10"
|
||||
zip = "0.6.6"
|
||||
base64 = "0.22.1"
|
||||
ed25519-dalek = { version = "2.1.1", default-features = true, features = ["std"] }
|
||||
goblin = "0.10.4"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0"
|
||||
|
||||
@@ -24,16 +24,11 @@ pub static CLIENT_MODULE: Lazy<MappedLib> = Lazy::new(|| {
|
||||
|
||||
|
||||
pub fn set_native_lib_instance(instance: GlobalRef) {
|
||||
NATIVE_LIB_INSTANCE
|
||||
.set(instance)
|
||||
.expect("NativeLib instance already set");
|
||||
NATIVE_LIB_INSTANCE.set(instance).expect("NativeLib instance already set");
|
||||
}
|
||||
|
||||
pub fn native_lib_instance() -> GlobalRef {
|
||||
NATIVE_LIB_INSTANCE
|
||||
.get()
|
||||
.expect("NativeLib instance not set")
|
||||
.clone()
|
||||
NATIVE_LIB_INSTANCE.get().expect("NativeLib instance not set").clone()
|
||||
}
|
||||
|
||||
pub fn set_java_vm(vm: *mut jni::sys::JavaVM) {
|
||||
@@ -42,16 +37,13 @@ pub fn set_java_vm(vm: *mut jni::sys::JavaVM) {
|
||||
|
||||
pub fn java_vm() -> JavaVM {
|
||||
unsafe {
|
||||
JavaVM::from_raw(*JAVA_VM.get().expect("JavaVM not set") as *mut jni::sys::JavaVM)
|
||||
.expect("Failed to get JavaVM")
|
||||
JavaVM::from_raw(*JAVA_VM.get().expect("JavaVM not set") as *mut jni::sys::JavaVM).expect("Failed to get JavaVM")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn attach_jni_env(block: impl FnOnce(&mut jni::JNIEnv)) {
|
||||
let jvm = java_vm();
|
||||
let mut env: jni::AttachGuard = jvm
|
||||
.attach_current_thread()
|
||||
.expect("Failed to attach to current thread");
|
||||
let mut env: jni::AttachGuard = jvm.attach_current_thread().expect("Failed to attach to current thread");
|
||||
|
||||
block(&mut env);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,11 @@
|
||||
use crate::{secstrings, util::get_jni_string};
|
||||
use jni::{objects::JObject, JNIEnv};
|
||||
use std::{error::Error, sync::Mutex};
|
||||
use jni::{objects::JObject, JNIEnv};
|
||||
use crate::{secstrings, util::get_jni_string};
|
||||
|
||||
static NATIVE_CONFIG: Mutex<Option<NativeConfig>> = Mutex::new(None);
|
||||
|
||||
pub fn native_config() -> NativeConfig {
|
||||
NATIVE_CONFIG
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.expect("NativeConfig not loaded")
|
||||
.clone()
|
||||
NATIVE_CONFIG.lock().unwrap().as_ref().expect("NativeConfig not loaded").clone()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -32,13 +27,11 @@ impl NativeConfig {
|
||||
macro_rules! get_string {
|
||||
($field:expr) => {
|
||||
match env.get_field(&obj, $field, "Ljava/lang/String;")?.l()? {
|
||||
jstring => {
|
||||
if !jstring.is_null() {
|
||||
Some(get_jni_string(env, jstring.into())?)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
jstring => if !jstring.is_null() {
|
||||
Some(get_jni_string(env, jstring.into())?)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -80,11 +73,10 @@ pub fn get_blocker_config() -> BlockerConfig {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_config(mut env: JNIEnv, _class: JObject, obj: JObject) {
|
||||
NATIVE_CONFIG
|
||||
.lock()
|
||||
.unwrap()
|
||||
.replace(NativeConfig::new(&mut env, obj).expect("Failed to load NativeConfig"));
|
||||
|
||||
pub fn load_config(mut env: JNIEnv, _class: JObject, obj: JObject) {
|
||||
NATIVE_CONFIG.lock().unwrap().replace(
|
||||
NativeConfig::new(&mut env, obj).expect("Failed to load NativeConfig")
|
||||
);
|
||||
|
||||
info!("Config loaded {:?}", native_config());
|
||||
}
|
||||
|
||||
@@ -36,3 +36,15 @@ macro_rules! dobby_hook {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! dobby_hook_sym {
|
||||
($lib:expr, $sym:expr, $hook:expr) => {
|
||||
if let Some(hook_symbol) = dobby_rs::resolve_symbol($lib, $sym) {
|
||||
crate::dobby_hook!(hook_symbol, $hook);
|
||||
debug!("hooked symbol: {}", $sym);
|
||||
} else {
|
||||
panic!("Failed to resolve symbol: {}", $sym);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ extern crate log;
|
||||
|
||||
mod common;
|
||||
|
||||
mod config;
|
||||
mod hook;
|
||||
mod mapped_lib;
|
||||
mod sig;
|
||||
mod util;
|
||||
mod mapped_lib;
|
||||
mod config;
|
||||
mod sig;
|
||||
|
||||
mod modules;
|
||||
mod security;
|
||||
@@ -15,10 +15,7 @@ mod secstrings;
|
||||
|
||||
use android_logger::Config;
|
||||
use log::LevelFilter;
|
||||
use modules::{
|
||||
custom_font_hook, duplex_hook, fstat_hook, linker_hook, sqlite_hook, unary_call_hook,
|
||||
valdi_hook,
|
||||
};
|
||||
use modules::{valdi_hook, custom_font_hook, duplex_hook, fstat_hook, linker_hook, sqlite_hook, unary_call_hook};
|
||||
|
||||
use jni::{JNIEnv, JavaVM, NativeMethod};
|
||||
use jni::objects::{JObject, JString, JClass, JValue};
|
||||
@@ -169,11 +166,10 @@ fn init(mut env: JNIEnv, _class: JObject, signature_cache: JString) -> jstring {
|
||||
let start_time = std::time::Instant::now();
|
||||
|
||||
// load signature cache
|
||||
|
||||
|
||||
if !signature_cache.is_null() {
|
||||
let sig_cache_str = util::get_jni_string(&mut env, signature_cache)
|
||||
.expect("Failed to convert mappings to string");
|
||||
|
||||
let sig_cache_str = util::get_jni_string(&mut env, signature_cache).expect("Failed to convert mappings to string");
|
||||
|
||||
if let Ok(signature_cache) = serde_json::from_str(sig_cache_str.as_str()) {
|
||||
sig::add_signatures(signature_cache);
|
||||
} else {
|
||||
@@ -181,11 +177,7 @@ fn init(mut env: JNIEnv, _class: JObject, signature_cache: JString) -> jstring {
|
||||
}
|
||||
}
|
||||
|
||||
common::set_native_lib_instance(
|
||||
env.new_global_ref(_class)
|
||||
.ok()
|
||||
.expect("Failed to create global ref"),
|
||||
);
|
||||
common::set_native_lib_instance(env.new_global_ref(_class).ok().expect("Failed to create global ref"));
|
||||
|
||||
let _ = common::CLIENT_MODULE;
|
||||
|
||||
|
||||
@@ -24,24 +24,21 @@ impl MappedLib {
|
||||
}
|
||||
|
||||
pub fn search(&mut self) -> Result<&Self, Box<dyn Error>> {
|
||||
procfs::process::Process::myself()?
|
||||
.maps()?
|
||||
.iter()
|
||||
.for_each(|map| {
|
||||
let pathname = &map.pathname;
|
||||
procfs::process::Process::myself()?.maps()?.iter().for_each(|map| {
|
||||
let pathname = &map.pathname;
|
||||
|
||||
if let MMapPath::Path(path_buffer) = pathname {
|
||||
let path = path_buffer.to_string_lossy();
|
||||
if let MMapPath::Path(path_buffer) = pathname {
|
||||
let path = path_buffer.to_string_lossy();
|
||||
|
||||
if path.contains(&self.name) {
|
||||
self.regions.push(MappedRegion {
|
||||
start: map.address.0,
|
||||
end: map.address.1,
|
||||
perms: map.perms,
|
||||
});
|
||||
}
|
||||
if path.contains(&self.name) {
|
||||
self.regions.push(MappedRegion {
|
||||
start: map.address.0,
|
||||
end: map.address.1,
|
||||
perms: map.perms,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if self.regions.is_empty() {
|
||||
return Err(format!("No regions found for {}", self.name).into());
|
||||
|
||||
@@ -2,41 +2,33 @@ use std::{ffi::CStr, fs};
|
||||
|
||||
use nix::libc::{self, c_uint};
|
||||
|
||||
use crate::{config, def_hook, dobby_hook, modules::util::elf};
|
||||
use crate::{config, def_hook, dobby_hook_sym};
|
||||
|
||||
def_hook!(open_hook, i32, |path: *const u8,
|
||||
flags: i32,
|
||||
mode: c_uint| {
|
||||
if let Ok(pathname) = CStr::from_ptr(path).to_str() {
|
||||
if pathname == "/system/fonts/NotoColorEmoji.ttf" {
|
||||
if let Some(font_path) = config::native_config().custom_emoji_font_path {
|
||||
if fs::metadata(&font_path).is_ok() {
|
||||
return libc::openat(
|
||||
libc::AT_FDCWD,
|
||||
font_path.as_ptr() as *const u8,
|
||||
flags,
|
||||
mode,
|
||||
);
|
||||
} else {
|
||||
warn!("custom emoji font path does not exist: {}", font_path);
|
||||
def_hook!(
|
||||
open_hook,
|
||||
i32,
|
||||
|path: *const u8, flags: i32, mode: c_uint| {
|
||||
if let Ok(pathname) = CStr::from_ptr(path).to_str() {
|
||||
if pathname == "/system/fonts/NotoColorEmoji.ttf" {
|
||||
if let Some(font_path) = config::native_config().custom_emoji_font_path {
|
||||
if fs::metadata(&font_path).is_ok() {
|
||||
return libc::openat(libc::AT_FDCWD, font_path.as_ptr() as *const u8, flags, mode);
|
||||
} else {
|
||||
warn!("custom emoji font path does not exist: {}", font_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open_hook_original.unwrap()(path, flags, mode)
|
||||
});
|
||||
open_hook_original.unwrap()(path, flags, mode)
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
pub fn init() {
|
||||
if config::native_config().custom_emoji_font_path.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let libc = elf::Elf::from_maps("/libc.so").expect("Failed to find libc.so in maps");
|
||||
|
||||
if let Some(ptr) = libc.get_symbol_address("open") {
|
||||
dobby_hook!(ptr as _, open_hook);
|
||||
} else {
|
||||
panic!("Failed to find open symbol");
|
||||
}
|
||||
}
|
||||
dobby_hook_sym!("libc.so", "open", open_hook);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ use jni::{objects::JObject, sys::jboolean, JNIEnv};
|
||||
|
||||
use crate::{common, def_hook, dobby_hook, util::get_jni_string};
|
||||
|
||||
|
||||
def_hook!(
|
||||
is_same_object,
|
||||
jboolean,
|
||||
@@ -19,15 +20,9 @@ def_hook!(
|
||||
if !env.is_instance_of(&obj1, class).unwrap() {
|
||||
return is_same_object_original.unwrap()(env, obj1, obj2);
|
||||
}
|
||||
|
||||
let obj1_class_name = env
|
||||
.call_method(&obj1, "getName", "()Ljava/lang/String;", &[])
|
||||
.unwrap()
|
||||
.l()
|
||||
.unwrap()
|
||||
.into();
|
||||
let class_name =
|
||||
get_jni_string(&mut env, obj1_class_name).expect("Failed to get class name");
|
||||
|
||||
let obj1_class_name = env.call_method(&obj1, "getName", "()Ljava/lang/String;", &[]).unwrap().l().unwrap().into();
|
||||
let class_name = get_jni_string(&mut env, obj1_class_name).expect("Failed to get class name");
|
||||
|
||||
if class_name.contains("com.snapchat.client.duplex.MessageHandler") {
|
||||
debug!("is_same_object hook: MessageHandler");
|
||||
@@ -38,11 +33,9 @@ def_hook!(
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
pub fn init() {
|
||||
common::attach_jni_env(|env| {
|
||||
dobby_hook!(
|
||||
(**env.get_native_interface()).IsSameObject.unwrap() as *mut c_void,
|
||||
is_same_object
|
||||
);
|
||||
dobby_hook!((**env.get_native_interface()).IsSameObject.unwrap() as *mut c_void, is_same_object);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,48 +1,44 @@
|
||||
|
||||
use crate::{
|
||||
config::{self, native_config},
|
||||
def_hook, dobby_hook,
|
||||
modules::util::elf,
|
||||
};
|
||||
use nix::libc;
|
||||
use std::fs;
|
||||
|
||||
def_hook!(fstat_hook, i32, |fd: i32, statbuf: *mut libc::stat| {
|
||||
if let Ok(link) = fs::read_link("/proc/self/fd/".to_owned() + &fd.to_string()) {
|
||||
let link_str = link.to_string_lossy();
|
||||
let config = native_config();
|
||||
if config.disable_metrics && link_str.contains("files/blizzardv2/queues") {
|
||||
if libc::unlink((link_str.to_string() + "\0").as_ptr()) == -1 {
|
||||
warn!("Failed to unlink {}", link_str);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
use nix::libc;
|
||||
|
||||
if config.disable_bitmoji {
|
||||
if link_str.contains("com.snap.file_manager_4_SCContent") {
|
||||
use crate::{config::{self, native_config}, def_hook, dobby_hook_sym};
|
||||
|
||||
def_hook!(
|
||||
fstat_hook,
|
||||
i32,
|
||||
|fd: i32, statbuf: *mut libc::stat| {
|
||||
if let Ok(link) = fs::read_link("/proc/self/fd/".to_owned() + &fd.to_string()) {
|
||||
let link_str = link.to_string_lossy();
|
||||
let config = native_config();
|
||||
if config.disable_metrics && link_str.contains("files/blizzardv2/queues") {
|
||||
if libc::unlink((link_str.to_string() + "\0").as_ptr()) == -1 {
|
||||
warn!("Failed to unlink {}", link_str);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if link_str.contains("/files/file_manager/") {
|
||||
let lower = link_str.to_lowercase();
|
||||
if lower.contains("bitmoji") {
|
||||
|
||||
if config.disable_bitmoji {
|
||||
if link_str.contains("com.snap.file_manager_4_SCContent") {
|
||||
return -1;
|
||||
}
|
||||
if link_str.contains("/files/file_manager/") {
|
||||
let lower = link_str.to_lowercase();
|
||||
if lower.contains("bitmoji") {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fstat_hook_original.unwrap()(fd, statbuf)
|
||||
});
|
||||
fstat_hook_original.unwrap()(fd, statbuf)
|
||||
}
|
||||
);
|
||||
|
||||
pub fn init() {
|
||||
let config = config::native_config();
|
||||
if config.disable_metrics || config.disable_bitmoji {
|
||||
let libc = elf::Elf::from_maps("/libc.so").expect("Failed to find libc.so in maps");
|
||||
|
||||
if let Some(ptr) = libc.get_symbol_address("fstat") {
|
||||
dobby_hook!(ptr as _, fstat_hook);
|
||||
} else {
|
||||
panic!("Failed to find fstat symbol");
|
||||
}
|
||||
dobby_hook_sym!("libc.so", "fstat", fstat_hook);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,12 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::{c_void, CStr},
|
||||
sync::Mutex,
|
||||
};
|
||||
use std::{collections::HashMap, ffi::{c_void, CStr}, sync::Mutex};
|
||||
|
||||
use jni::{
|
||||
objects::{JByteArray, JString},
|
||||
JNIEnv,
|
||||
};
|
||||
use jni::{objects::{JByteArray, JString}, JNIEnv};
|
||||
use nix::libc;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::{def_hook, dobby_hook, modules::util::elf};
|
||||
use crate::{def_hook, dobby_hook_sym};
|
||||
|
||||
static SHARED_LIBRARIES: Lazy<Mutex<HashMap<String, Box<Vec<i8>>>>> =
|
||||
Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
static SHARED_LIBRARIES: Lazy<Mutex<HashMap<String, Box<Vec<i8>>>>> = Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
|
||||
def_hook!(
|
||||
linker_openat,
|
||||
@@ -25,13 +17,8 @@ def_hook!(
|
||||
if let Some(content) = SHARED_LIBRARIES.lock().unwrap().remove(&pathname_str) {
|
||||
let memfd = libc::syscall(libc::SYS_memfd_create, "jit-cache\0".as_ptr(), 0) as i32;
|
||||
let content = content.into_boxed_slice();
|
||||
|
||||
if libc::write(
|
||||
memfd,
|
||||
content.as_ptr() as *const c_void,
|
||||
content.len() as libc::size_t,
|
||||
) == -1
|
||||
{
|
||||
|
||||
if libc::write(memfd, content.as_ptr() as *const c_void, content.len() as libc::size_t) == -1 {
|
||||
panic!("failed to write to memfd");
|
||||
}
|
||||
|
||||
@@ -49,44 +36,25 @@ def_hook!(
|
||||
}
|
||||
);
|
||||
|
||||
pub fn add_linker_shared_library(
|
||||
mut env: JNIEnv,
|
||||
_: *mut c_void,
|
||||
path: JString,
|
||||
content: JByteArray,
|
||||
) {
|
||||
pub fn add_linker_shared_library(mut env: JNIEnv, _: *mut c_void, path: JString, content: JByteArray) {
|
||||
let path = env.get_string(&path).unwrap().to_str().unwrap().to_string();
|
||||
let content_length = env
|
||||
.get_array_length(&content)
|
||||
.expect("Failed to get array length");
|
||||
let content_length = env.get_array_length(&content).expect("Failed to get array length");
|
||||
let mut content_buffer = Box::new(vec![0i8; content_length as usize]);
|
||||
|
||||
env.get_byte_array_region(content, 0, content_buffer.as_mut_slice())
|
||||
.expect("Failed to get byte array region");
|
||||
|
||||
|
||||
env.get_byte_array_region(content, 0, content_buffer.as_mut_slice()).expect("Failed to get byte array region");
|
||||
|
||||
debug!("added shared library: {}", path);
|
||||
|
||||
SHARED_LIBRARIES
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(path, content_buffer);
|
||||
SHARED_LIBRARIES.lock().unwrap().insert(path, content_buffer);
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
let linker = {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
elf::Elf::from_maps("/linker64").expect("Failed to find linker64 in maps")
|
||||
}
|
||||
#[cfg(target_arch = "arm")]
|
||||
{
|
||||
elf::Elf::from_maps("/linker").expect("Failed to find linker in maps")
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(ptr) = linker.get_symbol_address("__dl___openat") {
|
||||
dobby_hook!(ptr as _, linker_openat);
|
||||
} else {
|
||||
panic!("Failed to find open symbol");
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
dobby_hook_sym!("linker64", "__dl___openat", linker_openat);
|
||||
}
|
||||
#[cfg(target_arch = "arm")]
|
||||
{
|
||||
dobby_hook_sym!("linker", "__dl___openat", linker_openat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
pub mod custom_font_hook;
|
||||
pub mod duplex_hook;
|
||||
pub mod fstat_hook;
|
||||
pub mod linker_hook;
|
||||
pub mod sqlite_hook;
|
||||
pub mod unary_call_hook;
|
||||
pub mod util;
|
||||
pub mod linker_hook;
|
||||
pub mod duplex_hook;
|
||||
pub mod sqlite_hook;
|
||||
pub mod fstat_hook;
|
||||
pub mod unary_call_hook;
|
||||
pub mod valdi_hook;
|
||||
pub mod custom_font_hook;
|
||||
|
||||
@@ -1,34 +1,25 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::{c_void, CStr},
|
||||
mem::size_of,
|
||||
ptr::addr_of_mut,
|
||||
sync::Mutex,
|
||||
};
|
||||
use std::{collections::HashMap, ffi::{c_void, CStr}, mem::size_of, ptr::addr_of_mut, sync::Mutex};
|
||||
|
||||
use jni::{
|
||||
objects::{JObject, JString},
|
||||
JNIEnv,
|
||||
};
|
||||
use jni::{objects::{JObject, JString}, JNIEnv};
|
||||
use nix::libc::{self, pthread_mutex_t};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::{common, def_hook, dobby_hook, sig, util::get_jni_string};
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct Sqlite3Mutex {
|
||||
mutex: pthread_mutex_t,
|
||||
mutex: pthread_mutex_t
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct Sqlite3 {
|
||||
pad: [u8; 3 * size_of::<usize>()],
|
||||
mutex: *mut Sqlite3Mutex,
|
||||
mutex: *mut Sqlite3Mutex
|
||||
}
|
||||
|
||||
static SQLITE3_MUTEX_MAP: Lazy<Mutex<HashMap<String, pthread_mutex_t>>> =
|
||||
Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
static SQLITE3_MUTEX_MAP: Lazy<Mutex<HashMap<String, pthread_mutex_t>>> = Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
|
||||
def_hook!(
|
||||
sqlite3_open,
|
||||
@@ -40,38 +31,27 @@ def_hook!(
|
||||
let sqlite3_mutex = (**pp_db).mutex;
|
||||
|
||||
if sqlite3_mutex != std::ptr::null_mut() {
|
||||
let filename = CStr::from_ptr(filename)
|
||||
.to_string_lossy()
|
||||
.to_string()
|
||||
.split("/")
|
||||
.last()
|
||||
.expect("Failed to get filename")
|
||||
.to_string();
|
||||
let filename = CStr::from_ptr(filename).to_string_lossy().to_string().split("/").last().expect("Failed to get filename").to_string();
|
||||
debug!("sqlite3_open hook {:?}", filename);
|
||||
|
||||
SQLITE3_MUTEX_MAP
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(filename, (*sqlite3_mutex).mutex);
|
||||
SQLITE3_MUTEX_MAP.lock().unwrap().insert(
|
||||
filename,
|
||||
(*sqlite3_mutex).mutex
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
pub fn lock_database(mut env: JNIEnv, _: *mut c_void, filename: JString, runnable: JObject) {
|
||||
let database_filename =
|
||||
get_jni_string(&mut env, filename).expect("Failed to get database filename");
|
||||
let mutex = SQLITE3_MUTEX_MAP
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get(&database_filename)
|
||||
.map(|mutex| *mutex);
|
||||
let database_filename = get_jni_string(&mut env, filename).expect("Failed to get database filename");
|
||||
let mutex = SQLITE3_MUTEX_MAP.lock().unwrap().get(&database_filename).map(|mutex| *mutex);
|
||||
|
||||
let call_runnable = || {
|
||||
env.call_method(runnable, "run", "()V", &[])
|
||||
.expect("Failed to call run method");
|
||||
env.call_method(runnable, "run", "()V", &[]).expect("Failed to call run method");
|
||||
};
|
||||
|
||||
if let Some(mut mutex) = mutex {
|
||||
@@ -91,17 +71,16 @@ pub fn lock_database(mut env: JNIEnv, _: *mut c_void, filename: JString, runnabl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn init() {
|
||||
if let Some(signature) = sig::find_signature(
|
||||
&common::CLIENT_MODULE,
|
||||
"FF FF 00 A9 3F 00 00 F9",
|
||||
-0x3C,
|
||||
"9A 46 90 46 78 44 89 46 05 68",
|
||||
-0xd,
|
||||
&common::CLIENT_MODULE,
|
||||
"FF FF 00 A9 3F 00 00 F9", -0x3C,
|
||||
"9A 46 90 46 78 44 89 46 05 68",-0xd
|
||||
) {
|
||||
debug!("Found sqlite3_open signature: {:#x}", signature);
|
||||
dobby_hook!(signature as *mut c_void, sqlite3_open);
|
||||
} else {
|
||||
panic!("Failed to find sqlite3_open signature");
|
||||
warn!("Failed to find sqlite3_open signature");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,17 @@
|
||||
use std::ffi::{c_void, CStr};
|
||||
|
||||
use jni::{
|
||||
objects::{JByteArray, JMethodID, JValue},
|
||||
signature::ReturnType,
|
||||
};
|
||||
use jni::{objects::{JByteArray, JMethodID, JValue}, signature::ReturnType};
|
||||
use nix::libc;
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
use crate::{
|
||||
common::{self},
|
||||
def_hook, dobby_hook, sig,
|
||||
};
|
||||
use crate::{common::{self}, def_hook, dobby_hook, sig};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct SliceByteBuffer {
|
||||
struct RefCountedSliceByteBuffer {
|
||||
ref_counter: *mut c_void,
|
||||
length: usize,
|
||||
data: *mut u8,
|
||||
data: *mut u8
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@@ -25,7 +19,7 @@ struct GrpcByteBuffer {
|
||||
reserved: *mut c_void,
|
||||
type_: *mut c_void,
|
||||
compression: *mut c_void,
|
||||
slice_buffer: *mut SliceByteBuffer,
|
||||
slice_buffer: *mut RefCountedSliceByteBuffer
|
||||
}
|
||||
|
||||
static NATIVE_LIB_ON_UNARY_CALL_METHOD: OnceCell<JMethodID> = OnceCell::new();
|
||||
@@ -33,12 +27,7 @@ static NATIVE_LIB_ON_UNARY_CALL_METHOD: OnceCell<JMethodID> = OnceCell::new();
|
||||
def_hook!(
|
||||
unary_call,
|
||||
*mut c_void,
|
||||
|unk1: *mut c_void,
|
||||
uri: *const u8,
|
||||
grpc_byte_buffer: *mut *mut GrpcByteBuffer,
|
||||
unk4: *mut c_void,
|
||||
unk5: *mut c_void,
|
||||
unk6: *mut c_void| {
|
||||
|unk1: *mut c_void, uri: *const u8, grpc_byte_buffer: *mut *mut GrpcByteBuffer, unk4: *mut c_void, unk5: *mut c_void, unk6: *mut c_void| {
|
||||
macro_rules! call_original {
|
||||
() => {
|
||||
unary_call_original.unwrap()(unk1, uri, grpc_byte_buffer, unk4, unk5, unk6)
|
||||
@@ -56,73 +45,45 @@ def_hook!(
|
||||
let mut env = java_vm.get_env().expect("Failed to get JNIEnv");
|
||||
|
||||
let slice_buffer_length = slice_buffer.length as usize;
|
||||
let jni_buffer = env
|
||||
.new_byte_array(slice_buffer_length as i32)
|
||||
.expect("Failed to create new byte array");
|
||||
env.set_byte_array_region(
|
||||
&jni_buffer,
|
||||
0,
|
||||
std::slice::from_raw_parts(slice_buffer.data as *const i8, slice_buffer_length),
|
||||
)
|
||||
.expect("Failed to set byte array region");
|
||||
let jni_buffer = env.new_byte_array(slice_buffer_length as i32).expect("Failed to create new byte array");
|
||||
env.set_byte_array_region(&jni_buffer, 0, std::slice::from_raw_parts(slice_buffer.data as *const i8, slice_buffer_length)).expect("Failed to set byte array region");
|
||||
|
||||
let uri_str = CStr::from_ptr(uri).to_str().unwrap();
|
||||
|
||||
let native_request_data_object = env
|
||||
.call_method_unchecked(
|
||||
common::native_lib_instance(),
|
||||
NATIVE_LIB_ON_UNARY_CALL_METHOD.get().unwrap(),
|
||||
ReturnType::Object,
|
||||
&[
|
||||
JValue::from(&env.new_string(uri_str).unwrap()).as_jni(),
|
||||
JValue::from(&jni_buffer).as_jni(),
|
||||
],
|
||||
)
|
||||
.expect("Failed to call onNativeUnaryCall method")
|
||||
.l()
|
||||
.unwrap();
|
||||
let native_request_data_object = env.call_method_unchecked(
|
||||
common::native_lib_instance(),
|
||||
NATIVE_LIB_ON_UNARY_CALL_METHOD.get().unwrap(),
|
||||
ReturnType::Object,
|
||||
&[
|
||||
JValue::from(&env.new_string(uri_str).unwrap()).as_jni(),
|
||||
JValue::from(&jni_buffer).as_jni()
|
||||
]
|
||||
).expect("Failed to call onNativeUnaryCall method").l().unwrap();
|
||||
|
||||
if native_request_data_object.is_null() {
|
||||
return call_original!();
|
||||
}
|
||||
|
||||
let is_canceled = env
|
||||
.get_field(&native_request_data_object, "canceled", "Z")
|
||||
.expect("Failed to get canceled field")
|
||||
.z()
|
||||
.unwrap();
|
||||
let is_canceled = env.get_field(&native_request_data_object, "canceled", "Z").expect("Failed to get canceled field").z().unwrap();
|
||||
|
||||
if is_canceled {
|
||||
info!("canceled request for {}", uri_str);
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
|
||||
let new_buffer: JByteArray = env
|
||||
.get_field(&native_request_data_object, "buffer", "[B")
|
||||
.expect("Failed to get buffer field")
|
||||
.l()
|
||||
.unwrap()
|
||||
.into();
|
||||
let new_buffer_length = env
|
||||
.get_array_length(&new_buffer)
|
||||
.expect("Failed to get array length") as usize;
|
||||
let new_buffer: JByteArray = env.get_field(&native_request_data_object, "buffer", "[B").expect("Failed to get buffer field").l().unwrap().into();
|
||||
let new_buffer_length = env.get_array_length(&new_buffer).expect("Failed to get array length") as usize;
|
||||
|
||||
let mut new_buffer_data = Box::new(vec![0i8; new_buffer_length]);
|
||||
env.get_byte_array_region(&new_buffer, 0, new_buffer_data.as_mut_slice())
|
||||
.expect("Failed to get byte array region");
|
||||
env.get_byte_array_region(&new_buffer, 0, new_buffer_data.as_mut_slice()).expect("Failed to get byte array region");
|
||||
|
||||
let ref_counter_struct_size =
|
||||
(slice_buffer.data as usize) - (slice_buffer.ref_counter as usize);
|
||||
let ref_counter_struct_size = (slice_buffer.data as usize) - (slice_buffer.ref_counter as usize);
|
||||
|
||||
//we need to allocate a new ref_counter struct and copy the old ref_counter and the new_buffer to it
|
||||
let new_ref = {
|
||||
let new_ref = libc::malloc(ref_counter_struct_size + new_buffer_length) as *mut c_void;
|
||||
libc::memcpy(new_ref, slice_buffer.ref_counter, ref_counter_struct_size);
|
||||
libc::memcpy(
|
||||
new_ref.offset(ref_counter_struct_size as isize),
|
||||
new_buffer_data.as_ptr() as *const c_void,
|
||||
new_buffer_length,
|
||||
);
|
||||
libc::memcpy(new_ref.offset(ref_counter_struct_size as isize), new_buffer_data.as_ptr() as *const c_void, new_buffer_length);
|
||||
libc::free(slice_buffer.ref_counter);
|
||||
new_ref
|
||||
};
|
||||
@@ -143,25 +104,20 @@ def_hook!(
|
||||
pub fn init() {
|
||||
if let Some(signature) = sig::find_signature(
|
||||
&common::CLIENT_MODULE,
|
||||
"AA A8 03 1F F8 ?? ?? 00 94 ?? ?? 05 91",
|
||||
-0x47,
|
||||
"0A 90 00 F0 3F F9",
|
||||
-0x37,
|
||||
"A8 03 1F F8 ?? ?? 00 94 ?? ?? ?? 91 ?? ?? ?? A9", -0x48,
|
||||
"0A 90 00 F0 3F F9", -0x37
|
||||
) {
|
||||
dobby_hook!(signature as *mut c_void, unary_call);
|
||||
common::attach_jni_env(|env| {
|
||||
NATIVE_LIB_ON_UNARY_CALL_METHOD
|
||||
.set(
|
||||
env.get_method_id(
|
||||
env.get_object_class(common::native_lib_instance()).unwrap(),
|
||||
"onNativeUnaryCall",
|
||||
"(Ljava/lang/String;[B)Lme/eternal/purrfectsnap/nativelib/NativeRequestData;",
|
||||
)
|
||||
.expect("Failed to get onNativeUnaryCall method id"),
|
||||
)
|
||||
.expect("unary call method already set");
|
||||
NATIVE_LIB_ON_UNARY_CALL_METHOD.set(
|
||||
env.get_method_id(
|
||||
env.get_object_class(common::native_lib_instance()).unwrap(),
|
||||
"onNativeUnaryCall",
|
||||
"(Ljava/lang/String;[B)Lme/eternal/purrfectsnap/nativelib/NativeRequestData;"
|
||||
).expect("Failed to get onNativeUnaryCall method id")
|
||||
).expect("unary call method already set");
|
||||
});
|
||||
} else {
|
||||
panic!("Can't find unaryCall signature");
|
||||
error!("Can't find unaryCall signature");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
use procfs::process::MMapPath;
|
||||
|
||||
pub struct Elf<'elf> {
|
||||
base_address: usize,
|
||||
elf: goblin::elf::Elf<'elf>,
|
||||
_buffer: &'elf [u8],
|
||||
}
|
||||
|
||||
impl<'elf> Elf<'elf> {
|
||||
pub fn from_maps(lib: &str) -> Option<Self> {
|
||||
let maps = procfs::process::Process::myself().ok()?.maps().ok()?;
|
||||
|
||||
for memory_map in maps.iter() {
|
||||
if let MMapPath::Path(path) = &memory_map.pathname {
|
||||
let path = path.to_string_lossy();
|
||||
|
||||
if !path.contains(lib) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let file_data = std::fs::read(path.to_string()).ok()?;
|
||||
let file_buffer = Box::leak(file_data.into_boxed_slice());
|
||||
|
||||
if let Ok(elf) = goblin::elf::Elf::parse(file_buffer) {
|
||||
return Some(Elf {
|
||||
base_address: memory_map.address.0 as usize,
|
||||
elf,
|
||||
_buffer: file_buffer,
|
||||
});
|
||||
} else {
|
||||
warn!(
|
||||
"Failed to parse ELF for library {} at address {:x}",
|
||||
lib, memory_map.address.0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_symbol_address(&self, symbol: &str) -> Option<usize> {
|
||||
for sym in &self.elf.dynsyms {
|
||||
if let Some(name) = self.elf.dynstrtab.get_at(sym.st_name) {
|
||||
if name == symbol {
|
||||
return Some(self.base_address + sym.st_value as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for sym in &self.elf.syms {
|
||||
if let Some(name) = self.elf.strtab.get_at(sym.st_name) {
|
||||
if name == symbol {
|
||||
return Some(self.base_address + sym.st_value as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1 @@
|
||||
pub mod elf;
|
||||
pub mod valdi_utils;
|
||||
|
||||
@@ -43,12 +43,7 @@ pub struct ValdiModule {
|
||||
impl ValdiModule {
|
||||
pub fn parse(buffer: Vec<u8>) -> Result<ValdiModule, Error> {
|
||||
let mut offset = 0;
|
||||
let magic = u32::from_be_bytes([
|
||||
buffer[offset],
|
||||
buffer[offset + 1],
|
||||
buffer[offset + 2],
|
||||
buffer[offset + 3],
|
||||
]);
|
||||
let magic = u32::from_be_bytes([buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3]]);
|
||||
|
||||
offset += 4;
|
||||
|
||||
@@ -90,12 +85,13 @@ impl ValdiModule {
|
||||
tags.push(ModuleTag::new(has_padding, tag_buffer));
|
||||
}
|
||||
|
||||
let tags = tags
|
||||
.chunks(2)
|
||||
.map(|chunk| (chunk[0].clone(), chunk[1].clone()))
|
||||
.collect();
|
||||
let tags = tags.chunks(2).map(|chunk| {
|
||||
(chunk[0].clone(), chunk[1].clone())
|
||||
}).collect();
|
||||
|
||||
Ok(ValdiModule { tags })
|
||||
Ok(ValdiModule {
|
||||
tags,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
use super::util::valdi_utils::{ModuleTag, ValdiModule};
|
||||
use crate::{config, def_hook, dobby_hook, modules::util::elf, util::get_jni_string};
|
||||
#![allow(dead_code, unused_imports)]
|
||||
|
||||
use super::util::valdi_utils::{ValdiModule, ModuleTag};
|
||||
use std::{collections::HashMap, ffi::c_void, sync::Mutex};
|
||||
use jni::{objects::JString, JNIEnv};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::c_void,
|
||||
sync::Mutex,
|
||||
};
|
||||
use crate::{common, config, def_hook, dobby_hook, dobby_hook_sym, util::get_jni_string};
|
||||
|
||||
static AASSET_MAP: Lazy<Mutex<HashMap<usize, Vec<u8>>>> = Lazy::new(|| Mutex::new(HashMap::new()));
|
||||
static LOADER_DATA: Mutex<Option<String>> = Mutex::new(None);
|
||||
|
||||
def_hook!(aasset_get_length, i32, |arg0: *mut c_void| {
|
||||
if let Some(buffer) = AASSET_MAP.lock().unwrap().get(&(arg0 as usize)) {
|
||||
return buffer.len() as i32;
|
||||
def_hook!(
|
||||
aasset_get_length,
|
||||
i32,
|
||||
|arg0: *mut c_void| {
|
||||
if let Some(buffer) = AASSET_MAP.lock().unwrap().get(&(arg0 as usize)) {
|
||||
return buffer.len() as i32;
|
||||
}
|
||||
aasset_get_length_original.unwrap()(arg0)
|
||||
}
|
||||
aasset_get_length_original.unwrap()(arg0)
|
||||
});
|
||||
);
|
||||
|
||||
def_hook!(aasset_get_buffer, *const c_void, |arg0: *mut c_void| {
|
||||
if let Some(buffer) = AASSET_MAP.lock().unwrap().get(&(arg0 as usize)) {
|
||||
return buffer.as_ptr() as *const c_void;
|
||||
def_hook!(
|
||||
aasset_get_buffer,
|
||||
*const c_void,
|
||||
|arg0: *mut c_void| {
|
||||
if let Some(buffer) = AASSET_MAP.lock().unwrap().get(&(arg0 as usize)) {
|
||||
return buffer.as_ptr() as *const c_void;
|
||||
}
|
||||
aasset_get_buffer_original.unwrap()(arg0)
|
||||
}
|
||||
aasset_get_buffer_original.unwrap()(arg0)
|
||||
});
|
||||
);
|
||||
|
||||
def_hook!(
|
||||
aasset_manager_open,
|
||||
@@ -39,13 +45,9 @@ def_hook!(
|
||||
|
||||
let loader_data = LOADER_DATA.lock().unwrap().clone().expect("No loader data");
|
||||
|
||||
let archive_buffer: Vec<u8> =
|
||||
std::slice::from_raw_parts(asset_buffer as *const u8, asset_length as usize)
|
||||
.to_vec();
|
||||
let decompressed = zstd::stream::decode_all(&archive_buffer[..])
|
||||
.expect("Failed to decompress valdi archive");
|
||||
let mut valdi_module =
|
||||
ValdiModule::parse(decompressed).expect("Failed to parse valdi module");
|
||||
let archive_buffer: Vec<u8> = std::slice::from_raw_parts(asset_buffer as *const u8, asset_length as usize).to_vec();
|
||||
let decompressed = zstd::stream::decode_all(&archive_buffer[..]).expect("Failed to decompress valdi archive");
|
||||
let mut valdi_module = ValdiModule::parse(decompressed).expect("Failed to parse valdi module");
|
||||
|
||||
let mut tags = valdi_module.get_tags();
|
||||
let mut new_tags = Vec::new();
|
||||
@@ -56,22 +58,19 @@ def_hook!(
|
||||
continue;
|
||||
}
|
||||
|
||||
let old_file_name = name.split_once(".").unwrap().0.to_owned()
|
||||
+ rand::random::<u32>().to_string().as_str();
|
||||
let old_file_name = name.split_once(".").unwrap().0.to_owned() + rand::random::<u32>().to_string().as_str();
|
||||
tag1.set_buffer((old_file_name.to_owned() + ".js").as_bytes().to_vec());
|
||||
let original_module_path =
|
||||
path.split_once(".").unwrap().0.to_owned() + "/" + &old_file_name;
|
||||
let original_module_path = path.split_once(".").unwrap().0.to_owned() + "/" + &old_file_name;
|
||||
|
||||
let hooked_module = format!(
|
||||
"{};module.exports = require(\"{}\");",
|
||||
loader_data, original_module_path
|
||||
let hooked_module = format!("{};module.exports = require(\"{}\");", loader_data, original_module_path);
|
||||
|
||||
new_tags.push(
|
||||
(
|
||||
ModuleTag::new(true, name.as_bytes().to_vec()),
|
||||
ModuleTag::new(true, hooked_module.as_bytes().to_vec())
|
||||
)
|
||||
);
|
||||
|
||||
new_tags.push((
|
||||
ModuleTag::new(true, name.as_bytes().to_vec()),
|
||||
ModuleTag::new(true, hooked_module.as_bytes().to_vec()),
|
||||
));
|
||||
|
||||
debug!("Valdi loader injected in {}", name);
|
||||
break;
|
||||
}
|
||||
@@ -80,22 +79,22 @@ def_hook!(
|
||||
valdi_module.set_tags(tags);
|
||||
|
||||
let compressed = valdi_module.to_bytes();
|
||||
let compressed =
|
||||
zstd::stream::encode_all(&compressed[..], 3).expect("Failed to compress");
|
||||
let compressed = zstd::stream::encode_all(&compressed[..], 3).expect("Failed to compress");
|
||||
|
||||
AASSET_MAP
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(handle as usize, compressed);
|
||||
AASSET_MAP.lock().unwrap().insert(handle as usize, compressed);
|
||||
}
|
||||
handle
|
||||
}
|
||||
);
|
||||
|
||||
def_hook!(aasset_close, c_void, |handle: *mut c_void| {
|
||||
AASSET_MAP.lock().unwrap().remove(&(handle as usize));
|
||||
aasset_close_original.unwrap()(handle)
|
||||
});
|
||||
def_hook!(
|
||||
aasset_close,
|
||||
c_void,
|
||||
|handle: *mut c_void| {
|
||||
AASSET_MAP.lock().unwrap().remove(&(handle as usize));
|
||||
aasset_close_original.unwrap()(handle)
|
||||
}
|
||||
);
|
||||
|
||||
pub fn set_valdi_loader(mut env: JNIEnv, _: *mut c_void, code: JString) {
|
||||
let new_code = get_jni_string(&mut env, code).expect("Failed to get loader code");
|
||||
@@ -104,33 +103,11 @@ pub fn set_valdi_loader(mut env: JNIEnv, _: *mut c_void, code: JString) {
|
||||
|
||||
pub fn init() {
|
||||
if !config::native_config().valdi_hooks {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
let lib_android =
|
||||
elf::Elf::from_maps("/libandroid.so").expect("Failed to find libandroid.so in maps");
|
||||
|
||||
if let Some(ptr) = lib_android.get_symbol_address("AAsset_getBuffer") {
|
||||
dobby_hook!(ptr as _, aasset_get_buffer);
|
||||
} else {
|
||||
panic!("Failed to find AAsset_getBuffer symbol");
|
||||
}
|
||||
|
||||
if let Some(ptr) = lib_android.get_symbol_address("AAsset_getLength") {
|
||||
dobby_hook!(ptr as _, aasset_get_length);
|
||||
} else {
|
||||
panic!("Failed to find AAsset_getLength symbol");
|
||||
}
|
||||
|
||||
if let Some(ptr) = lib_android.get_symbol_address("AAsset_close") {
|
||||
dobby_hook!(ptr as _, aasset_close);
|
||||
} else {
|
||||
panic!("Failed to find AAsset_close symbol");
|
||||
}
|
||||
|
||||
if let Some(ptr) = lib_android.get_symbol_address("AAssetManager_open") {
|
||||
dobby_hook!(ptr as _, aasset_manager_open);
|
||||
} else {
|
||||
panic!("Failed to find AAssetManager_open symbol");
|
||||
}
|
||||
dobby_hook_sym!("libandroid.so", "AAsset_getBuffer", aasset_get_buffer);
|
||||
dobby_hook_sym!("libandroid.so", "AAsset_getLength", aasset_get_length);
|
||||
dobby_hook_sym!("libandroid.so", "AAsset_close", aasset_close);
|
||||
dobby_hook_sym!("libandroid.so", "AAssetManager_open", aasset_manager_open);
|
||||
}
|
||||
|
||||
@@ -61,18 +61,8 @@ pub fn find_signatures(module_base: usize, bytes_buffer: &[u8], pattern: &str, o
|
||||
let mut mask = Vec::new();
|
||||
let mut i = 0;
|
||||
|
||||
if let Some(cache) = SIGNATURE_CACHE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.find(|(sig, _)| sig == pattern)
|
||||
{
|
||||
return cache
|
||||
.1
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|offset| module_base + offset)
|
||||
.collect();
|
||||
if let Some(cache) = SIGNATURE_CACHE.lock().unwrap().iter().find(|(sig, _)| sig == pattern) {
|
||||
return cache.1.clone().into_iter().map(|offset| module_base + offset).collect();
|
||||
}
|
||||
|
||||
while i < pattern.len() {
|
||||
@@ -80,7 +70,7 @@ pub fn find_signatures(module_base: usize, bytes_buffer: &[u8], pattern: &str, o
|
||||
bytes.push(0);
|
||||
mask.push('?');
|
||||
} else {
|
||||
bytes.push(u8::from_str_radix(&pattern[i..i + 2], 16).unwrap());
|
||||
bytes.push(u8::from_str_radix(&pattern[i..i+2], 16).unwrap());
|
||||
mask.push('x');
|
||||
}
|
||||
i += 3;
|
||||
@@ -102,10 +92,7 @@ pub fn find_signatures(module_base: usize, bytes_buffer: &[u8], pattern: &str, o
|
||||
}
|
||||
if found {
|
||||
if once {
|
||||
SIGNATURE_CACHE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push((pattern.to_string(), vec![i]));
|
||||
SIGNATURE_CACHE.lock().unwrap().push((pattern.to_string(), vec![i]));
|
||||
return vec![module_base + i];
|
||||
}
|
||||
results.push(module_base + i);
|
||||
@@ -113,22 +100,14 @@ pub fn find_signatures(module_base: usize, bytes_buffer: &[u8], pattern: &str, o
|
||||
i += 1;
|
||||
}
|
||||
|
||||
SIGNATURE_CACHE
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push((pattern.to_string(), results.clone()));
|
||||
SIGNATURE_CACHE.lock().unwrap().push((pattern.to_string(), results.clone()));
|
||||
results
|
||||
}
|
||||
|
||||
pub fn find_signature_executable(mapped_lib: &MappedLib, pattern: &str) -> Option<usize> {
|
||||
let executable_regions = mapped_lib
|
||||
.regions
|
||||
.iter()
|
||||
.filter(|region| {
|
||||
region.perms.contains(MMPermissions::EXECUTE)
|
||||
&& region.perms.contains(MMPermissions::READ)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let executable_regions = mapped_lib.regions.iter().filter(|region| {
|
||||
region.perms.contains(MMPermissions::EXECUTE)
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
for region in executable_regions {
|
||||
let size = (region.end - region.start) as usize;
|
||||
@@ -138,27 +117,16 @@ pub fn find_signature_executable(mapped_lib: &MappedLib, pattern: &str) -> Optio
|
||||
let bytes_buffer = match read_region_bytes(module_base, size) {
|
||||
Some(buffer) => buffer,
|
||||
None => {
|
||||
warn!(
|
||||
"Unable to read executable region: {:#x} - {:#x}",
|
||||
region.start, region.end
|
||||
);
|
||||
warn!("Unable to read executable region: {:#x} - {:#x}", region.start, region.end);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let results = find_signatures(module_base, &bytes_buffer, pattern, true);
|
||||
|
||||
if results.is_empty() {
|
||||
warn!(
|
||||
"Signature not found in region: {:#x} - {:#x}",
|
||||
region.start, region.end
|
||||
);
|
||||
warn!("Signature not found in region: {:#x} - {:#x}", region.start, region.end);
|
||||
} else {
|
||||
debug!(
|
||||
"Found {} results in region: {:#x} - {:#x}",
|
||||
results.len(),
|
||||
region.start,
|
||||
region.end
|
||||
);
|
||||
debug!("Found {} results in region: {:#x} - {:#x}", results.len(), region.start, region.end);
|
||||
return Some(results[0]);
|
||||
}
|
||||
}
|
||||
@@ -167,21 +135,13 @@ pub fn find_signature_executable(mapped_lib: &MappedLib, pattern: &str) -> Optio
|
||||
None
|
||||
}
|
||||
|
||||
pub fn find_signature(
|
||||
mapped_lib: &MappedLib,
|
||||
_arm64_pattern: &str,
|
||||
_arm64_offset: i64,
|
||||
_arm32_pattern: &str,
|
||||
_arm32_offset: i64,
|
||||
) -> Option<usize> {
|
||||
pub fn find_signature(mapped_lib: &MappedLib, _arm64_pattern: &str, _arm64_offset: i64, _arm32_pattern: &str, _arm32_offset: i64) -> Option<usize> {
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{
|
||||
return find_signature_executable(mapped_lib, _arm64_pattern)
|
||||
.map(|address| (address as i64 + _arm64_offset) as usize);
|
||||
return find_signature_executable(mapped_lib, _arm64_pattern).map(|address| (address as i64 + _arm64_offset) as usize);
|
||||
}
|
||||
#[cfg(target_arch = "arm")]
|
||||
{
|
||||
return find_signature_executable(mapped_lib, _arm32_pattern)
|
||||
.map(|address| (address as i64 + _arm32_offset) as usize);
|
||||
return find_signature_executable(mapped_lib, _arm32_pattern).map(|address| (address as i64 + _arm32_offset) as usize);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user