{"action":"opened","issue":{"url":"https://api.github.com/repos/angr/angr/issues/1286","repository_url":"https://api.github.com/repos/angr/angr","labels_url":"https://api.github.com/repos/angr/angr/issues/1286/labels{/name}","comments_url":"https://api.github.com/repos/angr/angr/issues/1286/comments","events_url":"https://api.github.com/repos/angr/angr/issues/1286/events","html_url":"https://github.com/angr/angr/issues/1286","id":376261015,"node_id":"MDU6SXNzdWUzNzYyNjEwMTU=","number":1286,"title":"CFG party foul: B.W on thumb and ret-to-grandparent functions cause incorrect function recovery","user":{"login":"subwire","id":980067,"node_id":"MDQ6VXNlcjk4MDA2Nw==","avatar_url":"https://avatars0.githubusercontent.com/u/980067?v=4","gravatar_id":"","url":"https://api.github.com/users/subwire","html_url":"https://github.com/subwire","followers_url":"https://api.github.com/users/subwire/followers","following_url":"https://api.github.com/users/subwire/following{/other_user}","gists_url":"https://api.github.com/users/subwire/gists{/gist_id}","starred_url":"https://api.github.com/users/subwire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/subwire/subscriptions","organizations_url":"https://api.github.com/users/subwire/orgs","repos_url":"https://api.github.com/users/subwire/repos","events_url":"https://api.github.com/users/subwire/events{/privacy}","received_events_url":"https://api.github.com/users/subwire/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-11-01T05:41:39Z","updated_at":"2018-11-01T05:41:39Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"*Disclaimer: The angr suite is maintained by a small team of volunteers. While we cannot guarantee any timeliness for fixes and enhancements, we will do our best. For more real-time help with angr, from us and the community, join our [Slack.](http://angr.io/invite/)*\r\n\r\n---\r\n\r\n**Describe the bug**\r\nIn some Thumb/Cortex-M binaries, the compiler makes heavy use of the `B.W` instruction to do a frameless call.  This happens a lot in various kinds of wrapper functions.\r\nIn certain cases, this will cause functions to become part of other functions when they should not.\r\nIt's pretty clear, from at least the way GCC uses b.w, that this should be the boundary between one function and another.  It's not a call, it's a jump-out, as the thing jumped into will do the real ret.\r\n\r\nHere's an example.  This is `fputs` in the attached binary.  Note that the real fputs is at 0x08002efd, and the B.W at the bottom points to another function _fputs_r, with the real prologue there at 0x08002eb1\r\n\r\n```\r\n0x8002eb1:\tpush\t{r4, r5, lr}\r\n0x8002eb3:\tmov\tr5, r0\r\n0x8002eb5:\tsub\tsp, #0x1c\r\n0x8002eb7:\tmov\tr0, r1\r\n0x8002eb9:\tmov\tr4, r2\r\n0x8002ebb:\tstr\tr1, [sp, #4]\r\n0x8002ebd:\tbl\t#0x8004a61\r\n0x8002ec1:\tadd\tr2, sp, #4\r\n0x8002ec3:\tmovs\tr3, #1\r\n0x8002ec5:\tstr\tr0, [sp, #0x14]\r\n0x8002ec7:\tstr\tr0, [sp, #8]\r\n0x8002ec9:\tstr\tr2, [sp, #0xc]\r\n0x8002ecb:\tstr\tr3, [sp, #0x10]\r\n0x8002ecd:\tcbz\tr5, #0x8002ed3\r\n0x8002ecf:\tldr\tr3, [r5, #0x38]\r\n0x8002ed1:\tcbz\tr3, #0x8002ef5\r\n0x8002ed3:\tldrh\tr3, [r4, #0xc]\r\n0x8002ed5:\tlsls\tr2, r3, #0x12\r\n0x8002ed7:\tbmi\t#0x8002ee7\r\n0x8002ed9:\tldr\tr2, [r4, #0x64]\r\n0x8002edb:\torr\tr3, r3, #0x2000\r\n0x8002edf:\tbic\tr2, r2, #0x2000\r\n0x8002ee3:\tstrh\tr3, [r4, #0xc]\r\n0x8002ee5:\tstr\tr2, [r4, #0x64]\r\n0x8002ee7:\tmov\tr0, r5\r\n0x8002ee9:\tmov\tr1, r4\r\n0x8002eeb:\tadd\tr2, sp, #0xc\r\n0x8002eed:\tbl\t#0x8003445\r\n0x8002ef1:\tadd\tsp, #0x1c\r\n0x8002ef3:\tpop\t{r4, r5, pc}\r\n0x8002ef5:\tmov\tr0, r5\r\n0x8002ef7:\tbl\t#0x8002db1\r\n0x8002efb:\tb\t#0x8002ed3\r\n0x8002efd:\tldr\tr3, [pc, #8]\r\n0x8002eff:\tmov\tr2, r1\r\n0x8002f01:\tmov\tr1, r0\r\n0x8002f03:\tldr\tr0, [r3]\r\n0x8002f05:\tb.w\t#0x8002eb1\r\n```\r\n\r\nIn other words, if we jump to a real prologue (or something we already consider the start of a function) let's not try to merge them.  Heck, if the program uses B.W at all, and the offset is less than 16 bits, this is very much definitely 100% for certain a jumpout. (note that if the size is more than 16 bits, it could be one of those long-jumps chosen by the compiler to jump around in a large function, but who does that??)\r\n\r\nWe can deal with this nicely when there are symbols (because CFG will just use the symbols) but when there aren't, we get it wrong.\r\nAttached are the ELF and stripped ELF versions of the same program that triggers this.\r\nYou may want to be on fix/arm_cfg_party_2 or things will not work\r\n\r\n**Environment Information**\r\nMany common issues are caused by problems with the local Python environment.\r\nBefore submitting, double-check that your versions of all modules in the angr suite (angr, cle, pyvex, ...) are up to date.\r\nPlease include the output of `python -m angr.misc.bug_report` here.\r\n\r\n```\r\n(angr-pypy3) edg@syrinx:~/code/angr-py3k$ python -m angr.misc.bug_report\r\nangr environment report\r\n=============================\r\nDate: 2018-10-31 11:10:56.014870\r\nRunning in virtual environment at /home/edg/.virtualenvs/angr-pypy3\r\nPlatform: linux-x86_64\r\nPython version: 3.5.3 (fdd60ed87e94, Apr 24 2018, 06:10:04)\r\n[PyPy 6.0.0 with GCC 6.2.0 20160901]\r\n######## angr #########\r\nPython found it in /home/edg/code/angr-py3k/angr/angr\r\nPip version angr 8.18.10.1\r\nGit info:\r\n\tCurrent commit 1d2dd00f953e8bc4f09ce7105f9003efce6be49c from branch fix/arm_cfg_party_2\r\n\tChecked out from remote origin: git@github.com:angr/angr\r\n######## ailment #########\r\nPython found it in /home/edg/code/angr-py3k/ailment/ailment\r\nPip version ailment 8.18.10.1\r\nGit info:\r\n\tCurrent commit db8dea661a45044fd32795df86715053f6da12e9 from branch fix/clinic_clinic\r\nCould not resolve tracking branch or remote info!\r\n######## cle #########\r\nPython found it in /home/edg/code/angr-py3k/cle/cle\r\nPip version cle 8.18.10.1\r\nGit info:\r\n\tCurrent commit 70601f8cc273982e9a72fa7a3427b2b37ff2f65e from branch fix/arm_cfg_party_2\r\n\tChecked out from remote origin: git@github.com:angr/cle\r\n######## pyvex #########\r\nPython found it in /home/edg/code/angr-py3k/pyvex/pyvex\r\nPip version pyvex 8.18.10.5\r\nGit info:\r\n\tCurrent commit e82cfd75f106130253140055a69c29eb8afd3b98 from branch fix/arm_cfg_party_2\r\n\tChecked out from remote origin: git@github.com:angr/pyvex\r\n######## claripy #########\r\nPython found it in /home/edg/code/angr-py3k/claripy/claripy\r\nPip version claripy 8.18.10.1\r\nGit info:\r\n\tCurrent commit 49336fa3d3ad0ed941a47ab9ed8edbd86c2d2386 from branch master\r\n\tChecked out from remote origin: git@github.com:angr/claripy\r\n######## archinfo #########\r\nPython found it in /home/edg/code/angr-py3k/archinfo/archinfo\r\nPip version archinfo 8.18.10.5\r\nGit info:\r\n\tCurrent commit 74fa132436858bd5c5c4d8017178e8e2f8222d19 from branch fix/arm_cfg_party_2\r\n\tChecked out from remote origin: git@github.com:angr/archinfo\r\n######## ana #########\r\nPython found it in /home/edg/code/angr-py3k/ana/ana\r\nPip version ana 0.5\r\nGit info:\r\n\tCurrent commit 48657dc6500e33f5818b98003f1f179bfe03e1cc from branch master\r\n\tChecked out from remote origin: https://git:@github.com/zardus/ana\r\n######## z3 #########\r\nPython found it in /home/edg/.virtualenvs/angr-pypy3/site-packages/z3\r\nPip version not found!\r\nCouldn't find git info\r\n######## unicorn #########\r\nPython found it in /home/edg/.virtualenvs/angr-pypy3/site-packages/unicorn\r\nPip version unicorn 1.0.1\r\nCouldn't find git info\r\n######### Native Module Info ##########\r\nangr: <CDLL '/home/edg/code/angr-py3k/angr/angr/lib/angr_native.so', handle 3f51b60 at 0x7efc3aeeeec8>\r\nunicorn: <CDLL '/home/edg/.virtualenvs/angr-pypy3/site-packages/unicorn/lib/libunicorn.so', handle 2550090 at 0x7efc3e3b0368>\r\npyvex: <cffi.api._make_ffi_library.<locals>.FFILibrary object at 0x00007efc3f12a9f8>\r\nz3: <CDLL '/home/edg/.virtualenvs/angr-pypy3/site-packages/z3/lib/libz3.so', handle 5024e80 at 0x7efc39fc2bb8>\r\n\r\n```\r\n\r\n**To Reproduce**\r\n```python\r\nimport angr\r\np = angr.Project(\"a_thing-stripped.elf\")\r\ncfg = p.analyses.CFGFast(resolve_indirect_jumps=True, force_complete_scan=False, normalize=True, symbols=False)\r\nf = p.kb.functions[0x08002efd]\r\nassert len(list(f.blocks)) == 1\r\n[a_thingy.zip](https://github.com/angr/angr/files/2537324/a_thingy.zip)\r\n\r\n```\r\n\r\n**Additional context**\r\nAdd any other context about the problem here.\r\n"}}
{"actor":{"display_login":"subwire"}}