├── README.md ├── LICENSE └── radare2 ├── IOC extractor.ipynb └── Annotating Go Binaries using Cutter.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # notebooks 2 | Notebook collection 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Remco Verhoef 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /radare2/IOC extractor.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# IOC extractor using Radare2\n", 8 | "\n", 9 | "This notebook extract IOCs from binaries using Radare2. IOC matchers can be easily extended by adding an extra matcher. Every matcher result can be run through pipes, where currently only MISP is supported." 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "### Load environment" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 44, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "try:\n", 26 | " # if using jupyter within cutter, use the following. This will use the current active binary.\n", 27 | " import cutter\n", 28 | " # we'll assign cutter to variable r2 to be consistent with r2pipe\n", 29 | " r2 = cutter\n", 30 | "except ModuleNotFoundError as exc:\n", 31 | " # using r2pipe to open a binary\n", 32 | " import r2pipe\n", 33 | " r2 = r2pipe.open(\"/home/jovyan/radare2/malware/apache\")" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "### Start analysis" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "%time r2.cmd('aaa')" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "### Extract strings" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "metadata": { 63 | "scrolled": true 64 | }, 65 | "outputs": [], 66 | "source": [ 67 | "print(r2.cmd('iz'))" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "### Show information about binary" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "from pprint import pprint\n", 84 | "r = json.loads(r2.cmd('ij'))\n", 85 | "pprint(r)\n", 86 | "print(r.get('bin').get('arch'))" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "### MISP\n", 94 | "\n", 95 | "The following cell will configure a MISP pipe which will run each extracted IOC through MISP. Uncomment and configure the misp_url and misp_key." 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 84, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [ 104 | "# install pymisp if not exists\n", 105 | "try:\n", 106 | " from pymisp import ExpandedPyMISP\n", 107 | "except ModuleNotFoundError as exc:\n", 108 | " print(\"Could not find module pymisp, installing...\")\n", 109 | " !pip install pymisp" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": null, 115 | "metadata": {}, 116 | "outputs": [], 117 | "source": [ 118 | "# The URL of the MISP instance to connect to\n", 119 | "# make sure the radare2-notebook container can reach MISP\n", 120 | "# misp_url = 'https://172.17.0.3:443'\n", 121 | "\n", 122 | "# Can be found in the MISP web interface under ||\n", 123 | "# http://+MISP_URL+/users/view/me -> Authkey\n", 124 | "# misp_key = 'V9RraxF0YT6riCT1TBD1D1TdabxI1MsVJp12E8pq'\n", 125 | "\n", 126 | "# Should PyMISP verify the MISP certificate\n", 127 | "# not recommended\n", 128 | "misp_verifycert = False\n", 129 | "import urllib3\n", 130 | "urllib3.disable_warnings()\n", 131 | "print(\"warning: disabled certificate verification\")" 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "### Configure the matchers and pipes" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": null, 144 | "metadata": {}, 145 | "outputs": [], 146 | "source": [ 147 | "import r2pipe\n", 148 | "import json\n", 149 | "import struct\n", 150 | "import re\n", 151 | "import base64\n", 152 | "from pprint import pprint, pformat\n", 153 | "import urllib.parse\n", 154 | "\n", 155 | "IP_MATCHER = re.compile(\"(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(?:[:]\\d+)?)\")\n", 156 | "URL_MATCHER = re.compile('(?:(?:https?|ftp|file)://|www\\.|ftp\\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$]', re.IGNORECASE)\n", 157 | "EMAIL_MATCHER = re.compile('([A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4})', re.IGNORECASE)\n", 158 | "\n", 159 | "def regex_matcher(matcher):\n", 160 | " return lambda st: matcher.findall(st)\n", 161 | "\n", 162 | "def contains_matcher(s):\n", 163 | " return lambda st: [st] if s in st else []\n", 164 | " \n", 165 | "matchers = [regex_matcher(IP_MATCHER), regex_matcher(URL_MATCHER), regex_matcher(EMAIL_MATCHER), contains_matcher('\\\\e['), contains_matcher('HTTP')]\n", 166 | "\n", 167 | "pipes = []\n", 168 | "\n", 169 | "def misp_pipe():\n", 170 | " print(\"Using MISP pipe (url={})\".format(misp_url))\n", 171 | " from pymisp import ExpandedPyMISP\n", 172 | " misp = ExpandedPyMISP(misp_url, misp_key, misp_verifycert, debug=False)\n", 173 | " def fn(ioc):\n", 174 | " results = misp.search(value=ioc) # everything updated since that timestamp\n", 175 | " for result in results:\n", 176 | " print (\">>> MISP result found: {}\".format(urllib.parse.urljoin(misp_url, \"/events/view/\" + result.get('Event').get('id'))))\n", 177 | " return r\n", 178 | " \n", 179 | " return fn\n", 180 | "\n", 181 | "if misp_url != None:\n", 182 | " pipes.append(misp_pipe())\n", 183 | "\n", 184 | "def print_s(s, r):\n", 185 | " print('0x{:08x} 0x{:08x} {:10} {:4} {:10} {}'.format(s.get('paddr'), s.get('vaddr'), s.get('type'), s.get('length'), s.get('section'), r))" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "metadata": {}, 191 | "source": [ 192 | "### Start IOC extraction" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 88, 198 | "metadata": {}, 199 | "outputs": [ 200 | { 201 | "name": "stdout", 202 | "output_type": "stream", 203 | "text": [ 204 | "0x0010c3be 0x0050c3be ascii 15 .rodata \\e[01;32mresumed\n", 205 | ">>> MISP result found: https://172.17.0.3:443/events/view/2\n", 206 | "0x0010c3f0 0x0050c3f0 ascii 49 .rodata \\e[01;33mpaused\\e[0m, press \\e[01;35mr\\e[0m to resume\n", 207 | "0x0010c4e0 0x0050c4e0 ascii 71 .rodata \\e[1;32m * \\e[0m\\e[1;37mPOOL #%-7zu\\e[0m\\e[1;%dm%s\\e[0m variant \\e[1;37m%s\\e[0m\n", 208 | "0x0010c528 0x0050c528 ascii 60 .rodata \\e[1;32m * \\e[0m\\e[1;37m%-13s\\e[0m\\e[1;36m%s/%s\\e[0m\\e[1;37m %s\\e[0m\n", 209 | "0x0010c568 0x0050c568 ascii 41 .rodata \\e[1;32m * \\e[0m\\e[1;37m%-13slibuv/%s %s\\e[0m\n", 210 | "0x0010f8b0 0x0050f8b0 ascii 5 .rodata \\e[0m\\n\n", 211 | "0x0010f8b6 0x0050f8b6 ascii 7 .rodata \\e[0;31m\n", 212 | "0x0010f8be 0x0050f8be ascii 7 .rodata \\e[0;33m\n", 213 | "0x0010f8c6 0x0050f8c6 ascii 7 .rodata \\e[1;37m\n", 214 | "0x0010f8ce 0x0050f8ce ascii 5 .rodata \\e[90m\n", 215 | "0x0011031d 0x0051031d ascii 7 .rodata \\e[1;30m\n", 216 | "0x00110388 0x00510388 ascii 61 .rodata \\e[1;37muse pool \\e[0m\\e[1;36m%s:%d \\e[0m\\e[1;32m%s\\e[0m \\e[1;30m%s \n", 217 | "0x001103c8 0x005103c8 ascii 81 .rodata \\e[01;31mrejected\\e[0m (%ld/%ld) diff \\e[01;37m%u\\e[0m \\e[31m\"%s\"\\e[0m \\e[01;30m(%lu ms)\n", 218 | "0x00110450 0x00510450 ascii 67 .rodata \\e[01;32maccepted\\e[0m (%ld/%ld) diff \\e[01;37m%u\\e[0m \\e[01;30m(%lu ms)\n", 219 | "0x001104c0 0x005104c0 ascii 78 .rodata \\e[1;35mnew job\\e[0m from \\e[1;37m%s:%d\\e[0m diff \\e[1;37m%d\\e[0m algo \\e[1;37m%s\\e[0m\n", 220 | "0x001106c4 0x005106c4 ascii 8 .rodata \\e[1;31m-\n", 221 | "0x001106cd 0x005106cd ascii 7 .rodata \\e[1;31m\n", 222 | "0x0011076e 0x0051076e ascii 15 .rodata \\e[1;31mnone\\e[0m\n", 223 | "0x0011077e 0x0051077e ascii 16 .rodata \\e[1;32mintel\\e[0m\n", 224 | "0x0011078f 0x0051078f ascii 16 .rodata \\e[1;32mryzen\\e[0m\n", 225 | "0x001107a0 0x005107a0 ascii 93 .rodata \\e[1;32m * \\e[0m\\e[1;37m%-13s\\e[0m\\e[1;36m%d\\e[0m\\e[1;37m, %s, av=%d, %sdonate=%d%%\\e[0m\\e[1;37m%s\\e[0m\n", 226 | "0x00110828 0x00510828 ascii 73 .rodata \\e[1;32m * \\e[0m\\e[1;37m%-13s\\e[0m\\e[1;36m%d\\e[0m\\e[1;37m, %s, %sdonate=%d%%\\e[0m\n", 227 | "0x00110878 0x00510878 ascii 37 .rodata \\e[1;32m * \\e[0m\\e[1;37m%-13sauto:%s\\e[0m\n", 228 | "0x001108a0 0x005108a0 ascii 32 .rodata \\e[1;32m * \\e[0m\\e[1;37m%-13s%s\\e[0m\n", 229 | "0x001108c8 0x005108c8 ascii 49 .rodata \\e[1;32m * \\e[0m\\e[1;37m%-13s%s (%d)\\e[0m %sx64 %sAES\n", 230 | "0x00110900 0x00510900 ascii 45 .rodata \\e[1;32m * \\e[0m\\e[1;37m%-13s%.1f MB/%.1f MB\\e[0m\n", 231 | "0x00110930 0x00510930 ascii 127 .rodata \\e[1;32m * \\e[0m\\e[1;37mCOMMANDS \\e[0m\\e[1;35mh\\e[0m\\e[1;37mashrate, \\e[0m\\e[1;35mp\\e[0m\\e[1;37mause, \\e[0m\\e[1;35mr\\e[0m\\e[1;37mesume\\e[0m\n", 232 | "0x001124d0 0x005124d0 ascii 96 .rodata \\e[1;37mspeed\\e[0m 10s/60s/15m \\e[1;36m%s\\e[0m\\e[0;36m %s %s \\e[0m\\e[1;36mH/s\\e[0m max \\e[1;36m%s H/s\\e[0m\n", 233 | "0x001131c8 0x005131c8 ascii 7 .rodata \\e[1;33m\n", 234 | "0x00113230 0x00513230 ascii 110 .rodata \\e[1;32mREADY (CPU)\\e[0m threads \\e[1;36m%zu(%zu)\\e[0m huge pages %s%zu/%zu %1.0f%%\\e[0m memory \\e[1;36m%zu.0 MB\\e[0m\n" 235 | ] 236 | } 237 | ], 238 | "source": [ 239 | "strings = json.loads(r2.cmd('izj'))\n", 240 | "for s in strings:\n", 241 | " try:\n", 242 | " st = base64.b64decode(s.get('string')).decode(s.get('type'))\n", 243 | "\n", 244 | " for matcher in matchers:\n", 245 | " matches = matcher(st)\n", 246 | " for match in matches: \n", 247 | " print_s (s, match)\n", 248 | " for pipe in pipes:\n", 249 | " pipe(match)\n", 250 | " pass\n", 251 | " except ValueError as e:\n", 252 | " # print(e)\n", 253 | " continue\n", 254 | " except LookupError as e:\n", 255 | " # print(e)\n", 256 | " continue" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "metadata": {}, 263 | "outputs": [], 264 | "source": [] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": null, 269 | "metadata": {}, 270 | "outputs": [], 271 | "source": [] 272 | } 273 | ], 274 | "metadata": { 275 | "kernelspec": { 276 | "display_name": "Python 3", 277 | "language": "python", 278 | "name": "python3" 279 | }, 280 | "language_info": { 281 | "codemirror_mode": { 282 | "name": "ipython", 283 | "version": 3 284 | }, 285 | "file_extension": ".py", 286 | "mimetype": "text/x-python", 287 | "name": "python", 288 | "nbconvert_exporter": "python", 289 | "pygments_lexer": "ipython3", 290 | "version": "3.6.7" 291 | } 292 | }, 293 | "nbformat": 4, 294 | "nbformat_minor": 2 295 | } 296 | -------------------------------------------------------------------------------- /radare2/Annotating Go Binaries using Cutter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Analyzing Golang binaries with Radare2" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "### Load environment" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 4, 20 | "metadata": {}, 21 | "outputs": [ 22 | { 23 | "name": "stdout", 24 | "output_type": "stream", 25 | "text": [ 26 | "[+] loaded Cutter binary\n" 27 | ] 28 | } 29 | ], 30 | "source": [ 31 | "try:\n", 32 | " # if using jupyter within cutter, use the following. This will use the current active binary.\n", 33 | " import cutter\n", 34 | " # we'll assign cutter to variable r2 to be consistent with r2pipe\n", 35 | " r2 = cutter\n", 36 | " print(\"[+] loaded Cutter binary\")\n", 37 | "except ModuleNotFoundError as exc:\n", 38 | " # using r2pipe to open a binary\n", 39 | " import r2pipe\n", 40 | " r2 = r2pipe.open(\"test\")\n", 41 | " print(\"[+] loaded binary\")\n" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "### Start analysis" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 5, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "# %time r2.cmd('aaa')" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "### find .goclntab section" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 7, 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "import json\n", 74 | "\n", 75 | "sections = {}\n", 76 | "\n", 77 | "for section in json.loads(r2.cmd(\"iSj\")):\n", 78 | " name = section.get('name')\n", 79 | " sections[name] = { 'name': name, 'size': section.get('size'), 'vaddr': section.get('vaddr')}" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 14, 85 | "metadata": {}, 86 | "outputs": [ 87 | { 88 | "name": "stdout", 89 | "output_type": "stream", 90 | "text": [ 91 | "[+] .gopclntab section found: size=448041 vaddr=5024768\n" 92 | ] 93 | } 94 | ], 95 | "source": [ 96 | "size = sections['.gopclntab'].get('size')\n", 97 | "vaddr = sections['.gopclntab'].get('vaddr')\n", 98 | "\n", 99 | "# not efficient, takes a long time. Better will be to retrieve directly from \n", 100 | "# raw file.\n", 101 | "data = bytes(json.loads(r2.cmd(\"pxj {} @ {}\".format(size, vaddr))))\n", 102 | "\n", 103 | "print (\"[+] .gopclntab section found: size={} vaddr={}\".format(size, vaddr))" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 15, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "import binascii\n", 113 | "import struct\n", 114 | "\n", 115 | "def read_var_int(p): \n", 116 | " result = 0\n", 117 | " shift = 0\n", 118 | " while True:\n", 119 | " b = p[0]\n", 120 | " p = p[1:]\n", 121 | "\n", 122 | " result |= ((b & 0x7F) << shift)\n", 123 | " if not (b & 0x80):\n", 124 | " break\n", 125 | "\n", 126 | " shift += 7\n", 127 | "\n", 128 | " return p, result\n", 129 | "\n", 130 | "def pcValue(p):\n", 131 | " pc = 0\n", 132 | " val = -1\n", 133 | "\n", 134 | " j = 0\n", 135 | " while True:\n", 136 | " p, uvdelta = read_var_int(p)\n", 137 | " if uvdelta ==0:\n", 138 | " break \n", 139 | "\n", 140 | " val += decodeZigZag32(uvdelta)\n", 141 | " \n", 142 | " p, pcdelta = read_var_int(p)\n", 143 | " pc+=(pcdelta)\n", 144 | "\n", 145 | " yield (val, pc)\n", 146 | " \n", 147 | " j+=1\n", 148 | "\n", 149 | "# https://gist.github.com/matteobertozzi/1521947\n", 150 | "def encodeZigZag32(n): return (n << 1) ^ (n >> 31)\n", 151 | "def encodeZigZag64(n): return (n << 1) ^ (n >> 63)\n", 152 | "def decodeZigZag32(n): return (n >> 1) ^ -(n & 1)\n", 153 | "def decodeZigZag64(n): return (n >> 1) ^ -(n & 1)" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 17, 159 | "metadata": {}, 160 | "outputs": [ 161 | { 162 | "name": "stdout", 163 | "output_type": "stream", 164 | "text": [ 165 | "[ ] name=main.main entry=485040 args=0 frame=0 pcsp=6afcb pcfile=6afd4 pcln=6afd8 nfuncdata=3 npcdata=4\n", 166 | "[ ] path=/Users/remco/Projects/sans/test.go:5 addr=0x485040\n", 167 | "[ ] path=/Users/remco/Projects/sans/test.go:6 addr=0x48505d\n", 168 | "[ ] path=/Users/remco/Projects/sans/test.go:7 addr=0x48509d\n", 169 | "[ ] name=main.init entry=4850b0 args=0 frame=0 pcsp=6b063 pcfile=6b06e pcln=6b071 nfuncdata=3 npcdata=4\n" 170 | ] 171 | } 172 | ], 173 | "source": [ 174 | "import binascii\n", 175 | "import struct\n", 176 | "\n", 177 | "# https://docs.google.com/document/d/1lyPIbmsYbXnpNj57a261hgOYVpNRcgydurVQIyZOz_o/pub\n", 178 | "offset = 0 \n", 179 | "\n", 180 | "magic, = struct.unpack_from(\"I\", s, offset)\n", 181 | "offset += 4\n", 182 | "\n", 183 | "if magic != 0xfffffffb:\n", 184 | " print(\"[!] Magic incorrect for .gopclnt\")\n", 185 | " raise Exception(\"Magic incorrect\")\n", 186 | " \n", 187 | "quantum, uintptr_size, = struct.unpack_from(\"xxbb\", s, offset)\n", 188 | "offset += 4\n", 189 | "\n", 190 | "# https://docs.google.com/document/d/1lyPIbmsYbXnpNj57a261hgOYVpNRcgydurVQIyZOz_o/pub\n", 191 | "table_size, = struct.unpack_from(\"q\", s, offset)\n", 192 | "offset += 8\n", 193 | "\n", 194 | "# Retrieve path from file table. The file table is located at table_size\n", 195 | "def file_table(index):\n", 196 | " file_table_offset, = struct.unpack_from(\"i\", s, 4 + 4 + 8 + table_size * 16 + 8)\n", 197 | "\n", 198 | " file_table_size, = struct.unpack_from(\"i\", s, file_table_offset)\n", 199 | "\n", 200 | " name_offset, = struct.unpack_from(\"i\", s, file_table_offset + index * 4)\n", 201 | " name = s[name_offset:]\n", 202 | " name= name[:name.index(b\"\\0\")].decode('utf-8')\n", 203 | " return name\n", 204 | "\n", 205 | "# https://golang.org/src/cmd/internal/objfile/goobj.go\n", 206 | "for i in range(0, table_size):\n", 207 | " pc, func_offset, = struct.unpack_from(\"qq\", s, offset)\n", 208 | "\n", 209 | " offset += struct.calcsize(\"qq\")\n", 210 | " \n", 211 | " entry, name_offset, args, frame, pcsp, pcfile, pcln, nfuncdata, npcdata, = struct.unpack_from(\"qiiiiiiii\", s, func_offset)\n", 212 | " name = s[name_offset:]\n", 213 | " name= name[:name.index(b\"\\0\")].decode('utf-8')\n", 214 | " \n", 215 | " if not name.startswith('main.'):\n", 216 | " continue \n", 217 | "\n", 218 | " print(\"[ ] name={} entry={:x} args={:x} frame={:x} pcsp={:x} pcfile={:x} pcln={:x} nfuncdata={:x} npcdata={:x}\".format(name, entry, args, frame, pcsp, pcfile, pcln, nfuncdata, npcdata))\n", 219 | "\n", 220 | " if pcfile == 0:\n", 221 | " continue\n", 222 | "\n", 223 | " def line2path(addr):\n", 224 | " for (val, pc) in pcValue(s[pcfile:]):\n", 225 | " if addr < pc:\n", 226 | " return file_table(val)\n", 227 | "\n", 228 | " return None\n", 229 | "\n", 230 | " addr = 0\n", 231 | " for (val, pc) in pcValue(s[pcln:]):\n", 232 | " path = line2path(pc)\n", 233 | " if not path:\n", 234 | " continue\n", 235 | " \n", 236 | " r2.cmd('CCu {}:{} @ 0x{:x}'.format(path, val, entry + addr))\n", 237 | " print('[ ] path={}:{} addr=0x{:x}'.format(line2path(pc), val, entry + addr))\n", 238 | " addr = pc" 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": {}, 244 | "source": [ 245 | "### Print all source files" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": 20, 251 | "metadata": {}, 252 | "outputs": [ 253 | { 254 | "name": "stdout", 255 | "output_type": "stream", 256 | "text": [ 257 | "[ ] index=1 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/cpu/cpu.go\n", 258 | "[ ] index=2 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/cpu/cpu_x86.go\n", 259 | "[ ] index=3 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/cpu/cpu_x86.s\n", 260 | "[ ] index=4 path=\n", 261 | "[ ] index=5 path=/usr/local/Cellar/go/1.11.5/libexec/src/sync/atomic/value.go\n", 262 | "[ ] index=6 path=/usr/local/Cellar/go/1.11.5/libexec/src/sync/atomic/asm.s\n", 263 | "[ ] index=7 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/internal/atomic/asm_amd64.s\n", 264 | "[ ] index=8 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/bytealg/index_amd64.go\n", 265 | "[ ] index=9 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/bytealg/compare_amd64.s\n", 266 | "[ ] index=10 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/bytealg/equal_amd64.s\n", 267 | "[ ] index=11 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/bytealg/indexbyte_amd64.s\n", 268 | "[ ] index=12 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/alg.go\n", 269 | "[ ] index=13 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/stubs.go\n", 270 | "[ ] index=14 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/typekind.go\n", 271 | "[ ] index=15 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/atomic_pointer.go\n", 272 | "[ ] index=16 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mwbbuf.go\n", 273 | "[ ] index=17 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/cgo_mmap.go\n", 274 | "[ ] index=18 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/cgo_sigaction.go\n", 275 | "[ ] index=19 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/cgocall.go\n", 276 | "[ ] index=20 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/symtab.go\n", 277 | "[ ] index=21 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/cgocheck.go\n", 278 | "[ ] index=22 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mheap.go\n", 279 | "[ ] index=23 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mbitmap.go\n", 280 | "[ ] index=24 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/chan.go\n", 281 | "[ ] index=25 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/slice.go\n", 282 | "[ ] index=26 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/runtime2.go\n", 283 | "[ ] index=27 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/cpuflags_amd64.go\n", 284 | "[ ] index=28 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/cpuprof.go\n", 285 | "[ ] index=29 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/proc.go\n", 286 | "[ ] index=30 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/debug.go\n", 287 | "[ ] index=31 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/debugcall.go\n", 288 | "[ ] index=32 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/env_posix.go\n", 289 | "[ ] index=33 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/error.go\n", 290 | "[ ] index=34 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/extern.go\n", 291 | "[ ] index=35 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/float.go\n", 292 | "[ ] index=36 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/hash64.go\n", 293 | "[ ] index=37 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/unaligned1.go\n", 294 | "[ ] index=38 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/iface.go\n", 295 | "[ ] index=39 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/type.go\n", 296 | "[ ] index=40 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/lfstack.go\n", 297 | "[ ] index=41 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/lfstack_64bit.go\n", 298 | "[ ] index=42 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/lock_futex.go\n", 299 | "[ ] index=43 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/malloc.go\n", 300 | "[ ] index=44 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mfixalloc.go\n", 301 | "[ ] index=45 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/runtime1.go\n", 302 | "[ ] index=46 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mgc.go\n", 303 | "[ ] index=47 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/fastlog2.go\n", 304 | "[ ] index=48 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/map.go\n", 305 | "[ ] index=49 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/msize.go\n", 306 | "[ ] index=50 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/map_fast32.go\n", 307 | "[ ] index=51 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/map_fast64.go\n", 308 | "[ ] index=52 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/map_faststr.go\n", 309 | "[ ] index=53 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mbarrier.go\n", 310 | "[ ] index=54 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mcache.go\n", 311 | "[ ] index=55 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mcentral.go\n", 312 | "[ ] index=56 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mem_linux.go\n", 313 | "[ ] index=57 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mfinal.go\n", 314 | "[ ] index=58 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mgcwork.go\n", 315 | "[ ] index=59 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mgcsweep.go\n", 316 | "[ ] index=60 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mgclarge.go\n", 317 | "[ ] index=61 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mgcmark.go\n", 318 | "[ ] index=62 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mgcsweepbuf.go\n", 319 | "[ ] index=63 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mprof.go\n", 320 | "[ ] index=64 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/mstats.go\n", 321 | "[ ] index=65 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/netpoll.go\n", 322 | "[ ] index=66 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/netpoll_epoll.go\n", 323 | "[ ] index=67 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/os_linux.go\n", 324 | "[ ] index=68 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/defs_linux_amd64.go\n", 325 | "[ ] index=69 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/os_linux_generic.go\n", 326 | "[ ] index=70 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/panic.go\n", 327 | "[ ] index=71 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/string.go\n", 328 | "[ ] index=72 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/signal_unix.go\n", 329 | "[ ] index=73 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/print.go\n", 330 | "[ ] index=74 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/traceback.go\n", 331 | "[ ] index=75 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/sys_x86.go\n", 332 | "[ ] index=76 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/stack.go\n", 333 | "[ ] index=77 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/profbuf.go\n", 334 | "[ ] index=78 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/runtime.go\n", 335 | "[ ] index=79 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/rwmutex.go\n", 336 | "[ ] index=80 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/sema.go\n", 337 | "[ ] index=81 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/signal_amd64x.go\n", 338 | "[ ] index=82 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/signal_linux_amd64.go\n", 339 | "[ ] index=83 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/signal_sighandler.go\n", 340 | "[ ] index=84 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/sigqueue.go\n", 341 | "[ ] index=85 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/internal/sys/intrinsics.go\n", 342 | "[ ] index=86 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/time.go\n", 343 | "[ ] index=87 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/timestub.go\n", 344 | "[ ] index=88 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/trace.go\n", 345 | "[ ] index=89 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/utf8.go\n", 346 | "[ ] index=90 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/vdso_linux.go\n", 347 | "[ ] index=91 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/write_err.go\n", 348 | "[ ] index=92 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/select.go\n", 349 | "[ ] index=93 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/asm.s\n", 350 | "[ ] index=94 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/asm_amd64.s\n", 351 | "[ ] index=95 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/duff_amd64.s\n", 352 | "[ ] index=96 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/memclr_amd64.s\n", 353 | "[ ] index=97 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/memmove_amd64.s\n", 354 | "[ ] index=98 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/rt0_linux_amd64.s\n", 355 | "[ ] index=99 path=/usr/local/Cellar/go/1.11.5/libexec/src/runtime/sys_linux_amd64.s\n", 356 | "[ ] index=100 path=/usr/local/Cellar/go/1.11.5/libexec/src/math/exp_asm.go\n", 357 | "[ ] index=101 path=/usr/local/Cellar/go/1.11.5/libexec/src/errors/errors.go\n", 358 | "[ ] index=102 path=/usr/local/Cellar/go/1.11.5/libexec/src/unicode/utf8/utf8.go\n", 359 | "[ ] index=103 path=/usr/local/Cellar/go/1.11.5/libexec/src/strconv/decimal.go\n", 360 | "[ ] index=104 path=/usr/local/Cellar/go/1.11.5/libexec/src/strconv/extfloat.go\n", 361 | "[ ] index=105 path=/usr/local/Cellar/go/1.11.5/libexec/src/math/bits/bits.go\n", 362 | "[ ] index=106 path=/usr/local/Cellar/go/1.11.5/libexec/src/strconv/ftoa.go\n", 363 | "[ ] index=107 path=/usr/local/Cellar/go/1.11.5/libexec/src/strconv/itoa.go\n", 364 | "[ ] index=108 path=/usr/local/Cellar/go/1.11.5/libexec/src/strconv/quote.go\n", 365 | "[ ] index=109 path=/usr/local/Cellar/go/1.11.5/libexec/src/strconv/atoi.go\n", 366 | "[ ] index=110 path=/usr/local/Cellar/go/1.11.5/libexec/src/sync/map.go\n", 367 | "[ ] index=111 path=/usr/local/Cellar/go/1.11.5/libexec/src/sync/mutex.go\n", 368 | "[ ] index=112 path=/usr/local/Cellar/go/1.11.5/libexec/src/sync/once.go\n", 369 | "[ ] index=113 path=/usr/local/Cellar/go/1.11.5/libexec/src/sync/pool.go\n", 370 | "[ ] index=114 path=/usr/local/Cellar/go/1.11.5/libexec/src/sync/runtime.go\n", 371 | "[ ] index=115 path=/usr/local/Cellar/go/1.11.5/libexec/src/io/io.go\n", 372 | "[ ] index=116 path=/usr/local/Cellar/go/1.11.5/libexec/src/io/pipe.go\n", 373 | "[ ] index=117 path=/usr/local/Cellar/go/1.11.5/libexec/src/syscall/exec_unix.go\n", 374 | "[ ] index=118 path=/usr/local/Cellar/go/1.11.5/libexec/src/syscall/str.go\n", 375 | "[ ] index=119 path=/usr/local/Cellar/go/1.11.5/libexec/src/syscall/syscall.go\n", 376 | "[ ] index=120 path=/usr/local/Cellar/go/1.11.5/libexec/src/syscall/syscall_linux.go\n", 377 | "[ ] index=121 path=/usr/local/Cellar/go/1.11.5/libexec/src/syscall/syscall_unix.go\n", 378 | "[ ] index=122 path=/usr/local/Cellar/go/1.11.5/libexec/src/syscall/zsyscall_linux_amd64.go\n", 379 | "[ ] index=123 path=/usr/local/Cellar/go/1.11.5/libexec/src/syscall/env_unix.go\n", 380 | "[ ] index=124 path=/usr/local/Cellar/go/1.11.5/libexec/src/syscall/asm_linux_amd64.s\n", 381 | "[ ] index=125 path=/usr/local/Cellar/go/1.11.5/libexec/src/time/format.go\n", 382 | "[ ] index=126 path=/usr/local/Cellar/go/1.11.5/libexec/src/time/zoneinfo.go\n", 383 | "[ ] index=127 path=/usr/local/Cellar/go/1.11.5/libexec/src/time/zoneinfo_read.go\n", 384 | "[ ] index=128 path=/usr/local/Cellar/go/1.11.5/libexec/src/time/zoneinfo_unix.go\n", 385 | "[ ] index=129 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/poll/fd.go\n", 386 | "[ ] index=130 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/poll/fd_mutex.go\n", 387 | "[ ] index=131 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/poll/fd_poll_runtime.go\n", 388 | "[ ] index=132 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/poll/fd_unix.go\n", 389 | "[ ] index=133 path=/usr/local/Cellar/go/1.11.5/libexec/src/internal/syscall/unix/nonblocking.go\n", 390 | "[ ] index=134 path=/usr/local/Cellar/go/1.11.5/libexec/src/os/error.go\n", 391 | "[ ] index=135 path=/usr/local/Cellar/go/1.11.5/libexec/src/os/file.go\n", 392 | "[ ] index=136 path=/usr/local/Cellar/go/1.11.5/libexec/src/os/file_posix.go\n", 393 | "[ ] index=137 path=/usr/local/Cellar/go/1.11.5/libexec/src/os/file_unix.go\n", 394 | "[ ] index=138 path=/usr/local/Cellar/go/1.11.5/libexec/src/os/proc.go\n", 395 | "[ ] index=139 path=/usr/local/Cellar/go/1.11.5/libexec/src/os/executable_procfs.go\n", 396 | "[ ] index=140 path=/usr/local/Cellar/go/1.11.5/libexec/src/os/exec_unix.go\n", 397 | "[ ] index=141 path=/usr/local/Cellar/go/1.11.5/libexec/src/unicode/tables.go\n", 398 | "[ ] index=142 path=/usr/local/Cellar/go/1.11.5/libexec/src/reflect/makefunc.go\n", 399 | "[ ] index=143 path=/usr/local/Cellar/go/1.11.5/libexec/src/reflect/type.go\n", 400 | "[ ] index=144 path=/usr/local/Cellar/go/1.11.5/libexec/src/reflect/value.go\n", 401 | "[ ] index=145 path=/usr/local/Cellar/go/1.11.5/libexec/src/reflect/asm_amd64.s\n", 402 | "[ ] index=146 path=/usr/local/Cellar/go/1.11.5/libexec/src/fmt/format.go\n", 403 | "[ ] index=147 path=/usr/local/Cellar/go/1.11.5/libexec/src/fmt/print.go\n", 404 | "[ ] index=148 path=/usr/local/Cellar/go/1.11.5/libexec/src/fmt/scan.go\n", 405 | "[ ] index=149 path=/Users/remco/Projects/sans/test.go\n" 406 | ] 407 | } 408 | ], 409 | "source": [ 410 | "file_table_offset, = struct.unpack_from(\"i\", s, 4 + 4 + 8 + table_size * 16 + 8)\n", 411 | "\n", 412 | "file_table_size, = struct.unpack_from(\"i\", s, file_table_offset)\n", 413 | "\n", 414 | "for i in range(1, file_table_size):\n", 415 | " name_offset, = struct.unpack_from(\"i\", s, file_table_offset + i * 4)\n", 416 | " name = s[name_offset:]\n", 417 | " name= name[:name.index(b\"\\0\")]\n", 418 | " name = name.decode('utf-8')\n", 419 | " print(\"[ ] index={} path={}\".format(i, name))\n", 420 | " continue" 421 | ] 422 | } 423 | ], 424 | "metadata": { 425 | "kernelspec": { 426 | "display_name": "Python 3", 427 | "language": "python", 428 | "name": "python3" 429 | }, 430 | "language_info": { 431 | "codemirror_mode": { 432 | "name": "ipython", 433 | "version": 3 434 | }, 435 | "file_extension": ".py", 436 | "mimetype": "text/x-python", 437 | "name": "python", 438 | "nbconvert_exporter": "python", 439 | "pygments_lexer": "ipython3", 440 | "version": "3.6.4" 441 | } 442 | }, 443 | "nbformat": 4, 444 | "nbformat_minor": 2 445 | } 446 | --------------------------------------------------------------------------------