Module
Version |
World |
Privilege
|
1.69-3.60 |
Non-secure |
Kernel
|
Libraries
Known NIDs
SceNetPsForDriver
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;
};
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 can't use this logic to call sceNetPsMalloc with a custom heap.
common function
sceNetPsMallocHeapInitialization
Version |
Offset |
Mode
|
3.60 |
0x1C9C |
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
|
void *sceNetPsMalloc(SceSize size, char flags, SceSize align);
sceNetPsFree
Version |
Offset |
Mode
|
3.35 |
0x5A40 |
Thumb
|
3.60 |
0x598C |
Thumb
|
Return type may not be correct
void sceNetPsFree(void *ptr);