obliteration icon indicating copy to clipboard operation
obliteration copied to clipboard

Find out what is flag & 0x2000 on mmap

Open ultimaweapon opened this issue 2 years ago • 10 comments

It is not MAP_GUARD.

ultimaweapon avatar Oct 23 '23 11:10 ultimaweapon

 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;   

red-prig avatar Oct 23 '23 13:10 red-prig

Thanks!

ultimaweapon avatar Oct 23 '23 13:10 ultimaweapon

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.

red-prig avatar Oct 23 '23 14:10 red-prig

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.

ultimaweapon avatar Oct 23 '23 14:10 ultimaweapon

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?

red-prig avatar Oct 23 '23 16:10 red-prig

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?

ultimaweapon avatar Oct 23 '23 16:10 ultimaweapon

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();
}

red-prig avatar Oct 23 '23 16:10 red-prig

Thanks!

ultimaweapon avatar Oct 23 '23 16:10 ultimaweapon

updated flags

red-prig avatar Dec 19 '23 20:12 red-prig

When testing on a real console I got sys_budget_get_ptype=0 so it looks like I was wrong about the system mode.

red-prig avatar Dec 26 '23 17:12 red-prig