-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
81 lines (54 loc) · 41.2 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>EteroConLab</title>
<link href="https://eterocell.com/atom.xml" rel="self"/>
<link href="https://eterocell.com/"/>
<updated>2024-07-24T02:50:06.597Z</updated>
<id>https://eterocell.com/</id>
<author>
<name>Eterocell</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>Android NDK r27 Clang 18 Hikari 混淆器 LLVM Pass 插件加载方案</title>
<link href="https://eterocell.com/posts/7dbf3410/"/>
<id>https://eterocell.com/posts/7dbf3410/</id>
<published>2024-07-23T13:34:49.000Z</published>
<updated>2024-07-24T02:50:06.597Z</updated>
<content type="html">< {</span><br><span class="line"> PB.<span class="built_in">registerPipelineStartEPCallback</span>(</span><br><span class="line"> [](ModulePassManager &PM, OptimizationLevel) {</span><br><span class="line"> PM.<span class="built_in">addPass</span>(<span class="built_in">ObfuscationPass</span>());</span><br><span class="line"> });</span><br><span class="line"> }};</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">extern</span> <span class="string">"C"</span> <span class="function">LLVM_ATTRIBUTE_WEAK PassPluginLibraryInfo <span class="title">llvmGetPassPluginInfo</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">getHikariPluginInfo</span>();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">} <span class="comment">// namespace llvm</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br></pre></td></tr></table></figure><h2 id="构建混淆插件">构建混淆插件</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p build</span><br><span class="line">pushd build</span><br><span class="line">cmake -G Ninja -DCMAKE_BUILD_TYPE=MinSizeRel ../</span><br><span class="line">cmake --build .</span><br><span class="line">popd</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">构建出的 libHikari.so 在 ./build/Hikari 目录下</span></span><br></pre></td></tr></table></figure><p>构建时可能遇到的两种问题:</p><ol><li><p>CMake 报错:</p> <figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">CMake Error at clang-r522817-darwin-x86_64/lib/cmake/llvm/LLVMExports.cmake:1238 (message):</span><br><span class="line">The imported target "LLVMDemangle" references the file</span><br><span class="line"></span><br><span class="line"> "$(OBF_PROJECT_DIR)/clang-r522817/lib/libLLVMDemangle.a"</span><br><span class="line"></span><br><span class="line">but this file does not exist. Possible reasons include:</span><br><span class="line"></span><br><span class="line">* The file was deleted, renamed, or moved to another location.</span><br><span class="line"></span><br><span class="line">* An install or uninstall procedure did not complete successfully.</span><br><span class="line"></span><br><span class="line">* The installation package was faulty and contained</span><br></pre></td></tr></table></figure><p>在 $(OBF_PROJECT_DIR)/clang-r522817/lib/cmake/llvm/LLVMExports.cmake 中找到以下脚本, 注释即可:</p> <figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Loop over all imported files and verify that they actually exist</span></span><br><span class="line"><span class="keyword">foreach</span>(<span class="keyword">target</span> <span class="variable">${_IMPORT_CHECK_TARGETS}</span> )</span><br><span class="line"><span class="keyword">foreach</span>(<span class="keyword">file</span> <span class="variable">${_IMPORT_CHECK_FILES_FOR_${target}</span>} )</span><br><span class="line"> <span class="keyword">if</span>(<span class="keyword">NOT</span> <span class="keyword">EXISTS</span> <span class="string">"${file}"</span> )</span><br><span class="line"> <span class="keyword">message</span>(FATAL_ERROR <span class="string">"The imported target \"${target}\" references the file</span></span><br><span class="line"><span class="string">\"${file}\"</span></span><br><span class="line"><span class="string">but this file does not exist. Possible reasons include:</span></span><br><span class="line"><span class="string">* The file was deleted, renamed, or moved to another location.</span></span><br><span class="line"><span class="string">* An install or uninstall procedure did not complete successfully.</span></span><br><span class="line"><span class="string">* The installation package was faulty and contained</span></span><br><span class="line"><span class="string">\"${CMAKE_CURRENT_LIST_FILE}\"</span></span><br><span class="line"><span class="string">but not all the files it references.</span></span><br><span class="line"><span class="string">"</span>)</span><br><span class="line"> <span class="keyword">endif</span>()</span><br><span class="line"><span class="keyword">endforeach</span>()</span><br><span class="line"><span class="keyword">unset</span>(_IMPORT_CHECK_FILES_FOR_<span class="variable">${target}</span>)</span><br><span class="line"><span class="keyword">endforeach</span>()</span><br><span class="line"><span class="keyword">unset</span>(_IMPORT_CHECK_TARGETS)</span><br></pre></td></tr></table></figure></li><li><p>(macOS) 构建时报类似于 clang-18 已损坏: <code>sudo xattr -d com.apple.quarantine $(OBF_PROJECT_DIR)/clang-r522817/bin/*</code></p></li></ol><h2 id="NDK-Clang-工具链的改动">NDK Clang 工具链的改动</h2><p>如果直接用原版 NDK 加载 libHikari, 可能会遇到以下三种问题:</p><ol><li><p>(macOS) clang 和 <a href="http://libHikari.so">libHikari.so</a> 签名不一致导致被 Hardened Runtime 拒绝加载: <code>error: unable to load plugin 'libHikari.so': 'dlopen(libHikari.so, 0x0009): tried: 'libHikari.so' (code signature in <xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx> 'libHikari.so' not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs), '/System/Volumes/Preboot/Cryptexes/OSlibHikari.so' (no such file), 'libHikari.so' (code signature in <xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx> 'libHikari.so' not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs)'</code><br>需要将 llvm/bin 中的可执行文件与 <a href="http://libHikari.so">libHikari.so</a> 用同一苹果开发者 TeamID 签名:</p> <figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">sign_macho() {</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">Directory to search <span class="keyword">for</span> Mach-O executables</span></span><br><span class="line">local directory="$1"</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">Signing identity</span></span><br><span class="line">local signing_identity="$TeamID"</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">Find and sign all Mach-O executables</span></span><br><span class="line">find "$directory" -type f -perm +111 | while read -r file; do</span><br><span class="line"> # Check if the file is a Mach-O executable</span><br><span class="line"> if file "$file" | grep -q "Mach-O"; then</span><br><span class="line"> echo "Signing $file"</span><br><span class="line"> codesign -s "$signing_identity" -f "$file"</span><br><span class="line"> fi</span><br><span class="line">done</span><br><span class="line"></span><br><span class="line">echo "Signing process completed."</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>找不到符号: <code>error: unable to load plugin '$(PROJECT_DIR)/app/obf_lib/darwin_arm64/libHikari.so': 'dlopen($(PROJECT_DIR)/app/obf_lib/darwin_arm64/libHikari.so, 0x0009): symbol not found in flat namespace '__ZTVN4llvm2cl6OptionE''</code>. 这是由于官方 NDK 中自带的 clang 二进制符号不完整导致的. 需要自行构建 Android LLVM 来获取完整的 <code>clang-18</code>, <code>clang</code>, <code>clang++</code> 替换掉 NDK 内自带的对应的三个文件.</p></li></ol><h3 id="构建-Android-llvm-project">构建 Android llvm-project</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">git clone https://android.googlesource.com/toolchain/llvm-project</span><br><span class="line">cd llvm-project</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">确保与原版 NDK 相同的 git revision</span></span><br><span class="line">git checkout d8003a456d14a3deb8054cdaa529ffbf02d9b262</span><br><span class="line">cd ..</span><br><span class="line">mkdir -p build</span><br><span class="line">cd build</span><br><span class="line"></span><br><span class="line">cmake -G "Ninja" ../llvm-project/llvm \</span><br><span class="line"> -DCMAKE_INSTALL_PREFIX="./llvm_x64" \</span><br><span class="line"> -DCMAKE_CXX_STANDARD=17 \</span><br><span class="line"> -DCMAKE_BUILD_TYPE=MinSizeRel </span><br><span class="line"> -DLLVM_APPEND_VC_REV=on \</span><br><span class="line"> -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;compiler-rt;lld;mlir;openmp;polly;" \</span><br><span class="line"> -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \</span><br><span class="line"> -DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64" \</span><br><span class="line"> -DLLVM_INSTALL_UTILS=ON \</span><br><span class="line"> -DLLVM_INCLUDE_TESTS=OFF \</span><br><span class="line"> -DLLVM_BUILD_TESTS=OFF \</span><br><span class="line"> -DLLVM_INCLUDE_BENCHMARKS=OFF \</span><br><span class="line"> -DLLVM_BUILD_BENCHMARKS=OFF \</span><br><span class="line"> -DLLVM_INCLUDE_EXAMPLES=OFF \</span><br><span class="line"> -DLLVM_ENABLE_BACKTRACES=OFF \</span><br><span class="line"> -DLLVM_BUILD_DOCS=OFF</span><br><span class="line"></span><br><span class="line">cmake --build .</span><br></pre></td></tr></table></figure><p>构建完成后, 可以将原有的 NDK 复制一份出来专门用于混淆:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">cd $ANDROID_SDK_ROOT/ndk</span><br><span class="line">cp -r 27.0.12077973 27.0.12077973-obf</span><br><span class="line">cd 27.0.12077973-obf/toolchains/llvm/prebuilt/darwin-x86_64/bin</span><br><span class="line">mv clang clang.bak</span><br><span class="line">mv clang++ clang++.bak</span><br><span class="line">mv clang-18 clang-18.bak</span><br></pre></td></tr></table></figure><p>再将构建获得的 <code>clang</code>, <code>clang++</code>, <code>clang-18</code> 放到该目录下即可.</p><h2 id="加载混淆器-LLVM-Pass-插件-传递混淆参数">加载混淆器 LLVM Pass 插件, 传递混淆参数</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// build.gradle.kts</span></span><br><span class="line">android {</span><br><span class="line"> ndkVersion = <span class="string">"27.0.12077973"</span></span><br><span class="line"> ndkPath = <span class="string">"<span class="variable">$ANDROID_SDK_ROOT</span>/ndk/27.0.12077973-obf"</span></span><br><span class="line"></span><br><span class="line"> defaultConfig {</span><br><span class="line"> externalNativeBuild {</span><br><span class="line"> cmake {</span><br><span class="line"> <span class="comment">// 混淆插件路径</span></span><br><span class="line"> <span class="keyword">val</span> obfLibDir =</span><br><span class="line"> <span class="string">"<span class="subst">${project.layout.projectDirectory.asFile.absolutePath}</span>/obf_lib/darwin_arm64/libHikari.so"</span></span><br><span class="line"> <span class="keyword">val</span> obfArgs = listOf(</span><br><span class="line"> <span class="string">"-fvisibility=hidden"</span>,</span><br><span class="line"> <span class="string">"-fpass-plugin=<span class="variable">$obfLibDir</span>"</span>,</span><br><span class="line"> <span class="string">"-Xclang"</span>,</span><br><span class="line"> <span class="string">"-load"</span>,</span><br><span class="line"> <span class="string">"-Xclang"</span>,</span><br><span class="line"> obfLibDir,</span><br><span class="line"> <span class="comment">// 混淆参数, 请自行参考 Hikari-LLVM15-Core 原项目配置</span></span><br><span class="line"> <span class="string">"-mllvm"</span>,</span><br><span class="line"> <span class="string">"-enable-allobf"</span></span><br><span class="line"> )</span><br><span class="line"> cppFlags += obfArgs</span><br><span class="line"> cFlags += obfArgs</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="结果对比">结果对比</h2><p><img data-src="size.png" alt="so 大小"></p><p><img data-src="hopper.png" alt="未混淆"></p><p><img data-src="hopper_obf.png" alt="混淆后"></p><h2 id="致谢">致谢</h2><ul><li><a href="https://xtuly.cn/article/ndk-load-llvm-pass-plugin">NDK 加载 LLVM Pass 方案 | Ylarod’s Blog</a> - 本方案的绝大多数思路来源于该篇文章, 仅针对 NDK r27 做了调整.</li></ul>]]></content>
<summary type="html"><h2 id="要用到的项目及说明">要用到的项目及说明</h2>
<ul>
<li>
<p><a href="https://github.com/61bcdefg/Hikari-LLVM15-Core">Hikari-LLVM15-Core</a>: Obfuscator source code (Working on LLVM 18, Don’t be confused by its project name)</p>
</li>
<li>
<p><a href="https://github.com/61bcdefg/Hikari-LLVM15-Headers">Hikari-LLVM15-Headers</a>: Obfuscator headers</p>
</li>
<li>
<p><a href="https://android.googlesource.com/platform/prebuilts/clang/host/darwin-x86/+log/refs/heads/master/clang-r522817">Android Prebuilt Clang r522817</a>: NDK r27 使用的 clang revision 为 r522817 (见 <code>$ANDROID_SDK_ROOT/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/AndroidVersion.txt</code>)</p>
</li>
<li>
<p><a href="https://android.googlesource.com/platform/prebuilts/clang/host/darwin-x86/+/1c8f09d76cb556336e677ef21111c1d7b20775e4/clang-r522817/">clang-r522817 tarball</a>: 预编译 clang 工具链</p>
</li>
<li>
<p><a href="https://android.googlesource.com/toolchain/llvm-project">Android llvm-project</a>: NDK r27 的 revision 为 d8003a456d14a3deb8054cdaa529ffbf02d9b262 (见 <code>$ANDROID_SDK_ROOT/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang --version</code>)</p>
</li>
<li>
<p>仅在 arm64 的 macOS 14 上进行了测试, 在 macOS x86_64 及 Linux 上应该是通用的, Windows 上不可用.</p>
</li>
</ul></summary>
<category term="Android" scheme="https://eterocell.com/tags/Android/"/>
<category term="Obfuscator" scheme="https://eterocell.com/tags/Obfuscator/"/>
</entry>
<entry>
<title>一次 Git 将 jar 误认为文本文件自动替换换行符引发的血案</title>
<link href="https://eterocell.com/posts/ce8d81c3/"/>
<id>https://eterocell.com/posts/ce8d81c3/</id>
<published>2023-11-30T03:40:25.000Z</published>
<updated>2023-11-30T05:23:32.146Z</updated>
<content type="html"><![CDATA[<p>早上起来 Renovate 提 PR 帮我把 Gradle 更新到了 8.5, 我并没有看为什么 CI 报错直接合了, 毕竟 Gradle 从 8.4 更新到 8.5 大概率不会出现什么大问题可以合了之后再改, 只不过,:</p><span id="more"></span><p><img data-src="failed_commits.png" alt="Failed Commits"></p><p>报错的详情为 <code>Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain</code>, 因此大概率是运行 <code>./gradlew</code> 时, <code>./gradle/wrapper/gradle-wrapper.jar</code> 有问题. 果然拉回本地后, 第一次 <code>./gradlew</code> 报了同样的错, 删除 <code>./gradlew</code>, <code>./gradlew.bat</code>, <code>./gradle/wrapper/gradle-wrapper.jar</code> 之后运行 <code>gradle wrapper --gradle-version 8.5 --distribution-type all</code> 后再次运行 <code>./gradlew</code> 就可以了. 果断 add, commit 再 push, 于是再次报了 <code>Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain</code>.</p><p>之后尝试了很多, 包括 revert 前面升级 actions/setup-java 的 commit, 去掉 actions.yml 中保留 Gradle 缓存的步骤等. 但唯一有效的是 revert 升级 Gradle 的 commit.</p><p>机缘巧合下, 在 actions 中添加 gradle/wrapper-validation-action 后, 报错为 <code>./gradle/wrapper/gradle-wrapper.jar</code> 的 sha256 的校验和为 <code>c7b7b1c</code> 开头而非预期的 <code>d3b261c</code> 开头 (<a href="https://gradle.org/release-checksums/">可以再这里找到 Gradle 各版本 bin, all 和 wrapper jar 的 sha256 checksum</a>), 但我本地的校验和又是正确的. 于是删除本地重新拉远程, 发现远程的校验和确实是错误的, 于是又重新拉 Gradle wrapper, 本地确认 sha256 校验和无误后 commit 上传, 但 CI 仍然报错误校验和. 但发现在 commit 的时候报了这个警告: <code>warning: CRLF will be replaced by LF in gradle/wrapper/gradle-wrapper.jar</code>. 校验和对不上的原因算是找到了, 于是在 .gitattributes 中添加 <code>*.jar -text</code> 规则, 再重新拉 Gradle wrapper commit push 就正常了.</p><p>咱也不知道为啥 Git 把 gradle-wrapper.jar 认成了文本文件修改其换行符, 不过以后 gradle/wrapper-validation-action 和 <code>*.jar -txt</code> 大概会在我的 Actions 和 .gitattributes 中常驻了…</p><h3 id="Reference">Reference</h3><ul><li><a href="https://docs.gradle.org/current/userguide/gradle_wrapper.html#configuring_checksum_verification">Gradle Wrapper Reference - Configuring Checksum Verification</a></li></ul>]]></content>
<summary type="html"><p>早上起来 Renovate 提 PR 帮我把 Gradle 更新到了 8.5, 我并没有看为什么 CI 报错直接合了, 毕竟 Gradle 从 8.4 更新到 8.5 大概率不会出现什么大问题可以合了之后再改, 只不过,:</p></summary>
<category term="踩坑记录" scheme="https://eterocell.com/categories/%E8%B8%A9%E5%9D%91%E8%AE%B0%E5%BD%95/"/>
<category term="Git" scheme="https://eterocell.com/tags/Git/"/>
</entry>
</feed>