Custom props!

This commit is contained in:
chiteroman
2023-11-25 17:31:37 +01:00
parent 27c00e2ce7
commit edffde9b1a
7 changed files with 24804 additions and 49 deletions

24689
app/src/main/cpp/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,19 @@
#include <android/log.h>
#include <sys/system_properties.h>
#include <unistd.h>
#include <string_view>
#include <map>
#include <vector>
#include <fstream>
#include "zygisk.hpp"
#include "dobby.h"
#include "json.hpp"
#define DEX_FILE_PATH "/data/adb/modules/playintegrityfix/classes.dex"
#define PROP_FILE_PATH "/data/adb/modules/playintegrityfix/pif.json"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "PIF/Native", __VA_ARGS__)
#define FIRST_API_LEVEL "25"
#define SECURITY_PATCH "2017-08-05"
static std::string FIRST_API_LEVEL, SECURITY_PATCH;
typedef void (*T_Callback)(void *, const char *, const char *, uint32_t);
@@ -27,10 +28,18 @@ static void modify_callback(void *cookie, const char *name, const char *value, u
std::string_view prop(name);
if (prop.ends_with("api_level")) {
value = FIRST_API_LEVEL;
if (FIRST_API_LEVEL == "NULL") {
value = nullptr;
} else {
value = FIRST_API_LEVEL.c_str();
}
LOGD("[%s] -> %s", name, value);
} else if (prop.ends_with("security_patch")) {
value = SECURITY_PATCH;
if (SECURITY_PATCH == "NULL") {
value = nullptr;
} else {
value = SECURITY_PATCH.c_str();
}
LOGD("[%s] -> %s", name, value);
}
@@ -90,23 +99,44 @@ public:
return;
}
ssize_t size;
char buffer[10000];
int fd = api->connectCompanion();
long size;
char buffer[1024];
size = read(fd, buffer, sizeof(buffer));
while ((size = read(fd, buffer, sizeof(buffer))) > 0) {
if (size > 0) {
moduleDex.insert(moduleDex.end(), buffer, buffer + size);
} else {
LOGD("Couldn't load classes.dex file in memory");
close(fd);
api->setOption(zygisk::DLCLOSE_MODULE_LIBRARY);
return;
}
lseek(fd, 0, SEEK_SET);
size = read(fd, buffer, sizeof(buffer));
if (size > 0) {
jsonStr.insert(jsonStr.end(), buffer, buffer + size);
} else {
LOGD("Couldn't load pif.json file in memory");
}
close(fd);
LOGD("Received from socket %lu bytes!", moduleDex.size());
LOGD("Received 'classes.dex' file from socket: %d bytes",
static_cast<int>(moduleDex.size()));
LOGD("Received 'pif.json' file from socket: %d bytes", static_cast<int>(jsonStr.size()));
}
void postAppSpecialize(const zygisk::AppSpecializeArgs *args) override {
if (moduleDex.empty()) return;
readJson();
inject();
doHook();
@@ -120,6 +150,21 @@ private:
zygisk::Api *api = nullptr;
JNIEnv *env = nullptr;
std::vector<char> moduleDex;
std::string jsonStr;
void readJson() {
nlohmann::json json = nlohmann::json::parse(jsonStr, nullptr, false);
auto getStringFromJson = [&json](const std::string &key) {
return json.contains(key) && !json[key].is_null() ? json[key].get<std::string>()
: "NULL";
};
SECURITY_PATCH = getStringFromJson("SECURITY_PATCH");
FIRST_API_LEVEL = getStringFromJson("FIRST_API_LEVEL");
json.clear();
}
void inject() {
LOGD("get system classloader");
@@ -144,34 +189,34 @@ private:
auto entryClass = (jclass) entryClassObj;
LOGD("read json");
auto readProps = env->GetStaticMethodID(entryClass, "readJson",
"(Ljava/lang/String;)V");
auto javaStr = env->NewStringUTF(jsonStr.c_str());
env->CallStaticVoidMethod(entryClass, readProps, javaStr);
LOGD("call init");
auto entryInit = env->GetStaticMethodID(entryClass, "init", "()V");
env->CallStaticVoidMethod(entryClass, entryInit);
moduleDex.clear();
jsonStr.clear();
}
};
static void companion(int fd) {
FILE *file = fopen("/data/adb/modules/playintegrityfix/classes.dex", "rb");
std::ifstream dex(DEX_FILE_PATH, std::ios::binary);
std::ifstream prop(PROP_FILE_PATH);
if (file == nullptr) {
write(fd, nullptr, 0);
return;
}
std::vector<char> dexVector((std::istreambuf_iterator<char>(dex)),
std::istreambuf_iterator<char>());
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
std::vector<char> propVector((std::istreambuf_iterator<char>(prop)),
std::istreambuf_iterator<char>());
std::vector<char> vector(size);
fread(vector.data(), 1, size, file);
fclose(file);
write(fd, vector.data(), size);
vector.clear();
write(fd, dexVector.data(), dexVector.size());
lseek(fd, 0, SEEK_SET);
write(fd, propVector.data(), propVector.size());
}
REGISTER_ZYGISK_MODULE(PlayIntegrityFix)

View File

@@ -1,29 +1,40 @@
package es.chiteroman.playintegrityfix;
import android.os.Build;
import android.util.JsonReader;
import android.util.Log;
import java.io.IOException;
import java.io.StringReader;
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;
public final class EntryPoint {
private static final String PRODUCT = "sailfish";
private static final String DEVICE = "sailfish";
private static final String MANUFACTURER = "Google";
private static final String BRAND = "google";
private static final String MODEL = "Pixel";
private static final String FINGERPRINT = "google/sailfish/sailfish:7.1.2/NZH54D/4146044:user/release-keys";
private static final String SECURITY_PATCH = "2017-08-05";
private static final Map<String, String> map = new HashMap<>();
public static void init() {
spoofProvider();
spoofDevice();
}
public static void readJson(String data) {
try (JsonReader reader = new JsonReader(new StringReader(data))) {
reader.beginObject();
while (reader.hasNext()) {
map.put(reader.nextName(), reader.nextString());
}
reader.endObject();
} catch (IOException e) {
LOG("Couldn't read JSON from Zygisk: " + e);
}
}
private static void spoofProvider() {
final String KEYSTORE = "AndroidKeyStore";
@@ -52,13 +63,15 @@ public final class EntryPoint {
}
static void spoofDevice() {
setProp("PRODUCT", PRODUCT);
setProp("DEVICE", DEVICE);
setProp("MANUFACTURER", MANUFACTURER);
setProp("BRAND", BRAND);
setProp("MODEL", MODEL);
setProp("FINGERPRINT", FINGERPRINT);
setVersionProp("SECURITY_PATCH", SECURITY_PATCH);
if (map.isEmpty()) return;
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"));
}
private static void setProp(String name, String value) {