Skip to content
This repository has been archived by the owner on Jan 1, 2024. It is now read-only.

Commit

Permalink
some fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Strelsky committed Sep 22, 2023
1 parent 0a2b83d commit 4a9b217
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 95 deletions.
29 changes: 20 additions & 9 deletions daemon/source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/un.h>
#include <unistd.h>
#include "dbg.hpp"
Expand Down Expand Up @@ -185,6 +186,11 @@ static void killApp(int pid) noexcept {
}
}

static bool isProcessAlive(int pid) noexcept {
int mib[]{CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
return sysctl(mib, 4, nullptr, nullptr, nullptr, 0) == 0;
}

static bool handleIpc(const int syscore, const int fd) noexcept {
static constexpr int PING = 0;
static constexpr int PONG = 1;
Expand Down Expand Up @@ -246,15 +252,22 @@ static bool handleIpc(const int syscore, const int fd) noexcept {
dbg::Tracer tracer{pid};
auto regs = tracer.getRegisters();
regs.rip(res.func);
tracer.setRegisters(regs);
if (!tracer.setRegisters(regs)) {
puts("failed to set registers");
}

// run until execve completion
tracer.run();

while (spawned == nullptr) {
// this should grab it first try but I haven't confirmed yet
do { // NOLINT
spawned = Hijacker::getHijacker(pid);
}
if (spawned == nullptr) {
if (isProcessAlive(pid)) {
puts("process died");
return result;
}
}
} while (spawned == nullptr);

const uintptr_t nanosleepOffset = getNanosleepOffset(*spawned);

Expand All @@ -264,11 +277,9 @@ static bool handleIpc(const int syscore, const int fd) noexcept {

puts("success");

uintptr_t base = 0;
while (base == 0) {
// this should also work first try but not confirmed
base = spawned->getLibKernelBase();
}
uintptr_t base = spawned->getLibKernelBase();

printf("libkernel imagebase: 0x%08llx\n", base);

loop.setTarget(base + nanosleepOffset);
base = spawned->imagebase();
Expand Down
2 changes: 2 additions & 0 deletions include/elf/elf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class Elf : Elf64_Ehdr {
bool processPltRelocations() noexcept;
bool load() noexcept;
bool start(uintptr_t args) noexcept;
bool fillSymbolTables(const Array<String> &names, int handleCount, int *preLoadedHandles) noexcept;
bool processLibs(List<const Elf64_Dyn *> &neededLibs) noexcept;
uintptr_t setupKernelRW() noexcept;
uintptr_t getSymbolAddress(const Elf64_Rela *__restrict rel) const noexcept;

Expand Down
5 changes: 4 additions & 1 deletion include/hijacker/hijacker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ class Hijacker {
auto obj = p->getSharedObject();

// obj may be a nullptr when racing process creation
return obj != nullptr ? new Hijacker{obj.release()} : nullptr;
if (obj != nullptr) {
return {new Hijacker{obj.release()}};
}
return nullptr;
}

UniquePtr<KProc> getProc() const {
Expand Down
48 changes: 23 additions & 25 deletions include/kernel/rtld.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,13 +245,14 @@ class SharedLibIterable {
int pid;

public:
SharedLibIterable(decltype(nullptr)) : addr(), pid() {}
SharedLibIterable(uintptr_t addr, int pid) : addr(addr), pid(pid) {}
bool operator!=(decltype(nullptr)) const { return addr != 0; }
SharedLibIterable(decltype(nullptr)) noexcept : addr(), pid() {}
SharedLibIterable(uintptr_t addr, int pid) noexcept : addr(addr), pid(pid) {}
bool operator==(decltype(nullptr)) const noexcept { return addr == 0; }
bool operator!=(decltype(nullptr)) const noexcept { return addr != 0; }
UniquePtr<SharedLib> operator*() {
return new SharedLib{addr, pid};
return {new SharedLib{addr, pid}};
}
SharedLibIterable &operator++() {
SharedLibIterable &operator++() noexcept {
uintptr_t ptr = 0;
kernel_copyout(addr, &ptr, sizeof(ptr));
addr = ptr;
Expand All @@ -262,18 +263,19 @@ class SharedLibIterable {
}
};

struct SharedLibIterator {
class SharedLibIterator {

uintptr_t addr;
int pid;

SharedLibIterator(uintptr_t addr, int pid) : addr(addr), pid(pid) {}
SharedLibIterable begin() const {
return {addr, pid};
}
decltype(nullptr) end() const {
return nullptr;
}
public:
SharedLibIterator(uintptr_t addr, int pid) : addr(addr), pid(pid) {}
SharedLibIterable begin() const {
return {addr, pid};
}
decltype(nullptr) end() const {
return nullptr;
}

};

Expand All @@ -286,10 +288,10 @@ class SharedObject : KernelObject<SharedObject, SHARED_OBJECT_SIZE> {
public:
int pid;

SharedObject(uintptr_t addr, int pid)
SharedObject(uintptr_t addr, int pid) noexcept
: KernelObject(addr), eboot(nullptr), pid(pid) {}

SharedLibIterator getLibs() const {
SharedLibIterator getLibs() const noexcept {
return {get<uintptr_t, 0>(), pid};
}

Expand All @@ -299,12 +301,12 @@ class SharedObject : KernelObject<SharedObject, SHARED_OBJECT_SIZE> {
if (ptr == 0) [[unlikely]] {
return nullptr;
}
eboot = new SharedLib{ptr, pid};
eboot = {new SharedLib{ptr, pid}};
}
return eboot.get();
}

UniquePtr<SharedLib> getLib(int handle) const {
UniquePtr<SharedLib> getLib(int handle) const noexcept {
for (auto lib : getLibs()) {
if (lib->handle() == handle) {
return lib.release();
Expand All @@ -313,7 +315,7 @@ class SharedObject : KernelObject<SharedObject, SHARED_OBJECT_SIZE> {
return nullptr;
}

UniquePtr<SharedLib> getLib(const StringView &name) const {
UniquePtr<SharedLib> getLib(const StringView &name) const noexcept {
String fullname = name;
if (!name.endswith(".sprx"_sv)) {
fullname += ".sprx"_sv;
Expand Down Expand Up @@ -526,10 +528,6 @@ class rtld::ElfSymbolTable {
return nullptr;
}

const ElfSymbol operator[](Nid &&nid) const {
return this->operator[](nid);
}

size_t length() const {
return size;
}
Expand All @@ -542,15 +540,15 @@ class rtld::ElfSymbolTable {
namespace {

static inline UniquePtr<RtldMeta> newRtldMeta(uintptr_t imageBase, uintptr_t addr) {
return new RtldMeta(imageBase, addr);
return {new RtldMeta(imageBase, addr)};
}

static inline UniquePtr<rtld::ElfSymbolTable> newSymbolTable(const RtldMeta *meta) {
return new rtld::ElfSymbolTable(meta);
return {new rtld::ElfSymbolTable(meta)};
}

static inline UniquePtr<rtld::ElfStringTable> newStringTable(const RtldMeta *meta) {
return new rtld::ElfStringTable(meta);
return {new rtld::ElfStringTable(meta)};
}

}
2 changes: 1 addition & 1 deletion libhijacker/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ set(CMAKE_C_FLAGS "--target=x86_64-freebsd-pc-elf -march=znver2 -DPPR -DPS5 -DPS
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_SOURCE -D_POSIX_C_SOURCE=200112 -D__BSD_VISIBLE=1 -D__XSI_VISIBLE=500")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin -nostdlib -Wall") # -nostartfiles
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -O3 -march=znver2 -Wall -Wextra -Wmove -Wmost -Werror -pedantic -pedantic-errors -fno-exceptions")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -DDEBUG -gfull -gdwarf-2 -O0 -march=znver2 -Wall -Wextra -Wmove -Wmost -Werror -pedantic -pedantic-errors -fno-exceptions")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g0 -O0")
target_include_directories(${PROJECT_NAME} PRIVATE "${D_CWD}/../include")
target_include_directories(${PROJECT_NAME} PRIVATE "${D_CWD}/../libNidResolver/include")
Expand Down
119 changes: 61 additions & 58 deletions libhijacker/source/elf/elf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extern "C" {

namespace {

constexpr size_t NUM_PRELOADED_MODULES = 3;
constexpr size_t NUM_PRELOADED_MODULES = 2;
constexpr int LIBKERNEL_HANDLE = 0x2001;
constexpr int LIBC_HANDLE = 2;
//constexpr int LIBSYSMODULE_HANDLE = 0X11;
Expand Down Expand Up @@ -72,6 +72,65 @@ Elf::Elf(Hijacker *hijacker, uint8_t *data) noexcept :

bool loadLibraries(Hijacker &hijacker, const dbg::Tracer &tracer, const Array<String> &paths, ManagedResolver &resolver) noexcept;

bool Elf::fillSymbolTables(const Array<String> &names, int handleCount, int *preLoadedHandles) noexcept {
resolver = {new ManagedResolver{}};
resolver->reserve_library_memory(handleCount + names.length());

puts("filling symbol tables");
for (auto i = 0; i < handleCount; i++) {
auto ptr = hijacker->getLib(preLoadedHandles[i]);
if (ptr == nullptr) [[unlikely]] {
printf("failed to get lib for 0x%x\n", (unsigned int) preLoadedHandles[i]);
return false;
}
if (resolver->add_library_metadata(ptr->imagebase(), ptr->getMetaDataAddress()) != 0) {
printf("failed to add library metadata for 0x%x\n", (unsigned int) preLoadedHandles[i]);
return false;
}
}

if (names.length() > 0) {
puts("loading libraries");
if (!loadLibraries(*hijacker, tracer, names, *resolver)) {
__builtin_printf("failed to load libraries\n");
return false;
}
}

puts("finished process dynamic table");
return true;
}

bool Elf::processLibs(List<const Elf64_Dyn *> &neededLibs) noexcept {
Array<String> names{neededLibs.length()};

int preLoadedHandles[NUM_PRELOADED_MODULES];
int handleCount = 0;
size_t i = 0;
for (const Elf64_Dyn *lib : neededLibs) {
StringView filename = strtab + lib->d_un.d_val;
if (!filename.endswith(".so"_sv)) [[unlikely]] {
__builtin_printf("unexpected library 0x%llx %s\n", (unsigned long long)lib->d_un.d_val, filename.c_str());
return false;
}
if (filename.startswith("libkernel"_sv)) {
*(preLoadedHandles + handleCount++) = LIBKERNEL_HANDLE;
continue;
}
if (filename == "libSceLibcInternal.so"_sv || filename == "libc.so"_sv) {
*(preLoadedHandles + handleCount++) = LIBC_HANDLE;
continue;
}

names[i++] = StringView{filename.c_str(), filename.length() - 3};
}

// remove unset values
names.shrink(i);

return fillSymbolTables(names, handleCount, preLoadedHandles);
}

bool Elf::parseDynamicTable() noexcept {
const Elf64_Dyn *__restrict dyntbl = nullptr;
for (size_t i = 0; i < e_phnum; i++) {
Expand Down Expand Up @@ -167,63 +226,7 @@ bool Elf::parseDynamicTable() noexcept {
return true;
}

Array<String> names{neededLibs.length()};

int preLoadedHandles[NUM_PRELOADED_MODULES];
int handleCount = 0;
size_t i = 0;
for (const Elf64_Dyn *lib : neededLibs) {
StringView filename = strtab + lib->d_un.d_val;
if (!filename.endswith(".so"_sv)) [[unlikely]] {
__builtin_printf("unexpected library 0x%llx %s\n", (unsigned long long)lib->d_un.d_val, filename.c_str());
return false;
}
// I really do not want to implement a hashmap
if (filename.startswith("libkernel"_sv)) {
*(preLoadedHandles + handleCount++) = LIBKERNEL_HANDLE;
continue;
}
if (filename == "libSceLibcInternal.so"_sv || filename == "libc.so"_sv) {
*(preLoadedHandles + handleCount++) = LIBC_HANDLE;
continue;
}
//if (filename == "libSceSysmodule.so"_sv) {
// *(preLoadedHandles + handleCount++) = LIBSYSMODULE_HANDLE;
// continue;
//}

names[i++] = StringView{filename.c_str(), filename.length() - 3};
}

// remove unset values
names.shrink(i);

resolver = new ManagedResolver{};
resolver->reserve_library_memory(handleCount + names.length());

puts("filling symbol tables");
for (auto i = 0; i < handleCount; i++) {
auto ptr = hijacker->getLib(preLoadedHandles[i]);
if (ptr == nullptr) [[unlikely]] {
printf("failed to get lib for 0x%x\n", (unsigned int) preLoadedHandles[i]);
return false;
}
if (resolver->add_library_metadata(ptr->imagebase(), ptr->getMetaDataAddress()) != 0) {
printf("failed to add library metadata for 0x%x\n", (unsigned int) preLoadedHandles[i]);
return false;
}
}

if (names.length() > 0) {
puts("loading libraries");
if (!loadLibraries(*hijacker, tracer, names, *resolver)) {
__builtin_printf("failed to load libraries\n");
return false;
}
}

puts("finished process dynamic table");
return true;
return processLibs(neededLibs);
}

class TracedMemory {
Expand Down
2 changes: 1 addition & 1 deletion spawner/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ set(CMAKE_C_FLAGS "--target=x86_64-freebsd-pc-elf -O0 -march=znver2 -DPPR -DPS5
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_SOURCE -D_POSIX_C_SOURCE=200112 -D__BSD_VISIBLE=1 -D__XSI_VISIBLE=500")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-builtin -nostdlib -Wall") # -nostartfiles
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -O3 -march=znver2 -Wall -Wextra -Wmove -Wmost -Werror -pedantic -pedantic-errors -fno-exceptions -Wno-unused-function")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -DDEBUG -gfull -gdwarf-2 -O0 -march=znver2 -Wall -Wextra -Wmove -Wmost -Werror -pedantic -pedantic-errors -fno-exceptions -Wno-unused-function")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wno-unused-command-line-argument")

target_sources(${PROJECT_NAME} PRIVATE ${SrcFiles})
Expand Down

0 comments on commit 4a9b217

Please sign in to comment.