You've already forked TrickyStore
mirror of
https://github.com/5ec1cff/TrickyStore.git
synced 2025-09-06 06:37:07 +00:00
use plt hook
This commit is contained in:
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,6 +1,6 @@
|
|||||||
[submodule "module/src/main/cpp/external/libcxx"]
|
[submodule "module/src/main/cpp/external/libcxx"]
|
||||||
path = module/src/main/cpp/external/libcxx
|
path = module/src/main/cpp/external/libcxx
|
||||||
url = https://github.com/topjohnwu/libcxx
|
url = https://github.com/topjohnwu/libcxx
|
||||||
[submodule "module/src/main/cpp/external/dobby"]
|
[submodule "module/src/main/cpp/external/LSPlt"]
|
||||||
path = module/src/main/cpp/external/dobby
|
path = module/src/main/cpp/external/LSPlt
|
||||||
url = https://github.com/LSPosed/dobby
|
url = https://github.com/LSPosed/LSPlt
|
||||||
|
|||||||
@@ -10,20 +10,17 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS}")
|
|||||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}")
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}")
|
||||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
|
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
|
||||||
|
|
||||||
|
add_library(elf_util STATIC elf_util/elf_util.cpp)
|
||||||
|
add_library(my_logging STATIC logging/logging.cpp)
|
||||||
|
|
||||||
add_subdirectory(external)
|
add_subdirectory(external)
|
||||||
link_libraries(cxx)
|
link_libraries(cxx)
|
||||||
|
|
||||||
add_library(elf_util STATIC elf_util/elf_util.cpp)
|
|
||||||
add_library(lspmparser STATIC lspmparser/lsplt.cpp)
|
|
||||||
add_library(my_logging STATIC logging/logging.cpp)
|
|
||||||
|
|
||||||
target_include_directories(my_logging PUBLIC logging/include)
|
target_include_directories(my_logging PUBLIC logging/include)
|
||||||
target_include_directories(elf_util PUBLIC elf_util/include)
|
target_include_directories(elf_util PUBLIC elf_util/include)
|
||||||
target_include_directories(lspmparser PUBLIC lspmparser/include)
|
|
||||||
|
|
||||||
target_link_libraries(my_logging cxx log)
|
target_link_libraries(my_logging cxx log)
|
||||||
target_link_libraries(elf_util cxx lspmparser my_logging)
|
target_link_libraries(elf_util cxx lsplt my_logging)
|
||||||
target_link_libraries(lspmparser cxx)
|
|
||||||
|
|
||||||
# libutils stub
|
# libutils stub
|
||||||
add_library(utils SHARED binder/stub_utils.cpp)
|
add_library(utils SHARED binder/stub_utils.cpp)
|
||||||
@@ -35,11 +32,11 @@ target_include_directories(binder PUBLIC binder/include)
|
|||||||
target_link_libraries(binder utils)
|
target_link_libraries(binder utils)
|
||||||
|
|
||||||
add_executable(libinject.so inject/main.cpp inject/utils.cpp)
|
add_executable(libinject.so inject/main.cpp inject/utils.cpp)
|
||||||
target_link_libraries(libinject.so lspmparser my_logging)
|
target_link_libraries(libinject.so lsplt my_logging)
|
||||||
target_compile_options(libinject.so PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)
|
target_compile_options(libinject.so PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)
|
||||||
|
|
||||||
add_library(${MODULE_NAME} SHARED binder_interceptor.cpp)
|
add_library(${MODULE_NAME} SHARED binder_interceptor.cpp)
|
||||||
target_link_libraries(${MODULE_NAME} log binder utils dobby elf_util my_logging)
|
target_link_libraries(${MODULE_NAME} log binder utils elf_util my_logging)
|
||||||
target_compile_options(${MODULE_NAME} PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)
|
target_compile_options(${MODULE_NAME} PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)
|
||||||
|
|
||||||
add_library(tszygisk SHARED zygisk/main.cpp)
|
add_library(tszygisk SHARED zygisk/main.cpp)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "logging.hpp"
|
#include "logging.hpp"
|
||||||
#include "dobby.h"
|
#include "lsplt.hpp"
|
||||||
#include "elf_util.h"
|
#include "elf_util.h"
|
||||||
|
|
||||||
#include "hook_util/hook_helper.hpp"
|
#include "hook_util/hook_helper.hpp"
|
||||||
@@ -101,6 +101,7 @@ class BinderStub : public BBinder {
|
|||||||
|
|
||||||
static sp<BinderStub> gBinderStub = nullptr;
|
static sp<BinderStub> gBinderStub = nullptr;
|
||||||
|
|
||||||
|
// FIXME: when use ioctl hooking, some already blocked ioctl calls will not be hooked
|
||||||
int (*old_ioctl)(int fd, int request, ...) = nullptr;
|
int (*old_ioctl)(int fd, int request, ...) = nullptr;
|
||||||
int new_ioctl(int fd, int request, ...) {
|
int new_ioctl(int fd, int request, ...) {
|
||||||
va_list list;
|
va_list list;
|
||||||
@@ -242,52 +243,6 @@ BinderInterceptor::onTransact(uint32_t code, const android::Parcel &data, androi
|
|||||||
return UNKNOWN_TRANSACTION;
|
return UNKNOWN_TRANSACTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class HookHandler : public hook_helper::HookHandler {
|
|
||||||
public:
|
|
||||||
ElfImg img;
|
|
||||||
|
|
||||||
explicit HookHandler(ElfInfo info) : img{std::move(info)} {}
|
|
||||||
|
|
||||||
bool isValid() const {
|
|
||||||
return img.isValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get_symbol(const char *name) const override {
|
|
||||||
auto addr = img.getSymbAddress(name);
|
|
||||||
if (!addr) {
|
|
||||||
LOGE("%s: symbol not found", name);
|
|
||||||
}
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get_symbol_prefix(const char *prefix) const override {
|
|
||||||
auto addr = img.getSymbPrefixFirstOffset(prefix);
|
|
||||||
if (!addr) {
|
|
||||||
LOGE("%s: prefix symbol not found", prefix);
|
|
||||||
}
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *hook(void *original, void *replacement) const override {
|
|
||||||
void *result = nullptr;
|
|
||||||
if (DobbyHook(original, (dobby_dummy_func_t) replacement, (dobby_dummy_func_t *) &result) ==
|
|
||||||
0) {
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<uintptr_t, size_t> get_symbol_info(const char *name) const override {
|
|
||||||
auto p = img.getSymInfo(name);
|
|
||||||
if (!p.first) {
|
|
||||||
LOGE("%s: info not found", name);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BinderInterceptor::handleIntercept(sp<BBinder> target, uint32_t code, const Parcel &data, Parcel *reply,
|
BinderInterceptor::handleIntercept(sp<BBinder> target, uint32_t code, const Parcel &data, Parcel *reply,
|
||||||
uint32_t flags, status_t &result) {
|
uint32_t flags, status_t &result) {
|
||||||
@@ -366,15 +321,26 @@ BinderInterceptor::handleIntercept(sp<BBinder> target, uint32_t code, const Parc
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool hookBinder() {
|
bool hookBinder() {
|
||||||
ElfImg img{ElfInfo::getElfInfoForName("libc.so")};
|
auto maps = lsplt::MapInfo::Scan();
|
||||||
if (!img.isValid()) {
|
dev_t dev;
|
||||||
|
ino_t ino;
|
||||||
|
bool found = false;
|
||||||
|
for (auto &m: maps) {
|
||||||
|
if (m.path.ends_with("/libbinder.so")) {
|
||||||
|
dev = m.dev;
|
||||||
|
ino = m.inode;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
LOGE("libbinder not found!");
|
LOGE("libbinder not found!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
gBinderInterceptor = sp<BinderInterceptor>::make();
|
gBinderInterceptor = sp<BinderInterceptor>::make();
|
||||||
gBinderStub = sp<BinderStub>::make();
|
gBinderStub = sp<BinderStub>::make();
|
||||||
auto ioctlAddr = img.getSymbAddress("ioctl");
|
lsplt::RegisterHook(dev, ino, "ioctl", (void *) new_ioctl, (void **) &old_ioctl);
|
||||||
if (DobbyHook(ioctlAddr, (dobby_dummy_func_t) new_ioctl, (dobby_dummy_func_t*) &old_ioctl) != 0) {
|
if (!lsplt::CommitHook()) {
|
||||||
LOGE("hook failed!");
|
LOGE("hook failed!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
17
module/src/main/cpp/external/CMakeLists.txt
vendored
17
module/src/main/cpp/external/CMakeLists.txt
vendored
@@ -1,17 +1,14 @@
|
|||||||
project(external)
|
project(external)
|
||||||
|
|
||||||
|
# lsplt
|
||||||
|
set(SOURCES lsplt/lsplt/src/main/jni/lsplt.cc lsplt/lsplt/src/main/jni/elf_util.cc)
|
||||||
|
|
||||||
# dobby
|
add_library(lsplt STATIC ${SOURCES})
|
||||||
macro(SET_OPTION option value)
|
target_include_directories(lsplt PUBLIC lsplt/lsplt/src/main/jni/include)
|
||||||
set(${option} ${value} CACHE INTERNAL "" FORCE)
|
target_include_directories(lsplt PRIVATE lsplt/lsplt/src/main/jni)
|
||||||
endmacro()
|
|
||||||
|
|
||||||
SET_OPTION(DOBBY_GENERATE_SHARED OFF)
|
target_link_libraries(lsplt PUBLIC my_logging cxx)
|
||||||
SET_OPTION(Plugin.SymbolResolver OFF)
|
# end lsplt
|
||||||
|
|
||||||
add_subdirectory(dobby)
|
|
||||||
target_link_libraries(dobby cxx)
|
|
||||||
# end dobby
|
|
||||||
|
|
||||||
# cxx
|
# cxx
|
||||||
set(LIBCXX_SOURCES
|
set(LIBCXX_SOURCES
|
||||||
|
|||||||
1
module/src/main/cpp/external/LSPlt
vendored
Submodule
1
module/src/main/cpp/external/LSPlt
vendored
Submodule
Submodule module/src/main/cpp/external/LSPlt added at cef80a97a7
1
module/src/main/cpp/external/dobby
vendored
1
module/src/main/cpp/external/dobby
vendored
Submodule module/src/main/cpp/external/dobby deleted from 6813ca76dd
@@ -1,67 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
/// \namespace lsplt
|
|
||||||
namespace lsplt {
|
|
||||||
inline namespace v2 {
|
|
||||||
/// \struct MapInfo
|
|
||||||
/// \brief An entry that describes a line in /proc/self/maps. You can obtain a list of these entries
|
|
||||||
/// by calling #Scan().
|
|
||||||
struct MapInfo {
|
|
||||||
/// \brief The start address of the memory region.
|
|
||||||
uintptr_t start;
|
|
||||||
/// \brief The end address of the memory region.
|
|
||||||
uintptr_t end;
|
|
||||||
/// \brief The permissions of the memory region. This is a bit mask of the following values:
|
|
||||||
/// - PROT_READ
|
|
||||||
/// - PROT_WRITE
|
|
||||||
/// - PROT_EXEC
|
|
||||||
uint8_t perms;
|
|
||||||
/// \brief Whether the memory region is private.
|
|
||||||
bool is_private;
|
|
||||||
/// \brief The offset of the memory region.
|
|
||||||
uintptr_t offset;
|
|
||||||
/// \brief The device number of the memory region.
|
|
||||||
/// Major can be obtained by #major()
|
|
||||||
/// Minor can be obtained by #minor()
|
|
||||||
dev_t dev;
|
|
||||||
/// \brief The inode number of the memory region.
|
|
||||||
ino_t inode;
|
|
||||||
/// \brief The path of the memory region.
|
|
||||||
std::string path;
|
|
||||||
|
|
||||||
/// \brief Scans /proc/self/maps and returns a list of \ref MapInfo entries.
|
|
||||||
/// This is useful to find out the inode of the library to hook.
|
|
||||||
/// \return A list of \ref MapInfo entries.
|
|
||||||
[[maybe_unused, gnu::visibility("default")]]
|
|
||||||
static std::vector<MapInfo> Scan(std::string proc = "self",
|
|
||||||
std::function<bool(const MapInfo &)> filter = [](
|
|
||||||
auto &map) -> bool { return true; });
|
|
||||||
|
|
||||||
virtual std::string display() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SMapInfo : public MapInfo {
|
|
||||||
ssize_t size;
|
|
||||||
ssize_t rss;
|
|
||||||
ssize_t pss;
|
|
||||||
ssize_t shared_clean;
|
|
||||||
ssize_t shared_dirty;
|
|
||||||
ssize_t private_clean;
|
|
||||||
ssize_t private_dirty;
|
|
||||||
ssize_t referenced;
|
|
||||||
ssize_t anonymous;
|
|
||||||
|
|
||||||
[[maybe_unused, gnu::visibility("default")]]
|
|
||||||
static std::vector<SMapInfo> Scan(std::string proc = "self",
|
|
||||||
std::function<bool(const MapInfo &)> filter = [](
|
|
||||||
auto &map) -> bool { return true; });
|
|
||||||
|
|
||||||
std::string display() const override;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
#include "lsplt.hpp"
|
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/sysmacros.h>
|
|
||||||
#include <array>
|
|
||||||
#include <cinttypes>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <mutex>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace lsplt {
|
|
||||||
inline namespace v2 {
|
|
||||||
[[maybe_unused]] std::vector<MapInfo>
|
|
||||||
MapInfo::Scan(std::string proc, std::function<bool(const MapInfo &)> filter) {
|
|
||||||
constexpr static auto kPermLength = 5;
|
|
||||||
constexpr static auto kMapEntry = 7;
|
|
||||||
std::vector<MapInfo> info;
|
|
||||||
auto name = std::string("/proc/") + proc + "/maps";
|
|
||||||
auto maps = std::unique_ptr<FILE, decltype(&fclose)>{fopen(name.c_str(), "r"),
|
|
||||||
&fclose};
|
|
||||||
if (maps) {
|
|
||||||
char *line = nullptr;
|
|
||||||
size_t len = 0;
|
|
||||||
ssize_t read;
|
|
||||||
while ((read = getline(&line, &len, maps.get())) > 0) {
|
|
||||||
line[read - 1] = '\0';
|
|
||||||
uintptr_t start = 0;
|
|
||||||
uintptr_t end = 0;
|
|
||||||
uintptr_t off = 0;
|
|
||||||
ino_t inode = 0;
|
|
||||||
unsigned int dev_major = 0;
|
|
||||||
unsigned int dev_minor = 0;
|
|
||||||
std::array<char, kPermLength> perm{'\0'};
|
|
||||||
int path_off;
|
|
||||||
if (sscanf(line, "%" PRIxPTR"-%"
|
|
||||||
PRIxPTR
|
|
||||||
" %4s %"
|
|
||||||
PRIxPTR
|
|
||||||
" %x:%x %lu %n%*s", &start,
|
|
||||||
&end, perm.data(), &off, &dev_major, &dev_minor, &inode,
|
|
||||||
&path_off) == kMapEntry) {
|
|
||||||
while (path_off < read && isspace(line[path_off])) path_off++;
|
|
||||||
MapInfo sm{};
|
|
||||||
sm.start = start;
|
|
||||||
sm.end = end;
|
|
||||||
sm.perms = 0;
|
|
||||||
sm.is_private = perm[3] == 'p';
|
|
||||||
sm.offset = off;
|
|
||||||
sm.dev = static_cast<dev_t>(makedev(dev_major, dev_minor));
|
|
||||||
sm.inode = inode;
|
|
||||||
sm.path = line + path_off;
|
|
||||||
if (perm[0] == 'r') sm.perms |= PROT_READ;
|
|
||||||
if (perm[1] == 'w') sm.perms |= PROT_WRITE;
|
|
||||||
if (perm[2] == 'x') sm.perms |= PROT_EXEC;
|
|
||||||
if (filter(sm)) info.emplace_back(sm);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/fs/proc/task_mmu.c;l=827;drc=08582d678fcf11fc86188f0b92239d3d49667d8e
|
|
||||||
[[maybe_unused]] std::vector<SMapInfo>
|
|
||||||
SMapInfo::Scan(std::string proc, std::function<bool(const MapInfo &)> filter) {
|
|
||||||
constexpr static auto kPermLength = 5;
|
|
||||||
constexpr static auto kMapEntry = 7;
|
|
||||||
std::vector<SMapInfo> info;
|
|
||||||
auto name = std::string("/proc/") + proc + "/smaps";
|
|
||||||
auto maps = std::unique_ptr<FILE, decltype(&fclose)>{fopen(name.c_str(), "r"),
|
|
||||||
&fclose};
|
|
||||||
if (!maps) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
char *line = nullptr;
|
|
||||||
size_t len = 0;
|
|
||||||
ssize_t read;
|
|
||||||
while ((read = getline(&line, &len, maps.get())) > 0) {
|
|
||||||
line[read - 1] = '\0';
|
|
||||||
uintptr_t start = 0;
|
|
||||||
uintptr_t end = 0;
|
|
||||||
uintptr_t off = 0;
|
|
||||||
ino_t inode = 0;
|
|
||||||
unsigned int dev_major = 0;
|
|
||||||
unsigned int dev_minor = 0;
|
|
||||||
std::array<char, kPermLength> perm{'\0'};
|
|
||||||
int path_off;
|
|
||||||
if (sscanf(line, "%" PRIxPTR"-%"
|
|
||||||
PRIxPTR
|
|
||||||
" %4s %"
|
|
||||||
PRIxPTR
|
|
||||||
" %x:%x %lu %n%*s", &start,
|
|
||||||
&end, perm.data(), &off, &dev_major, &dev_minor, &inode,
|
|
||||||
&path_off) == kMapEntry) {
|
|
||||||
while (path_off < read && isspace(line[path_off])) path_off++;
|
|
||||||
SMapInfo sm{};
|
|
||||||
sm.start = start;
|
|
||||||
sm.end = end;
|
|
||||||
sm.perms = 0;
|
|
||||||
sm.is_private = perm[3] == 'p';
|
|
||||||
sm.offset = off;
|
|
||||||
sm.dev = static_cast<dev_t>(makedev(dev_major, dev_minor));
|
|
||||||
sm.inode = inode;
|
|
||||||
sm.path = line + path_off;
|
|
||||||
if (perm[0] == 'r') sm.perms |= PROT_READ;
|
|
||||||
if (perm[1] == 'w') sm.perms |= PROT_WRITE;
|
|
||||||
if (perm[2] == 'x') sm.perms |= PROT_EXEC;
|
|
||||||
if (filter(sm)) info.emplace_back(sm);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (info.empty()) continue;
|
|
||||||
auto ¤t = *info.rbegin();
|
|
||||||
ssize_t value;
|
|
||||||
auto s = strstr(line, ":");
|
|
||||||
if (s == nullptr) continue;
|
|
||||||
*s = 0;
|
|
||||||
if (sscanf(s + 1, "%zu", &value) != 1) continue;
|
|
||||||
std::string_view ss{line};
|
|
||||||
if (ss == "Size") current.size = value;
|
|
||||||
else if (ss == "Rss") current.rss = value;
|
|
||||||
else if (ss == "Pss") current.pss = value;
|
|
||||||
else if (ss == "Shared_Clean") current.shared_clean = value;
|
|
||||||
else if (ss == "Shared_Dirty") current.shared_dirty = value;
|
|
||||||
else if (ss == "Private_Clean") current.private_clean = value;
|
|
||||||
else if (ss == "Private_Dirty") current.private_dirty = value;
|
|
||||||
else if (ss == "Referenced") current.referenced = value;
|
|
||||||
else if (ss == "Anonymous") current.anonymous = value;
|
|
||||||
}
|
|
||||||
free(line);
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string MapInfo::display() const {
|
|
||||||
char buf[sizeof(long) * 2 + 1];
|
|
||||||
std::string result;
|
|
||||||
snprintf(buf, sizeof(buf), "%" PRIxPTR, start);
|
|
||||||
result += buf;
|
|
||||||
result += "-";
|
|
||||||
snprintf(buf, sizeof(buf), "%" PRIxPTR, end);
|
|
||||||
result += buf;
|
|
||||||
result += ' ';
|
|
||||||
result += (perms & PROT_READ) ? 'r' : '-';
|
|
||||||
result += (perms & PROT_WRITE) ? 'w' : '-';
|
|
||||||
result += (perms & PROT_EXEC) ? 'x' : '-';
|
|
||||||
result += is_private ? 'p' : 's';
|
|
||||||
result += ' ';
|
|
||||||
snprintf(buf, sizeof(buf), "%08" PRIxPTR, offset);
|
|
||||||
result += buf;
|
|
||||||
result += ' ';
|
|
||||||
snprintf(buf, sizeof(buf), "%02" PRIxPTR, major(dev));
|
|
||||||
result += buf;
|
|
||||||
result += ':';
|
|
||||||
snprintf(buf, sizeof(buf), "%02" PRIxPTR, minor(dev));
|
|
||||||
result += buf;
|
|
||||||
result += ' ';
|
|
||||||
snprintf(buf, sizeof(buf), "%lu", inode);
|
|
||||||
result += buf;
|
|
||||||
result += ' ';
|
|
||||||
result += path;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SMapInfo::display() const {
|
|
||||||
auto result = MapInfo::display();
|
|
||||||
char buf[sizeof(long) * 2 + 1];
|
|
||||||
result += '\n';
|
|
||||||
result += "SZ:";
|
|
||||||
snprintf(buf, sizeof(buf), "%zu", size);
|
|
||||||
result += buf;
|
|
||||||
result += " RSS:";
|
|
||||||
snprintf(buf, sizeof(buf), "%zu", rss);
|
|
||||||
result += buf;
|
|
||||||
result += " PSS:";
|
|
||||||
snprintf(buf, sizeof(buf), "%zu", pss);
|
|
||||||
result += buf;
|
|
||||||
result += " SC:";
|
|
||||||
snprintf(buf, sizeof(buf), "%zu", shared_clean);
|
|
||||||
result += buf;
|
|
||||||
result += " SD:";
|
|
||||||
snprintf(buf, sizeof(buf), "%zu", shared_dirty);
|
|
||||||
result += buf;
|
|
||||||
result += " PC:";
|
|
||||||
snprintf(buf, sizeof(buf), "%zu", private_clean);
|
|
||||||
result += buf;
|
|
||||||
result += " PD:";
|
|
||||||
snprintf(buf, sizeof(buf), "%zu", private_dirty);
|
|
||||||
result += buf;
|
|
||||||
result += " REF:";
|
|
||||||
snprintf(buf, sizeof(buf), "%zu", referenced);
|
|
||||||
result += buf;
|
|
||||||
result += " ANON:";
|
|
||||||
snprintf(buf, sizeof(buf), "%zu", anonymous);
|
|
||||||
result += buf;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
allow keystore keystore process execmem
|
|
||||||
allow keystore system_file unix_dgram_socket *
|
allow keystore system_file unix_dgram_socket *
|
||||||
allow system_file keystore unix_dgram_socket *
|
allow system_file keystore unix_dgram_socket *
|
||||||
allow keystore system_file file *
|
allow keystore system_file file *
|
||||||
|
|||||||
Reference in New Issue
Block a user