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)进行相应的分析和处理

目录
相关文章
|
数据安全/隐私保护 iOS开发
iOS逆向小技能:解锁无密码的设备、判断设备是否锁定、锁定设备、打开某个程序
介绍lua 函数: runApp、closeApp、getScreenSize、getDeviceID、lua_exit、isFrontApp。
254 0
|
安全 算法 开发工具
iOS逆向-day11:代码混淆
iOS逆向-day11:代码混淆
839 0
iOS逆向-day11:代码混淆
|
自然语言处理 前端开发 IDE
iOS逆向-day10:LLVM 编译器(上)
iOS逆向-day10:LLVM 编译器
217 0
iOS逆向-day10:LLVM 编译器(上)
|
安全 数据安全/隐私保护 iOS开发
iOS逆向-day9:签名机制(下)
iOS逆向-day9:签名机制(下)
337 0
iOS逆向-day9:签名机制(下)
|
存储 安全 数据安全/隐私保护
iOS逆向-day9:签名机制(中)
iOS逆向-day9:签名机制(中)
176 0
iOS逆向-day9:签名机制(中)
|
算法 网络安全 数据安全/隐私保护
iOS逆向-day9:签名机制(上)
iOS逆向-day9:签名机制(上)
177 0
iOS逆向-day9:签名机制(上)
|
NoSQL 编译器 C语言
iOS逆向-day8:LLDB 动态调试
iOS逆向-day8:LLDB 动态调试
760 0
iOS逆向-day8:LLDB 动态调试
|
9天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
2天前
|
存储 前端开发 Swift
探索iOS开发:从新手到专家的旅程
本文将带您领略iOS开发的奇妙之旅,从基础概念的理解到高级技巧的掌握,逐步深入iOS的世界。文章不仅分享技术知识,还鼓励读者在编程之路上保持好奇心和创新精神,实现个人成长与技术突破。
|
17天前
|
安全 数据处理 Swift
深入探索iOS开发中的Swift语言特性
本文旨在为开发者提供对Swift语言在iOS平台开发的深度理解,涵盖从基础语法到高级特性的全面分析。通过具体案例和代码示例,揭示Swift如何简化编程过程、提高代码效率,并促进iOS应用的创新。文章不仅适合初学者作为入门指南,也适合有经验的开发者深化对Swift语言的认识。
37 9