<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>海狸大師部落格</title><link>https://blog.yenslife.top/</link><description>Recent content on 海狸大師部落格</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Thu, 04 Dec 2025 15:52:44 +0800</lastBuildDate><atom:link href="https://blog.yenslife.top/index.xml" rel="self" type="application/rss+xml"/><item><title>Picoctf Pico Bank Writeup</title><link>https://blog.yenslife.top/post/picoctf-pico-bank-writeup/</link><pubDate>Thu, 04 Dec 2025 15:52:44 +0800</pubDate><guid>https://blog.yenslife.top/post/picoctf-pico-bank-writeup/</guid><description>&lt;img src="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/cover.png" alt="Featured image of post Picoctf Pico Bank Writeup" />&lt;h2 id="前言">前言
&lt;/h2>&lt;p>這是一題出現在 picoMini by CMU-Africa 的題目，因為只有 43% 的人喜歡，解出來的人也只有 322 個，我覺得很有意思所以寫了這個 write-up。&lt;/p>
&lt;p>題目連結：&lt;a class="link" href="https://play.picoctf.org/practice/challenge/529?originalEvent=77&amp;amp;page=1" target="_blank" rel="noopener"
>Pico Bank&lt;/a>&lt;/p>
&lt;p>題目會給一個 instance，在瀏覽器開啟這個連結可以看到一個叫 Pico Bank 的網頁，你可以在這個網頁找到下載 &lt;code>pico-bank.apk&lt;/code> 檔案的連結。除此之外，題目的提示有提到一個叫做 johnson 的人，這是很重要的線索。題目也提示了 Flag 會出現在兩個地方，一個是 transaction 的特別數字；另一個則是發送 otp 認證的方式。&lt;/p>
&lt;p>&lt;img src="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/pico-bank-web.png"
width="3404"
height="2042"
srcset="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/pico-bank-web_hu077029bff256a98ed681ea919de6aaa8_1685743_480x0_resize_box_3.png 480w, https://blog.yenslife.top/post/picoctf-pico-bank-writeup/pico-bank-web_hu077029bff256a98ed681ea919de6aaa8_1685743_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="Pico Bank 網頁"
class="gallery-image"
data-flex-grow="166"
data-flex-basis="400px"
>&lt;/p>
&lt;h2 id="解法">解法
&lt;/h2>&lt;h3 id="執行-apk">執行 apk
&lt;/h3>&lt;p>這邊我並沒有使用 Android Studio 等本地虛擬機 (因為我的硬碟快爆了哈哈哈)，而是一個可以線上使用虛擬機的網站： &lt;a class="link" href="https://appetize.io/" target="_blank" rel="noopener"
>https://appetize.io/&lt;/a> 。他唯一的缺點就是若超過 3 分鐘沒有和虛擬機互動，該 Session 就會被關掉，但對於免費仔來說已經很夠用了。&lt;/p>
&lt;p>建立新的專案然後把 apk 檔案放進去，就會遇到第一個關卡 &amp;ndash;&amp;gt; 找出帳號密碼&lt;/p>
&lt;p>&lt;img src="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/login-page.png"
width="3392"
height="1852"
srcset="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/login-page_hu77f268bd4650d35af2671966ff3513b5_442929_480x0_resize_box_3.png 480w, https://blog.yenslife.top/post/picoctf-pico-bank-writeup/login-page_hu77f268bd4650d35af2671966ff3513b5_442929_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="登入畫面，記得用 Debug 模式來啟動才看得到 App 的 Log"
class="gallery-image"
data-flex-grow="183"
data-flex-basis="439px"
>&lt;/p>
&lt;h3 id="反編譯-pico-bankapk">反編譯 pico-bank.apk
&lt;/h3>&lt;p>這邊我先用 &lt;a class="link" href="https://apktool.org/" target="_blank" rel="noopener"
>&lt;code>apktool&lt;/code>&lt;/a> 工具來進行反編譯，也可以直接用 &lt;a class="link" href="https://github.com/skylot/jadx" target="_blank" rel="noopener"
>jadx-gui&lt;/a> 來看 &lt;code>.apk&lt;/code> 檔案的 Java source。apktool 的輸出語言是 smali，你可以修改內容重新編譯 (像是把帳號密碼改成你要的之類的)；而 jadx 則是嘗試將 .dex 還原成 Java 但有時候也會怪怪的，看情況使用吧！我是都第一次用所以就都下載來玩了&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ apktool d pico-bank.apk
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Using Apktool 2.12.1 on pico-bank.apk with &lt;span class="m">8&lt;/span> threads
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Baksmaling classes.dex...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Loading resource table...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Baksmaling classes3.dex...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Baksmaling classes2.dex...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Decoding file-resources...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Loading resource table from file: /Users/mac/Library/apktool/framework/1.apk
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Decoding values */* XMLs...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Decoding AndroidManifest.xml with resources...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Copying original files...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">I: Copying unknown files...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;img src="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/jadx-gui.png"
width="2624"
height="1646"
srcset="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/jadx-gui_hu1a670e9ed67977453e6c6916a32c01e2_1063983_480x0_resize_box_3.png 480w, https://blog.yenslife.top/post/picoctf-pico-bank-writeup/jadx-gui_hu1a670e9ed67977453e6c6916a32c01e2_1063983_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="利用 jadx 工具來將 apk 反編譯回 Java 程式碼"
class="gallery-image"
data-flex-grow="159"
data-flex-basis="382px"
>&lt;/p>
&lt;p>觀察 &lt;code>pico-bank&lt;/code> 目錄底下的內容，用 VSCode 或者 Telescope 等能夠搜尋目錄檔案內容的工具查詢 &amp;ldquo;johnson&amp;rdquo;，會發現在 &lt;code>pico-bank/smali_classes3/com/example/picobank/Login$1.smali&lt;/code> 這個檔案有以下線索，其中就包含 username 和 password 寫死的值，分別為 &lt;code>johnson&lt;/code> 和 &lt;code>tricky1990&lt;/code>。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-asm" data-lang="asm">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># virtual methods
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="na">.method&lt;/span> &lt;span class="no">public&lt;/span> &lt;span class="no">onClick&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="no">Landroid&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">view&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">View&lt;/span>&lt;span class="c1">;)V
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="na">.locals&lt;/span> &lt;span class="mi">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.param&lt;/span> &lt;span class="no">p1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;v&amp;#34;&lt;/span> &lt;span class="c1"># Landroid/view/View;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.line&lt;/span> &lt;span class="mi">39&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">iget-object&lt;/span> &lt;span class="no">v0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">p0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login$1&lt;/span>&lt;span class="c1">;-&amp;gt;this$0:Lcom/example/picobank/Login;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-static&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v0&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login&lt;/span>&lt;span class="c1">;-&amp;gt;access$000(Lcom/example/picobank/Login;)Landroid/widget/EditText;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">move-result-object&lt;/span> &lt;span class="no">v0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-virtual&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v0&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Landroid&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">widget&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">EditText&lt;/span>&lt;span class="c1">;-&amp;gt;getText()Landroid/text/Editable;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">move-result-object&lt;/span> &lt;span class="no">v0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-virtual&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v0&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Ljava&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">lang&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Object&lt;/span>&lt;span class="c1">;-&amp;gt;toString()Ljava/lang/String;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">move-result-object&lt;/span> &lt;span class="no">v0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.line&lt;/span> &lt;span class="mi">40&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.local&lt;/span> &lt;span class="no">v0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;username&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="no">Ljava&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">lang&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">String&lt;/span>&lt;span class="c1">;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nf">iget-object&lt;/span> &lt;span class="no">v1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">p0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login$1&lt;/span>&lt;span class="c1">;-&amp;gt;this$0:Lcom/example/picobank/Login;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-static&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v1&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login&lt;/span>&lt;span class="c1">;-&amp;gt;access$100(Lcom/example/picobank/Login;)Landroid/widget/EditText;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">move-result-object&lt;/span> &lt;span class="no">v1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-virtual&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v1&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Landroid&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">widget&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">EditText&lt;/span>&lt;span class="c1">;-&amp;gt;getText()Landroid/text/Editable;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">move-result-object&lt;/span> &lt;span class="no">v1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-virtual&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v1&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Ljava&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">lang&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Object&lt;/span>&lt;span class="c1">;-&amp;gt;toString()Ljava/lang/String;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">move-result-object&lt;/span> &lt;span class="no">v1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.line&lt;/span> &lt;span class="mi">42&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.local&lt;/span> &lt;span class="no">v1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;password&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="no">Ljava&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">lang&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">String&lt;/span>&lt;span class="c1">;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nf">const-string&lt;/span> &lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="err">&amp;#34;&lt;/span>&lt;span class="no">johnson&lt;/span>&lt;span class="err">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-virtual&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">v0&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Ljava&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">lang&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">String&lt;/span>&lt;span class="c1">;-&amp;gt;equals(Ljava/lang/Object;)Z
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">move-result&lt;/span> &lt;span class="no">v2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">if-eqz&lt;/span> &lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">:&lt;/span>&lt;span class="no">cond_0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">const-string&lt;/span> &lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="err">&amp;#34;&lt;/span>&lt;span class="no">tricky1990&lt;/span>&lt;span class="err">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-virtual&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">v1&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Ljava&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">lang&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">String&lt;/span>&lt;span class="c1">;-&amp;gt;equals(Ljava/lang/Object;)Z
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">move-result&lt;/span> &lt;span class="no">v2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">if-eqz&lt;/span> &lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">:&lt;/span>&lt;span class="no">cond_0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.line&lt;/span> &lt;span class="mi">44&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">new-instance&lt;/span> &lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Landroid&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">content&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Intent&lt;/span>&lt;span class="c1">;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">iget-object&lt;/span> &lt;span class="no">v3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">p0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login$1&lt;/span>&lt;span class="c1">;-&amp;gt;this$0:Lcom/example/picobank/Login;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">const-class&lt;/span> &lt;span class="no">v4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">OTP&lt;/span>&lt;span class="c1">;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-direct&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">v3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">v4&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Landroid&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">content&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Intent&lt;/span>&lt;span class="c1">;-&amp;gt;&amp;lt;init&amp;gt;(Landroid/content/Context;Ljava/lang/Class;)V
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.line&lt;/span> &lt;span class="mi">45&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.local&lt;/span> &lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;intent&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="no">Landroid&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">content&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Intent&lt;/span>&lt;span class="c1">;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nf">iget-object&lt;/span> &lt;span class="no">v3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">p0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login$1&lt;/span>&lt;span class="c1">;-&amp;gt;this$0:Lcom/example/picobank/Login;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-virtual&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">v2&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login&lt;/span>&lt;span class="c1">;-&amp;gt;startActivity(Landroid/content/Intent;)V
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.line&lt;/span> &lt;span class="mi">46&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">iget-object&lt;/span> &lt;span class="no">v3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">p0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login$1&lt;/span>&lt;span class="c1">;-&amp;gt;this$0:Lcom/example/picobank/Login;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-virtual&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v3&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login&lt;/span>&lt;span class="c1">;-&amp;gt;finish()V
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.line&lt;/span> &lt;span class="mi">47&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.end&lt;/span> &lt;span class="no">local&lt;/span> &lt;span class="no">v2&lt;/span> &lt;span class="c1"># &amp;#34;intent&amp;#34;:Landroid/content/Intent;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nf">goto&lt;/span> &lt;span class="p">:&lt;/span>&lt;span class="no">goto_0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.line&lt;/span> &lt;span class="mi">49&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">:&lt;/span>&lt;span class="nf">cond_0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">iget-object&lt;/span> &lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">p0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Login$1&lt;/span>&lt;span class="c1">;-&amp;gt;this$0:Lcom/example/picobank/Login;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">const-string&lt;/span> &lt;span class="no">v3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="err">&amp;#34;&lt;/span>&lt;span class="no">Incorrect&lt;/span> &lt;span class="no">credentials&lt;/span>&lt;span class="err">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">const&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="mi">4&lt;/span> &lt;span class="no">v4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0x0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-static&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">v3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">v4&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Landroid&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">widget&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Toast&lt;/span>&lt;span class="c1">;-&amp;gt;makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">move-result-object&lt;/span> &lt;span class="no">v2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">invoke-virtual&lt;/span> &lt;span class="err">{&lt;/span>&lt;span class="no">v2&lt;/span>&lt;span class="err">}&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Landroid&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">widget&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">Toast&lt;/span>&lt;span class="c1">;-&amp;gt;show()V
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">.line&lt;/span> &lt;span class="mi">51&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">:&lt;/span>&lt;span class="nf">goto_0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">return-void&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">.end&lt;/span> &lt;span class="no">method&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Android 的 APK 中包含 &lt;code>.dex&lt;/code> 檔 (Dalvik Executable)，是 Android 執行的 bytecode 格式。因為反組譯沒辦法直接變成 Java code，但還是可以變成人類可讀的 &lt;code>.smali&lt;/code>，一種類似組合語言的東東。&lt;/p>
&lt;p>那上面這段在幹嘛呢？利用 jadx 工具還原成 Java 的 &lt;code>Login.java&lt;/code> 會像以下這樣&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">protected&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">onCreate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Bundle&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">savedInstanceState&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">super&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">onCreate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">savedInstanceState&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">EdgeToEdge&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">enable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">setContentView&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">layout&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">activity_login&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">ViewCompat&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">setOnApplyWindowInsetsListener&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">findViewById&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">id&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">main&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">OnApplyWindowInsetsListener&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// from class: com.example.picobank.Login$$ExternalSyntheticLambda0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nd">@Override&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// androidx.core.view.OnApplyWindowInsetsListener&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">final&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">WindowInsetsCompat&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">onApplyWindowInsets&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">View&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">view&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">WindowInsetsCompat&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">windowInsetsCompat&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Login&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">lambda$onCreate$0&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">view&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">windowInsetsCompat&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">});&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">usernameEditText&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">EditText&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">findViewById&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">id&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">username&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">passwordEditText&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">EditText&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">findViewById&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">id&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">password&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">loginButton&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Button&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">findViewById&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">id&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">loginBtn&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">loginButton&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">setOnClickListener&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">View&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">OnClickListener&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// from class: com.example.picobank.Login.1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nd">@Override&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// android.view.View.OnClickListener&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">onClick&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">View&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">v&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">username&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Login&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">usernameEditText&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getText&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="na">toString&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">password&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Login&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">passwordEditText&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getText&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="na">toString&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;johnson&amp;#34;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">equals&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">username&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;amp;&amp;amp;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;tricky1990&amp;#34;&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">equals&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">password&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Intent&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">intent&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Intent&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Login&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Class&lt;/span>&lt;span class="o">&amp;lt;?&amp;gt;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">OTP&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">class&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Login&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">startActivity&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">intent&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Login&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">finish&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">return&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Toast&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">makeText&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Login&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;Incorrect credentials&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">0&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="na">show&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">});&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>回到 apptized，輸入帳號密碼，會發現這個 App 還要你輸入一個四碼的 otp (one time password) 碼&lt;/p>
&lt;p>&lt;img src="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/otp-page.png"
width="2416"
height="2000"
srcset="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/otp-page_hue9e80724ecbe1ec84ff6b48a39ec7456_863724_480x0_resize_box_3.png 480w, https://blog.yenslife.top/post/picoctf-pico-bank-writeup/otp-page_hue9e80724ecbe1ec84ff6b48a39ec7456_863724_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="除了帳號密碼外，還需要找到 otp 碼"
class="gallery-image"
data-flex-grow="120"
data-flex-basis="289px"
>&lt;/p>
&lt;p>回到剛剛的 &lt;code>.smali&lt;/code> 檔案，其中有一行是&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-asm" data-lang="asm">&lt;span class="line">&lt;span class="cl">&lt;span class="nf">const-class&lt;/span> &lt;span class="no">v4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="no">Lcom&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">example&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">picobank&lt;/span>&lt;span class="err">/&lt;/span>&lt;span class="no">OTP&lt;/span>&lt;span class="c1">;
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>藉著這個線索，我們可以觀察 &lt;code>pico-bank/smali_classes3/com/exmaple/picobank/OPT.java&lt;/code> 的檔案內容，發現有 &lt;code>verifyOtp&lt;/code> 這個方法。猜測這是用來檢查 otp 值，也就是 &lt;code>otp_value&lt;/code>。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">verifyOtp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">otp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">throws&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">JSONException&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endpoint&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;your server url/verify-otp&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">getResources&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="na">getString&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">string&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">otp_value&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="na">equals&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">otp&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Intent&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">intent&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Intent&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Class&lt;/span>&lt;span class="o">&amp;lt;?&amp;gt;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">MainActivity&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">class&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">startActivity&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">intent&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">finish&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">else&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Toast&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">makeText&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;Invalid OTP&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">0&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="na">show&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">JSONObject&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">postData&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">JSONObject&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">try&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">postData&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">put&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;otp&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">otp&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">catch&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">JSONException&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">e&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">printStackTrace&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">JsonObjectRequest&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">jsonObjectRequest&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">JsonObjectRequest&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">endpoint&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">postData&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Response&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">Listener&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">JSONObject&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// from class: com.example.picobank.OTP.2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nd">@Override&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// com.android.volley.Response.Listener&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">onResponse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">JSONObject&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kd">throws&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">JSONException&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">try&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kt">boolean&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">success&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getBoolean&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;success&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">if&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">success&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">flag&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getString&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;flag&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">String&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">hint&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">getString&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;hint&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Intent&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">intent2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Intent&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">OTP&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">Class&lt;/span>&lt;span class="o">&amp;lt;?&amp;gt;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">MainActivity&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">class&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">intent2&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">putExtra&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;flag&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">flag&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">intent2&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">putExtra&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;hint&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">hint&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">OTP&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">startActivity&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">intent2&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">OTP&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">finish&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">else&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">Toast&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">makeText&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">OTP&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">this&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;Invalid OTP&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">0&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="na">show&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">catch&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">JSONException&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">e2&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">e2&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">printStackTrace&lt;/span>&lt;span class="p">();&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">},&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Response&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">ErrorListener&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// from class: com.example.picobank.OTP.3&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nd">@Override&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">// com.android.volley.Response.ErrorListener&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="kd">public&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kt">void&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nf">onErrorResponse&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">VolleyError&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">error&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">});&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">requestQueue&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">jsonObjectRequest&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>全域搜尋 &lt;code>otp_value&lt;/code>，在 &lt;code>pico-bank/res/values/strings.xml&lt;/code> 找到以下 otp 的值&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-xml" data-lang="xml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">&amp;lt;string&lt;/span> &lt;span class="na">name=&lt;/span>&lt;span class="s">&amp;#34;otp_value&amp;#34;&lt;/span>&lt;span class="nt">&amp;gt;&lt;/span>9673&lt;span class="nt">&amp;lt;/string&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>回到 apptized 來輸入 9673 看看！成功登入了！題目有提示我們可以去觀察 Pico Bank 是怎麼發送驗證 otp 請求的、以及交易哪邊怪怪的&lt;/p>
&lt;p>&lt;img src="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/otp-pass.png"
width="1590"
height="926"
srcset="https://blog.yenslife.top/post/picoctf-pico-bank-writeup/otp-pass_hu8bb097101550b64c0490e1415ab2f311_379157_480x0_resize_box_3.png 480w, https://blog.yenslife.top/post/picoctf-pico-bank-writeup/otp-pass_hu8bb097101550b64c0490e1415ab2f311_379157_1024x0_resize_box_3.png 1024w"
loading="lazy"
alt="可以看到右側 debug logs 出現 /verify_otp 這個請求"
class="gallery-image"
data-flex-grow="171"
data-flex-basis="412px"
>&lt;/p>
&lt;p>首先，誰的交易系統價格會是由 0 和 1 組成！很明顯有鬼；另一方面則是這個 /verify_otp 似乎是一個 post 請求，而且他並沒有寫正確的 url 而是「your server url」這個奇妙的 url 在 &lt;code>OPT.smali&lt;/code> 這個檔案中。&lt;/p>
&lt;h3 id="向-picoctf-的-instance-發送請求">向 PicoCTF 的 instance 發送請求
&lt;/h3>&lt;p>順著這個套路，我們向剛剛在 PicoCTF 啟動的 instance 發送請求，就找到它ㄌ！&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl -X POST &lt;span class="s1">&amp;#39;http://amiable-citadel.picoctf.net:58064/verify-otp&amp;#39;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span>-H &lt;span class="s1">&amp;#39;Content-Type: application/json; charset=utf-8&amp;#39;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span>-H &lt;span class="s1">&amp;#39;Accept: application/json&amp;#39;&lt;/span> &lt;span class="se">\
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="se">&lt;/span>-d &lt;span class="s1">&amp;#39;{&amp;#34;otp&amp;#34;: &amp;#34;9673&amp;#34;}&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">{&lt;/span>&lt;span class="s2">&amp;#34;success&amp;#34;&lt;/span>:true,&lt;span class="s2">&amp;#34;message&amp;#34;&lt;/span>:&lt;span class="s2">&amp;#34;OTP verified successfully&amp;#34;&lt;/span>,&lt;span class="s2">&amp;#34;flag&amp;#34;&lt;/span>:&lt;span class="s2">&amp;#34;s3cur3d_m0b1l3_l0g1n_c0085c75}&amp;#34;&lt;/span>,&lt;span class="s2">&amp;#34;hint&amp;#34;&lt;/span>:&lt;span class="s2">&amp;#34;The other part of the flag is hidden in the app&amp;#34;&lt;/span>&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>不過是一半的而已，我們還需要找到前半部&lt;/p>
&lt;h3 id="解讀-transaction-的奇妙數字">解讀 transaction 的奇妙數字
&lt;/h3>&lt;p>在 MainActivity 中可以看到這些價錢都是由 0 和 1 組成的，我們來寫一個簡單的 Python 腳本處理他們&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-java" data-lang="java">&lt;span class="line">&lt;span class="cl">&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Grocery Shopping&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-21&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1110000&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Electricity Bill&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-20&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1101001&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Salary&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-18&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1100011&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Internet Bill&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-17&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1101111&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Freelance Payment&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-16&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1000011&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Dining Out&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-15&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1010100&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Gym Membership&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-14&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1000110&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Stocks Dividend&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-13&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1111011&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Car Maintenance&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-12&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 110001&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Gift Received&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-11&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1011111&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Rent&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-10&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1101100&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Water Bill&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-09&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 110001&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Interest Earned&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-08&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 110011&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Medical Expenses&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-07&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1100100&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Transport&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-06&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1011111&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Bonus&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-05&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 110100&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Subscription Service&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-04&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1100010&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Freelance Payment&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-03&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 110000&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Entertainment&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-02&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1110101&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Groceries&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-07-01&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1110100&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Insurance Premium&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-06-28&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1011111&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Charity Donation&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-06-26&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1100010&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Vacation Expense&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-06-26&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 110011&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Home Repairs&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-06-24&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 110001&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Pet Care&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-06-22&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1101110&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Personal Loan&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-06-18&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1100111&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">this&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">transactionList&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="na">add&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">new&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Transaction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Childcare&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;2023-06-15&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s">&amp;#34;$ 1011111&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="p">));&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>取出這段文字 &lt;code>&amp;quot;$&lt;/code> 開頭的部分，將後面的數字從 binary 轉換成 ascii&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># tmp.py&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">re&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">source&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span> &lt;span class="c1"># 這邊放上面的字串&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 抓出所有 &amp;#34;$ xxxx&amp;#34; 的 0/1 字串&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">binaries&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">re&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">findall&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">r&lt;/span>&lt;span class="s1">&amp;#39;\$ ?([01]+)&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">source&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">output&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">binaries&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">output&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="nb">chr&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">int&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">except&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">output&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="s1">&amp;#39;?&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Binary → ASCII:&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">output&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>執行就可以找到前半部分的 Flag 了喔！&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ uv run tmp.py
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Binary → ASCII:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">picoCTF&lt;span class="o">{&lt;/span>1_l13d_4b0ut_b31ng_
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="結論">結論
&lt;/h2>&lt;p>這題我找不到網路上有人寫 write-up，可能因為出得太靠北了，導致這麼低的喜歡率。不過我覺得還蠻有趣的，我一開始沒有使用 jadx 這類的工具來將 apk 轉換成看得懂的 Java code，而是直接閱讀 .smali 檔案，真的是有病哈。我一直以為是要用 apktool 修改 request url，看 App 會跳出什麼線索，後來覺得不對呀，我都有 source code 而且還是沒有特別混淆過的，那就直接打看看 instance 吧！會有這樣的想法是因為這次的另一個 reverse engineering 題目是直接提供 apk 下載連結，而不用特別開 instance，那這題肯定有鬼呀，結果就通靈到了，開開心心&lt;/p></description></item><item><title>在 MacOS 中如果意外把 /etc/pam.d/sudo 的東西改壞怎麼辦？(在 MacOS 中使用指紋來驗證 sudo)</title><link>https://blog.yenslife.top/post/macos-sudo-pam-fix/</link><pubDate>Wed, 26 Nov 2025 02:04:48 +0800</pubDate><guid>https://blog.yenslife.top/post/macos-sudo-pam-fix/</guid><description>&lt;img src="https://i.meee.com.tw/CzGJ70z.png" alt="Featured image of post 在 MacOS 中如果意外把 /etc/pam.d/sudo 的東西改壞怎麼辦？(在 MacOS 中使用指紋來驗證 sudo)" />&lt;h2 id="前情提要">前情提要
&lt;/h2>&lt;p>我一開始是因為看到這個影片，作者 Chuck 提到的最後一個 MacOS terminal trick&lt;/p>
&lt;div class="video-wrapper">
&lt;iframe loading="lazy"
src="https://www.youtube.com/embed/qOrlYzqXPa8"
allowfullscreen
title="YouTube Video"
>
&lt;/iframe>
&lt;/div>
&lt;p>他說可以透過修改 &lt;code>/etc/pam.d/sudo&lt;/code>，加入 &lt;code>auth sufficent pam_tid.so&lt;/code> 來讓之後需要輸入 sudo 的地方都可以使用指紋來驗證，超帥超快的，特別是如果你的密碼很長，應該會輸入到很躁&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cat /etc/pam.d/sudo
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># sudo: auth account password session&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">auth sufficient pam_tid.so
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">auth include sudo_local
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">auth sufficient pam_smartcard.so
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">auth required pam_opendirectory.so
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">account required pam_permit.so
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">password required pam_deny.so
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">session required pam_permit.so
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>但好笑的是，我不小心把 &lt;code>pam_tid.so&lt;/code> 寫成 &lt;code>pam_unix.so&lt;/code> (有時候用 GitHub copilot 還是要注意呀QQ)&lt;/p>
&lt;p>導致我存檔離開並打算用 &lt;code>sudo&lt;/code> 的時候，出現 &lt;code>sudo: unable to initialize PAM: No such file or directory&lt;/code>，意思就是 pam 設定檔錯誤，然後想要改這個檔案又需要 sudo 的權限，所以哈哈，尷尬了，悲劇了，完蛋了&lt;/p>
&lt;h2 id="解決方法">解決方法
&lt;/h2>&lt;p>跟 Perplextiy 聊過之後，才知道這種系統層級的東西壞掉，在 MacOS 上可以透過「恢復模式」來修，在這個模式下的終端機預設就是 super user，所以只要用這個模式把 &lt;code>/etc/pam.d/sudo&lt;/code> 改好就好了！&lt;/p>
&lt;p>以下是步驟&lt;/p>
&lt;ol>
&lt;li>關機&lt;/li>
&lt;li>按住電源鍵不放，直到出現「繼續按住來進入選項」&lt;/li>
&lt;li>這時候你可以選擇你的磁碟和選項，當然是要選擇「選項」，然後按下繼續&lt;/li>
&lt;/ol>
&lt;p>Perplexity 跟我說可以用「磁碟工具程式」來選取掛載 &lt;code>/etc&lt;/code> 的磁碟，然後進入終端機用 vi 去改。我後來發現其實不用這樣，這一步應該只是要確定這個 Volume 的名字而已，我最後是用以下命令來改&lt;/p>
&lt;p>至於進入終端機的方式，你可以看到螢幕最上方繪有一條 menu bar，那邊有一個地方可以開啟終端機&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ vi /Volumes/Macintosh&lt;span class="se">\ &lt;/span>HD/etc/pam.d/sudo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>改好存檔之後，重新開機就可以用指紋來驗證 sudo 啦！！超酷的&lt;/p>
&lt;p>&lt;img src="https://i.meee.com.tw/CzGJ70z.png"
loading="lazy"
alt="系統要求使用指紋來驗證 sudo 的截圖"
>&lt;/p></description></item><item><title>Macbook pro (Intel 晶片)雙系統測試紀錄</title><link>https://blog.yenslife.top/post/macbook-pro-intel-chip-dual-system-testing-record/</link><pubDate>Wed, 20 Dec 2023 22:13:46 +0800</pubDate><guid>https://blog.yenslife.top/post/macbook-pro-intel-chip-dual-system-testing-record/</guid><description>&lt;img src="https://i.imgur.com/8zKsUF4.png" alt="Featured image of post Macbook pro (Intel 晶片)雙系統測試紀錄" />&lt;p>（舊網站文章，撰寫時間：2023-12-20）&lt;/p>
&lt;p>我的舊筆電 MacBook pro late 2013 前陣子被我弄成純 ubuntu，但最近因為作業需求 (微算機要用到 PuTTY)，需要一個 Windows 的環境會比較方便，這篇文章記錄我這幾天的心得。&lt;/p>
&lt;p>接下來會以步驟以及可能遇到的問題來做說明，希望未來的我不要踩到一樣的坑 ㄏㄚ&lt;/p>
&lt;p>別忘記一定要&lt;strong>備份&lt;/strong>喔，以下也只是我自己的經驗，不代表你的操作結果就會跟我一樣，只能當作參考。&lt;/p>
&lt;h2 id="製作-windows-10-開機碟">製作 Windows 10 開機碟
&lt;/h2>&lt;p>參考連結：&lt;a class="link" href="https://mrmad.com.tw/macos-makes-windows-refill-usb-flash-drive" target="_blank" rel="noopener"
>如何用macOS 製作Windows 開機隨身碟，兩種方式輕鬆實現 - 瘋先生 (mrmad.com.tw)&lt;/a>&lt;/p>
&lt;p>我使用 UNetbootin 來製作開機碟，要注意的是製作的過程可能會非常非常的久，尤其是有些檔案幾千Mb 就會卡住，但他不是壞掉他只是比較久而已。注意：不要使用 FAT32，因為檔案大小的問題。&lt;/p>
&lt;h3 id="遇到問題windows-無法開啟所需的檔案-csourcesinstallwim">遇到問題：Windows 無法開啟所需的檔案 C:\Sources\install.wim
&lt;/h3>&lt;p>像是下圖&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/tnEFMzu.png"
loading="lazy"
>
後來查一下才發現，原來是因為我使用的 USB 格式是 FAT32，但現在 windows 的 iso 中，install.wim 就超過 4G 了，所以應該要用更合適的格式來格式化 USB&lt;/p>
&lt;p>參考資料：&lt;a class="link" href="https://www.zendei.com/article/79639.html" target="_blank" rel="noopener"
>安裝系統時出現 Windows無法打開所需的文件 C:\Sources\install.wim 的解決辦法_ZenDei技術網路在線&lt;/a> &lt;a class="link" href="https://www.linwei.com.tw/forum-detail/60/" target="_blank" rel="noopener"
>隨身碟格式化教學：FAT32、NTFS、exFAT怎麼選？ - 凌威科技 (linwei.com.tw)&lt;/a>&lt;/p>
&lt;h3 id="遇到問題裝好的-windows-沒有無線網卡音效卡">遇到問題：裝好的 Windows 沒有無線網卡、音效卡….
&lt;/h3>&lt;p>這個問題可以透過這幾年 mac 的 boot camp 來解決，Boot camp 會附帶一些驅動程式給你。但我不是用 Boot camp，而是自己切一塊空間來裝。我第一次安裝時是沒有連接網路的，第二次將電腦接上有線網路，做一些設定就可以了。&lt;/p>
&lt;h3 id="遇到問題windows-說你的磁碟無法安裝">遇到問題：Windows 說你的磁碟無法安裝
&lt;/h3>&lt;p>可能是因為格式他不接受，這時候只要選擇你要的磁碟，然後按下刪除就可以了。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/NC6dBi2.png"
loading="lazy"
>&lt;/p>
&lt;h3 id="遇到問題第一次開機正常關機後就無法使用-windows-開機出現-no-bootable-device----insert-boot-disk-and-press-any-key">遇到問題：第一次開機正常，關機後就無法使用 Windows 開機，出現 No bootable device &amp;ndash; insert boot disk and press any key
&lt;/h3>&lt;p>如下圖&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/SmgpMwh.png"
loading="lazy"
>&lt;/p>
&lt;p>可能是因為把一些東西裝到 USB 了，你可以試著插上 USB 開機看看。&lt;/p>
&lt;p>以下是插上 USB 之前，按下 windows 會發現他掛掉了。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/rWhDI5B.png"
loading="lazy"
>&lt;/p>
&lt;p>以下是插上 USB 之後可以看到多了兩個選項，這時候按 EFI Boot 前面的 Windows 即可開機！&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/8zKsUF4.png"
loading="lazy"
>
恩…蠻瞎的，我朋友說可以再灌一次，但我累了 身心俱疲了，先可以應付作業需求就好哈哈哈哈&lt;/p>
&lt;p>(2023/12/24 更新) 我後來把 mac 更新到 MacOS Mojave 之後，就可以正常開機了，不知道為什麼，但我猜應該是因為我更新了 mac 的版本，所以他會去更新一些東西，然後就可以正常開機了)&lt;/p>
&lt;h2 id="如果真的完全掛掉了怎麼辦">如果真的完全掛掉了怎麼辦？
&lt;/h2>&lt;p>就直接重灌 Mac 吧！我會重灌這台 Mac 就是因為我對他沒有絲毫的牽掛，但她依舊是我的好夥伴，所以要寫這篇文章紀念一下&lt;/p>
&lt;p>你可以按住電源鍵，先強制讓他關機，等個幾秒之後按下 &lt;code>Command + r&lt;/code> 然後按下電源鍵，會進到 recovery mode 他第一次可能會出現這個畫面，要連上無線網路。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/SnPJjGo.png"
loading="lazy"
>&lt;/p>
&lt;p>然後按下重新安裝 macOS，這時候應該只能選擇安裝古老版本的 OSX Mavericks ，之後樣更新的話可以參考 &lt;a class="link" href="https://discussionschinese.apple.com/thread/140127319?sortBy=best" target="_blank" rel="noopener"
>os x 10.9.5 更新不了版本 - Apple 社区&lt;/a> 在網站上下載 .dmg 檔案，安裝新版 OS。&lt;/p>
&lt;p>下面就是一些安裝的畫面&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/hmhVRUx.png"
loading="lazy"
>&lt;/p>
&lt;p>在修復模式中可以用磁碟工具程式，看你要切割還是要格式化。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/B6KBBg6.png"
loading="lazy"
>&lt;/p>
&lt;p>OSX Mavericks 開機畫面，是白蘋果！&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/tGZWbTg.png"
loading="lazy"
>&lt;/p>
&lt;p>OSX Mavericks 超古老&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/CDrQXC2.png"
loading="lazy"
>&lt;/p>
&lt;p>幾乎什麼程式、比較新的網站都不能用，連 Edge 都不能裝 笑死&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/rNM6UKc.png"
loading="lazy"
>&lt;/p>
&lt;h3 id="手動更新-macos">手動更新 MacOS
&lt;/h3>&lt;p>參考 &lt;a class="link" href="https://discussionschinese.apple.com/thread/140127319?sortBy=best" target="_blank" rel="noopener"
>os x 10.9.5 更新不了版本 - Apple 社区&lt;/a> 在網站上下載 .dmg 檔案，安裝新版 OS。
(2023/12/25更新) 如果安裝更新遇到「您無法安裝到這個卷宗上，因為目前正在加密卷宗」的加密問題可以參考&lt;a class="link" href="https://discussionschinese.apple.com/thread/140127092?sortBy=best" target="_blank" rel="noopener"
>這個&lt;/a>。&lt;/p>
&lt;p>(2023/12/25更新) 你可以用&lt;a class="link" href="https://support.apple.com/zh-tw/102465" target="_blank" rel="noopener"
>這個&lt;/a>來安裝 Windows 支援軟體。裝完之後記得在 windows 那邊檢查 apple software update 有沒有更新，有的話就更新一下。還是怪怪的就多執行 setup.exe 幾次試試看。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/k5Ow6KS.jpg"
loading="lazy"
>&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/q5ZO5Q9.jpg"
loading="lazy"
>&lt;/p>
&lt;p>(2023/12/25更新) 沒有聲音的話可以試著切換音效裝置。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/oIVaB1D.jpg"
loading="lazy"
>&lt;/p>
&lt;h4 id="在-osx-可以切割硬碟嗎">在 OSX 可以切割硬碟嗎？
&lt;/h4>&lt;p>可以參考這個影片：&lt;a class="link" href="https://youtu.be/Z8-jm17YBt8?si=ClYQ_Jl982qF2GfW" target="_blank" rel="noopener"
>https://youtu.be/Z8-jm17YBt8?si=ClYQ_Jl982qF2GfW&lt;/a>&lt;/p>
&lt;pre>&lt;code>祝大家的重灌之路都很順利，尤其是 Mac 的使用者，在這個微軟爸爸最大的世界，我們要自立自強&lt;/code>&lt;/pre></description></item><item><title>內在動機與外在動機</title><link>https://blog.yenslife.top/post/intrinsic-and-extrinsic-motivation/</link><pubDate>Thu, 23 Nov 2023 21:19:59 +0800</pubDate><guid>https://blog.yenslife.top/post/intrinsic-and-extrinsic-motivation/</guid><description>&lt;img src="https://i.imgur.com/p28siwO.png" alt="Featured image of post 內在動機與外在動機" />&lt;p>（舊網站文章，撰寫時間：2023-11-23）&lt;/p>
&lt;p>這是一個通識課的作業，看完這部 Ted 演講的心得，我覺得這個主題很有趣，所以就寫了一些自己的心得。&lt;/p>
&lt;p>資料來源： &lt;a class="link" href="https://youtu.be/rrkrvAUbU9Y?si=0ppV40ITE7iARwBJ" target="_blank" rel="noopener"
>https://youtu.be/rrkrvAUbU9Y?si=44CFkKhIQvWVAjbq&lt;/a>、成大通識課心理學簡報&lt;/p>
&lt;h2 id="蠟燭難題">蠟燭難題
&lt;/h2>&lt;p>實驗人員給受試者一些釘子、火柴、請受試者將蠟燭年到牆壁上，但是蠟不能滴到牆壁上。很多人一開始看不出來，會嘗試把蠟燭用釘子釘在牆上，或是用蠟油黏著他，但其實把裝釘子的盒子當成平台就好。&lt;/p>
&lt;p>題目的情形如下圖所示：&lt;/p>
&lt;p>&lt;em>將釘子放在盒子內。&lt;/em>
&lt;img src="https://i.imgur.com/njTQRbY.png"
loading="lazy"
>&lt;/p>
&lt;p>最快最直接，但不那麼直覺的解法：&lt;/p>
&lt;p>&lt;em>其實直接用裝釘子的盒子就可以完成任務。&lt;/em>
&lt;img src="https://i.imgur.com/OukXBqY.png"
loading="lazy"
>&lt;/p>
&lt;h2 id="外在動機">外在動機
&lt;/h2>&lt;p>由外在世界驅動一個人做某些事情的動力來源，像是酬勞、懲罰等等。影片中有提到外在酬勞在二十世紀的工作是可行的，但到了二十一世紀，這種機械性、賞與罰的方式非但不可行，還會造成傷害。格魯茲堡做的實驗證明了這件事。這件事持續了好幾年都可以 work，這是最穩健的研究結果之一。有一些例外，像是簡單的問題，給受試者明確的動作，再加上獎勵，確實可以使表現更好。&lt;/p>
&lt;p>後來他又做了一次實驗，這次用簡單版本的蠟燭難題，顯示如果是因果式的獎勵，在這種有簡單規則，並有清晰目標的工作，很有用。因為這會使人思路更直，更狹窄。但生活中大部分的問題都是原本的蠟燭難題，是需要，是需要創造性、概念性的工作，右腦是的工作不能使用外在酬賞的方式，因為他們沒有清晰簡單的規則、解答。&lt;/p>
&lt;p>&lt;em>簡單版本的蠟燭難題&lt;/em>
&lt;img src="https://i.imgur.com/4SwsPtH.png"
loading="lazy"
>&lt;/p>
&lt;pre>&lt;code>💡 因果式的獎勵往往會摧毀創意，它只能在一個比我們想像更狹窄的環境下發揮作用。
&lt;/code>&lt;/pre>
&lt;h2 id="內在動機">內在動機
&lt;/h2>&lt;p>由自己的興趣、熱情、理想去驅動的動機，完全是自發性的。&lt;/p>
&lt;p>影片中也提及新的企業運作模式應該圍繞：&lt;/p>
&lt;ul>
&lt;li>Autonomy 自主性&lt;/li>
&lt;li>Mastery 掌握度&lt;/li>
&lt;li>Purpose 使命感&lt;/li>
&lt;/ul>
&lt;p>比起外在酬賞，這樣的方式能使員工的表現更好。最有名的例子應該是 Google 的 20 Percent Time 方法，他們有 20% 的的時間可以自主應用，幾乎有一半的新產品都是 20% 期間產生的。&lt;/p>
&lt;p>還有一個例子就是微軟的 Encarta 百科全書，他們當時幾乎動用了大筆資金請專業人士來完成這個專案，以期待能在預定的時間和開支範圍內完成壯舉，然而幾年後，有另一個百科全書誕生，大家為了興趣而做，沒人收到錢，而那個百科叫做 Wiki (維基百科)。&lt;/p>
&lt;h2 id="rowe-result-only-work-environment只看結果的工作環境">ROWE (Result Only Work Environment)：只看結果的工作環境
&lt;/h2>&lt;p>由兩個美國的美國的顧問專家創造。在這樣的體制下，員工沒有硬性的 schedule，他們只要負責把結果產出，有時候甚至連辦公室、開會都不用去，有點像我們熟知的「責任制」，但是又更彈性。這樣的實行結果是：差不多所有公司的生產力都上升、投入感上升、滿意度上升、離職率下降。提升了自主性、掌握度、使命感。&lt;/p>
&lt;h2 id="我的動機分享">我的動機分享
&lt;/h2>&lt;h3 id="選擇就讀成大資訊系的動機">選擇就讀成大資訊系的動機
&lt;/h3>&lt;p>其實我覺得我最一開始的動機是外在動機和內在動機組成的。一方面是，我很希望以後的工作可以有彈性的工時、高酬勞，選擇電資科系還可以滿足社會的期待；另一方面是，我自己本身就對電腦之類的知識蠻有興趣的，只是高中比較少接觸。&lt;/p>
&lt;h3 id="學習動機轉換">學習動機轉換
&lt;/h3>&lt;p>比較值得分享的是我的學習動機，大一因為大家都很厲害，都是第一志願上來的，我一個社區高中的，高中基礎其實也沒有打好，所以真的很受挫折，又受到當時補習班一直說：要前幾趴才可以推甄上頂大研究所。導致壓力很大，看到書就感到厭惡，所有的學習都是為了成績、學分。這樣的訓練一直到大二也有明顯的成果，就是我的成績真的變蠻好的，不過我也同時看了很多人 work life balance 的分享，覺得應該要回到高中那個我，單純想要學習知識而已，對領域感到好奇而學。我們都知道滿足好奇心是一件很快樂的事情。&lt;/p>
&lt;p>所以我後來的學習風格也逐漸從成績導向變成好奇心驅動，原本可能會為了考題而準備考試，雖然現在也會，但我會更在意學到的東西是不是真的懂了，而不是成績拿到就拍拍屁股走人。以前會參加一些資訊年會可能是因為希望在履歷上可以多一點色彩（其實沒什麼用哈哈），但現在單順為了滿足好奇心，享受學到新東西的感覺。也發現其實「讀書」本身是一件很開心的事，我真正不喜歡的其實是「考試」與「滿足他人的期待」，有時候只要當自己的英雄就好，不需要因為別人的話語或是期待而自責或是憤怒，就算真的有相應的情緒，也是自己讓自己生氣的不是嗎？&lt;/p>
&lt;h3 id="吉他與音樂">吉他與音樂
&lt;/h3>&lt;p>我從國中就開始彈吉他，但一開始是我爸覺得我的生活太無聊，要讓我有一個興趣，一開始也確實是外在動機，到後來這個興趣陪伴我許多情緒，加上家人和自己都很喜歡音樂，它就成了我與音樂世界的橋樑。到了高中才開始在社團展露頭角，當時的動機也是參半的，一方面是希望可以展現好的自己給大家看，隱藏自己的自卑感，有時候我也會想說，我真的享受台上的感覺嗎？我談的東西一點靈魂都沒有，和考試一樣，只是想要把它彈好，卻忘了不完美也是完美的一部分。&lt;/p>
&lt;p>到了大學，因為同學也都是很有才華的人，再加上要顧及課業（超好笑，別人都是大學開始玩我是大學開始讀書），這個興趣/技能我就把它擺在旁邊了，大概一年多沒有碰它，對自己的沒自信逐漸讓我忘記享受一件事最單純的動機。但後來隨著心境的轉變，我也慢慢找到當初那個透過音樂與自己的內在世界對話的自己，還為了想要讓自己進步而開始錄 Cover 影片，這一切都不是為了比較，而是單純想把一件事情做好，就是覺得自己喜歡、想要進步，看到自己進步就很爽，這些都不是課程要求的，但我就是覺得有意義、有熱情，這就是我的內在動機。&lt;/p>
&lt;p>講了這麼多，我覺得也不用太排斥外在動機，我們可以試著把它當成一個機會，可能只是時間還沒到，內在動機有可能會慢慢跑出來，就像我當初學吉他一樣，最初的動機也不是出於內在動機。前提是你必須持續探索，任何領域都一樣，加深加廣去理解後只會感到越來越有興趣，如果覺得沒興趣，當然也有可能是真的沒興趣，但也很有可能是探索不夠深。&lt;/p>
&lt;p>這只是通識課作業不小心就寫了有點多，希望大家可以從中得到一些啟發，也歡迎大家分享自己的動機，謝謝大家！&lt;/p></description></item><item><title>《菁英都是閱讀控》閱讀筆記：精英就是閱讀+共讀</title><link>https://blog.yenslife.top/post/elite-are-all-reading-enthusiasts/</link><pubDate>Sun, 28 May 2023 21:10:21 +0800</pubDate><guid>https://blog.yenslife.top/post/elite-are-all-reading-enthusiasts/</guid><description>&lt;img src="https://i.imgur.com/lOkiaSI.png" alt="Featured image of post 《菁英都是閱讀控》閱讀筆記：精英就是閱讀+共讀" />&lt;p>（舊網站文章，撰寫時間：2023-05-28）&lt;/p>
&lt;p>作者：海狸大師&lt;/p>
&lt;blockquote>
&lt;p>對你來說，閱讀有多大的力量呢？&lt;/p>
&lt;/blockquote>
&lt;p>本書&lt;a class="link" href="https://www.eslite.com/product/1001176302741479" target="_blank" rel="noopener"
>《菁英都是閱讀控》&lt;/a>的作者&lt;strong>神田昌典&lt;/strong>是一位行銷顧問、管理學大師，以及日本最大讀書會「為行動閱讀」的創始人，也是全腦思考法的發明者，對於管理和閱讀領域擁有豐富的實戰經驗。我也在這本書得到很大的啟發。不過他有很多內容範例都是從日本為核心出發，像是一些案例以及職場經驗，這部分讀者可能較難體會，但影響不大。接下來我會摘錄這本書的重點，主要是我覺得值得分享的部分。&lt;/p>
&lt;p>&lt;img src="https://images.unsplash.com/photo-1506880018603-83d5b814b5a6?ixlib=rb-4.0.3&amp;amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA==&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=2148&amp;amp;q=80"
loading="lazy"
>&lt;/p>
&lt;h2 id="書本過時了嗎">書本過時了嗎？
&lt;/h2>&lt;p>很多人覺得書本已經是過時的東西、出版業衰退，這別是在智慧型手機、網路普及的世代，要取得資訊直接 Google 或甚至 ChatGPT 一下就可以了，如果想學東西也可以到 MOOCs 像是 Coursera 等等平台學習，書本的更新完全比不上網路。但作者並不這麼認為，他反而認為書本是帶動潮流的推手。&lt;/p>
&lt;p>2000 年初，《窮爸爸與富爸爸》系列的書籍熱銷，在日本賣出過一百八十萬本，這股熱潮間接帶領整個社會走向「現在不做些什麼，我這輩子就無法翻身了」的風潮，再加上到日本社會的職場文化，大部分的人都是一輩子只待在一家公司，在節奏飛快的現在講求穩定反而成了一種不穩定，也難怪會在日本形成一股強大的潮流。受到這種風氣影響，大約從2007年起，更是帶動日本女性經濟獨立、經營美好身活的「新女性工作法」。&lt;/p>
&lt;p>作者說除了近年的加密貨幣、人工智慧，等科技相關議題，很多潮流、社會風氣的推動都是透過書籍，就算是電視、網路，頂多也只有「推廣」，能夠促使人們真正轉變想法並進行「典範轉移」的，就是書本。&lt;/p>
&lt;h2 id="書本有品值保障">書本有品值保障
&lt;/h2>&lt;p>正如同你現在閱讀的這篇文章，我在發表文章之前只需要自己審核，儘管已經做到最完美（也是我自己覺得最完美），也難免有些遺漏、錯誤的地方，可能需要讀者回饋我才會知道，而這就是從網路取得資訊的風險。為什麼各式各樣的媒體中，書本可以一直有一席之地，就是因為他的「權威性」。電視和網路媒體不一定會做事實查核，即使是 ChatGPT 也會犯錯，但書籍不一樣，一本書要發行除了作者的自我審查，還需要經過好多人的審查。&lt;/p>
&lt;p>那些經典名作都是被記錄在書籍裡，因為這些書已經證明自己經的起時間的考驗。&lt;/p>
&lt;h1 id="知識創造型的讀書法">知識創造型的讀書法
&lt;/h1>&lt;p>&lt;img src="https://images.unsplash.com/photo-1434030216411-0b793f4b4173?ixlib=rb-4.0.3&amp;amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA==&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=2370&amp;amp;q=80"
loading="lazy"
>&lt;/p>
&lt;p>因為作者對讀書方法有很深的研究與經驗，書中也提到了他獨特的讀書法，大致可以分成兩個&lt;/p>
&lt;ul>
&lt;li>影像閱讀法&lt;/li>
&lt;li>目標取向閱讀法&lt;/li>
&lt;/ul>
&lt;p>「影像閱讀法」的全名是「全腦影像閱讀法」，老實說我覺得這個方法並不適用所有人，它的概念有點像是速讀，號稱一秒閱讀一頁的速度，書中很詳細地描述了這個方法的步驟，這邊就留給大家自行閱讀吧！&lt;/p>
&lt;h2 id="目標取向閱讀法">目標取向閱讀法
&lt;/h2>&lt;p>然而，「目標取向閱讀法」對我甚至所有人都可以有很大的幫助，它的核心概念就是我們不能瞎讀書，要有目的的讀書。這麼做有很多好處，除了可以節省你的時間以外，也能夠讓大腦在閱讀時更專注。而且設定好目標就像是吸引力法則，在生活中、工作中，你都可能因此得到你想要的東西（在書店找到自己需要的書）&lt;/p>
&lt;p>因為專注在特定主題，所以你其實也「不用閱讀完整本書」，這個概念對我來說一開始難以接受，覺得書不就是要讀完才算「讀進去」嗎？但仔細想想也對，如果一本書你讀到一半發現沒辦法從書上學到對你而言有價值的東西，那乾脆一點吧，直接停下來找別的書吧，時間才是最貴的。&lt;strong>設定目標閱讀才能讓最重要的資訊顯現出來&lt;/strong>。&lt;/p>
&lt;p>作者也提到了各個年齡層要閱讀的書籍，都是很不錯的建議。我讀完這部分後覺得比起選擇書籍，對現在人來說養成閱讀的習慣就已經很不錯了，書籍選擇可以朝對自己工作、自我提升有幫助的書開始，再進階到歷史書（36~42 歲）、哲學與自然科學（40 歲之後）、藝術書（商品美感）。作者也鼓勵大家閱讀外文書，好處多多。&lt;/p>
&lt;p>如果只是想要讀得開心那也很好，只要把目標變成讓自己開心，你一樣可以很有「效率」地閱讀。&lt;/p>
&lt;h1 id="共讀的時代">共讀的時代
&lt;/h1>&lt;p>&lt;img src="https://images.unsplash.com/photo-1523240795612-9a054b0db644?ixlib=rb-4.0.3&amp;amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA==&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=2370&amp;amp;q=80"
loading="lazy"
>&lt;/p>
&lt;p>作者是日本最大讀書會「為行動閱讀」的創始人，他花了很大的篇幅強調共讀的重要性，一個人走的快，一群人走的遠。如今已是無法獨自解決問題、高度分工的時代，想要增進溝通能力、拓展交友圈，就去參加讀書會吧。或者，你也可以考慮自己辦一個！&lt;/p>
&lt;h2 id="讀書會的好處">讀書會的好處
&lt;/h2>&lt;p>在知識創造的章節，作者提到了 information (內化) 和 exformation (外化)。information 指的是從外部吸收資訊，並在心裡形成理解。在輸入新資訊後，將自己形塑成世界所要求的模樣；exformation 則是****************將心裡的理解在外界創新。除了輸出以外，也在這世界創造出自己想要的東西。****************要進行知識創造，exformation 不可或缺（畢竟都說是「創造」了），在發表之前自己就要先好好釐清資訊，並吸收他人的反饋，加深自己思考的深度，進入正向循環。&lt;/p>
&lt;p>加入讀書會的好處很多，像是「獲得不一樣的觀點」、「離開同溫層」等等。加入讀書會也是拓展社交圈的好方法。和素質參差不一的聯誼等活動相比，會參加讀書會的人的氣質大部分都是很不錯的。重點是，你可以利用書本、作者的名氣來聚集許多人，和一些特定興趣的社團相比，你很有機會遇到完全不同領域、生活圈的人。&lt;/p>
&lt;p>推動日本明治維新的力量就是讀書會，江戶末期有許多私塾連環出現，也有許多大人物參與其中，當時的私塾其實就是讀書會。&lt;/p>
&lt;p>作者也提到在許多公司有飲酒文化，特別是日本，這麼做其實是為了消除公司上下層的溝通隔閡，縮短彼此的距離。但近年來好像變少了，大家都有自己的事要做。有時候我們也會需要跟公司不同部門的人溝通，在不了解領域語言的前提下，溝通誤會就更頻繁了。所以，作者也鼓勵公司舉辦讀書會，甚至有的公司直接找作者辦讀書會，希望給他們一些讀書會的指導。&lt;/p>
&lt;h2 id="為行動閱讀讀書會">「為行動閱讀」讀書會
&lt;/h2>&lt;p>作者的讀書會相當特別，號稱三小時讀完 1000 頁。我看到這邊其實有點傻眼，這樣真的可以吸收嗎？但是作者強調他們採用「目標取向閱讀法」，而且有專門的「閱讀指導員」帶領學員讀書，在這樣的環境（作者說這是好的社會壓力）下，搭配「影像閱讀法」，真的可以完整吸收，甚至更多新想法激發。&lt;/p>
&lt;p>讀書會不乏那種不說話的人（不要再說自己社恐，小孤獨都組樂團了），他們的做法是直接請他出去。看起來好像很冷酷無情，這麼做是有原因的。不發表意見的人不只是在讀書會，各類研討會都一樣，他們就像一顆發霉的蘋果，是會影響到整體的氛圍的。真的為了大家好，最棒的做法就是讓大家參與其中。&lt;/p>
&lt;h1 id="我的觀點閱讀的魔力">我的觀點：閱讀的魔力
&lt;/h1>&lt;p>說來慚愧，我是一直到最近才慢慢愛上閱讀的。對我來說，閱讀總是和考試、排名等詞彙排在一起，也可能是不夠專注的緣故，一直無法體會閱讀帶來的愉快。讀完這本書後，更確信閱讀的力量超乎自己所想，目標取向閱讀法也很有幫助。&lt;/p>
&lt;p>因為平常也很忙，短期內應該不會找到讀書會參與。但我仍會努力嘗試 exformation，我還是可以透過寫閱讀筆記來輸出我的想法。寫到這邊也感覺這本書已經漸漸成為我的一部分，就是「有讀進去」的感覺。&lt;/p>
&lt;p>我覺得這本書很適合推薦給「不知道讀什麼書」以及自認為是「閱讀的新手」的人們，作者花了很大的篇幅，用它自身的經驗、參與的專案，來告訴你閱讀是一件很值得去做的事 (尤其是&lt;strong>共讀&lt;/strong>)，還可以透過閱讀來「改變世界」，這部分就讓大家自行品味吧。&lt;/p>
&lt;p>沒意外這應該會是閱讀筆記的第一篇，希望不會是最後一篇：）&lt;/p></description></item><item><title>Macbook 找不到 Python Module 解決方法</title><link>https://blog.yenslife.top/post/python-modulenotfounderror-in-macos/</link><pubDate>Tue, 07 Mar 2023 14:36:57 +0800</pubDate><guid>https://blog.yenslife.top/post/python-modulenotfounderror-in-macos/</guid><description>&lt;img src="https://i.imgur.com/HsOyXgx.png" alt="Featured image of post Macbook 找不到 Python Module 解決方法" />&lt;p>（舊網站文章，撰寫時間：2023-03-07）&lt;/p>
&lt;h2 id="問題">問題
&lt;/h2>&lt;p>當你在 MacOS 中使用 &lt;code>pip3 install [套件]&lt;/code> 安裝套件時 ，可能會發現 Python 找不到ｗ套件，會長這樣
&lt;img src="https://i.imgur.com/HsOyXgx.png"
loading="lazy"
>&lt;/p>
&lt;h2 id="解決方法">解決方法
&lt;/h2>&lt;ul>
&lt;li>
&lt;p>你可以用 &lt;code>pip3 show [套件名稱]&lt;/code> 來查看套件的安裝路徑。
&lt;img src="https://i.imgur.com/qJnj6oR.png"
loading="lazy"
>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>然後用 &lt;code>python3 -m site&lt;/code> 查看 USER-SITE 路徑
&lt;img src="https://i.imgur.com/XD80amt.png"
loading="lazy"
>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>會發現執行路徑和套件路徑不同，最好的解決方法就是不要用 &lt;code>pip3 install&lt;/code>，改用&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">python3 -m pip install &lt;span class="o">[&lt;/span>套件名稱&lt;span class="o">]&lt;/span> &lt;span class="c1"># 用這個他就會幫你裝在 USER_SITE 底下了&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>python3 -m pip install&lt;/code> 和 &lt;code>pip3 install&lt;/code> 兩者的功能都是用來安裝 Python 套件，但是在執行上有些微的差異。&lt;/p>
&lt;p>&lt;code>python3 -m pip install&lt;/code> 是使用 Python 解釋器內建的 &lt;code>pip&lt;/code> 模組進行安裝，透過 &lt;code>-m&lt;/code> 參數指定模組名稱 &lt;code>pip&lt;/code>，並且可以確保使用的是正確版本的 &lt;code>pip&lt;/code>，避免了因為系統環境問題導致的版本不一致或是套件安裝到錯誤的位置的問題。&lt;/p>
&lt;p>而 &lt;code>pip3 install&lt;/code> 則是直接呼叫系統上安裝的 &lt;code>pip&lt;/code> 工具進行安裝，這種方式可能會因為系統環境或是 PATH 設定不正確而導致安裝錯誤或是套件安裝到錯誤的位置。&lt;/p>
&lt;p>結論就是，使用 &lt;code>python3 -m pip install&lt;/code> 會比較保險，可以確保使用的是正確版本的 &lt;code>pip&lt;/code>，而且也避免了因為系統環境問題導致的版本不一致或是套件安裝到錯誤的位置的問題。&lt;/p>
&lt;blockquote>
&lt;p>結論：在 Mac 上用 python3 -m pip install 就對了：）&lt;/p>
&lt;/blockquote></description></item><item><title>Mac (intel x86), Linux 雙系統、Ubuntu 切割硬碟紀錄</title><link>https://blog.yenslife.top/post/mac-linux-ubuntu-partition-resize/</link><pubDate>Mon, 13 Feb 2023 17:57:12 +0800</pubDate><guid>https://blog.yenslife.top/post/mac-linux-ubuntu-partition-resize/</guid><description>&lt;img src="https://i.imgur.com/Q90BaZ4.png" alt="Featured image of post Mac (intel x86), Linux 雙系統、Ubuntu 切割硬碟紀錄" />&lt;p>（舊網站文章，撰寫時間：2023-02-13）&lt;/p>
&lt;p>（重要事項：我已經把我的 mac 作業系統弄壞了，這篇是紀錄我怎麼弄壞的，請大家操作硬碟一定要小心謹慎，還有我是怎麼解決的）&lt;/p>
&lt;h2 id="前情提要">前情提要
&lt;/h2>&lt;p>由於最近需要用到 x86 架構的電腦編譯，但我的主力機是 arm 架構，我試過在 M1 電腦用 UTM 虛擬機，但效能有點慘，所以在另一台舊電腦 (MacBook pro 2013) 灌 Ubuntu 雙系統並且放在桌上插電當 server 用，挺好用的。這邊記錄一下以免日後忘記可以回來看哈。&lt;/p>
&lt;p>雙系統參考：&lt;a class="link" href="https://www.zhihu.com/question/348950956" target="_blank" rel="noopener"
>如何在MacBook Pro上安装Linux系统？ - 知乎 (zhihu.com)&lt;/a> 這篇文章&lt;/p>
&lt;p>雖然我已經用 AirDrop 將家目錄備份到新筆電了，但我還是想分享一下我是如何把 Mac 弄壞的。&lt;/p>
&lt;p>當初，我只切割了 30G 左右的硬碟空間，但在做跨平台編譯 Linux kernel 時，發現空間不夠用，於是我想要從 Mac 那邊切一些空間過來。我是用上面那篇文章的方式來切的，但當我用 &lt;code>Option + 開機鍵&lt;/code> 更改開機啟動磁碟時，發現 Mac 硬碟消失了。&lt;/p>
&lt;p>當下，我並沒有太慌 (畢竟已經弄壞重灌過一次了)，反而很興奮，終於有藉口好好專注在 Linux 上，於是我直接擦掉 Mac 的分割區，把整個筆電弄成 Linux 了～&lt;/p>
&lt;h2 id="調整分割區大小">調整分割區大小
&lt;/h2>&lt;p>環境：
硬體：MacBook Pro 2013
作業系統：Ubuntu 20.04 x86&lt;/p>
&lt;p>如果忘記備份，可以試著用 &lt;a class="link" href="https://www.cleverfiles.com/" target="_blank" rel="noopener"
>Disk Drill&lt;/a> 把資料挖回來。(但不一定挖得回來)&lt;/p>
&lt;p>我遇到的問題是分割區無法調整大小，後來發現這其實是因為我們不能在你要調整大小的硬碟中修改你的硬碟 (有點拗口，就是你不能切自己)，所以我們需要用 live usb 開機的環境來調整。以下介紹完整流程。&lt;/p>
&lt;h3 id="製作-live-usb-並開機">製作 Live USB 並開機
&lt;/h3>&lt;p>不知道怎麼製作 live usb 可以使用 &lt;a class="link" href="https://www.balena.io/etcher" target="_blank" rel="noopener"
>balenaEtcher&lt;/a> ，網路上已經有很多關於他的教學了這邊就不多提了，最棒的是他可以在 Mac 上面用喔！&lt;/p>
&lt;p>弄好之後將電源關閉，插上你的 USB，按住 &lt;code>option + 電源鍵&lt;/code>，選擇這個 USB（通常是金色的），然後就一直 Enter 下去，選擇 &lt;code>try Ubuntu&lt;/code>&lt;/p>
&lt;h3 id="使用-gparted-分割">使用 GParted 分割
&lt;/h3>&lt;p>輸入指令 &lt;code>sudo apt install gparted&lt;/code> 安裝，然後你就會看到他在應用程式中。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/L070nGq.png"
loading="lazy"
>&lt;/p>
&lt;p>我的根目錄是在 &lt;code>/dev/sda4&lt;/code> 這邊，31.55GB 那個
&lt;img src="https://i.imgur.com/FlL6Mzc.png"
loading="lazy"
>&lt;/p>
&lt;p>右鍵選擇你要移動的分割區，點選 Resize/Move
&lt;img src="https://i.imgur.com/AOUnRwJ.png"
loading="lazy"
>&lt;/p>
&lt;p>這時候就可以自由移動了，把你的硬碟移到左邊，所以 unallocated 的空間會被移到右邊，這樣就可以自由擴充了
&lt;img src="https://i.imgur.com/TNOogmi.png"
loading="lazy"
>&lt;/p>
&lt;p>使用 &lt;code>df -l&lt;/code> 查看硬碟使用情形，可以看到真的變大ㄌ (以下是在另一台筆電 ssh 連線使用的畫面)
&lt;img src="https://i.imgur.com/wEDEBBi.png"
loading="lazy"
>&lt;/p>
&lt;p>然後記錄一下我真的把舊 Mac 的東西擦掉了，jserv 說過要好好學習 Linux 就整個都灌 Linux 最快，我想我也是有一點 &lt;a class="link" href="https://www.youtube.com/c/GUTS4tech" target="_blank" rel="noopener"
>GUTS&lt;/a> 的😎
&lt;img src="https://i.imgur.com/vQeUI1J.png"
loading="lazy"
>&lt;/p>
&lt;p>參考資料：
&lt;a class="link" href="https://askubuntu.com/questions/66000/how-to-merge-partitions" target="_blank" rel="noopener"
>partitioning - How to merge partitions? - Ask Ubuntu&lt;/a>
&lt;a class="link" href="https://superuser.com/questions/1712492/resizing-the-root-partition-using-free-space" target="_blank" rel="noopener"
>ubuntu - Resizing the root partition using free space - Super User&lt;/a>
&lt;a class="link" href="https://www.youtube.com/watch?v=Kyz9x71gEPI&amp;amp;ab_channel=SavvyNik" target="_blank" rel="noopener"
>Resize or Extend a Linux Partition/Volume/Disk (Swap - Ubuntu - Gparted) - YouTube&lt;/a>&lt;/p></description></item><item><title>Mac 遠端 ssh 連線到 Ubuntu</title><link>https://blog.yenslife.top/post/ubuntu-remote-ssh-macbook/</link><pubDate>Fri, 27 Jan 2023 00:21:03 +0800</pubDate><guid>https://blog.yenslife.top/post/ubuntu-remote-ssh-macbook/</guid><description>&lt;img src="https://images.unsplash.com/photo-1629654291663-b91ad427698f?ixlib=rb-4.0.3&amp;ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8dWJ1bnR1fGVufDB8fDB8fA%3D%3D&amp;auto=format&amp;fit=crop&amp;w=800&amp;q=60" alt="Featured image of post Mac 遠端 ssh 連線到 Ubuntu" />&lt;p>（舊網站文章，撰寫時間：2023-01-27）&lt;/p>
&lt;p>因為有案子需要用到 x86 架構的電腦編譯，但我的主力機是 arm 架構，我試過在 M1 電腦用 UTM 虛擬機，但效能有點慘，所以在另一台舊電腦 (MacBook pro 2013) 灌 Ubuntu 雙系統並且放在桌上插電當 server 用，挺好用的。這邊記錄一下以免日後忘記可以回來看哈。
環境:MacBook Pro 2021, Ubuntu 20.04&lt;/p>
&lt;h2 id="連線">連線
&lt;/h2>&lt;p>以下是連接同一個網路的方法&lt;/p>
&lt;ol>
&lt;li>安裝連線工具&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">sudo apt install openssh-server
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>在 Ubuntu 上啟動 ssh&lt;/li>
&lt;/ol>
&lt;pre tabindex="0">&lt;code>sudo /etc/init.d/ssh start
&lt;/code>&lt;/pre>&lt;p>或者&lt;/p>
&lt;pre tabindex="0">&lt;code>sudo systemctl start ssh # 啟動 ssh
sudo systemctl stop ssh # 停止 ssh
sudo systemctl status ssh # 查看目前 ssh 狀態
&lt;/code>&lt;/pre>&lt;p>最後開啟 mac 的終端機，輸入 &lt;code>ssh 你在Ubuntu的username@你的ip&lt;/code> ，不知道 IP 可以輸入 &lt;code>hostname -I&lt;/code> 查看(對外 ip 可以用 &lt;code>curl ipinfo.io&lt;/code>)&lt;/p>
&lt;br>
&lt;p>如果要對外連線又不想設定對外 ip，我推薦 &lt;a class="link" href="https://tmate.io/" target="_blank" rel="noopener"
>tmate&lt;/a> ，你可以把它理解成 terminal 版本的 &lt;a class="link" href="https://www.teamviewer.com/" target="_blank" rel="noopener"
>teamviewer&lt;/a>，挺方便的，我自己的做法是要出門前開幾個 tmate sessions，然後把 id 記在 &lt;a class="link" href="https://www.notion.so/" target="_blank" rel="noopener"
>Notion&lt;/a> 裡。
設定對外 ip 通常只要登入路由器的 Web 介面，通常是輸入網址 192.168.0.1 或 192.168.1.1，然後看你是用什麼路由器再去看他的說明書設定&lt;/p>
&lt;p>想使用外網 IP 來連線的話，記得要設定 Port forwarding，然後將 &lt;code>/etc/ssh/sshd_config&lt;/code> 中的 &lt;code>#Port&lt;/code> 註解拿掉，改成你要的 port。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">vim /etc/ssh/sshd_config
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>儲存退出之後，重啟 ssh 服務&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">service sshd restart
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="一些可能會有的問題">一些可能會有的問題
&lt;/h2>&lt;h3 id="如果在-mac-那邊連線時出現類似以下的訊息">如果在 Mac 那邊連線時出現類似以下的訊息
&lt;/h3>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Someone could be eavesdropping on you right now (man-in-the-middle attack)!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">It is also possible that a host key has just been changed.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">The fingerprint for the ED25519 key sent by the remote host is
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">SHA256:blablablablablablablablablablablablablablab.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Please contact your system administrator.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Add correct host key in /Users/username/.ssh/known_hosts to get rid of this message.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Offending ECDSA key in /Users/username/.ssh/known_hosts:5
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Host key for 192.168.1.137 has changed and you have requested strict checking.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Host key verification failed.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>會這樣可能是因為之前有用這個 IP 連線過導致的 (我就是這樣)，這時候只要用 &lt;code>ssh-keygen -R 你的ip&lt;/code> 就可以了，你也可以到 &lt;code>~/.ssh/known_host&lt;/code> 把有問題的 ip 刪掉。&lt;/p>
&lt;h3 id="筆電蓋上後會自動休眠而無法連線">筆電蓋上後會自動休眠而無法連線
&lt;/h3>&lt;p>因為我只會 ssh 到這台舊筆電，所以用不太到螢幕，每次都要螢幕半開也挺麻煩的&lt;/p>
&lt;p>1.修改 Ubuntu 登入管理配置檔案，將 &lt;code>#HandleLidSwitch=suspend&lt;/code> 改成 &lt;code>HandleLidSwitch=ignore&lt;/code>&lt;/p>
&lt;pre tabindex="0">&lt;code>sudo vim /etc/systemd/logind.conf # 進到編輯器修改 HandleLidSwitch 那一行
&lt;/code>&lt;/pre>&lt;p>2.重啟服務&lt;/p>
&lt;pre tabindex="0">&lt;code>sudo systemctl restart systemd-logind
&lt;/code>&lt;/pre></description></item><item><title>Mac 實用小工具</title><link>https://blog.yenslife.top/post/useful-tools-for-mac/</link><pubDate>Fri, 26 Aug 2022 18:24:34 +0800</pubDate><guid>https://blog.yenslife.top/post/useful-tools-for-mac/</guid><description>&lt;img src="https://i.imgur.com/4uvpVox.png" alt="Featured image of post Mac 實用小工具" />&lt;p>（舊網站文章，撰寫時間：2022-08-26）&lt;/p>
&lt;h2 id="mac-實用小工具不定期更新">Mac 實用小工具（不定期更新！）
&lt;/h2>&lt;p>身為一個 Mac 筆電使用者，今天想跟大家分享我常用的小工具或軟體，不論在寫程式或者日常使用都很常用到的工具，只要有「如果當初有人告訴我去使用這個工具那該有多好」的感覺就會出現在目錄。順便提醒之後要換筆電的自己要裝什麼（雖然我應該沒錢換🤧）。有興趣可以裝來玩玩看，有些工具能節省你非常多時間！這篇文章不會太過著墨在操作方法以及安裝，主要是在分享。以下是目錄。&lt;/p>
&lt;h3 id="桌面與系統相關日常生活">桌面與系統相關（日常生活）
&lt;/h3>&lt;ul>
&lt;li>&lt;a class="link" href="#Alfred%ef%bc%88Spotlight%e5%8d%87%e7%b4%9a%e7%89%88%ef%bc%89" >Alfred（Spotlight 升級版）&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#Rectangle%ef%bc%88%e8%a6%96%e7%aa%97%e8%aa%bf%e6%95%b4%e5%b7%a5%e5%85%b7%ef%bc%89" >Rectangle（視窗調整工具）&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#Bartander%ef%bc%88Menu-Bar-%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7%ef%bc%89" >Bartander（Menu-Bar-管理工具）&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#Itsycal%ef%bc%88%e8%a1%8c%e4%ba%8b%e6%9b%86%e5%b0%8f%e5%b7%a5%e5%85%b7%ef%bc%89" >Itsycal（行事曆小工具）&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#Stats%ef%bc%88%e5%85%8d%e8%b2%bb%e9%96%8b%e6%ba%90%e7%9a%84%e7%b3%bb%e7%b5%b1%e8%b3%87%e6%ba%90%e7%9b%a3%e6%8e%a7%e8%bb%9f%e9%ab%94%ef%bc%89" >Stats（免費開源的系統資源監控軟體）&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#Gifski%ef%bc%88%e5%bd%b1%e7%89%87%e8%bd%89gif%e7%9a%84%e8%b6%85%e5%a5%bd%e7%94%a8%e5%b7%a5%e5%85%b7%ef%bc%89" >Gifski（影片轉gif的超好用工具）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="程式電腦相關資工系可能會用到">程式電腦相關（資工系可能會用到）
&lt;/h3>&lt;ul>
&lt;li>&lt;a class="link" href="#Homebrew%ef%bc%88%e7%a5%9e%e7%b4%9a%e5%a5%97%e4%bb%b6%e7%ae%a1%e7%90%86%e5%b7%a5%e5%85%b7%ef%bc%89" >Homebrew（神級套件管理工具）&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#iterm2%ef%bc%88%e6%9b%b4%e5%a5%bd%e7%9a%84teminal%ef%bc%89" >iterm2（更好的 teminal）&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#Fig%ef%bc%88%e7%b5%82%e7%ab%af%e6%a9%9f%e8%87%aa%e5%8b%95%e8%a3%9c%e5%85%a8%ef%bc%89" >Fig（終端機自動補全）&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#Cloudflare-WARP-VPN%ef%bc%88%e5%85%8d%e8%b2%bb%e6%96%b9%e4%be%bf%e7%9a%84vpn%ef%bc%89" >Cloudflare WARP VPN（免費方便的 vpn）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="其他雜七雜八ㄉ東東">其他（雜七雜八ㄉ東東）
&lt;/h3>&lt;ul>
&lt;li>一些設定（角落關螢幕、dock隱藏）&lt;/li>
&lt;/ul>
&lt;br>
&lt;h3 id="alfredspotlight升級版">Alfred（Spotlight升級版）
&lt;/h3>&lt;p>&lt;img src="https://i.imgur.com/kB65WF7.png"
loading="lazy"
alt="Alfred"
>&lt;/p>
&lt;p>它叫&lt;a class="link" href="https://www.alfredapp.com/" target="_blank" rel="noopener"
>阿福&lt;/a>？因為他就像蝙蝠俠的管家一樣幫你從軟體到檔案管的好好的，只要按下 &lt;code>command + space(空白鍵)&lt;/code> 就可以叫出來，幾乎可以實現不用滑鼠及觸控板的老鳥級操作，想叫什麼就叫什麼，可以讓自己的雙手幾乎是黏在鍵盤上！&lt;/p>
&lt;p>一開始要到 Preference 中做一些設定，並到&lt;strong>系統偏好設定&lt;/strong>中把 Mac 內建的 Spotlight 改成 Alfred 即可使用（當然你想同時保留 Spotlight 或不想用 command + 空白鍵也可以）&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/mcIAeat.png"
loading="lazy"
>&lt;/p>
&lt;p>基本用法：command + 空白鍵 -&amp;gt; 跳出搜尋欄，以下是我常用的搜尋關鍵字：&lt;/p>
&lt;div style="text-align: center">
&lt;img src="https://i.imgur.com/O9mKg0v.png" width="50%"/>
&lt;p style="font-size:50%;">搜尋欄長這樣，也可以自訂喜歡的樣式&lt;/p>
&lt;/div>
&lt;ul>
&lt;li>open + 檔案 -&amp;gt; 開啟檔案&lt;/li>
&lt;li>find + 檔案 -&amp;gt; 從 finder 找到檔案位置&lt;/li>
&lt;li>直接打軟體名稱 -&amp;gt; 開啟軟體&lt;/li>
&lt;li>直接打搜尋內容 -&amp;gt; 用瀏覽起開啟搜尋結果&lt;/li>
&lt;/ul>
&lt;p>Alfred 唯一的小缺點就是要收費，聽說他還可以叫聯絡人和音樂等等，但我只需要基本功能，所以免費版就可以符合我的需求，進階玩法就留給大家試試咯。&lt;/p>
&lt;p>官網連結: &lt;a class="link" href="https://www.alfredapp.com/" target="_blank" rel="noopener"
>https://www.alfredapp.com/&lt;/a>&lt;/p>
&lt;br>
&lt;h3 id="rectangle視窗調整工具">Rectangle（視窗調整工具）
&lt;/h3>&lt;div style="text-align: center">
&lt;img src="https://i.imgur.com/Hwwz1Ud.png" width="35%"/>
&lt;/div>
&lt;p>不知道你有沒有這樣的經驗：打開軟體發現他的視窗位置很奇葩，又或是想同時用兩個視窗來做事情（邊看資料邊打字），於是花了一些時間調整視窗的 size 和位置，但就是沒辦法完美分割成兩個左右視窗？ 讓 &lt;a class="link" href="https://rectangleapp.com/" target="_blank" rel="noopener"
>Rectangle&lt;/a> 幫你搞定吧！免費的真香～&lt;/p>
&lt;p>點擊 menu bar 上的圖示就可以看到所有功能快捷鍵了，主要都是透過 &lt;code>control + alt(option) + 某個鍵&lt;/code> 來控制當下使用的視窗位置與大小。舉幾個我最常用的快捷鍵吧！&lt;/p>
&lt;div style="text-align: center">
&lt;img src="https://i.imgur.com/GmCrsSd.png" width="30%"/>
&lt;p style="font-size:50%;">圖示長這樣&lt;/p>
&lt;/div>
&lt;ul>
&lt;li>&lt;code>control + alt(option) + enter&lt;/code> -&amp;gt; 最大化視窗&lt;/li>
&lt;li>&lt;code>control + alt(option) + 左/右方向鍵&lt;/code> -&amp;gt; 左半/右半&lt;/li>
&lt;li>&lt;code>control + alt(option) + B&lt;/code> -&amp;gt; 接近最大化（有時候這樣蠻舒服的）&lt;/li>
&lt;li>&lt;code>control + alt(option) + C&lt;/code> -&amp;gt; 中央視窗&lt;/li>
&lt;li>&lt;code>control + alt(option) + + / -&lt;/code> -&amp;gt; 放大/縮小視窗&lt;/li>
&lt;/ul>
&lt;p>結果會像這樣：&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/rnr6a07.gif"
loading="lazy"
alt="Rectangle 示範"
>&lt;/p>
&lt;p>官網連結：https://rectangleapp.com/&lt;/p>
&lt;br>
&lt;h3 id="bartandermenu-bar-管理工具">Bartander（Menu-Bar-管理工具）
&lt;/h3>&lt;p>&lt;img src="https://i.imgur.com/hdWrFw3.png"
loading="lazy"
>&lt;/p>
&lt;p>因為我常常裝一些小工具在 Mac 上，一開始沒什麼，但當 Menu bar (螢幕右上角那個)上的東西越來越多時，情況開始不受控制，有些 icon 甚至會消失，Mac 居然沒有內建的管理工具，誇張！於是我找到了這款被人推崇的 &lt;a class="link" href="https://www.macbartender.com/" target="_blank" rel="noopener"
>Bartender&lt;/a>，現在我的右上角看起來整齊多了！(如下，鼠標移到上方叫出所有圖示)&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/N2Pu8e8.gif"
loading="lazy"
alt="bartender 自動"
>&lt;/p>
&lt;p>當然，你也可以自定義喜歡的樣式，像是隱藏的圖示，甚至是建立群組等等。他好像還有快捷鍵叫出的進階玩法，這部分就留給讀者玩玩看吧！&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/TFcWyrV.gif"
loading="lazy"
>&lt;/p>
&lt;p>唯一的小缺點就是：他要錢QQ。如果真的想體驗的話，網路上有很多免費(&lt;del>盜版&lt;/del>)版本的可以下載，但有機會還是支持一下作者吧！他是買斷制的，目前是US$16.80。&lt;/p>
&lt;p>官網連結：https://www.macbartender.com/&lt;/p>
&lt;br>
&lt;h3 id="itsycal行事曆小工具">Itsycal（行事曆小工具）
&lt;/h3>&lt;p>&lt;img src="https://i.imgur.com/dSLqpBm.png"
loading="lazy"
>&lt;/p>
&lt;p>&lt;a class="link" href="https://www.mowglii.com/itsycal/" target="_blank" rel="noopener"
>Itsycal&lt;/a> 是一款 Menu bar 上的行事曆軟體。有時候看到一些活動是在下個月的某某號，想知道他是禮拜幾卻又不想打開行事曆的話，輕點右上角的 &lt;a class="link" href="https://www.mowglii.com/itsycal/" target="_blank" rel="noopener"
>Itsycal&lt;/a> 圖示便能看到行事曆。若你有在使用 Mac 內建的行事曆，他甚至能幫你直接在 Menu bar 安排活動，不需要再多打開一個 app。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/Y4OCUa1.gif"
loading="lazy"
>&lt;/p>
&lt;div style="text-align: center">
&lt;p style="font-size:50%;">效果展示&lt;/p>
&lt;/div>
&lt;p>他還可以自訂圖示，有一套&lt;a class="link" href="https://www.mowglii.com/itsycal/datetime.html" target="_blank" rel="noopener"
>語法&lt;/a>，不會太難，我沒有用因為 mac 就有內建的日期顯示了，所以用一個可愛的表情符號代替 ٩(◕‿◕｡)۶，只要進到 Preference 設定即可！&lt;/p>
&lt;p>免費的就是香，官網&lt;a class="link" href="https://www.mowglii.com/itsycal/datetime.html" target="_blank" rel="noopener"
>連結&lt;/a>&lt;/p>
&lt;br>
&lt;h3 id="stats免費開源的系統資源監控軟體">Stats（免費開源的系統資源監控軟體）
&lt;/h3>&lt;p>&lt;img src="https://i.imgur.com/gGQ88ci.png"
loading="lazy"
>&lt;/p>
&lt;p>我們 Mac 使用者應該是不會太常把電腦關機吧（還是只有我這樣XD），有時候發現電腦開始變卡，不知道是哪個程序在搞，又不想打開「活動監視器」App 來看，這時候就可以透過 &lt;a class="link" href="https://github.com/exelban/stats" target="_blank" rel="noopener"
>Stats&lt;/a> 來觀察執行程序 Ram 使用量，甚至是 GPU、CPU、網路、風扇等等的運作狀態。重點是，只要點右上角的圖示就可以看到了，超方便ㄉ！我之前覺得電腦卡卡的，看了 Stats 馬上就知道原來是虛擬機忘記關、或是我又開了什麼奇怪的程序XD。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/HDqX4Jp.gif"
loading="lazy"
>&lt;/p>
&lt;div style="text-align:center">
&lt;p style="font-size:50%;">效果展示&lt;/p>
&lt;/div>
&lt;p>Homebrew 安裝指令：&lt;code>brew install --cask stats&lt;/code>
官方 Github &lt;a class="link" href="https://github.com/exelban/stats" target="_blank" rel="noopener"
>連結&lt;/a>
下載 dmg 安裝檔 &lt;a class="link" href="https://github.com/exelban/stats/releases/latest/download/Stats.dmg" target="_blank" rel="noopener"
>連結&lt;/a>&lt;/p>
&lt;br>
&lt;h3 id="gifski影片轉gif的超好用工具">Gifski（影片轉gif的超好用工具）
&lt;/h3>&lt;p>&lt;img src="https://i.imgur.com/WJBEHjS.png"
loading="lazy"
>&lt;/p>
&lt;p>&lt;a class="link" href="https://apps.apple.com/tw/app/gifski/id1351639930?mt=12" target="_blank" rel="noopener"
>Gifski&lt;/a> 是一款 mac 影片轉檔工具，轉檔完成後可以直接 copy 影片到剪貼簿，再貼到像是 HackMD 之類的的地方，非常方便。你可以在 App Store 上找到它，他是免費的，這篇文章的 Gif 大部分都是用它來做的呦！&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/TcAt0YH.gif"
loading="lazy"
>&lt;/p>
&lt;div style="text-align:center">
&lt;p style="font-size:50%;">將影片拖近來就可以轉檔，操作簡單明瞭&lt;/p>
&lt;/div>
&lt;p>App Store &lt;a class="link" href="https://apps.apple.com/tw/app/gifski/id1351639930?mt=12" target="_blank" rel="noopener"
>連結&lt;/a>&lt;/p>
&lt;br>
&lt;h3 id="homebrew神級套件管理工具">Homebrew（神級套件管理工具）
&lt;/h3>&lt;p>&lt;img src="https://i.imgur.com/aI1q8PU.png"
loading="lazy"
>&lt;/p>
&lt;p>&lt;a class="link" href="https://brew.sh/" target="_blank" rel="noopener"
>Homebrew&lt;/a> 就像 Mac 版本的 apt (Linux 上的套件管理工具) ，可以在終端機 (terminal) 用指令來安裝套件、軟體等等。想像一下人家 Windows 還在解壓縮，你只要打幾個字就好了，這就是為什麼 Homebrew 如此滴神orz。&lt;/p>
&lt;p>安裝方法如下：&lt;/p>
&lt;ol>
&lt;li>打開終端機 (terminal)。&lt;/li>
&lt;li>在終端機輸入以下指令，然後按 Enter。&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">/bin/bash -c &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="k">$(&lt;/span>curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="k">)&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>分享一些 Homebrew 基本指令：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">brew install &lt;span class="o">[&lt;/span>套件名稱&lt;span class="o">]&lt;/span> // 安裝套件
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew uninstall &lt;span class="o">[&lt;/span>套件名稱&lt;span class="o">]&lt;/span> // 解除安裝
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew update // 更新 brew 到最新版本
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew upgrate &lt;span class="o">[&lt;/span>套件名稱&lt;span class="o">]&lt;/span> // 更新指定套件
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew list // 查看現有的套件以及 Cask
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">brew search &lt;span class="o">[&lt;/span>關鍵字&lt;span class="o">]&lt;/span> // 查詢套件
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>Homebrew Cask 是安裝 GUI 軟體在用的，使用方法同上，只是要在 brew 之後加上 &lt;code>--cask&lt;/code>&lt;/li>
&lt;/ul>
&lt;br>
&lt;h3 id="iterm2更好的teminal">iterm2（更好的teminal）
&lt;/h3>&lt;p>&lt;img src="https://i.imgur.com/5uQ5ukT.png"
loading="lazy"
>&lt;/p>
&lt;p>&lt;a class="link" href="https://iterm2.com/" target="_blank" rel="noopener"
>iterm2&lt;/a> 是一款可以取代 Mac 原生 terminal 的好選擇，不信你看&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/S2ewQPq.png"
loading="lazy"
>&lt;/p>
&lt;p>是不是很漂亮ㄚ，通常 iterm2 會搭配 oh my zsh 框架使用，其實網路上已經有很多很棒的教學了，我覺得自己應該教不贏他們 (也忘記了XD) ，請自行 Google 搜尋一下ㄅ。（關鍵字：oh my zsh, iterm2 教學）&lt;/p>
&lt;p>&lt;a class="link" href="https://iterm2.com/" target="_blank" rel="noopener"
>iterm2 官網&lt;/a>
Home brew 安裝：&lt;code>brew install --cask iterm2&lt;/code>&lt;/p>
&lt;br>
&lt;h3 id="fig終端機自動補全">Fig（終端機自動補全）
&lt;/h3>&lt;p>&lt;img src="https://i.imgur.com/VUdtEMA.png"
loading="lazy"
>&lt;/p>
&lt;p>想不到吧？終端機竟然可以和 IDE 一樣自動補全指令，有了 Fig 就不用一直按 tab 鍵了，上下方向鍵即可選擇指令，安裝後即可發現新世界 (示範如下)，而且他是免費的！&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/MhpcGzM.gif"
loading="lazy"
>&lt;/p>
&lt;p>&lt;a class="link" href="https://fig.io/" target="_blank" rel="noopener"
>Fig 官網連結&lt;/a>&lt;/p>
&lt;br>
&lt;h3 id="cloudflare-warp-vpn免費方便的vpn">Cloudflare-WARP-VPN（免費方便的vpn）
&lt;/h3>&lt;p>&lt;img src="https://i.imgur.com/yu4u6W8.png"
loading="lazy"
>&lt;/p>
&lt;p>如果你是成大的學生，剛好最近在研究加密貨幣投資，那你可能會用到「幣安」這個交易所對吧？但學校的網路居然把它給擋下來了QQ（學校網路總是擋了很多東西），剛好你又沒有使用 VPN 的服務，這時候 &lt;a class="link" href="https://1.1.1.1/" target="_blank" rel="noopener"
>Warp VPN&lt;/a> 就可以幫你一個大忙了！他是 Cloudflare 公司免費提供的 VPN 服務，不用擔心隱私問題，只要點擊 Menu bar 上的雲朵圖示即可使用！&lt;/p>
&lt;div style="text-align:center">
&lt;img src="https://i.imgur.com/DOhXUCZ.gif" width="30%">
&lt;p style="font-size:50%">簡潔有力的使用方式&lt;/p>
&lt;/div>
&lt;p>官網網址：https://1.1.1.1/&lt;/p>
&lt;h3 id="clipy">Clipy
&lt;/h3>&lt;p>Mac 剪貼簿歷史紀錄功能，按下 &lt;code>command + shift + v&lt;/code> 即可叫出歷史紀錄，可以設定紀錄筆數，非常方便！&lt;/p>
&lt;p>&lt;a class="link" href="https://clipy-app.com/" target="_blank" rel="noopener"
>官網連結&lt;/a>&lt;/p>
&lt;p>&lt;img src="https://imgur.com/cjLMYWs.png"
loading="lazy"
>&lt;/p>
&lt;h3 id="bob">Bob
&lt;/h3>&lt;p>OCR 文字識別工具，可以將圖片上的文字轉成文字檔，很適合在有時候線上 meeting 時需要快速記錄文字的時候使用，真的太多時候用到了！重點是他是免費的！&lt;/p>
&lt;p>使用方法：&lt;code>optoin + s&lt;/code> 即可叫出，然後圈選出你要識別的區域，就像 Mac 的 &lt;code>command + shift + 4&lt;/code> 截圖一樣&lt;/p>
&lt;p>&lt;a class="link" href="https://github.com/ripperhe/Bob" target="_blank" rel="noopener"
>https://github.com/ripperhe/Bob&lt;/a>&lt;/p>
&lt;p>&lt;img src="https://imgur.com/DCTvH5s.gif"
loading="lazy"
>&lt;/p>
&lt;h3 id="一些設定角落關螢幕dock隱藏">一些設定（角落關螢幕、dock隱藏）
&lt;/h3>&lt;p>(待補)&lt;/p></description></item><item><title>UVa10190：Divide, But Not Quite Conquer!</title><link>https://blog.yenslife.top/post/uva10190/</link><pubDate>Mon, 11 Jul 2022 19:27:36 +0800</pubDate><guid>https://blog.yenslife.top/post/uva10190/</guid><description>&lt;img src="https://i.imgur.com/vFpXPab.png" alt="Featured image of post UVa10190：Divide, But Not Quite Conquer!" />&lt;p>（舊網站文章，撰寫時間：2022-07-11）&lt;/p>
&lt;h2 id="uva10190divide-but-not-quite-conquer">UVa10190：Divide, But Not Quite Conquer!
&lt;/h2>&lt;p>這是我在練習 CPE 歷屆題目時，順手寫下的解題心得，提醒自己不再重蹈覆徹。&lt;/p>
&lt;p>題目連結：&lt;a class="link" href="https://onlinejudge.org/external/101/10190.pdf" target="_blank" rel="noopener"
>10190.pdf (onlinejudge.org)&lt;/a>&lt;/p>
&lt;p>這題我主要採了兩個坑：&lt;/p>
&lt;ol>
&lt;li>&lt;a class="link" href="#%e5%95%8f%e9%a1%8c%e6%aa%a2%e8%a8%8e%ef%bc%88%e8%b8%a9%e5%88%b0pow%e7%9a%84%e5%9d%91%e4%ba%86%ef%bc%89" >搞不清楚&lt;code>pow()&lt;/code> 方法的實作細節，導致在強制轉型時數值有誤差。&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e5%95%8f%e9%a1%8c%e6%aa%a2%e8%a8%8e%ef%bc%88%e4%b8%8d%e5%a4%a0%e7%b4%b0%e5%bf%83%ef%bc%89" >沒有考慮到分母為0和1的情況。&lt;/a>&lt;/li>
&lt;/ol>
&lt;p>以下是我的程式碼：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#define true 1
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#define false 0
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#define bool int
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&amp;lt;stdio.h&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&amp;lt;math.h&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">bool&lt;/span> &lt;span class="nf">division&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">power&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">while&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">scanf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;%ld %ld&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="n">EOF&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="n">division&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Boring!&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">division&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">power&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">((&lt;/span>&lt;span class="kt">long&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">round&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">pow&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="kt">double&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">double&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="p">))&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">power&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">break&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">power&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;%d &amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">round&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">)));&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;1&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">bool&lt;/span> &lt;span class="nf">division&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">long&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">||&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">false&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">division&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>我的思路是，先用遞迴函式(因為感覺很帥，還有不知道為什麼在前面用&lt;code>#define&lt;/code>很厲害的感覺XD，但其實效能很慘，這題一顆星而已所以影響不大)判斷分子是否為分母的次方數，若為否則可直接印出boring!；若為是，則先用迴圈計算指數大小，就可以將答案印出來。&lt;/p>
&lt;h3 id="問題檢討踩到pow的坑了">問題檢討（踩到pow的坑了）
&lt;/h3>&lt;p>參考網站 &lt;a class="link" href="https://blog.csdn.net/qq_41115379/article/details/105159542" target="_blank" rel="noopener"
>C/C++ pow()函数结果强制类型转换为整型的误差分析_关切得大神的博客-CSDN博客&lt;/a>&lt;/p>
&lt;p>觀察以下函數 你覺得執行結果是什麼呢&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="n">printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;%d&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>答案是：99。奇怪，結果不應該是100嗎？原因其實很簡單，&lt;code>double pow(double x, double y)&lt;/code> 回傳值是以數值逼近的方法來的到double的數值的。舉例來說：99.9999最後會變成99。&lt;/p>
&lt;p>這邊&lt;a class="link" href="https://blog.csdn.net/qq_41115379" target="_blank" rel="noopener"
>关切得大神&lt;/a>給了個相當不錯的方法，對&lt;code>pow()&lt;/code> 的回傳值做一次四捨五入&lt;code>round()&lt;/code> 就行了，因為我們知道，&lt;code>pow()&lt;/code> 的回傳值已經很接近數學計算的答案了。請參考下方程式碼。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="n">printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;%d&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">round&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">pow&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>因為真的太久沒寫，又覺得自己應該都是對的，導致我差點以為是編譯器的問題(這哪來的自信)。神奇的是，原本的程式碼(還沒四捨五入)的執行結果在 online compiler 以及 mac 環境的 vs code 中都可以正常運作，但在瘋狂程設卻會遇到數值誤差。這個故事告訴我，幸好有裝瘋狂程設來試，如果我一樣在 Mac 練習可能永遠無法發現這個錯誤，到時候考 CPE 遇到這問題就爆炸ㄌ。順帶一提，我是用虛擬機跑 Windows 的，&lt;del>有機會再分享免費使用的方法 沒&lt;/del>。&lt;/p>
&lt;h3 id="問題檢討不夠細心">問題檢討（不夠細心）
&lt;/h3>&lt;p>再來就是沒有考慮到的測資了，可能是太就沒有解程式題目了，居然忘記要把分母為0和1的情況考慮進去。這題的情況是，若分母為0或1，也就是沒有結果，那就要印出boring!，如果沒有做條件判斷將會得到浮點數例外，要小心喔。&lt;/p></description></item><item><title>在 Mac 上使用 lima 作為 Linux 環境</title><link>https://blog.yenslife.top/post/use-lima-on-mac-as-linux-environment/</link><pubDate>Tue, 05 Jul 2022 18:35:07 +0800</pubDate><guid>https://blog.yenslife.top/post/use-lima-on-mac-as-linux-environment/</guid><description>&lt;img src="https://i.imgur.com/Ra8Ur5T.png" alt="Featured image of post 在 Mac 上使用 lima 作為 Linux 環境" />&lt;p>（舊網站文章，撰寫時間：2022-07-05）&lt;/p>
&lt;h2 id="在-mac-上使用-lima-作為-linux-環境">在 Mac 上使用 lima 作為 Linux 環境
&lt;/h2>&lt;h3 id="目錄">目錄
&lt;/h3>&lt;ol>
&lt;li>&lt;a class="link" href="#%e5%ae%89%e8%a3%9d" >安裝&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e4%bd%bf%e7%94%a8%e6%96%b9%e5%bc%8f" >使用方式&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="#%e5%95%8f%e9%a1%8c%e4%b8%80%ef%bc%88%e7%84%a1%e6%b3%95%e8%ae%80%e5%af%ab%e7%9a%84%e5%95%8f%e9%a1%8c%ef%bc%89" >問題一（無法讀寫的問題）&lt;/a>&lt;/li>
&lt;/ol>
&lt;h2 id="前言">前言
&lt;/h2>&lt;p>因為最近想打看看 picoCTF，需要使用 Linux 環境。由於我使用的是 MacOS，他畢竟不是 Linux，雖然有些指令可以通用，但在程式執行結果上有很大的不同。於是我決定使用 lima 作為我的 Linux container，原本有想過要用 VMWare 虛擬機的方式，但是一想到每次我想打打 CTF 就要讓這台老 MacBook pro(late 2013)受苦就於心不忍。
事實也是如此，我一開 VMWare，老夥伴的風扇就又開始叫了🤧。&lt;/p>
&lt;h3 id="安裝">安裝
&lt;/h3>&lt;p>我是使用 &lt;a class="link" href="https://brew.sh/index_zh-tw" target="_blank" rel="noopener"
>homebrew&lt;/a> 安裝的，記得到&lt;a class="link" href="https://brew.sh/index_zh-tw" target="_blank" rel="noopener"
>官方網站&lt;/a>下載喔。先輸入以下指令。&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-bash=" data-lang="bash=">$ brew install lima # 安裝 lima
$ limactl start # 安裝虛擬機
&lt;/code>&lt;/pre>&lt;p>當出現以下畫面，使用方向鍵上下來選擇配置，我們只要用預設的就行了，所以直接按 enter，看到READY就是完成了！&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-bash=" data-lang="bash=">? Creating an instance &amp;#34;default&amp;#34; [Use arrows to move, type to filter]
&amp;gt; Proceed with the default configuration
Open an editor to override the configuration
Exit
...
INFO[0111] READY. Run `lima` to open the shell.
&lt;/code>&lt;/pre>&lt;p>下載完成可以執行&lt;code>lima uname -a&lt;/code>來確認虛擬機已經在執行&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-bash=" data-lang="bash=">$ Linux lima-default 5.15.0-39-generic #42-Ubuntu SMP Thu Jun 9 23:42:32 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
&lt;/code>&lt;/pre>&lt;h3 id="使用方式">使用方式
&lt;/h3>&lt;p>直接在終端機輸入&lt;code>lima&lt;/code>就可以執行了，若要離開就直接輸入&lt;code>exit&lt;/code>。
(&lt;del>剛裝好時我還不知道怎麼離開，所以都用兩個 terminal 視窗，一個是 lima 一個是 zsh，不要跟我一樣蠢喔qq&lt;/del>)
如果沒有要使用虛擬機也記得關掉它，不然他會默默吃掉你的記憶體，輸入&lt;code>lima stop [虛擬機名稱]&lt;/code> 來關閉虛擬機。&lt;/p>
&lt;p>&lt;img src="https://i.imgur.com/4v2K8Fw.png"
loading="lazy"
alt="示意圖"
>&lt;/p>
&lt;p>至於容器的部分我還沒研究，這是 lima 的強項，它被號稱可以成為取代 docker 的 macOS Subsystem Linux。但畢竟我只是需要一個方便的 Linux 環境來練CTF，有興趣的朋友請參考&lt;a class="link" href="https://github.com/lima-vm/lima" target="_blank" rel="noopener"
>lima原始碼&lt;/a>。&lt;/p>
&lt;h3 id="問題一無法讀寫的問題">問題一（無法讀寫的問題）
&lt;/h3>&lt;p>如果你在 lima 想要用&lt;code>mkdir&lt;/code>指令，或者用&lt;code>vim&lt;/code>簡單改一下檔案，可能會出現這行。
&lt;code>lima mkdir cannot create directory Read-only file system&lt;/code>
我在找資料時發現了&lt;a class="link" href="https://ithelp.ithome.com.tw/questions/10188327" target="_blank" rel="noopener"
>這篇問答&lt;/a>，原本也以為是系統資料出問題，但我的情況好像和他不太一項。後來我找到這篇 &lt;a class="link" href="https://github.com/lima-vm/lima/issues/34" target="_blank" rel="noopener"
>lima 的 Github issue&lt;/a>，發現其實是 &lt;a class="link" href="https://github.com/lima-vm/lima/issues/34" target="_blank" rel="noopener"
>lima 設定檔&lt;/a>的問題。以下的指令在 zsh 或 bash 中都能使用，如果你在 lima shell 中使用會發現找不到這個檔案喔。總之就是開 mac 原本的 terminal 就對了。解決方式如下。&lt;/p>
&lt;ol>
&lt;li>修改設定檔&lt;/li>
&lt;/ol>
&lt;pre tabindex="0">&lt;code class="language-bash=" data-lang="bash=">$ vim ~/.lima/default/lima.yaml # 先用 vim 編輯設定檔。
# 有點長我就不貼上來了，找到 writable: null 並改成 writable: true
writable: null -&amp;gt; writable: true
&lt;/code>&lt;/pre>&lt;ol start="2">
&lt;li>重新跑 lima&lt;/li>
&lt;/ol>
&lt;pre tabindex="0">&lt;code class="language-bash=" data-lang="bash=">$ limactl list 這個指令可以列出所有正在執行的虛擬機，我看到的是名為 default 的虛擬機
$ limactl stop default 將它停止運行，default 可以替換成你的虛擬機名稱
$ limactl start default 同上，default 可以替換成你的虛擬機名稱
&lt;/code>&lt;/pre>&lt;ol start="3">
&lt;li>恭喜你成功了！&lt;/li>
&lt;/ol>
&lt;h3 id="參考資料">參考資料
&lt;/h3>&lt;p>&lt;a class="link" href="https://github.com/lima-vm/lima" target="_blank" rel="noopener"
>lima原始碼&lt;/a>
&lt;a class="link" href="https://github.com/lima-vm/lima/blob/41fd9cc6a1e2bac73666e1f2b11604c7c42227dc/pkg/limayaml/default.TEMPLATE.yaml#L33-L41" target="_blank" rel="noopener"
>參考資料(lima issue 34)&lt;/a>
&lt;a class="link" href="https://github.com/lima-vm/lima/issues/34" target="_blank" rel="noopener"
>參考資料(lima 設定檔)&lt;/a>&lt;/p></description></item><item><title/><link>https://blog.yenslife.top/page/intro/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.yenslife.top/page/intro/</guid><description>&lt;h1 id="海狸大師部落格-٩۶">海狸大師部落格 ٩(◕‿◕｡)۶
&lt;/h1>&lt;p>歡迎來到我的網站！恭喜你點進來了🎉，眼光真好😎。這邊主要會分享我學習時遇到的問題與心得，主要是資訊領域的東東&lt;/p>
&lt;ul>
&lt;li>&lt;a class="link" href="https://blog.yenslife.top/page/about" >關於我&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://yenslife.top/" target="_blank" rel="noopener"
>個人網站&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>這邊我應該都會放一些正經的東西，如果想要看不正經的可以到&lt;a class="link" href="https://reststop.yenslife.top" target="_blank" rel="noopener"
>另一個網站&lt;/a>；如果你是 Python 新手剛好對 LLM 有興趣，歡迎參考我的書《&lt;a class="link" href="https://llm-book.yenslife.top/" target="_blank" rel="noopener"
>零基礎玩轉 LLM 應用全攻略：Python × No-Code 實作 AI 開發超簡單&lt;/a>》&lt;/p></description></item><item><title>Links</title><link>https://blog.yenslife.top/page/links/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.yenslife.top/page/links/</guid><description>&lt;p>這邊有我的一些連結，點點看可能會有驚喜喔！&lt;/p>
&lt;h3 id="出版作品">出版作品
&lt;/h3>&lt;p>&lt;a class="link" href="https://llm-book.yenslife.top/" target="_blank" rel="noopener"
>零基礎玩轉 LLM 應用全攻略：Python × No-Code 實作 AI 開發超簡單&lt;/a>&lt;/p>
&lt;h3 id="筆記分享區">筆記分享區
&lt;/h3>&lt;ul>
&lt;li>⭐️ &lt;a class="link" href="https://yenslife.notion.site/CPE-fffac79b8c064376841be037a80680db" target="_blank" rel="noopener"
>CPE 顆星題目解題心得&lt;/a>&lt;/li>
&lt;li>🏴 &lt;a class="link" href="https://yenslife.notion.site/picoCTF-f40ab60069d34c90a1017ff4980e47b6" target="_blank" rel="noopener"
>PicoCTF 雜亂筆記&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://yenslife.notion.site/Problem-1-Hashing-Bloom-Filter-647ee1b56ac34d668c0aba935289e99b" target="_blank" rel="noopener"
>Bloom Filter 實驗與實作&lt;/a> 資料結構課程報告分享&lt;/li>
&lt;li>&lt;a class="link" href="https://yenslife.notion.site/VoiceFinance-12c40ba8bf1b48129d9d7ed516b3214f?pvs=4" target="_blank" rel="noopener"
>VoiceFinance 語音記帳系統&lt;/a> 用講話的方式來記帳！&lt;/li>
&lt;/ul>
&lt;h3 id="ithome-鐵人賽紀錄">IThome 鐵人賽紀錄
&lt;/h3>&lt;ul>
&lt;li>&lt;a class="link" href="https://ithelp.ithome.com.tw/users/20168885/ironman/7699" target="_blank" rel="noopener"
>Python 新手的 AI 之旅：從零開始打造屬於你的 AI / LLM 應用&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>搜尋</title><link>https://blog.yenslife.top/page/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.yenslife.top/page/search/</guid><description/></item><item><title>歸檔</title><link>https://blog.yenslife.top/page/archives/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.yenslife.top/page/archives/</guid><description/></item><item><title>關於我</title><link>https://blog.yenslife.top/page/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.yenslife.top/page/about/</guid><description>&lt;h2 id="-個人履歷">📋 個人履歷
&lt;/h2>&lt;p>歡迎來到我的網站！這邊主要會分享我學習時遇到的問題與心得，對生活與一些作品的想法～&lt;/p>
&lt;p>我是目前正就讀資訊所的研究生，喜歡學習新東西，最近在研究資安、AI 的東東。喔然後我最近寫了一本書&lt;a class="link" href="https://llm-book.yenslife.top/" target="_blank" rel="noopener"
>(連結點我)&lt;/a>，對 Python 和 LLM 有興趣的朋友可以參考看看歐，特別是新手的朋友&lt;/p>
&lt;p>目前網站定位是一半技術文章，一半心得文章。至於為什麼要寫技術文章呢？因為我的記性不好唉，寫文章可以隨時回來複習之前學過的東東，也能加深自己的印象，最重要的是可以分享給所有的朋友！&lt;/p>
&lt;p>若發現內容有誤，歡迎透過以下 E-mail 聯絡我。&lt;/p>
&lt;p align="center">
&lt;strong>&lt;a href="mailto:77geo5rge6@gmail.com">77geo5rge6@gmail.com&lt;/a>&lt;/strong>
&lt;/p>
&lt;p>更多詳細的個人資歷、作品集與專業經驗，歡迎參觀我的個人網站：&lt;/p>
&lt;p align="center">
&lt;strong>&lt;a href="https://yenslife.top" target="_blank">yenslife.top&lt;/a>&lt;/strong>
&lt;/p></description></item></channel></rss>