jjzjj

ios - iOS-将 “objects”添加到现有应用中(越狱)

coder 2023-07-25 原文

如何将“对象”添加到现有应用程序?

例如,EasyRefresh for Chrome调整与其他许多调整一样,在iOS Chrome应用中启用了一个新按钮。

我如何在Twitter应用程序中添加简单的UIButton

有没有GitHub项目可以帮助我了解它的完成方式?



图片来源:ModMyI

谢谢。

最佳答案

这个技巧涉及到一些(非常基础的)逆向工程,并且由几个步骤组成。我将尝试尽可能清楚地解释它们。

步骤零:(如果从AppStore下载了该应用程序,则该应用程序已加密)。您必须使用通常用于破解应用程序的脚本/应用程序之一对其进行解密。一个命令行脚本是poedCrack.sh(在Google上,您会在其中一个粘贴站点上快速找到它),一个GUI应用程序是Crakculous(在Cydia中可用)。请注意,其中的一个是进行简单(自动)解密所必需的-手动解密方法过于繁琐,无法放入StackOverflow答案,这就是我建议使用这些工具的原因。)但是,我绝不鼓励您破解应用程序! (基本上,我要您不要将这些工具用于其原始用途:)如果您想看看手动解密过程,head here.

第一步:,您需要执行应用程序使用/创建的类。为此,您需要class-dump或class-dump-z实用程序。此命令行应用程序会反转应用程序的二进制可执行文件,并为应用程序使用并包含在其中的所有Objective-C类生成接口(interface)声明。您可以找到class-dump-z,它是更高级和首选的变体here.

第二步:有了类声明后,您将不得不猜测哪个类在什么时候以及什么时候做(是的,有点令人困惑)。例如,在从上面的应用程序Google Chrome通过class-dump-z生成的文件之一中,您可能会找到类似的内容:

@interface ChromeUrlToolbar: UIToolbar {
    UISearchBar *urlBar;
}

- (id)initWithFrame:(CGRect)frame;
- (void)loadURL:(NSURL *)url;

@end

好吧,听起来不错,不是吗?您可以看到其实现具有initWithFrame:方法(与所有UIView子类一样)-为什么不尝试对其进行修改?

第三步:进行此修改,您需要MobileSubstrate。 MobileSubstrate是由Cydia的创建者Saurik创建的开发人员库,旨在简化向应用程序的代码注入(inject)。您可以在网上找到一些非常好的教程,包括this one
因此,您已经有了一个类,并且想“钩住”它-因此您可以编写如下代码:
static IMP __original_init; // A

id __modified_init(id __self, SEL __cmd, CGRect frame) // B
{
    __self = __original_init(__self, __cmd, frame); // C

    // D
    UIButton *newButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [newButton setTitle:@"Chrome Pwned"];
    newButton.frame = CGRectMake(0, 0, 100, 40);
    [__self addSubview:newButton];

    return __self;
}

// E
__attribute__((constructor))
void init()
{
    Class clazz = objc_getClass("ChromeUrlToolbar"); // F
    MSHookMessageEx(clazz, @selector(initWithFrame:), __modified_init, &__original_init); // G
}

说明:让我们从头开始。 init函数(E)被声明为__attribute__((constructor))。这意味着当我们将根据这些代码创建的库加载到Chrome中时,系统会自动调用它。这正是我们想要的,因为我们要在启动应用程序之前更改其行为。

在标记为// F的行上,我们捕获了要修改的类对象本身。 Objective-C是一种高度动态的语言;这意味着我们可以在运行时获取和修改有关类和对象的信息。在标记为// G的行上,我们使用了MobileSubstrate API的最重要功能:MSHookMes​​sageEx。要了解它是如何工作的(而不是它是做什么的),您必须了解以下内容:Objective-C本身是作为纯C库实现的-语言本身在幕后就是简单的C。因此,每个以Obejctive发送的消息-C实际上是一个C函数调用。这些C函数具有两个特殊参数:selfcmd -前者是指向要发送消息的对象的指针,后者是选择器(指向要发送的消息名称的特殊,唯一的指针)。因此,MSHookMes​​sageEx要做的是获取一个类和一个选择器,找到与它们相对应的函数的实现,然后将该函数与第3个参数本身提供的函数(在这种情况下为__modified_init)进行交换。为了不丢失数据,它还会在其第4个参数(此处为__original_init)中返回该函数。

那么,现在Chrome URL工具栏的初始化已重定向到我们的函数,下一步该怎么做?好吧,没什么特别的:首先,我们只调用原始的初始化函数(注意前两个特殊参数__self和__cmd!),它会像通常一样创建工具栏(此行代码由// C表示)。然后,我们进行实际的更改:在// D部分中,我们创建一个UIButton,设置其标题和位置,并将其作为 subview 添加到我们新创建的工具栏中。然后,知道这是一个初始化函数,我们返回原始实例以及注入(inject)到其中的按钮代码。

好吧,基本上这就是您需要了解的内容;如果您对Objective-C的工作原理以及如何创建漂亮的iOS调整的详细信息感兴趣,建议您阅读Apple的official documentation on the topic,也可以浏览some of my opensource Cydia tweaks.

我希望这能帮到您!

关于ios - iOS-将 “objects”添加到现有应用中(越狱),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11572265/

有关ios - iOS-将 “objects”添加到现有应用中(越狱)的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  3. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  4. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  5. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  6. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  7. ruby-on-rails - Rails 应用程序中的 Rails : How are you using application_controller. rb 是新手吗? - 2

    刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr

  8. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  9. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  10. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

随机推荐