Find out what is flag & 0x2000 on mmap
It is not MAP_GUARD.
MAP_SHARED =$00001; // share changes
MAP_PRIVATE =$00002; // changes are private
MAP_FIXED =$00010; // map addr must be exactly as requested
MAP_NO_OVERWRITE =$00080; // don't overwrite memory with MAP_FIXED
MAP_VOID =$00100; // reserve addr
MAP_HASSEMAPHORE =$00200; // region may contain semaphores
MAP_STACK =$00400; // region grows down, like a stack
MAP_NOSYNC =$00800; // page to but do not sync underlying file
MAP_FILE =$00000; // map from file (default)
MAP_ANON =$01000; // allocated from memory, swap space
MAP_ANONYMOUS =MAP_ANON; // For compatibility.
MAP_SYSTEM =$02000;
MAP_ALLAVAILABLE =$04000;
MAP_NOCORE =$20000; // dont include these pages in a coredump
MAP_PREFAULT_READ =$40000; // prefault mapping for reading
MAP_SELF =$80000; // map decryped SELF file
MAP_SANITIZER =$200000; // devkit only
MAP_NO_COALESCE =$400000; // do not merge nearby areas
MAP_WRITABLE_WB_GARLIC=$800000;
Thanks!
I tracked the influence of MAP_SYSTEM to the vm_map_findspace procedure, it seems that this affects the granularity of the aslr block when searching, if there is a MAP_SYSTEM then it is: 0x200000 if not then: 0x4000 perhaps it affects something else but I didn’t find anything else.
What I found is the first mmap from libkernel will always be:
0x200000000:0x201003000 is mapped as CPU_READ | CPU_WRITE with MAP_ANON | 0x2000.
Then it will set the name on this region to SceKernelInternalMemory:
Setting name for 0x200000000:0x201000000 to 'SceKernelInternalMemory'
Later on it will try to (re?)map the first part of the first mmap:
0x200000000:0x200004000 is mapped as CPU_READ | CPU_WRITE with MAP_ANON.
So I tried to implement 0x2000 as MAP_GUARD for the first mmap but segmentation fault, which imply 0x2000 is not MAP_GUARD.
The problem is when I allow it to remap the first mmap I got int 0x44 from libSceLibcInternal. It seems like not allow the remap is the correct path but this does not feel right because of the following logs:
++++++++++++++++++ I [00:00:00:00:402]:0x000000000000de7d:kernel/src/rtld/mod.rs:384
Getting symbol 'module_start' from /system/common/lib/libkernel.sprx.
++++++++++++++++++ W [00:00:00:00:402]:0x000000000000de7d:kernel/src/syscalls/mod.rs:63
Syscall 591 failed: no such process.
++++++++++++++++++ I [00:00:00:00:402]:0x000000000000de7d:kernel/src/rtld/mod.rs:384
Getting symbol 'module_start' from /system/common/lib/libSceLibcInternal.sprx.
++++++++++++++++++ W [00:00:00:00:402]:0x000000000000de7d:kernel/src/syscalls/mod.rs:63
Syscall 591 failed: no such process.
++++++++++++++++++ I [00:00:00:00:402]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_Atexit' (ID = 3) was created with data = 0x200000020 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:402]:0x000000000000de7d:kernel/src/fs/mod.rs:173
Opening /dev/console with O_WRONLY.
++++++++++++++++++ I [00:00:00:00:402]:0x000000000000de7d:kernel/src/fs/mod.rs:182
File descriptor 1 was allocated for /dev/console.
++++++++++++++++++ I [00:00:00:00:402]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_DebugOut' (ID = 4) was created with data = 0x2000000a0 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:402]:0x000000000000de7d:kernel/src/budget/mod.rs:26
Getting budget process type for process 1.
++++++++++++++++++ W [00:00:00:00:402]:0x000000000000de7d:kernel/src/syscalls/mod.rs:63
Syscall 610 failed: no such file or directory.
++++++++++++++++++ I [00:00:00:00:402]:0x000000000000de7d:kernel/src/budget/mod.rs:26
Getting budget process type for process 1.
++++++++++++++++++ W [00:00:00:00:403]:0x000000000000de7d:kernel/src/syscalls/mod.rs:63
Syscall 610 failed: no such file or directory.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_Locale' (ID = 5) was created with data = 0x200000100 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_Malloc' (ID = 6) was created with data = 0x200000160 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_Stream' (ID = 7) was created with data = 0x2000001c0 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_Debug' (ID = 8) was created with data = 0x200000220 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_CallOnce' (ID = 9) was created with data = 0x200000280 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_CallOnceEx' (ID = 10) was created with data = 0x2000002e0 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_AtThreadExit' (ID = 11) was created with data = 0x200000340 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_Reserved' (ID = 12) was created with data = 0x2000003a0 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_FileStdin' (ID = 13) was created with data = 0x200000400 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_FileStdout' (ID = 14) was created with data = 0x200000460 and flags = 0x101.
++++++++++++++++++ I [00:00:00:00:403]:0x000000000000de7d:kernel/src/process/mod.rs:438
Named object 'SceLibcI_FileStderr' (ID = 15) was created with data = 0x2000004c0 and flags = 0x101.
++++++++++++++++++ P [00:00:00:00:403]:0x000000000000de7d:kernel/src/sysctl/mod.rs:248
not yet implemented: sysctl name2oid(kern.sched.cpusetsize)
It create a bunch of named object with 0x200000XXX value, which is the address it was tried to remap.
It’s strange, according to my data, the first call to mmap for 'SceKernelInternalMemory' comes with the flag 0x1000 (MAP_VOID), that is, it simply reserves memory, maybe the difference is due to the fact that you are booting in system application mode and not game mode?
you are booting in system application mode and not game mode?
I don't know which mode we are currently boot the libkernel. Do you know how to control or verify this?
There are several different signs (Sony programmers, why make it so complicated? But this is the lyrics), it’s difficult to put together right away, but for a specific case:
int sceKernelGetProcessType(int pid)
{
int ret1;
int *piVar1;
ret1 = sys_budget_get_ptype(pid);
if (ret1 == -1) {
piVar1 = __error();
ret1 = *piVar1 + -0x7ffe0000;
if (*piVar1 == 0) {
ret1 = 0;
}
}
return ret1;
}
ptype = sceKernelGetProcessType(-1);
g_heap_param.ptype_1 = (int)(ptype == 1);
if (g_heap_param.SystemData == (void *)0x0) {
if (g_heap_param.ptype_1 == 0) {
ret1 = sceKernelMapNamedSystemFlexibleMemory(&addr,size,3,0,name);
}
else {
ret1 = sceKernelMapNamedFlexibleMemory(&addr,size,3,0,name);
}
if (ret1 == 0) {
res = addr;
if ((g_heap_param.HeapMemoryLock == 0) ||
(ret1 = sceKernelMlock(addr,size), res = addr, ret1 == 0)) goto _exit_result;
if (p_SceLibcIHeap->top == (malloc_chunk *)0x0) {
ret2 = strncmp(name,"SceKernelInternalMemory",0x18);
local_58 = 0xbbbb;
uVar2 = 0xbbbb;
goto _raise;
}
}
int sceKernelMapNamedSystemFlexibleMemory
(void **virtualAddrDest,qword length,int protections,int flags,char *name)
{
int *piVar1;
int ret1;
void *adr;
ulong unaff_retaddr;
ret1 = -0x7ffdffea;
if (((0x3fff < length) && ((length & 0x3fff) == 0)) &&
((flags & 0xffbfff6fU | protections & 0xffffffc8U) == 0)) {
adr = *virtualAddrDest;
if (((flags & 0x10U) != 0) && (adr == (void *)0x0)) {
if (0x16fffff < SDK_VERSION) {
return -0x7ffdffea;
}
flags = flags & 0xffffffef;
puts("[WARNING] map(addr=0, flags=MAP_FIXED)");
}
if (adr == (void *)0x0) {
adr = (void *)0x880000000;
if (0x83fffffff < unaff_retaddr) {
adr = (void *)0x200000000;
}
if (unaff_retaddr >> 0x23 == 0) {
adr = (void *)0x200000000;
}
}
adr = mmap(adr,length,protections,flags | 0x3000,-1,0);
if (adr != (void *)0xffffffffffffffff) {
*virtualAddrDest = adr;
ret1 = sys_mname(adr,length,name);
if (ret1 != -1) {
return 0;
}
}
piVar1 = __error();
ret1 = *piVar1 + -0x7ffe0000;
if (*piVar1 == 0) {
ret1 = 0;
}
}
return ret1;
}
int sceKernelMapNamedFlexibleMemory
(void **virtualAddrDest,qword length,int protections,int flags,char *name)
{
int iVar1;
int iVar2;
int *piVar3;
ulong unaff_retaddr;
void *local_38;
long local_30;
local_30 = __stack_chk_guard;
local_38 = *virtualAddrDest;
iVar1 = _sceKernelMapFlexibleMemory(&local_38,length,protections,flags,unaff_retaddr);
if (iVar1 == 0) {
*virtualAddrDest = local_38;
iVar2 = sys_mname(local_38,length,name);
iVar1 = 0;
if (iVar2 == -1) {
piVar3 = __error();
iVar1 = *piVar3 + -0x7ffe0000;
if (*piVar3 == 0) {
iVar1 = 0;
}
}
}
if (__stack_chk_guard == local_30) {
return iVar1;
}
__stack_chk_fail();
}
Thanks!
updated flags
When testing on a real console I got sys_budget_get_ptype=0 so it looks like I was wrong about the system mode.