SceNetPs: Difference between revisions
CelesteBlue (talk | contribs) (→Module) |
CelesteBlue (talk | contribs) No edit summary |
||
Line 1: | Line 1: | ||
== Module == | == Module == | ||
SceNetPs module is stored in file bootfs:net_ps.elf and since | 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 | 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. | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 20: | Line 20: | ||
! Version !! Name !! World !! Visibility !! NID | ! Version !! Name !! World !! Visibility !! NID | ||
|- | |- | ||
| | | 0.990.000-3.740.011 || [[SceNetPs#SceNetPsForDriver|SceNetPsForDriver]] || Non-secure || Kernel || 0xB2A5C920 | ||
|- | |- | ||
| 1. | | 1.000.071-3.740.011 || [[SceNetPs#SceNetPsForSyscalls|SceNetPsForSyscalls]] || Non-secure || User || 0x2CBED2C6 | ||
|} | |} | ||
== Types == | |||
<source lang="c"> | <source lang="c"> | ||
struct netdev_t | struct netdev_t { | ||
{ | |||
netdev_t *next; | netdev_t *next; | ||
netdev_t *prev; | netdev_t *prev; | ||
Line 78: | Line 74: | ||
}; | }; | ||
struct netdev_2_t | struct netdev_2_t { | ||
netdev_t *netdev; | netdev_t *netdev; | ||
int mask; | int mask; | ||
Line 121: | Line 116: | ||
}; | }; | ||
struct netdev_3_t | struct netdev_3_t { | ||
{ | |||
netdev_2_t *netdev_2_ptr; | netdev_2_t *netdev_2_ptr; | ||
int field_4; | int field_4; | ||
Line 158: | Line 152: | ||
int field_0; | int field_0; | ||
}; | }; | ||
</source> | |||
== SceNetPsForDriver == | |||
=== sceNetListenForDriver === | === sceNetListenForDriver === | ||
Line 535: | Line 530: | ||
Note that "MaAk" is appended right after the user provided "size" bytes, so it might not be aligned. | 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 | Also these implementations are completely part of SceNetPs so you cannot use this logic to call sceNetPsMalloc with a custom heap. | ||
== | == Subroutines == | ||
=== sceNetPsMallocHeapInitialization === | === sceNetPsMallocHeapInitialization === | ||
Line 584: | Line 579: | ||
|} | |} | ||
Return type may | Return type may be wrong. | ||
<source lang="C">void sceNetPsFree(void *ptr);</source> | <source lang="C">void sceNetPsFree(void *ptr);</source> | ||
[[Category:Modules]] | [[Category:Modules]] | ||
[[Category:Kernel]] | [[Category:Kernel]] |
Revision as of 02:37, 26 February 2023
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:
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);