Better code

This commit is contained in:
chiteroman 2023-11-22 00:32:52 +01:00
parent 066fa9b85f
commit f1f271b744
No known key found for this signature in database
GPG Key ID: 15FF53015D426D8E
12 changed files with 103 additions and 24790 deletions

View File

@ -28,7 +28,8 @@ android {
externalNativeBuild {
cmake {
arguments += setOf("-DANDROID_STL=none", "-DCMAKE_BUILD_TYPE=MinSizeRel")
cppFlags += setOf("-std=c++20", "-fno-exceptions", "-fno-rtti", "-fvisibility=hidden", "-fvisibility-inlines-hidden")
cFlags += setOf("-flto=full", "-fvisibility=hidden", "-fvisibility-inlines-hidden", "-ffunction-sections", "-fdata-sections")
cppFlags += setOf("-std=c++20", "-fno-exceptions", "-fno-rtti", "-flto=full", "-fvisibility=hidden", "-fvisibility-inlines-hidden", "-ffunction-sections", "-fdata-sections")
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -3,12 +3,11 @@
#include <unistd.h>
#include <string>
#include <vector>
#include <map>
#include <filesystem>
#include <fstream>
#include "zygisk.hpp"
#include "dobby.h"
#include "json.hpp"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "PIF/Native", __VA_ARGS__)
@ -18,15 +17,19 @@ static std::string SECURITY_PATCH;
#define DEX_FILE_PATH "/data/adb/modules/playintegrityfix/classes.dex"
#define JSON_FILE_PATH "/data/adb/modules/playintegrityfix/pif.json"
#define PROP_FILE_PATH "/data/adb/modules/playintegrityfix/pif.prop"
#define MAX_LINE_LENGTH 256
typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
static volatile T_Callback propCallback = nullptr;
static std::map<void *, T_Callback> callbacks;
static void modify_callback(void *cookie, const char *name, const char *value, uint32_t serial) {
if (cookie == nullptr || name == nullptr || value == nullptr || propCallback == nullptr) return;
if (cookie == nullptr || name == nullptr || value == nullptr ||
!callbacks.contains(cookie))
return;
std::string_view prop(name);
@ -35,7 +38,7 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
if (!prop.starts_with("cache") && !prop.starts_with("debug")) LOGD("[%s] -> %s", name, value);
return propCallback(cookie, name, value, serial);
return callbacks[cookie](cookie, name, value, serial);
}
static void (*o_system_property_read_callback)(const prop_info *, T_Callback, void *);
@ -46,23 +49,56 @@ my_system_property_read_callback(const prop_info *pi, T_Callback callback, void
if (pi == nullptr || callback == nullptr || cookie == nullptr) {
return o_system_property_read_callback(pi, callback, cookie);
}
propCallback = callback;
callbacks[cookie] = callback;
return o_system_property_read_callback(pi, modify_callback, cookie);
}
static void doHook() {
std::ifstream ifs("/data/data/com.google.android.gms/pif.json");
static void parsePropsFile(const char *filename) {
LOGD("Proceed to parse '%s' file", filename);
auto json = nlohmann::json::parse(ifs, nullptr, false);
FILE *file = fopen(filename, "r");
ifs.close();
char line[MAX_LINE_LENGTH];
LOGD("Loaded %d keys from pif.json", static_cast<int>(json.size()));
while (fgets(line, sizeof(line), file) != nullptr) {
API_LEVEL = json["API_LEVEL"].get<std::string>();
SECURITY_PATCH = json["SECURITY_PATCH"].get<std::string>();
std::string key, value;
json.clear();
char *data = strtok(line, "=");
while (data) {
if (key.empty()) {
key = data;
} else {
value = data;
}
data = strtok(nullptr, "=");
}
key.erase(std::remove_if(key.begin(), key.end(),
[](unsigned char x) { return std::isspace(x); }), key.end());
value.erase(std::remove_if(value.begin(), value.end(),
[](unsigned char x) { return std::isspace(x); }), value.end());
if (key == "SECURITY_PATCH") {
SECURITY_PATCH = value;
LOGD("Set SECURITY_PATCH to '%s'", value.c_str());
} else if (key == "API_LEVEL") {
API_LEVEL = value;
LOGD("Set API_LEVEL to '%s'", value.c_str());
}
key.clear();
value.clear();
key.shrink_to_fit();
key.shrink_to_fit();
}
fclose(file);
}
static void doHook(const std::string &str) {
parsePropsFile(str.c_str());
void *handle = DobbySymbolResolver("libc.so", "__system_property_read_callback");
if (handle == nullptr) {
@ -95,19 +131,24 @@ public:
if (isGmsUnstable) {
callbacks.clear();
API_LEVEL.clear();
SECURITY_PATCH.clear();
API_LEVEL.shrink_to_fit();
SECURITY_PATCH.shrink_to_fit();
int fd = api->connectCompanion();
auto rawDir = env->GetStringUTFChars(args->app_data_dir, nullptr);
std::string dir(rawDir);
propsFile = rawDir;
env->ReleaseStringUTFChars(args->app_data_dir, rawDir);
int strSize = static_cast<int>(dir.size());
propsFile = propsFile + "/pif.prop";
int strSize = static_cast<int>(propsFile.size());
write(fd, &strSize, sizeof(strSize));
write(fd, dir.data(), strSize);
dir.clear();
dir.shrink_to_fit();
write(fd, propsFile.data(), strSize);
long size;
read(fd, &size, sizeof(size));
@ -128,9 +169,15 @@ public:
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
if (!isGmsUnstable) return;
doHook();
doHook(propsFile);
if (!moduleDex.empty()) injectDex();
LOGD("clean");
propsFile.clear();
propsFile.shrink_to_fit();
moduleDex.clear();
moduleDex.shrink_to_fit();
}
void preServerSpecialize(zygisk::ServerSpecializeArgs *args) override {
@ -141,6 +188,7 @@ private:
zygisk::Api *api = nullptr;
JNIEnv *env = nullptr;
bool isGmsUnstable = false;
std::string propsFile;
std::vector<char> moduleDex;
void injectDex() {
@ -170,10 +218,6 @@ private:
auto entryClass = (jclass) entryClassObj;
auto entryInit = env->GetStaticMethodID(entryClass, "init", "()V");
env->CallStaticVoidMethod(entryClass, entryInit);
LOGD("clean");
moduleDex.clear();
moduleDex.shrink_to_fit();
}
};
@ -181,28 +225,30 @@ static void companion(int fd) {
int strSize;
read(fd, &strSize, sizeof(strSize));
std::string file;
std::string propsFile;
file.resize(strSize);
read(fd, file.data(), strSize);
propsFile.resize(strSize);
read(fd, propsFile.data(), strSize);
file = file + "/pif.json";
LOGD("Json path: %s", file.c_str());
std::filesystem::copy_file(JSON_FILE_PATH, file,
std::filesystem::copy_file(PROP_FILE_PATH, propsFile,
std::filesystem::copy_options::overwrite_existing);
std::filesystem::permissions(file, std::filesystem::perms::all);
std::filesystem::permissions(propsFile, std::filesystem::perms::others_all);
std::ifstream dex(DEX_FILE_PATH, std::ifstream::binary | std::ifstream::ate);
propsFile.clear();
propsFile.shrink_to_fit();
long size = dex.tellg();
dex.seekg(std::ifstream::beg);
FILE *dex = fopen(DEX_FILE_PATH, "rb");
fseek(dex, 0, SEEK_END);
long size = ftell(dex);
fseek(dex, 0, SEEK_SET);
char buffer[size];
dex.read(buffer, size);
fread(buffer, 1, size, dex);
dex.close();
fclose(dex);
buffer[size] = '\0';
write(fd, &size, sizeof(size));
write(fd, buffer, size);

View File

@ -1,43 +1,34 @@
package es.chiteroman.playintegrityfix;
import android.os.Build;
import android.util.JsonReader;
import android.util.Log;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Field;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.KeyStoreSpi;
import java.security.Provider;
import java.security.Security;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public final class EntryPoint {
private static final Map<String, String> map = new HashMap<>();
private static final File file = new File("/data/data/com.google.android.gms/pif.json");
private static final Properties props = new Properties();
private static final File file = new File("/data/data/com.google.android.gms/pif.prop");
public static void init() {
try (JsonReader reader = new JsonReader(new FileReader(file))) {
reader.beginObject();
while (reader.hasNext()) {
String field = reader.nextName();
String value = reader.nextString();
map.put(field, value);
}
reader.endObject();
try (Reader reader = new FileReader(file)) {
props.load(reader);
} catch (IOException e) {
LOG("Couldn't load pif.json: " + e);
LOG("Couldn't load pif.prop file!");
return;
}
LOG("Loaded " + map.size() + " fields!");
LOG("Loaded " + props.size() + " fields!");
spoofDevice();
spoofProvider();
@ -71,13 +62,13 @@ public final class EntryPoint {
}
public static void spoofDevice() {
setProp("PRODUCT", map.get("PRODUCT"));
setProp("DEVICE", map.get("DEVICE"));
setProp("MANUFACTURER", map.get("MANUFACTURER"));
setProp("BRAND", map.get("BRAND"));
setProp("MODEL", map.get("MODEL"));
setProp("FINGERPRINT", map.get("FINGERPRINT"));
setVersionProp("SECURITY_PATCH", map.get("SECURITY_PATCH"));
setProp("PRODUCT", props.getProperty("PRODUCT"));
setProp("DEVICE", props.getProperty("DEVICE"));
setProp("MANUFACTURER", props.getProperty("MANUFACTURER"));
setProp("BRAND", props.getProperty("BRAND"));
setProp("MODEL", props.getProperty("MODEL"));
setProp("FINGERPRINT", props.getProperty("FINGERPRINT"));
setVersionProp("SECURITY_PATCH", props.getProperty("SECURITY_PATCH"));
}
private static void setProp(String name, String value) {

View File

@ -1,33 +0,0 @@
#!/sbin/sh
#################
# Initialization
#################
umask 022
# echo before loading util_functions
ui_print() { echo "$1"; }
require_new_magisk() {
ui_print "*******************************"
ui_print " Please install Magisk v20.4+! "
ui_print "*******************************"
exit 1
}
#########################
# Load util_functions.sh
#########################
OUTFD=$2
ZIPFILE=$3
mount /data 2>/dev/null
[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
. /data/adb/magisk/util_functions.sh
[ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk
install_module
exit 0

View File

@ -1 +0,0 @@
#MAGISK

View File

@ -1,10 +0,0 @@
# Android < 8.0
if [ "$API" -lt 26 ]; then
abort "!!! You can't use this module on Android < 8.0"
fi
# Check if safetynet-fix is installed
if [ -d "/data/adb/modules/safetynet-fix" ]; then
ui_print "! safetynet-fix module will be removed"
touch "/data/adb/modules/safetynet-fix/remove"
fi

View File

@ -1,7 +0,0 @@
id=playintegrityfix
name=Play Integrity Fix
version=v13.2
versionCode=132
author=chiteroman
description=Fix CTS profile (SafetyNet) and DEVICE verdict (Play Integrity).
updateJson=https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/update.json

View File

@ -1,7 +0,0 @@
PRODUCT=bullhead
DEVICE=bullhead
MANUFACTURER=Google
BRAND=Google
MODEL=Nexus 5X
FINGERPRINT=google/bullhead/bullhead:8.0.0/OPR6.170623.013/4283548:user/release-keys
SECURITY_PATCH=2018-01-01

View File

@ -1,9 +0,0 @@
# Remove Play Services from the Magisk Denylist when set to enforcing.
if magisk --denylist status; then
magisk --denylist rm com.google.android.gms
fi
# Check if safetynet-fix is installed
if [ -d "/data/adb/modules/safetynet-fix" ]; then
touch "/data/adb/modules/safetynet-fix/remove"
fi

View File

@ -1,46 +0,0 @@
# Sensitive properties
maybe_set_prop() {
local prop="$1"
local contains="$2"
local value="$3"
if [[ "$(getprop "$prop")" == *"$contains"* ]]; then
resetprop "$prop" "$value"
fi
}
# Magisk recovery mode
maybe_set_prop ro.bootmode recovery unknown
maybe_set_prop ro.boot.mode recovery unknown
maybe_set_prop vendor.boot.mode recovery unknown
# Hiding SELinux | Permissive status
resetprop --delete ro.build.selinux
# Hiding SELinux | Use toybox to protect *stat* access time reading
if [[ "$(toybox cat /sys/fs/selinux/enforce)" == "0" ]]; then
chmod 640 /sys/fs/selinux/enforce
chmod 440 /sys/fs/selinux/policy
fi
# Late props which must be set after boot_completed
{
until [[ "$(getprop sys.boot_completed)" == "1" ]]; do
sleep 1
done
# SafetyNet/Play Integrity | Avoid breaking Realme fingerprint scanners
resetprop ro.boot.flash.locked 1
# SafetyNet/Play Integrity | Avoid breaking Oppo fingerprint scanners
resetprop ro.boot.vbmeta.device_state locked
# SafetyNet/Play Integrity | Avoid breaking OnePlus display modes/fingerprint scanners
resetprop vendor.boot.verifiedbootstate green
# SafetyNet/Play Integrity | Avoid breaking OnePlus display modes/fingerprint scanners on OOS 12
resetprop ro.boot.verifiedbootstate green
resetprop ro.boot.veritymode enforcing
resetprop vendor.boot.vbmeta.device_state locked
}&

View File

@ -1,16 +0,0 @@
# RootBeer, Microsoft
ro.build.tags=release-keys
# Samsung
ro.boot.warranty_bit=0
ro.vendor.boot.warranty_bit=0
ro.vendor.warranty_bit=0
ro.warranty_bit=0
# OnePlus
ro.is_ever_orange=0
# Other
ro.build.type=user
ro.debuggable=0
ro.secure=1