{"componentChunkName":"component---src-templates-post-template-js","path":"/ctf-android-apk-debug-tutorial-en","result":{"data":{"markdownRemark":{"id":"0cbfba44-2419-5ce3-9e64-fef7e9809178","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/ctf-android-apk-debug-tutorial\">original page</a>.</p>\n</blockquote>\n<p>Until now, whenever an APK challenge showed up in a CTF and I could not solve it with static analysis, I would just give up. But I figured it was time to properly learn dynamic analysis techniques for Android apps, so I wrote this article as part of that study.</p>\n<p>Using “Java Not Interesting” from <a href=\"/ctf-cryptoversectf-2023-en\">Cryptoverse CTF 2023</a> as the theme, I will summarize some basic ways to dynamically analyze Android apps.</p>\n<!-- omit in toc -->\n<h2 id=\"table-of-contents\" style=\"position:relative;\"><a href=\"#table-of-contents\" aria-label=\"table of contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Table of Contents</h2>\n<ul>\n<li>\n<p><a href=\"#unpack-the-apk-file-and-perform-static-analysis\">Unpack the APK File and Perform Static Analysis</a></p>\n<ul>\n<li><a href=\"#read-androidmanifestxml\">Read AndroidManifest.xml</a></li>\n<li><a href=\"#investigate-the-main-activity\">Investigate the Main Activity</a></li>\n<li><a href=\"#decompile-the-native-library\">Decompile the Native Library</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#perform-dynamic-analysis-with-the-android-studio-debugger\">Perform Dynamic Analysis with the Android Studio Debugger</a></p>\n<ul>\n<li><a href=\"#debug-a-native-app-in-android-studio\">Debug a Native App in Android Studio</a></li>\n<li><a href=\"#identify-the-app-architecture-and-image-base\">Identify the App Architecture and Image Base</a></li>\n<li><a href=\"#set-breakpoints-and-identify-the-flag\">Set Breakpoints and Identify the Flag</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#perform-dynamic-analysis-by-attaching-a-debugger-to-the-emulator\">Perform Dynamic Analysis by Attaching a Debugger to the Emulator</a></p>\n<ul>\n<li><a href=\"#install-the-apk-on-the-emulator\">Install the APK on the Emulator</a></li>\n<li><a href=\"#install-lldb-on-the-host-machine\">Install LLDB on the Host Machine</a></li>\n<li><a href=\"#deploy-lldb-server-to-the-android-emulator-and-launch-the-app\">Deploy lldb-server to the Android Emulator and Launch the App</a></li>\n<li><a href=\"#attach-the-debugger\">Attach the Debugger</a></li>\n<li><a href=\"#control-lldb-with-python\">Control LLDB with Python</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#use-dlopen-on-library-functions-and-dynamically-analyze-them-as-an-elf-binary\">Use <code class=\"language-text\">dlopen</code> on Library Functions and Dynamically Analyze Them as an ELF Binary</a></p>\n<ul>\n<li><a href=\"#identify-the-native-library-ndk-version\">Identify the Native Library NDK Version</a></li>\n<li><a href=\"#create-an-executable\">Create an Executable</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"#perform-dynamic-analysis-with-frida-hooks\">Perform Dynamic Analysis with Frida Hooks</a></p>\n<ul>\n<li><a href=\"#set-up-frida\">Set Up Frida</a></li>\n<li><a href=\"#debug-with-a-frida-hook\">Debug with a Frida Hook</a></li>\n</ul>\n</li>\n<li><a href=\"#bonus-perform-dynamic-analysis-with-symbolic-execution\">Bonus: Perform Dynamic Analysis with Symbolic Execution</a></li>\n<li><a href=\"#summary\">Summary</a></li>\n</ul>\n<h2 id=\"unpack-the-apk-file-and-perform-static-analysis\" style=\"position:relative;\"><a href=\"#unpack-the-apk-file-and-perform-static-analysis\" aria-label=\"unpack the apk file and perform static analysis permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Unpack the APK File and Perform Static Analysis</h2>\n<p>First, unpack the APK file to get a rough understanding of the implementation.</p>\n<p>APK files can be unpacked with tools such as <a href=\"https://ibotpeaches.github.io/Apktool/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Apktool</a> and <a href=\"https://github.com/pxb1988/dex2jar\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">dex2jar</a>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">apktool d app-debug.apk</code></pre></div>\n<p>You can also unpack an APK by loading it in Android Studio from [File] > [Profile or Debug APK].</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 303px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/bf1ba949e90b974ccf1306038ec77c25/6728c/image-20230511195619986.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 89.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAAsTAAALEwEAmpwYAAACjklEQVQ4y41UW44TMRCc48D+IrKTzCvjedrzSrKBzSJACIGEOAJfiANwKQ7WVLVnQhQFxIfjtqddrqpuJ4i7RqI3jTSP3+Tt919i3/+QvndS1Fa6cSeN7aRqOxl3B+mnva7LppVxfxBTNTp32G9dJ1lRSxAXhazLTMrpk4yff0pz/CpVU8sWH6vWSV5WerBGTLC8rHEZ1tYhp9KcsrF6CdcBmRxfncTg4CoMZXc4aNImTmWTZBKlWx2Ml/V1vEYuwbK8kGC13mBRiutHeXr3QSxm1w+S4uP1Qc5xlv9zBDmQ11EsZnByeH2Sxnm/KI1Si7pVcMpi7t9AuV/BioBe5KaQGkA0nXLdMIHpAKN7mQ5HGeaC8MAm2d4ES7ZGoiSVYNztJcWC+sMoFTdOKtmDjspw8YnzAnAJyH2qWUeJBLbrzwkRRtsNaBeCesAKUi8BbkleGN5vYglerEKlmuWgnObwsAe7EfOAij9oOzD5vwDXESRPO7kLC7lbZZD+B9CCIQs0wDsyXqQtANesz4DTfi/PAfjsJZLTzEsGYIeLumHSduKL4chQvGugpaW8ZADy2Rgkbo3RJ1a1VixAffdbmF3jVXQas30IxMMcbGa+JLYY45Ae0ivX5NJ3tbYH5ekMdjFuZ+VDVI9VXhhpDGCypz2+3ayXTClFaeTheJTTxy/KhAlWpU/qKf3MTIniwWdT6f4AS9w89xjshnu8uoCeMZl9lFsP0OMSNradGfAb5Xr/zCyxVJm0hDP7NcSLC46PT/Cv9MlgQMCqcQrEy8iUja+VvCrGZVF4iTY2AdTkuS1YAHpzfm6Q4gvhwZI5Ts6xUa/5l0ZvA/5wUBa9UfqI2dCUUUDS+fCtMV9E21jl39j0hrf5jUT5AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/bf1ba949e90b974ccf1306038ec77c25/8ac56/image-20230511195619986.webp 240w,\n/static/bf1ba949e90b974ccf1306038ec77c25/bac26/image-20230511195619986.webp 303w\"\n              sizes=\"(max-width: 303px) 100vw, 303px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/bf1ba949e90b974ccf1306038ec77c25/8ff5a/image-20230511195619986.png 240w,\n/static/bf1ba949e90b974ccf1306038ec77c25/6728c/image-20230511195619986.png 303w\"\n            sizes=\"(max-width: 303px) 100vw, 303px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/bf1ba949e90b974ccf1306038ec77c25/6728c/image-20230511195619986.png\"\n            alt=\"image-20230511195619986\"\n            title=\"image-20230511195619986\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>To understand the overall picture of the APK being analyzed, start by checking <code class=\"language-text\">AndroidManifest.xml</code>.</p>\n<h3 id=\"read-androidmanifestxml\" style=\"position:relative;\"><a href=\"#read-androidmanifestxml\" aria-label=\"read androidmanifestxml permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Read AndroidManifest.xml</h3>\n<p><code class=\"language-text\">AndroidManifest.xml</code> is the manifest file that is essential for Android app development.</p>\n<p>It declares many elements, including the SDK version the APK depends on, whether Android Studio can debug it, and the app’s permissions.</p>\n<p>For example, from the manifest file of <code class=\"language-text\">app-debug.apk</code>, which is the target of this analysis, we can read the following information.</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"># The minimum SDK version is 23\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>uses-sdk</span>\n<span class=\"token attr-name\"><span class=\"token namespace\">android:</span>minSdkVersion</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>23<span class=\"token punctuation\">\"</span></span>\n<span class=\"token attr-name\"><span class=\"token namespace\">android:</span>targetSdkVersion</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>33<span class=\"token punctuation\">\"</span></span> \n<span class=\"token punctuation\">/></span></span>\n\n# The app is configured to be debuggable\n# The Main Activity is com.example.hellojni.HelloJni\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>application</span>\n<span class=\"token attr-name\"><span class=\"token namespace\">android:</span>debuggable</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>true<span class=\"token punctuation\">\"</span></span>\n\n    <span class=\"token attr-name\">&lt;activity</span>\n        <span class=\"token attr-name\"><span class=\"token namespace\">android:</span>name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>com.example.hellojni.HelloJni<span class=\"token punctuation\">\"</span></span>\n        <span class=\"token attr-name\"><span class=\"token namespace\">android:</span>exported</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>true<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>activity</span><span class=\"token punctuation\">></span></span>\n/></code></pre></div>\n<p>Reference: <a href=\"https://developer.android.com/guide/topics/manifest/manifest-intro?hl=ja\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">App Manifest Overview  |  Android Developers</a></p>\n<p>Reference: <a href=\"https://ja.docs.monaca.io/reference/config/android/android_manifest\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">AndroidManifest.xml - Monaca Docs</a></p>\n<p>By the way, if the target APK does not have <code class=\"language-text\">debuggable</code> set to True as in this case, you need to tamper with the APK file and repackage it.</p>\n<p>The following reference covers the details.</p>\n<p>Reference: <a href=\"https://coky-t.gitbook.io/owasp-mastg-ja/android-tesutogaido/0x05c-reverse-engineering-and-tampering#debaggutotorsu\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Android Tampering and Reverse Engineering - owasp-mastg-ja</a></p>\n<h3 id=\"investigate-the-main-activity\" style=\"position:relative;\"><a href=\"#investigate-the-main-activity\" aria-label=\"investigate the main activity permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Investigate the Main Activity</h3>\n<p>Next, continue investigating to understand the overall structure of the target app.</p>\n<p>Once you understand the contents of <code class=\"language-text\">AndroidManifest.xml</code>, the next step is to look at the Main Activity that gets called first.</p>\n<p>In this binary, <code class=\"language-text\">com.example.hellojni.HelloJni</code> was registered as the Main Activity.</p>\n<p>If you unpack the APK in Android Studio, you can find this information in <code class=\"language-text\">java/com.example/hellojni/HelloJni.smali</code>.</p>\n<p>The <code class=\"language-text\">.smali</code> format is a disassembly of dex-format binaries used by Android’s Java VM (Dalvik).</p>\n<p>Incidentally, conversion to <code class=\"language-text\">.smali</code> is reversible, so you can edit it and then turn it back into an APK again.</p>\n<p>Smali files are somewhat readable as-is, but if you decompile them into Java with a tool such as <a href=\"https://github.com/AlexeySoshin/smali2java\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">smali2java</a>, they become even easier to read.</p>\n<p><a href=\"https://github.com/AlexeySoshin/smali2java\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">smali2java</a> can be used with the following command.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">smali2java_windows_amd64.exe  -path_to_smali<span class=\"token operator\">=</span>./HelloJini.smali</code></pre></div>\n<p>Reference: <a href=\"https://github.com/AlexeySoshin/smali2java\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">AlexeySoshin/smali2java: Recreate Java code from Smali</a></p>\n<p>The decompiled result of <code class=\"language-text\">java/com.example/hellojni/HelloJni.smali</code> obtained this time looked like this.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token comment\">// {{ omitted }}</span>\n\n<span class=\"token keyword\">private</span> <span class=\"token keyword\">native</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">Boolean</span> checkValid <span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">java<span class=\"token punctuation\">.</span>lang<span class=\"token punctuation\">.</span></span>String</span> p0 <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token punctuation\">}</span> <span class=\"token comment\">// .end method</span>\n\n<span class=\"token keyword\">private</span> <span class=\"token keyword\">native</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\"><span class=\"token namespace\">java<span class=\"token punctuation\">.</span>lang<span class=\"token punctuation\">.</span></span>String</span> getFIaggg <span class=\"token punctuation\">(</span> <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token punctuation\">}</span> <span class=\"token comment\">// .end method</span>\n\n<span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">void</span> onCreate$lambda$<span class=\"token number\">0</span> <span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">com<span class=\"token punctuation\">.</span>example<span class=\"token punctuation\">.</span>hellojni<span class=\"token punctuation\">.</span></span>HelloJni</span> p0<span class=\"token punctuation\">,</span> <span class=\"token class-name\"><span class=\"token namespace\">com<span class=\"token punctuation\">.</span>example<span class=\"token punctuation\">.</span>hellojni<span class=\"token punctuation\">.</span>databinding<span class=\"token punctuation\">.</span></span>ActivityHelloJniBinding</span> p1<span class=\"token punctuation\">,</span> <span class=\"token class-name\"><span class=\"token namespace\">android<span class=\"token punctuation\">.</span>view<span class=\"token punctuation\">.</span></span>View</span> p2 <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token comment\">/* .registers 5 */</span>\n<span class=\"token comment\">/* .param p0, \"this$0\" # Lcom/example/hellojni/HelloJni; */</span>\n<span class=\"token comment\">/* .param p1, \"$binding\" # Lcom/example/hellojni/databinding/ActivityHelloJniBinding; */</span>\n<span class=\"token comment\">/* .param p2, \"it\" # Landroid/view/View; */</span>\n<span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> v0 <span class=\"token operator\">=</span> <span class=\"token string\">\"this$0\"</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// const-string v0, \"this$0\"</span>\n<span class=\"token class-name\"><span class=\"token namespace\">kotlin<span class=\"token punctuation\">.</span>jvm<span class=\"token punctuation\">.</span>internal<span class=\"token punctuation\">.</span></span>Intrinsics</span> <span class=\"token punctuation\">.</span>checkNotNullParameter <span class=\"token punctuation\">(</span> p0<span class=\"token punctuation\">,</span>v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> v0 <span class=\"token operator\">=</span> <span class=\"token string\">\"$binding\"</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// const-string v0, \"$binding\"</span>\n<span class=\"token class-name\"><span class=\"token namespace\">kotlin<span class=\"token punctuation\">.</span>jvm<span class=\"token punctuation\">.</span>internal<span class=\"token punctuation\">.</span></span>Intrinsics</span> <span class=\"token punctuation\">.</span>checkNotNullParameter <span class=\"token punctuation\">(</span> p1<span class=\"token punctuation\">,</span>v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">/* .line 30 */</span>\nv0 <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>flag<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">android<span class=\"token punctuation\">.</span>widget<span class=\"token punctuation\">.</span></span>EditText</span> <span class=\"token punctuation\">)</span> v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>getText <span class=\"token punctuation\">(</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable;</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">java<span class=\"token punctuation\">.</span>lang<span class=\"token punctuation\">.</span></span>Object</span> <span class=\"token punctuation\">)</span> v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>toString <span class=\"token punctuation\">(</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String;</span>\n\nv0 <span class=\"token operator\">=</span> <span class=\"token comment\">/* invoke-direct {p0, v0}, Lcom/example/hellojni/HelloJni;->checkValid(Ljava/lang/String;)Z */</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span> v0 <span class=\"token operator\">!=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token comment\">// if-eqz v0, :cond_24</span>\n <span class=\"token comment\">/* .line 31 */</span>\n v0 <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>valid<span class=\"token punctuation\">;</span>\n <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> v1 <span class=\"token operator\">=</span> <span class=\"token string\">\"Correct!\"</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// const-string v1, \"Correct!\"</span>\n <span class=\"token comment\">/* check-cast v1, Ljava/lang/CharSequence; */</span>\n <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">android<span class=\"token punctuation\">.</span>widget<span class=\"token punctuation\">.</span></span>TextView</span> <span class=\"token punctuation\">)</span> v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>setText <span class=\"token punctuation\">(</span> v1 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V</span>\n <span class=\"token comment\">/* .line 33 */</span>\n<span class=\"token punctuation\">}</span> <span class=\"token comment\">// :cond_24</span>\nv0 <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>valid<span class=\"token punctuation\">;</span>\nv1 <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>flag<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">android<span class=\"token punctuation\">.</span>widget<span class=\"token punctuation\">.</span></span>EditText</span> <span class=\"token punctuation\">)</span> v1 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>getText <span class=\"token punctuation\">(</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v1}, Landroid/widget/EditText;->getText()Landroid/text/Editable;</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">java<span class=\"token punctuation\">.</span>lang<span class=\"token punctuation\">.</span></span>Object</span> <span class=\"token punctuation\">)</span> v1 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>toString <span class=\"token punctuation\">(</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v1}, Ljava/lang/Object;->toString()Ljava/lang/String;</span>\n<span class=\"token comment\">/* check-cast v1, Ljava/lang/CharSequence; */</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">android<span class=\"token punctuation\">.</span>widget<span class=\"token punctuation\">.</span></span>TextView</span> <span class=\"token punctuation\">)</span> v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>setText <span class=\"token punctuation\">(</span> v1 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V</span>\n<span class=\"token comment\">/* .line 35 */</span>\n<span class=\"token punctuation\">}</span> <span class=\"token comment\">// :goto_35</span>\n<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> <span class=\"token comment\">// .end method</span>\n\n<span class=\"token comment\">/* # virtual methods */</span>\n<span class=\"token keyword\">protected</span> <span class=\"token keyword\">void</span> onCreate <span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">android<span class=\"token punctuation\">.</span>os<span class=\"token punctuation\">.</span></span>Bundle</span> p0 <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"token comment\">/* .registers 5 */</span>\n<span class=\"token comment\">/* .param p1, \"savedInstanceState\" # Landroid/os/Bundle; */</span>\n<span class=\"token comment\">/* .line 25 */</span>\n<span class=\"token comment\">/* invoke-super {p0, p1}, Landroidx/appcompat/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V */</span>\n<span class=\"token comment\">/* .line 27 */</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">com<span class=\"token punctuation\">.</span>example<span class=\"token punctuation\">.</span>hellojni<span class=\"token punctuation\">.</span></span>HelloJni</span> <span class=\"token punctuation\">)</span> p0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>getLayoutInflater <span class=\"token punctuation\">(</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {p0}, Lcom/example/hellojni/HelloJni;->getLayoutInflater()Landroid/view/LayoutInflater;</span>\n<span class=\"token class-name\"><span class=\"token namespace\">com<span class=\"token punctuation\">.</span>example<span class=\"token punctuation\">.</span>hellojni<span class=\"token punctuation\">.</span>databinding<span class=\"token punctuation\">.</span></span>ActivityHelloJniBinding</span> <span class=\"token punctuation\">.</span>inflate <span class=\"token punctuation\">(</span> v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> v1 <span class=\"token operator\">=</span> <span class=\"token string\">\"inflate(layoutInflater)\"</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// const-string v1, \"inflate(layoutInflater)\"</span>\n<span class=\"token class-name\"><span class=\"token namespace\">kotlin<span class=\"token punctuation\">.</span>jvm<span class=\"token punctuation\">.</span>internal<span class=\"token punctuation\">.</span></span>Intrinsics</span> <span class=\"token punctuation\">.</span>checkNotNullExpressionValue <span class=\"token punctuation\">(</span> v0<span class=\"token punctuation\">,</span>v1 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">/* .line 28 */</span>\n<span class=\"token comment\">/* .local v0, \"binding\":Lcom/example/hellojni/databinding/ActivityHelloJniBinding; */</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">com<span class=\"token punctuation\">.</span>example<span class=\"token punctuation\">.</span>hellojni<span class=\"token punctuation\">.</span>databinding<span class=\"token punctuation\">.</span></span>ActivityHelloJniBinding</span> <span class=\"token punctuation\">)</span> v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>getRoot <span class=\"token punctuation\">(</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v0}, Lcom/example/hellojni/databinding/ActivityHelloJniBinding;->getRoot()Landroidx/constraintlayout/widget/ConstraintLayout;</span>\n<span class=\"token comment\">/* check-cast v1, Landroid/view/View; */</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">com<span class=\"token punctuation\">.</span>example<span class=\"token punctuation\">.</span>hellojni<span class=\"token punctuation\">.</span></span>HelloJni</span> <span class=\"token punctuation\">)</span> p0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>setContentView <span class=\"token punctuation\">(</span> v1 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {p0, v1}, Lcom/example/hellojni/HelloJni;->setContentView(Landroid/view/View;)V</span>\n<span class=\"token comment\">/* .line 29 */</span>\nv1 <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>getflag<span class=\"token punctuation\">;</span>\n<span class=\"token comment\">/* new-instance v2, Lcom/example/hellojni/HelloJni$$ExternalSyntheticLambda0; */</span>\n<span class=\"token comment\">/* invoke-direct {v2, p0, v0}, Lcom/example/hellojni/HelloJni$$ExternalSyntheticLambda0;->&lt;init>(Lcom/example/hellojni/HelloJni;Lcom/example/hellojni/databinding/ActivityHelloJniBinding;)V */</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">android<span class=\"token punctuation\">.</span>widget<span class=\"token punctuation\">.</span></span>Button</span> <span class=\"token punctuation\">)</span> v1 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>setOnClickListener <span class=\"token punctuation\">(</span> v2 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v1, v2}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V</span>\n<span class=\"token comment\">/* .line 36 */</span>\n<span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> <span class=\"token comment\">// .end method</span></code></pre></div>\n<p>Reading the code above, you can see that when the button created in <code class=\"language-text\">onCreate</code> is tapped, <code class=\"language-text\">onCreate$lambda$0</code> is called with the string entered in the form.</p>\n<p>The string passed here is then given to the <code class=\"language-text\">checkValid</code> function, which is called via <code class=\"language-text\">invoke-direct {p0, v0}</code> at the following point, and validated there.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token comment\">/* .line 30 */</span>\nv0 <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>flag<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">android<span class=\"token punctuation\">.</span>widget<span class=\"token punctuation\">.</span></span>EditText</span> <span class=\"token punctuation\">)</span> v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>getText <span class=\"token punctuation\">(</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable;</span>\n<span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">java<span class=\"token punctuation\">.</span>lang<span class=\"token punctuation\">.</span></span>Object</span> <span class=\"token punctuation\">)</span> v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>toString <span class=\"token punctuation\">(</span> <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String;</span>\n\nv0 <span class=\"token operator\">=</span> <span class=\"token comment\">/* invoke-direct {p0, v0}, Lcom/example/hellojni/HelloJni;->checkValid(Ljava/lang/String;)Z */</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span> v0 <span class=\"token operator\">!=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token comment\">// if-eqz v0, :cond_24</span>\n <span class=\"token comment\">/* .line 31 */</span>\n v0 <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>valid<span class=\"token punctuation\">;</span>\n <span class=\"token keyword\">final</span> <span class=\"token class-name\">String</span> v1 <span class=\"token operator\">=</span> <span class=\"token string\">\"Correct!\"</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// const-string v1, \"Correct!\"</span>\n <span class=\"token comment\">/* check-cast v1, Ljava/lang/CharSequence; */</span>\n <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">android<span class=\"token punctuation\">.</span>widget<span class=\"token punctuation\">.</span></span>TextView</span> <span class=\"token punctuation\">)</span> v0 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>setText <span class=\"token punctuation\">(</span> v1 <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V</span>\n <span class=\"token comment\">/* .line 33 */</span>\n<span class=\"token punctuation\">}</span> <span class=\"token comment\">// :cond_24</span></code></pre></div>\n<p>Then, if the result of validation by the <code class=\"language-text\">checkValid</code> function is True, the app displays <code class=\"language-text\">Correct!</code> on the screen.</p>\n<p>In other words, we can infer that <code class=\"language-text\">checkValid</code> determines whether the correct Flag was supplied as input.</p>\n<p>From here, I wanted to inspect the implementation of <code class=\"language-text\">checkValid</code> to retrieve the Flag, but if you look at the following line that declares <code class=\"language-text\">checkValid</code>, it appears to be defined in a native library.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">native</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">Boolean</span> checkValid <span class=\"token punctuation\">(</span> <span class=\"token class-name\"><span class=\"token namespace\">java<span class=\"token punctuation\">.</span>lang<span class=\"token punctuation\">.</span></span>String</span> p0 <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span> <span class=\"token comment\">// .end method</span></code></pre></div>\n<p>So from here, we continue by analyzing the native library.</p>\n<h3 id=\"decompile-the-native-library\" style=\"position:relative;\"><a href=\"#decompile-the-native-library\" aria-label=\"decompile the native library permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Decompile the Native Library</h3>\n<p>If you unpack the APK file with the command shown earlier, you can see that <code class=\"language-text\">libhello-jni.so</code> exists under <code class=\"language-text\">app-debug/lib/arm64-v8a</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">apktool d app-debug.apk</code></pre></div>\n<p>Because the <code class=\"language-text\">checkValid</code> function is implemented there, analyze this file with Ghidra.</p>\n<p>There are also other directories such as x86 under <code class=\"language-text\">app-debug/lib/</code>, but current Android environments basically require apps to support arm64-v8a, so I first used arm64-v8a as the analysis target.</p>\n<p>As described later, if you debug on an emulator running in an x86_64 environment, you can decompile x86 or other binaries as needed.</p>\n<p>Reference: <a href=\"https://developer.android.com/games/optimize/64-bit?hl=ja\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Support 64-bit architectures  |  Android Developers</a></p>\n<p>By decompiling it in Ghidra, you can identify how the <code class=\"language-text\">checkValid</code> function works.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/8c5e7d0de577c173f458b8ba894137eb/ccf0c/image-20230511222152913.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 70.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACSUlEQVQ4y41TyW4bMRTz/39XTjm0cG9tkaRuPPs+2rdhKblpHBQoKuB5PPYTH0VSp6enZ7y8vODy44LrtUXTTNjWHcs6s1as24zzl+94eHjF42NT6vOnDudzj29fBzw/jdy3oG1XjOOOU0oJec3Thm0DlExw1mHZFd7WNE38TPifdTLGwHuPrh05IWHfA4yRBFwQY8LBgXXdox8m9umyKR0HjrtK6f37yVqLEMINcDjIMkAbgUUsBMtNCVXdoR8lnBMIMRTQe0C+IT8+AnY3huvqyURh2ydYMi+AFbXtFYTooK36C/C+CmAMEX03UUdAbBGOMmhlb6JQuqZpIbcRRkoe17PCvzS00EHj0lxRDQYDzZjlhmqaYWBhkkFdXTlIQusIawBrD+oMDj5YJOA4JIVymmKK8AKXgYCLQCc2DGpEtfYQkNijQNu1WBaFuvE0x2CZI6U5IIWFEoEDHA10BI03wOAD5K75J/gMJTbO+ptWNKZtqZ2SmJnPvneYOFhqSRCf7fh4ZK01fPBkkHOYoFREHrJse4lNjJGGEVB7mmL5u2YCqLFOZIYigTHvbhfA7HLW0hjmcHOFYWHuYmGaTbFm5625ohskB0sO3qG0QSzavblMhkqpEuy2GZjDRBYEZ+PAm1NMZrC7ti8ZXLcz1v3nb+aOmcyOxz/HLbGRjEJm6Kmjd9nBVCo7+gZYNzVvkIKU2dGD/Si95MF3FELZkKJhZigpeN8PGHicrlvpnoBQ+VYQgDur6hXzLCGkIQCZheOuUHTOkcnrF8zXPQoM/ORVAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/8c5e7d0de577c173f458b8ba894137eb/8ac56/image-20230511222152913.webp 240w,\n/static/8c5e7d0de577c173f458b8ba894137eb/d3be9/image-20230511222152913.webp 480w,\n/static/8c5e7d0de577c173f458b8ba894137eb/e46b2/image-20230511222152913.webp 960w,\n/static/8c5e7d0de577c173f458b8ba894137eb/9e175/image-20230511222152913.webp 1428w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/8c5e7d0de577c173f458b8ba894137eb/8ff5a/image-20230511222152913.png 240w,\n/static/8c5e7d0de577c173f458b8ba894137eb/e85cb/image-20230511222152913.png 480w,\n/static/8c5e7d0de577c173f458b8ba894137eb/d9199/image-20230511222152913.png 960w,\n/static/8c5e7d0de577c173f458b8ba894137eb/ccf0c/image-20230511222152913.png 1428w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/8c5e7d0de577c173f458b8ba894137eb/d9199/image-20230511222152913.png\"\n            alt=\"image-20230511222152913\"\n            title=\"image-20230511222152913\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>From the decompiled result, the Flag appears to be 0x26 characters long, and characters 7 through 0x25 seem to be checked one by one at the line <code class=\"language-text\">cVar1 != *pcVar5</code>.</p>\n<p>(The first 6 characters and the last 1 character are probably ignored because the Flag format is <code class=\"language-text\">cvctf{}</code>.)</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\">lVar3 <span class=\"token operator\">=</span> <span class=\"token function\">FUN_0011f5ac</span><span class=\"token punctuation\">(</span>auStack_38<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>lVar3 <span class=\"token operator\">==</span> <span class=\"token number\">0x26</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">_ZNSt6__ndk16vectorIiNS_9allocatorIiEEEC2Em</span><span class=\"token punctuation\">(</span>auStack_50<span class=\"token punctuation\">,</span><span class=\"token number\">0x1f</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>j <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">&lt;</span> <span class=\"token number\">0x1f</span><span class=\"token punctuation\">;</span> j <span class=\"token operator\">=</span> j <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    dVar6 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">double</span><span class=\"token punctuation\">)</span><span class=\"token function\">FUN_0011f654</span><span class=\"token punctuation\">(</span><span class=\"token number\">2</span><span class=\"token punctuation\">,</span>j <span class=\"token operator\">%</span> <span class=\"token number\">0x10</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    piVar4 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">FUN_0011f698</span><span class=\"token punctuation\">(</span>auStack_50<span class=\"token punctuation\">,</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span>j<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token operator\">*</span>piVar4 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span><span class=\"token punctuation\">)</span>dVar6 <span class=\"token operator\">%</span> <span class=\"token number\">0x25</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">%</span> <span class=\"token number\">0x1f</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token function\">_ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2IDnEEPKc</span>\n            <span class=\"token punctuation\">(</span>auStack_68<span class=\"token punctuation\">,</span><span class=\"token operator\">&amp;</span>UNK_001141ef<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span>i <span class=\"token operator\">=</span> <span class=\"token number\">6</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">0x25</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">=</span> i <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    pcVar5 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">FUN_0011f6bc</span><span class=\"token punctuation\">(</span>auStack_38<span class=\"token punctuation\">,</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span>i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    cVar1 <span class=\"token operator\">=</span> <span class=\"token operator\">*</span>pcVar5<span class=\"token punctuation\">;</span>\n    piVar4 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">int</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">FUN_0011f698</span><span class=\"token punctuation\">(</span>auStack_50<span class=\"token punctuation\">,</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>i <span class=\"token operator\">*</span> <span class=\"token number\">7</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">%</span> <span class=\"token number\">0x1f</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    pcVar5 <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">char</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span><span class=\"token function\">FUN_0011f6bc</span><span class=\"token punctuation\">(</span>auStack_68<span class=\"token punctuation\">,</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">long</span><span class=\"token punctuation\">)</span><span class=\"token operator\">*</span>piVar4<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>cVar1 <span class=\"token operator\">!=</span> <span class=\"token operator\">*</span>pcVar5<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      uStack_6c <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">goto</span> LAB_0011f508<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n  uStack_6c <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>\nLAB_0011f508<span class=\"token operator\">:</span>\n  <span class=\"token function\">_ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED2Ev</span><span class=\"token punctuation\">(</span>auStack_68<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">FUN_0011f6ec</span><span class=\"token punctuation\">(</span>auStack_50<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>At this point, you could probably recover the Flag by statically analyzing the function in <code class=\"language-text\">(char *)FUN_0011f6bc(auStack_68,(long)*piVar4);</code>, which is used to obtain <code class=\"language-text\">pcVar5</code>, but that function is fairly complex, and it seemed like it would take quite a while to derive its output purely with static analysis.</p>\n<p>In a case like this, you can recover the Flag more easily by using dynamic analysis to obtain the return value of <code class=\"language-text\">(char *)FUN_0011f6bc(auStack_68,(long)*piVar4);</code> one by one.</p>\n<p>So from here on, I will focus on dynamically analyzing native libraries in Android apps.</p>\n<h2 id=\"perform-dynamic-analysis-with-the-android-studio-debugger\" style=\"position:relative;\"><a href=\"#perform-dynamic-analysis-with-the-android-studio-debugger\" aria-label=\"perform dynamic analysis with the android studio debugger permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Perform Dynamic Analysis with the Android Studio Debugger</h2>\n<p>As you can tell from <code class=\"language-text\">AndroidManifest.xml</code>, debugging was already enabled from the beginning for this APK file.</p>\n<p>That means after loading the APK file in Android Studio via [File] > [Profile or Debug APK], you can start debugging automatically on the emulator by clicking the bug icon in the top toolbar.</p>\n<p>(If debugging is not enabled, you need to edit <code class=\"language-text\">AndroidManifest.xml</code> and repackage the APK file.)</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 684px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e079842c4776f7b861909c0187fc0ac7/2c288/image-20230511223051867.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 100.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC60lEQVQ4y5WUy08TQRzHl8jJA2ct0AJt6YPubrttKSB97Xa3hT6QcPFiUEz0YsST/4Hxygko1fC3ePJx9qIHExM5SPrcvkvN15npI+WhyCbf/GZn5/eZ7/xmZ7hgREYoqiAUjiIUV6ElU0ispxCWYwjHVChaAoqaQFhRmKKahqBKcmQNMhmvygoiiQRiiSSS6Q1wshrHWirDOtRkGusb95HMbCK9uQWNgKMxrTfhBa0SAwNRU4oWZ2O5pZVVrKwG4SfRvxJEYPkeAqTtW1yCz78Et+QDL3oguCWIHi/cHh8k3yL8gWVI/gC8fdE+Ko4mOBZ4LPAikQCnS2DJExO3wXHcULfGOIyNvNsdDjYRzXMJ7qE4D6HSBv3YkwRBFGBzZeD0voCZf4o7c49hsOzgrnkHk9YncErP4BIDZKw4ktcTc3gO6PbC4bRh48EbvHr9DY9efsD27kcSP7G4vfsZD5+/h3dRJu7464G0TrNmK3Jv34E+pVKFqVgqo1zWUa83cXqah0p23+50sfJcC5yZs+D4+JgBm80Gfn3/gZMvX6HnC6xP1ytIpTM3A+ZyPYfVah3tdpuog1arjbOzLnFahha/ocPsUQ7d30Ct3kC320Wn02Fg2q5UKmTJcdj6wNH8K4GmWTNxmGMOqRsKaLVaQ6Cu61hbT8LmWLjeIX2nwOzREQMWCgUUi0XUajU0Gg2y5DM2QTyxRoCuGwCz2f6mNBlkdMmlUgmyEru6hh6v/xLQODOHg8NDBqSuepvSPgeMkPNsd/LkEHj+XcMBcH9/nwHr9foQRutIgbQEkag8BPJ9KDt6fwMeHPQcDiBUdOn0oTUM94H8/zrc29tjyfl8nu00FV1qtVrFyclPBEMRdqmMAt2eC8BBpLfOtNEIq9UKu90Oi8UCB7ldaBQEASaTCdZ52/AfHOSJovsy0NV3Oj4+fu76uiijaYb9s6NASZKudkijkbgwGAyYmp5mjgaanJpi/fN2xyWHdIP+AMdpNjzbSgLmAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/e079842c4776f7b861909c0187fc0ac7/8ac56/image-20230511223051867.webp 240w,\n/static/e079842c4776f7b861909c0187fc0ac7/d3be9/image-20230511223051867.webp 480w,\n/static/e079842c4776f7b861909c0187fc0ac7/e213b/image-20230511223051867.webp 684w\"\n              sizes=\"(max-width: 684px) 100vw, 684px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/e079842c4776f7b861909c0187fc0ac7/8ff5a/image-20230511223051867.png 240w,\n/static/e079842c4776f7b861909c0187fc0ac7/e85cb/image-20230511223051867.png 480w,\n/static/e079842c4776f7b861909c0187fc0ac7/2c288/image-20230511223051867.png 684w\"\n            sizes=\"(max-width: 684px) 100vw, 684px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/e079842c4776f7b861909c0187fc0ac7/2c288/image-20230511223051867.png\"\n            alt=\"image-20230511223051867\"\n            title=\"image-20230511223051867\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>When you start debugging in Android Studio, the APK launches on the emulator and then a debug window like the following opens.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 931px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/459c8de72bc14b714572e60ef07d639b/82b28/image-20230511223323738.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 74.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAABC0lEQVQ4y+2U3U6EQAyFeRwYuFoRgfmBYUAWltW4mxjf/0WOpbATfzYYjRdeePHlNJlypkDboB2f4KYz+sdn2OEEM57hji/Q/QnSHZiyGX0sm4OPVTtBuWnRlcC6DrqyMNZBVQ6lqaGMRakrFFIhL9WqEneF9JrlBXY3t9il7wlGMkyzDCKKEMdiQQgkHMdMkhCXeNU5L6JnPhIMe3odZRCGIScKMhPiolvE/sK3BMP0gLwoyT28mrDFbPzJsOl6+hYpl/tdw6sV6rr5XUNFf/jf8I8bft3Q23hDHj3u/oRG7Wdwhd1+wD2Nn207oqVFUcNQb+raorINx4Z0juclwqxns/JiqZfzQmq8AoFs1PBoPE/wAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/459c8de72bc14b714572e60ef07d639b/8ac56/image-20230511223323738.webp 240w,\n/static/459c8de72bc14b714572e60ef07d639b/d3be9/image-20230511223323738.webp 480w,\n/static/459c8de72bc14b714572e60ef07d639b/c4004/image-20230511223323738.webp 931w\"\n              sizes=\"(max-width: 931px) 100vw, 931px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/459c8de72bc14b714572e60ef07d639b/8ff5a/image-20230511223323738.png 240w,\n/static/459c8de72bc14b714572e60ef07d639b/e85cb/image-20230511223323738.png 480w,\n/static/459c8de72bc14b714572e60ef07d639b/82b28/image-20230511223323738.png 931w\"\n            sizes=\"(max-width: 931px) 100vw, 931px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/459c8de72bc14b714572e60ef07d639b/82b28/image-20230511223323738.png\"\n            alt=\"image-20230511223323738\"\n            title=\"image-20230511223323738\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>From here it looks like debugging would be easier if we could configure symbols for the native library, but unfortunately we do not have the target symbols on hand, so that approach is unavailable.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 811px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/2899fc08a33e6daf91d0b787ca9d7b87/fd28b/image-20230511224051351.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 50.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABPUlEQVQoz52S2U7DQAxF8zmINyRACulk9j0ttFH//1Mu9iSkLaAK8XCVzOJjX3s6v5+QS0XMBdZHGJIipf0BIWaM1kGlCBcyjAt0J+A0H3D8qJiKR/C+xYzaYic1Ok0X9/MZmYCjMuiFhLEGpVb4VKCshzJuEf+zCKxdbF+57jH0jWI7QQt/Oq2ATIEWUusGkCSzVq0peANeyYbUzqf3I1xMVKF3KPOMWhJ8cLDOwMeIkGqDhLxUqp1vtuSa6LsYLtjyY2/xZCbsyoxnmfDwqvEiHEEzBLWAbQyjauIe/a7lrN+NZJmyjtptTWUAZ+TqeC2UvgO6qCVn4Ff2i/Rm7S+gTTzQBrzaZNgg2abarN6c/UiubtrRDwId+2fosAWqVmGbOL1BBl/38V9A4WnStbRJ85Ow9By4R0vgfeAn+aVgHsVo9hAAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/2899fc08a33e6daf91d0b787ca9d7b87/8ac56/image-20230511224051351.webp 240w,\n/static/2899fc08a33e6daf91d0b787ca9d7b87/d3be9/image-20230511224051351.webp 480w,\n/static/2899fc08a33e6daf91d0b787ca9d7b87/a63ac/image-20230511224051351.webp 811w\"\n              sizes=\"(max-width: 811px) 100vw, 811px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/2899fc08a33e6daf91d0b787ca9d7b87/8ff5a/image-20230511224051351.png 240w,\n/static/2899fc08a33e6daf91d0b787ca9d7b87/e85cb/image-20230511224051351.png 480w,\n/static/2899fc08a33e6daf91d0b787ca9d7b87/fd28b/image-20230511224051351.png 811w\"\n            sizes=\"(max-width: 811px) 100vw, 811px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/2899fc08a33e6daf91d0b787ca9d7b87/fd28b/image-20230511224051351.png\"\n            alt=\"image-20230511224051351\"\n            title=\"image-20230511224051351\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<h3 id=\"debug-a-native-app-in-android-studio\" style=\"position:relative;\"><a href=\"#debug-a-native-app-in-android-studio\" aria-label=\"debug a native app in android studio permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Debug a Native App in Android Studio</h3>\n<p>To debug a native app in Android Studio, open the configuration window from [Run] > [Edit Configurations].</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 514px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/78d3d894b8700feecfe37587d3d32060/dea13/image-20230512215555817.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 58.75%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1ElEQVQoz32STW7bMBCFdZfCNiAJaYCuHP2LFEmRkm25CNK0QZwALVokWfUGWTQI2kUP0MO+zlBWkgJuFg9DieLHeW8UKK2wuf0Dd3kPISsI3UK1Dq3rUTcamtZZUaGSClIblEIiyUuk9O6QgqysUboOph9gLFUCNcYirwRy2uOa7Ss/Z3vlVe0BfKmxDkLpERjFMdIsh2iU3xQk7obF65qqF695TzQoaun3/SWkaf32+BjBfDZDIgroroNUxtviDis5HmSVUyUYH2TLk22+QLXWRxGGIYLFfIFEErDvoQjEMM5wOvwS8KwxrxFa+0aKWiCKIupwPkdWUw5u5UGactR2BPJH3Nn/BjBBT7LCywMXBFzK3Fv2Xe0hHPxLa4dAJWXHQ+ShcM7hE1AXcMOARlss/W3PoMQf/lcTkONgoO3GXyycLKfWwq4Hb3kcBOcnPexVuyRuYPlkOUYwoynnK4F+u4FpW7ieLdDUqgonaYIkSw8rHWstBA2F8i6LfYezN6hOv2P77TeGz4/YkN5//Qlz+QB58QPNxcMBje953+we0V7/gvp0j/joHWfI/+EW/fkd1h9vsT6/gVhdoex2r+gKhduhGb6g/3AHd3YDub5GFB/hL5burmm/hXluAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/78d3d894b8700feecfe37587d3d32060/8ac56/image-20230512215555817.webp 240w,\n/static/78d3d894b8700feecfe37587d3d32060/d3be9/image-20230512215555817.webp 480w,\n/static/78d3d894b8700feecfe37587d3d32060/7a333/image-20230512215555817.webp 514w\"\n              sizes=\"(max-width: 514px) 100vw, 514px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/78d3d894b8700feecfe37587d3d32060/8ff5a/image-20230512215555817.png 240w,\n/static/78d3d894b8700feecfe37587d3d32060/e85cb/image-20230512215555817.png 480w,\n/static/78d3d894b8700feecfe37587d3d32060/dea13/image-20230512215555817.png 514w\"\n            sizes=\"(max-width: 514px) 100vw, 514px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/78d3d894b8700feecfe37587d3d32060/dea13/image-20230512215555817.png\"\n            alt=\"image-20230512215555817\"\n            title=\"image-20230512215555817\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Next, set [Debug Type] to [Native Only].</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 896px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/de1012ff875c68b45d22cb5cf01c4664/4c42d/image-20230512215655342.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAuklEQVQY022PVw7DQAhEfZu0zxQ7ir2w3UXJ/W8zYXGRUj6ehl1ggIpzwjA9EVIPwxZdgWaM9SAX4GIS9TDfSL5jB/YBLHUlro4Ph3v/wtlk7C4GhxthfyWcapICDxsiQh5UtVGJCvnwa1i3hKZjwaIWXWla1g0K2iwNHEdQ6NWgXPAwjJZYVWOhavXTamJWuxWXU1M/Ig0TsuDyBC9YGVC2+Uel7ovBxvK2ISEuhuVsLwPKduvgj56FN+Qdrux3KucKAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/de1012ff875c68b45d22cb5cf01c4664/8ac56/image-20230512215655342.webp 240w,\n/static/de1012ff875c68b45d22cb5cf01c4664/d3be9/image-20230512215655342.webp 480w,\n/static/de1012ff875c68b45d22cb5cf01c4664/c1a89/image-20230512215655342.webp 896w\"\n              sizes=\"(max-width: 896px) 100vw, 896px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/de1012ff875c68b45d22cb5cf01c4664/8ff5a/image-20230512215655342.png 240w,\n/static/de1012ff875c68b45d22cb5cf01c4664/e85cb/image-20230512215655342.png 480w,\n/static/de1012ff875c68b45d22cb5cf01c4664/4c42d/image-20230512215655342.png 896w\"\n            sizes=\"(max-width: 896px) 100vw, 896px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/de1012ff875c68b45d22cb5cf01c4664/4c42d/image-20230512215655342.png\"\n            alt=\"image-20230512215655342\"\n            title=\"image-20230512215655342\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>This allows you to debug the native library from the Android Studio debugger.</p>\n<p>After changing this setting, press the debug button once more to start debugging the app again.</p>\n<h3 id=\"identify-the-app-architecture-and-image-base\" style=\"position:relative;\"><a href=\"#identify-the-app-architecture-and-image-base\" aria-label=\"identify the app architecture and image base permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Identify the App Architecture and Image Base</h3>\n<p>Now that native library debugging is enabled in Android Studio, it is finally time to set a breakpoint at the location that validates the Flag and trace the execution.</p>\n<p>From here on, the work is not very different from ordinary dynamic analysis of a typical ELF binary.</p>\n<p>To determine where to set the breakpoint, first identify the image base where the target native library is loaded.</p>\n<p>After starting debugging, if you break the app while it is running, you will see the disassembly of the current stop location and the LLDB console as shown below.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 925px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e38c8c6f27d00ea75232caabc802f890/2a50c/image-20230512234021749.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 77.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAABtklEQVQ4y52S2XKjMBBF9Tk2YHaxgw1I7A42TuYtU/OS//+Emway1bxg5+FUSyrq6LZo1g8t+n6lEAJZIXCcKSWyvERZNchFhTg7ITnmmzDHC/EJ9wL4Pv/Cth068+C6HIZpwbwDFiUZojiFF8TQDQuBrSL1DLiOid1uh/1+v6B81C1WIeGHJKQbXH2P2CWh60LTVKiKAlVV1noH/wkduKaOkNuwHL4kVjQd6gMswnAmCGCFArx+Rdj9g9O/QSleoYm/D8GiOMGM74eUyIRvKvSOB9iWtbR8OGjfaNuwVPTIZI+jHBDmDRJap/IMnkr4KSWOC/BkxUvKTZjoRpTdBaIZULQjiv5G+wmnekD3dIVozziKGrlskeZyExadJIKyRSQ6JFUPNythRCfEnk9/myMLE8ScIyE8eobItr/waR//WOuGATY9STxfKqLGbZS4DPlSLRqdnUKz9WMWt5hnlU1jQ4IKt0VYY6L1n6mDzWlk5vlT1YdgV5I8XxtK2Cx1Fr9cWzjUwnzr/JGi3C9ml7Nc2/2EEr5QQsf5Fj6UcBzE2jIxfbAktH8tXBNOi3RNOLdv/1L4DqdgDQp+5zkDAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/e38c8c6f27d00ea75232caabc802f890/8ac56/image-20230512234021749.webp 240w,\n/static/e38c8c6f27d00ea75232caabc802f890/d3be9/image-20230512234021749.webp 480w,\n/static/e38c8c6f27d00ea75232caabc802f890/31b98/image-20230512234021749.webp 925w\"\n              sizes=\"(max-width: 925px) 100vw, 925px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/e38c8c6f27d00ea75232caabc802f890/8ff5a/image-20230512234021749.png 240w,\n/static/e38c8c6f27d00ea75232caabc802f890/e85cb/image-20230512234021749.png 480w,\n/static/e38c8c6f27d00ea75232caabc802f890/2a50c/image-20230512234021749.png 925w\"\n            sizes=\"(max-width: 925px) 100vw, 925px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/e38c8c6f27d00ea75232caabc802f890/2a50c/image-20230512234021749.png\"\n            alt=\"image-20230512234021749\"\n            title=\"image-20230512234021749\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Next, run the following command in the LLDB console to list the loaded images.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">image list</code></pre></div>\n<p>From the output of this command, find the line where <code class=\"language-text\">libhello-jni.so</code>, the library being analyzed, is displayed, and identify the image base address.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/8cc0e480cd6cddaac131a29b88d226e6/66632/image-20230512234257109.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 10.416666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAa0lEQVQI13XJ0QqCMBiGYe/G2fbrpgtTZqPDTlTKDhTv/zbeRgVB0MEDL9+X9ZeJNo4czxNNXPCJiw/0sJKHHRU28mFPvaG6O+p0++qWzzaj/JXCBrKydljnMVIhUr6YRJuKwy9xf9j3r4UnD9ZA8KQ9YbgAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/8cc0e480cd6cddaac131a29b88d226e6/8ac56/image-20230512234257109.webp 240w,\n/static/8cc0e480cd6cddaac131a29b88d226e6/d3be9/image-20230512234257109.webp 480w,\n/static/8cc0e480cd6cddaac131a29b88d226e6/e46b2/image-20230512234257109.webp 960w,\n/static/8cc0e480cd6cddaac131a29b88d226e6/f992d/image-20230512234257109.webp 1440w,\n/static/8cc0e480cd6cddaac131a29b88d226e6/ca108/image-20230512234257109.webp 1504w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/8cc0e480cd6cddaac131a29b88d226e6/8ff5a/image-20230512234257109.png 240w,\n/static/8cc0e480cd6cddaac131a29b88d226e6/e85cb/image-20230512234257109.png 480w,\n/static/8cc0e480cd6cddaac131a29b88d226e6/d9199/image-20230512234257109.png 960w,\n/static/8cc0e480cd6cddaac131a29b88d226e6/07a9c/image-20230512234257109.png 1440w,\n/static/8cc0e480cd6cddaac131a29b88d226e6/66632/image-20230512234257109.png 1504w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/8cc0e480cd6cddaac131a29b88d226e6/d9199/image-20230512234257109.png\"\n            alt=\"image-20230512234257109\"\n            title=\"image-20230512234257109\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>This time, <code class=\"language-text\">0xd4b0d000</code> was the image base address. (It changes each time you launch the app.)</p>\n<p>Next, inspect the memory information at the image base address and identify the architecture of the loaded image from the ELF header.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 653px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/6d74dded3911fa8c22cbd8227b2f0ce7/e7dce/image-20230512234532190.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 13.333333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAdklEQVQI122OawrDMAyDc54kzaO0W5rY6aC9/5U0O6NjsP4QnywbYbOsD2yVwP0F9c5aeO9vNf1l06Bz7itzHgdWKWqtoZSCWiuISGYlo/cOkh0zg0feJNvl9omcZ1EapSl9aNSEEEYQY7yV7i/+ev3o+lZn5RvZe16lHYCgtwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/6d74dded3911fa8c22cbd8227b2f0ce7/8ac56/image-20230512234532190.webp 240w,\n/static/6d74dded3911fa8c22cbd8227b2f0ce7/d3be9/image-20230512234532190.webp 480w,\n/static/6d74dded3911fa8c22cbd8227b2f0ce7/d0839/image-20230512234532190.webp 653w\"\n              sizes=\"(max-width: 653px) 100vw, 653px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/6d74dded3911fa8c22cbd8227b2f0ce7/8ff5a/image-20230512234532190.png 240w,\n/static/6d74dded3911fa8c22cbd8227b2f0ce7/e85cb/image-20230512234532190.png 480w,\n/static/6d74dded3911fa8c22cbd8227b2f0ce7/e7dce/image-20230512234532190.png 653w\"\n            sizes=\"(max-width: 653px) 100vw, 653px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/6d74dded3911fa8c22cbd8227b2f0ce7/e7dce/image-20230512234532190.png\"\n            alt=\"image-20230512234532190\"\n            title=\"image-20230512234532190\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>By referring to the familiar table on Wikipedia, you can confirm that the image loaded during this debugging session uses the x86 architecture because <code class=\"language-text\">e_machine</code> at offset 0x12 is 0x3.</p>\n<p>Reference: <a href=\"https://en.wikipedia.org/wiki/Executable_and_Linkable_Format\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Executable and Linkable Format - Wikipedia</a></p>\n<p>So I analyzed the x86 native library that Apktool had unpacked earlier in Ghidra and identified the offset of the <code class=\"language-text\">checkValid</code> function.</p>\n<p>From Ghidra’s analysis result, you can see that the offset of the <code class=\"language-text\">checkValid</code> function is <code class=\"language-text\">0x1a020</code>, so I entered <code class=\"language-text\">0xd4b27020</code>, which is the image base address plus that offset, into the disassembly window.</p>\n<p>This allowed me to identify the address of the <code class=\"language-text\">checkValid</code> function.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 701px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/fea9e7d58b753451f2dfc0bc816a912e/49217/image-20230512235123740.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 72.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB6ElEQVQ4y32T2ZLaMBBF+Z14lWTtlmUwDDA1KfL/X3PTLTBjhkoebtlAcXR60S4uF0xHynIuyfQ+H8+4/r7h8nXD4XQq2S9HLB9nfN3+YD4syPsDztdPnC5X+u2EkHLJzvuANGXEMVEmGOtgjMExO3xMAz6PEcsckKPGPBrsk8EUdPm8TxpaCXRdj74XlB47S0AG+ZgQKMZ5CDlA9h28rOGMhtEaUkpUdY26aV7SUNrHk7NzYcSY94hpLrE+ohMKoq0xqV9wdMBgLJlItG2HqqpQU6p/ZMeAyPWTJce4gF4q9AT0ooIwAYMNsGTatO0dyKaUpmnLc/sdAclwmgmWS6z7NhxlBW0cFAH5T83jzytACEHWbSl1Bb8DNyVHAlprIW3EQH109F5Vq1FDw+jKILi/G+B7yQx8lqwMYghw3tPTf/dxY7u1LkNJZSj5bShs2A4Oc6YDrYZ3tphte7bN0zA81oajrX8OxZGhGRQ09dVsSt4CtrYPw4Q0H0ofOauh7O5Dsbw2BHR0WJ5SmexPw5cpc8/YjEvnrIZdU8P0FbrBQmj3uA39C4CH8gbkk6d5Ibt9WXCGroaJFlvaESZmqOF+Y/h2/FybFyAbcZlsyhlo73q6ei0ZDh3tXi+hCaSUgpKi7Nz/Sv4LK8C+qBriPbwAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/fea9e7d58b753451f2dfc0bc816a912e/8ac56/image-20230512235123740.webp 240w,\n/static/fea9e7d58b753451f2dfc0bc816a912e/d3be9/image-20230512235123740.webp 480w,\n/static/fea9e7d58b753451f2dfc0bc816a912e/e2a71/image-20230512235123740.webp 701w\"\n              sizes=\"(max-width: 701px) 100vw, 701px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/fea9e7d58b753451f2dfc0bc816a912e/8ff5a/image-20230512235123740.png 240w,\n/static/fea9e7d58b753451f2dfc0bc816a912e/e85cb/image-20230512235123740.png 480w,\n/static/fea9e7d58b753451f2dfc0bc816a912e/49217/image-20230512235123740.png 701w\"\n            sizes=\"(max-width: 701px) 100vw, 701px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/fea9e7d58b753451f2dfc0bc816a912e/49217/image-20230512235123740.png\"\n            alt=\"image-20230512235123740\"\n            title=\"image-20230512235123740\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<h3 id=\"set-breakpoints-and-identify-the-flag\" style=\"position:relative;\"><a href=\"#set-breakpoints-and-identify-the-flag\" aria-label=\"set breakpoints and identify the flag permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Breakpoints and Identify the Flag</h3>\n<p>Once you have come this far, the rest is easy.</p>\n<p>As identified earlier in the static analysis, this native library function accepts 38 (0x26) characters of input and checks characters 7 through 37 one by one at the line <code class=\"language-text\">if (cVar1 != *pcVar2)</code>.</p>\n<p>So I set a breakpoint at <code class=\"language-text\">0xd4b2720c</code>, which is the image base address plus the offset of the validation line.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Set a breakpoint</span>\nb *0xd4b2720c</code></pre></div>\n<p>After setting the breakpoint there, I entered an arbitrary 38-character string in the app on the emulator and pressed the [Check Flag] button, and execution stopped at the breakpoint I had set.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 538px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/2fd18089f248e5d735e55cb3b068d551/9516f/image-20230512235908953.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 105.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAAAsTAAALEwEAmpwYAAACEUlEQVQ4y52TS2/TQBSF5z8hdQUSFRICFiAKrJCQgG5ZIH4NQmJZgRCoiFIJtQKVpElL7DgJ9LFBSlM7yYKSp1/jcQ53JkmxHSdKuvh07Dv33jn2nWG3Hn7B6osMnj7/jkfPdrDyZBtX7mxg+d4mrq58Xohlgl2+/Qn3V7ep0RbuPt7CtQebuHR9HUs3P2LpxqKsg2XyNXzNVIdkq9jJnWB3v4bsBWHAAJOEczBIhbmujzQ8wg/EiOD8mfMAnpdeI2G+T4UJAs5hOw4ONAPlvQJKmo7KvoZKvgCjaKDb6yGQm6TUMk7FUVRDSu7afWTebyDz6i12iW9rH5B7+QbZ1+9w1mlBSMeUm6xPdSgXPM9Do9mEWbdg1eswGwRpw7TguO755hMO04LjpqEQCMNwiBiqIKY1m2iY9vkqHs1JyYt9sl628Ou4iWLFglYyoZdN5LWaev9RPFUYPy3s6cOYRuvDWF2prCnSeq5wgt/VP2AF4xTlg4ZKbrVt9PoOOl2HJpkgLRZB1ti2C1Yz/8JqtBXSshABTZkvjBgpGwwEBmGgmPWz54WlTTfggTqLM+H/DcSGEp3oWA+Pj1DQNeiGQRQTGNBIS5UyHLpNyaaM+xTgkWND6rW7cM/aRGc6rW7MRMxh7HxJ7fQRtHrg7SnINcpR53NcE716qul4IFLlxRdzMGrmJ//hhMMFmHA46xpdhH96IAkdc2WtHgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/2fd18089f248e5d735e55cb3b068d551/8ac56/image-20230512235908953.webp 240w,\n/static/2fd18089f248e5d735e55cb3b068d551/d3be9/image-20230512235908953.webp 480w,\n/static/2fd18089f248e5d735e55cb3b068d551/b52d2/image-20230512235908953.webp 538w\"\n              sizes=\"(max-width: 538px) 100vw, 538px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/2fd18089f248e5d735e55cb3b068d551/8ff5a/image-20230512235908953.png 240w,\n/static/2fd18089f248e5d735e55cb3b068d551/e85cb/image-20230512235908953.png 480w,\n/static/2fd18089f248e5d735e55cb3b068d551/9516f/image-20230512235908953.png 538w\"\n            sizes=\"(max-width: 538px) 100vw, 538px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/2fd18089f248e5d735e55cb3b068d551/9516f/image-20230512235908953.png\"\n            alt=\"image-20230512235908953\"\n            title=\"image-20230512235908953\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>At that moment, ECX contains the correct Flag character, and it is compared against EAX, which contains the input value.</p>\n<p>So if you print the value of ECX as shown below, write the value of ECX into EAX, and then continue execution, you can recover the correct Flag one character at a time.</p>\n<p>Originally, I wanted to automate this using LLDB’s embedded Python, but in Android Studio’s default debugger the <code class=\"language-text\">source</code> command did not work, so I used a source file for automation instead.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Put the following in cmd.txt</span>\np/c <span class=\"token variable\">$ecx</span>\nregister <span class=\"token function\">write</span> eax <span class=\"token variable\"><span class=\"token variable\">`</span>$ecx<span class=\"token variable\">`</span></span>\n<span class=\"token builtin class-name\">continue</span>\n\n<span class=\"token comment\"># Run the source file</span>\n<span class=\"token builtin class-name\">command</span> <span class=\"token builtin class-name\">source</span> C:<span class=\"token punctuation\">\\</span>Users<span class=\"token punctuation\">\\</span>Tadpole01<span class=\"token punctuation\">\\</span>Downloads<span class=\"token punctuation\">\\</span>cmd.txt</code></pre></div>\n<p>This allowed me to recover the Flag by determining it one character at a time, as shown below.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 508px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/fc60675043a08c43b45e20f2f76afdd8/2fd48/image-20230513000202912.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABp0lEQVQ4y41T2XKDMAzkY9ppAoFwGN82tP//T+quKD2mzUwfdiQcea3VKs3z/CT9MkjKm8RcxLogLkQxqxUfkoSUEaPkuktMBXVV6wJyRh+T1o3TJG17lSbEgMIoET/s+6vknMVaKxMKjDH67ZyTUquklFAX9Yz5Ce+91nZdJw2JEop4Kecky7JI17YyDIPc73e82sr1ekVxq/mJrv35rSBhwmullOM1EIcQINvpWUVX1q5yB/lxqftNcj4AMj4KyVHWdVUZxDLPKvcEpUzT+O3SY7CmyRFDV7kHoYHkGaSUe3l5OXC5qOxHoBnng03vexntJLnAZTgaMNMN5ngfZDGrGOvU8dV5zc9oVuSIrFnwe/8xlmZ2s9jglKhuG4iLznBGpx7zrNuuzr6+vWlObDti3bSeMWL+HBuNagp2iWbQ+loLZrbI7XZT9D3Ra07XmfPszIcPnDXH2oCdbkbuI0DiaZo/920cx4fO/gXdQy4yY1THje4kzyiDa8Td/I/L2mHm30flbrJhJpRMhynlcPBrz37u3ANCdsFd047MkbNTxu+X/9vhO4PAnAltgAAuAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/fc60675043a08c43b45e20f2f76afdd8/8ac56/image-20230513000202912.webp 240w,\n/static/fc60675043a08c43b45e20f2f76afdd8/d3be9/image-20230513000202912.webp 480w,\n/static/fc60675043a08c43b45e20f2f76afdd8/7b066/image-20230513000202912.webp 508w\"\n              sizes=\"(max-width: 508px) 100vw, 508px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/fc60675043a08c43b45e20f2f76afdd8/8ff5a/image-20230513000202912.png 240w,\n/static/fc60675043a08c43b45e20f2f76afdd8/e85cb/image-20230513000202912.png 480w,\n/static/fc60675043a08c43b45e20f2f76afdd8/2fd48/image-20230513000202912.png 508w\"\n            sizes=\"(max-width: 508px) 100vw, 508px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/fc60675043a08c43b45e20f2f76afdd8/2fd48/image-20230513000202912.png\"\n            alt=\"image-20230513000202912\"\n            title=\"image-20230513000202912\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>By the way, the following reference was helpful for LLDB commands.</p>\n<p>Reference: <a href=\"https://lldb.llvm.org/use/map.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GDB to LLDB command map — The LLDB Debugger</a></p>\n<h2 id=\"perform-dynamic-analysis-by-attaching-a-debugger-to-the-emulator\" style=\"position:relative;\"><a href=\"#perform-dynamic-analysis-by-attaching-a-debugger-to-the-emulator\" aria-label=\"perform dynamic analysis by attaching a debugger to the emulator permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Perform Dynamic Analysis by Attaching a Debugger to the Emulator</h2>\n<h3 id=\"install-the-apk-on-the-emulator\" style=\"position:relative;\"><a href=\"#install-the-apk-on-the-emulator\" aria-label=\"install the apk on the emulator permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install the APK on the Emulator</h3>\n<p>This time, instead of using Android Studio’s debugging features, I will attach a debugger to an application launched inside the system emulator.</p>\n<p>First, with the emulator running, install the target APK file with the following command.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">adb <span class=\"token function\">install</span> app-debug.apk</code></pre></div>\n<p><code class=\"language-text\">adb.exe</code> is included in the Android SDK and can be downloaded from the following page.</p>\n<p>Reference: <a href=\"https://developer.android.com/studio?gclid=CjwKCAjw6vyiBhB_EiwAQJRoprp-0U8PGLSdFb6ERPp2yPYxepcemF_TCzHbpOTHWLof5LRcMEFdHBoCQ84QAvD_BwE&#x26;gclsrc=aw.ds\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Download Android Studio &#x26; App Tools - Android Developers</a></p>\n<p>Once the APK has been installed, you will be able to launch the app on the running emulator.</p>\n<p>Next, download the Android NDK tools in advance so you can attach a debugger to the emulator.</p>\n<p>The NDK tools can be downloaded from the following page.</p>\n<p>Reference: <a href=\"https://developer.android.com/ndk/downloads\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">NDK Downloads  |  Android NDK  |  Android Developers</a></p>\n<p>Incidentally, although we use the NDK tools to attach a debugger to the emulator, it seems that the current latest version, r25, no longer includes <code class=\"language-text\">gdbserver</code>, which was bundled with NDK tools up through r23.</p>\n<p>I would have preferred to use the familiar <code class=\"language-text\">gdb</code>, but thinking ahead I decided to use LLDB.</p>\n<h3 id=\"install-lldb-on-the-host-machine\" style=\"position:relative;\"><a href=\"#install-lldb-on-the-host-machine\" aria-label=\"install lldb on the host machine permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install LLDB on the Host Machine</h3>\n<p>Next, install LLDB on the host machine so that it can attach to the emulator.</p>\n<p>To install LLDB, download the Windows installer from the releases page of the following GitHub repository.</p>\n<p>Reference: <a href=\"https://github.com/llvm/llvm-project\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub - llvm/llvm-project: The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Note: the repository does not accept github pull requests at this moment. Please submit your patches at http://reviews.llvm.org.</a></p>\n<p>The version I used this time, 16.0.3, depends on Python10, so if Python10 is not installed or is not in PATH, you need to install it separately in advance.</p>\n<h3 id=\"deploy-lldb-server-to-the-android-emulator-and-launch-the-app\" style=\"position:relative;\"><a href=\"#deploy-lldb-server-to-the-android-emulator-and-launch-the-app\" aria-label=\"deploy lldb server to the android emulator and launch the app permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Deploy lldb-server to the Android Emulator and Launch the App</h3>\n<p>Now it is finally time to debug the app running on the Android emulator by attaching LLDB from the host machine.</p>\n<p>First, deploy <code class=\"language-text\">lldb-server</code> to the emulator side.</p>\n<p>The prebuilt <code class=\"language-text\">lldb-server</code> binary is placed inside the <code class=\"language-text\">toolchains</code> directory of the NDK obtained earlier.</p>\n<p>This time, to match the OS platform, I used the <code class=\"language-text\">lldb-server</code> located at <code class=\"language-text\">$NDK_PATH\\toolchains\\llvm\\prebuilt\\windows-x86_64\\lib64\\clang\\14.0.7\\lib\\linux\\i386\\lldb-server</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Install the APK file on the emulator</span>\nadb <span class=\"token function\">install</span> app-debug.apk\n\n<span class=\"token comment\"># Push lldb-server to the emulator</span>\nadb push lldb-server /data/local/tmp\n\n<span class=\"token comment\"># Grant execute permission to lldb-server</span>\nadb shell <span class=\"token function\">chmod</span> +x /data/local/tmp/lldb-server\n\n<span class=\"token comment\"># Copy lldb-server to the target package path</span>\nadb shell run-as com.example.hellojni <span class=\"token function\">cp</span> /data/local/tmp/lldb-server /data/data/com.example.hellojni/</code></pre></div>\n<p>In the commands above, I eventually grant execute permission to the pushed <code class=\"language-text\">lldb-server</code> and copy it to the target package path.</p>\n<p>You can identify the package name of the target from the <code class=\"language-text\">AndroidManifest.xml</code> analyzed earlier.</p>\n<h3 id=\"attach-the-debugger\" style=\"position:relative;\"><a href=\"#attach-the-debugger\" aria-label=\"attach the debugger permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Attach the Debugger</h3>\n<p>Everything is finally ready, so let us start debugging.</p>\n<p>We will execute the following commands in order, but first let us look at the information for the target package.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Dump package information</span>\nadb shell pm dump com.example.hellojni\n\n<span class=\"token operator\">></span>\nDUMP OF SERVICE package:\nActivity Resolver Table:\n  Non-Data Actions:\n      android.intent.action.MAIN:\n        6525ec5 com.example.hellojni/.HelloJni filter 3d4e3e9\n          Action: <span class=\"token string\">\"android.intent.action.MAIN\"</span>\n          Category: <span class=\"token string\">\"android.intent.category.LAUNCHER\"</span>\n<span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> omitted <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span></code></pre></div>\n<p>The dump command shows a very large amount of information, but here we especially want to note the package’s <code class=\"language-text\">ActivityName</code>.</p>\n<p>Make a note of the <code class=\"language-text\">com.example.hellojni/.HelloJni</code> part in the output above.</p>\n<p>Now that all preparations are complete, start debugging with the following commands.</p>\n<p>By the way, <code class=\"language-text\">com.example.hellojni</code> is the target package name here.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Stop lldb-server in advance (not needed the first time)</span>\nadb shell run-as com.example.hellojni <span class=\"token function\">killall</span> -9 lldb-server\n\n<span class=\"token comment\"># Launch the app with adb shell am start -a &lt;Main Activity> -D -n \"com.package.name/com.package.name.ActivityName\"</span>\nadb shell am start -a android.intent.action.MAIN -n <span class=\"token string\">\"com.example.hellojni/.HelloJni\"</span>\n\n<span class=\"token comment\"># Once the app starts, begin listening with lldb-server</span>\nadb shell run-as com.example.hellojni <span class=\"token function\">sh</span> -c <span class=\"token string\">'/data/data/com.example.hellojni/lldb-server platform --server --listen unix-abstract:///data/data/com.example.hellojni/debug.socket'</span>\n\n<span class=\"token comment\"># Open another terminal and check the app's PID</span>\nadb shell run-as com.example.hellojni <span class=\"token function\">ps</span>\n\n<span class=\"token comment\"># Launch lldb</span>\nlldb.exe\n\n<span class=\"token comment\"># Run these in order at the (lldb) prompt</span>\nplatform <span class=\"token keyword\">select</span> remote-android\nplatform connect unix-abstract-connect:///data/data/com.example.hellojni/debug.socket\n\n<span class=\"token comment\"># Attach to the app PID identified above</span>\nattach <span class=\"token number\">17728</span></code></pre></div>\n<p>Reference: <a href=\"https://stackoverflow.com/questions/33441138/how-to-find-out-activity-names-in-a-package-android-adb-shell/37959688#37959688\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">How to find out activity names in a package? android. ADB shell - Stack Overflow</a></p>\n<p>Reference: <a href=\"https://stackoverflow.com/questions/4567904/how-to-start-an-application-using-android-adb-tools\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">How to start an application using Android ADB tools - Stack Overflow</a></p>\n<p>This lets you attach to the app running on the emulator from LLDB on the host machine.</p>\n<p>After that, as before, you can identify the Flag with the following commands.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Identify the base address of libhello-jni.so</span>\nimage list\n<span class=\"token operator\">></span>\n<span class=\"token punctuation\">[</span><span class=\"token number\">202</span><span class=\"token punctuation\">]</span> 2720F64E-E4CD-4F44-2073-43B9B03816BB-CE41285A 0xd86b5000 libhello-jni.so\n\n<span class=\"token comment\"># Set a breakpoint at 0xd86b5000+0x1a20c and resume app execution</span>\nb *0xd86cf20c\n<span class=\"token builtin class-name\">continue</span></code></pre></div>\n<p>Now that you can set a breakpoint at the location where the Flag is validated in the app running on the emulator, you can retrieve the Flag in the same way as before.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 847px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/661e42ca490c8aeb5cc1537c58ad6b48/b2cef/image-20230514112929403.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 27.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABBElEQVQY021RSW6EQAzkyjYsw74FAkNDQ3OD//+sYltBIlIOVpVtldvlto7jwDiOaNsWXdcjfr/xer0QBAF834fjOLBtW9BxXdgSzB24VHMpl94vt7Ztw7btWFeFffugbQqUZYm6rpGmKbIsE15QLQ9DtEGIKoyQEA856OEoioTzEpbWK/bd4DN9QasSeulgjKHaDqWUhNYay7JQf4GZFfqmRZnnKIoCOWFVVcKTJIHFguu6RGjMQbiIfc75HNM0yQZ8Bp8i5UG07dPmH8uKXj7PE/M8i3gcv8XyMAxyW96O8RZ4nifDGf8Li62woO/pQ+IYTdPI3W4xf8xzANfv3p0/B/4AFKaZIT/0gIYAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/661e42ca490c8aeb5cc1537c58ad6b48/8ac56/image-20230514112929403.webp 240w,\n/static/661e42ca490c8aeb5cc1537c58ad6b48/d3be9/image-20230514112929403.webp 480w,\n/static/661e42ca490c8aeb5cc1537c58ad6b48/8a8c4/image-20230514112929403.webp 847w\"\n              sizes=\"(max-width: 847px) 100vw, 847px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/661e42ca490c8aeb5cc1537c58ad6b48/8ff5a/image-20230514112929403.png 240w,\n/static/661e42ca490c8aeb5cc1537c58ad6b48/e85cb/image-20230514112929403.png 480w,\n/static/661e42ca490c8aeb5cc1537c58ad6b48/b2cef/image-20230514112929403.png 847w\"\n            sizes=\"(max-width: 847px) 100vw, 847px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/661e42ca490c8aeb5cc1537c58ad6b48/b2cef/image-20230514112929403.png\"\n            alt=\"image-20230514112929403\"\n            title=\"image-20230514112929403\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>However, this time I wanted to make the analysis a little easier by using LLDB scripts.</p>\n<h3 id=\"control-lldb-with-python\" style=\"position:relative;\"><a href=\"#control-lldb-with-python\" aria-label=\"control lldb with python permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Control LLDB with Python</h3>\n<p>LLDB provides very extensive support for interfaces using Python.</p>\n<p>To check whether LLDB’s Python interpreter is available, try entering the following command in the attached debugger.</p>\n<p>For some reason I could not use it in the debugger launched from Android Studio, but in the environment where I attached from the host this time I was able to start the interpreter.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Start LLDB's embedded Python interpreter</span>\nscript</code></pre></div>\n<p>Reference: <a href=\"https://lldb.llvm.org/use/python-reference.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Python Reference — The LLDB Debugger</a></p>\n<p>Now that we know Python scripts can be used in LLDB, we can automate Flag extraction as follows.</p>\n<p>This time, I decided to retrieve the Flag by registering a Python script that runs when the breakpoint is hit.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Identify the ID of the breakpoint you set</span>\nbr list\n<span class=\"token operator\">></span>\n<span class=\"token number\">1</span>: address <span class=\"token operator\">=</span> libhello-jni.so<span class=\"token punctuation\">[</span>0x0001a20c<span class=\"token punctuation\">]</span>, locations <span class=\"token operator\">=</span> <span class=\"token number\">1</span>, resolved <span class=\"token operator\">=</span> <span class=\"token number\">1</span>, hit count <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n\n<span class=\"token comment\"># Use the identified breakpoint ID to define what happens when the breakpoint is hit</span>\nscript <span class=\"token assign-left variable\">counter</span><span class=\"token operator\">=</span><span class=\"token number\">0</span>\nbreakpoint <span class=\"token builtin class-name\">command</span> <span class=\"token function\">add</span> --script-type python <span class=\"token number\">1</span>\n\n<span class=\"token comment\"># Enter the following</span>\n<span class=\"token function\">import</span> <span class=\"token function\">time</span>\n\neax <span class=\"token operator\">=</span> frame.FindRegister<span class=\"token punctuation\">(</span><span class=\"token string\">\"eax\"</span><span class=\"token punctuation\">)</span>\necx <span class=\"token operator\">=</span> frame.FindRegister<span class=\"token punctuation\">(</span><span class=\"token string\">\"ecx\"</span><span class=\"token punctuation\">)</span>.value\neax.SetValueFromCString<span class=\"token punctuation\">(</span>ecx<span class=\"token punctuation\">)</span>\nprint<span class=\"token punctuation\">(</span>chr<span class=\"token punctuation\">(</span>int<span class=\"token punctuation\">(</span>ecx,16<span class=\"token punctuation\">))</span>,end<span class=\"token operator\">=</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span>\n\ntime.sleep<span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\nthread <span class=\"token operator\">=</span> frame.GetThread<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nprocess <span class=\"token operator\">=</span> thread.GetProcess<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nprocess.Continue<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nDONE</code></pre></div>\n<p>When I actually ran this, I was able to capture the Flag characters as shown below.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 804px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/a4ecd5ed546d7222573f3eccc780cefc/27b7a/image-20230514131809863.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 47.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABHUlEQVQoz5WSx46EQAxEuZLzkBkyIonw///mUXnl1WyQ2D2UWt00z1V2K13XEdT3PVVVRdM0UV3XlKYpyTfsIdM0SdM0lqqqpOv6FxmGQQoA27bRMAy0LAud58lQ2UNt21IcxxQEAXmeR77vUxRFZNs2Q1AIK6CK67oMbJqGXQJ2XReD5nmmdV35DFCsx3HQOI58N89zLlSWJYVh+AFMkoQvIy4cOI7D6+Px4EtwA6Ew3OEcziTiD4foFSqJQ7iSAvgZIFyU3kEC+7WHaLZE2/edI0ksOIRbcXIndphlGRVF8dkHxJLo4uzd0R1UkUFIXDwTTBjNfgf8BcZARAUMLhETK54EZFnWv2AMxACezyc7QnxMHcKwcPZ9ond6AVi++56D/vM2AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/a4ecd5ed546d7222573f3eccc780cefc/8ac56/image-20230514131809863.webp 240w,\n/static/a4ecd5ed546d7222573f3eccc780cefc/d3be9/image-20230514131809863.webp 480w,\n/static/a4ecd5ed546d7222573f3eccc780cefc/95e88/image-20230514131809863.webp 804w\"\n              sizes=\"(max-width: 804px) 100vw, 804px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/a4ecd5ed546d7222573f3eccc780cefc/8ff5a/image-20230514131809863.png 240w,\n/static/a4ecd5ed546d7222573f3eccc780cefc/e85cb/image-20230514131809863.png 480w,\n/static/a4ecd5ed546d7222573f3eccc780cefc/27b7a/image-20230514131809863.png 804w\"\n            sizes=\"(max-width: 804px) 100vw, 804px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/a4ecd5ed546d7222573f3eccc780cefc/27b7a/image-20230514131809863.png\"\n            alt=\"image-20230514131809863\"\n            title=\"image-20230514131809863\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>Because scripting works, remote attach feels easier than debugging directly inside Android Studio.</p>\n<h2 id=\"use-dlopen-on-library-functions-and-dynamically-analyze-them-as-an-elf-binary\" style=\"position:relative;\"><a href=\"#use-dlopen-on-library-functions-and-dynamically-analyze-them-as-an-elf-binary\" aria-label=\"use dlopen on library functions and dynamically analyze them as an elf binary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Use <code class=\"language-text\">dlopen</code> on Library Functions and Dynamically Analyze Them as an ELF Binary</h2>\n<p>In this challenge, unfortunately I could not get as far as recovering the Flag because I was unable to successfully connect the argument string passed from a C program to the <code class=\"language-text\">GetStringUTFChars</code> function on the native library side. Still, depending on the target, there are cases where loading native library functions with <code class=\"language-text\">dlopen</code> from your own program makes it easy to recover the Flag or debug the target.</p>\n<h3 id=\"identify-the-native-library-ndk-version\" style=\"position:relative;\"><a href=\"#identify-the-native-library-ndk-version\" aria-label=\"identify the native library ndk version permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Identify the Native Library NDK Version</h3>\n<p>To execute the native library after loading it with <code class=\"language-text\">dlopen</code>, you need to obtain libraries that satisfy the native library’s dependencies.</p>\n<p>The version of the native library included in the built APK can be identified by placing the native library file on the Android emulator and examining it with the <code class=\"language-text\">file</code> command.</p>\n<p>So I first placed <code class=\"language-text\">libhello-jni.so</code> on the emulator and checked its version with the <code class=\"language-text\">file</code> command as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Push solver.out to the emulator</span>\nadb push libhello-jni.so /data/local/tmp\n\n<span class=\"token comment\"># Identify the version with the file command</span>\nadb shell <span class=\"token function\">file</span> /data/local/tmp/libhello-jni.so</code></pre></div>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ad2208f27f4cead52576a694837b5ea9/e405b/image-20230514193110857.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 12.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAY0lEQVQI14WOSQoAIQwEPbtc3BBx//8fe0hA0dMcikqaJET03rHWAnmMgdYam7JSCpxz0FofjDFPfUOZoMU5J3LOfGBTa2WnlGCthfeej4cQjmOMD5SJPaiUOkgpD9TfH/7xAT+RSRujhQznAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/ad2208f27f4cead52576a694837b5ea9/8ac56/image-20230514193110857.webp 240w,\n/static/ad2208f27f4cead52576a694837b5ea9/d3be9/image-20230514193110857.webp 480w,\n/static/ad2208f27f4cead52576a694837b5ea9/e46b2/image-20230514193110857.webp 960w,\n/static/ad2208f27f4cead52576a694837b5ea9/f992d/image-20230514193110857.webp 1440w,\n/static/ad2208f27f4cead52576a694837b5ea9/9b2c8/image-20230514193110857.webp 1566w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/ad2208f27f4cead52576a694837b5ea9/8ff5a/image-20230514193110857.png 240w,\n/static/ad2208f27f4cead52576a694837b5ea9/e85cb/image-20230514193110857.png 480w,\n/static/ad2208f27f4cead52576a694837b5ea9/d9199/image-20230514193110857.png 960w,\n/static/ad2208f27f4cead52576a694837b5ea9/07a9c/image-20230514193110857.png 1440w,\n/static/ad2208f27f4cead52576a694837b5ea9/e405b/image-20230514193110857.png 1566w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/ad2208f27f4cead52576a694837b5ea9/d9199/image-20230514193110857.png\"\n            alt=\"image-20230514193110857\"\n            title=\"image-20230514193110857\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>This showed that the NDK version used to build this library was r25b, so I downloaded the NDK r25b files from <a href=\"https://dl.google.com/android/repository/android-ndk-r25b-windows.zip\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://dl.google.com/android/repository/android-ndk-r25b-windows.zip</a>.</p>\n<p>After extracting the downloaded file and expanding it with <code class=\"language-text\">ndk-build.cmd</code>, you can obtain prebuilt library files for each platform from under <code class=\"language-text\">android-ndk-r25b\\toolchains\\llvm\\prebuilt\\windows-x86_64\\sysroot\\usr\\lib</code>.</p>\n<p>This time I was using an x86 binary, so I copied the library files built under <code class=\"language-text\">i686-linux-android</code>.</p>\n<h3 id=\"create-an-executable\" style=\"position:relative;\"><a href=\"#create-an-executable\" aria-label=\"create an executable permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create an Executable</h3>\n<p>Once the required dependency libraries were ready, I next created a binary that calls the native library.</p>\n<p>I used the following code.</p>\n<p>The symbol for the <code class=\"language-text\">checkValid</code> function could be used exactly as identified in Ghidra.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;stdio.h></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;stdlib.h></span></span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span> <span class=\"token string\">&lt;dlfcn.h></span></span>\n\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">void</span> <span class=\"token operator\">*</span>handle<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">char</span> <span class=\"token operator\">*</span>error<span class=\"token punctuation\">;</span>\n\n    handle <span class=\"token operator\">=</span> <span class=\"token function\">dlopen</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"./libhello-jni.so\"</span><span class=\"token punctuation\">,</span> RTLD_LAZY<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>handle<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">fprintf</span><span class=\"token punctuation\">(</span><span class=\"token constant\">stderr</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"%s\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token function\">dlerror</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">exit</span><span class=\"token punctuation\">(</span>EXIT_FAILURE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token function\">dlerror</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>checkValid<span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">wchar_t</span> <span class=\"token operator\">*</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token function\">dlsym</span><span class=\"token punctuation\">(</span>handle<span class=\"token punctuation\">,</span> <span class=\"token string\">\"Java_com_example_hellojni_HelloJni_checkValid\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    error <span class=\"token operator\">=</span> <span class=\"token function\">dlerror</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>error <span class=\"token operator\">!=</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">fprintf</span><span class=\"token punctuation\">(</span><span class=\"token constant\">stderr</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"%s\\n\"</span><span class=\"token punctuation\">,</span> error<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">exit</span><span class=\"token punctuation\">(</span>EXIT_FAILURE<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"pid : %d\\n\"</span><span class=\"token punctuation\">,</span> <span class=\"token function\">getpid</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">puts</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"dlopen success\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"handle addr : %p\\n\"</span><span class=\"token punctuation\">,</span> handle<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token class-name\">wchar_t</span> text <span class=\"token operator\">=</span> L<span class=\"token string\">\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">int</span> i <span class=\"token operator\">=</span> <span class=\"token function\">checkValid</span><span class=\"token punctuation\">(</span>text<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Result : %d\\n\"</span><span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">dlclose</span><span class=\"token punctuation\">(</span>handle<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>After building this code with the following command, launch it with <code class=\"language-text\">gdb</code>.</p>\n<p>At runtime, place the compiled file, <code class=\"language-text\">libhello-jni.so</code>, and the library files copied earlier including <code class=\"language-text\">libandroid.so</code> all in the same directory.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Build as an x86 binary</span>\ngcc solver.c -m32 -o solver.out\n\n<span class=\"token comment\"># Add the current directory to the library path</span>\n<span class=\"token builtin class-name\">export</span> <span class=\"token assign-left variable\">LD_LIBRARY_PATH</span><span class=\"token operator\">=</span>.:<span class=\"token variable\">$LD_LIBRARY_PATH</span>\n\n<span class=\"token comment\"># Run the program with gdb</span>\ngdb ./solver.out</code></pre></div>\n<p>Running this shows that you can call the <code class=\"language-text\">checkValid</code> function implemented in the native library.</p>\n<p>Unfortunately, this time I could not successfully connect the argument string passed from the C program to the <code class=\"language-text\">GetStringUTFChars</code> function on the native library side, so I did not get as far as recovering the Flag. However, as shown below, I was still able to reach the Flag validation logic itself using <code class=\"language-text\">gdb</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/5fa4545a2b278f2fa737c01d1cec3cb4/248b0/image-20230514185015218.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 44.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABk0lEQVQoz3WSyW7jMBAFdZuJRVGkSO2yFkqCFySeOJmD///Halq2DwMYORQeSJC9vO7I7j390uOLAuc8sdJC9tBYCYmg7+ziWDRGKfUjkZ08+bDi6w5le0xWkBc1RVGRVy1luanD+QxrDFrre9CfiHSb4dORphyo6xNNE8jbM00XWKYjbT9g5Y0pHX3fS4IS7z1Fnt81f+p2byRhVLY15/OZ0I8cw8I6z0xhJoSJ07wQlkDqLMZlZEaqtPb+cWtvs+Sl5TBN3G43jqcjX9/fXK9XLpcP/lwucv7i+nnFZRlV6ZmOHeNhT3/oMLUmyWN08aQSb420nItXy7rS7XupamGaZvphYRgCYV4ZQ8AWjrLNmUNLGBuW0FHmWireSbIYZ2O8qNYScJhWfqUrOtvjyoU0q4WO1GxTd6TWsNPSnvD2Fgu7O48hqBei949Pfru/5PWBpj+T+YaqbsQrJ6uTohJBbZ6JGkViEpIkeXoW/6cPoqYb2ZkJbRt8FcT8Bm1KlJadFJR2TxXsFlChE/0cyutO/gPopt9rRUIHoAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/5fa4545a2b278f2fa737c01d1cec3cb4/8ac56/image-20230514185015218.webp 240w,\n/static/5fa4545a2b278f2fa737c01d1cec3cb4/d3be9/image-20230514185015218.webp 480w,\n/static/5fa4545a2b278f2fa737c01d1cec3cb4/e46b2/image-20230514185015218.webp 960w,\n/static/5fa4545a2b278f2fa737c01d1cec3cb4/c5455/image-20230514185015218.webp 1316w\"\n              sizes=\"(max-width: 960px) 100vw, 960px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/5fa4545a2b278f2fa737c01d1cec3cb4/8ff5a/image-20230514185015218.png 240w,\n/static/5fa4545a2b278f2fa737c01d1cec3cb4/e85cb/image-20230514185015218.png 480w,\n/static/5fa4545a2b278f2fa737c01d1cec3cb4/d9199/image-20230514185015218.png 960w,\n/static/5fa4545a2b278f2fa737c01d1cec3cb4/248b0/image-20230514185015218.png 1316w\"\n            sizes=\"(max-width: 960px) 100vw, 960px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/5fa4545a2b278f2fa737c01d1cec3cb4/d9199/image-20230514185015218.png\"\n            alt=\"image-20230514185015218\"\n            title=\"image-20230514185015218\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>In particular, native library functions that do not require arguments from the app can be debugged easily with this method.</p>\n<h2 id=\"perform-dynamic-analysis-with-frida-hooks\" style=\"position:relative;\"><a href=\"#perform-dynamic-analysis-with-frida-hooks\" aria-label=\"perform dynamic analysis with frida hooks permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Perform Dynamic Analysis with Frida Hooks</h2>\n<p>Frida is a tool that lets you analyze native apps on a wide range of platforms such as Windows, macOS, Linux, iOS, and Android by injecting JavaScript code.</p>\n<p>According to the documentation, Frida’s core is implemented in C, and by injecting the <a href=\"https://bellard.org/quickjs/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">QuickJS Javascript Engine</a> into the target black-box process, it can hook functions and call arbitrary functions inside the process.</p>\n<p>Reference: <a href=\"https://frida.re/docs/home/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Welcome | Frida • A world-class dynamic instrumentation toolkit</a></p>\n<h3 id=\"set-up-frida\" style=\"position:relative;\"><a href=\"#set-up-frida\" aria-label=\"set up frida permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up Frida</h3>\n<p>Let us quickly set up Frida so we can analyze the Android app.</p>\n<p>First, install <code class=\"language-text\">frida-tools</code> on the host machine with <code class=\"language-text\">pip</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Install frida-tools on a Windows machine</span>\npython3.exe -m pip <span class=\"token function\">install</span> frida-tools</code></pre></div>\n<p>When I installed Frida in my environment, the Frida executable ended up under:</p>\n<p><code class=\"language-text\">%USERPROFILE%\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\\LocalCache\\local-packages\\Python310\\Scripts</code></p>\n<p>So I placed the downloaded files in an appropriate folder and added that folder to PATH.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Check that Frida is available</span>\nfrida.exe --version\n<span class=\"token operator\">></span>\n<span class=\"token number\">16.0</span>.19</code></pre></div>\n<p>Now that Frida is installed on the host machine, the next step is to configure <code class=\"language-text\">frida-server</code> on the Android environment running on the emulator.</p>\n<p>From the Frida releases page below, download and extract a <code class=\"language-text\">frida-server</code> with the same version as the Frida installation on the host machine that we confirmed earlier.</p>\n<p>Reference: <a href=\"https://github.com/frida/frida/releases\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Releases · frida/frida</a></p>\n<p>This time, because I was running it on an emulator, I downloaded <code class=\"language-text\">frida-server-16.0.19-android-x86.xz</code>.</p>\n<p>If you install it on a physical Android device, choose the ARM version instead.</p>\n<p>The APK file and <code class=\"language-text\">frida-server</code> can be deployed to the emulator in roughly the same way as the <code class=\"language-text\">lldb-server</code> mentioned earlier, but note that this time root access is required.</p>\n<p>If <code class=\"language-text\">adb root</code> outputs the error <code class=\"language-text\">adbd cannot run as root in production builds</code>, then to avoid that problem you need to choose an emulator OS whose [Play Store] field is blank.</p>\n<p>Also, if Android 12 or later is configured by default, the OS platform version becomes x86_64, so be careful.</p>\n<p>In that case, you can start <code class=\"language-text\">frida-server</code> by using <code class=\"language-text\">frida-server-16.0.19-android-x86_64</code>.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 619px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/c1a46618caa70a0d20b35769cc45e7d9/e628c/image-20230514222221793.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 106.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAAAsTAAALEwEAmpwYAAACsElEQVQ4y41VSW4UQRDsTzFmeq2q3qfH07OY5cAYIY0FAoFPPuEvIPmEOHCBP/EOnhBkZHe1LS/Yh1DWkhUZmZXVHcRVjsgY5GWNsmlRtwtUgszmSDKL1AjSDM7lWCwWaNv/I+j7Hl8vL/H29BR1XaPrOgUPe/h527aPIvjy+Rx//gJXv3/h1ckJzs7OsN+f4nA4KPb7N+roAz2GYLPZ4NvVdxzef8BSFjin6vV6PY2fSqaENi8wD0OkmYGTsZVa2RvWFaXUt3oaxDdIpfiL4x71YimX0aFqpFbLlc4T4xAmGcLUiL2J7J7xYIOYNymkmSsUed2glNsq6hZWohqJmolSwuSlwhblOC50n5ZrmWQlhAZFVYvkEkmaIq8aVUzCQtqItlv1imrRoemOdY1Z0I9ZDRl2KihIyx7bTz/Qf/yJ5t0VbCWHZNMWlaZM9ZZqJLrLS+3XVLLypPRrJQh9mG0QuxbN6wsULy9gt+dIXSUXUelmNEJJrUMm2dAmSappsjzcc5IhLcsQRAlfgRHnGGH0XDacqqA6khJ8NYaE8mpoE3k5VESVJKJlulQbRKmVS1hK7Vo57HSDdWGRPWFqrtXloowKc1Hl68aOILGmHElL8CLIzrGmoArtRMhU2GN81+zP2wp5fiL0bUMyT1iIAyNzPpAOfebbi+sMUjbDR8QTTwq5wC8M68cDnHt1BNVTtaoRywBUxVQ15XZIfSLkgJ8qjnkZmoLYYc9c15LlGEszKXSDQn+JAQfdao3VZqdY715oZPZYvz3BarsTu8PxeqOEyRiI1oy9x8amn7aNtsX47Dx8Q99ej8csvA3HutPfn9M+vAN1vG9NyG7YeJp7n0w+X3IRZvzMPwS2SRQn2ouPIcjkf8JD83mIMIzuYD6PEAtZJY08mx1h9mwmOHoQ/wB9/PYqPNwYWgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/c1a46618caa70a0d20b35769cc45e7d9/8ac56/image-20230514222221793.webp 240w,\n/static/c1a46618caa70a0d20b35769cc45e7d9/d3be9/image-20230514222221793.webp 480w,\n/static/c1a46618caa70a0d20b35769cc45e7d9/3aa79/image-20230514222221793.webp 619w\"\n              sizes=\"(max-width: 619px) 100vw, 619px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/c1a46618caa70a0d20b35769cc45e7d9/8ff5a/image-20230514222221793.png 240w,\n/static/c1a46618caa70a0d20b35769cc45e7d9/e85cb/image-20230514222221793.png 480w,\n/static/c1a46618caa70a0d20b35769cc45e7d9/e628c/image-20230514222221793.png 619w\"\n            sizes=\"(max-width: 619px) 100vw, 619px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/c1a46618caa70a0d20b35769cc45e7d9/e628c/image-20230514222221793.png\"\n            alt=\"image-20230514222221793\"\n            title=\"image-20230514222221793\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<p>If you are using an emulator whose [Play Store] field is blank, <code class=\"language-text\">adb root</code> works correctly, so you can start <code class=\"language-text\">frida-server</code> with the following commands.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\"># Enable adb root</span>\nadb root\n\n<span class=\"token comment\"># Install the APK on the emulator</span>\nadb <span class=\"token function\">install</span> app-debug.apk\n\n<span class=\"token comment\"># Rename the extracted file</span>\n<span class=\"token comment\"># Use frida-server-16.0.19-android-x86_64 for the x86_64 platform</span>\nren frida-server-16.0.19-android-x86 frida-server\n\n<span class=\"token comment\"># Push frida-server to the emulator and grant execute permission</span>\nadb push frida-server /data/local/tmp\nadb shell <span class=\"token function\">chmod</span> +x /data/local/tmp/frida-server\n\n<span class=\"token comment\"># Start frida-server</span>\nadb shell /data/local/tmp/frida-server</code></pre></div>\n<h3 id=\"debug-with-a-frida-hook\" style=\"position:relative;\"><a href=\"#debug-with-a-frida-hook\" aria-label=\"debug with a frida hook permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Debug with a Frida Hook</h3>\n<p>Once <code class=\"language-text\">frida-server</code> is running on the emulator side, it is finally time to start analyzing the app.</p>\n<p>The actual operation of analyzing with a Frida hook is very simple.</p>\n<p>Basically, the idea is to attach from a Python script to the <code class=\"language-text\">frida-server</code> running on the emulator and let the embedded JavaScript code in the script do the processing.</p>\n<p>Let us first look at the first half.</p>\n<p>Up to this point, the script identifies the <code class=\"language-text\">frida-server</code> instance the Python script should attach to.</p>\n<p><code class=\"language-text\">DEVICE_NAME</code> can be identified with the <code class=\"language-text\">adb devices</code> command.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> frida\n<span class=\"token keyword\">import</span> sys\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">on_message</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">,</span> data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">if</span> message<span class=\"token punctuation\">[</span><span class=\"token string\">'type'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token string\">'send'</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"[*] {0}\"</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">[</span><span class=\"token string\">'payload'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\"># Connect to the emulator</span>\nDEVICE_NAME <span class=\"token operator\">=</span> <span class=\"token string\">\"emulator-5554\"</span>\nAPK_PROCESS_NAME <span class=\"token operator\">=</span> <span class=\"token string\">\"HelloJni\"</span>\nprocess <span class=\"token operator\">=</span> frida<span class=\"token punctuation\">.</span>get_device_manager<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>get_device<span class=\"token punctuation\">(</span>DEVICE_NAME<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>attach<span class=\"token punctuation\">(</span>APK_PROCESS_NAME<span class=\"token punctuation\">)</span></code></pre></div>\n<p>Next comes the main JavaScript portion. The basic idea is the same as the dynamic analysis performed with the debugger so far: recover the Flag.</p>\n<p>First, <code class=\"language-text\">Module.findBaseAddress(module_name)</code> obtains the image base address from the native library filename.</p>\n<p>Then it adds the offset of the Flag validation code already identified in Ghidra to produce <code class=\"language-text\">target_address</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">var</span> module_name <span class=\"token operator\">=</span> <span class=\"token string\">\"libhello-jni.so\"</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// var sym_name = \"Java_com_example_hellojni_HelloJni_checkValid\";</span>\n\n<span class=\"token keyword\">var</span> base_addr <span class=\"token operator\">=</span> Module<span class=\"token punctuation\">.</span><span class=\"token function\">findBaseAddress</span><span class=\"token punctuation\">(</span>module_name<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">var</span> target_offset <span class=\"token operator\">=</span> <span class=\"token number\">0x1a20c</span>\n<span class=\"token keyword\">var</span> target_address <span class=\"token operator\">=</span> base_addr<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>target_offset<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">var</span> flag <span class=\"token operator\">=</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Next, <code class=\"language-text\">Interceptor.attach</code> uses <code class=\"language-text\">onEnter:</code> to define what should happen when the app reaches <code class=\"language-text\">target_address</code>. (It is like a breakpoint.)</p>\n<p>As identified through the analysis so far, the operations needed to recover the Flag were as follows.</p>\n<ol>\n<li>Enter a 38-character string in the app and press the [Check Flag] button.</li>\n<li>At offset 0x1a20c in the native library, obtain one Flag character from the value stored in <code class=\"language-text\">ecx</code>.</li>\n<li>Copy the value of <code class=\"language-text\">ecx</code> to <code class=\"language-text\">eax</code> and continue processing.</li>\n</ol>\n<p>In the following code, when execution reaches <code class=\"language-text\">target_address</code>, <code class=\"language-text\">this.context.ecx</code> is used to read the value in the <code class=\"language-text\">ecx</code> register and tamper with the <code class=\"language-text\">eax</code> register.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">Interceptor<span class=\"token punctuation\">.</span><span class=\"token function\">attach</span><span class=\"token punctuation\">(</span>target_address<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function-variable function\">onEnter</span><span class=\"token operator\">:</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">args</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// console.log(\"eax: \" + this.context.eax);</span>\n    <span class=\"token comment\">// console.log(\"ecx: \" + this.context.ecx);</span>\n\n    <span class=\"token comment\">// Retrieve a Flag character</span>\n    flag <span class=\"token operator\">=</span> flag <span class=\"token operator\">+</span> String<span class=\"token punctuation\">.</span><span class=\"token function\">fromCharCode</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>context<span class=\"token punctuation\">.</span>ecx<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>flag<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token comment\">// Rewrite the register value</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>context<span class=\"token punctuation\">.</span>eax <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>context<span class=\"token punctuation\">.</span>ecx<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token function-variable function\">onLeave</span><span class=\"token operator\">:</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">retval</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Do nothing</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The final code I implemented looked like this.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> frida\n<span class=\"token keyword\">import</span> sys\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">on_message</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">,</span> data<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">if</span> message<span class=\"token punctuation\">[</span><span class=\"token string\">'type'</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token string\">'send'</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"[*] {0}\"</span><span class=\"token punctuation\">.</span><span class=\"token builtin\">format</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">[</span><span class=\"token string\">'payload'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\"># Connect to the emulator</span>\nDEVICE_NAME <span class=\"token operator\">=</span> <span class=\"token string\">\"emulator-5554\"</span>\nAPK_PROCESS_NAME <span class=\"token operator\">=</span> <span class=\"token string\">\"HelloJni\"</span>\nprocess <span class=\"token operator\">=</span> frida<span class=\"token punctuation\">.</span>get_device_manager<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>get_device<span class=\"token punctuation\">(</span>DEVICE_NAME<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>attach<span class=\"token punctuation\">(</span>APK_PROCESS_NAME<span class=\"token punctuation\">)</span>\n\njscode <span class=\"token operator\">=</span> <span class=\"token triple-quoted-string string\">\"\"\"\nvar module_name = \"libhello-jni.so\";\nvar sym_name = \"Java_com_example_hellojni_HelloJni_checkValid\";\n\nvar base_addr = Module.findBaseAddress(module_name);\nvar target_offset = 0x1a20c\nvar target_address = base_addr.add(target_offset);\n\nvar flag = \"\";\n\n// console.log(base_addr);\n// console.log(target_address);\n\nInterceptor.attach(target_address, {\n  onEnter: function(args) {\n    // console.log(\"eax: \" + this.context.eax);\n    // console.log(\"ecx: \" + this.context.ecx);\n\n    // Retrieve a Flag character\n    flag = flag + String.fromCharCode(this.context.ecx);\n    console.log(flag);\n\n    // Rewrite the register value\n    this.context.eax = this.context.ecx;\n  },\n  onLeave: function(retval) {\n    // Do nothing\n  }\n});\n\"\"\"</span>\n\nscript <span class=\"token operator\">=</span> process<span class=\"token punctuation\">.</span>create_script<span class=\"token punctuation\">(</span>jscode<span class=\"token punctuation\">)</span>\nscript<span class=\"token punctuation\">.</span>on<span class=\"token punctuation\">(</span><span class=\"token string\">\"message\"</span><span class=\"token punctuation\">,</span> on_message<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"[*] Running APK\"</span><span class=\"token punctuation\">)</span>\n\nscript<span class=\"token punctuation\">.</span>load<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\nsys<span class=\"token punctuation\">.</span>stdin<span class=\"token punctuation\">.</span>read<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>By running this from the command prompt, I was able to recover the Flag as shown below.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 543px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/801b33cae8ba7111dd7c4867c4c8ec75/29579/image-20230514234120616.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 117.08333333333334%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAYAAAALHW+jAAAACXBIWXMAAAsTAAALEwEAmpwYAAABe0lEQVQ4y62V2Y6CQBBF+xEFwRi3sERlUVEB9QHw/z+sJreS6iDjRJZ5uCGxi8OtpUu13+8pz3Otx+NBYRjSbrdjHQ4HQgzkeR5tt1t9hrggCGixWNB0OiXLskghYL1ecyC02WxoNpvRZDLhoG8yTZMFGJ4qjmM+MAyDIZAE9JG8o5Ci7/sMgrN2QBP+6be2VFEUdD6fB7n6CLzf79yIZmHHwNkhoOjYvzgEEOOSpinN5/PRLhkI3W43njMBjnKYZRmdTicWZnIMVDsE7Hq98hMzOTRt7rKMzuVyoaqqyHGccTVEU+AM0Lqu32rZF6yBgEFwiEXw6YZ0AmKokbak/Hq96Hg88hYZ0py3lDGLcIiFgQYNqaVuigBRQwDxG2qJpdEnbX31ABOHSZKQOLdtu9OW+bPLZVlSFEV8c/Ah13V71VIPNmDNGuL2PJ/PX6vtm8u3wW7WEECcQcvlsvNcKvlzaqcsQJxho3d1qeSl9tightIwfGC1WnVqyg+dMjwgbCyI4AAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n          <source\n              srcset=\"/static/801b33cae8ba7111dd7c4867c4c8ec75/8ac56/image-20230514234120616.webp 240w,\n/static/801b33cae8ba7111dd7c4867c4c8ec75/d3be9/image-20230514234120616.webp 480w,\n/static/801b33cae8ba7111dd7c4867c4c8ec75/4b567/image-20230514234120616.webp 543w\"\n              sizes=\"(max-width: 543px) 100vw, 543px\"\n              type=\"image/webp\"\n            />\n          <source\n            srcset=\"/static/801b33cae8ba7111dd7c4867c4c8ec75/8ff5a/image-20230514234120616.png 240w,\n/static/801b33cae8ba7111dd7c4867c4c8ec75/e85cb/image-20230514234120616.png 480w,\n/static/801b33cae8ba7111dd7c4867c4c8ec75/29579/image-20230514234120616.png 543w\"\n            sizes=\"(max-width: 543px) 100vw, 543px\"\n            type=\"image/png\"\n          />\n          <img\n            class=\"gatsby-resp-image-image\"\n            src=\"/static/801b33cae8ba7111dd7c4867c4c8ec75/29579/image-20230514234120616.png\"\n            alt=\"image-20230514234120616\"\n            title=\"image-20230514234120616\"\n            loading=\"lazy\"\n            style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n          />\n        </picture>\n  </a>\n    </span></p>\n<h2 id=\"bonus-perform-dynamic-analysis-with-symbolic-execution\" style=\"position:relative;\"><a href=\"#bonus-perform-dynamic-analysis-with-symbolic-execution\" aria-label=\"bonus perform dynamic analysis with symbolic execution permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Bonus: Perform Dynamic Analysis with Symbolic Execution</h2>\n<p>When I read angr’s official documentation, it appeared to mention support for symbolic execution of Android apps that use native libraries.</p>\n<p>Reference: <a href=\"https://angr.io/blog/java_angr/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">experimental java, android, and jni support in angr</a></p>\n<p>Looking at the page above, it includes an example of recovering a Flag with angr from an Android app analysis challenge that actually appeared in a CTF.</p>\n<p>I did not try using angr for this problem, but if I feel like it later I may add an update.</p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>This time I tried four (+1) approaches for dynamically analyzing an Android app challenge from a CTF.</p>\n<p>In particular, Frida hooking was a technique I had been meaning to try someday and had left untouched for a long time, but once I actually used it, it felt remarkably easy and extremely powerful.</p>\n<p>It seems likely to be useful beyond Android analysis as well, so I plan to keep experimenting with it in various contexts.</p>","fields":{"slug":"/ctf-android-apk-debug-tutorial-en","tagSlugs":["/tag/ctf-en/","/tag/rev-en/","/tag/android-en/","/tag/english/"]},"frontmatter":{"date":"2023-05-15","description":"I summarized five ways to perform dynamic analysis on Android apps.","tags":["CTF (en)","Rev (en)","Android (en)","English"],"title":"5 Techniques I Learned for Tackling Android App Reverse Engineering Challenges","socialImage":{"publicURL":"/static/8ac192ff1e4e680fa0e15e5f9f5b8939/ctf-android-apk-debug-tutorial.png"}}}},"pageContext":{"slug":"/ctf-android-apk-debug-tutorial-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}