cea-sec/miasm

View on GitHub
doc/ir/lift.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Prerequisite: the reader is encouraged to read the documentation of `expression` and `locationdb` before this part.\n",
    "\n",
    "# Miasm Intermediate representation\n",
    "The intermediate representation of Miasm allows to represent the `side effects` of instructions in a control flow graph. To summarise, here is the correspondence between native world and its intermediate representation:\n",
    "- an assembly control flow graph (`AsmCFG`) is represented in intermediate representation by an \"Intermediate representation control flow graph\": `IRCfg`\n",
    "- an AsmCFG in composed of basic blocks. In intermediate representation, the `IRCfg` is composed of Intermediate representation blocks: `IRBlock`s\n",
    "- a native basic block is a sequence of instructions. In intermediate representation, the `IRBlock` if a sequence of `AssignBlock`s\n",
    "- an `AssignBlock` is composed of parallel assignments of expressions. \"Parallel\" mean that those assignments are executed exactly the same time (different from successive)\n",
    "\n",
    "Note this does not imply that an instruction translates to an `AssignBlock`. The translation of a native instruction can generate multiple `AssignBlock`s and even multiple `IRBlock`s. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Examples\n",
    "Let's take some examples of translated instructions. First of all, we will create an helper to generate intermediate representation from assembly code. Skip this code, it's not important for the rest of the documentation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from miasm.analysis.machine import Machine\n",
    "from miasm.arch.x86.arch import mn_x86\n",
    "from miasm.core import parse_asm, asmblock\n",
    "from miasm.arch.x86.lifter_model_call import LifterModelCall_x86_32\n",
    "from miasm.core.locationdb import LocationDB\n",
    "from miasm.loader.strpatchwork import StrPatchwork\n",
    "from miasm.analysis.binary import Container\n",
    "from miasm.ir.ir import IRCFG, AssignBlock\n",
    "from miasm.expression.expression import *\n",
    "import logging\n",
    "\n",
    "# Quiet warnings\n",
    "asmblock.log_asmblock.setLevel(logging.ERROR)\n",
    "\n",
    "\n",
    "def gen_x86_asmcfg(asm):\n",
    "    # First, asm code\n",
    "    machine = Machine(\"x86_32\")\n",
    "\n",
    "    # Add dummy label \"end\" at code's end\n",
    "    code = asm + \"\\nend:\\n\"\n",
    "    loc_db = LocationDB()\n",
    "    # The main will be at address 0\n",
    "    loc_db.set_location_offset(loc_db.get_or_create_name_location(\"main\"), 0x0)\n",
    "\n",
    "    asmcfg = parse_asm.parse_txt(\n",
    "        mn_x86, 32, code,\n",
    "        loc_db\n",
    "    )\n",
    "    virt = StrPatchwork()\n",
    "    # Assemble shellcode\n",
    "    patches = asmblock.asm_resolve_final(\n",
    "        machine.mn,\n",
    "        asmcfg,\n",
    "    )\n",
    "    # Put shelcode in a string\n",
    "    for offset, raw in patches.items():\n",
    "        virt[offset] = raw\n",
    "    data = bytes(virt)\n",
    "    cont = Container.fallback_container(\n",
    "        data,\n",
    "        vm=None, addr=0,\n",
    "        loc_db=loc_db,\n",
    "    )\n",
    "    dis_engine = machine.dis_engine\n",
    "    # Disassemble back the shellcode\n",
    "    # Now, basic blocks are at known position, determined by\n",
    "    # the assembled version\n",
    "    mdis = dis_engine(cont.bin_stream, loc_db=cont.loc_db)\n",
    "    asmcfg = mdis.dis_multiblock(0)\n",
    "    return asmcfg\n",
    "\n",
    "def lift_x86_asm(asm, model_call=False, lifter_custom=None):\n",
    "    asmcfg = gen_x86_asmcfg(asm)\n",
    "    machine = Machine(\"x86_32\")\n",
    "    # Get a lifter\n",
    "    if model_call and lifter_custom is None:\n",
    "        lifter = LifterModelCall_x86_32(asmcfg.loc_db)\n",
    "    elif lifter_custom is not None:\n",
    "        lifter = lifter_custom(asmcfg.loc_db)\n",
    "    else:\n",
    "        lifter = machine.lifter(asmcfg.loc_db)\n",
    "\n",
    "    # Translate to IR\n",
    "    ircfg = lifter.new_ircfg_from_asmcfg(asmcfg)\n",
    "    return ircfg\n",
    "\n",
    "def graph_ir_x86(asm, model_call=False, lifter_custom=None):\n",
    "    ircfg = lift_x86_asm(asm, model_call, lifter_custom)\n",
    "    return ircfg.graphviz()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"193pt\" height=\"158pt\"\n",
       " viewBox=\"0.00 0.00 193.00 158.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 154)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-154 189,-154 189,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 173,-93.5 173,-93.5 179,-93.5 185,-99.5 185,-105.5 185,-105.5 185,-137.5 185,-137.5 185,-143.5 179,-149.5 173,-149.5 173,-149.5 12,-149.5 12,-149.5 6,-149.5 0,-143.5 0,-137.5 0,-137.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10.5,-122.5 10.5,-143.5 175.5,-143.5 175.5,-122.5 10.5,-122.5\"/>\n",
       "<text text-anchor=\"start\" x=\"76\" y=\"-129.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-106.3\" font-family=\"Courier New\" font-size=\"14.00\">MOV &#160;&#160;&#160;&#160;&#160;&#160;&#160;EAX, EBX</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M61.5,-0.5C61.5,-0.5 123.5,-0.5 123.5,-0.5 129.5,-0.5 135.5,-6.5 135.5,-12.5 135.5,-12.5 135.5,-44.5 135.5,-44.5 135.5,-50.5 129.5,-56.5 123.5,-56.5 123.5,-56.5 61.5,-56.5 61.5,-56.5 55.5,-56.5 49.5,-50.5 49.5,-44.5 49.5,-44.5 49.5,-12.5 49.5,-12.5 49.5,-6.5 55.5,-0.5 61.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"59.5,-29.5 59.5,-50.5 125.5,-50.5 125.5,-29.5 59.5,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"80\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<text text-anchor=\"start\" x=\"62.5\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">IOError</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"blue\" d=\"M92.5,-93.2C92.5,-84.92 92.5,-75.68 92.5,-66.86\"/>\n",
       "<polygon fill=\"blue\" stroke=\"blue\" points=\"96,-66.78 92.5,-56.78 89,-66.78 96,-66.78\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f62910602b0>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Let's generate the AsmCFG\n",
    "asmcfg = gen_x86_asmcfg(\"\"\"\n",
    "main:\n",
    "    MOV EAX, EBX\n",
    "\"\"\")\n",
    "asmcfg.graphviz()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"152pt\" height=\"197pt\"\n",
       " viewBox=\"0.00 0.00 152.00 197.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 193)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-193 148,-193 148,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 132,-93.5 132,-93.5 138,-93.5 144,-99.5 144,-105.5 144,-105.5 144,-176.5 144,-176.5 144,-182.5 138,-188.5 132,-188.5 132,-188.5 12,-188.5 12,-188.5 6,-188.5 0,-182.5 0,-176.5 0,-176.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10,-161 10,-182 134,-182 134,-161 10,-161\"/>\n",
       "<text text-anchor=\"start\" x=\"55\" y=\"-167.8\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-144.8\" font-family=\"Courier New\" font-size=\"14.00\">EAX = EBX</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-113.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M24.5,-0.5C24.5,-0.5 119.5,-0.5 119.5,-0.5 125.5,-0.5 131.5,-6.5 131.5,-12.5 131.5,-12.5 131.5,-44.5 131.5,-44.5 131.5,-50.5 125.5,-56.5 119.5,-56.5 119.5,-56.5 24.5,-56.5 24.5,-56.5 18.5,-56.5 12.5,-50.5 12.5,-44.5 12.5,-44.5 12.5,-12.5 12.5,-12.5 12.5,-6.5 18.5,-0.5 24.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"23,-29.5 23,-50.5 122,-50.5 122,-29.5 23,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"60\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"23,-6.5 23,-27.5 120,-27.5 120,-6.5 23,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"26\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M72,-93.46C72,-84.57 72,-75.37 72,-66.82\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"75.5,-66.76 72,-56.76 68.5,-66.76 75.5,-66.76\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6291002a30>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# And graph the corresponding IRCFG\n",
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    MOV EAX, EBX\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lets analyze this graph:\n",
    "- the first ir basic block has the name set to `main`\n",
    "- it is composed of 2 `AssignBlock`s\n",
    "- the first `AssignBlock` contains only one assignment, `EAX = EBX`\n",
    "- the second one is `IRDst = loc_key_1`\n",
    "\n",
    "The `IRDst` is a special register which represent a kind of *program counter* in intermediate representation. Each `IRBlock` has one and only one assignment to `IRDst`. The position of the `IRDst` assignment is not always in the last `AssignBlock` of the `IRBlock`. In our case, the shellcode stops after the `MOV EAX, EBX`, so the next location to execution is unknown: `end`. This label has been artificially added by the script.\n",
    "\n",
    "\n",
    "Let's take another instruction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"342pt\" height=\"335pt\"\n",
       " viewBox=\"0.00 0.00 342.00 335.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 331)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-331 338,-331 338,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 322,-93.5 322,-93.5 328,-93.5 334,-99.5 334,-105.5 334,-105.5 334,-314.5 334,-314.5 334,-320.5 328,-326.5 322,-326.5 322,-326.5 12,-326.5 12,-326.5 6,-326.5 0,-320.5 0,-314.5 0,-314.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10,-299 10,-320 324,-320 324,-299 10,-299\"/>\n",
       "<text text-anchor=\"start\" x=\"150\" y=\"-305.8\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-282.8\" font-family=\"Courier New\" font-size=\"14.00\">zf = FLAG_EQ_CMP(EAX, &#45;0x3)</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-259.8\" font-family=\"Courier New\" font-size=\"14.00\">nf = FLAG_SIGN_SUB(EAX, &#45;0x3)</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-236.8\" font-family=\"Courier New\" font-size=\"14.00\">pf = parity((EAX + 0x3) &amp; 0xFF)</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-213.8\" font-family=\"Courier New\" font-size=\"14.00\">cf = FLAG_ADD_CF(EAX, 0x3)</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-190.8\" font-family=\"Courier New\" font-size=\"14.00\">of = FLAG_ADD_OF(EAX, 0x3)</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-167.8\" font-family=\"Courier New\" font-size=\"14.00\">af = ((EAX ^ 0x3) ^ (EAX + 0x3))[4:5]</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-144.8\" font-family=\"Courier New\" font-size=\"14.00\">EAX = EAX + 0x3</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-113.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M119.5,-0.5C119.5,-0.5 214.5,-0.5 214.5,-0.5 220.5,-0.5 226.5,-6.5 226.5,-12.5 226.5,-12.5 226.5,-44.5 226.5,-44.5 226.5,-50.5 220.5,-56.5 214.5,-56.5 214.5,-56.5 119.5,-56.5 119.5,-56.5 113.5,-56.5 107.5,-50.5 107.5,-44.5 107.5,-44.5 107.5,-12.5 107.5,-12.5 107.5,-6.5 113.5,-0.5 119.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"118,-29.5 118,-50.5 217,-50.5 217,-29.5 118,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"155\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"118,-6.5 118,-27.5 215,-27.5 215,-6.5 118,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"121\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M167,-93.29C167,-83.86 167,-74.84 167,-66.71\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"170.5,-66.58 167,-56.58 163.5,-66.58 170.5,-66.58\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f62a0172970>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    ADD EAX, 3\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this graph, we can note that each instruction side effect is represented.\n",
    "Note that in the equation:\n",
    "```\n",
    "zf = FLAG_EQ_CMP(EAX, -0x3)\n",
    "```\n",
    "The detailed version of the expression:\n",
    "```\n",
    "ExprId('zf', 1) = ExprOp('FLAG_EQ_CMP', ExprId('EAX', 32), ExprInt(-0x3, 32))\n",
    "```\n",
    "The operator `FLAG_EQ_CMP` is a kind of *high level* representation. But you can customize the lifter in order to get the real equation of the `zf`. This will be presented in a documentation dedicated to modification of the intermediate representation control flow graph.\n",
    "```\n",
    "ExprId('zf', 1) = ExprCond(ExprId('EAX', 32) - ExprInt(-0x3, 32), ExprInt(0, 1), ExprInt(1, 1))\n",
    "```\n",
    "which is, in a simplified form:\n",
    "```\n",
    "zf = (EAX - 3) ? (0, 1)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"152pt\" height=\"220pt\"\n",
       " viewBox=\"0.00 0.00 152.00 220.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 216)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-216 148,-216 148,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 132,-93.5 132,-93.5 138,-93.5 144,-99.5 144,-105.5 144,-105.5 144,-199.5 144,-199.5 144,-205.5 138,-211.5 132,-211.5 132,-211.5 12,-211.5 12,-211.5 6,-211.5 0,-205.5 0,-199.5 0,-199.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10,-184.5 10,-205.5 134,-205.5 134,-184.5 10,-184.5\"/>\n",
       "<text text-anchor=\"start\" x=\"55\" y=\"-191.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-168.3\" font-family=\"Courier New\" font-size=\"14.00\">EAX = EBX</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-145.3\" font-family=\"Courier New\" font-size=\"14.00\">EBX = EAX</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-114.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M24.5,-0.5C24.5,-0.5 119.5,-0.5 119.5,-0.5 125.5,-0.5 131.5,-6.5 131.5,-12.5 131.5,-12.5 131.5,-44.5 131.5,-44.5 131.5,-50.5 125.5,-56.5 119.5,-56.5 119.5,-56.5 24.5,-56.5 24.5,-56.5 18.5,-56.5 12.5,-50.5 12.5,-44.5 12.5,-44.5 12.5,-12.5 12.5,-12.5 12.5,-6.5 18.5,-0.5 24.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"23,-29.5 23,-50.5 122,-50.5 122,-29.5 23,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"60\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"23,-6.5 23,-27.5 120,-27.5 120,-6.5 23,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"26\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M72,-93.36C72,-84.38 72,-75.32 72,-66.96\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"75.5,-66.8 72,-56.8 68.5,-66.8 75.5,-66.8\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6290fc1910>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    XCHG EAX, EBX\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This one is interesting, as it demonstrate perfectly the parallel execution of multiple assignments. In you are puzzled by this notation, imagine this describes equations, which expresses destination variables of an output state depending on an input state. The equations can be rewritten:\n",
    "```\n",
    "EAX_out = EBX_in\n",
    "EBX_out = EAX_in\n",
    "```\n",
    "\n",
    "And this matches the `xchg` semantic. After the execution, those variables are committed, which means that `EAX` takes the value of `EAX_out`, and `EBX` takes the value of `EBX_out`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Some arbitrary choices have been done in order to try to match as best as possible. For example lets take the instruction:\n",
    "```\n",
    "CMOVZ EAX, EBX\n",
    "```\n",
    "This conditional move is done if the zero flag is activated. So we may want to translate it as:\n",
    "```\n",
    "EAX = zf ? EBX : EAX\n",
    "```\n",
    "Which can be read: if `zf` is 1, `EAX` is set to `EBX` else `EAX` is set to `EAX`, which is equivalent to no modifications.\n",
    "\n",
    "This representation seems good at first, as the semantic of the conditional move seems ok. But let's question the system on the equation `EAX = zf ? EBX, EAX`:\n",
    "- which register is written ? `EAX` is *always* written\n",
    "- which register is read ? `zf`, `EBX`, `EAX` are read\n",
    "\n",
    "IF we ask the same question on the instruction `CMOVZ EAX, EBX`, the answers are a bit different:\n",
    "- which register is written ? `EAX` is written only if the `zf` is 1\n",
    "- which register is read ? `zf` is *always* read, `EBX` may be read is `zf` is 1\n",
    "\n",
    "The conclusion is the representation we gave doesn't represent properly the instruction. Here is what Miasm will gave as intermediate representation for it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"210pt\" height=\"220pt\"\n",
       " viewBox=\"0.00 0.00 210.00 220.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 216)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-216 206,-216 206,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 190,-93.5 190,-93.5 196,-93.5 202,-99.5 202,-105.5 202,-105.5 202,-199.5 202,-199.5 202,-205.5 196,-211.5 190,-211.5 190,-211.5 12,-211.5 12,-211.5 6,-211.5 0,-205.5 0,-199.5 0,-199.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10,-184.5 10,-205.5 192,-205.5 192,-184.5 10,-184.5\"/>\n",
       "<text text-anchor=\"start\" x=\"84\" y=\"-191.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-168.3\" font-family=\"Courier New\" font-size=\"14.00\">ESP = ESP + &#45;0x4</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-145.3\" font-family=\"Courier New\" font-size=\"14.00\">@32[ESP + &#45;0x4] = EAX</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-114.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M53.5,-0.5C53.5,-0.5 148.5,-0.5 148.5,-0.5 154.5,-0.5 160.5,-6.5 160.5,-12.5 160.5,-12.5 160.5,-44.5 160.5,-44.5 160.5,-50.5 154.5,-56.5 148.5,-56.5 148.5,-56.5 53.5,-56.5 53.5,-56.5 47.5,-56.5 41.5,-50.5 41.5,-44.5 41.5,-44.5 41.5,-12.5 41.5,-12.5 41.5,-6.5 47.5,-0.5 53.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"52,-29.5 52,-50.5 151,-50.5 151,-29.5 52,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"89\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"52,-6.5 52,-27.5 149,-27.5 149,-6.5 52,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"55\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M101,-93.36C101,-84.38 101,-75.32 101,-66.96\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"104.5,-66.8 101,-56.8 97.5,-66.8 104.5,-66.8\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6290fc16d0>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Here is a push\n",
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    PUSH EAX\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"334pt\" height=\"290pt\"\n",
       " viewBox=\"0.00 0.00 334.00 290.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 286)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-286 330,-286 330,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-217.5C12,-217.5 314,-217.5 314,-217.5 320,-217.5 326,-223.5 326,-229.5 326,-229.5 326,-269.5 326,-269.5 326,-275.5 320,-281.5 314,-281.5 314,-281.5 12,-281.5 12,-281.5 6,-281.5 0,-275.5 0,-269.5 0,-269.5 0,-229.5 0,-229.5 0,-223.5 6,-217.5 12,-217.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10,-254.5 10,-275.5 316,-275.5 316,-254.5 10,-254.5\"/>\n",
       "<text text-anchor=\"start\" x=\"146\" y=\"-261.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-238.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = CC_EQ(zf)?(loc_key_2,b&#39;end&#39;)</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M115.5,-0.5C115.5,-0.5 210.5,-0.5 210.5,-0.5 216.5,-0.5 222.5,-6.5 222.5,-12.5 222.5,-12.5 222.5,-44.5 222.5,-44.5 222.5,-50.5 216.5,-56.5 210.5,-56.5 210.5,-56.5 115.5,-56.5 115.5,-56.5 109.5,-56.5 103.5,-50.5 103.5,-44.5 103.5,-44.5 103.5,-12.5 103.5,-12.5 103.5,-6.5 109.5,-0.5 115.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"114,-29.5 114,-50.5 213,-50.5 213,-29.5 114,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"151\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"114,-6.5 114,-27.5 211,-27.5 211,-6.5 114,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"117\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M145.24,-217.21C139.88,-206.13 134.7,-193.35 132,-181 123.65,-142.79 123.19,-131.11 132,-93 134.13,-83.78 137.79,-74.36 141.86,-65.69\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"145.06,-67.13 146.39,-56.62 138.79,-64 145.06,-67.13\"/>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M153,-93.5C153,-93.5 273,-93.5 273,-93.5 279,-93.5 285,-99.5 285,-105.5 285,-105.5 285,-168.5 285,-168.5 285,-174.5 279,-180.5 273,-180.5 273,-180.5 153,-180.5 153,-180.5 147,-180.5 141,-174.5 141,-168.5 141,-168.5 141,-105.5 141,-105.5 141,-99.5 147,-93.5 153,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"151,-153 151,-174 275,-174 275,-153 151,-153\"/>\n",
       "<text text-anchor=\"start\" x=\"175.5\" y=\"-159.8\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_2</text>\n",
       "<text text-anchor=\"start\" x=\"154\" y=\"-136.8\" font-family=\"Courier New\" font-size=\"14.00\">EAX = EBX</text>\n",
       "<text text-anchor=\"start\" x=\"154\" y=\"-113.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"limegreen\" d=\"M177.06,-217.43C180.92,-208.9 185.21,-199.43 189.44,-190.07\"/>\n",
       "<polygon fill=\"limegreen\" stroke=\"limegreen\" points=\"192.7,-191.35 193.64,-180.8 186.32,-188.46 192.7,-191.35\"/>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>2&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M192.95,-93.3C188.68,-84.2 184.21,-74.68 180.07,-65.85\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"183.14,-64.16 175.72,-56.59 176.8,-67.13 183.14,-64.16\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f629102b250>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    CMOVZ EAX, EBX\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here are some remarks we can do on this version:\n",
    "- *one* x86 instruction has generated multiple `IRBlocks`\n",
    "- the first `IRBlock` only reads the `zf` (we don't take the locations into account here)\n",
    "- `EAX` is assigned only in the case of `zf` equals to 1\n",
    "- `EBX` is read only in the case of `zf` equals to 1\n",
    "\n",
    "We can dispute on the fact that in this form, it's harder to get what is read and what is written. But one argument is: If `cmovz` doesn't exist (for example in older cpus) what may be the code to do this ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"301pt\" height=\"321pt\"\n",
       " viewBox=\"0.00 0.00 301.00 321.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 317)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-317 297,-317 297,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-225.5C12,-225.5 281,-225.5 281,-225.5 287,-225.5 293,-231.5 293,-237.5 293,-237.5 293,-300.5 293,-300.5 293,-306.5 287,-312.5 281,-312.5 281,-312.5 12,-312.5 12,-312.5 6,-312.5 0,-306.5 0,-300.5 0,-300.5 0,-237.5 0,-237.5 0,-231.5 6,-225.5 12,-225.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10.5,-285 10.5,-306 283.5,-306 283.5,-285 10.5,-285\"/>\n",
       "<text text-anchor=\"start\" x=\"130\" y=\"-291.8\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-268.8\" font-family=\"Courier New\" font-size=\"14.00\">EIP = CC_EQ(zf)?(b&#39;end&#39;,loc_2)</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-245.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = CC_EQ(zf)?(b&#39;end&#39;,loc_2)</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M99,-0.5C99,-0.5 194,-0.5 194,-0.5 200,-0.5 206,-6.5 206,-12.5 206,-12.5 206,-44.5 206,-44.5 206,-50.5 200,-56.5 194,-56.5 194,-56.5 99,-56.5 99,-56.5 93,-56.5 87,-50.5 87,-44.5 87,-44.5 87,-12.5 87,-12.5 87,-6.5 93,-0.5 99,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"97.5,-29.5 97.5,-50.5 196.5,-50.5 196.5,-29.5 97.5,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"134.5\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"97.5,-6.5 97.5,-27.5 194.5,-27.5 194.5,-6.5 97.5,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"100.5\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M126.44,-225.4C121.93,-213.85 117.8,-201.16 115.5,-189 107.57,-147.08 105.89,-134.57 115.5,-93 117.63,-83.78 121.29,-74.36 125.36,-65.69\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"128.56,-67.13 129.89,-56.62 122.29,-64 128.56,-67.13\"/>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M136.5,-93.5C136.5,-93.5 256.5,-93.5 256.5,-93.5 262.5,-93.5 268.5,-99.5 268.5,-105.5 268.5,-105.5 268.5,-176.5 268.5,-176.5 268.5,-182.5 262.5,-188.5 256.5,-188.5 256.5,-188.5 136.5,-188.5 136.5,-188.5 130.5,-188.5 124.5,-182.5 124.5,-176.5 124.5,-176.5 124.5,-105.5 124.5,-105.5 124.5,-99.5 130.5,-93.5 136.5,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"134.5,-161 134.5,-182 258.5,-182 258.5,-161 134.5,-161\"/>\n",
       "<text text-anchor=\"start\" x=\"175.5\" y=\"-167.8\" font-family=\"Courier New\" font-size=\"14.00\">loc_2</text>\n",
       "<text text-anchor=\"start\" x=\"137.5\" y=\"-144.8\" font-family=\"Courier New\" font-size=\"14.00\">EAX = EBX</text>\n",
       "<text text-anchor=\"start\" x=\"137.5\" y=\"-113.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"red\" d=\"M163.43,-225.34C166.92,-216.55 170.64,-207.16 174.29,-197.97\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" points=\"177.61,-199.09 178.05,-188.5 171.1,-196.51 177.61,-199.09\"/>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;1 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>2&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M175.44,-93.46C171.29,-84.28 166.98,-74.76 163,-65.97\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"166.15,-64.43 158.84,-56.76 159.77,-67.32 166.15,-64.43\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6290fd6100>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    JZ    end\n",
    "    MOV   EAX, EBX\n",
    "end:\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The conclusion is that in intermediate representation, the `cmovz` is exactly as difficult as analyzing the code using `jz/mov`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "So an important point is that in intermediate representation, one instruction can generate *multiple* `IRBlock`s. Here are some interesting examples:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"438pt\" height=\"336pt\"\n",
       " viewBox=\"0.00 0.00 438.00 336.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 332)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-332 434,-332 434,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M78.5,-240.5C78.5,-240.5 347.5,-240.5 347.5,-240.5 353.5,-240.5 359.5,-246.5 359.5,-252.5 359.5,-252.5 359.5,-315.5 359.5,-315.5 359.5,-321.5 353.5,-327.5 347.5,-327.5 347.5,-327.5 78.5,-327.5 78.5,-327.5 72.5,-327.5 66.5,-321.5 66.5,-315.5 66.5,-315.5 66.5,-252.5 66.5,-252.5 66.5,-246.5 72.5,-240.5 78.5,-240.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"77,-300 77,-321 350,-321 350,-300 77,-300\"/>\n",
       "<text text-anchor=\"start\" x=\"196.5\" y=\"-306.8\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"80\" y=\"-283.8\" font-family=\"Courier New\" font-size=\"14.00\">@8[EDI[0:32]] = @8[ESI[0:32]]</text>\n",
       "<text text-anchor=\"start\" x=\"80\" y=\"-260.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = df?(loc_key_3,loc_key_2)</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 190,-93.5 190,-93.5 196,-93.5 202,-99.5 202,-105.5 202,-105.5 202,-191.5 202,-191.5 202,-197.5 196,-203.5 190,-203.5 190,-203.5 12,-203.5 12,-203.5 6,-203.5 0,-197.5 0,-191.5 0,-191.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10,-176.5 10,-197.5 192,-197.5 192,-176.5 10,-176.5\"/>\n",
       "<text text-anchor=\"start\" x=\"63.5\" y=\"-183.3\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_2</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-160.3\" font-family=\"Courier New\" font-size=\"14.00\">ESI = ESI[0:32] + 0x1</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-137.3\" font-family=\"Courier New\" font-size=\"14.00\">EDI = EDI[0:32] + 0x1</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-114.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"red\" d=\"M177.25,-240.39C169.58,-231.24 161.31,-221.39 153.15,-211.67\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" points=\"155.76,-209.33 146.65,-203.91 150.4,-213.82 155.76,-209.33\"/>\n",
       "</g>\n",
       "<!-- 3 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>3</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M232,-93.5C232,-93.5 418,-93.5 418,-93.5 424,-93.5 430,-99.5 430,-105.5 430,-105.5 430,-191.5 430,-191.5 430,-197.5 424,-203.5 418,-203.5 418,-203.5 232,-203.5 232,-203.5 226,-203.5 220,-197.5 220,-191.5 220,-191.5 220,-105.5 220,-105.5 220,-99.5 226,-93.5 232,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"230,-176.5 230,-197.5 420,-197.5 420,-176.5 230,-176.5\"/>\n",
       "<text text-anchor=\"start\" x=\"287.5\" y=\"-183.3\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_3</text>\n",
       "<text text-anchor=\"start\" x=\"233\" y=\"-160.3\" font-family=\"Courier New\" font-size=\"14.00\">ESI = ESI[0:32] + &#45;0x1</text>\n",
       "<text text-anchor=\"start\" x=\"233\" y=\"-137.3\" font-family=\"Courier New\" font-size=\"14.00\">EDI = EDI[0:32] + &#45;0x1</text>\n",
       "<text text-anchor=\"start\" x=\"233\" y=\"-114.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;3 -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>0&#45;&gt;3</title>\n",
       "<path fill=\"none\" stroke=\"limegreen\" d=\"M248.75,-240.39C256.42,-231.24 264.69,-221.39 272.85,-211.67\"/>\n",
       "<polygon fill=\"limegreen\" stroke=\"limegreen\" points=\"275.6,-213.82 279.35,-203.91 270.24,-209.33 275.6,-213.82\"/>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M165.5,-0.5C165.5,-0.5 260.5,-0.5 260.5,-0.5 266.5,-0.5 272.5,-6.5 272.5,-12.5 272.5,-12.5 272.5,-44.5 272.5,-44.5 272.5,-50.5 266.5,-56.5 260.5,-56.5 260.5,-56.5 165.5,-56.5 165.5,-56.5 159.5,-56.5 153.5,-50.5 153.5,-44.5 153.5,-44.5 153.5,-12.5 153.5,-12.5 153.5,-6.5 159.5,-0.5 165.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"164,-29.5 164,-50.5 263,-50.5 263,-29.5 164,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"201\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"164,-6.5 164,-27.5 261,-27.5 261,-6.5 164,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"167\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>2&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M152.41,-93.34C161.85,-83.4 171.45,-73.27 180.16,-64.1\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"182.89,-66.31 187.23,-56.65 177.81,-61.49 182.89,-66.31\"/>\n",
       "</g>\n",
       "<!-- 3&#45;&gt;1 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>3&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M273.59,-93.34C264.15,-83.4 254.55,-73.27 245.84,-64.1\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"248.19,-61.49 238.77,-56.65 243.11,-66.31 248.19,-61.49\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f629103a1f0>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    MOVSB\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And now, the version using a repeat prefix:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"649pt\" height=\"561pt\"\n",
       " viewBox=\"0.00 0.00 648.50 561.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 557)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-557 644.5,-557 644.5,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-488.5C12,-488.5 314,-488.5 314,-488.5 320,-488.5 326,-494.5 326,-500.5 326,-500.5 326,-540.5 326,-540.5 326,-546.5 320,-552.5 314,-552.5 314,-552.5 12,-552.5 12,-552.5 6,-552.5 0,-546.5 0,-540.5 0,-540.5 0,-500.5 0,-500.5 0,-494.5 6,-488.5 12,-488.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10,-525.5 10,-546.5 316,-546.5 316,-525.5 10,-525.5\"/>\n",
       "<text text-anchor=\"start\" x=\"146\" y=\"-532.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-509.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = ECX[0:32]?(loc_key_4,b&#39;end&#39;)</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M167.5,-0.5C167.5,-0.5 262.5,-0.5 262.5,-0.5 268.5,-0.5 274.5,-6.5 274.5,-12.5 274.5,-12.5 274.5,-44.5 274.5,-44.5 274.5,-50.5 268.5,-56.5 262.5,-56.5 262.5,-56.5 167.5,-56.5 167.5,-56.5 161.5,-56.5 155.5,-50.5 155.5,-44.5 155.5,-44.5 155.5,-12.5 155.5,-12.5 155.5,-6.5 161.5,-0.5 167.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"166,-29.5 166,-50.5 265,-50.5 265,-29.5 166,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"203\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"166,-6.5 166,-27.5 263,-27.5 263,-6.5 166,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"169\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge7\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M148.14,-488.21C131.36,-451.01 105.09,-386.58 95,-328 86.62,-279.38 87.87,-265.82 95,-217 103.31,-160.09 99.34,-140.34 132,-93 139.72,-81.81 150.02,-71.74 160.74,-63.08\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"163.19,-65.61 168.99,-56.74 158.93,-60.06 163.19,-65.61\"/>\n",
       "</g>\n",
       "<!-- 4 -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>4</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M205.5,-364.5C205.5,-364.5 474.5,-364.5 474.5,-364.5 480.5,-364.5 486.5,-370.5 486.5,-376.5 486.5,-376.5 486.5,-439.5 486.5,-439.5 486.5,-445.5 480.5,-451.5 474.5,-451.5 474.5,-451.5 205.5,-451.5 205.5,-451.5 199.5,-451.5 193.5,-445.5 193.5,-439.5 193.5,-439.5 193.5,-376.5 193.5,-376.5 193.5,-370.5 199.5,-364.5 205.5,-364.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"204,-424 204,-445 477,-445 477,-424 204,-424\"/>\n",
       "<text text-anchor=\"start\" x=\"303\" y=\"-430.8\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_4</text>\n",
       "<text text-anchor=\"start\" x=\"207\" y=\"-407.8\" font-family=\"Courier New\" font-size=\"14.00\">@8[EDI[0:32]] = @8[ESI[0:32]]</text>\n",
       "<text text-anchor=\"start\" x=\"207\" y=\"-384.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = df?(loc_key_3,loc_key_2)</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;4 -->\n",
       "<g id=\"edge8\" class=\"edge\">\n",
       "<title>0&#45;&gt;4</title>\n",
       "<path fill=\"none\" stroke=\"limegreen\" d=\"M212.78,-488.43C228.36,-478.7 245.94,-467.72 262.95,-457.1\"/>\n",
       "<polygon fill=\"limegreen\" stroke=\"limegreen\" points=\"265.15,-459.85 271.78,-451.59 261.44,-453.92 265.15,-459.85\"/>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M116,-217.5C116,-217.5 294,-217.5 294,-217.5 300,-217.5 306,-223.5 306,-229.5 306,-229.5 306,-315.5 306,-315.5 306,-321.5 300,-327.5 294,-327.5 294,-327.5 116,-327.5 116,-327.5 110,-327.5 104,-321.5 104,-315.5 104,-315.5 104,-229.5 104,-229.5 104,-223.5 110,-217.5 116,-217.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"114,-300.5 114,-321.5 296,-321.5 296,-300.5 114,-300.5\"/>\n",
       "<text text-anchor=\"start\" x=\"167.5\" y=\"-307.3\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_2</text>\n",
       "<text text-anchor=\"start\" x=\"117\" y=\"-284.3\" font-family=\"Courier New\" font-size=\"14.00\">ESI = ESI[0:32] + 0x1</text>\n",
       "<text text-anchor=\"start\" x=\"117\" y=\"-261.3\" font-family=\"Courier New\" font-size=\"14.00\">EDI = EDI[0:32] + 0x1</text>\n",
       "<text text-anchor=\"start\" x=\"117\" y=\"-238.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = loc_key_5</text>\n",
       "</g>\n",
       "<!-- 5 -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>5</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M153.5,-93.5C153.5,-93.5 628.5,-93.5 628.5,-93.5 634.5,-93.5 640.5,-99.5 640.5,-105.5 640.5,-105.5 640.5,-168.5 640.5,-168.5 640.5,-174.5 634.5,-180.5 628.5,-180.5 628.5,-180.5 153.5,-180.5 153.5,-180.5 147.5,-180.5 141.5,-174.5 141.5,-168.5 141.5,-168.5 141.5,-105.5 141.5,-105.5 141.5,-99.5 147.5,-93.5 153.5,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"152,-153 152,-174 631,-174 631,-153 152,-153\"/>\n",
       "<text text-anchor=\"start\" x=\"354\" y=\"-159.8\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_5</text>\n",
       "<text text-anchor=\"start\" x=\"155\" y=\"-136.8\" font-family=\"Courier New\" font-size=\"14.00\">ECX = ECX[0:32] + &#45;0x1</text>\n",
       "<text text-anchor=\"start\" x=\"155\" y=\"-113.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = ((ECX[0:32] + &#45;0x1)?(0x0,0x1))?(b&#39;end&#39;,loc_key_4)</text>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;5 -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>2&#45;&gt;5</title>\n",
       "<path fill=\"none\" stroke=\"blue\" d=\"M280.39,-217.39C294.7,-207.12 309.58,-196.44 323.63,-186.36\"/>\n",
       "<polygon fill=\"blue\" stroke=\"blue\" points=\"325.7,-189.17 331.79,-180.5 321.62,-183.49 325.7,-189.17\"/>\n",
       "</g>\n",
       "<!-- 3 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>3</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M336,-217.5C336,-217.5 522,-217.5 522,-217.5 528,-217.5 534,-223.5 534,-229.5 534,-229.5 534,-315.5 534,-315.5 534,-321.5 528,-327.5 522,-327.5 522,-327.5 336,-327.5 336,-327.5 330,-327.5 324,-321.5 324,-315.5 324,-315.5 324,-229.5 324,-229.5 324,-223.5 330,-217.5 336,-217.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"334,-300.5 334,-321.5 524,-321.5 524,-300.5 334,-300.5\"/>\n",
       "<text text-anchor=\"start\" x=\"391.5\" y=\"-307.3\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_3</text>\n",
       "<text text-anchor=\"start\" x=\"337\" y=\"-284.3\" font-family=\"Courier New\" font-size=\"14.00\">ESI = ESI[0:32] + &#45;0x1</text>\n",
       "<text text-anchor=\"start\" x=\"337\" y=\"-261.3\" font-family=\"Courier New\" font-size=\"14.00\">EDI = EDI[0:32] + &#45;0x1</text>\n",
       "<text text-anchor=\"start\" x=\"337\" y=\"-238.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = loc_key_5</text>\n",
       "</g>\n",
       "<!-- 3&#45;&gt;5 -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>3&#45;&gt;5</title>\n",
       "<path fill=\"none\" stroke=\"blue\" d=\"M413.54,-217.2C411.04,-208.39 408.44,-199.28 405.95,-190.51\"/>\n",
       "<polygon fill=\"blue\" stroke=\"blue\" points=\"409.28,-189.45 403.18,-180.79 402.55,-191.37 409.28,-189.45\"/>\n",
       "</g>\n",
       "<!-- 4&#45;&gt;2 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>4&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"red\" d=\"M296.91,-364.39C287.48,-355.06 277.3,-345 267.28,-335.09\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" points=\"269.6,-332.46 260.03,-327.91 264.67,-337.43 269.6,-332.46\"/>\n",
       "</g>\n",
       "<!-- 4&#45;&gt;3 -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>4&#45;&gt;3</title>\n",
       "<path fill=\"none\" stroke=\"limegreen\" d=\"M368.4,-364.39C374.39,-355.42 380.81,-345.78 387.17,-336.24\"/>\n",
       "<polygon fill=\"limegreen\" stroke=\"limegreen\" points=\"390.09,-338.18 392.72,-327.91 384.26,-334.29 390.09,-338.18\"/>\n",
       "</g>\n",
       "<!-- 5&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>5&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M320.68,-93.45C303.31,-82.94 284.98,-71.85 268.56,-61.91\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"270.01,-58.7 259.65,-56.52 266.39,-64.69 270.01,-58.7\"/>\n",
       "</g>\n",
       "<!-- 5&#45;&gt;4 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>5&#45;&gt;4</title>\n",
       "<path fill=\"none\" stroke=\"red\" d=\"M507.8,-180.73C521.78,-190.56 534.2,-202.51 543,-217 568.61,-259.17 570.85,-287.28 543,-328 530.93,-345.65 514.29,-359.36 495.68,-370\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" points=\"493.85,-367.01 486.7,-374.83 497.17,-373.18 493.85,-367.01\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6290fe18b0>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    REP MOVSB\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the very same way as `cmovz`, if the `rep movsb` instruction didn't exist, we would use a more complex code."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The translation of some instructions are tricky:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"325pt\" height=\"312pt\"\n",
       " viewBox=\"0.00 0.00 325.00 312.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 308)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-308 321,-308 321,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 305,-93.5 305,-93.5 311,-93.5 317,-99.5 317,-105.5 317,-105.5 317,-291.5 317,-291.5 317,-297.5 311,-303.5 305,-303.5 305,-303.5 12,-303.5 12,-303.5 6,-303.5 0,-297.5 0,-291.5 0,-291.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10.5,-276.5 10.5,-297.5 307.5,-297.5 307.5,-276.5 10.5,-276.5\"/>\n",
       "<text text-anchor=\"start\" x=\"142\" y=\"-283.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-260.3\" font-family=\"Courier New\" font-size=\"14.00\">cf = (EAX &gt;&gt; (0x1 + &#45;0x1))[0:1]</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-237.3\" font-family=\"Courier New\" font-size=\"14.00\">of = (0x1 + &#45;0x1)?(0x0,EAX[31:32])</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-214.3\" font-family=\"Courier New\" font-size=\"14.00\">EAX = EAX &gt;&gt; 0x1</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-191.3\" font-family=\"Courier New\" font-size=\"14.00\">zf = (EAX &gt;&gt; 0x1)?(0x0,0x1)</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-168.3\" font-family=\"Courier New\" font-size=\"14.00\">nf = FLAG_SIGN_SUB(EAX &gt;&gt; 0x1, 0x0)</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-145.3\" font-family=\"Courier New\" font-size=\"14.00\">pf = parity((EAX &gt;&gt; 0x1) &amp; 0xFF)</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-114.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M111,-0.5C111,-0.5 206,-0.5 206,-0.5 212,-0.5 218,-6.5 218,-12.5 218,-12.5 218,-44.5 218,-44.5 218,-50.5 212,-56.5 206,-56.5 206,-56.5 111,-56.5 111,-56.5 105,-56.5 99,-50.5 99,-44.5 99,-44.5 99,-12.5 99,-12.5 99,-6.5 105,-0.5 111,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"109.5,-29.5 109.5,-50.5 208.5,-50.5 208.5,-29.5 109.5,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"146.5\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"109.5,-6.5 109.5,-27.5 206.5,-27.5 206.5,-6.5 109.5,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"112.5\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M158.5,-93.49C158.5,-84.06 158.5,-74.99 158.5,-66.79\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"162,-66.56 158.5,-56.56 155,-66.56 162,-66.56\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6290fd6df0>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    SHR EAX, 1\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For the moment, nothing special. `EAX` is updated correctly, and the flags are updated according to the result (note those side effects are in parallel here). But look at the next one:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"667pt\" height=\"405pt\"\n",
       " viewBox=\"0.00 0.00 666.50 405.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 401)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-401 662.5,-401 662.5,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-332.5C12,-332.5 479,-332.5 479,-332.5 485,-332.5 491,-338.5 491,-344.5 491,-344.5 491,-384.5 491,-384.5 491,-390.5 485,-396.5 479,-396.5 479,-396.5 12,-396.5 12,-396.5 6,-396.5 0,-390.5 0,-384.5 0,-384.5 0,-344.5 0,-344.5 0,-338.5 6,-332.5 12,-332.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10.5,-369.5 10.5,-390.5 481.5,-390.5 481.5,-369.5 10.5,-369.5\"/>\n",
       "<text text-anchor=\"start\" x=\"229\" y=\"-376.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-353.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = (zeroExt_32(ECX[0:8]) &amp; 0x1F)?(loc_key_2,b&#39;end&#39;)</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M198,-0.5C198,-0.5 293,-0.5 293,-0.5 299,-0.5 305,-6.5 305,-12.5 305,-12.5 305,-44.5 305,-44.5 305,-50.5 299,-56.5 293,-56.5 293,-56.5 198,-56.5 198,-56.5 192,-56.5 186,-50.5 186,-44.5 186,-44.5 186,-12.5 186,-12.5 186,-6.5 192,-0.5 198,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"196.5,-29.5 196.5,-50.5 295.5,-50.5 295.5,-29.5 196.5,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"233.5\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"196.5,-6.5 196.5,-27.5 293.5,-27.5 293.5,-6.5 196.5,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"199.5\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M155.69,-332.43C140.46,-323.1 126.65,-311.17 117.5,-296 70.9,-218.74 69.95,-169.67 117.5,-93 130.77,-71.6 153.65,-57.19 176.42,-47.58\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"177.78,-50.81 185.8,-43.88 175.21,-44.3 177.78,-50.81\"/>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M138.5,-93.5C138.5,-93.5 646.5,-93.5 646.5,-93.5 652.5,-93.5 658.5,-99.5 658.5,-105.5 658.5,-105.5 658.5,-283.5 658.5,-283.5 658.5,-289.5 652.5,-295.5 646.5,-295.5 646.5,-295.5 138.5,-295.5 138.5,-295.5 132.5,-295.5 126.5,-289.5 126.5,-283.5 126.5,-283.5 126.5,-105.5 126.5,-105.5 126.5,-99.5 132.5,-93.5 138.5,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"136.5,-268.5 136.5,-289.5 648.5,-289.5 648.5,-268.5 136.5,-268.5\"/>\n",
       "<text text-anchor=\"start\" x=\"355\" y=\"-275.3\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_2</text>\n",
       "<text text-anchor=\"start\" x=\"139.5\" y=\"-252.3\" font-family=\"Courier New\" font-size=\"14.00\">cf = (EAX &gt;&gt; ((zeroExt_32(ECX[0:8]) &amp; 0x1F) + &#45;0x1))[0:1]</text>\n",
       "<text text-anchor=\"start\" x=\"139.5\" y=\"-229.3\" font-family=\"Courier New\" font-size=\"14.00\">of = ((zeroExt_32(ECX[0:8]) &amp; 0x1F) + &#45;0x1)?(0x0,EAX[31:32])</text>\n",
       "<text text-anchor=\"start\" x=\"139.5\" y=\"-206.3\" font-family=\"Courier New\" font-size=\"14.00\">EAX = EAX &gt;&gt; (zeroExt_32(ECX[0:8]) &amp; 0x1F)</text>\n",
       "<text text-anchor=\"start\" x=\"139.5\" y=\"-183.3\" font-family=\"Courier New\" font-size=\"14.00\">zf = (EAX &gt;&gt; (zeroExt_32(ECX[0:8]) &amp; 0x1F))?(0x0,0x1)</text>\n",
       "<text text-anchor=\"start\" x=\"139.5\" y=\"-160.3\" font-family=\"Courier New\" font-size=\"14.00\">nf = FLAG_SIGN_SUB(EAX &gt;&gt; (zeroExt_32(ECX[0:8]) &amp; 0x1F), 0x0)</text>\n",
       "<text text-anchor=\"start\" x=\"139.5\" y=\"-137.3\" font-family=\"Courier New\" font-size=\"14.00\">pf = parity((EAX &gt;&gt; (zeroExt_32(ECX[0:8]) &amp; 0x1F)) &amp; 0xFF)</text>\n",
       "<text text-anchor=\"start\" x=\"139.5\" y=\"-114.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"limegreen\" d=\"M272.81,-332.29C280.35,-323.67 289,-313.79 298.11,-303.38\"/>\n",
       "<polygon fill=\"limegreen\" stroke=\"limegreen\" points=\"300.87,-305.54 304.82,-295.71 295.6,-300.93 300.87,-305.54\"/>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>2&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M302.75,-93.38C293.42,-82.96 284.45,-72.95 276.49,-64.07\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"279.05,-61.69 269.77,-56.58 273.84,-66.36 279.05,-61.69\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f62a01729d0>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    SHR EAX, CL\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this case, if `CL` is zero, the destination is shifted by a zero amount. The instruction behaves (in 32 bit mode) as a `nop`, and the flags are not assigned. We could have done the same trick as in the `cmovz`, but this representation matches more accurately the instruction semantic."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is another one:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"768pt\" height=\"313pt\"\n",
       " viewBox=\"0.00 0.00 768.00 313.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 309)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-309 764,-309 764,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M301,-240.5C301,-240.5 578,-240.5 578,-240.5 584,-240.5 590,-246.5 590,-252.5 590,-252.5 590,-292.5 590,-292.5 590,-298.5 584,-304.5 578,-304.5 578,-304.5 301,-304.5 301,-304.5 295,-304.5 289,-298.5 289,-292.5 289,-292.5 289,-252.5 289,-252.5 289,-246.5 295,-240.5 301,-240.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"299.5,-277.5 299.5,-298.5 580.5,-298.5 580.5,-277.5 299.5,-277.5\"/>\n",
       "<text text-anchor=\"start\" x=\"423\" y=\"-284.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"302.5\" y=\"-261.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = ECX?(loc_key_2,loc_key_3)</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 479,-93.5 479,-93.5 485,-93.5 491,-99.5 491,-105.5 491,-105.5 491,-191.5 491,-191.5 491,-197.5 485,-203.5 479,-203.5 479,-203.5 12,-203.5 12,-203.5 6,-203.5 0,-197.5 0,-191.5 0,-191.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10.5,-176.5 10.5,-197.5 481.5,-197.5 481.5,-176.5 10.5,-176.5\"/>\n",
       "<text text-anchor=\"start\" x=\"208.5\" y=\"-183.3\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_2</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-160.3\" font-family=\"Courier New\" font-size=\"14.00\">EDX = umod({EAX 0 32, EDX 32 64}, zeroExt_64(ECX))[0:32]</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-137.3\" font-family=\"Courier New\" font-size=\"14.00\">EAX = udiv({EAX 0 32, EDX 32 64}, zeroExt_64(ECX))[0:32]</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-114.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"limegreen\" d=\"M390.04,-240.4C374.7,-230.75 357.26,-219.78 339.92,-208.88\"/>\n",
       "<polygon fill=\"limegreen\" stroke=\"limegreen\" points=\"341.76,-205.9 331.43,-203.54 338.03,-211.82 341.76,-205.9\"/>\n",
       "</g>\n",
       "<!-- 3 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>3</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M521,-105C521,-105 748,-105 748,-105 754,-105 760,-111 760,-117 760,-117 760,-180 760,-180 760,-186 754,-192 748,-192 748,-192 521,-192 521,-192 515,-192 509,-186 509,-180 509,-180 509,-117 509,-117 509,-111 515,-105 521,-105\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"519.5,-164.5 519.5,-185.5 750.5,-185.5 750.5,-164.5 519.5,-164.5\"/>\n",
       "<text text-anchor=\"start\" x=\"597.5\" y=\"-171.3\" font-family=\"Courier New\" font-size=\"14.00\">loc_key_3</text>\n",
       "<text text-anchor=\"start\" x=\"522.5\" y=\"-148.3\" font-family=\"Courier New\" font-size=\"14.00\">exception_flags = 0x2010000</text>\n",
       "<text text-anchor=\"start\" x=\"522.5\" y=\"-125.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;3 -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>0&#45;&gt;3</title>\n",
       "<path fill=\"none\" stroke=\"red\" d=\"M489.21,-240.4C510.02,-227.38 534.69,-211.94 557.74,-197.52\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" points=\"559.87,-200.32 566.49,-192.05 556.15,-194.39 559.87,-200.32\"/>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M392,-0.5C392,-0.5 487,-0.5 487,-0.5 493,-0.5 499,-6.5 499,-12.5 499,-12.5 499,-44.5 499,-44.5 499,-50.5 493,-56.5 487,-56.5 487,-56.5 392,-56.5 392,-56.5 386,-56.5 380,-50.5 380,-44.5 380,-44.5 380,-12.5 380,-12.5 380,-6.5 386,-0.5 392,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"390.5,-29.5 390.5,-50.5 489.5,-50.5 489.5,-29.5 390.5,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"427.5\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"390.5,-6.5 390.5,-27.5 487.5,-27.5 487.5,-6.5 390.5,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"393.5\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>2&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M334.55,-93.34C352.2,-82.6 370.2,-71.65 386.2,-61.92\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"388.14,-64.83 394.87,-56.65 384.5,-58.85 388.14,-64.83\"/>\n",
       "</g>\n",
       "<!-- 3&#45;&gt;1 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>3&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M564.1,-104.9C540.71,-90.74 515.05,-75.22 493.13,-61.95\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"494.67,-58.79 484.3,-56.61 491.04,-64.78 494.67,-58.79\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6290fc7d90>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    DIV ECX\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This instruction may generate an exception in case of the divisor is zero. The intermediate representation generates a test in which it evaluate the divisor value and assigns a special register `exception_flags` to a constant. This constant represents the division by zero.\n",
    "\n",
    "Note this is arbitrary. We could have done the choice to not explicit the possible division by zero, and keep in mind that the `umod` and `udiv` operator may generate exceptions. This may change in a future version of Miasm. Indeed, each memory access may generate a exception, and Miasm doesn't explicit them in the intermediate representation: this may be misleading and very hard to analyze in a post pass. This is why we may accept to implicitly raise exception in both those operators rather than generating such a code.\n",
    "\n",
    "The same choice has been done in other instructions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"210pt\" height=\"220pt\"\n",
       " viewBox=\"0.00 0.00 210.00 220.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 216)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-216 206,-216 206,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 190,-93.5 190,-93.5 196,-93.5 202,-99.5 202,-105.5 202,-105.5 202,-199.5 202,-199.5 202,-205.5 196,-211.5 190,-211.5 190,-211.5 12,-211.5 12,-211.5 6,-211.5 0,-205.5 0,-199.5 0,-199.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10,-184.5 10,-205.5 192,-205.5 192,-184.5 10,-184.5\"/>\n",
       "<text text-anchor=\"start\" x=\"84\" y=\"-191.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-168.3\" font-family=\"Courier New\" font-size=\"14.00\">exception_flags = 0x2</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-145.3\" font-family=\"Courier New\" font-size=\"14.00\">interrupt_num = 0x3</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-114.3\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M53.5,-0.5C53.5,-0.5 148.5,-0.5 148.5,-0.5 154.5,-0.5 160.5,-6.5 160.5,-12.5 160.5,-12.5 160.5,-44.5 160.5,-44.5 160.5,-50.5 154.5,-56.5 148.5,-56.5 148.5,-56.5 53.5,-56.5 53.5,-56.5 47.5,-56.5 41.5,-50.5 41.5,-44.5 41.5,-44.5 41.5,-12.5 41.5,-12.5 41.5,-6.5 47.5,-0.5 53.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"52,-29.5 52,-50.5 151,-50.5 151,-29.5 52,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"89\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"52,-6.5 52,-27.5 149,-27.5 149,-6.5 52,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"55\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M101,-93.36C101,-84.38 101,-75.32 101,-66.96\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"104.5,-66.8 101,-56.8 97.5,-66.8 104.5,-66.8\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f629106a640>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    INT 0x3\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Memory accesses by default explicit segmentation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"235pt\" height=\"197pt\"\n",
       " viewBox=\"0.00 0.00 235.00 197.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 193)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-193 231,-193 231,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 215,-93.5 215,-93.5 221,-93.5 227,-99.5 227,-105.5 227,-105.5 227,-176.5 227,-176.5 227,-182.5 221,-188.5 215,-188.5 215,-188.5 12,-188.5 12,-188.5 6,-188.5 0,-182.5 0,-176.5 0,-176.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10.5,-161 10.5,-182 217.5,-182 217.5,-161 10.5,-161\"/>\n",
       "<text text-anchor=\"start\" x=\"97\" y=\"-167.8\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-144.8\" font-family=\"Courier New\" font-size=\"14.00\">EAX = @32[segm(FS, EBX)]</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-113.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M66,-0.5C66,-0.5 161,-0.5 161,-0.5 167,-0.5 173,-6.5 173,-12.5 173,-12.5 173,-44.5 173,-44.5 173,-50.5 167,-56.5 161,-56.5 161,-56.5 66,-56.5 66,-56.5 60,-56.5 54,-50.5 54,-44.5 54,-44.5 54,-12.5 54,-12.5 54,-6.5 60,-0.5 66,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"64.5,-29.5 64.5,-50.5 163.5,-50.5 163.5,-29.5 64.5,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"101.5\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"64.5,-6.5 64.5,-27.5 161.5,-27.5 161.5,-6.5 64.5,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"67.5\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;1 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M113.5,-93.46C113.5,-84.57 113.5,-75.37 113.5,-66.82\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"117,-66.76 113.5,-56.76 110,-66.76 117,-66.76\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f629106ab80>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    MOV EAX, DWORD PTR FS:[EBX]\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The pointer of the memory uses the special operator `segm`, which takes two arguments:\n",
    "- the value of the segment used the memory access\n",
    "- the base address\n",
    "\n",
    "Note that if you work in a flat segmentation model, you can add a post translation pass which will *simplify* `ExprOp(\"segm\", A, B)` into `B`. This will ease code analysis.\n",
    "\n",
    "Note: If you read carefully the documentation on `expression`s, you know that the word `ExprOp` is n-ary and that all of its arguments must have the same size. The operator `segm` is one of the exceptions. The register `FS` has a size of 16 bit (as a segment selector register) and `EBX` has a size of 32. In this case, the size of `ExprOp(\"segm\", FS, EBX)` has the size of `EBX`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Intermediate representation translation\n",
    "In this part, we will explain some manipulations which can be done during the native code *lifting*. Let's take the example of a call to a subfunction:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"226pt\" height=\"251pt\"\n",
       " viewBox=\"0.00 0.00 226.00 251.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 247)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-247 222,-247 222,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-186.5C12,-186.5 206,-186.5 206,-186.5 212,-186.5 218,-192.5 218,-198.5 218,-198.5 218,-230.5 218,-230.5 218,-236.5 212,-242.5 206,-242.5 206,-242.5 12,-242.5 12,-242.5 6,-242.5 0,-236.5 0,-230.5 0,-230.5 0,-198.5 0,-198.5 0,-192.5 6,-186.5 12,-186.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10,-215.5 10,-236.5 208,-236.5 208,-215.5 10,-215.5\"/>\n",
       "<text text-anchor=\"start\" x=\"92\" y=\"-222.3\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13\" y=\"-199.3\" font-family=\"Courier New\" font-size=\"14.00\">CALL &#160;&#160;&#160;&#160;&#160;&#160;loc_11223344</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M28.5,-93.5C28.5,-93.5 189.5,-93.5 189.5,-93.5 195.5,-93.5 201.5,-99.5 201.5,-105.5 201.5,-105.5 201.5,-137.5 201.5,-137.5 201.5,-143.5 195.5,-149.5 189.5,-149.5 189.5,-149.5 28.5,-149.5 28.5,-149.5 22.5,-149.5 16.5,-143.5 16.5,-137.5 16.5,-137.5 16.5,-105.5 16.5,-105.5 16.5,-99.5 22.5,-93.5 28.5,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"27,-122.5 27,-143.5 192,-143.5 192,-122.5 27,-122.5\"/>\n",
       "<text text-anchor=\"start\" x=\"88.5\" y=\"-129.3\" font-family=\"Courier New\" font-size=\"14.00\">loc_5</text>\n",
       "<text text-anchor=\"start\" x=\"30\" y=\"-106.3\" font-family=\"Courier New\" font-size=\"14.00\">MOV &#160;&#160;&#160;&#160;&#160;&#160;&#160;EBX, EAX</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"blue\" d=\"M109,-186.2C109,-177.92 109,-168.68 109,-159.86\"/>\n",
       "<polygon fill=\"blue\" stroke=\"blue\" points=\"112.5,-159.78 109,-149.78 105.5,-159.78 112.5,-159.78\"/>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M78,-0.5C78,-0.5 140,-0.5 140,-0.5 146,-0.5 152,-6.5 152,-12.5 152,-12.5 152,-44.5 152,-44.5 152,-50.5 146,-56.5 140,-56.5 140,-56.5 78,-56.5 78,-56.5 72,-56.5 66,-50.5 66,-44.5 66,-44.5 66,-12.5 66,-12.5 66,-6.5 72,-0.5 78,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"76,-29.5 76,-50.5 142,-50.5 142,-29.5 76,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"96.5\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<text text-anchor=\"start\" x=\"79\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">IOError</text>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;1 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>2&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"blue\" d=\"M109,-93.2C109,-84.92 109,-75.68 109,-66.86\"/>\n",
       "<polygon fill=\"blue\" stroke=\"blue\" points=\"112.5,-66.78 109,-56.78 105.5,-66.78 112.5,-66.78\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6291002940>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "asmcfg = gen_x86_asmcfg(\"\"\"\n",
    "main:\n",
    "    CALL 0x11223344\n",
    "    MOV EBX, EAX\n",
    "\"\"\")\n",
    "asmcfg.graphviz()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"488pt\" height=\"235pt\"\n",
       " viewBox=\"0.00 0.00 487.50 235.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 231)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-231 483.5,-231 483.5,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-93.5C12,-93.5 305,-93.5 305,-93.5 311,-93.5 317,-99.5 317,-105.5 317,-105.5 317,-214.5 317,-214.5 317,-220.5 311,-226.5 305,-226.5 305,-226.5 12,-226.5 12,-226.5 6,-226.5 0,-220.5 0,-214.5 0,-214.5 0,-105.5 0,-105.5 0,-99.5 6,-93.5 12,-93.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10.5,-199 10.5,-220 307.5,-220 307.5,-199 10.5,-199\"/>\n",
       "<text text-anchor=\"start\" x=\"142\" y=\"-205.8\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-182.8\" font-family=\"Courier New\" font-size=\"14.00\">ESP = ESP[0:32] + 0xFFFFFFFC</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-159.8\" font-family=\"Courier New\" font-size=\"14.00\">@32[ESP[0:32] + 0xFFFFFFFC] = loc_5</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-136.8\" font-family=\"Courier New\" font-size=\"14.00\">EIP = loc_11223344</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-113.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = loc_11223344</text>\n",
       "</g>\n",
       "<!-- 3 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>3</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M106.5,-0.5C106.5,-0.5 210.5,-0.5 210.5,-0.5 216.5,-0.5 222.5,-6.5 222.5,-12.5 222.5,-12.5 222.5,-44.5 222.5,-44.5 222.5,-50.5 216.5,-56.5 210.5,-56.5 210.5,-56.5 106.5,-56.5 106.5,-56.5 100.5,-56.5 94.5,-50.5 94.5,-44.5 94.5,-44.5 94.5,-12.5 94.5,-12.5 94.5,-6.5 100.5,-0.5 106.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"104.5,-29.5 104.5,-50.5 212.5,-50.5 212.5,-29.5 104.5,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"108.5\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">loc_11223344</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"104.5,-6.5 104.5,-27.5 205.5,-27.5 205.5,-6.5 104.5,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"107.5\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;3 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;3</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M158.5,-93.49C158.5,-84.32 158.5,-75.16 158.5,-66.76\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"162,-66.59 158.5,-56.59 155,-66.59 162,-66.59\"/>\n",
       "</g>\n",
       "<!-- 1 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>1</title>\n",
       "<path fill=\"red\" stroke=\"black\" d=\"M360,-0.5C360,-0.5 455,-0.5 455,-0.5 461,-0.5 467,-6.5 467,-12.5 467,-12.5 467,-44.5 467,-44.5 467,-50.5 461,-56.5 455,-56.5 455,-56.5 360,-56.5 360,-56.5 354,-56.5 348,-50.5 348,-44.5 348,-44.5 348,-12.5 348,-12.5 348,-6.5 354,-0.5 360,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"358.5,-29.5 358.5,-50.5 457.5,-50.5 457.5,-29.5 358.5,-29.5\"/>\n",
       "<text text-anchor=\"start\" x=\"395.5\" y=\"-36.3\" font-family=\"Courier New\" font-size=\"14.00\">end</text>\n",
       "<polygon fill=\"red\" stroke=\"transparent\" points=\"358.5,-6.5 358.5,-27.5 455.5,-27.5 455.5,-6.5 358.5,-6.5\"/>\n",
       "<text text-anchor=\"start\" x=\"361.5\" y=\"-13.3\" font-family=\"Courier New\" font-size=\"14.00\">NOT PRESENT</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M347.5,-112.5C347.5,-112.5 467.5,-112.5 467.5,-112.5 473.5,-112.5 479.5,-118.5 479.5,-124.5 479.5,-124.5 479.5,-195.5 479.5,-195.5 479.5,-201.5 473.5,-207.5 467.5,-207.5 467.5,-207.5 347.5,-207.5 347.5,-207.5 341.5,-207.5 335.5,-201.5 335.5,-195.5 335.5,-195.5 335.5,-124.5 335.5,-124.5 335.5,-118.5 341.5,-112.5 347.5,-112.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"345.5,-180 345.5,-201 469.5,-201 469.5,-180 345.5,-180\"/>\n",
       "<text text-anchor=\"start\" x=\"386.5\" y=\"-186.8\" font-family=\"Courier New\" font-size=\"14.00\">loc_5</text>\n",
       "<text text-anchor=\"start\" x=\"348.5\" y=\"-163.8\" font-family=\"Courier New\" font-size=\"14.00\">EBX = EAX</text>\n",
       "<text text-anchor=\"start\" x=\"348.5\" y=\"-132.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = b&#39;end&#39;</text>\n",
       "</g>\n",
       "<!-- 2&#45;&gt;1 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>2&#45;&gt;1</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M407.5,-112.25C407.5,-97.35 407.5,-81.08 407.5,-66.93\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"411,-66.59 407.5,-56.59 404,-66.59 411,-66.59\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6290f66df0>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    CALL 0x11223344\n",
    "    MOV EBX, EAX\n",
    "\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What did happened here ?\n",
    "- the `call` instruction has 2 side effects: stacking the return address and jumping to the subfunction address\n",
    "- here, the subfunction address is 0x1122334455, and the return address is located at offset `0x5`, which is represented here by `loc_5`\n",
    "\n",
    "The question is: why are there unlinked nodes in the graph? The answer is that the graph only analyzes destinations of the `IRBlock`s, which means the value of `IRDst`. So in the `main`, Miasm knowns that the next `IRBlock` is located at `loc_11223344`. But as we didn't disassemble code at this address, we don't have its intermediate representation.\n",
    "\n",
    "But the disassembler engine knowns (this behavior can be customized) that a `call` returns back to the instruction just next to the call. So the basic block at `end` has been disassembled and translated. If we analyze `IRDst` only, there are no links between them."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This `raw` way of translating is interesting to see low level moves of stack and return address, but it makes code analysis a bit hard. What we may want is to consider subcalls like an unknown operator, with arguments and side effects. This may *model* the call to a subfunction.\n",
    "\n",
    "This is the difference in Miasm between translating using `lifter` (raw translation) and `lifter_model_call` (`ilifter` + call modelization) which models subfunction calls. By default, Miasm uses a basic model which is *wrong* in most cases. But this model can (and must ?) be replaced by the user behavior.\n",
    "\n",
    "You can observe the difference in the examples:\n",
    "```\n",
    "example/disasm/dis_binary_lift.py\n",
    "```\n",
    "and\n",
    "```\n",
    "example/disasm/dis_binary_lifter_model_call.py\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"367pt\" height=\"336pt\"\n",
       " viewBox=\"0.00 0.00 367.00 336.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 332)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-332 363,-332 363,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-178.5C12,-178.5 347,-178.5 347,-178.5 353,-178.5 359,-184.5 359,-190.5 359,-190.5 359,-315.5 359,-315.5 359,-321.5 353,-327.5 347,-327.5 347,-327.5 12,-327.5 12,-327.5 6,-327.5 0,-321.5 0,-315.5 0,-315.5 0,-190.5 0,-190.5 0,-184.5 6,-178.5 12,-178.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10.5,-300 10.5,-321 349.5,-321 349.5,-300 10.5,-300\"/>\n",
       "<text text-anchor=\"start\" x=\"163\" y=\"-306.8\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-283.8\" font-family=\"Courier New\" font-size=\"14.00\">EBX = 0x1234</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-252.8\" font-family=\"Courier New\" font-size=\"14.00\">EAX = call_func_ret(loc_11223344, ESP)</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-229.8\" font-family=\"Courier New\" font-size=\"14.00\">ESP = call_func_stack(loc_11223344, ESP)</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-198.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = loc_a</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M86.5,-0.5C86.5,-0.5 272.5,-0.5 272.5,-0.5 278.5,-0.5 284.5,-6.5 284.5,-12.5 284.5,-12.5 284.5,-129.5 284.5,-129.5 284.5,-135.5 278.5,-141.5 272.5,-141.5 272.5,-141.5 86.5,-141.5 86.5,-141.5 80.5,-141.5 74.5,-135.5 74.5,-129.5 74.5,-129.5 74.5,-12.5 74.5,-12.5 74.5,-6.5 80.5,-0.5 86.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"84.5,-114 84.5,-135 274.5,-135 274.5,-114 84.5,-114\"/>\n",
       "<text text-anchor=\"start\" x=\"158.5\" y=\"-120.8\" font-family=\"Courier New\" font-size=\"14.00\">loc_a</text>\n",
       "<text text-anchor=\"start\" x=\"87.5\" y=\"-97.8\" font-family=\"Courier New\" font-size=\"14.00\">ECX = EAX</text>\n",
       "<text text-anchor=\"start\" x=\"87.5\" y=\"-66.8\" font-family=\"Courier New\" font-size=\"14.00\">ESP = ESP[0:32] + 0x4</text>\n",
       "<text text-anchor=\"start\" x=\"87.5\" y=\"-43.8\" font-family=\"Courier New\" font-size=\"14.00\">EIP = @32[ESP[0:32]]</text>\n",
       "<text text-anchor=\"start\" x=\"87.5\" y=\"-20.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = @32[ESP[0:32]]</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"blue\" d=\"M179.5,-178.27C179.5,-169.54 179.5,-160.61 179.5,-151.81\"/>\n",
       "<polygon fill=\"blue\" stroke=\"blue\" points=\"183,-151.56 179.5,-141.56 176,-151.56 183,-151.56\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6291012670>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    MOV  EBX, 0x1234\n",
    "    CALL 0x11223344\n",
    "    MOV  ECX, EAX\n",
    "    RET\n",
    "\"\"\", True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What happened here?\n",
    "The translation of the `call` is replaced by two side effects which occur in parallel:\n",
    "- `EAX` is set to the result of the operator `call_func_ret` which has two arguments: `loc_11223344` and `ESP`\n",
    "- `ESP` is set to the result of the operator `call_func_stack` which has two arguments: `loc_11223344` and `ESP`\n",
    "\n",
    "The first one is there to model the assignment in 'classic' x86 code of the return value. The second one is there to model a possible change of the stack pointer depending on the function called, that the old stack pointer.\n",
    "Everything here can be subclassed in order to customize the translation behavior."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Subfunction call custom modeling\n",
    "The code responsible of the modelisation of function calls is located in the `LifterModelCall` class (the lifter with call modeling) in `miasm/ir/analysis.py`:\n",
    "```python\n",
    "...\n",
    "    def call_effects(self, addr, instr):\n",
    "        \"\"\"Default modelisation of a function call to @addr. This may be used to:\n",
    "\n",
    "        * insert dependencies to arguments (stack base, registers, ...)\n",
    "        * add some side effects (stack clean, return value, ...)\n",
    "\n",
    "        Return a couple:\n",
    "        * list of assignments to add to the current irblock\n",
    "        * list of additional irblocks\n",
    "\n",
    "        @addr: (Expr) address of the called function\n",
    "        @instr: native instruction which is responsible of the call\n",
    "        \"\"\"\n",
    "\n",
    "        call_assignblk = AssignBlock(\n",
    "            [\n",
    "                ExprAssign(self.ret_reg, ExprOp('call_func_ret', addr, self.sp)),\n",
    "                ExprAssign(self.sp, ExprOp('call_func_stack', addr, self.sp))\n",
    "            ],\n",
    "            instr\n",
    "        )\n",
    "        return [call_assignblk], []\n",
    "\n",
    "```\n",
    "\n",
    "Some architectures subclass it to include some architecture dependent stuffs, for example in `miasm/arch/x86/lifter_model_call.py` in which we use a default calling convention linked to arguments passed through registers:\n",
    "```python\n",
    "...\n",
    "    def call_effects(self, ad, instr):\n",
    "        call_assignblk = AssignBlock(\n",
    "            [\n",
    "                ExprAssign(\n",
    "                    self.ret_reg,\n",
    "                    ExprOp(\n",
    "                        'call_func_ret',\n",
    "                        ad,\n",
    "                        self.sp,\n",
    "                        self.arch.regs.RCX,\n",
    "                        self.arch.regs.RDX,\n",
    "                        self.arch.regs.R8,\n",
    "                        self.arch.regs.R9,\n",
    "                    )\n",
    "                ),\n",
    "                ExprAssign(self.sp, ExprOp('call_func_stack', ad, self.sp)),\n",
    "            ],\n",
    "            instr\n",
    "        )\n",
    "        return [call_assignblk], []\n",
    "\n",
    "```\n",
    "\n",
    "This is the generic code used in `x86_64` to model function calls. But you can finely model functions. For example, suppose you are analysing code on `x86_32` with `stdcall` convention. Suppose you know the callee clean its stack arguments. Suppose as well you know for each function how many arguments it has. You can then customize the model to match the callee and compute the correct stack modification, as well as getting the arguments from stack:\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.44.1 (0)\n",
       " -->\n",
       "<!-- Title: html_table Pages: 1 -->\n",
       "<svg width=\"705pt\" height=\"498pt\"\n",
       " viewBox=\"0.00 0.00 705.00 498.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 494)\">\n",
       "<title>html_table</title>\n",
       "<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-494 701,-494 701,4 -4,4\"/>\n",
       "<!-- 0 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>0</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M12,-178.5C12,-178.5 685,-178.5 685,-178.5 691,-178.5 697,-184.5 697,-190.5 697,-190.5 697,-477.5 697,-477.5 697,-483.5 691,-489.5 685,-489.5 685,-489.5 12,-489.5 12,-489.5 6,-489.5 0,-483.5 0,-477.5 0,-477.5 0,-190.5 0,-190.5 0,-184.5 6,-178.5 12,-178.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"10.5,-462 10.5,-483 687.5,-483 687.5,-462 10.5,-462\"/>\n",
       "<text text-anchor=\"start\" x=\"332\" y=\"-468.8\" font-family=\"Courier New\" font-size=\"14.00\">main</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-445.8\" font-family=\"Courier New\" font-size=\"14.00\">EBX = 0x1234</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-414.8\" font-family=\"Courier New\" font-size=\"14.00\">ESP = ESP + &#45;0x4</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-391.8\" font-family=\"Courier New\" font-size=\"14.00\">@32[ESP + &#45;0x4] = 0x3</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-360.8\" font-family=\"Courier New\" font-size=\"14.00\">ESP = ESP + &#45;0x4</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-337.8\" font-family=\"Courier New\" font-size=\"14.00\">@32[ESP + &#45;0x4] = 0x2</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-306.8\" font-family=\"Courier New\" font-size=\"14.00\">ESP = ESP + &#45;0x4</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-283.8\" font-family=\"Courier New\" font-size=\"14.00\">@32[ESP + &#45;0x4] = 0x1</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-252.8\" font-family=\"Courier New\" font-size=\"14.00\">EAX = call_func_ret(loc_11223344, @32[ESP + 0x0], @32[ESP + 0x4], @32[ESP + 0x8])</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-229.8\" font-family=\"Courier New\" font-size=\"14.00\">ESP = ESP + 0xC</text>\n",
       "<text text-anchor=\"start\" x=\"13.5\" y=\"-198.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = loc_10</text>\n",
       "</g>\n",
       "<!-- 2 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>2</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M255.5,-0.5C255.5,-0.5 441.5,-0.5 441.5,-0.5 447.5,-0.5 453.5,-6.5 453.5,-12.5 453.5,-12.5 453.5,-129.5 453.5,-129.5 453.5,-135.5 447.5,-141.5 441.5,-141.5 441.5,-141.5 255.5,-141.5 255.5,-141.5 249.5,-141.5 243.5,-135.5 243.5,-129.5 243.5,-129.5 243.5,-12.5 243.5,-12.5 243.5,-6.5 249.5,-0.5 255.5,-0.5\"/>\n",
       "<polygon fill=\"grey\" stroke=\"transparent\" points=\"253.5,-114 253.5,-135 443.5,-135 443.5,-114 253.5,-114\"/>\n",
       "<text text-anchor=\"start\" x=\"323.5\" y=\"-120.8\" font-family=\"Courier New\" font-size=\"14.00\">loc_10</text>\n",
       "<text text-anchor=\"start\" x=\"256.5\" y=\"-97.8\" font-family=\"Courier New\" font-size=\"14.00\">ECX = EAX</text>\n",
       "<text text-anchor=\"start\" x=\"256.5\" y=\"-66.8\" font-family=\"Courier New\" font-size=\"14.00\">ESP = ESP[0:32] + 0x4</text>\n",
       "<text text-anchor=\"start\" x=\"256.5\" y=\"-43.8\" font-family=\"Courier New\" font-size=\"14.00\">EIP = @32[ESP[0:32]]</text>\n",
       "<text text-anchor=\"start\" x=\"256.5\" y=\"-20.8\" font-family=\"Courier New\" font-size=\"14.00\">IRDst = @32[ESP[0:32]]</text>\n",
       "</g>\n",
       "<!-- 0&#45;&gt;2 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>0&#45;&gt;2</title>\n",
       "<path fill=\"none\" stroke=\"blue\" d=\"M348.5,-178.16C348.5,-169.18 348.5,-160.37 348.5,-151.89\"/>\n",
       "<polygon fill=\"blue\" stroke=\"blue\" points=\"352,-151.73 348.5,-141.73 345,-151.73 352,-151.73\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.dot.Digraph at 0x7f6290e9b940>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Construct a custom lifter\n",
    "class LifterFixCallStack(LifterModelCall_x86_32):\n",
    "        def call_effects(self, addr, instr):\n",
    "            if addr.is_loc():\n",
    "                if self.loc_db.get_location_offset(addr.loc_key) == 0x11223344:\n",
    "                    # Suppose the function at 0x11223344 has 3 arguments\n",
    "                    args_count = 3\n",
    "                else:\n",
    "                    # It's a function we didn't analyze\n",
    "                    raise RuntimeError(\"Unknown function parameters\")\n",
    "            else:\n",
    "                # It's a dynamic call !\n",
    "                raise RuntimeError(\"Dynamic destination ?\")\n",
    "            # Arguments are taken from stack\n",
    "            args = []\n",
    "            for i in range(args_count):\n",
    "                args.append(ExprMem(self.sp + ExprInt(i * 4, 32), 32))\n",
    "            # Generate the model\n",
    "            call_assignblk = AssignBlock(\n",
    "                [\n",
    "                    ExprAssign(self.ret_reg, ExprOp('call_func_ret', addr, *args)),\n",
    "                    ExprAssign(self.sp, self.sp + ExprInt(args_count * 4, self.sp.size))\n",
    "                ],\n",
    "                instr\n",
    "            )\n",
    "            return [call_assignblk], []\n",
    "\n",
    "graph_ir_x86(\"\"\"\n",
    "main:\n",
    "    MOV  EBX, 0x1234\n",
    "    PUSH 3\n",
    "    PUSH 2\n",
    "    PUSH 1\n",
    "    CALL 0x11223344\n",
    "    MOV  ECX, EAX\n",
    "    RET\n",
    "\"\"\", lifter_custom=LifterFixCallStack)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the new graph, it's now easy to see that `EAX` depends on a custom operator `call_func_ret` with arguments:\n",
    "- `loc_11223344`\n",
    "- @32[ESP + 0x0]\n",
    "- @32[ESP + 0x4]\n",
    "- @32[ESP + 0x8]\n",
    "\n",
    "The stack pointer is updated: it is increased by 0xC bytes, which corresponds to its arguments size (we didn't model the extra 4 bytes pushed on the stack for the return address, so no need to take them into account using our arbitrary model)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}