开发者社区> JoanKing> 正文

iOS逆向-day10:LLVM 编译器(下)

简介: iOS逆向-day10:LLVM 编译器(下)
+关注继续查看

四、LLVM 源码下载



  • 4.1、下载LLVM 和 下载clang
    • 创建一个文件夹 LLVM_ALL ,其他的名字也可以
    • 先下载 LLVM 到 LLVM_ALL 文件夹下 ,大小 648.2 M,仅供参考


git clone https://github.com/llvm-mirror/llvm.git
    • 再下载clang,大小 240.6 M,仅供参考,放到 /LLVM_ALL /llvm/tools 目录下


//  clang 放到  /LLVM_ALL /llvm/tools 目录下
cd llvm/tools
// 下载 clang
git clone https://github.com/llvm-mirror/clang.git
  • 4.2、源码编译


brew install cmake
brew install ninja


提示:如果 ninja 如果安装失败,可以直接从github获取release版放入【/usr/local/bin】中


image.png

llvm 源码同级目录下新建一个【llvm_build】目录(最终会在【llvm_build】目录下生成【build.ninja】)

image.png

      • cd llvm_build
      • cmake -G Ninja ../llvm -DCMAKE_INSTALL_PREFIX=llvm的安装路径


提示:更多cmake相关选项,可以参考: https://llvm.org/docs/CMake.html

    • 依次执行编译、安装指令


      • 编译完毕后, 【llvm_build】目录大概 21.05 G(仅供参考)


ninja
      • 安装完毕后,安装目录大概 11.92 G(仅供参考)


ninja install


  • 4.3、如果不想按照4.2的编译方式,也可以生成Xcode项目再进行编译,但是速度很慢(可能需要1个多小时)
    • 在 llvm 同级目录下新建一个【llvm_xcode】目录


image.png

cd llvm_xcode
cmake -G Xcode ../llvm

image.png


五、应用与实践



六、clang插件开发



  • 6.1、clang插件开发1 – 插件目录
    • clang/tools 源码目录下新建一个插件目录,假设叫做mj-plugin


image.png


在 clang/tools/CMakeLists.txt 最后加入内容: add_clang_subdirectory(mj-plugin),小括号里是 插件目录名


image.png

6.2、插件必要文件

image.png



  • mj-plugin 下创建 MJPlugin.cpp 文件,插件使用 C++ 编写


touch MJPlugin.cpp


  • mj-plugin 里面也要有一份 CMakeLists.txt 文件,里面写清插件需要加载哪些 C++ 代码,文件内容如下



image.png


add_llvm_loadable_module(MJPlugin MJPlugin.cpp)


提示:如果多个 C++ 文件,可以如下


image.png


6.3、clang插件开发3 – 编写插件源码


image.png

在 llvm 同级目录下新建一个【llvm_xcode】目录

cd llvm_xcode
cmake -G Xcode ../llvm


image.png


找到我们的插件文件进行开发,如下


image.png

具体的源码


image.png


#include <iostream>
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
using namespace clang;
using namespace std;
using namespace llvm;
using namespace clang::ast_matchers;
namespace MJPlugin {
    class MJHandler : public MatchFinder::MatchCallback {
        private:
        CompilerInstance &ci;
       public:
       MJHandler(CompilerInstance &ci) :ci(ci) {}
            void run(const MatchFinder::MatchResult &Result) {
                 if (const ObjCInterfaceDecl *decl = Result.Nodes.getNodeAs<ObjCInterfaceDecl>("ObjCInterfaceDecl")) {
                      size_t pos = decl->getName().find('_');
                      if (pos != StringRef::npos) {
                          DiagnosticsEngine &D = ci.getDiagnostics();
                          SourceLocation loc = decl->getLocation().getLocWithOffset(pos);
                          D.Report(loc, D.getCustomDiagID(DiagnosticsEngine::Error, "M了个J:类名中不能带有下划线"));
                      }
                 }
            }
       };
       class MJASTConsumer: public ASTConsumer {
           private:
           MatchFinder matcher;
           MJHandler handler;
           public:
           MJASTConsumer(CompilerInstance &ci) :handler(ci) {
               matcher.addMatcher(objcInterfaceDecl().bind("ObjCInterfaceDecl"), &handler);
           }
           void HandleTranslationUnit(ASTContext &context) {
              matcher.matchAST(context);
           }
    };
    class MJASTAction: public PluginASTAction {
    public:
        unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &ci, StringRef iFile) {
            return unique_ptr<MJASTConsumer> (new MJASTConsumer(ci));
        }
        bool ParseArgs(const CompilerInstance &ci, const vector<string> &args) {
            return true;
        }
    };
}
// 注册插件
// 左边是插件的名称,右边是插件的描述,X 可以随便写,官方使用的是 X
static FrontendPluginRegistry::Add<MJPlugin::MJAction>
X("MJPlugin", "The MJPlugin is my first clang-plugin.");


  • 6.4、clang插件开发4 – 编译插件
    • 利用cmake生成的Xcode项目来编译插件(第一次编写完插件,需要利用cmake重新生成一下Xcode项目)
    • 插件源代码在【Sources/Loadable modules】目录下可以找到,这样就可以直接在Xcode里编写插件代码
    • 选择MJPlugin这个target进行编译,编译完会生成一个动态库文件


image.png

6.5、clang插件开发5 – 加载插件


  • 在Xcode项目中指定加载插件动态库:Build Settings > OTHER_CFLAGS
  • -Xclang -load -Xclang 动态库路径 -Xclang -add-plugin -Xclang 插件名称


image.png


6.6、clang插件开发6 – Hack Xcode (Xcode 破解 由于制作Xcode插件)


  • 首先要对Xcode进行Hack,才能修改默认的编译器
  • 下载【XcodeHacking.zip】,解压,修改HackedClang.xcplugin/Contents/Resources/HackedClang.xcspec】的内容,设
    置一下自己编译好的clang的路径


image.png

    • 然后在XcodeHacking目录下进行命令行,将XcodeHacking的内容剪切到Xcode内部


// 命令一
sudo mv HackedClang.xcplugin `xcode-select-print�path`/../PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins
// 命令二
sudo mv HackedBuildSystem.xcspec `xcode-select-print�path`/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications


  • 6.7、clang插件开发7 – 修改Xcode的编译器,修改位置如下,使用我们自己编译的 clang


image.png

6.8、clang插件开发8 – 编译项目

编译项目后,会在编译日志看到MJPlugin插件的打印信息(如果插件更新了,最好先Clean一下项目)

image.png


6.9、clang插件开发9 – 更多

想要实现更复杂的插件功能,就需要利用clang的API针对语法树(AST)进行相应的分析和处理

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
20707 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
30118 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
23007 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
21205 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
17254 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14926 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
23629 0
+关注
433
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载