Skip to content

Commit

Permalink
Add support for split caves.
Browse files Browse the repository at this point in the history
  • Loading branch information
idc committed Jan 14, 2018
1 parent 8b36b4e commit 7dc207e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 17 deletions.
41 changes: 31 additions & 10 deletions fake_installer/source/main.c
Expand Up @@ -49,7 +49,8 @@ struct real_info

struct cave_info
{
const size_t kernel_offset;
const size_t kernel_call_offset;
const size_t kernel_ptr_offset;
const size_t payload_offset;
};

Expand Down Expand Up @@ -101,7 +102,7 @@ int syscall_install_payload(void* td, struct syscall_install_payload_args* args)

if (!payload_data ||
payload_size < sizeof(payload_header) ||
payload_header->signature != 0x5041594C4F414432ull)
payload_header->signature != 0x5041594C4F414433ull)
{
kernel_printf("payload_installer: bad payload data\n");
return -2;
Expand Down Expand Up @@ -166,31 +167,51 @@ int syscall_install_payload(void* td, struct syscall_install_payload_args* args)
struct cave_info* cave_info =
(struct cave_info*)(&payload_data[payload_header->cave_info_offset]);
for (
; cave_info->payload_offset != 0 && cave_info->kernel_offset != 0
; cave_info->kernel_call_offset != 0 &&
cave_info->kernel_ptr_offset != 0 &&
cave_info->payload_offset != 0
; ++cave_info)
{
uint8_t* kernel_target = &kernel_base[cave_info->kernel_offset];
uint8_t* kernel_call_target = &kernel_base[cave_info->kernel_call_offset];
uint8_t* kernel_ptr_target = &kernel_base[cave_info->kernel_ptr_offset];
void* payload_target = &payload_buffer[cave_info->payload_offset];
kernel_printf(" %lx(%lx) : %lx(%lx)\n",
cave_info->kernel_offset, kernel_target,
int32_t new_disp = (int32_t)(kernel_ptr_target - &kernel_call_target[6]);

if (&kernel_call_target[6] == kernel_ptr_target)
{
kernel_printf(" %lx(%lx)\n",
cave_info->kernel_call_offset, kernel_call_target);
}
else
{
kernel_printf(" %lx(%lx) -> %lx(%lx) = %d\n",
cave_info->kernel_call_offset, kernel_call_target,
cave_info->kernel_ptr_offset, kernel_ptr_target,
new_disp);
}
kernel_printf(" %lx(%lx)\n",
cave_info->payload_offset, payload_target);

if ((uint64_t)(kernel_ptr_target - &kernel_call_target[6]) > UINT32_MAX)
{
kernel_printf(" error! new_disp > UINT32_MAX!\n");
}

#pragma pack(push,1)
struct
{
uint8_t op[2];
int32_t disp;
uint64_t address;
}
jmp;
#pragma pack(pop)
jmp.op[0] = 0xFF;
jmp.op[1] = 0x25;
jmp.disp = 0;
jmp.address = (uint64_t)payload_target;
jmp.disp = new_disp;
cr0 = readCr0();
writeCr0(cr0 & ~X86_CR0_WP);
kernel_memcpy(kernel_target, &jmp, sizeof(jmp));
kernel_memcpy(kernel_call_target, &jmp, sizeof(jmp));
kernel_memcpy(kernel_ptr_target, &payload_target, sizeof(void*));
writeCr0(cr0);
}
}
Expand Down
18 changes: 11 additions & 7 deletions fake_payload/source/main.c
Expand Up @@ -43,7 +43,8 @@ struct real_info

struct cave_info
{
const size_t kernel_offset;
const size_t kernel_call_offset;
const size_t kernel_ptr_offset;
const void* payload_target;
};

Expand All @@ -70,14 +71,17 @@ struct real_info real_infos[] PAYLOAD_DATA =
{ 0, NULL },
};

#define ADJACENT(x) \
x, x + 6
struct cave_info cave_infos[] PAYLOAD_DATA =
{
{ 0x6116F1, &my_sceSblAuthMgrIsLoadable2 },
{ 0x612EA1, &my_sceSblAuthMgrVerifyHeader },
{ 0x617A32, &my_sceSblAuthMgrSmLoadSelfSegment__sceSblServiceMailbox },
{ 0x617B80, &my_sceSblAuthMgrSmLoadSelfBlock__sceSblServiceMailbox },
{ 0, NULL },
{ ADJACENT(0x6116F1), &my_sceSblAuthMgrIsLoadable2 },
{ ADJACENT(0x612EA1), &my_sceSblAuthMgrVerifyHeader },
{ ADJACENT(0x617A32), &my_sceSblAuthMgrSmLoadSelfSegment__sceSblServiceMailbox },
{ ADJACENT(0x617B80), &my_sceSblAuthMgrSmLoadSelfBlock__sceSblServiceMailbox },
{ 0, 0, NULL },
};
#undef ADJACENT

struct disp_info disp_infos[] PAYLOAD_DATA =
{
Expand All @@ -99,7 +103,7 @@ struct
}
payload_header PAYLOAD_HEADER =
{
0x5041594C4F414432ull,
0x5041594C4F414433ull,
real_infos,
cave_infos,
disp_infos,
Expand Down

0 comments on commit 7dc207e

Please sign in to comment.