<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>D1N0's hacking blog</title>
    <link>https://d1n0.tistory.com/</link>
    <description>디노의 디지털 노가다</description>
    <language>ko</language>
    <pubDate>Mon, 13 Apr 2026 23:54:26 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>D1N0</managingEditor>
    <image>
      <title>D1N0's hacking blog</title>
      <url>https://tistory1.daumcdn.net/tistory/4342758/attach/4fd55ca14a9f4589ba3f967f67bbfb97</url>
      <link>https://d1n0.tistory.com</link>
    </image>
    <item>
      <title>vscode typescript 코딩 중 ssh 연결이 끊길 때</title>
      <link>https://d1n0.tistory.com/39</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;vscode remote ssh로 서버에 연결에서 typescript로 코딩하고 있는데 자꾸 연결이 끊겼다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버 접속도 안 되길래 서버 CPU 사용량을 보니까 100%를 훌쩍 넘어가 있었다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QPltC/btrIOwoQCbG/gBl4wzNzGdon3SUCRKOt3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QPltC/btrIOwoQCbG/gBl4wzNzGdon3SUCRKOt3k/img.png&quot; data-alt=&quot;CPU 사용량 126%를 돌파한 그래프&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QPltC/btrIOwoQCbG/gBl4wzNzGdon3SUCRKOt3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQPltC%2FbtrIOwoQCbG%2FgBl4wzNzGdon3SUCRKOt3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1023&quot; height=&quot;366&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CPU 사용량 126%를 돌파한 그래프&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;node 프로세스들이 CPU를 잔뜩 잡아먹길래 찾아봤더니 역시 이미 누가 해결방법을 올려놨다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vscode extensions에서 @builtin typescript를 검색하고 TypeScript and JavaScript Language Features를 disable시키면 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;215&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y7AsV/btrIMB5gjc8/aVlkBn5f3GlkWmmKYr8Mf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y7AsV/btrIMB5gjc8/aVlkBn5f3GlkWmmKYr8Mf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y7AsV/btrIMB5gjc8/aVlkBn5f3GlkWmmKYr8Mf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy7AsV%2FbtrIMB5gjc8%2FaVlkBn5f3GlkWmmKYr8Mf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;374&quot; height=&quot;215&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;215&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거 말고도 제시된 방법이 좀 있었는데 내가 고쳐졌던건 이거 하나였다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 typescript 부가 기능(import할 때 파일 목록을 보여준다던지 등)을 못 쓰는 임시방편의 방법이니 정 안 고쳐지면 사용하도록 하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;참고&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/microsoft/vscode-remote-release/issues/3319&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/microsoft/vscode-remote-release/issues/3319&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/good-robot/use-visual-studio-code-remote-ssh-sftp-without-crashing-your-server-a1dc2ef0936d&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://medium.com/good-robot/use-visual-studio-code-remote-ssh-sftp-without-crashing-your-server-a1dc2ef0936d&lt;/a&gt;&lt;/p&gt;</description>
      <category>Misc</category>
      <author>D1N0</author>
      <guid isPermaLink="true">https://d1n0.tistory.com/39</guid>
      <comments>https://d1n0.tistory.com/39#entry39comment</comments>
      <pubDate>Wed, 3 Aug 2022 16:56:44 +0900</pubDate>
    </item>
    <item>
      <title>UPX 패킹된 파일의 OEP 구하기</title>
      <link>https://d1n0.tistory.com/34</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. pushad, popad&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x96dbg로 패킹된 파일을 열어 사용자 코드로 실행을 하면 pushad 명령을 찾을 수 있다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;89&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhIh1d/btq79rvqYFh/pBYqHoovTQPv7TZAKG0ea0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhIh1d/btq79rvqYFh/pBYqHoovTQPv7TZAKG0ea0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhIh1d/btq79rvqYFh/pBYqHoovTQPv7TZAKG0ea0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhIh1d%2Fbtq79rvqYFh%2FpBYqHoovTQPv7TZAKG0ea0%2Fimg.png&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;89&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 실행을 위한 언패킹 전에 레지스터 상태를 스택에 저장하고, 언패킹이 끝날때 popad 명령으로 레지스터를 복구한다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;293&quot; data-origin-height=&quot;147&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfWTVC/btq73hPlwSQ/I0taUkI83tq89Cc49GGd60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfWTVC/btq73hPlwSQ/I0taUkI83tq89Cc49GGd60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfWTVC/btq73hPlwSQ/I0taUkI83tq89Cc49GGd60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfWTVC%2Fbtq73hPlwSQ%2FI0taUkI83tq89Cc49GGd60%2Fimg.png&quot; data-origin-width=&quot;293&quot; data-origin-height=&quot;147&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pushad를 실행하고 esp를 덤프해서 따라가면 레지스터들이 보인다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;76&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/96gMZ/btq79k4h9Ox/n8kVw39pFxXqjqV69A1dIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/96gMZ/btq79k4h9Ox/n8kVw39pFxXqjqV69A1dIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/96gMZ/btq79k4h9Ox/n8kVw39pFxXqjqV69A1dIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F96gMZ%2Fbtq79k4h9Ox%2Fn8kVw39pFxXqjqV69A1dIK%2Fimg.png&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;76&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 주소에 하드웨어 중단점을 걸어준다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;251&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dSBpx3/btq79pLby8T/KRYlu6hmGisX4soo3iVXC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dSBpx3/btq79pLby8T/KRYlu6hmGisX4soo3iVXC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSBpx3/btq79pLby8T/KRYlu6hmGisX4soo3iVXC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSBpx3%2Fbtq79pLby8T%2FKRYlu6hmGisX4soo3iVXC0%2Fimg.png&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;251&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 F9로 실행하면 언패킹이 끝난 주소에서 멈춘다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;126&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1fHkd/btq73jflTyx/mCmnKzwkENaLbhWG98YnV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1fHkd/btq73jflTyx/mCmnKzwkENaLbhWG98YnV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1fHkd/btq73jflTyx/mCmnKzwkENaLbhWG98YnV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1fHkd%2Fbtq73jflTyx%2FmCmnKzwkENaLbhWG98YnV0%2Fimg.png&quot; data-origin-width=&quot;717&quot; data-origin-height=&quot;126&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 popad 명령이 실행된 것을 확인할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jmp 08.1012475가 보이는데, 이 01012475가 이 프로그램의 OEP이다&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Exeinfo PE&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 upx로 파일을 언패킹해준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Exeinfo로 보면 EP를 바로 알 수 있다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;267&quot; data-origin-height=&quot;125&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GaC6l/btq74N09VxP/KFGtQPgDv5zuvExZlcEb41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GaC6l/btq74N09VxP/KFGtQPgDv5zuvExZlcEb41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GaC6l/btq74N09VxP/KFGtQPgDv5zuvExZlcEb41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGaC6l%2Fbtq74N09VxP%2FKFGtQPgDv5zuvExZlcEb41%2Fimg.png&quot; data-origin-width=&quot;267&quot; data-origin-height=&quot;125&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PE버튼을 눌러 헤더 정보를 보면 Image base를 알 수 있다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;463&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MGjQv/btq74Drgezn/DetkSJLLoi9ACmYg97gS1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MGjQv/btq74Drgezn/DetkSJLLoi9ACmYg97gS1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MGjQv/btq74Drgezn/DetkSJLLoi9ACmYg97gS1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMGjQv%2Fbtq74Drgezn%2FDetkSJLLoi9ACmYg97gS1K%2Fimg.png&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;463&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OEP는 EP랑 Image base를 더한 01012475이다&lt;/p&gt;</description>
      <category>Reversing</category>
      <author>D1N0</author>
      <guid isPermaLink="true">https://d1n0.tistory.com/34</guid>
      <comments>https://d1n0.tistory.com/34#entry34comment</comments>
      <pubDate>Fri, 25 Jun 2021 14:18:51 +0900</pubDate>
    </item>
    <item>
      <title>C언어 함수 호출과정 - x64</title>
      <link>https://d1n0.tistory.com/22</link>
      <description>&lt;p&gt;&lt;span&gt;이 글에서는 64bit 환경에서의 함수 호출 과정을 알아보겠다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;나는 함수 호출 규약을 64bit에선 fastcall만 쓰는 줄 알았는데,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;찾아보니 &lt;/span&gt;&lt;span&gt;vectorcall을 사용한다, 기본 64bit 호출 규약이 있다,... &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;말이 다 달라서 &lt;/span&gt;&lt;span&gt;용어는 모르겠지만 나는 그냥 gcc 기본옵션으로 컴파일된 바이너리를 살펴보겠다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;어차피 일반적으로 그냥 컴파일 된 바이너리를 제일 자주 볼 테니 말이다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;물론 내가 기본옵션으로 컴파일 한 파일이 일반적인 방식으로 컴파일된 파일이 아닐 수도 있다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;아무튼 나중에 자세히 알게된다면 이 부분에 대해선 다시 정리하겠다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 글은 전 글과 연결되어 있으니 아직 보지 않았다면 이전 글을 보고 오는 것을 추천한다&lt;/p&gt;
