NID

From PS3 Developer wiki
Revision as of 19:40, 23 December 2019 by CelesteBlue (talk | contribs) (Created page with "= NID generation = == PS3 NIDs == === PS3 exports === ps3_nid_suffix: 6759659904250490566427499489741A To calculate FNID value of exported/imported symbol from .PRX you ne...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

NID generation

PS3 NIDs

PS3 exports

ps3_nid_suffix: 6759659904250490566427499489741A

To calculate FNID value of exported/imported symbol from .PRX you need to take SHA-1 hash over concatenation of symbol's name and ps3_nid_suffix and then grab first 4 bytes from it and reverse these bytes (because of little-endian). Let's take, for example, _sys_sprintf:

 SHA1('_sys_sprintf' + '\x67\x59\x65\x99\x04\x25\x04\x90\x56\x64\x27\x49\x94\x89\x74\x1A') = FEEAF9A123D7D1A7619B40CD52500F9735A852A4
 FNID('_sys_sprintf') = swap_uint32(0xFEEAF9A1) = 0xA1F9EAFE.

For C++ functions you should use mangled representation of symbol's name. For example, mangled name of std::runtime_error::what() const is _ZNKSt13runtime_error4whatEv and FNID('_ZNKSt13runtime_error4whatEv') = 0x5333BDC9.

More complex example: FNID(mangle('std::basic_filebuf<wchar_t, std::char_traits<wchar_t> >::seekpos(std::fpos<std:: _Mbstatet>, std::_Iosb<int>::_Openmode)')) = FNID('_ZNSt13basic_filebufIwSt11char_traitsIwEE7seekposESt4fposISt9_MbstatetENSt5_IosbIiE9_OpenmodeE') = 0xB6A4D760

PS3 NONAME exports

ps3_noname_nid_suffix: 0xbc5eba9e042504905b64274994d9c41f

For import stubs with no names, you must use SHA1 over concatenation of symbol's name and ps3_noname_nid_suffix as an ascii string. Some examples of noname imports are module_start, module_info, and module_stop. SHA1('module_info' + '0xbc5eba9e042504905b64274994d9c41f') = 1630f4d70bf3df419db9d481983411fd3130482a = 0xD7F43016

Generation code

Here is some code in C# with the example "sys_crash_dump_get_user_log_area":

 void main() { 
   byte[] input = GetBytes(BitConverter.ToString(Encoding.UTF8.GetBytes("sys_crash_dump_get_user_log_area")).Replace("-","") + "6759659904250490566427499489741A");
   Console.WriteLine(BitConverter.ToInt32( SHA1CryptoServiceProvider.Create().ComputeHash(input) ,0 ).ToString("X0"));
 }

 byte[] GetBytes(string str) {
   byte[] bytes = new byte[str.Length / 2];
   for (int i = 0; i < str.Length; i += 2)
       bytes[i / 2] = byte.Parse(str.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
   return bytes;
 }