{"id":71,"date":"2026-01-04T16:33:29","date_gmt":"2026-01-04T08:33:29","guid":{"rendered":"http:\/\/8.210.123.186\/?p=71"},"modified":"2026-01-04T20:56:50","modified_gmt":"2026-01-04T12:56:50","slug":"%e6%b7%b7%e6%b7%86%e5%ad%a6%e4%b9%a0","status":"publish","type":"post","link":"http:\/\/8.210.123.186\/index.php\/2026\/01\/04\/%e6%b7%b7%e6%b7%86%e5%ad%a6%e4%b9%a0\/","title":{"rendered":"\u6df7\u6dc6\u5b66\u4e60"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">llvm<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">LLVM Pass<br><code>llvm<\/code><br>\u4e00\u5957\u7f16\u8bd1\u5668\u548c\u5de5\u5177\u94fe\u6280\u672f\uff0c\u7528\u4e8e\u4e3a\u4efb\u4f55\u7f16\u7a0b\u8bed\u8a00\u5f00\u53d1\u524d\u7aef\uff0c\u4e3a\u4efb\u4f55\u6307\u4ee4\u96c6\u67b6\u6784\u5f00\u53d1\u540e\u7aef\uff0c\u57fa\u4e8e\u4e2d\u95f4\u8868\u793air\u8bbe\u8ba1\uff08\u53ef\u79fb\u690d\u9ad8\u7ea7\u6c47\u7f16\uff09\uff0c\u6700\u521d\u4f5c\u4e3a\u52a8\u6001\u7f16\u8bd1\u6280\u672f\uff0c\u80fd\u63d0\u4f9b\u4e00\u4e2a\u5b8c\u6574\u7f16\u8bd1\u5668\u7cfb\u7edf\u7684\u4e2d\u95f4\u5c42\uff0c\u4ece\u7f16\u8bd1\u5668\u4e2d\u83b7\u53d6\u4e2d\u95f4\u8868\u793air\uff0c\u65b0\u7684ir\u53ef\u4ee5\u88ab\u8f6c\u5316\u4e3a\u5e73\u53f0\u4f9d\u8d56\u4e8e\u673a\u5668\u7684\u6c47\u7f16\u8bed\u8a00\u4ee3\u7801\u3002\u8fd8\u80fd\u5728\u7f16\u8bd1\u65f6\uff0c\u94fe\u63a5\u65f6\uff0c\u8fd0\u884c\u65f6\u751f\u6210\u53ef\u91cd\u5b9a\u4f4d\u7684\u673a\u5668\u4ee3\u7801\uff0c\u6216\u8005\u4e8c\u8fdb\u5236\u673a\u5668\u4ee3\u7801<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u91cd\u8981\u547d\u4ee4\u884c\u5de5\u5177<br>llvm-as\uff1a\u628aLLVM IR\u4ece\u4eba\u7c7b\u80fd\u770b\u61c2\u7684\u6587\u672c\u683c\u5f0f\u6c47\u7f16\u6210\u4e8c\u8fdb\u5236\u683c\u5f0f\u3002\u6ce8\u610f\uff1a\u6b64\u5904\u5f97\u5230\u7684\u4e0d\u662f\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\u3002<br>llvm-dis\uff1allvm-as\u7684\u9006\u8fc7\u7a0b\uff0c\u5373\u53cd\u6c47\u7f16\u3002 \u4e0d\u8fc7\u8fd9\u91cc\u7684\u53cd\u6c47\u7f16\u7684\u5bf9\u8c61\u662fLLVM IR\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\uff0c\u800c\u4e0d\u662f\u673a\u5668\u7801\u3002<br>opt\uff1a\u4f18\u5316LLVM IR\u3002\u8f93\u51fa\u65b0\u7684LLVM IR\u3002<br>llc\uff1a\u628aLLVM IR\u7f16\u8bd1\u6210\u6c47\u7f16\u7801\u3002\u9700\u8981\u7528as\u8fdb\u4e00\u6b65\u5f97\u5230\u673a\u5668\u7801\u3002<br>lli\uff1a\u89e3\u91ca\u6267\u884cLLVM IR\u3002<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u524d\u7aef\u628a\u6e90\u4ee3\u7801\u7f16\u8bd1\u4e3a\u4e2d\u95f4\u8868\u793a\uff08IR\uff09\uff0c\u540e\u7aef\u628aIR\u7f16\u8bd1\u4e3a\u76ee\u6807\u5e73\u53f0\u7684\u673a\u5668\u7801\uff0cir\u4e5f\u53ef\u4ee5\u7ed9\u89e3\u91ca\u5668\u89e3\u91ca\u6267\u884c\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">llvm\u8bbe\u8ba1\u4e86\u4e00\u4e2a\u53ebllvm ir\u7684\u4e2d\u95f4\u8868\u793a\uff0c\u4ee5\u5e93\uff08library\uff09\u7684\u65b9\u5f0f\u6765\u63d0\u4f9b\u63a5\u53e3\uff0c\u63d0\u4f9b\u540e\u7aef\u670d\u52a1\uff0cllvm pass\u5c31\u662f\uff0c\u904d\u5386\u4e00\u904dir\uff0c\u540c\u65f6\u5bf9\u5b83\u8fdb\u884c\u4e00\u4e9b\u64cd\u4f5c\uff0c\u5b9e\u73b0\u4e0a\uff0cllvm\u6838\u5fc3\u5e93\u63d0\u4f9b\u4e00\u4e9bpass\u7c7b\u53bb\u7ee7\u627f\uff0c\u4fee\u6539\u4e00\u4e9b\u5b9e\u73b0\u5b83\u7684\u65b9\u6cd5\uff0c\u6700\u540e\u4f7f\u7528llvm\u7f16\u8bd1\u5668\u628a\u5b83\u7ffb\u8bd1\u5f97\u5230ir\u4f20\u5165pass\u8fdb\u884c\u904d\u5386\u548c\u4fee\u6539\u3002\u7136\u540e\u4f7f\u7528\u5c31\u662f\uff0c\u53ef\u4ee5\u62ff\u6765\u63d2\u6869\uff0c\u4f18\u5316\u4ee3\u7801\uff0c\u9759\u6001\u5206\u6790\u4e00\u4e9b<br><code>clang<\/code><br>\u7f16\u8bd1\u5668\u524d\u7aef\uff08\u9a71\u52a8\uff09\uff0cllvm\u7f16\u8bd1\u5668\u57fa\u7840\u8bbe\u65bd\u9879\u76ee\u4e00\u90e8\u5206\uff08\u5f53gcc\u66ff\u4ee3\u54c1\u770b\uff0c\u4e3b\u8981\u5728unix\u7c7b\u7cfb\u7edf\u4e0a\uff0c\u5b98\u65b9\u8fd9\u4e48\u4ecb\u7ecd\uff1f\uff09\u4e3b\u8981\u662f\u4e00\u4e2a\u5e93\u96c6\u5408\uff0clibclang\uff08\u63d0\u4f9bc\u63a5\u53e3\uff0capi\u7a33\u5b9a\uff09\u548clibtooling\uff08c++\u5e93\uff0c\u63d0\u4f9b\u5bf9ast\u63a7\u5236\u2014\u5c31\u90a3\u4e2a\u8bed\u6cd5\u7ed3\u6784\u56fe\u6709\u70b9\u50cf\u2014\u7f16\u5199\u5206\u6790\u5668\uff0c\u6784\u5efa\u6e90\u4ee3\u7801\u91cd\u6784\u5de5\u5177\uff0c\u521b\u5efa\u4ee3\u7801\u751f\u6210\u5de5\u5177\uff09\u8fd8\u6709\u534f\u8bae\u5565\u7684\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ir\u8fc7\u7a0b<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e2d\u95f4\u5c42ir\u4f1a\u7ecf\u8fc7\u4f18\u5316\uff0c\u5e38\u89c1\u4ee3\u7801\u4f18\u5316\u65b9\u5f0f\uff1a\u5220\u9664\u65e0\u7528\u4ee3\u7801\uff0c\u5220\u9664\u516c\u5171\u5b50\u8868\u8fbe\u5f0f\uff0c\u5e38\u91cf\u5408\u5e76\u7b49<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5220\u9664\u65e0\u7528\u4ee3\u7801\uff0c\u53d1\u73b0\u6709\u8ba1\u7b97\u7ed3\u679c\u4e0d\u4f1a\u88ab\u8ba1\u7b97\u7684\u5c31\u5220\u9664<\/li>\n\n\n\n<li>\u5220\u9664\u516c\u5171\u5b50\u8868\u8fbe\u5f0f\uff0c\u5bf9\u91cd\u590d\u8ba1\u7b97\u7ed3\u679c\u4e0d\u91cd\u590d\u8ba1\u7b97\uff0c\u590d\u7528\u8ba1\u7b97\u7ed3\u679c,\u5982<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>int fff(int x,int y){\n    int d=x*y;\n    int f=x*y+2;\n    int c=x*y+3;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u4f18\u5316\u6210<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int fff(int x,int y){\n    int d=x*y;\n    int f=d+2;\n    int c=d+3;\n}<\/code><\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>\u5e38\u91cf\u5408\u5e76\uff0c\u5e38\u91cf\u8ba1\u7b97\u62ff\u7ed3\u679c\u76f4\u63a5\u7f16\u8bd1\u88ab\u8ba1\u7b97\u5f97\u5230\u7684\uff0c\u76f4\u63a5\u5199\u4e86\u7ed3\u679c<\/li>\n\n\n\n<li>\u9664\u6b64\u4e4b\u5916\u8fd8\u6709\u5faa\u73af\u5c55\u5f00\uff0c\u5bc4\u5b58\u5668\u5206\u914d\u7b49\u4f18\u5316\u65b9\u5f0f<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">pass<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">![[Pasted image 20260103232526.png]]<br>pass\u662f\u5728\u4e2d\u95f4ir\u9636\u6bb5\u5bf9\u4e2d\u95f4\u4ee3\u7801\u8fdb\u884c\u4f18\u5316\uff0c\u6df7\u6dc6\u7b49\u64cd\u4f5c\uff0c\u800c\u4e14\u662f\u94fe\u5f0f\uff0c\u524d\u4e00\u4e2apass\u7684\u7ed3\u679c\u53ef\u4ee5\u4f5c\u4e3a\u4e0b\u4e00\u4e2apass\u7684\u8f93\u5165\u8fdb\u53bb<br>\u8fd9\u91cc\u7684pass\u5206\u4e3a\u4e24\u7c7b\uff0c\u4e00\u7c7b\u5206\u6790analysis\u4ee5\u63d0\u4f9b\u4fe1\u606f\u4e3a\u4e3b\uff0c\u4e00\u7c7b\u662ftransform\u3002\u4ee5\u4f18\u5316\u4e2d\u95f4\u4ee3\u7801\u4e3a\u4e3b\uff0collvm\u7684\u4e3b\u8981\u4ee3\u7801\u5c31\u5728\u8fd9\u4e2atransform\u76ee\u5f55\u4e0b<br>\u6ce8\u518c\u4e00\u4e2apass\u7684\u683c\u5f0f<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include \"llvm\/Pass.h\"          \/\/ \u5f15\u5165\u5b9a\u4e49 Pass \u57fa\u7c7b\u53ca\u76f8\u5173\u63a5\u53e3\u7684\u5934\u6587\u4ef6\n#include \"llvm\/IR\/Function.h\"   \/\/ \u5f15\u5165 LLVM IR \u4e2d Function \u7c7b\u578b\u7684\u5b9a\u4e49\n#include \"llvm\/Support\/raw_ostream.h\" \/\/ \u5f15\u5165\u652f\u6301\u8f93\u51fa\u7684\u539f\u59cb\u6d41\uff08errs\uff0couts \u7b49\uff09\n\nusing namespace llvm;\n\n\/\/ \u5c06 Pass \u5b9e\u73b0\u5728\u533f\u540d\u547d\u540d\u7a7a\u95f4\u4e2d\uff0c\u53ef\u907f\u514d\u547d\u540d\u51b2\u7a81\nnamespace {\n\/\/\u7ee7\u627f\u81eafunctionPass\nstruct EncodeFunctionName : public FunctionPass {\n  static char ID;  \/\/ \u6bcf\u4e2a Pass \u90fd\u9700\u8981\u4e00\u4e2a ID \u6765\u6807\u8bc6\u81ea\u5df1\n\n  \/\/ \u6784\u9020\u51fd\u6570\uff1a\u5411\u7236\u7c7b\uff08FunctionPass\uff09\u7684\u6784\u9020\u51fd\u6570\u4f20\u9012 ID\n  EncodeFunctionName() : FunctionPass(ID) {}\n\n  \/\/ runOnFunction \u65b9\u6cd5\u662f FunctionPass \u7684\u6838\u5fc3\u63a5\u53e3\uff0c\u6bcf\u5f53 Pass \u5728\u4e00\u4e2a Function \u5bf9\u8c61\u4e0a\u8fd0\u884c\u65f6\u8c03\u7528\n  bool runOnFunction(Function &amp;F) override {\n    \/\/ \u4f7f\u7528 write_escaped \u8f93\u51fa\u51fd\u6570\u540d\u79f0\uff0c\u53ef\u4ee5\u5c06\u4e00\u4e9b\u7279\u6b8a\u5b57\u7b26\u8f6c\u4e49\u8f93\u51fa\n    errs().write_escaped(F.getName()) &lt;&lt; '\\n';\n    \/\/ \u8fd4\u56de false\uff0c\u8868\u793a\u8be5 Pass \u5e76\u672a\u6539\u53d8\u5f53\u524d\u51fd\u6570\u7684 IR\uff08\u5982\u679c\u6709\u66f4\u6539 IR\uff0c\u9700\u8fd4\u56de true\uff09\n    return false;\n  }\n}; e\n\n} \n\/\/ \u5728\u533f\u540d\u547d\u540d\u7a7a\u95f4\u4e4b\u5916\u5b9a\u4e49\u9759\u6001\u6210\u5458\u53d8\u91cf ID\nchar EncodeFunctionName::ID = 0;\n\n\nstatic RegisterPass&lt;EncodeFunctionName&gt; X(\"encode\", \"Hello EncodeFunctionName Pass\",\n                                          false \/* Only looks at CFG *\/,\n                                          false \/* Analysis Pass *\/);<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">ir\u8bed\u6cd5<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">ir\u662f\u5404\u79cdpass\u7c7b\u7684\u76ee\u6807<br>\u6709\u4e24\u79cd\u8868\u73b0\u5f62\u5f0f\uff0c.ll\u548c\u65b9\u4fbf\u673a\u5668\u5904\u7406\u7684.bc<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">![[Pasted image 20260103234955.png]]<br>llvm\u5c06\u7f16\u8bd1\u8fc7\u7a0b\u5206\u4e3a\u4e09\u6b65<br>\u524d\u7aef\uff0c\u9ad8\u7ea7\u8bed\u8a00\u8f6cir<br>\u4e2d\u7aef\uff0cir\u4f18\u5316<br>\u540e\u7aef\uff0c\u628air\u8f6c\u5316\u4e3a\u5bf9\u5e94\u7684\u786c\u4ef6\u5e73\u53f0\u7684\u6c47\u7f16\u8bed\u8a00<br>ir\u5305\u542b\u4e09\u90e8\u5206\u6307\u4ee4\u683c\u5f0f\u3001Basic Block &amp; CFG\uff0cSSA<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u6307\u4ee4\u683c\u5f0f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">LLVM IR\u63d0\u4f9b\u4e86\u4e00\u79cd\u7c7b\u4f3c\u4e8e\u6c47\u7f16\u8bed\u8a00\u7684\u4e09\u5730\u5740\u7801\u5f0f\u7684\u6307\u4ee4\u683c\u5f0f\u3002\u4e0b\u9762\u7684\u4ee3\u7801\u7247\u6bb5\u662f\u4e00\u4e2a\u975e\u5e38\u7b80\u5355\u7684\u7528LLVM IR\u5b9e\u73b0\u7684\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u7684\u8f93\u5165\u662f5\u4e2ai32\u7c7b\u578b(int32)\u7684\u6574\u6570\uff0c\u51fd\u6570\u7684\u529f\u80fd\u662f\u8ba1\u7b97\u8fd95\u4e2a\u6570\u7684\u548c\u5e76\u8fd4\u56de\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>define i32 @ir_add(i32, i32, i32, i32, i32){\n%6 = add i32 %0, %1\n%7 = add i32 %6, %2\n%8 = add i32 %7, %3\n%9 = add i32 %8, %4\nret i32 %9\n}Basic Block &amp; CFG<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">llvm ir \u652f\u6301\u4e00\u4e9b\u57fa\u672c\u6570\u636e\u7c7b\u578b\uff0c\u5982i1\uff08\u5e03\u5c14\u503c\uff09\uff0ci8\uff088\u4f4d\u6574\u6570\uff0c\u5bf9\u5e94c\u8bed\u8a00\u4e2dbyte\u6216char\uff09\uff0ci16\uff08\u77ed\u6574\u6570\uff09i32\uff0832\u4f4d\u6574\u6570\uff0c\u5bf9\u5e94c\u8bed\u8a00\u4e2dint\uff09\uff0ci64\uff08long\u621664\u4f4d\u7cfb\u7edf\u7684\u6307\u9488\u5927\u5c0f\uff09\uff0ci128\uff08\u8d85\u5927\u6574\u6570\uff0c\u7f16\u8bd1\u5668\u5185\u90e8\u652f\u6301\uff09\uff0c\u6d6e\u70b9\u6570\uff0816\u4f4dhalf\uff0c32\u4f4dfloat 64\u4f4ddouble\uff09\u6307\u9488\u7c7b\u578b\uff0c\u6570\u7ec4\u548c\u7ed3\u6784\u4f53\u7b49\u3002<br>llvm ir\u4e2d\uff0c\u6240\u6709\u53d8\u91cf\u548c\u5bc4\u5b58\u5668\u90fd\u5fc5\u987b\u5e26\u524d\u7f00\uff0c\u7528\u6765\u533a\u5206\u4f5c\u7528\u57df\uff0c<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>%\u5f00\u5934 (Local Variables)\uff1a\u8868\u793a\u5c40\u90e8\u53d8\u91cf\uff08\u6216\u8005\u53eb\u865a\u62df\u5bc4\u5b58\u5668\uff09\u5b83\u4eec\u53ea\u5728\u5f53\u524d\u51fd\u6570\u5185\u6709\u6548\u3002LLVM IR\u4e2d\u7684\u53d8\u91cf\u7684\u547d\u540d\u662f\u4ee5&#8221;%&#8221;\u5f00\u5934\uff0c\u9ed8\u8ba4%0\u662f\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c%1\u662f\u7b2c\u4e8c\u4e2a\u53c2\u6570\uff0c\u4f9d\u6b21\u7c7b\u63a8\u3002<\/li>\n\n\n\n<li>@\u5f00\u5934 (Global Variables)\uff1a\u8868\u793a \u5168\u5c40\u53d8\u91cf\u6216\u51fd\u6570\u540d\u3002<br>\u5728 LLVM IR \u4e2d\uff0c\u53d8\u91cf\uff08\u5bc4\u5b58\u5668\uff09\u6709\u4e24\u79cd\u547d\u540d\u65b9\u5f0f\uff1a<\/li>\n\n\n\n<li>\u6709\u540d\u5b57\u7684\uff1a\u6bd4\u5982%a,%retval\uff08\u901a\u5e38\u662fDebug\u6a21\u5f0f\u4e0b\u751f\u6210\u7684\u65b9\u4fbf\u4eba\u770b\uff09<\/li>\n\n\n\n<li>\u6ca1\u540d\u5b57\u7684\uff08\u7f16\u53f7\uff09\uff1a\u6bd4\u5982%0,%1,%2\uff08Release\u6a21\u5f0f\u6216\u4f18\u5316\u540e\u5e38\u89c1\uff09<br>\u4e3e\u4f8b<br>c\u8bed\u8a00\u4ee3\u7801<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u4e00\u4e2a\u7b80\u5355\u7684\u52a0\u6cd5\u51fd\u6570\nint add(int a, int b) {\n    return a + b;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5bf9\u5e94ir\u65e0\u540d\u79f0\u6a21\u5f0f<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>define i32 @add(i32 %0, i32 %1) {\n    ; %0 \u4ee3\u8868\u7b2c\u4e00\u4e2a\u53c2\u6570 (\u5373 C\u4ee3\u7801\u91cc\u7684 a)\n    ; %1 \u4ee3\u8868\u7b2c\u4e8c\u4e2a\u53c2\u6570 (\u5373 C\u4ee3\u7801\u91cc\u7684 b)\n\n    %3 = add i32 %0, %1   ; \u628a %0 \u548c %1 \u76f8\u52a0\uff0c\u7ed3\u679c\u5b58\u5165\u65b0\u7684\u5bc4\u5b58\u5668 %3\n    ret i32 %3            ; \u8fd4\u56de %3 \u7684\u503c\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5bf9\u5e94ir\u6709\u540d\u79f0\u6a21\u5f0f<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>define i32 @add(i32 %a, i32 %b) {\n    %result = add i32 %a, %b\n    ret i32 %result\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u6ce8\uff1a\u6bcf\u4e2a%\u53d8\u91cf\u53ea\u80fd\u88ab\u8d4b\u503c\u4e00\u6b21\uff0c\u56e0\u4e3a\u4e0b\u6587\u8981\u8bb2\u7684ssa<br>LLVM IR\u7684\u6307\u4ee4\u683c\u5f0f\u5305\u62ec\u64cd\u4f5c\u7b26\u3001\u7c7b\u578b\u3001\u8f93\u5165\u3001\u8fd4\u56de\u503c\u3002\u4f8b\u5982 \u201c%6 = add i32 %0, %1&#8243;\u7684\u64cd\u4f5c\u7b26\u53f7\u662f&#8221;add\u201d\u3001\u7c7b\u578b\u662f&#8221;i32&#8243;\u3001\u8f93\u5165\u662f&#8221;%0&#8243;\u548c\u201c%1\u201d\u3001\u8fd4\u56de\u503c\u662f&#8221;%6&#8243;\u3002\u603b\u7684\u6765\u8bf4\uff0cIR\u652f\u6301\u4e00\u4e9b\u57fa\u672c\u7684\u6307\u4ee4\uff0c\u7136\u540e\u7f16\u8bd1\u5668\u901a\u8fc7\u8fd9\u4e9b\u57fa\u672c\u6307\u4ee4\u7684\u6765\u5b8c\u6210\u4e00\u4e9b\u590d\u6742\u7684\u8fd0\u7b97\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u57fa\u672c\u5757\uff08basic block\uff09\u548c\u63a7\u5236\u6d41\u56feCFG<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u6c47\u7f16\u8bed\u8a00\u901a\u5e38\u901a\u8fc7\u6709\u6761\u4ef6\u8df3\u8f6c\u548c\u65e0\u6761\u4ef6\u8df3\u8f6c\u4e24\u79cd\u8df3\u8f6c\u6307\u4ee4\u6765\u5b9e\u73b0\u903b\u8f91\u8fd0\u7b97\uff0cllvm ir\u540c\u7406\uff0c\u6709\u65e0\u6761\u4ef6\u8df3\u8f6cbr label\uff0c\u6709\u6761\u4ef6\u8df3\u8f6cbr i1\u2026\uff0c\u6bd4\u5982\u5728LLVM IR\u4e2d&#8221;br label %7&#8243;\u610f\u5473\u7740\u65e0\u8bba\u5982\u4f55\u90fd\u8df3\u8f6c\u5230\u540d\u4e3a%7\u7684label\u90a3\u91cc\uff0c\u8fd9\u662f\u4e00\u6761\u65e0\u6761\u4ef6\u8df3\u8f6c\u6307\u4ee4\u3002&#8221;br i1 %10, label %11, label %22&#8243;\u662f\u6709\u6761\u4ef6\u8df3\u8f6c\uff0c\u610f\u5473\u7740\u8fd9\u5982\u679c%10\u662ftrue\u5219\u8df3\u8f6c\u5230\u540d\u4e3a%11\u7684label\uff0c\u5426\u5219\u8df3\u8f6c\u5230\u540d\u4e3a%22\u7684label\u3002\u57fa\u672c\u5757\uff0c\u4ece\u7b2c\u4e00\u6761\u6307\u4ee4(Leading instruction)\u5230\u6700\u540e\u4e00\u6761\uff08Terminator Instruction\uff09\u8df3\u8f6c\u6307\u4ee4\uff08\u5982br\uff0cret\uff0cswitch\u7b49\uff09\uff0cCFG\u5c31\u662f\u628a\u8df3\u8f6c\u6307\u4ee4\u5f53\u4f5c\u8fde\u63a5\u7684\u8def\u7ebf\uff0c\u6bcf\u4e2a\u57fa\u672c\u5757\u5f53\u6210\u4e00\u4e2a\u5757\u8fde\u6210\u7684\u6267\u884c\u8def\u5f84\u56fe\u3002\u63a7\u5236\u6d41\u5e73\u5766\u5316\u5c31\u662f\u628a\u6240\u6709\u57fa\u672c\u5757\u90fd\u585e\u5728\u4e00\u4e2aswicth\u5206\u53d1\u5668\u4e0b\uff0c\u539f\u672c\u7684a\u5230b\u53d8\u6210\u4e86a\uff0c\u8fd4\u56de\u5206\u53d1\u5668\uff0c\u8ba1\u7b97\uff0c\u5206\u53d1\u5668\u51b3\u5b9a\u53bbb<br>\u4ee5\u4e00\u4e2a\u7b80\u5355c\u8bed\u8a00\u4ee3\u7801\u4e3e\u4f8b<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int test(int a) {\n    int b = a + 5;\n    if (b &gt; 10) {\n        return 1;\n    } else {\n        return 0;\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd9\u6bb5\u4ee3\u7801\u53d8\u6210ir\u540e\u5bf9\u5e94\u4e09\u4e2a\u57fa\u672c\u5757\uff0c\u5165\u53e3\u5757\uff08entry\uff09\uff1a\u505a\u52a0\u6cd5\uff0c\u5224\u65ad\u5927\u5c0f\uff0ctrue\u5757\uff08if.then\uff09\uff1a\u8fd4\u56de1\uff0cfalse\u5757\uff08if.else\uff09\uff1a\u8fd4\u56de0<br>\u5165\u53e3\u5757<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>define i32 @test(i32 %a) {\nentry:                                  ; &lt;--- 1. \u540d\u5b57 (Label)\n  %add = add nsw i32 %a, 5              ; &lt;--- 2. \u5165\u53e3 (Leading Instruction)\n  %cmp = icmp sgt i32 %add, 10\n  br i1 %cmp, label %if.then, label %if.else  ; &lt;--- 3. \u51fa\u53e3 (Terminator)\n\nif.then:                                ; \u4e0b\u4e00\u4e2a\u57fa\u672c\u5757\u7684\u540d\u5b57\n  ret i32 1\n\nif.else:                                ; \u518d\u4e0b\u4e00\u4e2a\u57fa\u672c\u5757\u7684\u540d\u5b57\n  ret i32 0\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">SSA<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u9759\u6001\u5355\u8d4b\u503c\uff0c\u6838\u5fc3\u601d\u60f3\u5c31\u662f\uff0c\u5728ir\u4ee3\u7801\u5217\u51fa\u770b\uff0c\u6bcf\u4e2a\u53d8\u91cf\u53ea\u4f1a\u88ab\u8d4b\u503c\u4e00\u6b21\uff0c\u4ece\u7f16\u8bd1\u5668\u89d2\u5ea6\u6765\u770b\uff0c\u7f16\u8bd1\u5668\u4e0d\u5173\u5fc3\u53d8\u91cf\uff0c\u7f16\u8bd1\u5668\u662f\u4ee5\u6570\u636e\u4e3a\u4e2d\u5fc3\u8bbe\u8ba1\u7684\uff0c\u6bcf\u4e2a\u53d8\u91cf\u7684\u6bcf\u6b21\u5199\u5165\uff0c\u90fd\u751f\u6210\u4e86\u4e00\u4e2a\u65b0\u7684\u6570\u636e\u7248\u672c\uff0c\u7f16\u8bd1\u5668\u7684\u4f18\u5316\u662f\u56f4\u7ed5\u6570\u636e\u7248\u672c\u5c55\u5f00\u7684\uff0c\u76f8\u5f53\u4e8e\u540c\u4e00\u53d8\u91cf\uff0c\u6bcf\u6b21\u88ab\u8d4b\u503c\uff0c\u90fd\u4f1a\u4ea7\u751f\u4e00\u4e2a\u65b0\u7684\u53d8\u91cf\u7248\u672c\u3002<br>\u4f46\u662f\u4f1a\u51fa\u73b0\u4e00\u4e2a\u95ee\u9898\uff0c\u53d8\u91cf\u4e0d\u80fd\u91cd\u5199\uff0c\u90a3\u9047\u5230\u5206\u652f\u600e\u4e48\u529e<br>\u5047\u8bbe\u6709\u4e00\u4e2a\u8fd9\u6837\u7684c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>int a;\nif (condition) {\n    a = 10;  \/\/ \u8def\u5f84A\n} else {\n    a = 20;  \/\/ \u8def\u5f84B\n}\n\/\/ \u90a3\u5728\u8fd9\u91cca\u7b49\u4e8e\u591a\u5c11\uff1f\nreturn a;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u8def\u5f84a\u4f1a\u751f\u6210%a1 = 10\uff0c\u8def\u5f84b\u4f1a\u751f\u6210%a2 = 20<br>\u90a3\u540e\u7eed\u7528a\u7684\u65f6\u5019\uff0c\u8be5\u7528\u54ea\u4e00\u4e2a\uff0c\u8fd9\u65f6\u5019Phi\u8282\u70b9\uff08\u901a\u5e38\u4f4d\u4e8e\u57fa\u672c\u5757\u6700\u5f00\u5934\uff09\uff0c\u6839\u636e\u524d\u9762\u7684\u662f\u4ece\u54ea\u4e2a\u57fa\u672c\u5757\u8df3\u8fc7\u6765\u7684\uff0c\u6839\u636e\u5757\u7ed9\u5bf9\u5e94\u503c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>; ... \u524d\u9762\u662f\u5206\u652f\u5224\u65ad ...\n\nif.true:              ; \u5bf9\u5e94\u8def\u5f84 A\n  %a1 = add i32 0, 10 ; a1 = 10\n  br label %merge     ; \u8df3\u5230\u6c47\u5408\u70b9\n\nif.false:             ; \u5bf9\u5e94\u8def\u5f84 B\n  %a2 = add i32 0, 20 ; a2 = 20\n  br label %merge     ; \u8df3\u5230\u6c47\u5408\u70b9\n\nmerge:                ; \u6c47\u5408\u70b9\n  ; Phi \u8282\u70b9\n  %final_a = phi i32 &#91; %a1, %if.true ], &#91; %a2, %if.false ]\n\n  ret i32 %final_a<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5728\u4fee\u6539\u63a7\u5236\u6d41\u65f6\uff0cphi\u5fc5\u987b\u4e25\u683c\u653e\u5728\u7b2c\u4e00\u884c\uff0c\u8986\u76d6\u6240\u6709\u524d\u9a71\uff08\u5047\u8bbe\u4e00\u4e2a\u57fa\u672c\u5757\u6709\u4e09\u4e2a\u5165\u53e3\uff0c\u90a3phi\u8282\u70b9\u8981\u5168\u90e8\u5199\u51fa\uff09\uff0c\u518d\u9047\u5230\u5faa\u73af\u5904\u7406\uff0c\u5faa\u73af\u4f5c\u4e3a\u4e00\u4e2a\u56de\u73af\u7ed3\u6784\uff0c\u5934\u90e8\u7684\u53d8\u91cf\u503c\uff0c\u7b2c\u4e00\u6b21\u8fdb\u5165\u65f6\u662f\u521d\u59cb\u503c\uff0c\u7b2c\u4e8c\u6b21\u8fdb\u5165\u662f\u7d2f\u52a0\u540e\u7684\u503c\uff0c\u9700\u8981phi\u8282\u70b9\u540c\u65f6\u5904\u7406\u4ece\u5916\u9762\u8fdb\u6765\u548c\u4ece\u5faa\u73af\u5c3e\u90e8\u8df3\u56de\u7684\u60c5\u51b5<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">LLVM IR\u57fa\u7840\u5de5\u5177\u4e0e\u683c\u5f0f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">LLVM IR \u5728\u78c1\u76d8\u4e0a\u6709\u4e24\u79cd\u5b58\u50a8\u683c\u5f0f\uff1aBitcode(.bc)\u548c\u6c47\u7f16\u6587\u672c (.ll)\u3002Bitcode\u662f\u7d27\u51d1\u7684\u4e8c\u8fdb\u5236\u683c\u5f0f\uff0c\u9002\u5408\u673a\u5668\u5904\u7406\uff1b\u6c47\u7f16\u6587\u672c\u662f\u4eba\u7c7b\u53ef\u8bfb\u7684\u683c\u5f0f\uff0c\u9002\u5408\u8c03\u8bd5\u548c\u9605\u8bfb\u3002<br>\u5e38\u7528\u5de5\u5177\u94fe\u5982\u4e0b\uff1a<br>Clang(\u524d\u7aef\u7f16\u8bd1\u5668)\uff1a\u5c06C\/C++\u6e90\u7801\u8f6c\u4e3aIR\u3002<br>\u751f\u6210Bitcode(.bc)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>clang sum.c -emit-llvm -c -o sum.bc<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u751f\u6210\u6c47\u7f16\u8868\u793a (.ll)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>clang sum.c -emit-llvm -S -c -o sum.ll<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">llvm-as\/llvm-dis (\u683c\u5f0f\u8f6c\u6362)\uff1a\u5728\u4e8c\u8fdb\u5236\u548c\u6587\u672c\u4e4b\u95f4\u4e92\u8f6c\u3002<br>\u5c06\u6c47\u7f16\u6587\u672c\u8f6c\u6362\u4e3aBitcode<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>llvm-as sum.ll -o sum.bc<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5c06Bitcode\u53cd\u6c47\u7f16\u4e3a\u6c47\u7f16\u6587\u672c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>llvm-dis sum.bc -o sum.ll<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">llvm-extract (\u63d0\u53d6\u5de5\u5177)\uff1a\u4ece\u6a21\u5757\u4e2d\u5265\u79bb\u51fa\u7279\u5b9a\u7684\u51fd\u6570\u6216\u5168\u5c40\u53d8\u91cf\u3002<br>\u63d0\u53d6sum\u51fd\u6570<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>llvm-extract -func=sum sum.bc -o sum-fn.bc<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>opt -load LLVMObfuscator.so -hlw -S hello.ll -o hello_opt.ll\n\/\/opt\u662f\u8bfb\u53d6bitcode\u548c\u6267\u884cpass\u7684\u5de5\u5177\n-hlw \u662f LLVM Pass \u4e2d\u81ea\u5b9a\u4e49\u7684\u53c2\u6570\uff0c\u7528\u6765\u6307\u5b9a\u4f7f\u7528\u54ea\u4e2a Pass \u8fdb\u884c\u4f18\u5316<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u6ce8\uff1a-S\u5c31\u662f\u4eba\u7c7b\u53ef\u8bfb<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">LLVM\u5185\u5b58\u6a21\u578b (C++ API)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">LLVM\u5728\u5185\u5b58\u4e2d\u901a\u8fc7C++\u7c7b\u5c42\u7ea7\u6765\u8868\u793a\u4ee3\u7801\uff0c\u8fd9\u5957\u7ed3\u6784\u5bf9\u5e94\u4e86LLVM\u8bed\u8a00\u7684\u8bed\u6cd5\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Module\u7c7b<br>\u805a\u5408\u4e86\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\uff08Translation Unit\uff09\u7684\u6570\u636e\u3002\u5b83\u662f\u6700\u9ad8\u5c42\u7ea7\u7684\u5bb9\u5668\uff0c\u5305\u542b\u51fd\u6570\u5217\u8868\u548c\u5168\u5c40\u53d8\u91cf\u3002\u53ef\u4ee5\u901a\u8fc7begin() \u548c end() \u65b9\u6cd5\u904d\u5386\u5176\u4e2d\u7684Function\u3002<\/li>\n\n\n\n<li>Function\u7c7b<br>\u5305\u542b\u51fd\u6570\u5b9a\u4e49\u548c\u58f0\u660e\u3002\u5982\u679c\u662f\u4e00\u4e2a\u51fd\u6570\u5b9a\u4e49\uff0c\u5b83\u5305\u542b\u4e86\u4e00\u7cfb\u5217BasicBlock\u3002\u53ef\u4ee5\u901a\u8fc7begin()\u548cend()\u65b9\u6cd5\u904d\u5386\u8fd9\u4e9b\u57fa\u672c\u5757\u3002\u5b83\u8fd8\u5305\u542b\u53c2\u6570\u5217\u8868\u3002<\/li>\n\n\n\n<li>BasicBlock\u7c7b<br>\u4ee3\u8868\u63a7\u5236\u6d41\u56fe (CFG) \u4e2d\u7684\u4e00\u4e2a\u8282\u70b9\u3002\u5b83\u5305\u542b\u4e00\u4e2a\u6307\u4ee4\u5e8f\u5217\u3002\u5176\u6838\u5fc3\u7279\u5f81\u662f\u5355\u5165\u53e3\u5355\u51fa\u53e3\uff0c\u53ea\u6709\u6700\u540e\u4e00\u6761\u6307\u4ee4\uff08Terminator\uff09\u53ef\u4ee5\u6539\u53d8\u63a7\u5236\u6d41\u3002\u53ef\u4ee5\u901a\u8fc7getTerminator()\u83b7\u53d6\u7ec8\u7ed3\u6307\u4ee4\uff0c\u6216\u901a\u8fc7begin()\u548cend()\u904d\u5386\u5176\u4e2d\u7684Instruction\u3002<\/li>\n\n\n\n<li>Instruction\u7c7b<br>\u4ee3\u8868LLVM IR\u7684\u8fd0\u7b97\u539f\u5b50\uff0c\u5373\u5355\u6761\u6307\u4ee4\u3002\u53ef\u4ee5\u901a\u8fc7getOpcode()\u83b7\u53d6\u64cd\u4f5c\u7801\uff08\u5982add,sub,load\uff09\u3002\u6307\u4ee4\u7ee7\u627f\u81eaUser\u7c7b\uff0c\u56e0\u4e3a\u5b83\u4f7f\u7528\u64cd\u4f5c\u6570\uff1b\u540c\u65f6\u4e5f\u662fValue\u7684\u5b50\u7c7b\uff0c\u56e0\u4e3a\u5b83\u4ea7\u751f\u7ed3\u679c\u3002<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Value\u4e0eUser\u63a5\u53e3<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u8fd9\u662fLLVM\u5904\u7406\u6570\u636e\u6d41\u7684\u6838\u5fc3\u673a\u5236\uff0c\u57fa\u4e8eSSA\u5f62\u5f0f\u8bbe\u8ba1\u3002\u5b83\u5141\u8bb8\u76f4\u63a5\u64cd\u4f5cUse-Def\uff08\u4f7f\u7528-\u5b9a\u4e49\uff09\u94fe\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Value\u7c7b<br>\u4ee3\u8868\u4e00\u4e2a\u53ef\u4ee5\u88ab\u5176\u4ed6\u6307\u4ee4\u4f7f\u7528\u7684\u7ed3\u679c\u3002\u51fd\u6570\u53c2\u6570\u3001\u6307\u4ee4\u7684\u8fd0\u7b97\u7ed3\u679c\u3001\u57fa\u672c\u5757\u7684\u6807\u7b7e\u90fd\u662fValue\u3002<br>\u5b83\u5b9a\u4e49\u4e86use_begin()\u548cuse_end()\u65b9\u6cd5\uff0c\u7528\u4e8e\u904d\u5386\u6240\u6709\u4f7f\u7528\u8be5\u503c\u7684\u5730\u65b9\uff08User\uff09\u3002<br>replaceAllUsesWith(Value *New) \u65b9\u6cd5\u53ef\u4ee5\u5c06\u6240\u6709\u4f7f\u7528\u5f53\u524d\u503c\u7684\u5730\u65b9\u66ff\u6362\u4e3a\u65b0\u503c\uff0c\u5e38\u7528\u4e8e\u4ee3\u7801\u4f18\u5316\u3002<\/li>\n\n\n\n<li>User\u7c7b<br>\u4ee3\u8868\u4f7f\u7528\u4e86\u4e00\u4e2a\u6216\u591a\u4e2aValue\u7684\u5b9e\u4f53\u3002<br>\u5b83\u5b9a\u4e49\u4e86op_begin()\u548cop_end()\u65b9\u6cd5\uff0c\u7528\u4e8e\u5feb\u901f\u8bbf\u95ee\u5b83\u6240\u4f9d\u8d56\u7684\u64cd\u4f5c\u6570\u3002<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">PASS\u57fa\u7c7b<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">LLVM Pass\u57fa\u7c7b\u4e0e\u5176\u8fd0\u884c\u7c92\u5ea6<br>\u5e38\u89c1\u7684Pass\u4e3b\u8981\u5206\u4e3a\u4e09\u7c7b\uff0c\u533a\u522b\u5728\u4e8eLLVM\u904d\u5386\u4ee3\u7801\u7684\u7c92\u5ea6\u548c\u8303\u56f4\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>ModulePass<br>\u9488\u5bf9\u6574\u4e2aModule\u8fd0\u884c\u3002\u901a\u5e38\u5bf9\u5e94\u4e00\u4e2a\u6e90\u6587\u4ef6\uff08\u7ffb\u8bd1\u5355\u5143\uff09\u3002<br>\u7279\u70b9\uff1a\u53ef\u8fdb\u884c\u8de8\u51fd\u6570\u5206\u6790\uff0c\u67e5\u770b\u5168\u5c40\u53d8\u91cf\u4e0e\u51fd\u6570\u4e4b\u95f4\u7684\u5173\u7cfb\u3002<\/li>\n\n\n\n<li>FunctionPass<br>\u9488\u5bf9Function\u8fd0\u884c\u3002<br>\u7279\u70b9\uff1aLLVM\u5728IR\u5c42\u904d\u5386\u6a21\u5757\u4e2d\u7684\u6bcf\u4e2a\u51fd\u6570\uff0c\u5e76\u5bf9\u6bcf\u4e2a\u51fd\u6570\u8c03\u7528\u4e00\u6b21runOnFunction\u65b9\u6cd5\u3002\u8fd9\u662f\u5e38\u7528\u7684Pass\u7c7b\u578b\u4e4b\u4e00\u3002<\/li>\n\n\n\n<li>BasicBlockPass<br>\u9488\u5bf9\u6bcf\u4e00\u4e2aBasicBlock\u8fd0\u884c\u3002<br>\u5b9a\u4e49\uff1a\u57fa\u672c\u5757\u662f\u51fd\u6570\u4e2d\u7684\u57fa\u672c\u5355\u4f4d\uff0c\u8868\u793a\u4e00\u7ec4\u987a\u5e8f\u6267\u884c\u7684\u6307\u4ee4\u3002<br>\u7ed3\u6784\uff1a\u6bcf\u4e2a\u57fa\u672c\u5757\u4ee5\u4e00\u4e2a\u6807\u7b7e(Label)\u5f00\u59cb\uff0c\u5e76\u4ee5\u4e00\u4e2a\u7ec8\u6b62\u6307\u4ee4(Terminator\uff0c\u5982ret\u6216br)\u7ed3\u675f\u3002<br>\u5e94\u7528\uff1a\u8fd9\u79cd\u7c92\u5ea6\u7684Pass\u5728\u63a7\u5236\u6d41\u5e73\u5766\u5316(Control Flow Flattening)\u7b49\u6df7\u6dc6\u6e90\u7801\u4e2d\u5e38\u89c1\u3002<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Module\u7c7b\u6210\u5458\u5217\u8868(C++\u7ed3\u6784)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Module\u7c7b\u4f5c\u4e3a\u6700\u9ad8\u5c42\u5bb9\u5668\uff0c\u5185\u90e8\u7ef4\u62a4\u591a\u79cd\u5217\u8868\u7ba1\u7406\u4e0d\u540c\u7c7b\u578b\u7684\u5168\u5c40\u5bf9\u8c61\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Module {\n  GlobalListType   GlobalList;    \/\/ \u5168\u5c40\u53d8\u91cf\u5217\u8868\n  FunctionListType FunctionList;  \/\/ \u51fd\u6570\u5217\u8868\n  AliasListType    AliasList;     \/\/ \u522b\u540d\u5217\u8868\n  IFuncListType    IFuncList;     \/\/ \"IFunc\"\u5217\u8868(\u95f4\u63a5\u51fd\u6570)\n  NamedMDListType  NamedMDList;   \/\/ \u547d\u540d\u5143\u6570\u636e\u5217\u8868\n  ...\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">LLVM\u7c7b\u578b\u67e5\u8be2\u4e0e\u5b89\u5168\u8f6c\u6362\u6a21\u677f\u51fd\u6570<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">![[0d9e1ae5f21f0064f74774c4aaed3238.png]]<br>\u8fd0\u884c\u65f6\u68c0\u67e5x\u662f\u4e0d\u662f\u5c5e\u4e8eT\u7c7b\u578b\uff0c\u6709\u79cdC++\u6cdb\u578b\u7f16\u7a0b\u7684\u611f\u89c9\uff0c\u8fd4\u56de\u503c\u662fboo\u7c7b\u578b\uff0c\u5982\u679c\u662f\u8fd9\u4e2a\u7c7b\u578b\u5c31true\uff0c\u5426\u5219\u5c31false<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if (isa&lt;CallInst&gt;(inst)) {\n    \/\/ inst \u786e\u5b9e\u662f\u4e00\u4e2a CallInst \u6216\u5176\u5b50\u7c7b\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">![[8f67086242e1ab9a42d0dd4c3ecab39d.png]]<br>\u5728\u8fd0\u884c\u7684\u65f6\u5019\u5c06x\u5411\u4e0b\u8f6c\u6362\u6210T\u7c7b\u578b<br>\u8fd4\u56de\u503c\u662f\u5f53isatx\u4e3atrue\u65f6\u5c31\u8fd4\u56de\u4e00\u4e2a\u6307\u5411T\u7684\u6307\u9488\uff0c\u4e0d\u7136\u5c31\u8fd4\u56denull<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> if (auto *CI = dyn_cast&lt;CallInst&gt;(inst)) {\n  \/\/ \u53ea\u6709\u5f53 inst \u662f CallInst \u65f6\uff0cCI \u975e\u7a7a\n  CI-&gt;getCalledFunction()-&gt;print(errs());\n} else {\n  \/\/ inst \u4e0d\u662f CallInst\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">![[841aebb2aedb0d5664e0e5c3a20777b0.png]]<br>\u8fd0\u884c\u65f6\u65ad\u8a00x\u662fT\u6216T\u7684\u5b50\u7c7b\uff0c\u7136\u540e\u8fdb\u884c\u8f6c\u6362<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> \/\/ \u786e\u4fe1 inst \u662f CallInst\uff0c\u5426\u5219\u4f1a\u5728\u8c03\u8bd5\u6a21\u5f0f\u4e0b\u65ad\u8a00\u5931\u8d25\nauto *CI = cast&lt;CallInst&gt;(inst);\nFunction *callee = CI-&gt;getCalledFunction();<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\">c\u8bed\u8a00\u7f16\u8bd1\u7a0b\u5e8f\u9636\u6bb5<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udcc4 hello.c<br>(\u6e90\u7a0b\u5e8f \/ \u6587\u672c)<br>\u3000\u3000\u2b07\ufe0f<br>\ud83d\udd32 \u9884\u5904\u7406\u5668 (cpp)<br>\u3000\u3000\u2b07\ufe0f<br>\ud83d\udcc4 hello.i<br>(\u4fee\u6539\u4e86\u7684\u6e90\u7a0b\u5e8f \/ \u6587\u672c)<br>\u3000\u3000\u2b07\ufe0f<br>\ud83d\udd32 \u7f16\u8bd1\u5668 (cc1)<br>\u3000\u3000\u2b07\ufe0f<br>\ud83d\udcc4 hello.s<br>(\u6c47\u7f16\u7a0b\u5e8f \/ \u6587\u672c)<br>\u3000\u3000\u2b07\ufe0f<br>\ud83d\udd32 \u6c47\u7f16\u5668 (as)<br>\u3000\u3000\u2b07\ufe0f<br>\ud83d\udcc4 hello.o<br>(\u53ef\u91cd\u5b9a\u4f4d\u76ee\u6807\u7a0b\u5e8f \/ \u4e8c\u8fdb\u5236)<br>\u3000\u3000\u2b07\ufe0f \u2795 (\u5e76\u5165 printf.o)<br>\ud83d\udd32 \u94fe\u63a5\u5668 (ld)<br>\u3000\u3000\u2b07\ufe0f<br>\ud83d\ude80 hello<br>(\u53ef\u6267\u884c\u76ee\u6807\u7a0b\u5e8f \/ \u4e8c\u8fdb\u5236)<br>ir\u7684\u751f\u6210\u5728\u7b2c\u4e8c\u4e2a\u6b65\u9aa4\uff0c\u7f16\u8bd1\u5668\uff08cc1\uff09\u5185\u90e8\uff0c\u5185\u90e8\u6d41\u7a0b<br>hello.i (\u6587\u672c)<br>\u2b07\ufe0f<br>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br>\u2502 \u7f16\u8bd1\u5668 (cc1) \u5185\u90e8 \u2502<br>\u2502 \u2502<br>\u2502 1. \u8bcd\u6cd5\/\u8bed\u6cd5\u5206\u6790 (Parser) \u2502<br>\u2502 \u2b07\ufe0f \u2502<br>\u2502 2. \u751f\u6210 IR (\u4e2d\u95f4\u4ee3\u7801) \ud83d\udc48 \u8fd9\u91cc \u2502<br>\u2502 \u2b07\ufe0f \u2502<br>\u2502 3. \u4f18\u5316 IR (Optimizer) \u2502<br>\u2502 \u2b07\ufe0f \u2502<br>\u2502 4. \u4ee3\u7801\u751f\u6210 (Code Gen) \u2502<br>\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<br>\u2b07\ufe0f<br>hello.s (\u6c47\u7f16\u6587\u672c)<br>LLVM\/Clang: \u5b83\u7684IR\u5c31\u53ebLLVM IR\uff08\u4e5f\u5c31\u662f.ll\u6216.bc\u6587\u4ef6\uff09<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\u4ee3\u7801\u63a7\u5236\u6d41\u6df7\u6dc6<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">\u6761\u4ef6\u63a7\u5236\u6d41\u6df7\u6dc6<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u6dfb\u52a0\u65e0\u5173\u6761\u4ef6\u8bed\u53e5\uff0c\u4ea4\u6362\u6761\u4ef6\u5224\u65ad\u987a\u5e8f\uff0c\u63d2\u5165\u5197\u4f59\u6761\u4ef6\u8bed\u53e5<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u63a7\u5236\u6d41\u5e73\u5766\u5316<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u6d41\u7a0b\u8f6c\u4e3a\u5e73\u5766\u7ed3\u6784\uff0c\u91cd\u6392\u8f6c\u6362\uff0c\u6d41\u7a0b\u5c31\u662f\uff0c\u5206\u53d1\u5faa\u73af\uff0c\u72b6\u6001\u53d8\u91cf\uff0c\u57fa\u672c\u5757\u8c03\u5ea6\uff0c\u6b63\u5e38\u7684\u63a7\u5236\u6d41\u7684\u5c31\u662f\u7ebf\u6027\u5206\u652f\u548c\u8df3\u8f6c<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u51fd\u6570\u5185\u8054<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u5e38\u89c1\u4ee3\u7801\u63a7\u5236\u6d41\u6df7\u6dc6\uff0c\u901a\u8fc7\u5c06\u51fd\u6570\u8c03\u7528\u66ff\u6362\u4e3a\u51fd\u6570\u4f53\u7684\u590d\u5236\u6765\u6539\u53d8\u7a0b\u5e8f\u7684\u63a7\u5236\u6d41\u7a0b<br>\u7b80\u5355\u793a\u4f8b<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u539f\u59cb\u4ee3\u7801\nint add(int a, int b) {\n    return a + b;\n}\n\nint result = add(2, 3);\n\n\/\/ \u6df7\u6dc6\u540e\u7684\u4ee3\u7801\nint result = 2 + 3;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u63a7\u5236\u6d41\u56fe\u91cd\u6784<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u6539\u53d8\u7a0b\u5e8f\u63a7\u5236\u6d41\u7ed3\u6784\uff0c\u901a\u5e38\u4f7f\u7528\u56fe\u8f6c\u6362\u548c\u56fe\u91cd\u6392\u64cd\u4f5c\uff0c\u5c06\u63a7\u5236\u6d41\u56fe\u53d8\u6210\u66f4\u590d\u6742\u6df7\u4e71\u7684\u7ed3\u6784<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u539f\u59cb\u4ee3\u7801\nif (condition1) {\n    \/\/ code block 1\n} else if (condition2) {\n    \/\/ code block 2\n} else {\n    \/\/ code block 3\n}\n\n\/\/ \u6df7\u6dc6\u540e\u7684\u4ee3\u7801\nif (condition1) {\n    \/\/ code block 1\n} else {\n    if (condition2) {\n        \/\/ code block 2\n    } else {\n        \/\/ code block 3\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u5b57\u7b26\u4e32\u52a0\u5bc6<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u52a0\u5bc6\u548c\u89e3\u5bc6\u64cd\u4f5c\uff0c\u901a\u5e38\u4f7f\u7528\u5bf9\u79f0\u52a0\u5bc6\u7b97\u6cd5\u548c\u5bc6\u94a5\u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u52a0\u89e3\u5bc6\u64cd\u4f5c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ \u539f\u59cb\u4ee3\u7801\nString username = \"admin\";\nString password = \"123456\";\n\n\/\/ \u6df7\u6dc6\u540e\u7684\u4ee3\u7801\nString encryptedUsername = decrypt(\"encrypted_username\");\nString encryptedPassword = decrypt(\"encrypted_password\");<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">ollvm\u53cd\u6df7\u6dc6<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">\u53bb\u6307\u4ee4\u66ff\u6362\u6df7\u6dc6\uff08SUB)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">llvm\u63d0\u4f9b\u7684\u4e00\u4e9b\u4f18\u5316pass\u53ef\u4ee5\u7b80\u5316\u548c\u4f18\u5316\u7f16\u8bd1\u540e\u7684ir\uff0c\u53bb\u9664\u65e0\u610f\u4e49\u7684\u6df7\u6dc6\u6307\u4ee4\uff0c\u5c24\u5176\u4f7f\u7528llvm-dis\u53cd\u6c47\u7f16\u6307\u4ee4\u540e\uff0c\u53ef\u4ee5\u901a\u8fc7opt\u5de5\u5177\u7ed3\u5408-03\u4f18\u5316\u7ea7\u522b\u6765\u7b80\u5316\u7a0b\u5e8f\uff0c\u5229\u7528llvm\u7f16\u8bd1\u5de5\u5177\u94fe\u4e2d\u5185\u7f6e\u4f18\u5316\u6280\u672f\u81ea\u52a8\u53bb\u66ff\u6362<br>\u6216\u8005\u4f7f\u7528miasm\u6846\u67b6\u8fdb\u884c\u5339\u914d\u518d\u4f18\u5316\uff0c\u901a\u8fc7\u6a21\u62df\u4e8c\u8fdb\u5236\u4ee3\u7801\u7684\u6267\u884c\uff0c\u81ea\u52a8\u5316\u8bc6\u522b\u7a0b\u5e8f\u4e2d\u7684\u6df7\u6dc6\u6a21\u5f0f\uff0c\u901a\u8fc7\u53bb\u9664\u5197\u4f59\u00b7\u6307\u4ee4\u6765\u7b80\u5316\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u8fdb\u884c\u4e8c\u8fdb\u5236\u5206\u6790\uff0c\u63a7\u5236\u6d41\u6062\u590d\uff0c\u6df7\u6dc6\u53bb\u9664<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>d810\u53bb\u9664<\/li>\n\n\n\n<li>GAMBA \u7b80\u5316\u590d\u6742\u7684 SUB \u8868\u8fbe\u5f0f<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">\u53cd\u5b57\u7b26\u4e32\u52a0\u5bc6<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5b57\u7b26\u4e32\u52a0\u5bc6\u5b58\u5728\u89e3\u5bc6\u51fd\u6570\uff0c\u901a\u8fc7\u67d0\u4e9b\u7b97\u6cd5\u5c06\u52a0\u5bc6\u5b57\u7b26\u4e32\u8fd8\u539f\u6210\u660e\u6587\uff0c\u4f8b\u5982\u547d\u540d\u4e3adatadiv_decode\u6216\u5176\u4ed6\u7684\u7c7b\u4f3c\u51fd\u6570\uff0c\u5728\u4e8c\u8fdb\u5236\u4e2d\u641c\u7d22\u7279\u5b9a\u89e3\u5bc6\u51fd\u6570\u5feb\u901f\u5b9a\u4f4d<\/li>\n\n\n\n<li>init_array\u4e2d\u89e3\u5bc6\uff0c\u5728\u7a0b\u5e8f\u542f\u52a8\u65f6\u6267\u884c\u7684\u4ee3\u7801\u533a\u57df\uff0c\u901a\u5e38\u7528\u4e8e\u521d\u59cb\u5316\u64cd\u4f5c\uff0c\u56e0\u6b64\u901a\u8fc7\u6a21\u62df\u7a0b\u5e8f\u542f\u52a8\u8fc7\u7a0b\u53ef\u4ee5\u63d0\u53d6\u89e3\u5bc6\u540e\u5b57\u7b26\u4e32\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u52a8\u6001\u5206\u6790\u5de5\u5177\u6216\u6a21\u62df\u6267\u884c\u6765\u67e5\u770b\u89e3\u5bc6\u8fc7\u7a0b<\/li>\n\n\n\n<li>jni_onload\u89e3\u5bc6\uff0c\u5728jni\u5e93\u52a0\u8f7d\u65f6\u88ab\u8c03\u7528\uff0c\u5728jni\u5e93\u52a0\u8f7d\u65f6\uff0c\u89e3\u5bc6\u64cd\u4f5c\u53ef\u80fd\u4f1a\u5728jni_onload\u4e2d\u6267\u884c\uff0c\u901a\u5e38\u51c6\u5907\u4e00\u4e9b\u52a0\u5bc6\u6570\u636e\u7ed9java\u5c42\uff0c\u53ef\u4ee5hook\u6216\u8005\u7528unicorn\u6a21\u62df\u6267\u884c<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">\u53cd\u865a\u5047\u63a7\u5236\u6d41\uff08BCF\uff09<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e00\u822c\u601d\u8def\u4e3a\u51fa\u53bb\u4e0d\u53ef\u8fbe\u5757\u548c\u4e0d\u900f\u660e\u8c13\u8bcd\uff0c\u96be\u70b9\u5728\u4e8e\u4e0d\u900f\u660e\u8c13\u8bcd\uff0c\u5b58\u5728\u6c38\u771f\u6c38\u5047\u578b\uff0c\u53ef\u771f\u53ef\u5047\u578b\uff0c\u4e5f\u8981\u8003\u8651\u6b7b\u5faa\u73af\u95ee\u9898<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u6c38\u771f\/\u5047\u578b\uff1a\u63d2\u5165\u7684\u540e\u7eed\u57fa\u672c\u5757\u4e2d\u5fc5\u6709\u4e00\u4e2a\u4e0d\u88ab\u6267\u884c\n\u53ef\u771f\u53ef\u5047\u578b\uff1a\u63d2\u5165\u7684\u4e24\u4e2a\u540e\u7ee7\u57fa\u672c\u5757\u7684\u8bed\u4e49\u5e94\u76f8\u540c<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u601d\u8def\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\uff081\uff09\u4e0d\u76f4\u63a5\u5904\u7406\u4e0d\u900f\u660e\u8c13\u8bcd\uff0c\u901a\u8fc7\u8ba9\u4e0d\u900f\u660e\u8c13\u8bcd\u7684\u53d8\u91cf\u5730\u5740\u53ef\u8bfb\uff0c\u5219IDA\u4fbf\u53ef\u4ee5\u4f18\u5316\n\u627e\u5230\u53c2\u4e0e\u4e0d\u900f\u660e\u8c13\u8bcd\u8ba1\u7b97\u7684\u5168\u5c40\u53d8\u91cf\uff0c\u4fee\u6539\u53d8\u91cf\u6240\u5728\u7684\u5185\u5b58\u6bb5\uff08segment\uff09\u7684\u5c5e\u6027\uff0c\u901a\u5e38\u4f4d\u4e8edata\u6bb5\u6216\u8005bss\u6bb5\uff0c\u4fee\u6539\u4e3a\u53ea\u8bfb\uff0c\u6216\u8005\u901a\u8fc7\u5feb\u6377\u952ealt\u52a0s\u7f16\u8f91\uff0c\u6216\u8005\u7528idapy\u4fee\u6539\n\uff082\uff09\u76f4\u63a5\u5c06\u4e0d\u900f\u660e\u8c13\u8bcd\u8d4b\u503c\u4e3a0\u6216\u8005\u5c06\u4e0d\u900f\u660e\u8c13\u8bcd\u4e2d\u53d8\u91cfx\uff0cy\u8d4b\u503c\u4e3a0\n\u627e\u5230\u4e0d\u900f\u660e\u8c13\u8bcd\u5bf9\u5e94\u7684\u6c47\u7f16\u6307\u4ee4\uff08\u901a\u5e38\u662f\u6761\u4ef6\u8df3\u8f6c\u6307\u4ee4\uff0c\u5982jz, jnz\uff09\u3002\n\u901a\u8fc7\u52a8\u6001\u8c03\u8bd5\u6216\u5206\u6790\u786e\u5b9a\u8be5\u8c13\u8bcd\u7684\u7ed3\u679c\u662f\u6c38\u771f\u8fd8\u662f\u6c38\u5047\u3002\n\u76f4\u63a5\u4fee\u6539\u4e8c\u8fdb\u5236\u4ee3\u7801\u3002\u5982\u679c\u6761\u4ef6\u5fc5\u4e3a\u771f\uff0c\u5c06jnz target\u6539\u4e3ajmp target\uff1b\u5982\u679c\u5fc5\u4e3a\u5047\uff0c\u5c06\u8df3\u8f6c\u6307\u4ee4\u4fee\u6539\u4e3anop\u3002\u6216\u8005\uff0c\u5728\u6c47\u7f16\u5c42\u9762\u5c06\u6bd4\u8f83\u6307\u4ee4\u524d\u7684\u53d8\u91cf\u8d4b\u503c\u6307\u4ee4\u76f4\u63a5\u4fee\u6539\u4e3a\u5e38\u6570\u8d4b\u503c\uff08\u5982mov eax, 0\uff09\uff0c\u8feb\u4f7f\u6761\u4ef6\u8df3\u8f6c\u53d8\u4e3a\u786e\u5b9a\u8df3\u8f6c\u3002\n\uff083\uff09\u7f16\u8bd1\u5668\u4f18\u5316\u53bb\u5e72\u6389\u4e0d\u900f\u660e\u8c13\u8bcd\n\u83b7\u53d6LLVM IR\uff08\u5982\u679c\u662f\u9006\u5411\u5de5\u7a0b\uff0c\u9700\u4f7f\u7528RetDec\u6216McSema\u7b49\u5de5\u5177\u5c06\u4e8c\u8fdb\u5236\u63d0\u5347\u4e3aIR\uff09\u3002\u4f7f\u7528LLVM\u7684opt\u5de5\u5177\u8fd0\u884c\u4f18\u5316Pass\u3002\n\u5404Pass\u4f5c\u7528\uff1a\n-mem2reg\uff1a\u5c06\u5185\u5b58\u8bbf\u95ee\u63d0\u5347\u4e3a\u5bc4\u5b58\u5668\u64cd\u4f5c\uff0c\u8fd9\u662f\u540e\u7eed\u4f18\u5316\u7684\u57fa\u7840\u3002\n-sccp (Sparse Conditional Constant Propagation)\uff1a\u7a00\u758f\u6761\u4ef6\u5e38\u91cf\u4f20\u64ad\uff0c\u80fd\u8ba1\u7b97\u51fa\u5f88\u591a\u590d\u6742\u7684\u5e38\u91cf\u8868\u8fbe\u5f0f\u3002\n-simplifycfg\uff1a\u7b80\u5316\u63a7\u5236\u6d41\u56fe\uff0c\u5b83\u4f1a\u5220\u9664\u90a3\u4e9b\u786e\u5b9a\u7684\u6761\u4ef6\u8df3\u8f6c\u751f\u6210\u7684\u6b7b\u5206\u652f\uff0c\u5e76\u5408\u5e76\u57fa\u672c\u5757\u3002\n-adce (Aggressive Dead Code Elimination)\uff1a\u6fc0\u8fdb\u7684\u6b7b\u4ee3\u7801\u6d88\u9664\uff0c\u79fb\u9664\u5bf9\u7ed3\u679c\u65e0\u5f71\u54cd\u7684\u8ba1\u7b97\u6307\u4ee4\u3002<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e0d\u53ef\u8fbe\u5757\uff0c\u6307\u63a7\u5236\u6d41\u65e0\u6cd5\u5230\u8fbe\u57fa\u672c\u5feb\uff0c\u53ef\u4ee5\u7528\u7b26\u53f7\u6267\u884c\u6216\u8005\u6a21\u62df\u6267\u884c\u6765\u9664\u53bb\u4e00\u4e9b\u57fa\u672c\u4e0d\u53ef\u8fbe\u5757<br>idapython\u811a\u672c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import ida_xref\nimport ida_idaapi\nfrom ida_bytes import get_bytes, patch_bytes\nfrom ida_segment import get_segm_by_name\n\n# \u5c06 mov \u5bc4\u5b58\u5668, \u4e0d\u900f\u660e\u8c13\u8bcd \u4fee\u6539\u4e3a mov \u5bc4\u5b58\u5668, 0\ndef do_patch(ea):\n    \"\"\"\n    \u68c0\u67e5\u5e76\u66ff\u6362\u4e0d\u900f\u660e\u8c13\u8bcd\u7684 mov \u64cd\u4f5c\uff0c\u5c06\u5176\u66ff\u6362\u4e3a mov \u5bc4\u5b58\u5668, 0\n    \"\"\"\n    # \u83b7\u53d6\u6307\u4ee4\u5b57\u8282\n    opcode = get_bytes(ea, 1)\n\n    # \u5224\u65ad\u662f\u5426\u4e3a mov \u5bc4\u5b58\u5668, &#91;\u5bc4\u5b58\u5668\/\u5185\u5b58] \u6307\u4ee4 (\u4f8b\u5982 mov eax, edi)\n    if opcode == b\"\\x8B\":\n        # \u83b7\u53d6\u76ee\u6807\u5bc4\u5b58\u5668\n        reg = (ord(get_bytes(ea + 1, 1)) &amp; 0b00111000) &gt;&gt; 3\n\n        # \u5c06\u539f\u59cb\u7684 mov \u6307\u4ee4\u66ff\u6362\u4e3a mov \u5bc4\u5b58\u5668, 0 (\u5373 mov eax, 0)\n        patch_bytes(ea, (0xB8 + reg).to_bytes(1, 'little') + b'\\x00\\x00\\x00\\x00\\x90')\n    else:\n        print(f\"Unsupported instruction at {hex(ea)}\")\n\ndef get_bss_segment():\n    \"\"\"\n    \u83b7\u53d6 BSS \u6bb5\u7684\u5730\u5740\u8303\u56f4\n    \"\"\"\n    seg = get_segm_by_name('.bss')\n    if seg is None:\n        print(\"BSS segment not found.\")\n        return None, None\n    return seg.start_ea, seg.end_ea\n\ndef patch_control_flow(start, end):\n    \"\"\"\n    \u5bf9\u6307\u5b9a\u7684\u5730\u5740\u8303\u56f4\u5185\u7684\u865a\u5047\u63a7\u5236\u6d41\u8fdb\u884c\u4fee\u590d\n    \"\"\"\n    for addr in range(start, end, 4):\n        # \u83b7\u53d6\u6240\u6709\u5bf9\u8be5\u5730\u5740\u7684\u4ea4\u53c9\u5f15\u7528\n        ref = ida_xref.get_first_dref_to(addr)\n        print(f\"Processing references for address {hex(addr)}\".center(40, '-'))\n\n        # \u904d\u5386\u6240\u6709\u4ea4\u53c9\u5f15\u7528\n        while ref != ida_idaapi.BADADDR:\n            print(f\"Patch reference at {hex(ref)}\")\n            do_patch(ref)\n            ref = ida_xref.get_next_dref_to(addr, ref)\n\n        print('-' * 40)\n\ndef main():\n    # \u83b7\u53d6 .bss \u6bb5\u7684\u5730\u5740\u8303\u56f4\n    start, end = get_bss_segment()\n    if start is None or end is None:\n        return  # \u5982\u679c\u627e\u4e0d\u5230 .bss \u6bb5\u5219\u9000\u51fa\n\n    # \u5bf9\u865a\u5047\u63a7\u5236\u6d41\u8fdb\u884c\u4fee\u590d\n    patch_control_flow(start, end)\n\nif __name__ == \"__main__\":\n    main()<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\u53cd\u63a7\u5236\u6d41\u5e73\u5766\u5316<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">![[Pasted image 20260103030401.png]]<br>\u771f\u5b9e\u903b\u8f91\u5728\u4e8e\uff0c\u5e8f\u8a00\u5757\uff0c\u771f\u5b9e\u5757\uff0cretn\u5757\u4e2d<br>\u6838\u5fc3\u5728\u4e8e\u533a\u5206\u771f\u5b9e\u5757\u548c\u5206\u53d1\u5668\uff0c\u6062\u590d\u771f\u5b9e\u5757\u987a\u5e8f\uff0c\u901a\u8fc7\u7279\u5f81\u5339\u914d\u548c\u52a8\u6001\u6267\u884c\u76f8\u7ed3\u5408\u3002\u4fee\u8865\u8fc7\u7a0b\u4e2d\u4f18\u5148\u4f7f\u7528\u7b80\u5355\u7684\u8df3\u8f6c\u903b\u8f91\uff0c\u5fc5\u8981\u65f6\u6574\u4f53\u91cd\u6784\u51fd\u6570<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u5148\u4fdd\u5b58\u6240\u6709\u57fa\u672c\u5757<br>\u63a7\u5236\u6d41\u5e73\u5766\u5316\u91cd\u6784\u6267\u884c\u6d41\u5206\u4e3a\u4e09\u94fe<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5165\u53e3\u94fe\uff1a\u539f\u59cb\u51fd\u6570\u5165\u53e3\u5230\u4e3b\u5206\u53d1\u5668\u8def\u5f84<\/li>\n\n\n\n<li>\u5faa\u73af\u94fe\uff1a\u4e3b\u5206\u53d1\u5668\u4e4b\u95f4\u7684\u5faa\u73af\u8df3\u8f6c\u8def\u5f84<\/li>\n\n\n\n<li>\u8fd4\u56de\u94fe\uff1a\u4e3b\u5206\u53d1\u5668\u5230\u51fd\u6570\u7ed3\u675f\u7684\u8def\u5f84<br>\u91cd\u70b9\u5173\u6ce8\u5206\u53d1\u5668\u8bc6\u522b<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u533a\u5206\u771f\u5b9e\u5757\u548c\u5206\u53d1\u5668 \u5206\u53d1\u5668\uff1a\u5f15\u5bfc\u6d41\u7a0b\u8df3\u8f6c\u5230\u4e0b\u4e00\u4e2a\u57fa\u672c\u5757 \u5f15\u7528\u6b21\u6570\u8f83\u9ad8\uff0c\u7ed3\u6784\u56fa\u5b9a\uff08\u5982switchcase\u6216\u590d\u6742ifelse\uff09 \u771f\u5b9e\u5757\uff1a\u5b58\u5728\u5185\u5b58\u64cd\u4f5c\uff08\u5982\u5185\u5b58\u8bbf\u95ee\u6307\u4ee4ldr,str\uff09\uff0c\u51fd\u6570\u8c03\u7528\uff08\u51fa\u73b0bl\u6216blx\u6307\u4ee4\uff09\uff0c\u786e\u5b9a\u6027\u8df3\u8f6c\uff08\u660e\u786e\u6761\u4ef6\u8df3\u8f6c\u6307\u4ee4\uff0c\u5982beq\uff0cbne\uff09 \u65b9\u6cd5\uff1a\n<ol class=\"wp-block-list\">\n<li>\u904d\u5386\u6240\u6709\u57fa\u672c\u5757\uff0c\u7edf\u8ba1\u5f15\u7528\u6b21\u6570<\/li>\n\n\n\n<li>\u901a\u8fc7\u7279\u5f81\u5339\u914d\u8bc6\u522b<\/li>\n<\/ol>\n<\/li>\n\n\n\n<li>\u8fde\u63a5\u771f\u5b9e\u5757\u987a\u5e8f\uff0c\u4e00\u822c\u9759\u6001\u901a\u8fc7ida trace\u7136\u540e\u7f16\u5199idapython\u811a\u672c\uff0c\u52a8\u6001\u901a\u8fc7\u7b26\u53f7\u6267\u884c\uff0c\u6a21\u62df\u6267\u884c<br>\u9759\u6001\uff1a\u4f7f\u7528trace\u529f\u80fd\u83b7\u53d6\u6267\u884c\u8def\u5f84\uff0c\u7528idapython\u89e3\u6790\u8fde\u63a5\u5173\u7cfb\uff0c\u5224\u65ad\u5206\u652f\u6761\u4ef6<br>\u52a8\u6001\uff1a\u4f7f\u7528\u7b26\u53f7\u6267\u884c\u5de5\u5177\u5982angr\u6a21\u62df\u6267\u884c\u4ee3\u7801\uff0c\u8ddf\u8e2a\u6267\u884c\u7ed3\u679c\uff0c\u7ed3\u5408\u4eba\u5de5\u5206\u6790\u8c03\u6574<br>\u7279\u4f8b\uff1a\u771f\u5b9e\u5757\u5305\u542b\u53cc\u8def\u5f84\uff08movwne\/movtne r1\uff09\u7684\u60c5\u51b5\uff0c\u9700\u8981\u5206\u522b\u5904\u7406\u4e24\u6761\u8def\u5f84\u5e76\u8fde\u63a5\u81f3\u5bf9\u5e94\u7684\u771f\u5b9e\u5757\u3002<\/li>\n\n\n\n<li>\u7f16\u5199patch\u4fee\u590d\uff0c\u5bf9\u76ee\u6807\u51fd\u6570\u8fdb\u884c\u4fee\u590d\uff0c\u6062\u590d\u539f\u59cb\u903b\u8f91<br>\u4e00. \u76f4\u63a5patch<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6e05\u7406\u65e0\u7528\u5757\uff1a\u5c06\u5206\u53d1\u5668\u6216\u865a\u5047\u5757nop\u6389<\/li>\n\n\n\n<li>\u4fee\u8865\u65e0\u5206\u652f\u5757\uff1a\u771f\u5b9e\u5757\u6700\u540e\u4e00\u6761\u6307\u4ee4\u6539\u4e3a\u65e0\u6761\u4ef6\u8df3\u8f6c\uff08jmp\uff09\u5230\u4e0b\u4e00\u4e2a\u771f\u5b9e\u5757<\/li>\n\n\n\n<li>\u4fee\u8865\u5206\u652f\u5757\uff1a\u5c06\u6761\u4ef6\u8df3\u8f6c\u6307\u4ee4\uff08\u5982cmovz\uff09\u66ff\u6362\u4e3a\u660e\u786e\u7684\u6761\u4ef6\u8df3\u8f6c\uff08\u5982jz\uff09\uff0c\u5e76\u6dfb\u52a0\u65e0\u6761\u4ef6\u8df3\u8f6c\u6307\u4ee4\u8c03\u9999=\u5411\u53e6\u4e00\u5206\u652f<br>\u4e8c.\u91cd\u6784\u51fd\u6570\u903b\u8f91<\/li>\n\n\n\n<li>\u63d0\u53d6\u6240\u6709\u771f\u5b9e\u5757\u6307\u4ee4\uff0c\u6839\u636e\u5173\u7cfb\u6392\u5217<\/li>\n\n\n\n<li>\u8ba1\u7b97\u6bcf\u4e2a\u771f\u5b9e\u5757\u76f8\u5bf9\u504f\u79fb\uff0c\u5f62\u6210\u65b0\u51fd\u6570\u4ee3\u7801<\/li>\n\n\n\n<li>\u66ff\u6362\u6df7\u6dc6\u540e\u7684\u76ee\u6807\u51fd\u6570<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">idapython\u5bfb\u627e\u771f\u5b9e\u5757<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>#idapython\u5bfb\u627e\u771f\u5b9e\u5757\nimport idaapi\nimport idc\n\ntarget_func=0x401CE0#\u8981\u5904\u7406\u7684\u51fd\u6570\u5730\u5740\npreprocess_block=0x402057#\u9884\u5904\u7406\u5757\u7684\u5730\u5740\n#\u5bfb\u627e\u6240\u6709\u9884\u5904\u7406\u5668\u7684\u524d\u9a71\nTrue_Block=&#91;]\nFake_Block=&#91;]\n'''FlowChart\nConstructor\n@param f: A func_t type, use get_func(ea) to get a reference\n@param bounds: A tuple of the form (start, end). Used if \"f\" is None\n@param flags: one of the FC_xxxx flags.\n\u8fd9\u4e2a\u51fd\u6570\u5c31\u662f\u8fd4\u56deida\u6d41\u7a0b\u56fe\u4e2d\u7684\u6240\u6709\u5757\u4e2d\u7684\u64cd\u4f5c\u6743\uff0c\u6bd4\u5982\u67e5\u770b\u51fd\u6570\u8d77\u59cb\u5730\u5740\uff0c\u7ed3\u675f\u5730\u5740\u7b49\u7b49\n'''\nf_block=idaapi.FlowChart(idaapi.get_func(target_func),flags=idaapi.FC_PREDS)\nfor block in f_block:\n    #print(block)\n    #\u9884\u5904\u7406\u5668\u7684\u524d\u9a71\u90fd\u662f\u771f\u5b9e\u5757\n    if block.start_ea==preprocess_block:\n        Fake_Block.append((block.start_ea,idc.prev_head(block.end_ea)))\n        print(\"Find True Bolcks\\n\")\n        tbs=block.preds()\n        for tb in tbs:\n            True_Block.append((tb.start_ea,idc.prev_head(tb.end_ea)))\n        print(True_Block)\n    elif not &#91;x for x in block.succs()]:\n        print(\"find ret\")\n        True_Block.append((block.start_ea,idc.prev_head(block.end_ea)))    \n    elif block.start_ea!=target_func:\n        Fake_Block.append((block.start_ea,idc.prev_head(block.end_ea)))\n\nprint('True block')\nprint(True_Block)\nprint(\"Fake Block\")\nprint(Fake_Block)<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">OLLVM\u73af\u5883\u642d\u5efa<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">ollvm4.0\u6e90\u7801<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone -b llvm-4.0 --depth=1 https:\/\/github.com\/obfuscator-llvm\/obfuscator.git<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5b89\u88c5docker<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install docker.io<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u5b89\u88c5\u7f16\u8bd1 ollvm \u7684 docker \u73af\u5883<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo docker pull nickdiego\/ollvm-build<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u7f16\u8bd1ollvm<br>\u4e0b\u8f7d\u7f16\u8bd1\u811a\u672c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone --depth=1 https:\/\/github.com\/oacia\/docker-ollvm.git<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u7f16\u8bd1<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ollvm-build.sh`  \u540e\u9762\u8ddf\u7684\u53c2\u6570\u662f `ollvm\u7684\u6e90\u7801\u76ee\u5f55\nsudo docker-ollvm\/ollvm-build.sh \/home\/xw\/Desktop\/ollvm\/obfuscator\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u521b\u5efa\u8f6f\u94fe\u63a5<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/usr\/bin\/env bash\n# \u4e00\u952e\u90e8\u7f72 OLLVM \u53ef\u6267\u884c\u6587\u4ef6\u5230 \/usr\/local\/ollvm\/bin\uff0c\u5e76\u52a0 -ollvm \u540e\u7f00\n\nset -e\n\nSRC_DIR=\"\/home\/xw\/Desktop\/ollvm\/obfuscator\/build_release\/bin\"\nDEST_DIR=\"\/usr\/local\/ollvm\/bin\"\n\nsudo mkdir -p \"${DEST_DIR}\"\n\necho \"&gt;&gt;&gt; \u6b63\u5728\u6279\u91cf\u521b\u5efa\u8f6f\u94fe\u63a5 ...\"\nfor f in \"${SRC_DIR}\"\/*; do\n    base=$(basename \"$f\")\n    sudo ln -sf \"$f\" \"${DEST_DIR}\/${base}-ollvm\"\ndone\n\necho \"&gt;&gt;&gt; \u5df2\u5b8c\u6210\u94fe\u63a5\u5230 ${DEST_DIR}\"<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>vim ~\/.bashrc\nexport PATH=\"\/usr\/local\/ollvm\/bin:$PATH\"\nsource ~\/.hasbrc<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">\u4e00\u4e9b\u4f7f\u7528<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">trace<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u9996\u5148\u9700\u8981\u8bbe\u7f6eTracing options\u3002Debugger->Tracing->Tracing options\u3002<\/li>\n\n\n\n<li>\u6253\u5f00\u540e\u8bbe\u7f6ebuffer size\uff0c\u548cTrace file\u3002\u5982\u679c\u9700\u8981buffer size\u65e0\u9650\u5927\uff0c\u53ef\u4ee5\u8bbe\u7f6e\u4e3a0\u3002\uff08\u5982\u4e0b\u56fe\u6240\u793a\uff09<\/li>\n\n\n\n<li>Tracing \u652f\u6301 \u51fd\u6570Tracing \u548c \u6307\u4ee4Tracing\u3002\u53ef\u4ee5\u5728\u52a8\u6001\u8c03\u8bd5\u65f6\uff0c\u70b9\u51fb\u5de5\u5177\u680f\u4e2d\u7684\u6309\u94ae\u5f00\u542f\u3002<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">unicorn<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Unicorn \u662f\u4e00\u4e2a\u6a21\u62df CPU \u6267\u884c\u7684\u6846\u67b6\uff0cUnicorn \u5728 OLLVM \u53cd\u6df7\u6dc6\u4e2d\u7684\u4f5c\u7528\u4e3a\u8ba1\u7b97 BR \u5bc4\u5b58\u5668\u7684\u503c\u4ee5\u53ca\u63a7\u5236\u6d41\u5e73\u5766\u5316\u4e2d\u4f5c\u4e3a SWITCH ID \u7684\u5bc4\u5b58\u5668\u7684\u503c<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import unicorn  # \u5bfc\u5165 Unicorn \u5e93\nimport capstone  # \u5bfc\u5165 Capstone \u5e93\nimport binascii  # \u5bfc\u5165 binascii \u5e93\n\n# \u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570 print_regs\uff0c\u7528\u4e8e\u6253\u5370\u5bc4\u5b58\u5668\u7684\u503c\ndef print_regs(mu):\n    for i in range(unicorn.arm64_const.UC_ARM64_REG_X0, unicorn.arm64_const.UC_ARM64_REG_X30 + 1):  # \u904d\u5386 X0-X30\n        print('X%d: 0x%x' % (i - unicorn.arm64_const.UC_ARM64_REG_X0, mu.reg_read(i)))\n\n# \u5b9a\u4e49\u4e00\u4e2a\u56de\u8c03\u51fd\u6570 hook_code\uff0c\u7528\u4e8e\u5728\u4ee3\u7801\u6267\u884c\u65f6\u89e6\u53d1\ndef hook_code(mu, addr, size, user_data):\n    print('-------hook code start-------')\n    code = mu.mem_read(addr, size)  # \u8bfb\u53d6\u5185\u5b58\u4e2d\u7684\u4ee3\u7801\n    cp = capstone.Cs(capstone.CS_ARCH_ARM64, capstone.CS_MODE_ARM)  # \u521d\u59cb\u5316 Capstone \u6a21\u5757\n    for i in cp.disasm(code, addr):  # \u53cd\u6c47\u7f16\u4ee3\u7801\n        print('&#91;addr:0x%x]: %s %s' % (i.address, i.mnemonic, i.op_str))\n    print_regs(mu)  # \u6253\u5370\u5bc4\u5b58\u5668\u7684\u503c\n\n# \u5b9a\u4e49\u4e00\u4e2a\u56de\u8c03\u51fd\u6570 hook_mem_write\uff0c\u7528\u4e8e\u5728\u5185\u5b58\u5199\u5165\u65f6\u89e6\u53d1\ndef hook_mem_write(mu, type, addr, size, value, user_data):\n    print('-------hook mem write-------')\n    if type == unicorn.UC_MEM_WRITE:  # \u5982\u679c\u662f\u5185\u5b58\u5199\u5165\u4e8b\u4ef6\n        print('memory write addr:0x%x size:%x value:0x%x' % (addr, size, value))\n\n# \u5b9a\u4e49\u4e00\u4e2a\u56de\u8c03\u51fd\u6570 hook_intr\uff0c\u7528\u4e8e\u5728\u4e2d\u65ad\u53d1\u751f\u65f6\u89e6\u53d1\ndef hook_intr(mu, intno, user_data):\n    print('-------hook intr start-------')\n    print_regs(mu)  # \u6253\u5370\u5bc4\u5b58\u5668\u7684\u503c\n\n# \u5b9a\u4e49\u4e00\u4e2a\u6d4b\u8bd5\u51fd\u6570 test_arm64\ndef test_arm64():\n    # \u5b9a\u4e49\u4e00\u6bb5 ARM64 \u6307\u4ee4\u96c6\u7684\u4ee3\u7801\n    code = b'\\xe0\\x03\\x1f\\xaa'  # mov x0, xzr (\u793a\u4f8b\u6307\u4ee4\uff0c\u53ef\u66ff\u6362)\n\n    # \u521d\u59cb\u5316 Unicorn \u6a21\u5757\n    mu = unicorn.Uc(unicorn.UC_ARCH_ARM64, unicorn.UC_MODE_ARM)\n\n    # \u5b9a\u4e49\u5185\u5b58\u5730\u5740\u3001\u5927\u5c0f\n    addr = 0x1000  \n    size = 0x1000\n\n    # \u6620\u5c04\u5185\u5b58\u5e76\u5c06\u4ee3\u7801\u5199\u5165\u5185\u5b58\n    mu.mem_map(addr, size)  \n    mu.mem_write(addr, code)\n\n    # \u8bfb\u53d6\u5185\u5b58\u4e2d\u7684\u4ee3\u7801\u5e76\u6253\u5370\n    code_bytes = mu.mem_read(addr, len(code))  \n    print('addr:0x%x, content:%s' % (addr, binascii.b2a_hex(code_bytes)))\n\n    # \u8bbe\u7f6e\u5bc4\u5b58\u5668\u7684\u503c\n    mu.reg_write(unicorn.arm64_const.UC_ARM64_REG_X0, 0x100)\n    mu.reg_write(unicorn.arm64_const.UC_ARM64_REG_X1, 0x200)\n    mu.reg_write(unicorn.arm64_const.UC_ARM64_REG_X2, 0x300)\n    mu.reg_write(unicorn.arm64_const.UC_ARM64_REG_X3, 0x400)\n\n    # \u76d1\u542c\u4ee3\u7801\u6267\u884c\u4e8b\u4ef6\n    mu.hook_add(unicorn.UC_HOOK_CODE, hook_code)\n\n    # \u76d1\u542c\u5185\u5b58\u5199\u5165\u4e8b\u4ef6\n    mu.hook_add(unicorn.UC_HOOK_MEM_WRITE, hook_mem_write)\n\n    # \u76d1\u542c\u4e2d\u65ad\u4e8b\u4ef6\n    mu.hook_add(unicorn.UC_HOOK_INTR, hook_intr)\n\n    try:\n        # \u5f00\u59cb\u6a21\u62df\u6267\u884c\u4ee3\u7801\n        mu.emu_start(addr, addr + len(code))  \n    except unicorn.UcError as e:\n        print(e)\n\n    # \u8bfb\u53d6\u5185\u5b58\u4e2d\u7684\u6570\u636e\u5e76\u6253\u5370\n    stack_bytes = mu.mem_read(addr, 4)  \n    print(\"mem:0x%x, value:%s\" % (addr, binascii.b2a_hex(stack_bytes)))\n\nif __name__ == '__main__':\n    test_arm64()<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">flare-emu<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">flare-emu\u7684\u6838\u5fc3\u529f\u80fd\u662f\u901a\u8fc7 Unicorn \u7684\u4eff\u771f\u80fd\u529b\uff0c\u4e3a IDA \u4e8c\u8fdb\u5236\u5206\u6790\u63d0\u4f9b\u5f3a\u5927\u7684\u52a8\u6001\u4eff\u771f\u652f\u6301\u3002\u5b83\u652f\u6301\u591a\u79cd\u67b6\u6784\uff08\u5305\u62ecx86\u3001x86_64\u3001ARM\u548cARM64\uff09\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e94\u79cd\u4e3b\u8981\u7684\u4eff\u771f\u63a5\u53e3\uff0c\u4ee5\u53ca\u4e00\u7cfb\u5217\u76f8\u5173\u7684\u8f85\u52a9\u548c\u5b9e\u7528\u51fd\u6570\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>emulateRange<br>\u7528\u4e8e\u4eff\u771f\u6307\u5b9a\u8303\u56f4\u5185\u7684\u6307\u4ee4\u6216\u51fd\u6570\u3002\u652f\u6301\u7528\u6237\u5b9a\u4e49\u7684\u6307\u4ee4\u94a9\u5b50\u548c\u201c\u8c03\u7528\u201d\u6307\u4ee4\u94a9\u5b50\u3002\u7528\u6237\u53ef\u4ee5\u6307\u5b9a\u5bc4\u5b58\u5668\u548c\u5806\u6808\u53c2\u6570\u7684\u503c\u3002\u5982\u679c\u63d0\u4f9b\u5b57\u8282\u5b57\u7b26\u4e32\uff0c\u4f1a\u5c06\u5176\u5199\u5165\u4eff\u771f\u5668\u7684\u5185\u5b58\uff0c\u5e76\u5c06\u6307\u9488\u5199\u5165\u5bc4\u5b58\u5668\u6216\u5806\u6808\u53d8\u91cf\u3002\u63d0\u4f9b\u4e86\u4ece\u4eff\u771f\u5185\u5b58\u6216\u5bc4\u5b58\u5668\u8bfb\u53d6\u6570\u636e\u7684\u5b9e\u7528\u51fd\u6570\u3002<\/li>\n\n\n\n<li>iterate<br>\u5f3a\u5236\u4eff\u771f\u8fdb\u5165\u6307\u5b9a\u51fd\u6570\u5185\u7684\u7279\u5b9a\u5206\u652f\uff0c\u4ee5\u8fbe\u5230\u7ed9\u5b9a\u7684\u76ee\u6807\u5730\u5740\u3002<br>\u7528\u6237\u53ef\u4ee5\u6307\u5b9a\u76ee\u6807\u5730\u5740\u5217\u8868\uff0c\u6216\u4ece\u51fd\u6570\u7684\u4ea4\u53c9\u5f15\u7528\u4e2d\u83b7\u53d6\u76ee\u6807\u5730\u5740\u3002<br>\u63d0\u4f9b\u4e86\u7528\u6237\u5b9a\u4e49\u7684\u6307\u4ee4\u548c\u201c\u8c03\u7528\u201d\u6307\u4ee4\u94a9\u5b50\u3002<\/li>\n\n\n\n<li>iterateAllPaths<br>\u5c1d\u8bd5\u627e\u5230\u5e76\u4eff\u771f\u76ee\u6807\u51fd\u6570\u7684\u6240\u6709\u8def\u5f84\u3002<br>\u9002\u7528\u4e8e\u9700\u8981\u8986\u76d6\u51fd\u6570\u4e2d\u6240\u6709\u57fa\u672c\u5757\u7684\u4ee3\u7801\u5206\u6790\u573a\u666f\u3002<\/li>\n\n\n\n<li>emulateBytes<br>\u7528\u4e8e\u4eff\u771f\u4e00\u6bb5\u72ec\u7acb\u7684\u4ee3\u7801\uff08\u5982 shellcode\uff09\u3002\u63d0\u4f9b\u7684\u5b57\u8282\u4e0d\u4f1a\u6dfb\u52a0\u5230 IDB \u4e2d\uff0c\u800c\u662f\u76f4\u63a5\u4eff\u771f\u3002<\/li>\n\n\n\n<li>emulateFrom<br>\u4ece\u6307\u5b9a\u5730\u5740\u5f00\u59cb\u4eff\u771f\uff0c\u76f4\u5230\u6ca1\u6709\u66f4\u591a\u6307\u4ee4\u53ef\u4eff\u771f\uff0c\u6216\u5728\u94a9\u5b50\u4e2d\u505c\u6b62\u4eff\u771f\u3002\u652f\u6301\u52a8\u6001\u4ee3\u7801\u53d1\u73b0\uff0c\u9002\u7528\u4e8e\u8fb9\u754c\u4e0d\u660e\u786e\u7684\u51fd\u6570\u6216\u6df7\u6dc6\u4ee3\u7801\u3002<br><a href=\"https:\/\/github.com\/mandiant\/flare-emu\">\u7f51\u5740<\/a><br>\u793a\u4f8b\u4f7f\u7528<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>import flare_emu  # \u5bfc\u5165flare_emu\u6a21\u5757\uff0c\u7528\u4e8e\u6a21\u62df\u6267\u884c\nimport idc  # \u5bfc\u5165idc\u6a21\u5757\uff0c\u7528\u4e8e\u4e0eIDA\u4ea4\u4e92\nimport idaapi  # \u5bfc\u5165idaapi\u6a21\u5757\uff0c\u7528\u4e8e\u83b7\u53d6\u51fd\u6570\u4fe1\u606f\u7b49\nimport keypatch  # \u5bfc\u5165keypatch\u6a21\u5757\uff0c\u7528\u4e8e\u6c47\u7f16\u6307\u4ee4\u7684\u4fee\u590d\n\n# \u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570\uff0c\u7528\u4e8e\u4fee\u590d\u6307\u5b9a\u5730\u5740\u7684\u6307\u4ee4\ndef patch_one(address: int, new_instruction: str):\n    \"\"\"\n    \u4f7f\u7528Keypatch\u4fee\u590d\u6307\u5b9a\u5730\u5740\u7684\u6307\u4ee4\u3002\n\n    \u53c2\u6570:\n        address (int): \u8981\u4fee\u590d\u7684\u6307\u4ee4\u5730\u5740\u3002\n        new_instruction (str): \u65b0\u7684\u6c47\u7f16\u6307\u4ee4\u3002\n\n    \u8fd4\u56de:\n        bool: \u5982\u679c\u4fee\u590d\u6210\u529f\u8fd4\u56deTrue\uff0c\u5426\u5219\u8fd4\u56deFalse\u3002\n    \"\"\"\n    kp_asm = keypatch.Keypatch_Asm()  # \u521d\u59cb\u5316Keypatch\u6c47\u7f16\u5bf9\u8c61\n    if kp_asm.arch is None:  # \u68c0\u67e5Keypatch\u662f\u5426\u652f\u6301\u5f53\u524d\u67b6\u6784\n        print(\"ERROR: Keypatch\u65e0\u6cd5\u5904\u7406\u6b64\u67b6\u6784\")\n        return False\n\n    # \u89e3\u6790\u65b0\u7684\u6c47\u7f16\u6307\u4ee4\n    assembly = kp_asm.ida_resolve(new_instruction, address)\n    (encoding, count) = kp_asm.assemble(assembly, address)  # \u5c06\u6c47\u7f16\u6307\u4ee4\u8f6c\u6362\u4e3a\u673a\u5668\u7801\n\n    if encoding is None:  # \u5982\u679c\u6ca1\u6709\u751f\u6210\u673a\u5668\u7801\uff0c\u8bf4\u660e\u65e0\u9700\u4fee\u590d\n        print(\"Keypatch: \u65e0\u9700\u4fee\u590d\")\n        return False\n\n    # \u5c06\u673a\u5668\u7801\u8f6c\u6362\u4e3a\u5b57\u8282\u6570\u636e\n    patch_data = ''.join(chr(c) for c in encoding)\n    patch_len = len(patch_data)  # \u83b7\u53d6\u673a\u5668\u7801\u957f\u5ea6\n    kp_asm.patch(address, patch_data, patch_len)  # \u4f7f\u7528Keypatch\u8fdb\u884c\u4fee\u590d\n\n    print(f\"\u4fee\u590d\u5b8c\u6210: {assembly}\")  # \u8f93\u51fa\u4fee\u590d\u7684\u6307\u4ee4\n\ndef myTargetCallBack(emu, address, argv, userData):\n    \"\"\"\n    \u6a21\u62df\u6267\u884c\u65f6\u7684\u56de\u8c03\u51fd\u6570\uff0c\u7528\u4e8e\u8bb0\u5f55\u95f4\u63a5\u8c03\u7528\u7684\u76ee\u6807\u5730\u5740\u3002\n\n    \u53c2\u6570:\n        emu (flare_emu.EmuHelper): \u6a21\u62df\u5668\u5bf9\u8c61\u3002\n        address (int): \u5f53\u524d\u6307\u4ee4\u5730\u5740\u3002\n        argv (list): \u5f53\u524d\u6307\u4ee4\u7684\u53c2\u6570\u3002\n        userData (dict): \u7528\u6237\u6570\u636e\uff0c\u7528\u4e8e\u5b58\u50a8\u95f4\u63a5\u8c03\u7528\u7684\u6620\u5c04\u3002\n    \"\"\"\n    # \u83b7\u53d6\u5f53\u524d\u6307\u4ee4\u7684\u53cd\u6c47\u7f16\u5b57\u7b26\u4e32\n    code_str = idc.GetDisasm(address)\n\n    # \u63d0\u53d6BR\u6307\u4ee4\u4f7f\u7528\u7684\u5bc4\u5b58\u5668\u540d\n    register_name = code_str.split(\" \")&#91;-1]\n\n    # \u8f93\u51fa\u5f53\u524d\u5730\u5740\u548c\u5bc4\u5b58\u5668\u503c\n    print(f\"address = {hex(address)}, X* = {hex(emu.getRegVal(register_name))}\")\n\n    # \u5c06\u5f53\u524d\u5730\u5740\u548c\u5bc4\u5b58\u5668\u503c\u5b58\u50a8\u5230\u7528\u6237\u6570\u636e\u4e2d\n    userData&#91;\"br_map\"]&#91;address] = emu.getRegVal(register_name)\n\ndef anti_icall():\n    \"\"\"\n    \u4e3b\u51fd\u6570\uff0c\u7528\u4e8e\u5904\u7406\u95f4\u63a5\u8c03\u7528\uff08indirect call\uff09\u7684\u4fee\u590d\u3002\n    \"\"\"\n\n    br_addr_list = &#91;0x4006A0, 0x400724]  # \u521d\u59cb\u5316\u95f4\u63a5\u8c03\u7528\u5730\u5740\u5217\u8868\n\n    eh = flare_emu.EmuHelper()  # \u521d\u59cb\u5316flare_emu\u6a21\u62df\u5668\n\n    # \u6a21\u62df\u6267\u884c\u6307\u5b9a\u8303\u56f4\u5185\u7684\u4ee3\u7801\uff0c\u5e76\u8bb0\u5f55\u95f4\u63a5\u8c03\u7528\u7684\u76ee\u6807\u5730\u5740\n    eh.iterate(br_addr_list, targetCallback=myTargetCallBack, hookData={\"br_map\": {}})\n\n    # \u904d\u5386\u8bb0\u5f55\u7684\u95f4\u63a5\u8c03\u7528\u5730\u5740\uff0c\u5e76\u4fee\u590d\u4e3a\u76f4\u63a5\u8c03\u7528\n    for br_addr in eh.hookData&#91;\"br_map\"]:\n        print(f\"br_addr = {hex(br_addr)} {hex(eh.hookData&#91;'br_map']&#91;br_addr])}\")\n        patch_one(br_addr, f\"bl {hex(eh.hookData&#91;'br_map']&#91;br_addr])}\")<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">arm\u67b6\u6784\u4e0b\u672a\u6620\u5c04\u811a\u672c<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">(\u9488\u5bf9\u5e73\u5766\u5316)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import flare_emu\nimport idaapi\nimport idc\nimport unicorn\nimport unicorn.arm64_const as uc_arm64\nimport keypatch\nimport struct\n\n# ==========================================\n# \u8f85\u52a9\u7c7b\uff1a\u5904\u7406 ARM64 \u6761\u4ef6\u7801\u4e0e NZCV \u7684\u5173\u7cfb\n# ==========================================\nclass ConditionHandler:\n    def __init__(self):\n        # \u6620\u5c04\u6761\u4ef6\u7801\u5230\u6ee1\u8db3\u8be5\u6761\u4ef6\u7684 NZCV \u8bbe\u7f6e (N, Z, C, V)\n        # \u8fd9\u91cc\u7684\u8bbe\u7f6e\u662f\u4e3a\u4e86\u8ba9\u6761\u4ef6 100% \u6210\u7acb\n        self.cond_map = {\n            \"EQ\": (0, 1, 0, 0), # Z=1\n            \"NE\": (0, 0, 0, 0), # Z=0\n            \"CS\": (0, 0, 1, 0), # C=1 (HS)\n            \"CC\": (0, 0, 0, 0), # C=0 (LO)\n            \"MI\": (1, 0, 0, 0), # N=1\n            \"PL\": (0, 0, 0, 0), # N=0\n            \"VS\": (0, 0, 0, 1), # V=1\n            \"VC\": (0, 0, 0, 0), # V=0\n            \"HI\": (0, 0, 1, 0), # C=1, Z=0\n            \"LS\": (0, 1, 0, 0), # C=0 or Z=1\n            \"GE\": (0, 0, 0, 0), # N=V\n            \"LT\": (1, 0, 0, 0), # N!=V\n            \"GT\": (0, 0, 0, 0), # Z=0, N=V\n            \"LE\": (0, 1, 0, 0), # Z=1 or N!=V\n        }\n        # \u6620\u5c04\u6761\u4ef6\u7801\u5230\u5bf9\u5e94\u7684\u8df3\u8f6c\u6307\u4ee4\n        self.b_map = {k: f\"B.{k}\" for k in self.cond_map.keys()}\n\n    def get_flags_for_true(self, cond_str):\n        \"\"\"\u8fd4\u56de\u8ba9\u6761\u4ef6\u6210\u7acb\u7684 NZCV\"\"\"\n        return self.cond_map.get(cond_str, (0,0,0,0))\n\n    def get_flags_for_false(self, cond_str):\n        \"\"\"\u8fd4\u56de\u8ba9\u6761\u4ef6\u4e0d\u6210\u7acb\u7684 NZCV (\u53d6\u53cd)\"\"\"\n        # \u7b80\u5355\u5904\u7406\uff1a\u5bf9\u4e8e EQ(Z=1)\uff0c\u53cd\u9762\u5c31\u662f Z=0\u3002\n        # \u8fd9\u91cc\u4e3a\u4e86\u7b80\u5316\uff0c\u9488\u5bf9\u4e0d\u540c\u6761\u4ef6\u53d6\u53cd\u903b\u8f91\u4e0d\u540c\uff0c\u4f46\u901a\u5e38\u7ffb\u8f6c\u5173\u952e\u4f4d\u5373\u53ef\n        # \u5b9e\u9645\u4e0a\u6a21\u62df\u6267\u884c\u65f6\uff0c\u6211\u4eec\u4f1a\u5f3a\u884c\u8986\u76d6 PSTATE\uff0c\u6240\u4ee5\u53ea\u8981\u7ed9\u51fa\u4e00\u7ec4\u5fc5\u5047\u7684\u503c\u5373\u53ef\n        n, z, c, v = self.cond_map.get(cond_str, (0,0,0,0))\n        if cond_str in &#91;\"EQ\", \"LE\", \"LS\"]: return (n, 0, c, v) # Z=0\n        if cond_str in &#91;\"NE\", \"GT\", \"HI\"]: return (n, 1, c, v) # Z=1\n        if cond_str in &#91;\"GE\", \"LT\"]: return (1-n, z, c, v) # \u7ffb\u8f6c N \u5bfc\u81f4 N!=V \u53d8\u5316\n        return (0, 0, 0, 0) # \u9ed8\u8ba4\n\n# ==========================================\n# \u6838\u5fc3\u903b\u8f91\n# ==========================================\n\nclass BlockInfo:\n    def __init__(self, start_addr, end_addr):\n        self.start_addr = start_addr\n        self.end_addr = end_addr\n        self.behind_block = {True: None, False: None} # True: \u6761\u4ef6\u6210\u7acb\u8df3\u8f6c, False: \u6761\u4ef6\u4e0d\u6210\u7acb\n        self.csel_instr = None # \u8bb0\u5f55 (address, condition_string)\n\n    def is_conditional(self):\n        return self.csel_instr is not None\n\nclass OLLVMDeobfuscator:\n    def __init__(self, func_start):\n        self.func_start = func_start\n        self.func_end = idc.find_func_end(func_start)\n        self.real_blocks = {} # addr -&gt; BlockInfo\n        self.fake_blocks = &#91;]\n        self.visited_paths = set() # \u8bb0\u5f55\u5df2\u63a2\u7d22\u7684 (block_addr, branch_bool)\n        self.cond_handler = ConditionHandler()\n        self.path_queue = &#91;] # \u5f85\u63a2\u7d22\u961f\u5217\n\n    def set_nzcv(self, uc, n, z, c, v):\n        pstate = uc.reg_read(uc_arm64.UC_ARM64_REG_PSTATE)\n        # \u6e05\u9664 NZCV (bits 31, 30, 29, 28)\n        pstate &amp;= ~(0xF0000000)\n        pstate |= (n &lt;&lt; 31) | (z &lt;&lt; 30) | (c &lt;&lt; 29) | (v &lt;&lt; 28)\n        uc.reg_write(uc_arm64.UC_ARM64_REG_PSTATE, pstate)\n\n    def find_csel_backwards(self, start_addr, end_addr):\n        \"\"\"\u5012\u5e8f\u67e5\u627e CSEL \u6307\u4ee4\uff0c\u4e0d\u518d\u4f9d\u8d56\u56fa\u5b9a\u504f\u79fb\"\"\"\n        curr = end_addr\n        # \u5411\u524d\u56de\u6eaf\u6700\u591a 8 \u6761\u6307\u4ee4\n        for _ in range(8):\n            curr = idc.prev_head(curr)\n            if curr &lt; start_addr: break\n            mnem = idc.print_insn_mnem(curr)\n            # \u5339\u914d CSEL, CSEL.EQ \u7b49\n            if mnem.startswith(\"CSEL\"):\n                # \u83b7\u53d6\u6761\u4ef6\u7801\uff0c\u4f8b\u5982 CSEL EQ -&gt; EQ; CSEL.EQ -&gt; EQ\n                # IDA \u663e\u793a\u901a\u5e38\u662f CSEL Rd, Rn, Rm, COND\n                op_str = idc.generate_disasm_line(curr, 0)\n                parts = op_str.replace(\",\", \"\").split()\n                cond = parts&#91;-1] # \u6700\u540e\u4e00\u4e2a\u901a\u5e38\u662f\u6761\u4ef6\n                return curr, cond\n        return None, None\n\n    def is_real_block(self, start, end):\n        \"\"\"\u5224\u65ad\u903b\u8f91\uff1a\u4e0d\u662f\u5206\u53d1\u5668\uff0c\u901a\u5e38\u4ee5 RET \u6216 B \u7ed3\u5c3e\uff0c\u4e14\u5305\u542b CSEL \u66f4\u65b0\u72b6\u6001\"\"\"\n        if start == self.func_start: return True\n        last_mnem = idc.print_insn_mnem(end)\n\n        if last_mnem == \"RET\": return True\n\n        # \u771f\u5b9e\u5757\u901a\u5e38\u5728\u8ba1\u7b97\u5b8c\u540e\u8df3\u8f6c\u56de\u5206\u53d1\u5668\n        if last_mnem == \"B\":\n            csel_addr, _ = self.find_csel_backwards(start, end)\n            if csel_addr: return True\n\n        return False\n\n    def hook_code(self, uc, address, size, user_data):\n        # \u8fd9\u91cc\u7684 user_data \u662f\u5f53\u524d\u6b63\u5728\u6a21\u62df\u7684 BlockInfo\n        current_block = user_data\n\n        # 1. \u68c0\u67e5\u662f\u5426\u9047\u5230\u4e86 CSEL\n        mnem = idc.print_insn_mnem(address)\n        if mnem.startswith(\"CSEL\"):\n            # \u89e3\u6790\u6761\u4ef6\n            op_line = idc.generate_disasm_line(address, 0)\n            cond = op_line.replace(\",\", \"\").split()&#91;-1]\n            current_block.csel_instr = (address, cond)\n\n            # \u68c0\u67e5\u6211\u4eec\u662f\u5426\u9700\u8981\u5f3a\u5236\u6539\u6d41\n            # \u8fd9\u91cc\u7684\u903b\u8f91\u662f\uff1a\u5982\u679c\u8fd9\u662f\u4e00\u4e2a\u65b0\u53d1\u73b0\u7684\u5206\u652f\u70b9\uff0c\u6211\u4eec\u9700\u8981\u628a\u53e6\u4e00\u6761\u8def\u52a0\u5165\u961f\u5217\n            # \u5e76\u5728\u5f53\u524d\u6267\u884c\u4e2d\u5f3a\u5236\u8d70\u5176\u4e2d\u4e00\u6761\u8def\n            pass\n\n    def run_emulation(self):\n        print(\"&#91;*] \u5f00\u59cb\u6a21\u62df\u6267\u884c...\")\n        # \u4f7f\u7528\u6808\u6216\u961f\u5217\u6765\u7ba1\u7406\u5f85\u63a2\u7d22\u7684\u8def\u5f84\n        # \u521d\u59cb\uff1a\u4ece\u51fd\u6570\u5934\u5f00\u59cb\n        queue = &#91;(self.func_start, None, None)] # (addr, set_flags_func, parent_block)\n\n        processed_blocks = set()\n\n        eh = flare_emu.EmuHelper()\n\n        # \u8fd9\u91cc\u7684\u903b\u8f91\u6bd4\u8f83\u590d\u6742\uff0c\u4e3a\u4e86\u7b80\u5316\u811a\u672c\uff0c\u6211\u4eec\u91c7\u7528 \n        # \"\u591a\u6b21\u6a21\u62df + \u5f3a\u5236\u5206\u652f\" \u7684\u7b56\u7565\uff0c\u7c7b\u4f3c\u4f60\u539f\u811a\u672c\u7684 range(0,3) \u6216\u8005\u662f DFS\n\n        # \u6211\u4eec\u4f7f\u7528\u4e00\u4e2a\u7b80\u5355\u7684\u9012\u5f52 DFS \u6a21\u62df\u5668\n        self.dfs_emulate(eh, self.func_start)\n\n    def dfs_emulate(self, eh, start_addr):\n        # \u627e\u5230\u5f53\u524d\u57fa\u672c\u5757\u8303\u56f4\n        end_addr = idc.get_item_end(start_addr)\n        while True:\n            mnem = idc.print_insn_mnem(idc.prev_head(end_addr))\n            if mnem in &#91;\"B\", \"RET\"] or end_addr &gt; self.func_end:\n                end_addr = idc.prev_head(end_addr) # \u6307\u5411\u6700\u540e\u4e00\u6761\u6307\u4ee4\u5730\u5740\n                break\n            end_addr = idc.next_head(end_addr)\n\n        block_key = start_addr\n        if block_key in self.real_blocks:\n            return # \u5df2\u5904\u7406\n\n        # \u5224\u5b9a\u662f\u5426\u771f\u5b9e\u5757\n        if not self.is_real_block(start_addr, end_addr):\n            # \u5982\u679c\u662f\u5206\u53d1\u5668\uff0c\u6211\u4eec\u901a\u5e38\u4e0d\u8bb0\u5f55\uff0c\u4f46\u9700\u8981\u8ba9\u6a21\u62df\u5668\u8dd1\u8fc7\u53bb\n            return \n\n        print(f\"\u53d1\u73b0\u771f\u5b9e\u5757: {hex(start_addr)} - {hex(end_addr)}\")\n        block_info = BlockInfo(start_addr, end_addr)\n        self.real_blocks&#91;start_addr] = block_info\n\n        # \u5bfb\u627e CSEL\n        csel_addr, csel_cond = self.find_csel_backwards(start_addr, end_addr)\n\n        if csel_addr:\n            block_info.csel_instr = (csel_addr, csel_cond)\n            print(f\"  \u5305\u542b\u6761\u4ef6\u8df3\u8f6c: {csel_cond} at {hex(csel_addr)}\")\n\n            # \u6a21\u62df\u4e24\u6b21\uff1a\u4e00\u6b21\u5f3a\u5236 True\uff0c\u4e00\u6b21\u5f3a\u5236 False\n            # 1. Force True\n            print(f\"  &gt;&gt; \u6a21\u62df True \u5206\u652f ({csel_cond})...\")\n            next_true = self.get_next_block(eh, start_addr, end_addr, csel_cond, force_true=True)\n            block_info.behind_block&#91;True] = next_true\n            if next_true and next_true != start_addr: # \u907f\u514d\u6b7b\u5faa\u73af\n                self.dfs_emulate(eh, next_true)\n\n            # 2. Force False\n            print(f\"  &gt;&gt; \u6a21\u62df False \u5206\u652f (!{csel_cond})...\")\n            next_false = self.get_next_block(eh, start_addr, end_addr, csel_cond, force_true=False)\n            block_info.behind_block&#91;False] = next_false\n            if next_false and next_false != start_addr:\n                self.dfs_emulate(eh, next_false)\n        else:\n            # \u65e0\u6761\u4ef6\u8df3\u8f6c (\u53ea\u6709\u4e00\u6761\u8def)\n            print(f\"  &gt;&gt; \u6a21\u62df\u65e0\u6761\u4ef6\u8df3\u8f6c...\")\n            next_addr = self.get_next_block(eh, start_addr, end_addr, None, None)\n            block_info.behind_block&#91;True] = next_addr # \u9ed8\u8ba4\u653e True\n            if next_addr and next_addr != start_addr:\n                self.dfs_emulate(eh, next_addr)\n\n    def get_next_block(self, eh, start, end, cond, force_true):\n        \"\"\"\u6267\u884c\u4e00\u6bb5\u4ee3\u7801\u5e76\u83b7\u53d6\u8df3\u51fa\u7684\u76ee\u6807\u5730\u5740\"\"\"\n\n        def hook(uc, address, size, user_data):\n            # \u5230\u4e86 CSEL \u6307\u4ee4\uff0c\u5f3a\u5236\u6539 PSTATE\n            if cond and address == user_data&#91;'csel_addr']:\n                n, z, c, v = (0,0,0,0)\n                if force_true:\n                    n, z, c, v = self.cond_handler.get_flags_for_true(cond)\n                else:\n                    n, z, c, v = self.cond_handler.get_flags_for_false(cond)\n                self.set_nzcv(uc, n, z, c, v)\n\n        # \u5bfb\u627e CSEL \u5730\u5740\n        csel_addr = 0\n        if cond:\n            csel_addr, _ = self.find_csel_backwards(start, end)\n\n        user_data = {'csel_addr': csel_addr}\n\n        # \u6a21\u62df\u6267\u884c\uff0c\u76f4\u5230\u8df3\u51fa\u5f53\u524d\u5757\u8303\u56f4\uff0c\u6216\u8005\u8dd1\u4e86\u4e00\u5b9a\u6b65\u6570\n        # \u8fd9\u91cc\u5229\u7528 flare_emu \u7684 emulateRange\uff0c\u4f46\u6211\u4eec\u9700\u8981\u83b7\u53d6\u6700\u7ec8\u505c\u5728\u54ea\n        # \u7531\u4e8e flare_emu \u5c01\u88c5\u8f83\u591a\uff0c\u8fd9\u91cc\u7b80\u5316\u4e3a\uff1a\u8dd1\u5b8c\u8be5\u5757\u540e\uff0c\u518d\u5355\u6b65\u8dd1\u51e0\u6b65\u76f4\u5230\u9047\u5230\u6bd4\u8f83\u5927\u7684\u8df3\u8f6c\uff08\u8df3\u56de\u771f\u5b9e\u5757\uff09\n\n        # \u6ce8\u610f\uff1a\u8fd9\u91cc\u4e3a\u4e86\u7b80\u5316\u4ee3\u7801\uff0c\u5047\u8bbe emulateRange \u80fd\u6b63\u786e\u5904\u7406\u3002\n        # \u5b9e\u9645\u4e0a OLLVM \u8dd1\u5b8c\u771f\u5b9e\u5757\u540e\u4f1a\u8fdb\u5165 Dispatcher\uff0c\u6211\u4eec\u9700\u8981\u8ba9\u5b83\u8dd1\u8fc7 Dispatcher \u505c\u5728\u4e0b\u4e00\u4e2a\u771f\u5b9e\u5757\u5f00\u5934\u3002\n\n        # \u5b9a\u4e49\u4e00\u4e2a\u505c\u6b62 hook\uff1a\u5f53 PC \u6307\u5411\u4e00\u4e2a\u65b0\u7684\u771f\u5b9e\u5757\u5019\u9009\u65f6\u505c\u6b62\n        final_pc = &#91;None]\n\n        def stop_hook(uc, address, size, user_data):\n            # \u5982\u679c\u8dd1\u51fa\u4e86\u5f53\u524d\u5757\uff0c\u4e14\u770b\u8d77\u6765\u50cf\u662f\u4e2a\u4ee3\u7801\u5757\u5f00\u5934\n            if address != start and address &gt; self.func_start and address &lt; self.func_end:\n                # \u7b80\u5355\u7684\u542f\u53d1\u5f0f\uff1a\u5982\u679c\u662f dispatcher \u7684\u4e2d\u95f4\uff0c\u7ee7\u7eed\u8dd1\n                # \u5982\u679c\u662f real block\uff0c\u505c\u6b62\n                # \u5b9e\u9645\u64cd\u4f5c\u4e2d\uff0c\u53ef\u4ee5\u8bbe\u7f6e\u6b65\u6570\u9650\u5236\n                pass\n\n        # \u8fd9\u91cc\u7684\u5b9e\u73b0\u96be\u70b9\u5728\u4e8e\u5982\u4f55\u7cbe\u786e\u622a\u83b7 \"\u4e0b\u4e00\u4e2a\u771f\u5b9e\u5757\"\u3002\n        # \u7b80\u5355\u65b9\u6848\uff1a\u4f7f\u7528 unicorn \u76f4\u63a5\u8dd1\uff0c\u4e0d\u4f9d\u8d56 flare_emu \u7684\u9ad8\u7ea7\u5c01\u88c5\uff0c\u4ee5\u4fbf\u63a7\u5236\u5faa\u73af\n        uc = eh.uc\n        try:\n            # \u521d\u59cb\u5316\u5bc4\u5b58\u5668 context (flare_emu \u5e94\u8be5\u5df2\u7ecf\u505a\u597d\u4e86\u73af\u5883)\n            # \u4ec5\u505a\u5c40\u90e8\u6a21\u62df\n            eh._init_emulation() # \u8fd9\u662f\u4e00\u4e2a hack\uff0c\u5b9e\u9645\u9700\u53c2\u8003 flare_emu \u6e90\u7801\n\n            # \u91cd\u65b0\u8bbe\u7f6e PC\n            uc.reg_write(uc_arm64.UC_ARM64_REG_PC, start)\n\n            # \u6ce8\u518c hook\n            h1 = uc.hook_add(unicorn.UC_HOOK_CODE, hook, user_data)\n\n            # \u8dd1\uff01\u9650\u5236\u6b65\u6570\u9632\u6b62\u6b7b\u5faa\u73af (\u4f8b\u5982 500 \u6761\u6307\u4ee4\u8db3\u591f\u8dd1\u8fc7 dispatcher)\n            uc.emu_start(start, self.func_end, count=500) \n\n            final_pc&#91;0] = uc.reg_read(uc_arm64.UC_ARM64_REG_PC)\n            uc.hook_del(h1)\n\n        except unicorn.UcError as e:\n            # \u901a\u5e38\u662f\u56e0\u4e3a\u8df3\u5230\u4e86\u4e0d\u53ef\u8bfb\u5185\u5b58\u6216\u8dd1\u98de\u4e86\n            final_pc&#91;0] = uc.reg_read(uc_arm64.UC_ARM64_REG_PC)\n\n        return final_pc&#91;0]\n\n    def patch(self):\n        print(\"&#91;*] \u5f00\u59cb Patch...\")\n        kp = keypatch.Keypatch_Asm()\n\n        for addr, block in self.real_blocks.items():\n            if block.end_addr is None: continue\n\n            # 1. \u53ea\u6709\u4e00\u6761\u8def\n            if not block.is_conditional():\n                target = block.behind_block&#91;True]\n                if target:\n                    print(f\"Patching Unconditional: {hex(block.end_addr)} -&gt; {hex(target)}\")\n                    self.apply_patch(kp, block.end_addr, f\"B {hex(target)}\")\n\n            # 2. \u6709\u4e24\u6761\u8def (CSEL)\n            else:\n                csel_addr, cond = block.csel_instr\n                target_true = block.behind_block&#91;True]\n                target_false = block.behind_block&#91;False]\n\n                if target_true and target_false:\n                    print(f\"Patching Conditional ({cond}): {hex(csel_addr)}\")\n                    # \u903b\u8f91\uff1a\n                    # CSEL Rd, Rn, Rm, COND\n                    # \u5982\u679c COND \u6210\u7acb -&gt; \u9009 Rn -&gt; \u5bf9\u5e94 target_true\n                    # \u6545\uff1aB.COND target_true\n\n                    patch_asm = f\"B.{cond} {hex(target_true)}\"\n                    self.apply_patch(kp, csel_addr, patch_asm)\n\n                    # \u7d27\u63a5\u7740 CSEL \u540e\u9762\uff08\u6216\u8005\u5728 Block \u7ed3\u5c3e B \u7684\u4f4d\u7f6e\uff09Patch \u8df3\u8f6c\u5230 False\n                    # \u539f\u5730 CSEL \u88ab\u6539\u6210 B.COND \u4e86 (4\u5b57\u8282)\uff0c\u4e0b\u4e00\u6761\u6307\u4ee4\u5982\u679c\u662f STR \u6216 B\uff0c\u6539\u6210 B target_false\n                    # \u901a\u5e38\u6211\u4eec\u5728 Block \u7ed3\u5c3e\u7684 B \u5904 patch False \u8def\u5f84\n                    self.apply_patch(kp, block.end_addr, f\"B {hex(target_false)}\")\n\n                    # \u4e2d\u95f4\u7684\u5783\u573e\u6307\u4ee4\uff08\u5982 STR Wx, &#91;SP]\uff09\u53ef\u4ee5 NOP \u6389\uff0c\u4e5f\u53ef\u4ee5\u4e0d\u7ba1\uff0c\u53cd\u6b63\u8df3\u8d70\u4e86\n\n    def apply_patch(self, kp, addr, asm):\n        try:\n            encoding, count = kp.assemble(asm, addr)\n            if encoding:\n                idc.patch_bytes(addr, bytes(encoding))\n                print(f\"  Success: {asm}\")\n            else:\n                print(f\"  Fail to assemble: {asm}\")\n        except Exception as e:\n            print(f\"  Error: {e}\")\n\n# \u7528\u6cd5\n# d = OLLVMDeobfuscator(0x123456)\n# d.run_emulation()\n# d.patch()<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">x86<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">eflags\u8f85\u52a9\u7c7b\uff0c\u7528\u66f4\u76f4\u89c2\u7684\u65b9\u5f0f\u6765\u4fee\u6539 CPU \u7684\u72b6\u6001\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class X86Flags:\n    # EFLAGS \u4f4d\u7684\u63a9\u7801\n    CF = 1 &lt;&lt; 0\n    PF = 1 &lt;&lt; 2\n    AF = 1 &lt;&lt; 4\n    ZF = 1 &lt;&lt; 6\n    SF = 1 &lt;&lt; 7\n    OF = 1 &lt;&lt; 11\n\n    @staticmethod\n    def get_flags_for_cond(cond_str):\n        \"\"\"\n        \u6839\u636e\u6761\u4ef6\u7801\u8fd4\u56de (mask, value)\n        mask: \u9700\u8981\u4fee\u6539\u7684\u4f4d\n        value: \u4fee\u6539\u540e\u7684\u503c\n        \"\"\"\n        f = X86Flags\n        # \u4ec5\u5217\u4e3e\u5e38\u7528\n        mapping = {\n            \"E\":  (f.ZF, f.ZF),       # Equal (ZF=1)\n            \"Z\":  (f.ZF, f.ZF),\n            \"NE\": (f.ZF, 0),          # Not Equal (ZF=0)\n            \"NZ\": (f.ZF, 0),\n            \"S\":  (f.SF, f.SF),       # Sign (SF=1)\n            \"NS\": (f.SF, 0),\n            \"G\":  (f.ZF|f.SF|f.OF, 0),# Greater (ZF=0, SF=OF) -&gt; \u4e5f\u5c31\u662f ZF=0 \u4e14 SF=0,OF=0\n            \"GE\": (f.SF|f.OF, 0),     # Greater or Equal (SF=OF)\n            \"L\":  (f.SF|f.OF, f.SF),  # Less (SF!=OF) -&gt; SF=1, OF=0\n            \"LE\": (f.ZF|f.SF|f.OF, f.ZF|f.SF), # Less or Equal (ZF=1 or SF!=OF)\n            \"A\":  (f.CF|f.ZF, 0),     # Above (CF=0, ZF=0)\n            \"B\":  (f.CF, f.CF),       # Below (CF=1)\n        }\n        # \u6ce8\u610f\uff1a\u8fd9\u91cc\u7b80\u5316\u4e86 G\/L \u7684\u8bbe\u7f6e\uff0c\u53ea\u8981\u6ee1\u8db3\u4e00\u79cd\u60c5\u51b5\u5373\u53ef\u8ba9\u6761\u4ef6\u6210\u7acb\n        return mapping.get(cond_str.upper(), (0, 0))<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u6839\u636e\u4e0a\u4e00\u4e2aarm\u6539\u7684<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import flare_emu\nimport idaapi\nimport idc\nimport unicorn\nimport unicorn.x86_const as uc_x86\nimport keypatch\n\nclass X86OLLVMDeobfuscator:\n    def __init__(self, func_start):\n        self.func_start = func_start\n        self.func_end = idc.find_func_end(func_start)\n        self.real_blocks = {} \n\n        # \u6620\u5c04 conditions \u5230 EFLAGS \u4fee\u6539\u903b\u8f91\n        self.cond_map = {\n            \"e\":   (1&lt;&lt;6, 1&lt;&lt;6), # ZF=1\n            \"z\":   (1&lt;&lt;6, 1&lt;&lt;6),\n            \"ne\":  (1&lt;&lt;6, 0),    # ZF=0\n            \"nz\":  (1&lt;&lt;6, 0),\n            \"g\":   (1&lt;&lt;6|1&lt;&lt;7|1&lt;&lt;11, 0), # ZF=0, SF=0, OF=0 (\u7b80\u5355\u6ee1\u8db3 G)\n            \"le\":  (1&lt;&lt;6, 1&lt;&lt;6), # ZF=1 (\u7b80\u5355\u6ee1\u8db3 LE)\n            # ... \u5176\u4ed6\u9700\u8981\u6839\u636e\u5177\u4f53\u6c47\u7f16\u8865\u5145\n        }\n\n    def set_eflags(self, uc, mask, value):\n        \"\"\"\u4fee\u6539 EFLAGS \u5bc4\u5b58\u5668\"\"\"\n        eflags = uc.reg_read(uc_x86.UC_X86_REG_EFLAGS)\n        eflags &amp;= ~mask # \u6e05\u9664\u76f8\u5173\u4f4d\n        eflags |= value # \u8bbe\u7f6e\u65b0\u503c\n        uc.reg_write(uc_x86.UC_X86_REG_EFLAGS, eflags)\n\n    def is_real_block(self, start, end):\n        \"\"\"\u5224\u65ad\u662f\u5426\u4e3a\u771f\u5b9e\u5757\"\"\"\n        if start == self.func_start: return True\n\n        # x86 \u5757\u901a\u5e38\u4ee5 JMP \u7ed3\u5c3e\u8df3\u56de\u5206\u53d1\u5668\uff0c\u6216\u8005 RET\n        last_mnem = idc.print_insn_mnem(end)\n        if last_mnem.startswith(\"ret\"): return True\n        if last_mnem.startswith(\"jmp\"):\n            # \u68c0\u67e5\u5757\u5185\u662f\u5426\u6709 CMOV \u6307\u4ee4\n            curr = end\n            for _ in range(10): # \u5411\u524d\u56de\u6eaf\n                curr = idc.prev_head(curr)\n                if curr &lt; start: break\n                mnem = idc.print_insn_mnem(curr)\n                if mnem.startswith(\"cmov\"):\n                    return True\n        return False\n\n    def get_cmov_condition(self, addr):\n        \"\"\"\u4ece\u6307\u4ee4\u4e2d\u63d0\u53d6\u6761\u4ef6\u540e\u7f00\uff0c\u4f8b\u5982 cmovne -&gt; ne\"\"\"\n        mnem = idc.print_insn_mnem(addr)\n        if mnem.startswith(\"cmov\"):\n            return mnem&#91;4:] # \u8fd4\u56de ne, e, g \u7b49\n        return None\n\n    def run_emulation(self):\n        print(\"\u5f00\u59cb x86 \u6a21\u62df...\")\n        eh = flare_emu.EmuHelper()\n\n        # \u5bfb\u627e\u6240\u6709\u771f\u5b9e\u5757 (\u7b80\u5316\u7248\uff1a\u904d\u5386\u6240\u6709\u5757\u8fdb\u884c\u5224\u65ad)\n        flow = idaapi.FlowChart(idaapi.get_func(self.func_start))\n        for block in flow:\n            # \u83b7\u53d6\u5757\u7684\u6700\u540e\u4e00\u6761\u6307\u4ee4\u5730\u5740\n            end_addr = idc.prev_head(block.end_ea)\n\n            if self.is_real_block(block.start_ea, end_addr):\n                print(f\"\u5206\u6790\u771f\u5b9e\u5757: {hex(block.start_ea)}\")\n\n                # \u5bfb\u627e CMOV\n                cmov_addr = 0\n                cond = None\n                curr = end_addr\n                for _ in range(10):\n                    curr = idc.prev_head(curr)\n                    mnem = idc.print_insn_mnem(curr)\n                    if mnem.startswith(\"cmov\"):\n                        cmov_addr = curr\n                        cond = self.get_cmov_condition(curr)\n                        break\n\n                if cmov_addr:\n                    print(f\"  \u53d1\u73b0\u6761\u4ef6\u5206\u652f: cmov{cond} at {hex(cmov_addr)}\")\n                    # \u8fd9\u91cc\u7684\u5904\u7406\u903b\u8f91\u4e0e ARM \u7c7b\u4f3c\uff1a\n                    # 1. \u5f3a\u5236\u6761\u4ef6\u6210\u7acb (\u4fee\u6539 EFLAGS) -&gt; \u8dd1\u51fa True \u5206\u652f\u76ee\u6807\n                    # 2. \u5f3a\u5236\u6761\u4ef6\u5931\u8d25 (\u4fee\u6539 EFLAGS) -&gt; \u8dd1\u51fa False \u5206\u652f\u76ee\u6807\n\n                    # \u6a21\u62df\u83b7\u53d6 True Target\n                    mask, val = self.cond_map.get(cond, (0,0))\n                    target_true = self.emulate_path(eh, block.start_ea, cmov_addr, mask, val)\n\n                    # \u6a21\u62df\u83b7\u53d6 False Target (\u53d6\u53cd\u6bd4\u8f83\u9ebb\u70e6\uff0c\u901a\u5e38\u53ea\u8981\u8ba9\u6761\u4ef6\u4e0d\u6ee1\u8db3\u5373\u53ef)\n                    # \u7b80\u5355\u505a\u6cd5\uff1a\u5982\u679c True \u662f ZF=1\uff0cFalse \u5c31\u8bbe ZF=0\n                    # \u6ce8\u610f\uff1amask \u4e0d\u53d8\uff0cval \u53d6\u53cd\u9700\u8981\u4f4d\u8fd0\u7b97\u6280\u5de7\uff0c\u6216\u8005\u624b\u52a8\u786c\u7f16\u7801\n                    val_false = val ^ mask # \u7b80\u5355\u7684\u7ffb\u8f6c\u5c1d\u8bd5\n                    target_false = self.emulate_path(eh, block.start_ea, cmov_addr, mask, val_false)\n\n                    print(f\"  True -&gt; {hex(target_true) if target_true else 'None'}\")\n                    print(f\"  False -&gt; {hex(target_false) if target_false else 'None'}\")\n\n                    # \u8bb0\u5f55\u4e0b\u6765\u51c6\u5907 Patch...\n                    pass\n                else:\n                    # \u65e0\u6761\u4ef6\u8df3\u8f6c\uff0c\u76f4\u63a5\u8dd1\n                    target = self.emulate_path(eh, block.start_ea, 0, 0, 0)\n                    print(f\"  Unconditional -&gt; {hex(target) if target else 'None'}\")\n\n    def emulate_path(self, eh, start_addr, hook_addr, flag_mask, flag_val):\n        \"\"\"\u6a21\u62df\u6267\u884c\u5e76\u8fd4\u56de\u4e0b\u4e00\u8df3\u5730\u5740\"\"\"\n\n        result = &#91;None]\n\n        def hook(uc, address, size, user_data):\n            # \u5728 CMOV \u5904\u4fee\u6539\u6807\u5fd7\u4f4d\n            if address == hook_addr and flag_mask != 0:\n                self.set_eflags(uc, flag_mask, flag_val)\n\n            # \u505c\u6b62\u6761\u4ef6\uff1a\u8df3\u51fa\u4e86\u5f53\u524d\u51fd\u6570\u8303\u56f4\uff0c\u6216\u8005\u8df3\u5230\u4e86\u53e6\u4e00\u4e2a\u5df2\u77e5\u5757\n            # \u8fd9\u91cc\u7b80\u5316\u5904\u7406\uff1a\u5982\u679c\u662f JMP \u6307\u4ee4\u4e14\u76ee\u6807\u4e0d\u5728\u5f53\u524d\u5757\u5185\uff0c\u8bb0\u5f55\u76ee\u6807\n            pass \n            # \u5b9e\u9645\u9700\u8981\u7ed3\u5408 flare_emu \u7684 iterate \u6216\u8005\u624b\u52a8\u63a7\u5236 step\n\n        # \u8fd9\u91cc\u53ea\u662f\u4f2a\u4ee3\u7801\u793a\u610f\uff0c\u5b9e\u9645\u9700\u8981\u50cf ARM \u7248\u90a3\u6837\u8bbe\u7f6e uc.emu_start\n        return 0xDEADBEEF # \u5360\u4f4d\u7b26\n\n    def patch(self):\n        # x86 Patch \u903b\u8f91\n        # CMOVcc -&gt; Jcc (\u6761\u4ef6\u8df3\u8f6c)\n        # JMP Dispatcher -&gt; NOP\n        pass\n\n# \u6ce8\u610f\uff1ax86 \u7684\u6307\u4ee4\u957f\u5ea6\u4e0d\u5b9a\u957f\uff01Patch \u65f6\u975e\u5e38\u75db\u82e6\u3002\n# CMOV (3-4 bytes) \u53ef\u80fd\u6bd4 JZ (2 bytes short, 6 bytes near) \u957f\u6216\u77ed\u3002\n# \u5fc5\u987b\u4f7f\u7528 Keypatch \u91cd\u65b0\u6c47\u7f16\uff0c\u5e76\u786e\u4fdd\u4e0d\u8986\u76d6\u540e\u7eed\u6307\u4ee4\uff0c\u6216\u8005\u7528 NOP \u586b\u5145\u591a\u4f59\u5b57\u8282\u3002<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u6ce8\uff1a\u5bb9\u6613\u6307\u4ee4\u4e0d\u7b49\u957f\uff0c\u8981patch<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">angr<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/bbs.kanxue.com\/thread-276834-1.htm\">angr\u901f\u901a<\/a><br>\u6587\u7ae0\u680f\uff1a<br><a href=\"https:\/\/www.cnblogs.com\/xiaowaaaa\/p\/19022282#%E8%99%9A%E5%81%87%E6%8E%A7%E5%88%B6%E6%B5%81bcf\">\u6587\u7ae0\uff0c\u73af\u5883\u642d\u5efa\u52a0\u5b9e\u6218\u53bb\u9664<\/a><br><a href=\"https:\/\/xz.aliyun.com\/news\/18642\">\u6e90\u7801\u5206\u6790\u591a\u4e00\u4e9b<\/a><br><a href=\"https:\/\/zhuanlan.zhihu.com\/p\/1895774891107668236\">\u633a\u5168\u7684\uff0c\u5305\u62ecunicorn\u914d\u7f6e\u52a0\u7528\u6cd5<\/a><br><a href=\"https:\/\/lich4.github.io\/cpp_posts\/20240826_ollvm\/\">\u5927\u6846\u67b6<\/a><br><a href=\"https:\/\/1ens.github.io\/2024\/12\/04\/OLLVM%E5%8F%8D%E6%B7%B7%E6%B7%86\/\">\u597d\u7406\u89e3\u5f88\u591a<\/a><br><a href=\"https:\/\/zhuanlan.zhihu.com\/p\/659819382\">\u4ee3\u7801\u63a7\u5236\u6d41\u6df7\u6dc6\uff0c\u6709\u70b9\u6742\uff0c\u53c2\u8003<\/a><br><a href=\"https:\/\/oacia.dev\/ollvm-study\/\">\u6587\u7ae0\uff0c\u4e0a\u9762\u67d0\u4e00\u7bc7\u7684\u53c2\u8003<\/a><br><a href=\"https:\/\/skyi23.github.io\/2025\/08\/19\/Unicorn%20%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93\/\">unicorn\u4f7f\u7528<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>llvm LLVM Passllvm\u4e00\u5957\u7f16\u8bd1\u5668\u548c\u5de5\u5177\u94fe\u6280\u672f\uff0c\u7528\u4e8e\u4e3a\u4efb\u4f55\u7f16\u7a0b\u8bed\u8a00\u5f00\u53d1\u524d\u7aef\uff0c\u4e3a\u4efb\u4f55\u6307\u4ee4\u96c6\u67b6\u6784\u5f00\u53d1\u540e [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":74,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-71","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-learn"],"_links":{"self":[{"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/posts\/71","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/comments?post=71"}],"version-history":[{"count":1,"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/posts\/71\/revisions"}],"predecessor-version":[{"id":72,"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/posts\/71\/revisions\/72"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/media\/74"}],"wp:attachment":[{"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/media?parent=71"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/categories?post=71"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/8.210.123.186\/index.php\/wp-json\/wp\/v2\/tags?post=71"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}