main.x 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /**
  2. * AppEnabler for nitoTV
  3. *
  4. * Makes it possible to load Applications from /var/mobile/Applications
  5. *
  6. * By Luca Todesco and Kevin Bradley
  7. *
  8. */
  9. #import <Foundation/Foundation.h>
  10. #include <mach-o/dyld.h>
  11. #import <objc/runtime.h>
  12. //#import "rocketbootstrap.h"
  13. //#import "AppSupport/CPDistributedMessagingCenter.h"
  14. #import "../PBReloadHelper.h"
  15. #import <Foundation/Foundation.h>
  16. #import "AppSupport/CPDistributedMessagingCenter.h"
  17. @interface NSDistributedNotificationCenter : NSNotificationCenter
  18. + (id)defaultCenter;
  19. - (void)addObserver:(id)arg1 selector:(SEL)arg2 name:(id)arg3 object:(id)arg4;
  20. - (void)postNotificationName:(id)arg1 object:(id)arg2 userInfo:(id)arg3;
  21. @end
  22. @interface MessageHandler : NSObject
  23. -(void)runAppEnabler:(id)a;
  24. @end
  25. @implementation MessageHandler
  26. -(void)runAppEnabler:(id)a
  27. {
  28. //NSLog(@"#### for luck!");
  29. [PBReloadHelper reloadApplications];
  30. }
  31. @end
  32. %class LSContext
  33. %class FSNode
  34. /*
  35. Some fun magic happens in here. We hook _MobileInstallationEnumerateAllInstalledItemDictionaries
  36. in tvOS 10 and _MobileInstallationCopyInstalledAppsForLaunchServices in tvOS 9 to inject
  37. our "whitelist" of applications that is created during uicache process.
  38. */
  39. //tvOS 10 function for _MobileInstallationEnumerateAllInstalledItemDictionaries
  40. id (*original_func)(uint64_t a, id b);
  41. //tvOS 9 function for _MobileInstallationCopyInstalledAppsForLaunchServices
  42. id (*original_func2)(uint64_t a);
  43. //hook for _MobileInstallationCopyInstalledAppsForLaunchServices
  44. id we_really_out_here_nine(uint64_t a)
  45. {
  46. /*
  47. in tvOS 9 this list is just one huge plist that we need to inject ourselves into the
  48. System key of.
  49. */
  50. id retv = original_func2(a);
  51. //read the list created in uicache of apps to inject
  52. NSString* pth = @"/var/mobile/Library/Preferences/kjc.appenabler.state.plist";
  53. NSArray* arr = [NSArray arrayWithContentsOfFile: pth];
  54. if(!arr) return retv;
  55. NSLog(@"got apps to inject!!");
  56. [retv autorelease];
  57. retv = [retv mutableCopy];
  58. NSLog(@"retv allKeys:%@", [(NSDictionary*)retv allKeys]);
  59. //get the System key of the installed plist
  60. id sysdb = retv[@"System"];
  61. id pkp = retv[@"PluginKitPlugin"];
  62. if(sysdb){
  63. NSLog(@"injecting to system apps");
  64. sysdb=[sysdb mutableCopy];
  65. pkp=[pkp mutableCopy];
  66. retv[@"System"] = sysdb;
  67. retv[@"PluginKitPlugin"] = pkp;
  68. for (NSDictionary* appb in arr)
  69. {
  70. NSString *appType = appb[@"ApplicationType"];
  71. if (![appType isEqualToString:@"PluginKitPlugin"])
  72. {
  73. NSLog(@"injecting %@", appb[@"CFBundleIdentifier"]);
  74. if (sysdb[appb[@"CFBundleIdentifier"]])
  75. {
  76. NSLog(@"already present!! WTF??? overwriting..");
  77. }
  78. //add current CFBundleIdentifier to System bundle
  79. sysdb[appb[@"CFBundleIdentifier"]] = appb;
  80. } else { //its a plugin
  81. NSLog(@"injecting %@", appb[@"CFBundleIdentifier"]);
  82. if (pkp[appb[@"CFBundleIdentifier"]])
  83. {
  84. NSLog(@"already present!! WTF??? overwriting..");
  85. }
  86. //add current CFBundleIdentifier to System bundle
  87. pkp[appb[@"CFBundleIdentifier"]] = appb;
  88. }
  89. }
  90. }
  91. //NSLog(@"return: %@",retv);
  92. //at this point we've injected our bundle ids into the System list/
  93. //from here, some other process adds the entry to PBAppDepot for us! :)
  94. return retv;
  95. }
  96. //hook for _MobileInstallationEnumerateAllInstalledItemDictionaries
  97. id we_really_out_here(uint64_t a, uint64_t (^block)(id b1, uint64_t b2, uint64_t b3))
  98. {
  99. //NSLog(@"Stack trace : %@",[NSThread callStackSymbols]);
  100. //define the return block
  101. uint64_t (^blockz)(id b1, uint64_t b2, uint64_t b3) = ^(id b1, uint64_t b2, uint64_t b3){
  102. //NSLog(@"called!!! %@ %llx %llx", b1, b2, b3);
  103. return block(b1, b2, b3);
  104. };
  105. //load our whitelist that is created in uicache
  106. NSString* pth = @"/var/mobile/Library/Preferences/kjc.appenabler.state.plist";
  107. NSArray* arr = [NSArray arrayWithContentsOfFile: pth];
  108. //get original return value
  109. id retv = original_func(a, blockz);
  110. //NSLog(@"crack out of coke");
  111. //loop through our apps an call the block to add the application to the list,
  112. //from here it will be added to PBAppDepot automatically, but in a disabled state.
  113. for (NSDictionary* appb in arr)
  114. {
  115. //blockz(@{@"ApplicationType": @"System", @"CFBundleIdentifier": appb[0], @"CodeInfoIdentifier": appb[0], @"Path": appb[1]},0,0);
  116. blockz(appb,0,0);
  117. }
  118. return retv;
  119. }
  120. %ctor
  121. {
  122. dlopen("/System/Library/PrivateFrameworks/MobileInstallation.framework/MobileInstallation", RTLD_LAZY);
  123. MSImageRef gangshit = MSGetImageByName("/System/Library/PrivateFrameworks/MobileInstallation.framework/MobileInstallation");
  124. //tvos 10 symbol
  125. void* weouthere = MSFindSymbol(gangshit, "_MobileInstallationEnumerateAllInstalledItemDictionaries");
  126. NSLog(@"tvOS 10 hooking %p", weouthere);
  127. if (weouthere)
  128. {
  129. MSHookFunction((void*)weouthere, (void*)we_really_out_here, (void**)&original_func);
  130. //void (*lolz)() = weouthere;
  131. //lolz();
  132. }
  133. //tvos 9 symbol
  134. void* weouthere2 = MSFindSymbol(gangshit, "_MobileInstallationCopyInstalledAppsForLaunchServices");
  135. NSLog(@"ios 9 hooking %p", weouthere2);
  136. if (weouthere2)
  137. {
  138. MSHookFunction((void*)weouthere2, (void*)we_really_out_here_nine, (void**)&original_func2);
  139. //void (*lolz)() = weouthere;
  140. //lolz();
  141. }
  142. //NSLog(@"before note center");
  143. NSDistributedNotificationCenter* notificationCenter = [NSDistributedNotificationCenter defaultCenter];
  144. //NSLog(@"after note center");
  145. [notificationCenter addObserver:[MessageHandler new] selector:@selector(runAppEnabler:) name:@"kjc.AppEnabler.recache" object:nil];
  146. // NSLog(@"after observe");
  147. }