This commit is contained in:
chiteroman 2023-11-24 01:57:17 +01:00
parent 9774d68b3b
commit ed330ac37a
No known key found for this signature in database
GPG Key ID: 15FF53015D426D8E
5 changed files with 126 additions and 120 deletions

View File

@ -1,6 +1,2 @@
FLAGS := -DNDEBUG -g0 -Oz -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -flto=full -Wl,--icf=all -Wl,--exclude-libs,ALL -Wl,--gc-sections
APP_STL := none
APP_CPPFLAGS := -std=c++20
APP_CFLAGS := $(FLAGS)
APP_LDFLAGS := $(FLAGS)
APP_CPPFLAGS := -std=c++20 -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden

View File

@ -4,8 +4,7 @@
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <sstream>
#include <filesystem>
#include "zygisk.hpp"
#include "shadowhook.h"
@ -16,6 +15,10 @@
#define PROP_FILE_PATH "/data/adb/modules/playintegrityfix/pif.prop"
#define DEFAULT_SECURITY_PATCH "2017-08-05"
#define DEFAULT_FIRST_API_LEVEL "23"
static std::string SECURITY_PATCH, FIRST_API_LEVEL;
typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
@ -26,7 +29,7 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
if (cookie == nullptr || name == nullptr || value == nullptr || o_callback == nullptr) return;
std::string_view prop(name);
std::string prop(name);
if (prop.ends_with("api_level")) {
if (FIRST_API_LEVEL.empty()) {
@ -59,7 +62,7 @@ my_system_property_read_callback(const prop_info *pi, T_Callback callback, void
}
static void doHook() {
shadowhook_init(SHADOWHOOK_MODE_UNIQUE, true);
shadowhook_init(SHADOWHOOK_MODE_UNIQUE, false);
void *handle = shadowhook_hook_sym_name(
"libc.so",
"__system_property_read_callback",
@ -82,86 +85,49 @@ public:
void preAppSpecialize(zygisk::AppSpecializeArgs *args) override {
auto rawProcess = env->GetStringUTFChars(args->nice_name, nullptr);
std::string_view process(rawProcess);
bool isGms = process.starts_with("com.google.android.gms");
isGmsUnstable = process.compare("com.google.android.gms.unstable") == 0;
std::string process(rawProcess);
env->ReleaseStringUTFChars(args->nice_name, rawProcess);
if (isGms) api->setOption(zygisk::FORCE_DENYLIST_UNMOUNT);
if (process.starts_with("com.google.android.gms")) {
if (!isGmsUnstable) {
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
api->setOption(zygisk::FORCE_DENYLIST_UNMOUNT);
int fd = api->connectCompanion();
if (process == "com.google.android.gms.unstable") {
long size = 0;
read(fd, &size, sizeof(size));
isGmsUnstable = true;
if (size < 1) {
close(fd);
LOGD("Couldn't read classes.dex from socket! File exists?");
return;
}
auto rawDir = env->GetStringUTFChars(args->app_data_dir, nullptr);
dir = std::string(rawDir);
env->ReleaseStringUTFChars(args->app_data_dir, rawDir);
moduleDex.resize(size);
read(fd, moduleDex.data(), size);
auto fd = api->connectCompanion();
int mapSize = 0;
read(fd, &mapSize, sizeof(mapSize));
write(fd, dir.data(), dir.size());
if (mapSize < 1) {
close(fd);
SECURITY_PATCH = "2017-08-05";
FIRST_API_LEVEL = "23";
LOGD("Couldn't read pif.prop from socket! File exists?");
return;
}
int temp;
read(fd, &temp, sizeof(temp));
for (int i = 0; i < size; ++i) {
int keyLenght, valueLenght;
std::string key, value;
close(fd);
read(fd, &keyLenght, sizeof(keyLenght));
read(fd, &valueLenght, sizeof(valueLenght));
key.resize(keyLenght);
value.resize(valueLenght);
read(fd, key.data(), keyLenght);
read(fd, value.data(), valueLenght);
props[key] = value;
}
LOGD("Received from socket %d props!", static_cast<int>(props.size()));
for (const auto &item: props) {
if (item.first == "SECURITY_PATCH") {
SECURITY_PATCH = item.second;
} else if (item.first == "FIRST_API_LEVEL") {
FIRST_API_LEVEL = item.second;
return;
}
}
close(fd);
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
}
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
if (!isGmsUnstable) return;
readDexFile();
readPropsFile();
doHook();
inject();
LOGD("clean");
moduleDex.clear();
moduleDex.shrink_to_fit();
props.clear();
clean();
}
void preServerSpecialize(zygisk::ServerSpecializeArgs *args) override {
@ -172,12 +138,85 @@ private:
zygisk::Api *api = nullptr;
JNIEnv *env = nullptr;
bool isGmsUnstable = false;
std::map<std::string, std::string> props;
std::string dir;
std::vector<char> moduleDex;
std::map<std::string, std::string> props;
void clean() {
dir.clear();
moduleDex.clear();
props.clear();
}
void readPropsFile() {
std::string f = dir + "/pif.prop";
FILE *file = fopen(f.c_str(), "r");
if (file == nullptr) {
SECURITY_PATCH = DEFAULT_SECURITY_PATCH;
FIRST_API_LEVEL = DEFAULT_FIRST_API_LEVEL;
LOGD("File pif.prop doesn't exist, using default values");
return;
}
char buffer[256];
while (fgets(buffer, sizeof(buffer), file)) {
char *rawKey = strtok(buffer, "=");
char *rawValue = strtok(nullptr, "=");
if (rawKey == nullptr) continue;
std::string key(rawKey);
std::string value(rawValue);
key.erase(std::remove_if(key.begin(), key.end(), [](unsigned char x) {
return std::isspace(x);
}), key.end());
value.erase(std::remove(value.begin(), value.end(), '\n'), value.end());
props[key] = value;
}
fclose(file);
std::filesystem::remove(f);
LOGD("Read %d props from file!", static_cast<int>(props.size()));
SECURITY_PATCH = props["SECURITY_PATCH"];
FIRST_API_LEVEL = props["FIRST_API_LEVEL"];
}
void readDexFile() {
std::string f = dir + "/classes.dex";
FILE *file = fopen(f.c_str(), "rb");
if (file == nullptr) {
LOGD("File classes.dex doesn't exist. This is weird... Report to @chiteroman");
return;
}
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
char buffer[size];
fread(buffer, 1, size, file);
fclose(file);
std::filesystem::remove(f);
moduleDex.insert(moduleDex.end(), buffer, buffer + size);
}
void inject() {
if (moduleDex.empty()) {
LOGD("Dex not loaded in memory");
LOGD("ERROR! Dex in memory is empty!");
return;
}
@ -223,56 +262,27 @@ private:
};
static void companion(int fd) {
std::ifstream dex(DEX_FILE_PATH, std::ios::binary | std::ios::ate);
char buffer[256];
auto bytes = read(fd, buffer, sizeof(buffer));
long size = static_cast<long>(dex.tellg());
dex.seekg(std::ios::beg);
std::string file(buffer, bytes);
LOGD("[ROOT] Read file: %s", file.c_str());
char buffer[size];
dex.read(buffer, size);
std::string dex = file + "/classes.dex";
std::string prop = file + "/pif.prop";
dex.close();
write(fd, &size, sizeof(size));
write(fd, buffer, size);
std::ifstream prop(PROP_FILE_PATH);
if (prop.bad()) {
prop.close();
int i = 0;
write(fd, &i, sizeof(i));
return;
if (std::filesystem::copy_file(DEX_FILE_PATH, dex,
std::filesystem::copy_options::overwrite_existing)) {
std::filesystem::permissions(dex, std::filesystem::perms::all);
}
std::map<std::string, std::string> props;
std::string line;
while (std::getline(prop, line)) {
std::istringstream iss(line);
std::string key, value;
if (std::getline(iss, key, '=') && std::getline(iss, value)) {
props[key] = value;
}
if (std::filesystem::copy_file(PROP_FILE_PATH, prop,
std::filesystem::copy_options::overwrite_existing)) {
std::filesystem::permissions(prop, std::filesystem::perms::all);
}
prop.close();
int mapSize = static_cast<int>(props.size());
write(fd, &mapSize, sizeof(mapSize));
for (const auto &item: props) {
int keyLenght = static_cast<int>(item.first.size());
int valueLenght = static_cast<int>(item.second.size());
write(fd, &keyLenght, sizeof(keyLenght));
write(fd, &valueLenght, sizeof(valueLenght));
write(fd, item.first.data(), keyLenght);
write(fd, item.second.data(), valueLenght);
}
int temp = 1;
write(fd, &temp, sizeof(temp));
}
REGISTER_ZYGISK_MODULE(PlayIntegrityFix)

View File

@ -21,6 +21,7 @@ public final class EntryPoint {
}
public static void addProp(String key, String value) {
if (key == null || value == null || key.isEmpty() || value.isEmpty()) return;
map.put(key, value);
LOG(String.format("Received from Zygisk lib: [%s] -> '%s'", key, value));
}

View File

@ -4,11 +4,10 @@ https://t.me/playintegrityfix
Also, if Google blacklist the fingerprint (again), you can post your custom pif.prop and I will update the module.
# v13.4
# v13.5
- Custom resetprop utility! Thanks to @HuskyDG.
- Don't write in GMS folder, everything stored in memory. (Issue from @osm0sis :D)
- Downgrade to Zygisk API 2.
- Should fix crashes.
- Remove custom resetprop.
- Fixes in code.
This build includes 'pif.prop', you can modify it and use your custom props to pass Device verdict.
This module will backup your pif.prop into adb root folder.
If you remove this file, module will use default props for attestation.

View File

@ -1,6 +1,6 @@
{
"version": "v13.4",
"versionCode": 134,
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v13.4/PlayIntegrityFix_v13.4.zip",
"version": "v13.5",
"versionCode": 135,
"zipUrl": "https://github.com/chiteroman/PlayIntegrityFix/releases/download/v13.5/PlayIntegrityFix_v13.5.zip",
"changelog": "https://raw.githubusercontent.com/chiteroman/PlayIntegrityFix/main/changelog.md"
}