FLEXAddressExplorerCoordinator.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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 "FLEXGlobalsTableViewController.h"
  10. #import "FLEXObjectExplorerFactory.h"
  11. #import "FLEXObjectExplorerViewController.h"
  12. #import "FLEXRuntimeUtility.h"
  13. #import "FLEXUtility.h"
  14. @interface FLEXGlobalsTableViewController (FLEXAddressExploration)
  15. - (void)deselectSelectedRow;
  16. - (void)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely;
  17. @end
  18. @implementation FLEXAddressExplorerCoordinator
  19. #pragma mark - FLEXGlobalsTableViewControllerEntry
  20. + (NSString *)globalsEntryTitle {
  21. return @"🔎 Address Explorer";
  22. }
  23. + (FLEXGlobalsTableViewControllerRowAction)globalsEntryRowAction {
  24. return ^(FLEXGlobalsTableViewController *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. UIAlertController *addressInput = [UIAlertController alertControllerWithTitle:title
  30. message:message
  31. preferredStyle:UIAlertControllerStyleAlert];
  32. void (^handler)(UIAlertAction *) = ^(UIAlertAction *action) {
  33. if (action.style == UIAlertActionStyleCancel) {
  34. [host deselectSelectedRow]; return;
  35. }
  36. NSString *address = addressInput.textFields.firstObject.text;
  37. [host tryExploreAddress:address safely:action.style == UIAlertActionStyleDefault];
  38. };
  39. [addressInput addTextFieldWithConfigurationHandler:^(UITextField *textField) {
  40. NSString *copied = [UIPasteboard generalPasteboard].string;
  41. textField.placeholder = @"0x00000070deadbeef";
  42. // Go ahead and paste our clipboard if we have an address copied
  43. if ([copied hasPrefix:@"0x"]) {
  44. textField.text = copied;
  45. [textField selectAll:nil];
  46. }
  47. }];
  48. [addressInput addAction:[UIAlertAction actionWithTitle:@"Explore"
  49. style:UIAlertActionStyleDefault
  50. handler:handler]];
  51. [addressInput addAction:[UIAlertAction actionWithTitle:@"Unsafe Explore"
  52. style:UIAlertActionStyleDestructive
  53. handler:handler]];
  54. [addressInput addAction:[UIAlertAction actionWithTitle:@"Cancel"
  55. style:UIAlertActionStyleCancel
  56. handler:handler]];
  57. [host presentViewController:addressInput animated:YES completion:nil];
  58. };
  59. }
  60. @end
  61. @implementation FLEXGlobalsTableViewController (FLEXAddressExploration)
  62. - (void)deselectSelectedRow {
  63. NSIndexPath *selected = self.tableView.indexPathForSelectedRow;
  64. [self.tableView deselectRowAtIndexPath:selected animated:YES];
  65. }
  66. - (void)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely {
  67. NSScanner *scanner = [NSScanner scannerWithString:addressString];
  68. unsigned long long hexValue = 0;
  69. BOOL didParseAddress = [scanner scanHexLongLong:&hexValue];
  70. const void *pointerValue = (void *)hexValue;
  71. NSString *error = nil;
  72. if (didParseAddress) {
  73. if (safely && ![FLEXRuntimeUtility pointerIsValidObjcObject:pointerValue]) {
  74. error = @"The given address is unlikely to be a valid object.";
  75. }
  76. } else {
  77. error = @"Malformed address. Make sure it's not too long and starts with '0x'.";
  78. }
  79. if (!error) {
  80. id object = (__bridge id)pointerValue;
  81. FLEXObjectExplorerViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:object];
  82. [self.navigationController pushViewController:explorer animated:YES];
  83. } else {
  84. [FLEXUtility alert:@"Uh-oh" message:error from:self];
  85. [self deselectSelectedRow];
  86. }
  87. }
  88. @end