<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>HACKCATML</title>
    <link>https://hackcatml.tistory.com/</link>
    <description>Information Security Blogger</description>
    <language>ko</language>
    <pubDate>Mon, 13 Jul 2026 09:39:17 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>hackcatml</managingEditor>
    <image>
      <title>HACKCATML</title>
      <url>https://tistory1.daumcdn.net/tistory/3087109/attach/7cb1e1434df847869d6a973cce07f3f8</url>
      <link>https://hackcatml.tistory.com</link>
    </image>
    <item>
      <title>비트코인 자동매매 시스템</title>
      <link>https://hackcatml.tistory.com/204</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 육아를 하면서 느끼는 점은 &quot;돈이 모이지 않는다&quot;는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이래서는 미래가 그려지지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 아기가 생기기 전까지가 돈을 모을 수 있는 골든타임이라고 많이들 하는 것 같습니다. 골든타임을 놓쳐버렸...흑&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;월급외에 부수입을 한푼이라도 더 만들긴 해야 하는데...방법이 마땅히 떠오르지 않더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;투잡을 뛰자니 몸이 예전같지 않고, 불법 해킹을 할 수도 없고...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그나마 간간히 재미를 보던 비트코인이 떠올랐습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매월 부수입을 만들어야 하니 무작정 비트코인 사고 3, 4년 존버하는 방식은 안되겠고, 단타로 접근해야 겠더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현물 단타는 시드를 크게 집어넣어야 유의미한 수익을 얻을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그에 반해 선물 단타는 레버리지를 사용하기 때문에, 적은 시드로도 유의미한 수익을 얻을 수 있죠. 단, 청산이라는 위험이 있어서 단타 잘못치다가 자산이 삭제되는 일이 비일비재합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현물 단타에 큰 시드를 넣고 운영하기에는 압박감이 심하고, 본업에 집중도 안될것 같아서 선물 단타로 방향을 정했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선물에서 돈을 따는 법을 우리 모두는 알고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신만의 로직에 따른 &quot;기계적 매매&quot;...그런데 저 포함 99% 휴먼은 이 감정 통제가 안되어서 선물의 끝인 청산을 보게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;감정 통제는 코드가 해주면 되잖아?&quot; 나의 손가락 개입을 최소화해주는 매매 로직을 짠다면 승산이 있겠다 생각이 들더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 자동매매를 알아보기 시작했는데, 트레이딩뷰라는 좋은 툴이 있더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파인스크립트라는 전용 스크립트를 사용해서 정교한 매매 로직을 작성하는 것이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리하여 5월달부터 비트코인 자동매매 개발을 시작했는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트레이딩뷰 매매로직 + 웹훅 서버 프론트 + 시그널 처리 웹훅 서버 + DB 연동 으로 구성하였습니다. (Bitget 전용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매매로직에서 시그널이 발동되면 웹훅 서버에서 시그널을 받아서 Bitget 에 주문을 넣는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 매매로직인데, 순환매 + 엘리엇파동 + 피보나치 + 개인 경험 짬뽕해서 로직을 작성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매매로직 이름은 고양이 쥐잡듯이 저점 잡으라고 쥐캣(G-Cat) 이라고 명명...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 20.06.01 ~ 25.06.01 5년 백테스팅 돌려보니 수익률 4688% 나오네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흠...과거에 비트코인이 워낙 폭등을 했었으니 좋게 나오나 봅니다. 앞으로도 이렇게 나오면 좋겠네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1810&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBA1Nh/btsQW4cPH2v/PUPvJV0VRfZBkLlMAQVR5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBA1Nh/btsQW4cPH2v/PUPvJV0VRfZBkLlMAQVR5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBA1Nh/btsQW4cPH2v/PUPvJV0VRfZBkLlMAQVR5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBA1Nh%2FbtsQW4cPH2v%2FPUPvJV0VRfZBkLlMAQVR5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1810&quot; height=&quot;796&quot; data-origin-width=&quot;1810&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5월 달부터 개발과 동시에 테스트를 진행하였는데, 말이 테스트지 시드가 작았을뿐 실매매를 진행하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1 ~ 5 번째 매매까지는 시드 1000달러, 5 ~ 10 번째 매매까지는 시드 5000달러로 진행하고 전부 익절하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 그림은 9번째, 10번째 테스트 매매. 1차 진입한 상태에서 바로 차트가 방향을 틀어서 1차 익절(녹색선), 2차 익절(파란선) 을 할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3차 익절은 빨간선을 건드리면 되는데, 3차선 안 닿을것 같으면 그냥 수동으로 개입해서 익절하고 &quot;Long Close Manual&quot; 이라고 표시합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1819&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kRNRq/btsQVADM36E/knxJFT4HVyYkbABZokgFBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kRNRq/btsQVADM36E/knxJFT4HVyYkbABZokgFBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kRNRq/btsQVADM36E/knxJFT4HVyYkbABZokgFBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkRNRq%2FbtsQVADM36E%2FknxJFT4HVyYkbABZokgFBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1819&quot; height=&quot;762&quot; data-origin-width=&quot;1819&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1625&quot; data-origin-height=&quot;1152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jde33/btsQYuhtO83/hTNvC0x5A4yPx0sKXFolP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jde33/btsQYuhtO83/hTNvC0x5A4yPx0sKXFolP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jde33/btsQYuhtO83/hTNvC0x5A4yPx0sKXFolP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJde33%2FbtsQYuhtO83%2FhTNvC0x5A4yPx0sKXFolP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;586&quot; height=&quot;415&quot; data-origin-width=&quot;1625&quot; data-origin-height=&quot;1152&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 적은 시드로 돌리는 10번의 테스트는 끝났고, 시드를 상향 조정(만달러 단위)해서 돌리고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흠 이게 되는건가 싶지만...완벽한 것은 없겠지요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선물시장은 정말 위험하기 때문에 조심해서 운영해보려고 합니다. (내가 만들었고 5년 백테스팅 기간동안 청산 한번 없었지만 시장 자체가 확률 싸움이니 내가 만든 로직을 100% 믿을 수 없는 아이러니...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 10번 테스트 매매 끝나면 Bitget 에 카피 트레이딩(다른 투자자들이 쥐캣의 매수 매도를 그대로 카피해서 투자하는 것)을 오픈하려고 했는데, 최근에 시그널이 안울리는 오류도 있고 해서 아직은 위험하다 판단이 되어서 당분간은 혼자서 계속 돌려보려구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코인 및 재테크 관심 있으신 분들은 텔방 들어오셔서 보안쟁이가 자본주의 세상에서 살아남기 위해 발버둥치는거 구경하십쇼.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://t.me/+VvTCsJa0fIhiYzc1&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://t.me/+VvTCsJa0fIhiYzc1&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Auto Trading</category>
      <category>비트코인</category>
      <category>빗겟</category>
      <category>선물</category>
      <category>자동매매</category>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/204</guid>
      <comments>https://hackcatml.tistory.com/204#entry204comment</comments>
      <pubDate>Tue, 30 Sep 2025 21:23:03 +0900</pubDate>
    </item>
    <item>
      <title>Magisk v27.0+ 달라진 점 (Zygote Injection 방식)</title>
      <link>https://hackcatml.tistory.com/203</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Magisk v27.0 이후로 많은 부분이 업데이트 되었지만 주목할 만한 것은, Zygisk의 Zygote Injection 방식이 달라진 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 버전에서는 LD_PRELOAD 방식을 이용하여 Injection 하였습니다. 이 방식은 linker 에 침투 흔적을 남겨서 zygisk 활성화 여부를 탐지 할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v27.0 에서는 Zygote Injection 으로 native bridge 방식이 도입되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Zygisk 가 없던 시절 Riru (&lt;a href=&quot;https://github.com/RikkaApps/Riru?tab=readme-ov-file&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/RikkaApps/Riru?tab=readme-ov-file&lt;/a&gt;) 가 해당 방식으로 Zygote Injection 을 구현하였는데, Zygisk 도 해당 방식을 차용한 것으로 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Native bridge 방식이 어떤 흔적을 남기는지 간략히 확인해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Magisk 에서 Zygisk 기능을 활성화하고 재부팅을 해보면 &quot;Unsupported native bridge API...&quot; 로그를 볼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFrxXt/btsJmxHzkER/BARP4ikO3wR1sGMyiBS0J1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFrxXt/btsJmxHzkER/BARP4ikO3wR1sGMyiBS0J1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFrxXt/btsJmxHzkER/BARP4ikO3wR1sGMyiBS0J1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFrxXt%2FbtsJmxHzkER%2FBARP4ikO3wR1sGMyiBS0J1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;319&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 로그는 안드로이드 소스코드의 native_bridge.cc 에서 찾을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처: &lt;a href=&quot;https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:art/libnativebridge/native_bridge.cc;drc=1aa5d121d7eb21a96f42cfd396e56bf2acdca162;l=231&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:art/libnativebridge/native_bridge.cc;drc=1aa5d121d7eb21a96f42cfd396e56bf2acdca162;l=231&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스 코드를 보면 해당 로그를 찍고, callbacks = nullptr; 로 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과 CloseNativeBridge(true); 가 호출됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1725258125034&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bool LoadNativeBridge(const char* nb_library_filename,
                      const NativeBridgeRuntimeCallbacks* runtime_cbs) {
  // We expect only one place that calls LoadNativeBridge: Runtime::Init. At that point we are not
  // multi-threaded, so we do not need locking here.

  if (state != NativeBridgeState::kNotSetup) {
    // Setup has been called before. Ignore this call.
    if (nb_library_filename != nullptr) {  // Avoids some log-spam for dalvikvm.
      ALOGW(&quot;Called LoadNativeBridge for an already set up native bridge. State is %s.&quot;,
            GetNativeBridgeStateString(state));
    }
    // Note: counts as an error, even though the bridge may be functional.
    had_error = true;
    return false;
  }

  if (nb_library_filename == nullptr || *nb_library_filename == 0) {
    CloseNativeBridge(false);
    return false;
  } else {
    if (!NativeBridgeNameAcceptable(nb_library_filename)) {
      CloseNativeBridge(true);
    } else {
      // Try to open the library. We assume this library is provided by the
      // platform rather than the ART APEX itself, so use the system namespace
      // to avoid requiring a static linker config link to it from the
      // com_android_art namespace.
      void* handle = OpenSystemLibrary(nb_library_filename, RTLD_LAZY);

      if (handle != nullptr) {
        callbacks = reinterpret_cast&amp;lt;NativeBridgeCallbacks*&amp;gt;(dlsym(handle,
                                                                   kNativeBridgeInterfaceSymbol));
        if (callbacks != nullptr) {
          if (isCompatibleWith(NAMESPACE_VERSION)) {
            // Store the handle for later.
            native_bridge_handle = handle;
          } else {
            ALOGW(&quot;Unsupported native bridge API in %s (is version %d not compatible with %d)&quot;,
                  nb_library_filename, callbacks-&amp;gt;version, NAMESPACE_VERSION);
            callbacks = nullptr;
            dlclose(handle);
          }
        } else {
          dlclose(handle);
          ALOGW(&quot;Unsupported native bridge API in %s: %s not found&quot;,
                nb_library_filename, kNativeBridgeInterfaceSymbol);
        }
      } else {
        ALOGW(&quot;Failed to load native bridge implementation: %s&quot;, dlerror());
      }

      // Two failure conditions: could not find library (dlopen failed), or could not find native
      // bridge interface (dlsym failed). Both are an error and close the native bridge.
      if (callbacks == nullptr) {
        CloseNativeBridge(true);
      } else {
        runtime_callbacks = runtime_cbs;
        state = NativeBridgeState::kOpened;
      }
    }
    return state == NativeBridgeState::kOpened;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CloseNativeBridge 함수의 소스코드는 다음과 같은데, CloseNativeBridge(true); 호출 결과 had_error 값이 true 로 설정되는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처: &lt;a href=&quot;https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:art/libnativebridge/native_bridge.cc;drc=1aa5d121d7eb21a96f42cfd396e56bf2acdca162;l=225&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:art/libnativebridge/native_bridge.cc;drc=1aa5d121d7eb21a96f42cfd396e56bf2acdca162;l=225&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1725258430085&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static void CloseNativeBridge(bool with_error) {
  state = NativeBridgeState::kClosed;
  had_error |= with_error;
  ReleaseAppCodeCacheDir();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 had_error 가 메모리의 어디에 위치해 있나가 궁금한데, 그것은 libnativebridge.so 파일을 IDA 로 까보면 알 수 있습니다. 음 소스코드와 IDA 를 비교해보니 had_error 변수가 byte_5288 에 있군요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2060&quot; data-origin-height=&quot;802&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btUvSC/btsJpjOuqMI/JVX6k0S77rG48YYsOJKXgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btUvSC/btsJpjOuqMI/JVX6k0S77rG48YYsOJKXgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btUvSC/btsJpjOuqMI/JVX6k0S77rG48YYsOJKXgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtUvSC%2FbtsJpjOuqMI%2FJVX6k0S77rG48YYsOJKXgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2060&quot; height=&quot;802&quot; data-origin-width=&quot;2060&quot; data-origin-height=&quot;802&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;byte_5288 은 .bss segment 의 시작부분입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oLdws/btsJpnpARLI/zph6io8IEd5qKuJKUavPTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oLdws/btsJpnpARLI/zph6io8IEd5qKuJKUavPTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oLdws/btsJpnpARLI/zph6io8IEd5qKuJKUavPTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoLdws%2FbtsJpnpARLI%2Fzph6io8IEd5qKuJKUavPTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1670&quot; height=&quot;676&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 앱 프로세스에서도 확인 가능합니다. Zygisk 활성화 후 아무앱이나 실행시키고 Frida 로 libnativebridge.so 의 오프셋 0x5288 로 이동해봅니다. 0x1 이 설정되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Zygisk 가 비활성화된 상태에서는 had_error 값이 false 이므로 앱 프로세스에서 확인하면 0x0 이 설정되어 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;448&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d6aXQy/btsJoAws2d0/roIAOF4la8VHnIe5FkBRKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d6aXQy/btsJoAws2d0/roIAOF4la8VHnIe5FkBRKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d6aXQy/btsJoAws2d0/roIAOF4la8VHnIe5FkBRKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd6aXQy%2FbtsJoAws2d0%2FroIAOF4la8VHnIe5FkBRKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1001&quot; height=&quot;448&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;448&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;헛?! 그렇다면 이것으로 Zygisk 를 탐지할 수 있는것인가!! 라는 생각이 들 수 있지만, 매지스크 개발자 topjohnwoo 도 알고 있겠죠. 아마 이정도 사소한 것은 모듈단에서 알아서 처리하라고 내비두지 않았을까 생각됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shamiko (&lt;a href=&quot;https://github.com/LSPosed/LSPosed.github.io/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/LSPosed/LSPosed.github.io/releases&lt;/a&gt;) 나 Zygisk-Assistant (&lt;a href=&quot;https://github.com/snake-4/Zygisk-Assistant/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/snake-4/Zygisk-Assistant/releases&lt;/a&gt;) 모듈을 설치하면 해당 값을 0x0 으로 패치해줍니다. 따라서 유의미한 탐지 방식이 될 수는 없겠죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음 여기까지 봤을때 제 짧은 식견으로는 Zygisk 자체를 어떻게 탐지해야 할지 아이디어가 떠오르지 않더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 뛰어난 해커, 솔루션 개발자들은 탐지하고 있겠죠?? 저도 더욱 분발해야 겠네요 :)&lt;/p&gt;</description>
      <category>Information Security/Android</category>
      <category>androidreverseengineering</category>
      <category>magisk</category>
      <category>nativebridge</category>
      <category>Reversing</category>
      <category>Zygisk</category>
      <category>ZygoteInjection</category>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/203</guid>
      <comments>https://hackcatml.tistory.com/203#entry203comment</comments>
      <pubDate>Tue, 3 Sep 2024 10:04:17 +0900</pubDate>
    </item>
    <item>
      <title>모바일 해킹, 보안 주제로 자유롭게 대화 나눠요</title>
      <link>https://hackcatml.tistory.com/notice/202</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;텔레그램 채널 및 대화방 개설하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모바일 해킹, 보안, 리버싱 관심 있으신 분들은 들어오셔서 자유롭고 편하게 대화 나눠봐요 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채널: &lt;a href=&quot;https://t.me/hackcatml1&quot;&gt;https://t.me/hackcatml1&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대화방: &lt;a href=&quot;https://t.me/hackcatmlchat&quot;&gt;https://t.me/hackcatmlchat&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/notice/202</guid>
      <pubDate>Mon, 2 Sep 2024 13:40:32 +0900</pubDate>
    </item>
    <item>
      <title>Android SO File Dump</title>
      <link>https://hackcatml.tistory.com/199</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;악성코드 분석을 하다 보면 반복적으로  so 파일을 추출하고 있는 자신을 발견하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apk를 까봤더니 그 안에 타겟 so 파일이 들어 있고 IDA에서 문제없이 열린다면 매우 땡큐입니다. 분석 난이도가 매우 낮은 경우로 흔하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇지 않은 경우에도, frida 가 순조롭게 붙기만 하면 쉽게 타겟 so 파일을 획득할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 조금 난이도가 있는 친구들은 frida 탐지 기능은 내비둔채, 앱의 솔루션을 무력화합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 frida 탐지 기능을 우회하면 되지만, 여의치 않은 경우 native 모듈을 만들어 so 파일을 추출하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 그림의 so 로딩 흐름을 보면, 최종적으로 linker 의 do_dlopen 을 호출하는 것을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처: &lt;a href=&quot;https://juejin.cn/post/6899061455610773511&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://juejin.cn/post/6899061455610773511&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1512&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccD27c/btsJm6PTnam/PBRxr6Z0IbPuJ8yJl6vgB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccD27c/btsJm6PTnam/PBRxr6Z0IbPuJ8yJl6vgB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccD27c/btsJm6PTnam/PBRxr6Z0IbPuJ8yJl6vgB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccD27c%2FbtsJm6PTnam%2FPBRxr6Z0IbPuJ8yJl6vgB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1512&quot; height=&quot;418&quot; data-origin-width=&quot;1512&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do_dlopen 함수는 첫번째 인자로 so 파일 이름이 전달되고, so 파일이 로드되었다면 그 so 파일의 handle 을 반환하는 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처: &lt;a href=&quot;https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:bionic/linker/linker.cpp;l=2112;bpv=1?q=do_dlopen&amp;amp;ss=android%2Fplatform%2Fsuperproject&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:bionic/linker/linker.cpp;l=2112;bpv=1?q=do_dlopen&amp;amp;ss=android%2Fplatform%2Fsuperproject&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;361&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcEwfH/btsJmlAah3q/qAONE1GJJ1kORHD6CyipN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcEwfH/btsJmlAah3q/qAONE1GJJ1kORHD6CyipN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcEwfH/btsJmlAah3q/qAONE1GJJ1kORHD6CyipN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcEwfH%2FbtsJmlAah3q%2FqAONE1GJJ1kORHD6CyipN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1089&quot; height=&quot;361&quot; data-origin-width=&quot;1089&quot; data-origin-height=&quot;361&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 do_dlopen 함수를 후킹하면 so 파일 로딩을 추적 및 덤프를 뜰 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;do_dlopen 함수의 심볼은 &quot;__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv&quot; 입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NbqE8/btsJlKABxv2/mXL3U9tVmLXu8KYLAzupc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NbqE8/btsJlKABxv2/mXL3U9tVmLXu8KYLAzupc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NbqE8/btsJlKABxv2/mXL3U9tVmLXu8KYLAzupc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNbqE8%2FbtsJlKABxv2%2FmXL3U9tVmLXu8KYLAzupc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1380&quot; height=&quot;506&quot; data-origin-width=&quot;1380&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;so 파일 로딩을 온전히 추적하기 위해서 후킹 타이밍은 빠르면 빠를 수록 좋겠죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 프로세스의 부모인 zygote 에 injection 하여 구현하는게 제일 좋습니다.&amp;nbsp; zygote 가 fork 되면서 앱 프로세스가 시작이 되는데, 이 zygote 에 모듈을 인젝션 해놓으면, 앱의 시작과 동시에 모듈을 작동하게 할 수 있기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;magisk 의 기능인 zygisk 가 zygote injection 을 구현해놓았으며, 우리가 할 것은 zygisk 모듈을 만들기만 하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음 zygisk 모듈을 만드는 것은 알겠고, 덤프 로직은 어떻게 구현해야 할까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;so 파일의 base 주소와 size 정보를 알아내서 메모리에서 그만큼을 읽어들여 파일에 쓰면 되겠네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;frida-gum (&lt;a href=&quot;https://github.com/frida/frida-gum&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/frida/frida-gum&lt;/a&gt;) 에서 제공하는 여러 유용한 api 들을 이용하면 수월하게 구현 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 종합해서,&amp;nbsp; 여러 so 파일 로딩 case에 대응하여 덤프를 뜰 수 있는 툴을 제작하였습니다. 사용법은 깃헙 참고 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/hackcatml/zygisk-memdump&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/hackcatml/zygisk-memdump&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1725113328986&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - hackcatml/zygisk-memdump: A zygisk module that dumps so file from process memory&quot; data-og-description=&quot;A zygisk module that dumps so file from process memory - hackcatml/zygisk-memdump&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/hackcatml/zygisk-memdump&quot; data-og-url=&quot;https://github.com/hackcatml/zygisk-memdump&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ZqYmu/hyWZg4vmfC/wIMhEkaEnudbv5LunqkXw1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/hackcatml/zygisk-memdump&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/hackcatml/zygisk-memdump&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ZqYmu/hyWZg4vmfC/wIMhEkaEnudbv5LunqkXw1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - hackcatml/zygisk-memdump: A zygisk module that dumps so file from process memory&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A zygisk module that dumps so file from process memory - hackcatml/zygisk-memdump&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Information Security/Android</category>
      <category>android so file dump</category>
      <category>androidreversing</category>
      <category>magisk</category>
      <category>Zygisk</category>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/199</guid>
      <comments>https://hackcatml.tistory.com/199#entry199comment</comments>
      <pubDate>Sat, 31 Aug 2024 23:11:08 +0900</pubDate>
    </item>
    <item>
      <title>Frida Build &amp;amp; Debug Using Logs For Android</title>
      <link>https://hackcatml.tistory.com/198</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;MacOS, frida v16.4.10 android-arm64 빌드 및 디버깅(log 찍기) 하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;◼︎ How to build&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;// clone&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;git clone --recurse-submodules &lt;a href=&quot;https://github.com/frida/frida.git&quot;&gt;https://github.com/frida/frida.git&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;cd frida&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;// ndk 환경변수 설정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;export&amp;nbsp;ANDROID_NDK_ROOT=$HOME/Library/Android/sdk/ndk/25.0.8775105&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;// configure &amp;amp; make&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mkdir&amp;nbsp;android-arm64&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;cd&amp;nbsp;android-arm64&lt;br /&gt;../configure&amp;nbsp;--host=android-arm64&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;make&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;// build output&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;frida-server&amp;nbsp;위치:&amp;nbsp;frida/android-arm64/subprojects/frida-core/server/frida-server&lt;br /&gt;frida-gadget&amp;nbsp;위치:&amp;nbsp;frida/android-arm64/subprojects/frida-core/lib/gadget/frida-gadget.so&lt;br /&gt;frida-inject&amp;nbsp;위치:&amp;nbsp;frida/android-arm64/subprojects/frida-core/inject/frida-inject&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;◼︎ How to debug using logs&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관심 있는 구간에 g_info 집어 넣고 빌드&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xdaIz/btsJmz5T0JJ/PngPcc3Ls1TsczECbXrcJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xdaIz/btsJmz5T0JJ/PngPcc3Ls1TsczECbXrcJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xdaIz/btsJmz5T0JJ/PngPcc3Ls1TsczECbXrcJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxdaIz%2FbtsJmz5T0JJ%2FPngPcc3Ls1TsczECbXrcJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;818&quot; height=&quot;382&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;382&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;adb logcat -s &quot;Frida&quot;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbjy8r/btsJmaFAiZN/s84ajfcoDdJumwAgp7Oue1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbjy8r/btsJmaFAiZN/s84ajfcoDdJumwAgp7Oue1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbjy8r/btsJmaFAiZN/s84ajfcoDdJumwAgp7Oue1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcbjy8r%2FbtsJmaFAiZN%2Fs84ajfcoDdJumwAgp7Oue1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;845&quot; height=&quot;200&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Information Security/Android</category>
      <category>fridaandroid</category>
      <category>fridabuild</category>
      <category>fridadebug</category>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/198</guid>
      <comments>https://hackcatml.tistory.com/198#entry198comment</comments>
      <pubDate>Sat, 31 Aug 2024 17:35:45 +0900</pubDate>
    </item>
    <item>
      <title>Proxy Android Flutter Apps</title>
      <link>https://hackcatml.tistory.com/197</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◼︎ 개요&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter 앱은  Flutter 프레임워크(&lt;a href=&quot;https://flutter.dev/&quot;&gt;https://flutter.dev/&lt;/a&gt;)를 사용해 개발된 앱으로, Flutter 프레임워크는 Dart 언어(&lt;a href=&quot;https://dart.dev&quot;&gt;https://dart.dev&lt;/a&gt;)를 사용합니다.&lt;br /&gt;다양한 앱들이 Flutter 로 개발됩니다. Google Ads, BMW, 네이버 블로그, 네이버 지식인, 삼쩜삼, Demaecan, Nubank 등이 있죠.&lt;br /&gt;Flutter 는 빠르게 네이티브 성능의 앱을, 그것도 멀티플랫폼으로 개발할 수 있습니다.&lt;br /&gt;개발자들에게는 Flutter 가 좋은 옵션이 되겠네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음...하지만, 보안인에게는 Flutter 앱이 꽤나 골치가 아픕니다.&lt;br /&gt;분석을 하려고 하는데 심볼은 전부 날라가 있고, 일반적인 방식으로 네트워크 프록시도 안잡히기 때문이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 글에서는 안드로이드 Flutter 앱의 http 패킷을 BurpSuite 으로 잡기 위해 수행한 분석에 대해서 다뤄보고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성격 급하신 분들을 위해, 제가 작성한 frida script 공유합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/hackcatml/frida-flutterproxy&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/hackcatml/frida-flutterproxy&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1716087221129&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - hackcatml/frida-flutterproxy: Burp proxy android flutter apps&quot; data-og-description=&quot;Burp proxy android flutter apps. Contribute to hackcatml/frida-flutterproxy development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/hackcatml/frida-flutterproxy&quot; data-og-url=&quot;https://github.com/hackcatml/frida-flutterproxy&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmMNtg/hyV6dCp1Qc/Z6vd1GbBn2mBP7m6VkSXEK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/hackcatml/frida-flutterproxy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/hackcatml/frida-flutterproxy&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmMNtg/hyV6dCp1Qc/Z6vd1GbBn2mBP7m6VkSXEK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - hackcatml/frida-flutterproxy: Burp proxy android flutter apps&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Burp proxy android flutter apps. Contribute to hackcatml/frida-flutterproxy development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◼︎ BurpSuite 으로 http 패킷 보내기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 컴퓨터에서 돌아가고 있는 Burp 에 http 패킷을 보내야 프록시를 잡을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, Flutter 의 경우 Flutter 엔진 내부에서 네트워크를 담당하고 있어서 아래 그림처럼 단말기에서 프록시를 설정하여도 패킷이 Burp 로 날라가지 않습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDC9Q4/btsHuqbpdLU/lrDudtBmg1U0vKVUT0iMr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDC9Q4/btsHuqbpdLU/lrDudtBmg1U0vKVUT0iMr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDC9Q4/btsHuqbpdLU/lrDudtBmg1U0vKVUT0iMr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDC9Q4%2FbtsHuqbpdLU%2FlrDudtBmg1U0vKVUT0iMr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;329&quot; height=&quot;414&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter 엔진에서 &quot;Socket_CreateConnect&quot; 라는 함수가 서버와의 연결을 담당합니다. (출처: &lt;a href=&quot;https://blog.weghos.com/flutter/engine/third_party/dart/runtime/bin/socket.cc.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.weghos.com/flutter/engine/third_party/dart/runtime/bin/socket.cc.html&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음...IDA 에서 해당 함수를 찾아봐야 겠군요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBJthq/btsHucR0IWu/FbIYJ0jZm6nuAglZLPKpe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBJthq/btsHucR0IWu/FbIYJ0jZm6nuAglZLPKpe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBJthq/btsHucR0IWu/FbIYJ0jZm6nuAglZLPKpe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBJthq%2FbtsHucR0IWu%2FFbIYJ0jZm6nuAglZLPKpe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;780&quot; height=&quot;483&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드에서 Flutter 엔진 파일은 libflutter.so 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Socket_CreateConnect&quot; 문자열을 검색해서 클릭, 클릭 따라 들어가면 쉽게 해당 함수의 주소를 찾아낼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmsbf5/btsHuzsyFKH/SngkiJoJnKbzTInNIyysCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmsbf5/btsHuzsyFKH/SngkiJoJnKbzTInNIyysCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmsbf5/btsHuzsyFKH/SngkiJoJnKbzTInNIyysCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbmsbf5%2FbtsHuzsyFKH%2FSngkiJoJnKbzTInNIyysCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;900&quot; height=&quot;302&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1138&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdYUkG/btsHuy1wOLA/z2KoYfwDnLP4Sl4cAARC61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdYUkG/btsHuy1wOLA/z2KoYfwDnLP4Sl4cAARC61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdYUkG/btsHuy1wOLA/z2KoYfwDnLP4Sl4cAARC61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdYUkG%2FbtsHuy1wOLA%2Fz2KoYfwDnLP4Sl4cAARC61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1138&quot; height=&quot;179&quot; data-origin-width=&quot;1138&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMpra6/btsHtoFQZ3P/dHsKKn7hf23qWGknRXKO71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMpra6/btsHtoFQZ3P/dHsKKn7hf23qWGknRXKO71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMpra6/btsHtoFQZ3P/dHsKKn7hf23qWGknRXKO71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMpra6%2FbtsHtoFQZ3P%2FdHsKKn7hf23qWGknRXKO71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1018&quot; height=&quot;269&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 함수 sub_6FD704 의 pseudo code 의 생김새를 보아하니, 두번째 함수 sub_70371c 가 &quot;SocketAddress::GetSockAddr&quot; 함수 이겠군요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4pkev/btsHtPv6Bml/6wsbWGYNC0EeJuch0a8Zg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4pkev/btsHtPv6Bml/6wsbWGYNC0EeJuch0a8Zg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4pkev/btsHtPv6Bml/6wsbWGYNC0EeJuch0a8Zg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4pkev%2FbtsHtPv6Bml%2F6wsbWGYNC0EeJuch0a8Zg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;921&quot; height=&quot;384&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sub_70371c 의 두번째 인자는 sockaddr 구조체입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; 아하! sub_70371C 를 후킹하면 sockaddr 구조체 주소를 얻을 수 있겠군요. sockaddr 구조체에는 IP 및 PORT 정보가 담겨져 있기 때문에, 이를 조작해서 Burp 로 패킷을 보낼 수 있겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1432&quot; data-origin-height=&quot;364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIrFfS/btsHtOc57m7/RLzXNr55diWeZV4tCsyt6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIrFfS/btsHtOc57m7/RLzXNr55diWeZV4tCsyt6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIrFfS/btsHtOc57m7/RLzXNr55diWeZV4tCsyt6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIrFfS%2FbtsHtOc57m7%2FRLzXNr55diWeZV4tCsyt6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1432&quot; height=&quot;364&quot; data-origin-width=&quot;1432&quot; data-origin-height=&quot;364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음 좀더 살펴보니 &quot;Socket_CreateConnect&quot; 함수는 내부적으로 socket 함수를 사용하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아하! sockaddr 구조체 조작 시점을 socket 함수 사용 시점으로 하면 되겠네요. socket 함수 사용 시점이 네트워크 통신을 위한 socket 생성 시점이니, 이때 Burp IP 와 PORT 로 조작한 sockaddr 구조체를 준비해 놓으면 되겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZOkBv/btsHubZUl5P/enF5TfIxaO4UYpFGKAk9Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZOkBv/btsHubZUl5P/enF5TfIxaO4UYpFGKAk9Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZOkBv/btsHubZUl5P/enF5TfIxaO4UYpFGKAk9Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZOkBv%2FbtsHubZUl5P%2FenF5TfIxaO4UYpFGKAk9Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;616&quot; height=&quot;230&quot; data-origin-width=&quot;616&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 문제는 Flutter 앱이 업데이트 되거나 다른 Flutter 앱을 마주치면 매번 IDA로 디컴파일해서 &quot;SocketAddress::GetSockAddr&quot; 함수 주소를 찾아내고 후킹을 해서 sockaddr 구조체 주소를 얻어야 하는 건가 싶습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 여러 Flutter 앱들을 디컴파일해서 살펴봤는데요, 모두 &quot;Socket_CreateConnect&quot; 함수의 두번째 BL 인스트럭션이 가리키는 주소가 &quot;SocketAddress::GetSockAddr&quot; 함수 주소였습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1139&quot; data-origin-height=&quot;510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUZDx4/btsHtNL1HWa/K8utprU7VrGcV28s6NHTc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUZDx4/btsHtNL1HWa/K8utprU7VrGcV28s6NHTc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUZDx4/btsHtNL1HWa/K8utprU7VrGcV28s6NHTc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUZDx4%2FbtsHtNL1HWa%2FK8utprU7VrGcV28s6NHTc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1139&quot; height=&quot;510&quot; data-origin-width=&quot;1139&quot; data-origin-height=&quot;510&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 Flutter 앱들에서 동일 패턴이 발견되었으니, 이는 frida script 로 충분히 구현 할 수 있습니다. 다음과 같은 흐름이 되겠죠.&lt;/p&gt;
&lt;pre id=&quot;code_1716102443412&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;libflutter.so 메모리에서 &quot;Socket_CreateConnect&quot; 문자열을 메모리 스캔 --&amp;gt;

&quot;Socket_CreateConnect&quot; 문자열이 저장된 주소를 참조하는 곳을 메모리 스캔 --&amp;gt;

(발견된 주소 - 0x10) 이 &quot;Socket_CreateConnect&quot; 함수 주소임 --&amp;gt;

&quot;Socket_CreateConnect&quot; 함수 주소에서 두 번째 BL 지시어가 가리키는 곳이 &quot;SocketAddress::GetSockAddr&quot; 함수 주소임 --&amp;gt;

&quot;SocketAddress::GetSockAddr&quot; 함수를 후킹해서 sockaddr 구조체 주소를 얻을 수 있음 --&amp;gt;

socket 함수를 후킹해서 socket 함수 사용 시점에 sockaddr 구조체의 정보를 Burp IP 와 PORT 로 변조&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자 여기까지 frida 로 구현하고 앱을 실행해보면, Burp로 패킷이 날라가기는 하지만 패킷이 잡히지는 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Burp 에서 &quot;Remote host terminated the handshake&quot; 에러가 발생합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1057&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8EcjM/btsHu4ltd8E/22kdY8knAFBA0Gjp775md0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8EcjM/btsHu4ltd8E/22kdY8knAFBA0Gjp775md0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8EcjM/btsHu4ltd8E/22kdY8knAFBA0Gjp775md0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8EcjM%2FbtsHu4ltd8E%2F22kdY8knAFBA0Gjp775md0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1057&quot; height=&quot;213&quot; data-origin-width=&quot;1057&quot; data-origin-height=&quot;213&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◼︎Verify cert chain 우회&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 에러의 원인을 찾아보니, Flutter 엔진의 경우 자체적으로 boringssl 을 사용해서 인증서 검증을 하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 보니 Burp 인증서가 검증을 통과하지 못해서 에러가 발생한 것이지요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter 엔진에서 인증서 검증을 담당하는 함수는 &quot;ssl_crypto_x509_session_verify_cert_chain&quot; 입니다. (출처: &lt;a href=&quot;https://blog.weghos.com/flutter/engine/third_party/boringssl/src/ssl/ssl_x509.cc.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.weghos.com/flutter/engine/third_party/boringssl/src/ssl/ssl_x509.cc.html&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;669&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A5N18/btsHvtee0Gg/KaSzzPcDyVU9t6MqAX92b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A5N18/btsHvtee0Gg/KaSzzPcDyVU9t6MqAX92b0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A5N18/btsHvtee0Gg/KaSzzPcDyVU9t6MqAX92b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA5N18%2FbtsHvtee0Gg%2FKaSzzPcDyVU9t6MqAX92b0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;974&quot; height=&quot;669&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;669&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음 함수 내부에 &quot;ssl_client&quot; 라는 문자열이 보이네요. IDA 에서 해당 문자열을 검색하면 verify_cert_chain 함수를 쉽게 찾을 수 있겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kCxcn/btsHtcr7nED/b0dLENkkkvCjenMTHOKMn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kCxcn/btsHtcr7nED/b0dLENkkkvCjenMTHOKMn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kCxcn/btsHtcr7nED/b0dLENkkkvCjenMTHOKMn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkCxcn%2FbtsHtcr7nED%2Fb0dLENkkkvCjenMTHOKMn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;618&quot; height=&quot;107&quot; data-origin-width=&quot;618&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;994&quot; data-origin-height=&quot;131&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5a0H6/btsHt2ov6NZ/IJU5Llad6mYbr8nh6qZUW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5a0H6/btsHt2ov6NZ/IJU5Llad6mYbr8nh6qZUW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5a0H6/btsHt2ov6NZ/IJU5Llad6mYbr8nh6qZUW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5a0H6%2FbtsHt2ov6NZ%2FIJU5Llad6mYbr8nh6qZUW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;994&quot; height=&quot;131&quot; data-origin-width=&quot;994&quot; data-origin-height=&quot;131&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 Flutter 앱들을 살펴보았는데, 모두 &quot;ssl_client&quot; 문자열이 노출되었으며 이를 통해 &quot;ssl_crypto_x509_session_verify_cert_chain&quot; 함수 주소를 찾아낼 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 이것도 충분히 frida script 로 구현 가능합니다. 이런 흐름이 되겠죠&lt;/p&gt;
&lt;pre id=&quot;code_1716104477305&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;libflutter.so 메모리에서 &quot;ssl_client&quot; 문자열을 메모리 스캔 --&amp;gt;

&quot;ssl_client&quot; 문자열이 저장된 주소를 참조하는 곳을 메모리 스캔 --&amp;gt;

발견된 주소가 속해 있는 함수가 &quot;ssl_crypto_x509_session_verify_cert_chain&quot; 임 --&amp;gt;

&quot;ssl_crypto_x509_session_verify_cert_chain&quot; 함수 후킹해서 return 값 변조&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◼︎결과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;BurpSuite 으로 http 패킷 보내기&quot;&lt;/b&gt; 에서의 분석결과와 &lt;b&gt;&quot;&lt;b&gt;Verify cert chain 우회&quot; &lt;/b&gt;&lt;/b&gt;에서의 분석결과를 종합해서 frida script 를 작성하였습니다. 사용방법은 Github 주소 참고 바랍니다. &lt;a href=&quot;https://github.com/hackcatml/frida-flutterproxy&quot;&gt;https://github.com/hackcatml/frida-flutterproxy&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트한 모든 앱들에서 정상적으로 프록시를 잡을 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;938&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHOi29/btsHuaUesY5/bYQHaAuF2qSFqiMhojeBv1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHOi29/btsHuaUesY5/bYQHaAuF2qSFqiMhojeBv1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHOi29/btsHuaUesY5/bYQHaAuF2qSFqiMhojeBv1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bHOi29/btsHuaUesY5/bYQHaAuF2qSFqiMhojeBv1/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1500&quot; height=&quot;938&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;938&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◼︎참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Impact-I/reFlutter&quot;&gt;https://github.com/Impact-I/reFlutter&lt;/a&gt; (reFlutter)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.nviso.eu/2020/05/20/intercepting-flutter-traffic-on-android-x64/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.nviso.eu/2020/05/20/intercepting-flutter-traffic-on-android-x64/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://swarm.ptsecurity.com/fork-bomb-for-flutter/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://swarm.ptsecurity.com/fork-bomb-for-flutter/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Information Security/Android</category>
      <category>android flutter proxy</category>
      <category>Android Reversing</category>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/197</guid>
      <comments>https://hackcatml.tistory.com/197#entry197comment</comments>
      <pubDate>Sun, 19 May 2024 17:48:35 +0900</pubDate>
    </item>
    <item>
      <title>kfd exploit 활용</title>
      <link>https://hackcatml.tistory.com/196</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;felix-pb 에 의해 공개된 kfd 는 kernel file descriptor 의 약자로 애플 단말기의 유저단에서 커널 영역의 메모리를 읽고, 쓰는 것을 목표로 하는 프로젝트입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃헙에 들어가보면 write up 도 자세히 적어놨는데, 제 레벨로는 읽어도 이해가 안되더군요... &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/felix-pb/kfd&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/felix-pb/kfd&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707478188683&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - felix-pb/kfd: kfd, short for kernel file descriptor, is a project to read and write kernel memory on Apple devices.&quot; data-og-description=&quot;kfd, short for kernel file descriptor, is a project to read and write kernel memory on Apple devices. - GitHub - felix-pb/kfd: kfd, short for kernel file descriptor, is a project to read and write ...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/felix-pb/kfd&quot; data-og-url=&quot;https://github.com/felix-pb/kfd&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hF5DJ/hyVf40Slud/nKG7f24YT79sYVtGXGQ3x1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/felix-pb/kfd&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/felix-pb/kfd&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hF5DJ/hyVf40Slud/nKG7f24YT79sYVtGXGQ3x1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - felix-pb/kfd: kfd, short for kernel file descriptor, is a project to read and write kernel memory on Apple devices.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;kfd, short for kernel file descriptor, is a project to read and write kernel memory on Apple devices. - GitHub - felix-pb/kfd: kfd, short for kernel file descriptor, is a project to read and write ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 어떻게 커널과 친해질 수 있을까 고민하던중에 kfund 프로젝트를 발견하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 kfd 를 사용하려면 단말기의 고유한 offset 들을 직접 찾아내고 소스코드에 적어줘야 하는데, kfund 에서는 dynamic 하게 offset 들을 찾아줍니다. 유용한 api도 많이 제공하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/wh1te4ever/kfund&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/wh1te4ever/kfund&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707479959303&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - wh1te4ever/kfund: kfund, short for my fun with kfd exploit.&quot; data-og-description=&quot;kfund, short for my fun with kfd exploit. Contribute to wh1te4ever/kfund development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/wh1te4ever/kfund&quot; data-og-url=&quot;https://github.com/wh1te4ever/kfund&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oVgC8/hyVf1whmBc/k9vWl2I0eAHm0tPk0usFk0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/wh1te4ever/kfund&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/wh1te4ever/kfund&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oVgC8/hyVf1whmBc/k9vWl2I0eAHm0tPk0usFk0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - wh1te4ever/kfund: kfund, short for my fun with kfd exploit.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;kfund, short for my fun with kfd exploit. Contribute to wh1te4ever/kfund development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jailbreak community 에서 활동하시는 분들 보면 자동으로 엄지척이 올라갑니다.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리를 자주 들여다보면 뉴비인 저도 커널과 친숙해지지 않을까 싶어서, kfund 에 frida-gadet 을 삽입하여 kernel memory 를 들여다볼수 있는 툴을 제작하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/hackcatml/kfd-explorer&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/hackcatml/kfd-explorer&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1707480433415&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - hackcatml/kfd-explorer: iOS kernel memory explorer&quot; data-og-description=&quot;iOS kernel memory explorer. Contribute to hackcatml/kfd-explorer development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/hackcatml/kfd-explorer&quot; data-og-url=&quot;https://github.com/hackcatml/kfd-explorer&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBrgtu/hyVjib7WvS/F4Aa6BtgFCj09UrICzw5w1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/hackcatml/kfd-explorer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/hackcatml/kfd-explorer&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBrgtu/hyVjib7WvS/F4Aa6BtgFCj09UrICzw5w1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - hackcatml/kfd-explorer: iOS kernel memory explorer&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;iOS kernel memory explorer. Contribute to hackcatml/kfd-explorer development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kfund 프로젝트에는 &quot;/System/Library/Audio/UISounds/photoShutter.caf&quot; 파일을 숨겨서 아이폰 카메라를 무음으로 만드는 예시가 있는데요. 이것을 한번 따라 해보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iPhone11, iOS 16.1.1 에서 테스트하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;/System/Library/Audio/UISounds/photoShutter.caf&quot; 파일의 vnode 를 구합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vnode는 커널 메모리 영역에 있는 object 로써, 유닉스 파일 인터페이스(open, read, write, close, readdir, etc.)와 소통하는 역할을 한다고 합니다. (&lt;a href=&quot;https://man.openbsd.org/vnode.9&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://man.openbsd.org/vnode.9&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;695&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqVbg2/btsEFSIHj6Y/hnBLjCKH6dVVLSPGEC0Lwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqVbg2/btsEFSIHj6Y/hnBLjCKH6dVVLSPGEC0Lwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqVbg2/btsEFSIHj6Y/hnBLjCKH6dVVLSPGEC0Lwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqVbg2%2FbtsEFSIHj6Y%2FhnBLjCKH6dVVLSPGEC0Lwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1073&quot; height=&quot;695&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;695&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 vnode 주소로 이동해보면 iocount, usecount, flag 필드가 보입니다. Offsets 탭에서 해당 필드들이 vnode 로부터 얼만큼 떨어져 있는지 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;694&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AQYwY/btsEEEkhGQI/DJn1WIKwALeBchax2emNe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AQYwY/btsEEEkhGQI/DJn1WIKwALeBchax2emNe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AQYwY/btsEEEkhGQI/DJn1WIKwALeBchax2emNe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAQYwY%2FbtsEEEkhGQI%2FDJn1WIKwALeBchax2emNe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1076&quot; height=&quot;694&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;694&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vnode 플래그에는 VISSHADOW (0x008000) 라는 값이 있습니다. &lt;a href=&quot;https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/vnode_internal.h#L297&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/apple-oss-distributions/xnu/blob/xnu-8792.41.9/bsd/sys/vnode_internal.h#L297&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 설정되어 있는 플래그 (0x84800) 와 VISSHADOW 플래그 (0x8000) 를 OR 연산한 값을 덮어씌우면 파일에 접근할 수 없게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(0x84800 | 0x8000) --&amp;gt; 0x8c800&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kfund 에서는 flag 값을 덮어씌우기 전에 usecount 및 iocount 값을 1씩 증가시킵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;usecount 및 iocount 변화 없이 flag만 설정하면 처음에는 카메라가 무음이었다가 몇분 지나면 다시 카메라 음이 살아나더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨌든 따라해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iocount 및 usecount 1씩 증가한 값 kwrite&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;695&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kVAeA/btsEGLbj4Q2/s00HI8VIfCwupUSRuQtKU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kVAeA/btsEGLbj4Q2/s00HI8VIfCwupUSRuQtKU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kVAeA/btsEGLbj4Q2/s00HI8VIfCwupUSRuQtKU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkVAeA%2FbtsEGLbj4Q2%2Fs00HI8VIfCwupUSRuQtKU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1072&quot; height=&quot;695&quot; data-origin-width=&quot;1072&quot; data-origin-height=&quot;695&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VISSHADOW 와 OR 연산한 새로운 flag (0x8c800) kwrite&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 설정하면 단말기 재부팅하기 전까지 아이폰 카메라 셔터음이 나지 않습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;693&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qj1Dc/btsEF5OFSIq/F8yagm01nQWlrKoEWlrlXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qj1Dc/btsEF5OFSIq/F8yagm01nQWlrKoEWlrlXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qj1Dc/btsEF5OFSIq/F8yagm01nQWlrKoEWlrlXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQj1Dc%2FbtsEF5OFSIq%2FF8yagm01nQWlrKoEWlrlXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1076&quot; height=&quot;693&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;693&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Information Security/iOS</category>
      <category>ios</category>
      <category>iOS kernel memory</category>
      <category>kfd</category>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/196</guid>
      <comments>https://hackcatml.tistory.com/196#entry196comment</comments>
      <pubDate>Fri, 9 Feb 2024 22:04:52 +0900</pubDate>
    </item>
    <item>
      <title>버sucker 키우기</title>
      <link>https://hackcatml.tistory.com/195</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 새로 출시된 중국산 게임이 모바일 매출순위에서 리니지를 제꼈다고 게임 유튜버 및 온라인 뉴스에서 시끌벅적했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글을 올리는 시점에도 매출순위 2등을 하고 있군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 도대체 어떤 게임이길래 궁금해서 플레이해봤는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딱 봐도 전형적인 유저들 돈 단기간에 뽑아먹고 튈 형태의 게임처럼 보였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안을 하는 입장에서 이런 생각이 들더군요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;이 정도 퀄리티의 간단한 게임이면 변조앱 사이트서 무료로 변조앱 뿌려서 누구나 다 현질없이 게임하고, 어뷰징하고 개판나서 망할텐데 어떻게 매출순위가 이렇게 높지?&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 궁금해서 까봤더니 아이쿠~ 유니티가 아니고 cocos 게임입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니티였으면 출시하자마자 게임 변조앱 사이트들에 어뷰징앱이 올라왔을 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cocos, lua 같은 언어로 제작된 게임은 마이너여서 그런지 모드앱이 안보이더군요. 흠, 개발사 입장에서는 일단은 모드앱 걱정은 줄일 수 있겠네요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;970&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtIbZL/btsD3oarGXP/Nk2yu3vwGjGc5Ct0goQCbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtIbZL/btsD3oarGXP/Nk2yu3vwGjGc5Ct0goQCbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtIbZL/btsD3oarGXP/Nk2yu3vwGjGc5Ct0goQCbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtIbZL%2FbtsD3oarGXP%2FNk2yu3vwGjGc5Ct0goQCbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;497&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;970&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 구조를 살펴보니 script 기반의 게임이더군요...아...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면 배포되고 있는 모드앱만 없을 뿐이지, 잼민이들도 script 수정해서 어뷰징하고 있을 가능성이 높습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 게임내 사용되는 어느 변수에 대한 로그를 찍어본 것입니다. 변수에 대한 로그를 찍을수 있으면 뭐다? 조작도 가능하겠죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음...나름 캐릭터는 귀엽더군요. 출퇴근시간에 무과금으로 즐기기에 적합한 게임인것 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eu4X0o/btsD1aRGtAK/bxDnskjEJkZLr2fUPOEeCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eu4X0o/btsD1aRGtAK/bxDnskjEJkZLr2fUPOEeCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eu4X0o/btsD1aRGtAK/bxDnskjEJkZLr2fUPOEeCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feu4X0o%2FbtsD1aRGtAK%2FbxDnskjEJkZLr2fUPOEeCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;815&quot; height=&quot;284&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Information Security/Android</category>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/195</guid>
      <comments>https://hackcatml.tistory.com/195#entry195comment</comments>
      <pubDate>Sat, 27 Jan 2024 19:13:36 +0900</pubDate>
    </item>
    <item>
      <title>Roothide Bootstrap</title>
      <link>https://hackcatml.tistory.com/194</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Dopamine 이후로 arm64e 단말기(iPhone X 이후 기종)에 대한 탈옥툴이 나오고 있지 않은 가운데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탈옥툴은 아니지만 앱에서 tweak이 작동하게끔 하는 Bootstrap 이라는 툴이 RootHide 에 의해 공개되었습니다. (&lt;a href=&quot;https://github.com/RootHide/Bootstrap&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/RootHide/Bootstrap)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704618500215&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - RootHide/Bootstrap: A full featured bootstrap for ios14.0~17.0 (A8~A17,M1+M2)&quot; data-og-description=&quot;A full featured bootstrap for ios14.0~17.0 (A8~A17,M1+M2) - GitHub - RootHide/Bootstrap: A full featured bootstrap for ios14.0~17.0 (A8~A17,M1+M2)&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/RootHide/Bootstrap&quot; data-og-url=&quot;https://github.com/RootHide/Bootstrap&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sADB8/hyUXROu3lq/NaKqSHwKd3J0h1kn8hvhmK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/RootHide/Bootstrap&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/RootHide/Bootstrap&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sADB8/hyUXROu3lq/NaKqSHwKd3J0h1kn8hvhmK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - RootHide/Bootstrap: A full featured bootstrap for ios14.0~17.0 (A8~A17,M1+M2)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A full featured bootstrap for ios14.0~17.0 (A8~A17,M1+M2) - GitHub - RootHide/Bootstrap: A full featured bootstrap for ios14.0~17.0 (A8~A17,M1+M2)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탈옥툴은 아니지만, 탈옥의 주요 목적이 tweak injection 이므로 탈옥단말기와 비슷한 환경을 갖출 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안을 하는 입장에서는 tweak 을 통해 앱 동작을 조사할 수 있으므로 좋은 소식이 아닐 수 없습니다.  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bootstrap 은 TrollStore 설치 가능한 단말기에서 tweak 이 작동하도록 해줍니다. (TrollStore 설치 가능 단말기: &lt;a href=&quot;https://ios.cfw.guide/installing-trollstore/)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ios.cfw.guide/installing-trollstore/&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bootstrap.tipa 파일을 TrollStore로 설치해줍니다. (직접 빌드하거나, &lt;a href=&quot;https://github.com/Baw-Appie/RootHideBootstrap/releases/tag/release&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/Baw-Appie/RootHideBootstrap/releases/tag/release&lt;/a&gt; 에서 빌드된 .tipa 파일을 다운로드 받을 수 있습니다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;855&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NOzhk/btsDbfq6tc8/nrqk39CPKjgdqbW0cNJ5A0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NOzhk/btsDbfq6tc8/nrqk39CPKjgdqbW0cNJ5A0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NOzhk/btsDbfq6tc8/nrqk39CPKjgdqbW0cNJ5A0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNOzhk%2FbtsDbfq6tc8%2Fnrqk39CPKjgdqbW0cNJ5A0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;309&quot; height=&quot;549&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;855&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 우선 sileo 에서 ellekit 을 설치해줘야합니다.&lt;br /&gt;그 후, AppEnabler 에서 앱별로 트윅 활성화를 해줄수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카카오페이앱에 트윅 활성화를 해봤습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;961&quot; data-origin-height=&quot;856&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tetIS/btsC9BuoJGw/cYyImWGjPtTudZOOJk3XL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tetIS/btsC9BuoJGw/cYyImWGjPtTudZOOJk3XL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tetIS/btsC9BuoJGw/cYyImWGjPtTudZOOJk3XL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtetIS%2FbtsC9BuoJGw%2FcYyImWGjPtTudZOOJk3XL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;567&quot; height=&quot;505&quot; data-origin-width=&quot;961&quot; data-origin-height=&quot;856&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; 트윅 활성화를 하면 앱을 rebuild 하게 되는데요, 다음과 같은 현상이 발생하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본앱이 .backup 에 백업되고, 변조앱이 .app 에 위치하게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;858&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1CRXw/btsC53yLbyp/ejVqcJvynwRaGkyEcyp24K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1CRXw/btsC53yLbyp/ejVqcJvynwRaGkyEcyp24K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1CRXw/btsC53yLbyp/ejVqcJvynwRaGkyEcyp24K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1CRXw%2FbtsC53yLbyp%2FejVqcJvynwRaGkyEcyp24K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;337&quot; height=&quot;601&quot; data-origin-width=&quot;481&quot; data-origin-height=&quot;858&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패치된 바이너리를 살펴볼 경우 .prelib 가 LC_LOAD_DYLIB 에 인젝션되어 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2094&quot; data-origin-height=&quot;754&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SmRMO/btsC6p9DbrM/RKxCRJLtFW6ik4By0ku5V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SmRMO/btsC6p9DbrM/RKxCRJLtFW6ik4By0ku5V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SmRMO/btsC6p9DbrM/RKxCRJLtFW6ik4By0ku5V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSmRMO%2FbtsC6p9DbrM%2FRKxCRJLtFW6ik4By0ku5V0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2094&quot; height=&quot;754&quot; data-origin-width=&quot;2094&quot; data-origin-height=&quot;754&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 솔루션이 강하게 적용된 앱의 경우에는 무결성 탐지를 우회해줘야 합니다. 보통 탈옥탐지 우회보다 까다롭습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카카오페이앱은 역시 무결성 탐지를 하고 있군요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0ZRyC/btsDbf5HAwC/zyxijXHm88MLtEjWkWoWtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0ZRyC/btsDbf5HAwC/zyxijXHm88MLtEjWkWoWtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0ZRyC/btsDbf5HAwC/zyxijXHm88MLtEjWkWoWtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0ZRyC%2FbtsDbf5HAwC%2FzyxijXHm88MLtEjWkWoWtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;551&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트윅은 roothide 용으로 빌드해줘야 합니다. (&lt;a href=&quot;https://github.com/RootHide/Developer?tab=readme-ov-file&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/RootHide/Developer&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트결과 C function, address 후킹 정상적으로 작동하였으며, frida 도 정상 작동하였습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mm3p0/btsC778sY82/Nu8QpfhqepSVC36JBHD6T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mm3p0/btsC778sY82/Nu8QpfhqepSVC36JBHD6T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mm3p0/btsC778sY82/Nu8QpfhqepSVC36JBHD6T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmm3p0%2FbtsC778sY82%2FNu8QpfhqepSVC36JBHD6T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;795&quot; height=&quot;290&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;364&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pylcA/btsC2vCLQLB/HInxQyer4jxhbE0qSWPSb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pylcA/btsC2vCLQLB/HInxQyer4jxhbE0qSWPSb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pylcA/btsC2vCLQLB/HInxQyer4jxhbE0qSWPSb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpylcA%2FbtsC2vCLQLB%2FHInxQyer4jxhbE0qSWPSb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;751&quot; height=&quot;364&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;364&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Information Security/iOS</category>
      <category>roothide</category>
      <category>roothideBootStrap</category>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/194</guid>
      <comments>https://hackcatml.tistory.com/194#entry194comment</comments>
      <pubDate>Sun, 7 Jan 2024 18:39:07 +0900</pubDate>
    </item>
    <item>
      <title>Frida-portal 사용법</title>
      <link>https://hackcatml.tistory.com/193</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;주로 단말기에서 frida-server 구동하고 attach 를 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;attach 방향이 Device &amp;lt;----- Local 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문득 Reverse TCP 처럼 방향이 Device ----&amp;gt; Local 은 될 수 없는 것일까? 라는 생각이 들었습니다만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 frida-portal 이라고 frida 15.0 버전에 도입되었더군요...허허&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;a href=&quot;https://frida.re/news/2021/07/18/frida-15-0-released/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://frida.re/news/2021/07/18/frida-15-0-released/&lt;/a&gt;,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://frida.re/docs/gadget/#connect&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://frida.re/docs/gadget/#connect&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 사용법은 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬에서 frida-portal 파이썬 코드 작성해서 구동시켜줍니다. (출처: &lt;a href=&quot;https://github.com/frida/frida-python/blob/bbdcdfaca821276361399775bd81599710ec0625/examples/portal_server.py&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/frida/frida-python/blob/bbdcdfaca821276361399775bd81599710ec0625/examples/portal_server.py&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cluster_params 는 gadget 이 attach 시도할 내 컴퓨터의 ip address 입니다. 192.168.0.76:27052 로 설정하였구요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;control_params 는 gadget 이 내 컴퓨터에 attach 되었을때, 이를 컨트롤 할 수 있게끔 노출되는 인터페이스입니다. 127.0.0.1:27042 로 설정하였습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701439138547&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# -*- coding: utf-8 -*-
import json

import frida
from frida_tools.application import Reactor

ENABLE_CONTROL_INTERFACE = True


def on_message(message, data):
    message = json.loads(message)
    if message is not None and 'payload' in message and message['payload'] is not None:
        print(message['payload'])


class Application:
    def __init__(self):
        self._reactor = Reactor(run_until_return=self._process_input)

        cluster_params = frida.EndpointParameters(address=&quot;192.168.0.76&quot;,
                                                  port=27052)

        if ENABLE_CONTROL_INTERFACE:
            control_params = frida.EndpointParameters(address=&quot;::1&quot;,
                                                      port=27042)
        else:
            control_params = None

        service = frida.PortalService(cluster_params, control_params)
        self._service = service
        self._device = service.device

        service.on('node-connected', lambda *args: self._reactor.schedule(lambda: self._on_node_connected(*args)))
        service.on('node-joined', lambda *args: self._reactor.schedule(lambda: self._on_node_joined(*args)))
        service.on('node-left', lambda *args: self._reactor.schedule(lambda: self._on_node_left(*args)))
        service.on('node-disconnected', lambda *args: self._reactor.schedule(lambda: self._on_node_disconnected(*args)))
        service.on('controller-connected', lambda *args: self._reactor.schedule(lambda: self._on_controller_connected(*args)))
        service.on('controller-disconnected', lambda *args: self._reactor.schedule(lambda: self._on_controller_disconnected(*args)))

    def run(self):
        self._reactor.schedule(self._start)
        self._reactor.run()

    def _start(self):
        self._service.start()
        self._device.enable_spawn_gating()

    def _stop(self):
        self._service.stop()

    def _process_input(self, reactor):
        while True:
            try:
                command = input(&quot;Enter command: &quot;).strip()
            except KeyboardInterrupt:
                self._reactor.cancel_io()
                return

            if len(command) == 0:
                print(&quot;Processes:&quot;, self._device.enumerate_processes())
                pid = self._device.enumerate_processes()[0].pid
                session = self._device.attach(pid)
                self._device.resume(pid)
                self.script = session.create_script('''
                    send(&quot;hello world&quot;);
                ''')
                self.script.on('message', on_message)
                self.script.load()
                continue

            if command == &quot;stop&quot;:
                self._reactor.schedule(self._stop)
                break

    def _on_node_connected(self, connection_id, remote_address):
        print(&quot;on_node_connected()&quot;, connection_id, remote_address)

    def _on_node_joined(self, connection_id, application):
        print(&quot;on_node_joined()&quot;, connection_id, application)
        print(&quot;\ttags:&quot;, self._service.enumerate_tags(connection_id))

    def _on_node_left(self, connection_id, application):
        print(&quot;on_node_left()&quot;, connection_id, application)

    def _on_node_disconnected(self, connection_id, remote_address):
        print(&quot;on_node_disconnected()&quot;, connection_id, remote_address)

    def _on_controller_connected(self, connection_id, remote_address):
        print(&quot;on_controller_connected()&quot;, connection_id, remote_address)

    def _on_controller_disconnected(self, connection_id, remote_address):
        print(&quot;on_controller_disconnected()&quot;, connection_id, remote_address)


if __name__ == '__main__':
    app = Application()
    app.run()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 frida-gadget 을 앱에 인젝션 시켜줍니다. 여러가지 방법이 있습니다만, 기본적으로 &lt;a href=&quot;https://hackcatml.tistory.com/58&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://hackcatml.tistory.com/58&lt;/a&gt; 참고해서 인젝션 할 수 있겠죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;config 파일을 위치시켜줘야 하는데, frida-gadget 과 동일 디렉터리에 확장자가 .config.so 라는 이름으로 위치시켜주면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1701439479867&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;lib
└── arm64-v8a
    ├── libgadget.config.so
    ├── libgadget.so&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;config 내용은 다음과 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1701439509415&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;interaction&quot;: {
    &quot;type&quot;: &quot;connect&quot;,
    &quot;address&quot;: &quot;192.168.0.76&quot;,
    &quot;port&quot;: 27052
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그다음 앱을 실행시켜주면, node 가 connect, join 했다는 알림이 뜹니다. Gadget 이 내 컴퓨터에 attach 한 것이지요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔터 입력하면, script 가 실행되어 &quot;hello world&quot;가 출력됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDXljq/btsBiqWoc7Z/XVkH5JSVpvhOuvfDboAF5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDXljq/btsBiqWoc7Z/XVkH5JSVpvhOuvfDboAF5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDXljq/btsBiqWoc7Z/XVkH5JSVpvhOuvfDboAF5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDXljq%2FbtsBiqWoc7Z%2FXVkH5JSVpvhOuvfDboAF5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1838&quot; height=&quot;328&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, frida -H 명령어로 control interface 에 frida 를 붙여줄수도 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkxhY6/btsBiV9EMwH/68j7zMqBTtnC5iwA6ENn80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkxhY6/btsBiV9EMwH/68j7zMqBTtnC5iwA6ENn80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkxhY6/btsBiV9EMwH/68j7zMqBTtnC5iwA6ENn80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkxhY6%2FbtsBiV9EMwH%2F68j7zMqBTtnC5iwA6ENn80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1064&quot; height=&quot;490&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;490&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Information Security/Android</category>
      <category>Frida</category>
      <category>frida-portal</category>
      <category>reverseTCP</category>
      <author>hackcatml</author>
      <guid isPermaLink="true">https://hackcatml.tistory.com/193</guid>
      <comments>https://hackcatml.tistory.com/193#entry193comment</comments>
      <pubDate>Fri, 1 Dec 2023 23:33:32 +0900</pubDate>
    </item>
  </channel>
</rss>