chiteroman/PlayIntegrityFix

Some kernel strings are blocked by Goolag

Closed this issue Β· 112 comments

For example Sultan kernel on Pixel 7/Pro/a is blocked from Goolag since it has a string named Sultan in it. They are checking for blocked words (case insensitive) in the uname kernel string, so I wonder if we can override that.

EDIT: Known Banned Kernel List

This can be fixed by changing the contents of /proc/version This comes from the uname syscall as suggested by Sultan

Tagging @osm0sis, as this will certainly be of relevance to him as well.

Interesting! How have you checked and/or proven this? And also if so, why does it work on the December build of a custom kernel, but not the January one of the same custom kernel, as per Fishawy's original report in the XDA thread?

Sultan kernel dev renamed his kernel to Slutan and it passes. Renamed back to Sultan and it fails. Not sure why it's not failing for everyone/every kernel version, though.

It is failing for some linage os kernels (https://t.me/AutoPIFNEXT/1292). This is not related to monthly build, but rather because after Jan 25 Google might have made an update to check for uname kernel string as we can verify from the images in the Telegram link.

Can hexpatch fix this issue? πŸ€”

It does certainly seem like there's a rollout of this new check going on, whatever it is.

I'm checking with the user about his rolling back to the December kernel helping, to see if there are other mitigating factors involved, e.g. actually a different custom kernel, or a test build without the custom kernel string or something.

If the uname syscall is how it's checked, and it's done via libc we can just hook it directly like we do prop calls, we just need to find/look up the correct name for it.

Arguably custom kernel developers will also just need to stop customizing the kernel string. πŸ€·β€β™‚οΈ

Edit: Yeppp, confirmed the user switched to a different December kernel with a different string, he just assumed they were the same since it's a fork of the January kernel he was on. πŸ€¦β€β™‚οΈ

I'm worried that they are going to check the kernel string against ones that are known to have been validated by them, such as stock kernel updates, so it would be better if we can spoof this without relying on kernel author

It does certainly seem like there's a rollout of this new check going on, whatever it is.

I'm checking with the user about his rolling back to the December kernel helping, to see if there are other mitigating factors involved, e.g. actually a different custom kernel, or a test build without the custom kernel string or something.

If the uname syscall is how it's checked, and it's done via libc we can just hook it directly like we do prop calls, we just need to find/look up the correct name for it.

Arguably custom kernel developers will also just need to stop customizing the kernel string. πŸ€·β€β™‚οΈ

The only solution we've found that will continue to work is to use OEM-esque names, i.e. -android14 instead of -ExtraFancyName. We're already playing whackamole with fingerprints, last thing we need is kernels too.

Unfortunately, that's going to require kernel devs to not put a name on their kernel, which might not be something they're willing to do

I'm worried that they are going to check the kernel string against ones that are known to have been validated by them, such as stock kernel updates, so it would be better if we can spoof this without relying on kernel author

Kernels aren't directly certified so that's unfeasible; however; as I said above, most custom kernel devs name their kernels which is easy to check.

Low effort but ingenious move on Google's part. You can't flash a custom kernel unless you unlock so I'm honestly surprised they just now started checking.

Ask custom kernel devs to stop rename kernel version

Yeah even if we do figure out how to hook it and sanitize it, that could require maintaining a list of banned keywords on our side as well, since if we replaced the whole thing Google would also definitely catch on if 70,000 people suddenly all have some super basic matching string... Brutal for upkeep.

I think the thing we could accommodate reasonably to have our cake and eat it too, is that most kernel devs do just slap their name on the end, so we could just chop that part off. It's not a guarantee that's where they'll always put it, but those other kernels can suffer the consequences.

Yeah even if we do figure out how to hook it and sanitize it, that could require maintaining a list of banned keywords on our side as well, since Google would also definitely catch on if 70,000 people suddenly all have some super basic matching string... Brutal for upkeep.

Why don't we let users pick their own kernel string, when users have to pick their own fps anyway?

Yeah even if we do figure out how to hook it and sanitize it, that could require maintaining a list of banned keywords on our side as well, since if we replaced the whole thing Google would also definitely catch on if 70,000 people suddenly all have some super basic matching string... Brutal for upkeep.

I think the thing we could accommodate reasonably to have our cake and eat it too, is that most kernel devs do just slap their name on the end, so we could just chop that part off. It's not a guarantee that's where they'll always put it, but those other kernels can suffer the consequences.

Why sanitize when you can replace it outright with some GKI uname?

Why sanitize when you can replace it outright with some GKI uname?

What I just said.

if we replaced the whole thing Google would also definitely catch on if 70,000 people suddenly all have some super basic matching string...

I suppose some Google stock full kernel string could be safe though, since they couldn't risk banning those. That could still be a problematic moving target though and require upkeep.

Honestly kernel developers not broadcasting the device is unlocked via changing the kernel version string anymore is probably the simplest longest term fix.

Why sanitize when you can replace it outright with some GKI uname?

What I just said.

if we replaced the whole thing Google would also definitely catch on if 70,000 people suddenly all have some super basic matching string...

It's possible to customize the git sha component of the auto localversion to create a uname that's structured like a GKI uname but unique for everyone.

For example, one user may have 5.15.110-android14-11-g4bdf4d09f338, then another user may have 5.15.110-android14-11-11e6df074ae23, where the g4bdf4d09f338 and 11e6df074ae23 are just randomly generated on the user's device.

I suppose some Google stock full kernel string could be safe though, since they couldn't risk banning those. That could still be a problematic moving target though and require upkeep.

^ This would also be a consequence of what you mention here:

Honestly kernel developers not broadcasting the device is unlocked via changing the kernel version string anymore is probably the simplest longest term fix.

Because the same issue would perpetuate itself, where custom kernels spoof stock kernel strings that may someday be blocked.

So I don't think this is a robust solution. It also makes it difficult to catch updated kernel version checks in the future since the spoofed kernel version isn't centralized through PIF; attestation failures due to blocked kernel versions could therefore be misconstrued on an individual basis as being caused by a blocked fingerprint for example.

But a centralized one is arguably easier to block, where all the custom kernels just being their own generic untouched kernel version string would be very difficult for Google to block.

Basically the same argument as all of us using our own fingerprint to decrease the statistical data Google receives to block them by.

But a centralized one is arguably easier to block, where all the custom kernels just being their own generic untouched kernel version string would be very difficult for Google to block.

Basically the same argument as all of us using our own fingerprint to decrease the statistical data Google receives to block them by.

Fingerprints are a finite resource, while kernel version strings are infinite. I think it's therefore better to prioritize the ability to determine if a fingerprint is blocked by making a centralized uname spoof, especially since parts of the uname can be randomly generated, whereas fingerprints must be on Google's allowlist.

To this point, Magisk's package name randomization feature hasn't been defeated; I think employing the same tactic on the kernel version string would be quite successful.

If there's some future blanket ban on a centralized kernel version spoof, then it can always be revisited and/or become like fingerprints which need to be customized by the user. But I think that's moreso a last resort and isn't necessary right now.

Sounds fair!

So yeah, here's our libc call to intercept/hook:
https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/include/sys/utsname.h#65

And the struct to spoof above it.

perhaps google has started matching kernel names and fingerprints and that's how they are failing fingerprints.

is there evidence of any other kernels with custom strings being blocked?

could this just be google blacklisting terms that could be taken "offensive or racist"?
Maybe something like King, Queen, Slave or Master would be blacklisted as well?

Much like google removed the terms of master/slave from all their drivers.
freak07/Kirisakura_Pantah@dd3a351
Or renaming all branches from master to main

is there evidence of any other kernels with custom strings being blocked?

could this just be google blacklisting terms that could be taken "offensive or racist"? Maybe something like King, Queen, Slave or Master would be blacklisted as well?

Much like google removed the terms of master/slave from all their drivers. Renaming all branches from master to main

They are definitely blocking kernel version strings. "lineageos" in the uname causes device attestation to fail as well, and I've seen others mention that the same occurs with your "kirisakura".

is there evidence of any other kernels with custom strings being blocked?
could this just be google blacklisting terms that could be taken "offensive or racist"? Maybe something like King, Queen, Slave or Master would be blacklisted as well?
Much like google removed the terms of master/slave from all their drivers. Renaming all branches from master to main

They are definitely blocking kernel version strings. "lineageos" in the uname causes device attestation to fail as well, and I've seen others mention that the same occurs with your "kirisakura".

no problems on my end with my kernels on about 10 of my own devices when using fingerprints that pass integrity checks.

If google indeed starts to blacklist kernel strings it gets extremely hard to verify whatΒ΄s actually breaking.
Every change to the prints takes a reboot.
A reboot has sometimes fixed integrity passing on my own end for me, without changing the kernel.

edit:
or the prints employed by the play integrity fix module.

Check v15.4

I added uname hook to spoof release name!

PIF hooked into uname, but GMS unstable isn't accessing it... Here is the log:
https://github.com/chiteroman/PlayIntegrityFix/files/14075761/28_01-18-05-02_219.txt

Log detail
1706439817.416  root 18531 18531 D PIF     : Dex file size: 7120
1706439817.416  root 18531 18531 D PIF     : Json file size: 385
1706439817.434 10148 18531 18531 D PIF     : get system classloader
1706439817.434 10148 18531 18531 D PIF     : create class loader
1706439817.435 10148 18531 18531 D PIF     : load class
1706439817.435 10148 18531 18531 D PIF     : call init
1706439817.436 10148 18531 18531 D PIF     : Spoof Provider done!
1706439817.437 10148 18531 18531 D PIF     : Save BRAND with value: asus
1706439817.437 10148 18531 18531 D PIF     : Save DEVICE with value: ASUS_Z010_2
1706439817.437 10148 18531 18531 D PIF     : Save FINGERPRINT with value: asus/WW_Phone/ASUS_Z010_2:6.0.1/MMB29P/13.8.26.98-20170502:user/release-keys
1706439817.437 10148 18531 18531 D PIF     : Save ID with value: MMB29P
1706439817.437 10148 18531 18531 D PIF     : Save MANUFACTURER with value: asus
1706439817.437 10148 18531 18531 D PIF     : Save MODEL with value: ASUS_Z010DD
1706439817.437 10148 18531 18531 D PIF     : Save PRODUCT with value: WW_Phone
1706439817.437 10148 18531 18531 D PIF     : Save SECURITY_PATCH with value: 2017-03-05
1706439817.437 10148 18531 18531 D PIF     : Map size: 8
1706439817.437 10148 18531 18531 D PIF     : Call spoofFields!
1706439817.437 10148 18531 18531 D PIF     : Set MANUFACTURER field value: asus
1706439817.437 10148 18531 18531 D PIF     : Set BRAND field value: asus
1706439817.437 10148 18531 18531 D PIF     : Set DEVICE field value: ASUS_Z010_2
1706439817.437 10148 18531 18531 D PIF     : Set ID field value: MMB29P
1706439817.437 10148 18531 18531 D PIF     : Set MODEL field value: ASUS_Z010DD
1706439817.437 10148 18531 18531 D PIF     : Set FINGERPRINT field value: asus/WW_Phone/ASUS_Z010_2:6.0.1/MMB29P/13.8.26.98-20170502:user/release-keys
1706439817.437 10148 18531 18531 D PIF     : Set PRODUCT field value: WW_Phone
1706439817.437 10148 18531 18531 D PIF     : Set SECURITY_PATCH field value: 2017-03-05
1706439817.437 10148 18531 18531 D PIF     : Found '__system_property_read_callback' handle at 0x76884daaf0
1706439817.437 10148 18531 18531 D PIF     : Found 'uname' handle at 0x7688520a70
1706439817.454 10148 18531 18544 D PIF     : [ro.vndk.version] -> 34
1706439817.454 10148 18531 18544 D PIF     : [sys.use_memfd] -> false
1706439817.456 10148 18531 18531 D PIF     : [ro.product.vndk.version] -> 34
1706439817.458 10148 18531 18531 D PIF     : [dalvik.vm.dexopt.secondary] -> true
1706439817.460 10148 18531 18531 D PIF     : [dalvik.vm.dexopt.secondary] -> true
1706439817.462 10148 18531 18531 D PIF     : [dalvik.vm.dexopt.secondary] -> true
1706439817.464 10148 18531 18531 D PIF     : [dalvik.vm.dexopt.secondary] -> true
1706439817.479 10148 18531 18531 D PIF     : [build.version.extensions.r] -> 10
1706439817.479 10148 18531 18531 D PIF     : [build.version.extensions.s] -> 10
1706439817.479 10148 18531 18531 D PIF     : [build.version.extensions.t] -> 10
1706439817.479 10148 18531 18531 D PIF     : [build.version.extensions.u] -> 10
1706439817.479 10148 18531 18531 D PIF     : [build.version.extensions.ad_services] -> 10
1706439817.583 10148 18531 18543 D PIF     : [dalvik.vm.dexopt.secondary] -> true
1706439817.627 10148 18531 18543 D PIF     : DroidGuard call certificate chain! Throw exception.
1706439817.659 10148 18531 18543 D PIF     : [ro.boot.flash.locked] -> 1
1706439817.659 10148 18531 18543 D PIF     : [ro.boot.vbmeta.device_state] -> locked
1706439817.661 10148 18531 18543 D PIF     : Call spoofFields!
1706439817.661 10148 18531 18543 D PIF     : [Zygisk] Call Java spoofFields!
1706439817.661 10148 18531 18543 D PIF     : [ro.product.first_api_level] -> 25
1706439817.661 10148 18531 18543 D PIF     : [ro.boot.verifiedbootstate] -> green
1706439817.661 10148 18531 18543 D PIF     : [ro.boot.vbmeta.digest] -> fc97f54106f2d03aa5b5a7661f1a48aa10f2188e3394c330e41bee7f57d27ddd
1706439817.746 10148 18531 18543 D PIF     : [ro.boot.hardware.revision] -> MP1.0
1706439817.774 10148 18531 18543 D PIF     : [ro.secure] -> 1
1706439817.774 10148 18531 18543 D PIF     : [ro.debuggable] -> 0
1706439817.798 10148 18531 18543 D PIF     : DroidGuard call certificate chain! Throw exception.
1706439817.801 10148 18531 18543 D PIF     : [ro.hardware.egl] -> mali
1706439817.818 10148 18531 18543 D PIF     : [vendor.mali.base_protected_tls_max] -> 67108864
1706439817.818 10148 18531 18543 D PIF     : [vendor.mali.base_protected_max_core_count] -> 1
1706439817.818 10148 18531 18543 D PIF     : [vendor.mali.platform_agt_frequency_khz] -> 24576
1706439817.820 10148 18531 18543 D PIF     : [ro.surface_flinger.has_wide_color_display] -> true
1706439817.820 10148 18531 18543 D PIF     : [ro.surface_flinger.has_HDR_display] -> true
1706439817.820 10148 18531 18543 D PIF     : [ro.vndk.version] -> 34
1706439817.828 10148 18531 18543 D PIF     : [ro.egl.blobcache.multifile] -> true
1706439817.828 10148 18531 18543 D PIF     : [ro.egl.blobcache.multifile_limit] -> 33554432
1706439817.856 10148 18531 18543 D PIF     : [ro.build.version.security_patch] -> 2017-03-05
1706439817.857 10148 18531 18543 D PIF     : [ro.zygote] -> zygote64
1706439817.858 10148 18531 18543 D PIF     : [ro.vendor.api_level] -> 25
My fingerprint was:
{
  "MANUFACTURER": "asus",
  "MODEL": "ASUS_Z010DD",
  "BRAND": "asus",
  "PRODUCT": "WW_Phone",
  "DEVICE": "ASUS_Z010_2",
  "BUILD_ID": "MMB29P",
  "FINGERPRINT": "asus/WW_Phone/ASUS_Z010_2:6.0.1/MMB29P/13.8.26.98-20170502:user/release-keys",
  "SECURITY_PATCH": "2017-03-05",
  "FIRST_API_LEVEL": "25",
  "KERNEL": "5.10.177-android13-4-00003-ga7208022a7ea-ab10815828"
}

Jan 28, 2024

I updated to this on my LOS 20 and I ran PIFS by TheFreeman193 to find a working fingerprint but issue still remain, none of them work, I'll tell you what happen tomorrow when my LOS rom will receive an OTA update

/data/local/tmp/stackplz -n com.google.android.gms -s uname
< hook syscall count:1
uid => whitelist:[10222];blacklist:[]                        pid => whitelist:[8712,9729,11163];blacklist:[]
tid => whitelist:[];blacklist:[]                             start 2 modules
[11163|11396|binder:11163_2] nr:uname(buf=0xb4000072c4bb3898) LR:0x7266607784 PC:0x72666077b8 SP:0x725d4773f0
[11163|11396|binder:11163_2] nr:uname(ret=0x0 => buf=0xb4000072c4bb3898{sysname=Linux, nodename=localhost, release=5.15.94-android13-8-o-00703-gaafa2cb5a21a, version=#1 SMP PREEMPT Fri Dec 29 04:26:23 UTC 2023, machine=aarch64, domainname=localdomain})

The call exists but it isn't done via libc.

Tried to modify kernel to "5.15.110-Sultan" but Device is still passing...

Seems like DG doesn't check uname output...

But a centralized one is arguably easier to block, where all the custom kernels just being their own generic untouched kernel version string would be very difficult for Google to block.

Basically the same argument as all of us using our own fingerprint to decrease the statistical data Google receives to block them by.

Fingerprints are a finite resource, while kernel version strings are infinite. I think it's therefore better to prioritize the ability to determine if a fingerprint is blocked by making a centralized uname spoof, especially since parts of the uname can be randomly generated, whereas fingerprints must be on Google's allowlist.

To this point, Magisk's package name randomization feature hasn't been defeated; I think employing the same tactic on the kernel version string would be quite successful.

If there's some future blanket ban on a centralized kernel version spoof, then it can always be revisited and/or become like fingerprints which need to be customized by the user. But I think that's moreso a last resort and isn't necessary right now.

Actually.....

Some apps can, in fact, still detect the Magisk app when hidden. Just saying.

Tried to modify kernel to "5.15.110-Sultan" but Device is still passing...

It's currently a limited rollout on Google's end afaik

is there evidence of any other kernels with custom strings being blocked?
could this just be google blacklisting terms that could be taken "offensive or racist"? Maybe something like King, Queen, Slave or Master would be blacklisted as well?
Much like google removed the terms of master/slave from all their drivers. Renaming all branches from master to main

They are definitely blocking kernel version strings. "lineageos" in the uname causes device attestation to fail as well, and I've seen others mention that the same occurs with your "kirisakura".

no problems on my end with my kernels on about 10 of my own devices when using fingerprints that pass integrity checks.

If google indeed starts to blacklist kernel strings it gets extremely hard to verify whatΒ΄s actually breaking.
Every change to the prints takes a reboot.
A reboot has sometimes fixed integrity passing on my own end for me, without changing the kernel.

edit:
or the prints employed by the play integrity fix module.

See my comment above, it's not fully rolled out. For example, one of our devices is failing on sultan, and a different device but the same everything else is passing still. Quite a few users however have reported only flashing stock kernel fixes it, and @kerneltoast himself I believe verified slightly altering his kernel name resulted in a pass.

Several of us in the Sultan beta testing group have been renaming our kernel (changing the string in the Image file from the zip, then re-flash), and that does indeed fix device integrity. Everything else is identical, same kernel version we were running before, except changing "Sultan" to some other 6-character word.

/data/local/tmp/stackplz -n com.google.android.gms -s uname
< hook syscall count:1
uid => whitelist:[10222];blacklist:[]                        pid => whitelist:[8712,9729,11163];blacklist:[]
tid => whitelist:[];blacklist:[]                             start 2 modules
[11163|11396|binder:11163_2] nr:uname(buf=0xb4000072c4bb3898) LR:0x7266607784 PC:0x72666077b8 SP:0x725d4773f0
[11163|11396|binder:11163_2] nr:uname(ret=0x0 => buf=0xb4000072c4bb3898{sysname=Linux, nodename=localhost, release=5.15.94-android13-8-o-00703-gaafa2cb5a21a, version=#1 SMP PREEMPT Fri Dec 29 04:26:23 UTC 2023, machine=aarch64, domainname=localdomain})

The call exists but it isn't done via libc.

Tried hooking libbinder.so instead over on my fork, but still with no luck; when I attempt to switch it to e.g. "Google-Sultan" in my json the stackplz output still shows the original kernel uname release string, even though the logcat shows it hooks and switches. Just to be thorough I even tried all the other libbinder*.so files, but with no change in behavior. Not sure what we're missing here. πŸ˜•πŸ€”

osm0sis@8382559

/data/local/tmp/stackplz -n com.google.android.gms -s uname
< hook syscall count:1
uid => whitelist:[10222];blacklist:[]                        pid => whitelist:[8712,9729,11163];blacklist:[]
tid => whitelist:[];blacklist:[]                             start 2 modules
[11163|11396|binder:11163_2] nr:uname(buf=0xb4000072c4bb3898) LR:0x7266607784 PC:0x72666077b8 SP:0x725d4773f0
[11163|11396|binder:11163_2] nr:uname(ret=0x0 => buf=0xb4000072c4bb3898{sysname=Linux, nodename=localhost, release=5.15.94-android13-8-o-00703-gaafa2cb5a21a, version=#1 SMP PREEMPT Fri Dec 29 04:26:23 UTC 2023, machine=aarch64, domainname=localdomain})

The call exists but it isn't done via libc.

Tried hooking libbinder.so instead over on my fork, but still with no luck; when I attempt to switch it to e.g. "Google-Sultan" in my json the stackplz output still shows the original kernel uname release string, even though the logcat shows it hooks and switches. Just to be thorough I even tried all the other libbinder*.so files, but with no change in behavior. Not sure what we're missing here. πŸ˜•πŸ€”

osm0sis@8382559

Our current theory is perhaps GMS is calling the uname binary itself, not a syscall.

Our current theory is perhaps GMS is calling the uname binary itself, not a syscall.

That feels unlikely considering you can see the binder uname call (complete with buf, ret and full struct) in the stackplz output with every attestation... πŸ€”

I've also confirmed that the PID in the stackplz output uname call is that of gms.unstable.

:/data/local/tmp # ./stackplz -n com.google.android.gms -s uname
hook syscall count:1
ConfigMap{stackplz_pid=14222,thread_whitelist=0}
uid => whitelist:[10154];blacklist:[]
pid => whitelist:[2965,3505,8175,13380];blacklist:[]
tid => whitelist:[];blacklist:[]
start 2 modules
[8175|8208|binder:8175_2] uname(buf=0xb4000073cd233ee8) LR:0x72a641d784 PC:0x72a641d7b8 SP:0x721e9cf130
[8175|8208|binder:8175_2] uname(buf=0xb4000073cd233ee8{sysname=Linux, nodename=localhost, release=5.15.110-android14-11-gcc48824eebe8-ab10865596, version=#1 SMP PREEMPT Tue Sep 26 19:57:58 UTC 2023, machine=aarch64, domainname=localdomain}, ret=0)
^C
TotalLost => 0
mod Close
TotalLost => 0
mod Close
:/data/local/tmp # pidof com.google.android.gms
3505
:/data/local/tmp # pidof com.google.android.gms.unstable
8175

Our current theory is perhaps GMS is calling the uname binary itself, not a syscall.

That feels unlikely considering you can see the binder uname call (complete with buf, ret and full struct) in the stackplz output with every attestation... πŸ€”

I've also confirmed that the PID in the stackplz output uname call is that of gms.unstable.

I think binder:11163_2 is just the thread name? Also the function in libc is not actually needed to call uname. It is just a wrapper can implement it itself.

From stackplz:

shiba:/data/local/tmp # ./stackplz -n com.google.android.gms -s uname
hook syscall count:1
uid => whitelist:[10166];blacklist:[]
pid => whitelist:[2864,3261,4819,5770];blacklist:[]
tid => whitelist:[];blacklist:[]
start 2 modules
[2864|2881|Jit thread pool] nr:uname(buf=0x76fb585230) LR:0x770d046ee0 PC:0x79cb744a78 SP:0x76fb585220
[2864|2881|Jit thread pool] nr:uname(ret=0x0 => buf=0x76fb585230{sysname=Linux, nodename=localhost, release=5.15.110-android14-11-gcc48824eebe8-ab10865596, version=#1 SMP PREEMPT Tue Sep 26 19:57:58 UTC 2023, machine=aarch64, domainname=localdomain})

PC is 0x79cb744a78, and when we look at /proc/2864/maps, we see that it resides in one of the libc mappings:

79cb68f000-79cb6d2000 r--p 00000000 07:30 24                             /apex/com.android.runtime/lib64/bionic/libc.so
79cb6d2000-79cb764000 r-xp 00043000 07:30 24                             /apex/com.android.runtime/lib64/bionic/libc.so
79cb764000-79cb768000 r--p 000d5000 07:30 24                             /apex/com.android.runtime/lib64/bionic/libc.so
79cb768000-79cb76a000 rw-p 000d8000 07:30 24                             /apex/com.android.runtime/lib64/bionic/libc.so

Loading libc.so into Ghidra at base address 0x79cb68f000, we see that our PC value of 0x79cb744a78 puts us right here:
image

In libc's uname() function.

From stackplz:

shiba:/data/local/tmp # ./stackplz -n com.google.android.gms -s uname
hook syscall count:1
uid => whitelist:[10166];blacklist:[]
pid => whitelist:[2864,3261,4819,5770];blacklist:[]
tid => whitelist:[];blacklist:[]
start 2 modules
[2864|2881|Jit thread pool] nr:uname(buf=0x76fb585230) LR:0x770d046ee0 PC:0x79cb744a78 SP:0x76fb585220
[2864|2881|Jit thread pool] nr:uname(ret=0x0 => buf=0x76fb585230{sysname=Linux, nodename=localhost, release=5.15.110-android14-11-gcc48824eebe8-ab10865596, version=#1 SMP PREEMPT Tue Sep 26 19:57:58 UTC 2023, machine=aarch64, domainname=localdomain})

PC is 0x79cb744a78, and when we look at /proc/2864/maps, we see that it resides in one of the libc mappings:

79cb68f000-79cb6d2000 r--p 00000000 07:30 24                             /apex/com.android.runtime/lib64/bionic/libc.so
79cb6d2000-79cb764000 r-xp 00043000 07:30 24                             /apex/com.android.runtime/lib64/bionic/libc.so
79cb764000-79cb768000 r--p 000d5000 07:30 24                             /apex/com.android.runtime/lib64/bionic/libc.so
79cb768000-79cb76a000 rw-p 000d8000 07:30 24                             /apex/com.android.runtime/lib64/bionic/libc.so

Loading libc.so into Ghidra at base address 0x79cb68f000, we see that our PC value of 0x79cb744a78 puts us right here: image

In libc's uname() function.
Nice!

So why didn't chit's libc uname hooking version in 15.4 work correctly then? Some other reason? 😯

Tried hooking 'uname' in libc.so, tried non-specific 'uname' hooking with nullptr instead of libc.so (how we hooked '__system_property_read_callback' previously, which should be the same technically), and then tried changing the hook to '__NR_uname' and then 'SYS_uname' with no change, other than with those last 2 direct syscall hook attempts Dobby's symbol resolver failed to find a handle at all. πŸ˜–

Ref: https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/include/bits/glibc-syscalls.h#1345

Tried hooking 'uname' in libc.so, tried non-specific 'uname' hooking with nullptr instead of libc.so (how we hooked '__system_property_read_callback' previously, which should be the same technically), and then tried changing the hook to '__NR_uname' and then 'SYS_uname' with no change, other than with those last 2 direct syscall hook attempts Dobby's symbol resolver failed to find a handle at all. πŸ˜–

Ref: https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/include/bits/glibc-syscalls.h#1345

Will try to dlopen libc using ShadowHook and hook by handle... Maybe it works :o

Tested using ShadowHook and it didn't work :(.

Seems like Google use something more to detect a custom kernel...

libdata.txt

Droidguard lib doesn't have uname symbol...

Very bizarre indeed. I also ran some tests, Dobby & Shadowhook, with their own symbol resolvers or straight dlopen, for every lib in the gms stack trace, even tried fixed memory addresses and nothing works. GMS still sees the original data. Renaming/deleting the uname binary also has no effect, so it's not that. Only left to test /proc/version, but highly unlikely due to how the stack trace shows the utsname struct.
Somehow shadowhook found uname in libdroidguard once, probably some sort of fluke/error though, readelf shows nothing.
Is there anyplace to get the older DG apks? Might be worth to investigate what changed

I've already tried mount-master bind mounting a file over /proc/sys/kernel/osrelease with no effect on the attestation uname result, so yeah I highly doubt the pre-concatenated one in /proc/version will have any effect.

@hldr4, if you haven't wiped GMS data for awhile you'll have a number of older DG the.apk files in here: /data/data/com.google.android.gms/app_dg_cache

I've already tried mount-master bind mounting a file over /proc/sys/kernel/osrelease with no effect on the attestation uname result, so yeah I highly doubt the pre-concatenated one in /proc/version will have any effect.

@hldr4, if you haven't wiped GMS data for awhile you'll have a number of older DG the.apk files in here: /data/data/com.google.android.gms/app_dg_cache

Yea I wiped the data pretty recently, so I only have 3 cached versions, all of which are past Jan. 25. Anyways gonna keep at it, surely someone will find a solution

Yea I wiped the data pretty recently, so I only have 3 cached versions, all of which are past Jan. 25. Anyways gonna keep at it, surely someone will find a solution

I've got:

:/data/data/com.google.android.gms/app_dg_cache # ls -al
total 30
drwxrwx--x 10 u0_a154 u0_a154 3452 2024-01-30 10:37 .
drwx--x--x 37 u0_a154 u0_a154 3452 2024-01-30 01:32 ..
drwx------  4 u0_a154 u0_a154 3452 2023-12-19 08:30 1FF1CAAF27B5C2D89CCDAAC2580B20511F43612A
drwx------  4 u0_a154 u0_a154 3452 2024-01-16 19:31 37FC500541014CED511312DE94C04F404D04E00E
drwx------  4 u0_a154 u0_a154 3452 2024-01-16 09:02 5B980760123E8D4F8398A691301E61F9BC6EB0CF
drwx------  4 u0_a154 u0_a154 3452 2024-01-16 10:37 6D7C2BED07EDD194A1C659B6D25C19C2AC483B0A
drwx------  4 u0_a154 u0_a154 3452 2024-01-16 06:44 9BE10F83DFFDB00C88B68F60B209E79A20D1B3B5
drwx------  4 u0_a154 u0_a154 3452 2024-01-30 10:37 A11D05DF5EBD84F84A3D0BA201BB0E1B8CAD2613
drwx------  4 u0_a154 u0_a154 3452 2024-01-19 00:24 BB978A211C63297BDE4D1A9726C93232415A4CEF
drwx------  4 u0_a154 u0_a154 3452 2024-01-30 06:13 D32468B4E02C50202F8FA7000A34F9BCAAB07877
:/data/data/com.google.android.gms/app_dg_cache #

If you want to dig in to them... 🀞

app_dg_cache.tar.xz.rename-me.gz
(rename to .tar.xz)

Also I tried to hook syscall to check if DroidGuard is calling uname from that but it doesn't.

This is weird...

Also I tried to hook syscall to check if DroidGuard is calling uname from that but it doesn't.

This is weird...

How did you do "hook syscall"?

There being classes in the.apk called DroidGauss, GpuDriverFingerprint and SceneRenderer are probably bad signs for the future of spoofing Play Integrity. GPU driver values can only be gotten from a running device, and if it actually renders an image with them and matches it to one in their database from the real device, maybe impossible to spoof. 😢

wow that will suck a lot

I think we need to decompile DroidGuard lib...

It's very weird how they can detect if your device has custom kernel...

Also, new DG app, has a class "GpuDriverFingerprint" with a method "getDriverFingerprint". Seems like Google wants to add more checks.

Will be this the end of PIF ?

I think we need to decompile DroidGuard lib...

It's very weird how they can detect if your device has custom kernel...

Also, new DG app, has a class "GpuDriverFingerprint" with a method "getDriverFingerprint". Seems like Google wants to add more checks.

Will be this the end of PIF ?

I'd wager they've been building the new GPU fingerprint database for quite a while now. Check my last message. 🫀

Also, new DG app, has a class "GpuDriverFingerprint" with a method "getDriverFingerprint". Seems like Google wants to add more checks.

Will be this the end of PIF ?

I observed this during some initial reverse-engineering of the Java classes from recent DroidGuard VM versions (starting in late December). The actual fingerprint class seems relatively simple. It gets all *.so files in /system/lib/egl and /vendor/lib/egl and adds a string to an array for each, consisting of the name, size, and SHA-1 hash of the first 1 KB. It does the same for the EGL configuration from /system/lib/egl/egl.cfg.

GpuDriverFingerprint

The droidguasso class was more intriguing. It has the capacity for full 2D EGL (Khronos libraries) rendering. It sets up two scene renderers:

scene renderer setup

And, when requested, renders them with vertex colours passed in from outside:

droidguasso render()

image

sceneRenderer render()

image

The call comes from g() of the main DroidGuard class which, in turn, gets the vertex colour values from l():

image

There are no calls to l() I can find from within the DG VM itself, so I suspect the seed for these comes from the bytecode downloaded from the server per integrity request. Ingenious - because the server can select some seed values for the renderer based on device information provided in the protobuf request, and when the integrity results are sent back to the server it knows what it should expect if that device is what it claims to be.

I reckon all the extra functionality that exists in the DroidGuard VM (including the above) is mostly for hardware evaluation verdicts and won't be used to determine DEVICE_INTEGRITY verdicts from software/"basic" evaluation. I think the bigger threat long term is the gradual enforcement of hardware evaluation which will truly be the end of device modding while remaining a part of the Google services ecosystem.

As there don't seem to be uname references in the VM, I'm guessing they also originate in the bytecode.

@TheFreeman193, correct me if I'm wrong, but I believe you also tried hooking the uname calls for all of com.google.android.gms in your recent uname test fork. That didn't work either though, unfortunately. πŸ€”

@TheFreeman193, correct me if I'm wrong, but I believe you also tried hooking the uname calls for all of com.google.android.gms in your recent uname test fork. That didn't work either though, unfortunately. πŸ€”

Correct - there are definitely libc uname calls from the GMS parent and .persistent processes but they don't seem to be where DG is getting the value from.

There being classes in the.apk called DroidGauss, GpuDriverFingerprint and SceneRenderer are probably bad signs for the future of spoofing Play Integrity. GPU driver values can only be gotten from a running device, and if it actually renders an image with them and matches it to one in their database from the real device, maybe impossible to spoof. 😢

It honestly fits. We've suspected for a while that their ability to ban the fingerprints came from on device telemetry, not some secret Google agent monitoring GitHub.

My guess is once a bunch of devices with a fingerprint (fingerprint in the sense of what this module supports) that doesn't fall within the bounds of their fingerprinting (using GPU and who knows what else), it gets automatically banned. I also doubt we've found all the ways they've been fingerprinting our devices so far.

This ain't SafetyNet days anymore. Play Integrity isn't going to be half assed, and we're probably always going to be reacting to their changes.

Sounds similar to canvas fingerprint which is widely used in web development. https://browserleaks.com/canvas

I think the main purpose is to detect emulator tho.

Current known list of banned strings I've found through semi-automated testing this evening: https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89308909

Current known list of banned strings I've found through semi-automated testing this evening: https://xdaforums.com/t/module-play-integrity-fix-safetynet-fix.4607985/post-89308909

If I did not mess up my setup, I think they did more than blacklisting kernel strings.

I have 2 identical devices, one is rooted with stock rom (Device A), and the other one is rooted with lineage nightly rom (Device B). I tried to check the integrity of both devices using Play Store and Device A passed MEETS_DEVICE_INTEGRITY, while Device B failed to pass MEETS_DEVICE_INTEGRITY.

The uname -r result of Device A is 4.4.153-perf+ while the result of Device B is 4.4.302-perf+. Note that the kernel string of Device B does not contain any banned strings and looks quite similar to the original kernel of Device A, but still failed to pass MEETS_DEVICE_INTEGRITY.

For additional info, I use Device A's fingerprint as the custom fingerprint for Device B (since the fingerprint is confirmed to be working as per Device A's integrity result). However, when checking the integrity of Device B, Play Store still reported the original fingerprint of Device B instead of Device A's fingerprint.

I only mentioned it in the Telegram group but I shall mention here that I'm on a LineageOS image for Samsung Galaxy S8 that has the following output for uname -a:

Linux localhost 4.4.302-g051e3314 #1 SMP PREEMPT Sat Oct 7 14:21:40 UTC 2023 aarch64 Toybox

None of the banned strings are contained in this but I haven't had any fingerprint work on this one anymore. Are we sure they only banned certain words? Maybe they went the other way round and whitelisted only certain strings instead.

kxxt commented

Strace shows that the uname call is issued by pid 4877<Jit thread pool> and pid 4882<binder:4845_1>. Looking at the logs generated by strace, it seems that binder:4845_1 thread does all the information collection work for droidguard.

Also, new DG app, has a class "GpuDriverFingerprint" with a method "getDriverFingerprint". Seems like Google wants to add more checks.

DroidGuard reads the first 1024 bytes of some elf files like /vendor/lib/egl/libq3dtools_adreno.so and /vendor/lib/egl/eglSubDriverAndroid.so. The first 64 bytes of some elf files(which should be the elf header on 64-bit platforms) are also checked, like /apex/com.android.vndk.v33/lib64/libhidlmemory.so and /vendor/lib64/vendor.qti.hardware.display.mapper@2.0.so It also issues some ioctl calls to /dev/kgsl-3d0 which I don't understand. I guess they are GPU driver checks.

It also checks /proc/self/{mountinfo,mounts,stat,cmdline,status}, which detects ptrace. To strace it without being noticed, I forced TracerPid to be zero in the kernel.

The strace log is attached here for further analysis:
unstable.trace.log

DroidGuard reads the first 1024 bytes of some elf files like /vendor/lib/egl/libq3dtools_adreno.so and /vendor/lib/egl/eglSubDriverAndroid.so.

@kxxt This aligns with some of the code I pulled from the DroidGuard VM (see here). As @aviraxp pointed out, checking GPU drivers and performing actual rendering is a great way to prove there's a real device with a real GPU on the client side, so can detect emulators and devices that aren't what they claim to be.

perhaps google has started matching kernel names and fingerprints and that's how they are failing fingerprints.

I am using my custom kernel with own kernel string name. Still works wonders.

I only mentioned it in the Telegram group but I shall mention here that I'm on a LineageOS image for Samsung Galaxy S8 that has the following output for uname -a:

Linux localhost 4.4.302-g051e3314 #1 SMP PREEMPT Sat Oct 7 14:21:40 UTC 2023 aarch64 Toybox

None of the banned strings are contained in this but I haven't had any fingerprint work on this one anymore. Are we sure they only banned certain words? Maybe they went the other way round and whitelisted only certain strings instead.

If I did not mess up my setup, I think they did more than blacklisting kernel strings.

I have 2 identical devices, one is rooted with stock rom (Device A), and the other one is rooted with lineage nightly rom (Device B). I tried to check the integrity of both devices using Play Store and Device A passed MEETS_DEVICE_INTEGRITY, while Device B failed to pass MEETS_DEVICE_INTEGRITY.

The uname -r result of Device A is 4.4.153-perf+ while the result of Device B is 4.4.302-perf+. Note that the kernel string of Device B does not contain any banned strings and looks quite similar to the original kernel of Device A, but still failed to pass MEETS_DEVICE_INTEGRITY.

For additional info, I use Device A's fingerprint as the custom fingerprint for Device B (since the fingerprint is confirmed to be working as per Device A's integrity result). However, when checking the integrity of Device B, Play Store still reported the original fingerprint of Device B instead of Device A's fingerprint.

One Plus 5 with LineageOS 20
Kernel string

    Device Kernel:                   Linux localhost 4.4.302-perf+ #1 SMP PREEMPT Mon Jan 8 07:38:35 UTC 2024 aarch64 Toybox

@drionix Same as yours (the relevant part), passes Device integrity, your issue must be somewhere else.

It's time to file a class action lawsuit against Google

It's time to file a class action lawsuit against Google

While frustrations with Google's Play Services are understandable, it's essential to recognize that Play Services are offered by Google and not inherent to the AOSP source code. Legal grounds for a lawsuit may be limited if a service provider chooses not to offer their services.

While frustrations with Google's Play Services are understandable, it's essential to recognize that Play Services are offered by Google and not inherent to the AOSP source code. Legal grounds for a lawsuit may be limited if a service provider chooses not to offer their services.

Essentially, this is an abuse of the monopoly on the Android market. there is no full-fledged replacement for Google services - they are simply not licensed or subject to American sanctions (say hello to Huawei Mobile Services).

Device Integrity was failing before ln my device ( NP2 ) with arter's kernel
This change has fixed that.

arter97/android_kernel_nothing_sm8475@8861034

and adding this to configs:

CONFIG_UNAME_OVERRIDE=y
CONFIG_UNAME_OVERRIDE_TARGET="com.google.android.gms"
CONFIG_UNAME_OVERRIDE_STRING="5.10.177-android12-9-00001-g25f6aed0b75f-ab10758107"

Thanks to @markfm62 for all of his research.

@osm0sis, when you do take a look about this kernel (uname -r ==> 4.19.224-g3c01f924b7c4 / uname -a ==> Linux localhost 4.19.224-g3c01f924b7c4), would you post back & lemme know if you believe, in deed, my/this LineageOS kernel is specifically google-banned?

I'd like to keep the LineageOS for this phone, but if you let me know what you think about this kernel's specifically being banned then, of course, I'll start over with a factory image...

Thanks in advance...

Let's try to keep the "Hey, is this string also banned?" questions out of this issue thread and on xda (where my list post is) instead, so that the focus here can properly remain on trying to work around it on PIF's side.

But anyway, no, g3c01f924b7c4 is not banned in my testing. so you likely have something else wrong with your setup.

If you have follow-up questions or comments about that please direct them to xda.

Certainly, no problem, not really on here before, and appreciate all you folks are doin' to keep us "free".

And, despite being the wrong place, thanks for lettin' me know the kernel's likely not the problem. So, since I've only tried about 20 custom pifs so far, I'm gonna hope the problem is that I just haven't tried enough, and try a bunch more.

Plus, if there there's anything you need or if I can help/contribute move the projects forward, don't hesitate.

I only mentioned it in the Telegram group but I shall mention here that I'm on a LineageOS image for Samsung Galaxy S8 that has the following output for uname -a:

Linux localhost 4.4.302-g051e3314 #1 SMP PREEMPT Sat Oct 7 14:21:40 UTC 2023 aarch64 Toybox

None of the banned strings are contained in this but I haven't had any fingerprint work on this one anymore. Are we sure they only banned certain words? Maybe they went the other way round and whitelisted only certain strings instead.

If I did not mess up my setup, I think they did more than blacklisting kernel strings.
I have 2 identical devices, one is rooted with stock rom (Device A), and the other one is rooted with lineage nightly rom (Device B). I tried to check the integrity of both devices using Play Store and Device A passed MEETS_DEVICE_INTEGRITY, while Device B failed to pass MEETS_DEVICE_INTEGRITY.
The uname -r result of Device A is 4.4.153-perf+ while the result of Device B is 4.4.302-perf+. Note that the kernel string of Device B does not contain any banned strings and looks quite similar to the original kernel of Device A, but still failed to pass MEETS_DEVICE_INTEGRITY.
For additional info, I use Device A's fingerprint as the custom fingerprint for Device B (since the fingerprint is confirmed to be working as per Device A's integrity result). However, when checking the integrity of Device B, Play Store still reported the original fingerprint of Device B instead of Device A's fingerprint.

One Plus 5 with LineageOS 20 Kernel string

    Device Kernel:                   Linux localhost 4.4.302-perf+ #1 SMP PREEMPT Mon Jan 8 07:38:35 UTC 2024 aarch64 Toybox

@drionix Same as yours (the relevant part), passes Device integrity, your issue must be somewhere else.

After reading this, I tried using @TheFreeman193's pickaprint.sh on Device B. After shuffling around 5 times, i finally found a print that could pass MEETS_DEVICE_INTEGRITY on Device B.

The weird part is, as I mentioned before, Device A is identical to Device B, with the difference being only Device A is using stock rom, while Device B is using lineage nightly rom (but the kernel string of both devices are still quite similar as mentioned above). While Device A could pass MEETS_DEVICE_INTEGRITY, setting Device A's print on Device B would not cause Device B to pass MEETS_DEVICE_INTEGRITY.

I still think that Google did more than merely blacklisting kernel strings.

...
I still think that Google did more than merely blacklisting kernel strings.

Yes, they also clearly banned a bunch of prints, and likely A-B test DroidGuard changes on us so different devices don't behave exactly the same. Take your generic troubleshooting to xda.

And read my FAQ, but specifically # 5: https://xdaforums.com/t/pif-faq.4653307/#post-89302976

I wanted to pass this along in case it's could be of use. I have been working with folks here for ideas on getting new my phone IntegrityCheck "cleared".

Thanks to helpful suggestions from @markfm62 & very useful info from @osm0sis, I was able to perform some careful experimentation (& a bunch of good luck), and appears I've discovered that chiteroman's very own LSPosed mod, BootloaderSpoofer v3.8 will just not clear Integrity Check. But his v1.2 clears Play Integrity Check with flying colors! (of course except "STRONG", since as I understand it, nothing clears that) and v1.2 still appears to successfully spoof the bootloader, at least according to the "Key Attestation" app. Maybe a comparison of v1.2 vs v3.8 code might uncover something in some way.

Anyway, it's my hope if this turns out useful, in some way, toward the hard work that folks are putting forth, and of course particularly @chiteroman & @osm0sis, in keeping us & our devices "free".

(In case it's needed: this was done on a Pixel 5; loaded with LineageOS 19.1 (2022-12-28 which is a12.1; and a known valid fingerprint file)

I have "KERNEL": "Goolag-perf" on my pixel fold and it's working fine (android 14 beta)

"BRAND": "google",
"BUILD_ID": "AP11.231215.009",
"DEVICE": "felix",
"FINGERPRINT": "google/felix_beta/felix:14/AP11.231215.009/11331907:user/release-keys",
"FIRST_API_LEVEL": "33",
"FORCE_BASIC_ATTESTATION": "true",
"ID": "AP11.231215.009",
"KERNEL": "Goolag-perf",
"MANUFACTURER": "Google",
"MODEL": "Pixel Fold",
"PRODUCT": "felix_beta",
"SECURITY_PATCH": "2024-01-05",
"VNDK_VERSION": "35"

I have "KERNEL": "Goolag-perf" on my pixel fold and it's working fine (android 14 beta)

"BRAND": "google",
"BUILD_ID": "AP11.231215.009",
"DEVICE": "felix",
"FINGERPRINT": "google/felix_beta/felix:14/AP11.231215.009/11331907:user/release-keys",
"FIRST_API_LEVEL": "33",
"FORCE_BASIC_ATTESTATION": "true",
"ID": "AP11.231215.009",
"KERNEL": "Goolag-perf",
"MANUFACTURER": "Google",
"MODEL": "Pixel Fold",
"PRODUCT": "felix_beta",
"SECURITY_PATCH": "2024-01-05",
"VNDK_VERSION": "35"

That's because it's doing nothing and your device didn't need it. Please stop with the OT, non-technical people.

Device Integrity was failing before ln my device ( NP2 ) with arter's kernel This change has fixed that.

arter97/android_kernel_nothing_sm8475@8861034

and adding this to configs:

CONFIG_UNAME_OVERRIDE=y
CONFIG_UNAME_OVERRIDE_TARGET="com.google.android.gms"
CONFIG_UNAME_OVERRIDE_STRING="5.10.177-android12-9-00001-g25f6aed0b75f-ab10758107"

Nice work @arter97!

I think @arter97 and any dev using this patch to try to have their cake and eat it too would still want to try to target specifically com.google.android.gms.unstable instead of all of gms, by the way. πŸ‘

Device Integrity was failing before ln my device ( NP2 ) with arter's kernel This change has fixed that.

arter97/android_kernel_nothing_sm8475@8861034

and adding this to configs:

CONFIG_UNAME_OVERRIDE=y
CONFIG_UNAME_OVERRIDE_TARGET="com.google.android.gms"
CONFIG_UNAME_OVERRIDE_STRING="5.10.177-android12-9-00001-g25f6aed0b75f-ab10758107"

Nice work @arter97!

I think @arter97 and any dev using this patch to try to have their cake and eat it too would still want to try to target specifically com.google.android.gms.unstable instead of all of gms, by the way. πŸ‘

Still requires work from kernel devs, which is far from certain to happen.

Surely there's a way to emulate what those patches do, in userspace?

Device Integrity was failing before ln my device ( NP2 ) with arter's kernel This change has fixed that.

arter97/android_kernel_nothing_sm8475@8861034

and adding this to configs:

CONFIG_UNAME_OVERRIDE=y
CONFIG_UNAME_OVERRIDE_TARGET="com.google.android.gms"
CONFIG_UNAME_OVERRIDE_STRING="5.10.177-android12-9-00001-g25f6aed0b75f-ab10758107"

This doesn't seem like a wise approach as it targets all process with "com.google.android.gms" cmdline...

Uhh, I modified in source code the kernel version string to match stock one.

I get a perfect SafetyNet attestation, basicIntegrity and CTS pass, BASIC and HARDWARE_BACKED pass.
But in Play Integrity I only have BASIC verdict, Device and Strong not passing.

I used @osm0sis AnyKernel3 to patch stock boot.img, only Image, dtb and dtbo are original (stock).

Seems like DroidGuard detects something more...

This doesn't seem like a wise approach as it targets all process with "com.google.android.gms" cmdline...

What about this ?

#define MOD_KERNEL_RELEASE "4.14.180-perf-g2c687cdb9430"

static void override_custom_release(char __user *release, size_t len)
{
	char *buf;

	buf = kstrdup_quotable_cmdline(current, GFP_KERNEL);
	if (buf == NULL)
		return;

	if (strncmp(buf, "com.google.android.gms", 22) == 0) {
		copy_to_user(release, MOD_KERNEL_RELEASE, strlen(MOD_KERNEL_RELEASE) + 1);
	}

	kfree(buf);
}

This doesn't seem like a wise approach as it targets all process with "com.google.android.gms" cmdline...

What about this ?

#define MOD_KERNEL_RELEASE "4.14.180-perf-g2c687cdb9430"

static void override_custom_release(char __user *release, size_t len)
{
	char *buf;

	buf = kstrdup_quotable_cmdline(current, GFP_KERNEL);
	if (buf == NULL)
		return;

	if (strncmp(buf, "com.google.android.gms", 22) == 0) {
		copy_to_user(release, MOD_KERNEL_RELEASE, strlen(MOD_KERNEL_RELEASE) + 1);
	}

	kfree(buf);
}

I don't think so

Device Integrity was failing before ln my device ( NP2 ) with arter's kernel This change has fixed that.
arter97/android_kernel_nothing_sm8475@8861034
and adding this to configs:

CONFIG_UNAME_OVERRIDE=y
CONFIG_UNAME_OVERRIDE_TARGET="com.google.android.gms"
CONFIG_UNAME_OVERRIDE_STRING="5.10.177-android12-9-00001-g25f6aed0b75f-ab10758107"

This doesn't seem like a wise approach as it targets all process with "com.google.android.gms" cmdline...

Is there a good reason not to?

I frankly don't care, I just want the original uname to show on all places that I can see (e.g., adb shell, terminal apps, Settings app).

This is a very cold path and micro-optimization here doesn't matter.
(If it did, I'd avoid kfree.)

This doesn't seem like a wise approach as it targets all process with "com.google.android.gms" cmdline...

Is there a good reason not to?

I frankly don't care, I just want the original uname to show on all places that I can see (e.g., adb shell, terminal apps, Settings app).

This is a very cold path and micro-optimization here doesn't matter. (If it did, I'd avoid kfree.)

If it works with only .unstable you should probably isolate the spoof to that, since doing all of .gms has potential for other side effects.

Is there a good reason not to?

I frankly don't care, I just want the original uname to show on all places that I can see (e.g., adb shell, terminal apps, Settings app).

This is a very cold path and micro-optimization here doesn't matter. (If it did, I'd avoid kfree.)

Because it will introduce another detection. Example, third-party apps can open another process with com.google.android.gms cmdline and compare two uname outputs together. If two uname outputs are not same, it will be detected that you are running custom kernel.
How about override uname for all processes that are not root or shell?

This doesn't seem like a wise approach as it targets all process with "com.google.android.gms" cmdline...

Is there a good reason not to?
I frankly don't care, I just want the original uname to show on all places that I can see (e.g., adb shell, terminal apps, Settings app).
This is a very cold path and micro-optimization here doesn't matter. (If it did, I'd avoid kfree.)

If it works with only .unstable you should probably isolate the spoof to that, since doing all of .gms has potential for other side effects.

The only potential side effect that I can see is that non-SafetyNet GMS components would be seeing untrue kernel version string, which I don't see any problem with.

(If you're spoofing a v5.10 kernel with a v5.15 string or something like that, that may cause trouble but it's up to the individual kernel developers to spoof with appropriate version string, just like the /proc/config.gz spoofing by @kerneltoast )

As I said, this is a very cold path and being overly conservative (as in, spoofing more than what would be absolutely necessary) is fine.

That said, if any kernel developers want to take this further (which I see no point in doing so), be my guest.

Is there a good reason not to?
I frankly don't care, I just want the original uname to show on all places that I can see (e.g., adb shell, terminal apps, Settings app).
This is a very cold path and micro-optimization here doesn't matter. (If it did, I'd avoid kfree.)

Because it will introduce another detection. Example, third-party apps can open another process with com.google.android.gms cmdline and compare two uname outputs together. If two uname outputs are not same, it will be detected that you are running custom kernel. How about override uname for all processes that are not root or shell?

You're talking about a hypothetical detection that did not exist before Google rolled this out, and very likely will not ever exist.

If Google or other 3rd party with root detection solution want to play cat-and-mouse game with uname, this would be a waste of all of our time and kernel developers can simply just spoof version during build with no runtime spoofing like my commit.

As I said, the primary reason I made this commit was to see real, proper kernel strings on all possible places where applicable. I personally use a lot of both root and non-root terminal apps and seeing spoofed uname output there would be confusing.

I see no point in advancing this further to "future-proof" other possible uname detections. Let's focus our time in doing other relevant stuff in kernel ricing and worry about this later in a very unlikely future when it actually becomes a problem.

Even then, userspace modules can very easily hide this without kernel's help altogether with syscall hijacking.

Okay so presuming everyone here tried everything possible to get a proper hook and spoof on libc's uname, which stackplz showed as being called, the only thing I can imagine for why our hook attempts didn't work is this...

DroidGuard might have its own uname wrapper that does both a uname libc call and a direct uname syscall, then if they differ only returns the direct uname syscall struct, which is why we never saw any change to the uname output in stackplz during any of our hooking/spoofing attempts here.

Possible? Maybe? πŸ˜•πŸ€·β€β™‚οΈ

Oh, I thought Android userspace wizards had it figured out.

Is system-call hijacking not working on Android these days?

On Glibc and x86, I used something like this: https://github.com/pmem/syscall_intercept

Oh, I thought Android userspace wizards had it figured out.

Is system-call hijacking not working on Android these days?

On Glibc and x86, I used something like this: https://github.com/pmem/syscall_intercept

Not yet! A lot of people in this thread tried a lot of things, but still with no change in the utsname struct returned by the .gms.unstable libc uname call visible in the stackplz output. We're a bit stumped I'd say!

Found "magic" fingerprint to avoid kernel detection.

Using stock fingerprint (vayu) seems like DroidGuard doesn't like a patched boot.img by Magisk or with custom kernel, I don' t know how it's possible it can detect it...

Now I'm passing Strong again πŸŽ‰

Found "magic" fingerprint to avoid kernel detection.

Using stock fingerprint (vayu) seems like DroidGuard doesn't like a patched boot.img by Magisk or with custom kernel, I don' t know how it's possible it can detect it...

Now I'm passing Strong again πŸŽ‰

Your whole hacked Strong thing is very different from what's going on here for everyone else. 😜

Found "magic" fingerprint to avoid kernel detection.

Using stock fingerprint (vayu) seems like DroidGuard doesn't like a patched boot.img by Magisk or with custom kernel, I don' t know how it's possible it can detect it...

Now I'm passing Strong again πŸŽ‰

Careful, we don't need another news story about how strong has been hacked 😁

Revert the spoof in v15.5

Not sure if it's related to the revert. But the release today is working for me Pixel 7 pro stock image rooted December 23 with Magisk 26405 + LSPosed

Not sure if it's related to the revert. But the release today is working for me Pixel 7 pro stock image rooted December 23 with Magisk 26405 + LSPosed

He added the latest Xiaomi.eu fingerprint back into the zip. πŸ™„

you all trying multiple stuff, but did anyone try making a dublicate uname binary which provide perf LOCALVERSION but other stuff correctly

uname is symlinked to system toybox
why not just mod that shit xD

you all trying multiple stuff, but did anyone try making a dublicate uname binary which provide perf LOCALVERSION but other stuff correctly

uname is symlinked to system toybox why not just mod that shit xD

I think we eliminated that possibility above, fyi.