NID Explained

This is to help beginners understand what exactly an NID is and what they are used for (content was originally posted on lan.st forums).

Just casually speaking, I usually use “nid” interchangeably to mean either the 32bit hash or the function name that belongs to that hash.

Technically though, an “nid” is a Name Identifier (SCE’s terminology). That is, a value that is used to identify a name. It is a 32bit hex value that is taken from the first 32bits of the SHA1 hash of a name (in little endian format).

Example: for the name “HelloWorld”,

- the SHA1 hash of the string:

C:
  1. db 8a c1 c2 59 eb 89 d4 a1 31 b2 53 ba cf ca 5f 31 9d 54 f2

- the first 32bits are:

C:
  1. db 8a c1 c2

- and in little endian format, makes:

C:
  1. 0xc2c18adb

Therefore 0xc2c18adb is then the Name Identifier (the NID) for the name “HelloWorld”.

SCE uses these nids to identify the imports/exports of a module. We do not know the original names of these functions. However, since we know the nids (the hash of the name of the functions) we can run a dictionary brute force attack on the nids to crack the original names.

Though there’s a bit more skill to actually crack them. Firstly, you need to correctly guess the prefix; secondly, you need to be able to differentiate real hits from false positives (since the nid is only using 32bits of the hash, you will get a LOT of false positives); and thirdly, you need to be able to carefully choose a good dictionary (again because of false positives). It also helps to target individual functions, knowing what the function does helps in guessing its name and hence building a good dictionary for it.

From fw 3.70 and onwards, SCE started “randomising” the nids so they could no longer be cracked via a dictionary brute force. These new nids are not actually “random” but instead, they now append a new 128bit “randomising key” to the end of each string before the SHA1 hash is calculated. A 128bit value is almost impossible to bruteforce practically so these new nids cannot be cracked anymore.

The randomising key is changed every few fw updates which means the nids also get changed in each of those updates. So now new functions and new libs added after 3.70 will probably also remain unknown.