V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
waruqi
V2EX  ›  程序员

一个静态注入动态库的工具: luject

  •  
  •   waruqi ·
    waruqi · 2020-04-27 07:41:26 +08:00 · 2143 次点击
    这是一个创建于 1706 天前的主题,其中的信息可能已经有所发展或是发生改变。

    luject是一个静态注入动态库的工具,它可以实现对 mac, ios, linux, windows, android 的可执行程序,动态库程序进行修改,来插入指定动态库实现注入和加载。

    另外 luject 也实现了对 ios 的 ipa 包,android 的 apk 包自己 macOS 的.app 包的动态库注入,重打包和重签名支持。

    注入技术简介

    我们可以通过 ptrace 附加或启动一个程序,然后将指定的动态库注入进去,但很多情况下需要 root 权限才行。

    除了通过动态注入,我们也可以通过设置DYLD_INSERT_LIBRARIES等环境变量的方式,来注入指定的动态库,mac/ios 程序就可以使用这种方式来简单快速地实现注入,例如:

    $DYLD_INSERT_LIBRARIES=inject.dylib ./test
    

    不过这种方式在 ios 上也需要越狱后才可用,另外我们也可以在工程的 Build Settings 中找到 Other Linker Flages 并添加下面的字段来限制这种加载方式,实现对可执行程序的注入保护。

    -Wl,-sectcreate,__RESTRICT,__restrict,/dev/null
    

    因此,也不是非常的通用,其实还有一种更加通用的方式,就是直接静态修改可执行文件,插入需要加载的动态库就可以了,简单暴力有效。

    Mayhem 在Phrack中也详细解释了这一技术的原理,而 LIEF 库提供了一种跨平台的 api,实现对 MachO, ELF, PE 等可执行文件格式的快速修改。

    这里 luject 就是利用了这个库,通过修改可执行文件,插入动态库加载路径,来实现静态注入,例如:

    auto elf_binary = std::unique_ptr<LIEF::ELF::Binary>{LIEF::ELF::Parser::parse("testapp")};
    elf_binary->add_library("libtest.so");
    elf_binary->write("testapp_injected");
    

    luject 编译安装

    准备工作

    我们需要先安装xmake来编译此项目。

    编译

    $ xmake
    

    安装

    $ xmake install
    

    luject 使用说明

    用法很简单,主要就是指定输入输出的文件路径就好:

    $ luject -i [input] -o [output] -p [libpattern] lib1 lib2 ..
    

    最后面的 lib 列表,就是指定有哪些动态库需要被注入进去

    例如:

    $ luject -i app.apk lib1.so lib2.so
    $ luject -i app.ipa lib1.dylib lib2.dylib
    $ luject -i liba.so lib1.so lib2.so
    $ luject -i app.exe lib1.dll lib2.dll
    $ luject -i a.dll lib1.dll lib2.dll
    $ luject -i liba.dylib lib1.dylib lib2.dyib
    $ luject -i bin lib1.so lib2.so
    

    当然,除了指定库路径,我们也可以指定@loader_path, $ORIGIN的路径进去,例如:

    $ luject -i libdemo.dylib @loader_path/libtest.dylib
    

    上面的命令,我们就可以把libtest.dylib注入到另一个libdemo.dylib的动态库中去,如果libdemo.dylib被加载,那么就会从@loader_path也就是 libdemo.dylib 当前加载目录下 找对应的libtest.dylib库,然后自动加载进来,我们也可以通过 otool/ldd 等工具也查看验证加载列表:

    $ otool -L libdemo.dylib
    libdemo.dylib:
    	@loader_path/libtest.dylib (compatibility version 0.0.0, current version 0.0.0)
    	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
    	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 800.7.0)
    	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)
    

    可以看到,libtest 库已经被成功插入进去了。

    注入 libfrida-gadget.so 到 apk

    通常我们在使用 frida 系列工具对 app 进行动态分析时,如果不想 root,那么可以通过 luject 将 frida-gadget 库静态注入到 apk 里面的 so 库中去,比如:

    $ luject -i app.apk -p libtest /tmp/libfrida-gadget.so
    

    其中,libtest 是指定 apk 中需要匹配注入的 so 库,并且支持模式匹配实现批量注入,例如:libtest_*.so,如果不指定-p参数,默认多所有 so 进行批量全注入。

    关于这块,我们也可以详细看下相关文章: How to use frida on a non-rooted device

    另外,luject 重打包后,还会对 apk 进行重签名,来确保可以正常安装使用

    注入 libfrida-gadget.dylib 到 ipa

    除了 android 的应用程序包,luject 也支持对 ios 的 ipa 包进行注入,用法类似:

    $ luject -i app.ipa -p libtest /tmp/libfrida-gadget.dylib
    

    luject 也会对 ipa 包进行重签名,它会自动探测用户环境中的有效签名证书,来直接重签名,当然如果默认检测的签名不符合需求,我们也可以手动指定对应的签名信息:

    $ luject -i app.ipa -p libtest --codesign_identity='Apple Development: [email protected] (T3NA4MRVPU)' --mobile_provision='iOS Team Provisioning Profile: org.tboox.test' --bundle_identifier=org.tboox.test /tmp/libfrida-gadget.dylib
    

    那如何知道我们需要的签名配置呢?一种就是在 xcode 里面查看,另外 xmake 也提供了一些辅助工具可以 dump 出当前可用的所有签名配置:

    $ xmake l private.tools.codesign.dump
    ==================================== codesign identities ====================================
    { 
      "Apple Development: [email protected] (T3NA4MRVPU)" = "AF73C231A0C35335B72761BD3759694739D34EB1" 
    }
    
    ===================================== mobile provisions =====================================
    { 
      "iOS Team Provisioning Profile: org.tboox.test" = "<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>AppIDName</key>
    	<string>XC org tboox test5</string>
    	<key>ApplicationIdentifierPrefix</key>
    	<array>
    	<string>43AAQM58X3</string>
    ...
    

    xmake 也提供了其他辅助工具来对已有的 ipa/app 程序进行重签名,例如:

    $ xmake l utils.ipa.resign test.ipa|test.app [codesign_identity] [mobile_provision] [bundle_identifier]
    

    其中,后面的签名参数都是可选的,如果没设置,那么默认会探测使用一个有效的签名:

    $ xmake l utils.ipa.resign test.ipa
    $ xmake l utils.ipa.resign test.app "Apple Development: [email protected] (T3NA4MRVPU)"
    $ xmake l utils.ipa.resign test.ipa "Apple Development: [email protected] (T3NA4MRVPU)" iOS Team Provisioning Profile: org.tboox.test" org.tboox.test
    
    4 条回复    2020-04-27 08:55:10 +08:00
    ostrichb
        1
    ostrichb  
       2020-04-27 07:43:37 +08:00 via Android
    这东西是不是有 xposed 那味
    colinxu
        2
    colinxu  
       2020-04-27 07:45:23 +08:00 via Android
    这个有点牛批啊
    waruqi
        3
    waruqi  
    OP
       2020-04-27 07:48:41 +08:00 via Android
    @ostrichb 这个是直接篡改的包,跟 xposed 不一样
    billwsy
        4
    billwsy  
       2020-04-27 08:55:10 +08:00 via iPhone
    好东西,可以拿来代替这个了 https://github.com/Naituw/IPAPatch
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2656 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:00 · PVG 23:00 · LAX 07:00 · JFK 10:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.