&lt;figure id=&quot;og_1612486343399&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;C언어 함수 호출과정 - cdecl&quot; data-og-description=&quot;포너블에서 너무 중요하고 기초적인 내용이지만 아직도 헷갈려서 정리한다 이 글은 독자가 기초적인 C언어와 어셈블리어를 알고 있는 상태라고 가정한다 모든 코드는 WSL Ubuntu 20.04 LTS에서 -m32 -n&quot; data-og-host=&quot;d1n0.tistory.com&quot; data-og-source-url=&quot;https://d1n0.tistory.com/21&quot; data-og-url=&quot;https://d1n0.tistory.com/21&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/maCp8/hyJabxdVml/Os6ERbN5zXRCU4pNSqbZBK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/po7xI/hyJbjf7Fzm/OQxfZUesNokaD9UTTC1sN0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bd8KGT/hyJak11Fbb/2kiDX7ICj4wbBHy4KBJO5K/img.jpg?width=745&amp;amp;height=700&amp;amp;face=0_0_745_700&quot;&gt;&lt;a href=&quot;https://d1n0.tistory.com/21&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://d1n0.tistory.com/21&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/maCp8/hyJabxdVml/Os6ERbN5zXRCU4pNSqbZBK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/po7xI/hyJbjf7Fzm/OQxfZUesNokaD9UTTC1sN0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/bd8KGT/hyJak11Fbb/2kiDX7ICj4wbBHy4KBJO5K/img.jpg?width=745&amp;amp;height=700&amp;amp;face=0_0_745_700');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;C언어 함수 호출과정 - cdecl&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;포너블에서 너무 중요하고 기초적인 내용이지만 아직도 헷갈려서 정리한다 이 글은 독자가 기초적인 C언어와 어셈블리어를 알고 있는 상태라고 가정한다 모든 코드는 WSL Ubuntu 20.04 LTS에서 -m32 -n&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;d1n0.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1612484144917&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
int foo(int a, int b, int c) {
    return a+b+c;
}

