facebook_messenger_friends.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. const log = require('../util/log')
  2. const path = require('path')
  3. const sqlite3 = require('sqlite3')
  4. const bplist = require('bplist-parser')
  5. const fs = require('fs')
  6. const plist = require('plist')
  7. // Derive filenames based on domain + file path
  8. const fileHash = require('../util/backup_filehash')
  9. const domain = 'AppDomainGroup-group.com.facebook.Messenger'
  10. module.exports.name = 'facebook_messenger_friends'
  11. module.exports.description = 'Show Facebook Messenger friends'
  12. // Specify this only works for iOS 9+
  13. module.exports.supportedVersions = '>=10.0'
  14. // Specify this reporter requires a backup.
  15. // The second parameter to func() is now a backup instead of the path to one.
  16. module.exports.requiresBackup = true
  17. // Specify this reporter supports the promises API for allowing chaining of reports.
  18. module.exports.usesPromises = true
  19. // You can also provide an array of functions instead of using `module.exports.func`.
  20. // These functions *should* be independent ranges to ensure reliable execution
  21. module.exports.functions = {
  22. '>=10.0': function (program, backup, resolve, reject) {
  23. // This function would be called for iOS 10+
  24. backup.getFileManifest()
  25. .then((items) => {
  26. let filename = 'fbomnistore.db'
  27. let fileitem = items.find((file) => {
  28. if (file && file.relativePath)
  29. return ~file.relativePath.indexOf(filename)
  30. return false
  31. })
  32. if (fileitem) {
  33. let filepath = fileitem.relativePath
  34. let file = fileHash(filepath, domain)
  35. return facebookMessengerFriendsReport(backup, file)
  36. } else return [] // Return an empty array to the formatter, since no fbomnistore.db file can be found in the manifest
  37. })
  38. .then((items) => {
  39. var result = program.formatter.format(items, {
  40. program: program,
  41. columns: {
  42. 'Facebook Friend Usernames': el => el.field_value
  43. }
  44. })
  45. resolve(result)
  46. })
  47. .catch((e) => {
  48. console.log('[!] Encountered an Error:', e)
  49. })
  50. },
  51. '>=5.0,<10.0': function (program, backup, resolve, reject) {
  52. // This function would be called for all iOS 5 up to iOS 9.x.
  53. // TODO
  54. /*backup.getOldFileManifest()
  55. .then((items) => {
  56. var result = program.formatter.format(items, {
  57. program: program,
  58. columns: {
  59. 'Facebook Friend Username': el => el.field_value
  60. }
  61. })
  62. resolve(result)
  63. })
  64. .catch(reject)*/
  65. }
  66. }
  67. const facebookMessengerFriendsReport = (backup, file) => {
  68. return new Promise((resolve, reject) => {
  69. var database = backup.getDatabase(file)
  70. try {
  71. database.get(`
  72. SELECT name
  73. FROM sqlite_master
  74. WHERE type='table'
  75. AND name LIKE 'collection_index#messenger_contacts_ios%'
  76. LIMIT 1
  77. `,
  78. (err, table_name) => {
  79. table_name = table_name.name
  80. console.log("Table", table_name)
  81. database.all(`
  82. SELECT field_value
  83. FROM '${table_name}'
  84. WHERE field_name='username'
  85. `, (err, rows) => {
  86. resolve(rows)
  87. })
  88. })
  89. } catch (e) {
  90. reject(e)
  91. }
  92. })
  93. }