FLEXAddressExplorerCoordinator.m 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //
  2. // FLEXAddressExplorerCoordinator.m
  3. // FLEX
  4. //
  5. // Created by Tanner Bennett on 7/10/19.
  6. // Copyright © 2019 Flipboard. All rights reserved.
  7. //
  8. #import "FLEXAddressExplorerCoordinator.h"
  9. #import "FLEXGlobalsViewController.h"
  10. #import "FLEXObjectExplorerFactory.h"
  11. #import "FLEXObjectExplorerViewController.h"
  12. #import "FLEXRuntimeUtility.h"
  13. #import "FLEXUtility.h"
  14. @interface UITableViewController (FLEXAddressExploration)
  15. - (void)deselectSelectedRow;
  16. - (void)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely;
  17. @end
  18. @implementation FLEXAddressExplorerCoordinator
  19. #pragma mark - FLEXGlobalsEntry
  20. + (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row {
  21. return @"🔎 Address Explorer";
  22. }
  23. + (FLEXGlobalsEntryRowAction)globalsEntryRowAction:(FLEXGlobalsRow)row {
  24. return ^(UITableViewController *host) {
  25. NSString *title = @"Explore Object at Address";
  26. NSString *message = @"Paste a hexadecimal address below, starting with '0x'. "
  27. "Use the unsafe option if you need to bypass pointer validation, "
  28. "but know that it may crash the app if the address is invalid.";
  29. [FLEXAlert makeAlert:^(FLEXAlert *make) {
  30. make.title(title).message(message);
  31. make.configuredTextField(^(UITextField *textField) {
  32. NSString *copied = UIPasteboard.generalPasteboard.string;
  33. textField.placeholder = @"0x00000070deadbeef";
  34. // Go ahead and paste our clipboard if we have an address copied
  35. if ([copied hasPrefix:@"0x"]) {
  36. textField.text = copied;
  37. [textField selectAll:nil];
  38. }
  39. });
  40. make.button(@"Explore").handler(^(NSArray<NSString *> *strings) {
  41. [host tryExploreAddress:strings.firstObject safely:YES];
  42. });
  43. make.button(@"Unsafe Explore").destructiveStyle().handler(^(NSArray *strings) {
  44. [host tryExploreAddress:strings.firstObject safely:NO];
  45. });
  46. make.button(@"Cancel").cancelStyle();
  47. } showFrom:host];
  48. };
  49. }
  50. @end
  51. @implementation UITableViewController (FLEXAddressExploration)
  52. - (void)deselectSelectedRow {
  53. NSIndexPath *selected = self.tableView.indexPathForSelectedRow;
  54. [self.tableView deselectRowAtIndexPath:selected animated:YES];
  55. }
  56. - (void)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely {
  57. NSScanner *scanner = [NSScanner scannerWithString:addressString];
  58. unsigned long long hexValue = 0;
  59. BOOL didParseAddress = [scanner scanHexLongLong:&hexValue];
  60. const void *pointerValue = (void *)hexValue;
  61. NSString *error = nil;
  62. if (didParseAddress) {
  63. if (safely && ![FLEXRuntimeUtility pointerIsValidObjcObject:pointerValue]) {
  64. error = @"The given address is unlikely to be a valid object.";
  65. }
  66. } else {
  67. error = @"Malformed address. Make sure it's not too long and starts with '0x'.";
  68. }
  69. if (!error) {
  70. id object = (__bridge id)pointerValue;
  71. FLEXObjectExplorerViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:object];
  72. [self.navigationController pushViewController:explorer animated:YES];
  73. } else {
  74. [FLEXAlert showAlert:@"Uh-oh" message:error from:self];
  75. [self deselectSelectedRow];
  76. }
  77. }
  78. @end