int main() {
    int a = foo(1, 2, 3);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이전 글과 같은 코드를 x64 환경에서 컴파일했다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;560&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnEpJz/btqVV2OwFgh/pTpgCD0K7kQGZ31YSwVxyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnEpJz/btqVV2OwFgh/pTpgCD0K7kQGZ31YSwVxyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnEpJz/btqVV2OwFgh/pTpgCD0K7kQGZ31YSwVxyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnEpJz%2FbtqVV2OwFgh%2FpTpgCD0K7kQGZ31YSwVxyK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;560&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;main은 이렇게&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;561&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8c1yg/btqVV214ud8/LUGKIKLIMJzccytavbcrYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8c1yg/btqVV214ud8/LUGKIKLIMJzccytavbcrYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8c1yg/btqVV214ud8/LUGKIKLIMJzccytavbcrYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8c1yg%2FbtqVV214ud8%2FLUGKIKLIMJzccytavbcrYK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;561&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;foo는 이렇게 생겼다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;32bit cdecl과 다른점은 함수를 호출하기 전 인자를 넘길 때 push로 스택에 저장하는 것이 아니라&lt;/p&gt;
&lt;p&gt;mov edx, 0x3&lt;/p&gt;
&lt;p&gt;mov esi, 0x2&lt;/p&gt;
&lt;p&gt;mov edi, 0x1 처럼 레지스터에 넣는다는 것이다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;foo함수에서는&lt;/p&gt;
&lt;p&gt;push rbp&lt;/p&gt;
&lt;p&gt;mov rbp, rsp로 64bit 레지스터에 해당하는 SFP를 푸시한다&lt;/p&gt;
&lt;p&gt;또, 함수를 호출할 때 레지스터에 넣었던 인자를 함수 내부에서 스택에 넣는 것을 확인할 수 있다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그러면 이제 직접 실행하며 스택과 레지스터의 변화를 살펴보자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;558&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J7j1w/btqWn1Dz7xw/qqcarhvrBk5CXBRMe2kuJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J7j1w/btqWn1Dz7xw/qqcarhvrBk5CXBRMe2kuJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J7j1w/btqWn1Dz7xw/qqcarhvrBk5CXBRMe2kuJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ7j1w%2FbtqWn1Dz7xw%2FqqcarhvrBk5CXBRMe2kuJK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;558&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;call foo 직전의 레지스터의 모습이다&lt;/p&gt;
&lt;p&gt;인자로 넘길 1, 2, 3이 rdi, rsi, rdx에 들어가 있다&lt;/p&gt;
&lt;p&gt;또한 스택은 sub rsp, 0x10으로 할당되어있는 상황이다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;708&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HapOm/btqWzsz0EIQ/LccfAfyUsPqIM5yvhTEWK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HapOm/btqWzsz0EIQ/LccfAfyUsPqIM5yvhTEWK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HapOm/btqWzsz0EIQ/LccfAfyUsPqIM5yvhTEWK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHapOm%2FbtqWzsz0EIQ%2FLccfAfyUsPqIM5yvhTEWK0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;708&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;함수 호출 전 스택은 이러하다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;707&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JgSYz/btqWztscqcM/kbPAGkFnzo8KmTUmL7HCkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JgSYz/btqWztscqcM/kbPAGkFnzo8KmTUmL7HCkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JgSYz/btqWztscqcM/kbPAGkFnzo8KmTUmL7HCkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJgSYz%2FbtqWztscqcM%2FkbPAGkFnzo8KmTUmL7HCkk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;707&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;함수에 들어가서&lt;/p&gt;
&lt;p&gt;push rbp&lt;/p&gt;
&lt;p&gt;mov rbp, rsp를 한 모습이다&lt;/p&gt;
&lt;p&gt;32bit와 마찬가지로 RET가 푸시되어있고, SFP가 그 위에 푸시되어있다&lt;/p&gt;
&lt;p&gt;32bit와 다르게 8byte씩 사용되는 것을 잊지 말자&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;711&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BMheB/btqWGLZ76W7/nIVycGeKiGqSElanM8vX9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BMheB/btqWGLZ76W7/nIVycGeKiGqSElanM8vX9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BMheB/btqWGLZ76W7/nIVycGeKiGqSElanM8vX9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBMheB%2FbtqWGLZ76W7%2FnIVycGeKiGqSElanM8vX9K%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;711&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;레지스터로 넘긴 인자를 스택에 저장하고 나면 이렇게 SFP 위에 들어가게 된다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그 뒤로는 함수의 기능을 하고, pop rbp로 SFP를 rbp에 넣어 원래 rbp를 복구하고, ret을 통해 main으로 돌아간다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여기까지 알아봤다면 몇가지 궁금증이 생긴다&lt;/p&gt;
&lt;p&gt;먼저, 인자가 엄청 많아서 레지스터에 다 집어넣을 수 없다면 어떻게 될지, 그리고 그 기준은 어떤지이다&lt;/p&gt;
&lt;p&gt;이걸 알아보기 위해 다음과 같은 코드를 컴파일해보겠다&lt;/p&gt;
&lt;pre id=&quot;code_1612852041266&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
int foo(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j) {
    return a+b+c+d+e+f+g+h+i+j;
}

int main() {
    int a = foo(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;610&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FaZNC/btqWBBqbYLo/aWZKKZolmgoMFrg4m79VcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FaZNC/btqWBBqbYLo/aWZKKZolmgoMFrg4m79VcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FaZNC/btqWBBqbYLo/aWZKKZolmgoMFrg4m79VcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFaZNC%2FbtqWBBqbYLo%2FaWZKKZolmgoMFrg4m79VcK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;610&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;main은 이렇게 컴파일된다&lt;/p&gt;
&lt;p&gt;첫 번째부터 여섯 번째까지의 인자는 순서대로 rdi, rsi, rdx, rcx, r8, r9에 들어가고,&lt;/p&gt;
&lt;p&gt;그다음부턴 스택에 쌓는 것을 확인할 수 있다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;610&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dWBor8/btqWzt0jjJW/eLGeeLOSWBFpqz4BMqR2j0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dWBor8/btqWzt0jjJW/eLGeeLOSWBFpqz4BMqR2j0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dWBor8/btqWzt0jjJW/eLGeeLOSWBFpqz4BMqR2j0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdWBor8%2FbtqWzt0jjJW%2FeLGeeLOSWBFpqz4BMqR2j0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;610&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;foo는 이렇게 생겼는데, 레지스터에 들어있는 인자는 스택에 넣어주고, 원래 스택에 넣었던 7번째 이후의 인자는 별다른 처리 없이 바로 참조한다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;691&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0O6RX/btqWxfBvXcy/sF73bkklVPMRrRZucfZjoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0O6RX/btqWxfBvXcy/sF73bkklVPMRrRZucfZjoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0O6RX/btqWxfBvXcy/sF73bkklVPMRrRZucfZjoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0O6RX%2FbtqWxfBvXcy%2FsF73bkklVPMRrRZucfZjoK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;691&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;6번째까지의 인자와 그 후의 인자가 분리되기 때문에 스택 모습을 보면 되게 묘한데,&lt;/p&gt;
&lt;p&gt;7번째부터의 인자가 아래에 깔려있고, 그위에 RET와 SFP이, 그 위에 1~6번째 인자가 올라와있다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 점 말고는 전과 크게 다르지 않다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그다음 궁금한 점은 x86과 마찬가지로 함수 내에서 지역변수가 사용되면 어떻게 될지이다&lt;/p&gt;
&lt;p&gt;이번에도 전과 같은 코드를 준비했다&lt;/p&gt;
&lt;pre id=&quot;code_1612859621616&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
int foo(int a, int b, int c) {
    int d=4;
    int e=5;
    int f=6;
    return a+b+c+d+e+f;
}

int main(){
    int a = foo(1, 2, 3);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;592&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s3P2m/btqWx6EjP00/zcMDmXiOtdprlugMETQgf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s3P2m/btqWx6EjP00/zcMDmXiOtdprlugMETQgf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s3P2m/btqWx6EjP00/zcMDmXiOtdprlugMETQgf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs3P2m%2FbtqWx6EjP00%2FzcMDmXiOtdprlugMETQgf0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;592&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;main은 전과 같고, foo는 위의 형태로 컴파일되었다&lt;/p&gt;
&lt;p&gt;한 가지 이상한 점은 sub rsp부분이 없고, 때문에 leave부분도 없다는 것이다&lt;/p&gt;
&lt;p&gt;이 부분에 대해선 잘 모르겠는데, 다른 글에서는 애초에 rbp가 아니라 rsp를 기준으로 스택이 지정된다고도 하고,&lt;/p&gt;
&lt;p&gt;스택 공간이 애초에 할당되지도 않은걸 보면 앞서 말했듯 기본 컴파일 옵션이 뭔가 최적화를 했다거나 해서 변화가 일어난 게 아닐까 추측해본다&lt;/p&gt;
&lt;p&gt;이 부분 외에는 역시 특별한 건 없다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이렇게 64비트 환경에서의 기본적인 함수 호출 과정을 알아보았다&lt;/p&gt;
&lt;p&gt;애초에 그냥 간단히 흐름만 정리한다는 걸 너무 자세히 정리한 것 같다&lt;/p&gt;
&lt;p&gt;다시 한번 말하지만, 이 글은 그냥 내 환경에서 간단히 테스트해본 것이므로 일반적인 상황과 다를 수 있다&lt;/p&gt;
&lt;p&gt;인터넷에 다른 좋은 글도 많으니 내 글과 안 맞다고 이상하게 생각하지 말고 그때그때 상황에 맞는 정보를 찾아보도록 하자&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 글에서 사용한 실행파일은 모두 이곳에 올려놓았다&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://drive.google.com/file/d/1f9cWjZKnVYuAGaaJmM4sPI8XemB3Gqhr/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;drive.google.com/file/d/1f9cWjZKnVYuAGaaJmM4sPI8XemB3Gqhr/view?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1612861641051&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;64bit.tar.gz&quot; data-og-description=&quot;&quot; data-og-host=&quot;drive.google.com&quot; data-og-source-url=&quot;https://drive.google.com/file/d/1f9cWjZKnVYuAGaaJmM4sPI8XemB3Gqhr/view?usp=sharing&quot; data-og-url=&quot;https://drive.google.com/file/d/1f9cWjZKnVYuAGaaJmM4sPI8XemB3Gqhr/view?usp=sharing&amp;amp;usp=embed_facebook&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/1f9cWjZKnVYuAGaaJmM4sPI8XemB3Gqhr/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://drive.google.com/file/d/1f9cWjZKnVYuAGaaJmM4sPI8XemB3Gqhr/view?usp=sharing&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;64bit.tar.gz&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;drive.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Pwnable</category>
      <author>D1N0</author>
      <guid isPermaLink="true">https://d1n0.tistory.com/22</guid>
      <comments>https://d1n0.tistory.com/22#entry22comment</comments>
      <pubDate>Tue, 9 Feb 2021 18:08:16 +0900</pubDate>
    </item>
    <item>
      <title>C언어 함수 호출과정 - x86</title>
      <link>https://d1n0.tistory.com/21</link>
      <description>&lt;p&gt;포너블에서 너무 중요하고 기초적인 내용이지만 아직도 헷갈려서 정리한다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 글은 독자가 기초적인 C언어와 어셈블리어를 알고 있는 상태라고 가정한다&lt;/p&gt;
&lt;p&gt;모든 코드는 WSL Ubuntu 20.04 LTS에서 -m32 -no-pie 옵션을 사용해서 gcc로 컴파일 되었고,&lt;/p&gt;
&lt;p&gt;실행 파일들은 글 하단에 올려놓았다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;cdecl은 수많은 32bit 프로그램에서 사용되는 방식이다&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;함수를 호출하고, 호출자가 스택을 정리하는 &lt;/span&gt;호출자 정리 방식의 일종이다&lt;/p&gt;
&lt;pre id=&quot;code_1612409946080&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
int foo(int a, int b, int c) {
    return a+b+c;
}

int main() {
    int a = foo(1, 2, 3);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;위와 같은 C 코드를 짜고 32bit 컴파일을 했다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;gef gdb로 까 보면&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;509&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsd31X/btqVFCw2OOJ/tAbqelHwiOJdYClT97RmB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsd31X/btqVFCw2OOJ/tAbqelHwiOJdYClT97RmB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsd31X/btqVFCw2OOJ/tAbqelHwiOJdYClT97RmB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdsd31X%2FbtqVFCw2OOJ%2FtAbqelHwiOJdYClT97RmB0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;509&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;main 함수는 이렇게,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;513&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lxXJA/btqVyVRR9Lw/WoVRgChIiyzNFKia5ulZL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lxXJA/btqVyVRR9Lw/WoVRgChIiyzNFKia5ulZL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lxXJA/btqVyVRR9Lw/WoVRgChIiyzNFKia5ulZL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlxXJA%2FbtqVyVRR9Lw%2FWoVRgChIiyzNFKia5ulZL0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;513&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;foo함수는 이렇게 컴파일되었다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여기서 우리가 주목해야 할 것은 main에서의 push 0x3, push 0x2, push 0x1이다&lt;/p&gt;
&lt;p&gt;여기서 우리는 cdecl 호출 방식은 함수에 전달되는 인자는 오른쪽부터 하나씩 스택에 푸시하고 함수를 실행하는 것을 알 수 있다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;두 번째는 call foo를 하면 어떤 일이 일어나는가인데,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KFYlF/btqVFCjVpmD/IIzI7AltDZdnbmcQQhXN5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KFYlF/btqVFCjVpmD/IIzI7AltDZdnbmcQQhXN5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KFYlF/btqVFCjVpmD/IIzI7AltDZdnbmcQQhXN5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKFYlF%2FbtqVFCjVpmD%2FIIzI7AltDZdnbmcQQhXN5k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;위와 같던 스택이 call foo 후에는&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/28WPb/btqVIKu10eB/Ee3VkQEMKZKn1zmGQQ9qe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/28WPb/btqVIKu10eB/Ee3VkQEMKZKn1zmGQQ9qe0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/28WPb/btqVIKu10eB/Ee3VkQEMKZKn1zmGQQ9qe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F28WPb%2FbtqVIKu10eB%2FEe3VkQEMKZKn1zmGQQ9qe0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이렇게 0x080491b5이 푸시된 것을 확인할 수 있다&lt;/p&gt;
&lt;p&gt;call은 push eip&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jmp [주소] 같은 역할을 하고,&lt;/p&gt;
&lt;p&gt;0x080491b5는 main에서 call foo 다음 명령의 주소, 즉 push eip를 통해 푸시된 값임을 알 수 있다&lt;/p&gt;
&lt;p&gt;이것을 RET라고 부르는데, 함수 실행이 끝나고 돌아갈 주소를 이 RET을 참조한다&lt;/p&gt;
&lt;p&gt;수많은 바이너리 해킹이 이 RET을 조작하여 이루어진다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그 후 push ebp와 mov ebp, esp가 실행되며 main의 스택과 구분되는 새로운 foo의 스택이 할당된다&lt;/p&gt;
&lt;p&gt;이 과정을 함수 프롤로그라고 하고, 푸시된 ebp는 SFP(Stack Frame Pointer)라고 부른다&lt;/p&gt;
&lt;p&gt;스택 모양을 보면 다음과 같다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLSf5z/btqVCbAcJCN/NZVODXlzWtGTVMplwzHS9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLSf5z/btqVCbAcJCN/NZVODXlzWtGTVMplwzHS9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLSf5z/btqVCbAcJCN/NZVODXlzWtGTVMplwzHS9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLSf5z%2FbtqVCbAcJCN%2FNZVODXlzWtGTVMplwzHS9k%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;0xffffd068이 main의 ebp이고, foo에서는 0xffffd044라는 새로운 ebp를 갖게 된다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;함수는 이 ebp를 바탕으로 인자를 사용하는데,&lt;/p&gt;
&lt;p&gt;mov edx,DWORD PTR [ebp+0x8]와 같이 ebp+숫자 와 같은 방식으로 참조하게 된다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;함수의 역할이 모두 끝난 후에는 pop ebp, ret을 한다&lt;/p&gt;
&lt;p&gt;현재 foo에서는 스택에 값을 푸시하지 않았으므로 여전히 esp는 SFP를 가리키고 있다&lt;/p&gt;
&lt;p&gt;때문에 pop ebp를 하면 ebp에 함수 프롤로그에서 넣었던 SFP가 들어가고,&lt;/p&gt;
&lt;p&gt;esp는 함수를 호출하기 전과 같은 값을 가진다&lt;/p&gt;
&lt;p&gt;ret은 &lt;span&gt;pop eip&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jmp eip 같은 기능을 한다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;call에서 푸시된 RET를 참조해 원래 main의 주소로 돌아가며 foo 함수가 끝난다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이렇게 함수가 끝나고 처음 상태로 스택을 복원하는 것을 함수 에필로그라고 한다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;마지막으로 main에서는 add esp, 0xc를 통해 인자로 넘기기 위해 푸시한 것을 복원한다&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;글로만 써놓으니 복잡한데, 스택의 변화를 그림으로 보겠다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;405&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6zcU0/btqVQW2lWUk/LXxY9WDROI8lZYfk1hbRI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6zcU0/btqVQW2lWUk/LXxY9WDROI8lZYfk1hbRI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6zcU0/btqVQW2lWUk/LXxY9WDROI8lZYfk1hbRI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6zcU0%2FbtqVQW2lWUk%2FLXxY9WDROI8lZYfk1hbRI0%2Fimg.png&quot; width=&quot;405&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;3, 2, 1 순서대로 인자를 스택에 푸시한 뒤,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;397&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WfWrX/btqVCcMN39D/nQVf8i7RKGdZ7Aoo9R2PkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WfWrX/btqVCcMN39D/nQVf8i7RKGdZ7Aoo9R2PkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WfWrX/btqVCcMN39D/nQVf8i7RKGdZ7Aoo9R2PkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWfWrX%2FbtqVCcMN39D%2FnQVf8i7RKGdZ7Aoo9R2PkK%2Fimg.png&quot; width=&quot;397&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;call foo에서 다음 main의 주소 RET을 스택에 푸시하고,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;439&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2kMCa/btqVFByLXmP/Rp0xONT19tGKQWGVrWsOc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2kMCa/btqVFByLXmP/Rp0xONT19tGKQWGVrWsOc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2kMCa/btqVFByLXmP/Rp0xONT19tGKQWGVrWsOc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2kMCa%2FbtqVFByLXmP%2FRp0xONT19tGKQWGVrWsOc0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;439&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;push ebp, &lt;span style=&quot;color: #333333;&quot;&gt;mov ebp, esp에서 SFP를 스택에 푸시한다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;397&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WfWrX/btqVCcMN39D/nQVf8i7RKGdZ7Aoo9R2PkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WfWrX/btqVCcMN39D/nQVf8i7RKGdZ7Aoo9R2PkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WfWrX/btqVCcMN39D/nQVf8i7RKGdZ7Aoo9R2PkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWfWrX%2FbtqVCcMN39D%2FnQVf8i7RKGdZ7Aoo9R2PkK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;397&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;함수의 역할이 끝나면 &lt;span style=&quot;color: #333333;&quot;&gt;pop ebp로 ebp를 복원하고,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;405&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6zcU0/btqVQW2lWUk/LXxY9WDROI8lZYfk1hbRI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6zcU0/btqVQW2lWUk/LXxY9WDROI8lZYfk1hbRI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6zcU0/btqVQW2lWUk/LXxY9WDROI8lZYfk1hbRI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6zcU0%2FbtqVQW2lWUk%2FLXxY9WDROI8lZYfk1hbRI0%2Fimg.png&quot; width=&quot;405&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;ret을 통해&amp;nbsp; main으로 돌아온다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;cdecl의 또 다른 상황을 보도록 하자&lt;/p&gt;
&lt;pre id=&quot;code_1612427196525&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
int foo(int a, int b, int c) {
    int d=4;
    int e=5;
    int f=6;
    return a+b+c+d+e+f;
}

int main(){
    int a = foo(1, 2, 3);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;앞의 예제에 foo를 살짝 바꾼 코드이다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;528&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buYPGf/btqVSu5n1SD/UdKqK3cbdZlBHPKV53hUMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buYPGf/btqVSu5n1SD/UdKqK3cbdZlBHPKV53hUMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buYPGf/btqVSu5n1SD/UdKqK3cbdZlBHPKV53hUMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuYPGf%2FbtqVSu5n1SD%2FUdKqK3cbdZlBHPKV53hUMK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;528&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;gdb로 까 보면 main은 다르지 않지만 foo부분이 조금 달라졌다&lt;/p&gt;
&lt;p&gt;int d=4; &lt;br /&gt;int e=5; &lt;br /&gt;int f=6;&lt;/p&gt;
&lt;p&gt;때문에 foo에서도 스택을 사용하는 것을 볼 수 있다&lt;/p&gt;
&lt;p&gt;sub esp, 0x10으로 esp를 0x10만큼 낮은 주소로 이동하여 스택을 할당하고,&lt;/p&gt;
&lt;p&gt;mov DWORD PTR [ebp-0xc], 0x4 같은 명령으로 할당한 스택을 사용하고 있다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;741&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d8C1vq/btqVFByQdrm/yKzfEGP0MWav8xaPgknk70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d8C1vq/btqVFByQdrm/yKzfEGP0MWav8xaPgknk70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d8C1vq/btqVFByQdrm/yKzfEGP0MWav8xaPgknk70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd8C1vq%2FbtqVFByQdrm%2FyKzfEGP0MWav8xaPgknk70%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;741&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;스택의 모습을 보면 3, 2, 1이 들어가 있고,&lt;/p&gt;
&lt;p&gt;RET(0x080491dc)가 들어가 있고,&lt;/p&gt;
&lt;p&gt;SFP(0xffffd068)가 있고,&lt;/p&gt;
&lt;p&gt;6, 5, 4 순서대로 변수가 들어있다(맨 앞의 0x00080000는 더미 값이다)&lt;/p&gt;
&lt;p&gt;여기서 주목할 점은 인자를 넘길 때와 다르게 함수 내부에서 스택을 사용할 때는 push를 하며 낮은 주소로 움직이는 게 아니라 이미 할당되어 있는 스택에 대해 mov 명령을 사용해 대입한다는 점이다&lt;/p&gt;
&lt;p&gt;이 때문에 포너블에서 RET을 덮을 수 있다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그리고, &lt;span style=&quot;color: #333333;&quot;&gt;pop ebp 대신 leave라는 명령어가 등장했다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;leave는 mov ebp, esp&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;pop ebp라고 생각하면 된다&lt;/p&gt;
&lt;p&gt;이것이 SFP를 사용하는 이유인데, 함수에서 스택을 사용해서 esp가 저 위에 가있더라도 esp를 ebp에 옮기고 (정확히는 esp에 ebp의 값을 넣고), ebp가 가리키고 있던 SFP를 ebp에 넣음으로써 스택을 원상태로 복구할 수 있다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이렇게 cdecl에서의 함수 호출 과정에 대해 알아봤다&lt;/p&gt;
&lt;p&gt;cdecl은 함수를 호출할 때 인자를 스택에 푸시하는 방식으로 전달하고,&lt;/p&gt;
&lt;p&gt;함수가 끝나면 호출자에서 그 스택을 정리하는 것이 특징이라고 요약할 수 있겠다&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 글에서 사용한 실행파일은 여기에 올려놓았다&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://drive.google.com/file/d/1IHDe1UldlgFvFXWveBGowpcbiv-0XpSi/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;drive.google.com/file/d/1IHDe1UldlgFvFXWveBGowpcbiv-0XpSi/view?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1612430006996&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;cdecl.tar.gz&quot; data-og-description=&quot;&quot; data-og-host=&quot;drive.google.com&quot; data-og-source-url=&quot;https://drive.google.com/file/d/1IHDe1UldlgFvFXWveBGowpcbiv-0XpSi/view?usp=sharing&quot; data-og-url=&quot;https://drive.google.com/file/d/1IHDe1UldlgFvFXWveBGowpcbiv-0XpSi/view?usp=sharing&amp;amp;usp=embed_facebook&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://drive.google.com/file/d/1IHDe1UldlgFvFXWveBGowpcbiv-0XpSi/view?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://drive.google.com/file/d/1IHDe1UldlgFvFXWveBGowpcbiv-0XpSi/view?usp=sharing&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;cdecl.tar.gz&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;drive.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Pwnable</category>
      <author>D1N0</author>
      <guid isPermaLink="true">https://d1n0.tistory.com/21</guid>
      <comments>https://d1n0.tistory.com/21#entry21comment</comments>
      <pubDate>Thu, 4 Feb 2021 18:18:02 +0900</pubDate>
    </item>
    <item>
      <title>Z3 solver 정리</title>
      <link>https://d1n0.tistory.com/18</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Z3 solver&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;z3 solver는 특정 값들을 찾아주는 SMT solver 모듈이라고 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면 여러 수식을 풀어주는 모듈이라고 생각하면 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리버싱 할 때도 많이 필요하고 그게 아니더라도 유용히 쓸 수 있을 거 같아서 정리하기로 했다&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 Z3 solver 모듈의 링크는 이곳이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Z3Prover/z3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/Z3Prover/z3&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어가면 다양한 언어에서의 설치 과정이 자세히 나와있지만 나는 파이썬을 쓸 거라서 pip로 간단히 설치가 가능하다&lt;/p&gt;
&lt;pre id=&quot;code_1607948023112&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install z3-solver

 or
 
pip3 install z3-solver&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기본 문법&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;사용 전 모듈 불러오기&lt;/h4&gt;
&lt;pre id=&quot;code_1607948125121&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from z3 import *&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정수형 미지수 선언&lt;/h4&gt;
&lt;pre id=&quot;code_1607948194858&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;x = Int('x')
y = Int('y')&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;실수형 미지수 선언&lt;/h4&gt;
&lt;pre id=&quot;code_1607948218914&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;x = Real('x')
y = Real('y')&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;불 형 미지수 선언&lt;/h4&gt;
&lt;pre id=&quot;code_1607989883145&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;x = Bool('x')
y = Bool('y')&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;비트 벡터 미지수 선언&lt;/h4&gt;
&lt;pre id=&quot;code_1607948370208&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;x = BitVec('x',16)
y = BitVec('y',16)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트벡터는 모듈러 역수 같은걸 구할 때 쓰인다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미지수 뒤의 숫자는 몇 비트인지를 설정해주는 숫자이다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;답 구하기&lt;/h4&gt;
&lt;pre id=&quot;code_1607948644688&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;solve()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시로 $\begin{cases}x+y=12\\x-y=6\end{cases}$라는 연립방정식의 해를 구하려고 하면 아래와 같이 쓸 수 있다&lt;/p&gt;
&lt;pre id=&quot;code_1607952263847&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from z3 import *
&amp;gt;&amp;gt;&amp;gt; x = Int('x')
&amp;gt;&amp;gt;&amp;gt; y = Int('y')
&amp;gt;&amp;gt;&amp;gt; solve(x+y==12,x-y==6)
[x = 9, y = 3]&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Solver class&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;z3 solver는 Solver라는 객체를 지원하는데, 이를 사용하면 여러 수식을 원할때 추가하고 계산하는 식을 나누는 등 더욱 쉽게 코드를 짤 수 있다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;선언&lt;/h4&gt;
&lt;pre id=&quot;code_1607952276422&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;s = Solver()&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;식 추가&lt;/h4&gt;
&lt;pre id=&quot;code_1607952288381&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;s.add()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 본 식을 Solver 객체로 추가해보자&lt;/p&gt;
&lt;pre id=&quot;code_1607951057008&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; s = Solver()
&amp;gt;&amp;gt;&amp;gt; s.add(x+y==12)
&amp;gt;&amp;gt;&amp;gt; s.add(x-y==3)
&amp;gt;&amp;gt;&amp;gt; s
[x + y == 12, x - y == 3]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 들어간것을 알 수 있다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;push &amp;amp; pop&lt;/h4&gt;
&lt;pre id=&quot;code_1607951225569&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;s.push()
s.pop()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수식의 이전 상태를 기억해놓기 위한 함수 push와 push 했던 상태로 되돌리는 pop이 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;push를 하고 수식을 추가하다가 pop을 하면 push를 했을때의 식 상황으로 돌아간다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;해의 존재 여부&lt;/h4&gt;
&lt;pre id=&quot;code_1607951330704&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;s.check()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 식들을 모두 만족하는 해가 있으면 sat, 없으면 unsat, 해결할 수 없는 식이면 unknown을 반환한다&lt;/p&gt;
&lt;pre id=&quot;code_1607952107861&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;s.reason_unknown()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;unkwown일 때는 위 함수를 통해 그 이유를 알 수 있다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;답 구하기&lt;/h4&gt;
&lt;pre id=&quot;code_1607951677367&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;s.model()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;s.check()가 sat일 때 만족하는 해 중 하나를 반환한다&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;초기화&lt;/h4&gt;
&lt;pre id=&quot;code_1607988368405&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;s.reset()&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;예제&lt;/h4&gt;
&lt;pre id=&quot;code_1607988276334&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from z3 import *
&amp;gt;&amp;gt;&amp;gt; x = Int('x')
&amp;gt;&amp;gt;&amp;gt; y = Int('y')
&amp;gt;&amp;gt;&amp;gt; s = Solver()
&amp;gt;&amp;gt;&amp;gt; s.add(x+y&amp;lt;12)
&amp;gt;&amp;gt;&amp;gt; s.add(x&amp;gt;8)
&amp;gt;&amp;gt;&amp;gt; s.push()
&amp;gt;&amp;gt;&amp;gt; s.add(y&amp;gt;9)
&amp;gt;&amp;gt;&amp;gt; s.check()
unsat
&amp;gt;&amp;gt;&amp;gt; s.pop()
&amp;gt;&amp;gt;&amp;gt; s
[x + y &amp;lt; 12, x &amp;gt; 8]
&amp;gt;&amp;gt;&amp;gt; s.check()
sat 
&amp;gt;&amp;gt;&amp;gt; s.model()
[y = 2, x = 9]
&amp;gt;&amp;gt;&amp;gt; s.reset()
&amp;gt;&amp;gt;&amp;gt; s
[]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;push를 하고 식을 추가했더니 unsat이 떠서 pop으로 되돌려 답을 구하는 모습이다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;답을 구한후 reset을 하니 식이 모두 사라지는 걸 볼 수 있다&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;답을 모두 구하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 풀다보면 답이 하나가 아닌 경우가 생긴다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴 때는 전에 구한 답이 중복되는지 비교하는 식을 넣어주면 된다&lt;/p&gt;
&lt;pre id=&quot;code_1607990492253&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;while s.check() == sat:
  print s.model()
  s.add(Or(x != s.model()[x], y != s.model()[y]))&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그 외&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지는 필요하면 추가하도록 하겠다&lt;/p&gt;</description>
      <category>Reversing</category>
      <author>D1N0</author>
      <guid isPermaLink="true">https://d1n0.tistory.com/18</guid>
      <comments>https://d1n0.tistory.com/18#entry18comment</comments>
      <pubDate>Mon, 14 Dec 2020 21:36:39 +0900</pubDate>
    </item>
  </channel>
</rss>