Skip to content
This repository has been archived by the owner on Sep 2, 2021. It is now read-only.

Commit

Permalink
Read config from rirud first
Browse files Browse the repository at this point in the history
  • Loading branch information
RikkaW committed Dec 1, 2020
1 parent fb50cf4 commit 89b2e39
Show file tree
Hide file tree
Showing 11 changed files with 316 additions and 20 deletions.
8 changes: 4 additions & 4 deletions module.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ ext {
moduleName = "Location Report Enabler"
moduleAuthor = "Rikka"
moduleDescription = "Enable Google Feed & Timeline & Location reprot in unsupported regions by changing system properties in related packages."
moduleVersion = "v10.0"
moduleVersionCode = 13
moduleVersion = "v10.1"
moduleVersionCode = 14
moduleMinRiruApiVersion = 9
moduleMinRiruVersionName = "v22.0"
moduleMaxRiruApiVersion = 9
moduleMinRiruVersionName = "v23.0"
moduleMaxRiruApiVersion = 10

moduleProp = [
name : moduleName,
Expand Down
2 changes: 1 addition & 1 deletion module/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ repositories {
}

dependencies {
implementation 'rikka.ndk:riru:9.1'
implementation 'rikka.ndk:riru:10'
implementation 'rikka.ndk.thirdparty:xhook:1.2.0'
implementation 'rikka.ndk.thirdparty:nativehelper:20201111'
}
Expand Down
2 changes: 1 addition & 1 deletion module/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ find_package(riru REQUIRED CONFIG)
find_package(nativehelper REQUIRED CONFIG)
find_package(xhook REQUIRED CONFIG)

add_library(${MODULE_NAME} SHARED main.cpp hook.cpp android.cpp misc.cpp config.cpp)
add_library(${MODULE_NAME} SHARED main.cpp hook.cpp android.cpp misc.cpp config.cpp socket.cpp rirud.cpp)
target_link_libraries(${MODULE_NAME} log riru::riru nativehelper::nativehelper_header_only xhook::xhook)
set_target_properties(${MODULE_NAME} PROPERTIES LINK_FLAGS_RELEASE -s)
50 changes: 40 additions & 10 deletions module/src/main/cpp/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "config.h"
#include "misc.h"
#include "logging.h"
#include "rirud.h"

using namespace Config;

Expand Down Expand Up @@ -51,21 +52,50 @@ void Packages::Add(const char *name) {
}

void Config::Load() {
foreach_dir(PROPS_PATH, [](int dirfd, struct dirent *entry) {
if (!rirud::ForeachDir(PROPS_PATH, [](struct dirent *entry, bool *) {
if (entry->d_name[0] == '.') return;

char path[PATH_MAX];
char *buf;
size_t size;

auto name = entry->d_name;
int fd = openat(dirfd, name, O_RDONLY);
if (fd == -1) return;
snprintf(path, PATH_MAX, "%s/%s", PROPS_PATH, name);

char buf[PROP_VALUE_MAX]{0};
if (read(fd, buf, PROP_VALUE_MAX) >= 0) {
if (rirud::ReadFile(path, buf, size)) {
Properties::Put(name, buf);
if (buf) free(buf);
}
})) {
LOGD("read props from rirud failed");

foreach_dir(PROPS_PATH, [](int dirfd, struct dirent *entry, bool *) {
auto name = entry->d_name;
int fd = openat(dirfd, name, O_RDONLY);
if (fd == -1) return;

char buf[PROP_VALUE_MAX]{0};
if (read(fd, buf, PROP_VALUE_MAX) >= 0) {
Properties::Put(name, buf);
}

close(fd);
});
} else {
LOGD("read props from rirud");
}

close(fd);
});

foreach_dir(PACKAGES_PATH, [](int, struct dirent *entry) {
if (!rirud::ForeachDir(PACKAGES_PATH, [](struct dirent *entry, bool *) {
if (entry->d_name[0] == '.') return;
auto name = entry->d_name;
Packages::Add(name);
});
})) {
LOGD("read packages from rirud failed");
foreach_dir(PACKAGES_PATH, [](int, struct dirent *entry, bool *) {
auto name = entry->d_name;
Packages::Add(name);
});
} else {
LOGD("read packages from rirud");
}
}
1 change: 1 addition & 0 deletions module/src/main/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ void *init(void *arg) {
}
case 2: {
switch (riru_api_version) {
case 10:
case 9: {
riru_api_v9 = (RiruApiV9 *) arg;

Expand Down
45 changes: 42 additions & 3 deletions module/src/main/cpp/misc.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,60 @@
#include <dirent.h>
#include <unistd.h>
#include <cerrno>

int foreach_dir(const char *path, void(*callback)(int, struct dirent *)) {
bool foreach_dir(const char *path, void(*callback)(int, struct dirent *, bool *)) {
DIR *dir;
struct dirent *entry;
int fd;
bool continue_read = true;

if ((dir = opendir(path)) == nullptr)
return -1;
return false;

fd = dirfd(dir);

while ((entry = readdir(dir))) {
if (entry->d_name[0] == '.') continue;
callback(fd, entry);
callback(fd, entry, &continue_read);
if (!continue_read) break;
}

closedir(dir);
return true;
}

static ssize_t read_eintr(int fd, void *out, size_t len) {
ssize_t ret;
do {
ret = read(fd, out, len);
} while (ret < 0 && errno == EINTR);
return ret;
}

int read_full(int fd, void *out, size_t len) {
while (len > 0) {
ssize_t ret = read_eintr(fd, out, len);
if (ret <= 0) {
return -1;
}
out = (void *) ((uintptr_t) out + ret);
len -= ret;
}
return 0;
}

int write_full(int fd, const void *buf, size_t count) {
while (count > 0) {
ssize_t size = write(fd, buf, count < SSIZE_MAX ? count : SSIZE_MAX);
if (size == -1) {
if (errno == EINTR)
continue;
else
return -1;
}

buf = (const void *) ((uintptr_t) buf + size);
count -= size;
}
return 0;
}
4 changes: 3 additions & 1 deletion module/src/main/cpp/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

#include <dirent.h>

int foreach_dir(const char *path, void(*callback)(int dirfd, struct dirent * entry));
bool foreach_dir(const char *path, void(*callback)(int, struct dirent *, bool *));
int read_full(int fd, void *buf, size_t count);
int write_full(int fd, const void *buf, size_t count);
190 changes: 190 additions & 0 deletions module/src/main/cpp/rirud.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <cinttypes>
#include <malloc.h>
#include <dirent.h>
#include "riru.h"
#include "rirud.h"
#include "logging.h"
#include "socket.h"
#include "misc.h"

#define SOCKET_ADDRESS "rirud"

static const uint32_t ACTION_READ_FILE = 4;
static const uint32_t ACTION_READ_DIR = 5;

bool rirud::ReadFile(const char *path, char *&bytes, size_t &bytes_size) {
if (riru_api_version < 10) return false;

struct sockaddr_un addr{};
uint32_t path_size = strlen(path);
int32_t reply;
int32_t file_size;
int fd;
socklen_t socklen;
uint32_t buffer_size = 1024 * 8;
bool res = false;

bytes = nullptr;
bytes_size = 0;

if ((fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) {
PLOGE("socket");
goto clean;
}

socklen = setup_sockaddr(&addr, SOCKET_ADDRESS);

if (connect(fd, (struct sockaddr *) &addr, socklen) == -1) {
PLOGE("connect %s", SOCKET_ADDRESS);
goto clean;
}

if (write_full(fd, &ACTION_READ_FILE, sizeof(uint32_t)) != 0
|| write_full(fd, &path_size, sizeof(uint32_t)) != 0
|| write_full(fd, path, path_size) != 0) {
PLOGE("write %s", SOCKET_ADDRESS);
goto clean;
}

if (read_full(fd, &reply, sizeof(int32_t)) != 0) {
PLOGE("read %s", SOCKET_ADDRESS);
goto clean;
}

if (reply != 0) {
LOGE("open %s failed with %d from remote: %s", path, reply, strerror(reply));
errno = reply;
goto clean;
}

if (read_full(fd, &file_size, sizeof(uint32_t)) != 0) {
PLOGE("read %s", SOCKET_ADDRESS);
goto clean;
}

LOGD("%s size %d", path, file_size);

if (file_size > 0) {
bytes = (char *) malloc(file_size);
while (file_size > 0) {
LOGD("attempt to read %d bytes", (int) buffer_size);
auto read_size = TEMP_FAILURE_RETRY(read(fd, bytes + bytes_size, buffer_size));
if (read_size == -1) {
PLOGE("read");
goto clean;
}

file_size -= read_size;
bytes_size += read_size;
LOGD("read %d bytes (total %d)", (int) read_size, (int) bytes_size);
}
res = true;
} else if (file_size == 0) {
while (true) {
if (bytes == nullptr) {
bytes = (char *) malloc(buffer_size);
} else {
bytes = (char *) realloc(bytes, bytes_size + buffer_size);
}

LOGD("attempt to read %d bytes", (int) buffer_size);
auto read_size = TEMP_FAILURE_RETRY(read(fd, bytes + bytes_size, buffer_size));
if (read_size == -1) {
PLOGE("read");
goto clean;
}
if (read_size == 0) {
res = true;
goto clean;
}

bytes_size += read_size;
LOGD("read %d bytes (total %d)", (int) read_size, (int) bytes_size);
}
}


clean:
if (fd != -1) close(fd);
return res;
}

bool rirud::ForeachDir(const char *path, void(*callback)(struct dirent *, bool *continue_read)) {
if (riru_api_version < 10) return false;

struct sockaddr_un addr{};
uint32_t path_size = strlen(path);
int32_t reply;
int fd;
socklen_t socklen;
bool res = false;
bool continue_read = true;

dirent dirent{};

if ((fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) {
PLOGE("socket");
goto clean;
}

socklen = setup_sockaddr(&addr, SOCKET_ADDRESS);

if (connect(fd, (struct sockaddr *) &addr, socklen) == -1) {
PLOGE("connect %s", SOCKET_ADDRESS);
goto clean;
}

if (write_full(fd, &ACTION_READ_DIR, sizeof(uint32_t)) != 0
|| write_full(fd, &path_size, sizeof(uint32_t)) != 0
|| write_full(fd, path, path_size) != 0) {
PLOGE("write %s", SOCKET_ADDRESS);
goto clean;
}

if (read_full(fd, &reply, sizeof(int32_t)) != 0) {
PLOGE("read %s", SOCKET_ADDRESS);
goto clean;
}

if (reply != 0) {
LOGE("opendir %s failed with %d from remote: %s", path, reply, strerror(reply));
errno = reply;
goto clean;
}

while (true) {
if (write_full(fd, &continue_read, sizeof(uint8_t)) != 0) {
PLOGE("write %s", SOCKET_ADDRESS);
goto clean;
}

if (read_full(fd, &reply, sizeof(int32_t)) != 0) {
PLOGE("read %s", SOCKET_ADDRESS);
goto clean;
}

if (reply == -1) {
goto clean;
}

if (reply != 0) {
LOGE("opendir %s failed with %d from remote: %s", path, reply, strerror(reply));
continue;
}

if (read_full(fd, &dirent.d_type, sizeof(unsigned char)) != 0
|| read_full(fd, dirent.d_name, 256) != 0) {
PLOGE("read %s", SOCKET_ADDRESS);
goto clean;
}

callback(&dirent, &continue_read);
}

clean:
if (fd != -1) close(fd);
return res;
}
7 changes: 7 additions & 0 deletions module/src/main/cpp/rirud.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

namespace rirud {

bool ReadFile(const char *path, char *&bytes, size_t &bytes_size);
bool ForeachDir(const char *path, void(*callback)(struct dirent *, bool *continue_read));
}
Loading

0 comments on commit 89b2e39

Please sign in to comment.