SceNetPs

From Vita Development Wiki
Revision as of 21:21, 1 May 2023 by Princess of Sleeping (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Module

SceNetPs module is stored in file bootfs:net_ps.elf and since System Software version 3.61 also in os0:kd/net_ps_dev.skprx.

net_ps_dev.skprx was introduced in System Software 3.61 to patch HENkaku kernel exploit. net_ps_dev.skprx exists only in DevKit os0: and is loaded instead of net_ps.skprx only in development mode. Exported functions in dev net_ps are the same as in non-dev net_ps.

Version World Privilege
1.69-3.74 Non-secure Kernel

Libraries

Known NIDs

Version Name World Visibility NID
0.990.000-3.740.011 SceNetPsForDriver Non-secure Kernel 0xB2A5C920
1.000.071-3.740.011 SceNetPsForSyscalls Non-secure User 0x2CBED2C6

Types

struct netdev_t {
  netdev_t *next;
  netdev_t *prev;
  void *(__cdecl *fnc_alloc)(netdev_t *, unsigned int, int); // filed by netps
  int (__cdecl *fnc_free)(netdev_t *, void *); // filed by netps
  int (__cdecl *fnc_dev_pbuf_alloc)(netdev_t *result, int a2, int a3); // filed by netps
  int (__cdecl *field_14)(netdev_t *result, int a2, int a3); // filed by netps
  int (__cdecl *fnc_dev_pbuf_free)(netdev_t *result, int a2); // filed by netps
  int (__cdecl *fnc_pkt_rx)(netdev_t *result, int a2); // filed by netps
  _BYTE *(__fastcall *fnc_get_tx_pbuf)(netdev_t *result); // filed by netps
  int (__cdecl *field_24)(netdev_t *a1, int a); // filed by netps
  int (__cdecl *field_28)(netdev_t *result, int a2); // filed by netps
  int field_2C;
  int field_30;
  netdev_2_t *netdev_2_ptr;
  int (__fastcall *field_38)(netdev_t *); // filed by device driver
  int (__fastcall *field_3C)(netdev_t *); // filed by device driver
  int (__cdecl *field_40)(netdev_t *); // filed by device driver
  int (__cdecl *field_44)(netdev_t *); // filed by device driver
  int (__cdecl *fnc_tx_pkt)(netdev_t *); // filed by device driver
  int (__fastcall *fnc_multicast_filter)(netdev_t *, _BYTE *, unsigned int); // filed by device driver
  int (__fastcall *fnc_ioctl)(netdev_t *devstruct, unsigned int req, void *buf, int buf_len); // filed by device driver
  int field_54;  // filed by device driver
  int dev_type; // filed by device driver
  char mac_address[8]; // filed by device driver
  int mtu; // filed by device driver
  int aggr_smt; // filed by device driver
  void *priv; // filed by device driver
  int field_70;
  int field_74;
  int tx_bytes;
  int tx_pkts;
  int tx_bcast_bytes;
  int tx_bcast_pkts;
  int tx_mcast_bytes;
  int tx_mcast_pkts;
  int rx_bytes;
  int rx_pkts;
  int rx_bcast_bytes;
  int rx_bcast_pkts;
  int rx_mcast_bytes;
  int rx_mcast_pkts;
  int field_A8;
  int field_AC;
};

 struct netdev_2_t {
   netdev_t *netdev;
   int mask;
   int field_8;
   int field_C;
   int field_10;
   int field_14;
   int field_18;
   int field_1C;
   int field_20;
   int field_24;
   int field_28;
   int field_2C;
   netdev_3_t *netdev_3_ptr;
   int field_34;
   int field_38;
   int field_3C;
   int field_40;
   int field_44;
   int field_48;
   int field_4C;
   int field_50;
   int field_54;
   _BYTE gap58[164];
   int field_58;
   _BYTE gap100[24];
   int field_118;
   int field_11C;
   int field_120;
   _BYTE gap124[8];
   int field_12C;
   int field_130;
   int field_134;
   int field_138;
   int field_13C;
   int field_140;
   _BYTE gap144[232];
   int field_5C;
   _BYTE gap230[300];
   int field_60;
 };

struct netdev_3_t {
  netdev_2_t *netdev_2_ptr;
  int field_4;
  int field_8;
  int field_C;
  _BYTE gap10[4];
  char name[16];
  _BYTE gap24[12];
  int field_30;
  __attribute__((aligned(8))) char field_38;
  char field_39;
  __attribute__((aligned(8))) int mtu;
  int field_44;
  _BYTE gap48[100];
  char field_AC;
  _BYTE gapAD[11];
  int (__cdecl *field_B8)(void *result, int a2);
  int (__cdecl *field_BC)(void *result, int a2);
  int (__cdecl *field_C0)(netdev_t *result, int a2);
  int (__cdecl *field_C4)(netdev_t *result, int a2);
  int field_C8;
  int field_CC;
  int field_D0;
  int field_D4;
  _BYTE gapD8[64];
  int field_118;
  _BYTE gap11C[60];
  int flag;
  int flag2;
  _BYTE gap160[8];
  int field_168;
  _BYTE gap16C[12];
  int field_178;
  _BYTE gap17C[120];
  int field_0;
};

SceNetPsForDriver

sceNetListenForDriver

Version NID
3.60 0x080C7992

sceNetConnectForDriver

Version NID
3.60 0x13491DA1

sceNetCloseForDriver

Version NID
3.60 0x21F4428D

sceNetRecvfromForDriver

Version NID
3.60 0x49B1669C

sceNetSetsockoptForDriver

Version NID
3.60 0x4BF5FAB4

sceNetBindForDriver

Version NID
3.60 0x84AB650F

sceNetAcceptForDriver

Version NID
3.60 0x880A5423

sceNetGetsocknameForDriver

Version NID
3.60 0x8F1BB0E7

sceNetGetsockoptForDriver

Version NID
3.60 0x92EE24A6

sceNetSendtoForDriver

Version NID
3.60 0xAB746734

sceNetGetpeernameForDriver

Version NID
3.60 0xB949AFD5

sceNetSocketForDriver

Version NID
3.60 0xEB95B024

sceNetShutdownForDriver

Version NID
3.60 0xEEB19FB6

sceNetRegisterDeviceForDriver

Version NID
3.60 0x1ABF937D

Registers network interface in OS.

Fills netdev_t structure with OS functions, allocates netdev2_t and netdev3_t structures and finally adds interface to global interface linked-list.

int sceNetRegisterDeviceForDriver(netdev_t *);

SceNetPsForSyscalls

sceNetSyscallSetsockopt

Version NID
1.69 0x10DE34EA

sceNetSyscallRecvfrom

Version NID
1.69 0x144C9758

sceNetSyscallConnect

Version NID
1.69 0x14A4DE52

sceNetSyscallClose

Version NID
1.69 0x1EBC2E28

sceNetSyscallDumpClose

Version NID
1.69 0x263E52FD

sceNetSyscallBind

Version NID
1.69 0x267F1EF9

sceNetSyscallIoctl

Version NID
1.69 0x310F0725

sceNetSyscallRecvmsg

Version NID
1.69 0x32C1AE45

sceNetSyscallSendto

Version NID
1.69 0x39796C01

sceNetSyscallDumpRead

Version NID
1.69 0x3CBE7071

sceNetSyscallSysctl

Version NID
1.69 0x3D7495B0

sceNetSyscallDumpCreate

Version NID
1.69 0x3FC34171

sceNetSyscallAccept

Version NID
1.69 0x45EAAD89

sceNetSyscallDumpAbort

Version NID
1.69 0x5CD20B54

sceNetSyscallGetsockname

Version NID
1.69 0x6AA945D9

sceNetSyscallEpollClose

Version NID
1.69 0x75E82300

sceNetSyscallSocket

Version NID
1.69 0x81A120BE

sceNetSyscallDescriptorClose

Version NID
1.69 0x854AFB6F

sceNetSyscallGetIfList

Version NID
1.69 0x878274CE

sceNetSyscallIcmConnect

Version NID
1.69 0x8C3FBC87

sceNetSyscallEpollAbort

Version NID
1.69 0x94C3AE47

sceNetSyscallShutdown

Version NID
1.69 0xA4014519

sceNetSyscallDescriptorCtl

Version NID
1.69 0xA7064C2C

sceNetSyscallEpollCreate

Version NID
1.69 0xA98AEF04

sceNetSyscallSendmsg

Version NID
1.69 0xAEC6BE5D

sceNetSyscallListen

Version NID
1.69 0xAEEB7CA0

sceNetSyscallDescriptorCreate

Version NID
1.69 0xB518A2DE

sceNetSyscallGetsockopt

Version NID
1.69 0xBC472DC5

sceNetSyscallGetpeername

Version NID
1.69 0xBD7B0213

sceNetSyscallEpollCtl

Version NID
1.69 0xDF30BE68

sceNetSyscallControl

Version NID
1.69 0xEA0C1B71

sceNetSyscallGetSockinfo

Version NID
1.69 0xF7748E56

sceNetSyscallSocketAbort

Version NID
1.69 0xF9203B48

sceNetSyscallEpollWait

Version NID
1.69 0xF933D6FC

Custom malloc()/free() implementation

This module contains a custom malloc() and free() implementation.

In 3.35 void *malloc(SceSize size, char flags, SceSize align) is located at offset 0x57b8 and void free(void *ptr) at 0x5a40.

Another way to find them is search for immediate value 0x4D61416B, one will be in a data segment and referenced by malloc, another is an immediate value used from free.

Here's an illustration of how allocated/free chunks work:

Scenet-malloc.png

Chunks are linked to each other, but for example busy chunk and free chunk are never linked.


The primary problem with exploiting heap overflows are the red "heap cookies": BuSy, MaAk, FrEe.

When a chunk is allocated and the freelist is iterated it checks for the presence of "FrEe" on every iterated chunk.

When a chunk is freed, it checks for "BuSy" and "MaAk".

If cookies don't match, the code does an *(int*)0 = 0 which crashes the system.

Note that "MaAk" is appended right after the user provided "size" bytes, so it might not be aligned.

Also these implementations are completely part of SceNetPs so you cannot use this logic to call sceNetPsMalloc with a custom heap.

Subroutines

sceNetPsMallocHeapInitialization

Version Offset Mode
3.60 0x1C9C Thumb
3.63 (dev) 0x1E04 Thumb
// a5 is maybe SceSysEventUID

int sceNetPsMallocHeapInitialization(SceUID memblk_uid, void *heap_base, SceSize size, void *a4, int a5, int a6, int a7);

sceNetPsMalloc

Version Offset Mode
3.35 0x57B8 Thumb
3.60 0x56B4 Thumb
3.63 (dev) 0x5830 Thumb
void *sceNetPsMalloc(SceSize size, char flags, SceSize align);

sceNetPsFree

Version Offset Mode
3.35 0x5A40 Thumb
3.60 0x598C Thumb
3.63 (dev) 0x5B08 Thumb

Return type may be wrong.

void sceNetPsFree(void *ptr);