{"action":"created","issue":{"url":"https://api.github.com/repos/angr/angr/issues/161","repository_url":"https://api.github.com/repos/angr/angr","labels_url":"https://api.github.com/repos/angr/angr/issues/161/labels{/name}","comments_url":"https://api.github.com/repos/angr/angr/issues/161/comments","events_url":"https://api.github.com/repos/angr/angr/issues/161/events","html_url":"https://github.com/angr/angr/issues/161","id":166641557,"number":161,"title":"Restoring a base state with call_state","user":{"login":"kevinkoo001","id":4110479,"avatar_url":"https://avatars.githubusercontent.com/u/4110479?v=3","gravatar_id":"","url":"https://api.github.com/users/kevinkoo001","html_url":"https://github.com/kevinkoo001","followers_url":"https://api.github.com/users/kevinkoo001/followers","following_url":"https://api.github.com/users/kevinkoo001/following{/other_user}","gists_url":"https://api.github.com/users/kevinkoo001/gists{/gist_id}","starred_url":"https://api.github.com/users/kevinkoo001/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kevinkoo001/subscriptions","organizations_url":"https://api.github.com/users/kevinkoo001/orgs","repos_url":"https://api.github.com/users/kevinkoo001/repos","events_url":"https://api.github.com/users/kevinkoo001/events{/privacy}","received_events_url":"https://api.github.com/users/kevinkoo001/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2016-07-20T17:50:28Z","updated_at":"2016-07-29T18:26:03Z","closed_at":null,"body":"Hi, I am playing with a base_state param in a call_state. I expected that a base state restores all registers and stacks to the state I previously saved.\r\n\r\nI wrote a very simple program as following:\r\n```\r\nint call_func1(int x) {\r\n\treturn x+100;\r\n}\r\n\r\nint main(int argc, char **argv) {\r\n\tif (argc < 2) {\r\n\t\tprintf(\"Usage: %s [num]\\n\", argv[0]);\r\n\t}\r\n\telse {\r\n\t\tint x = atoi(argv[1]);\r\n\t\tint res = call_func1(x);\r\n\t\tprintf(\"Result: %d\\n\", res);\r\n\t}\r\n\r\n\treturn -1;\r\n}\r\n```\r\n\r\nWith angr, I manually step into a certain state right before calling a call_func1. And I stored the state and used it as a base one. \r\n\r\n```\r\ndef test(target):\r\n        b = angr.Project(target)\r\n        state = b.factory.entry_state(args=[b.filename, '156']) \r\n        p = b.factory.path(state)\r\n        cfg = b.analyses.CFGAccurate(keep_state=True)\r\n        func1 = func_call(cfg, name='call_func1')\r\n\r\n        ############\r\n        # TEST (A) #\r\n        ############\r\n        p.step()\r\n        while len(p.successors) == 1:\r\n            # Find the target function in a trace\r\n            if func1.addr in [x for x in p.addr_trace]:\r\n                #print '**%d steps: %s' % (len(prev.addr_trace), [hex(x) for x in prev.addr_trace])\r\n                base_state = prev.state\r\n                print \">>> (1-1) STATE BEFORE CALLING FUNC1\"\r\n                util.pp_state(prev.state, stack_bytes=32, arch='x86')\r\n                #print '**', prev.state.se.constraints\r\n                break\r\n            prev = p\r\n            p = p.successors[0]\r\n            p.step()\r\n\r\n        # Move forward one more step and check if eax has been changed\r\n        p = prev.successors[0]\r\n        p.step()\r\n\r\n        print \">>> (1-2) STATE AFTER CALLING FUNC1\"\r\n        util.pp_state(p.state, stack_bytes=32, arch='x86')\r\n        print '**%d steps: %s' % (len(p.addr_trace), [hex(x) for x in p.addr_trace])\r\n\r\n        ############\r\n        # TEST (B) #\r\n        ############\r\n        state = b.factory.call_state(func1.addr, '156', base_state=base_state)\r\n        np = b.factory.path(state)\r\n        #np.state.regs.esp += 16  # ADJUSTED ESP ***\r\n\r\n        print \">>> (2-1) STATE BEFORE CALLING FUNC1\"\r\n        util.pp_state(np.state, stack_bytes=32, arch='x86')\r\n        np.step()\r\n        np = np.successors[0]\r\n\r\n        print \">>> (2-2) STATE AFTER CALLING FUNC1\"\r\n        util.pp_state(np.state, stack_bytes=32, arch='x86')\r\n        print '**%d steps: %s' % (len(np.addr_trace), [hex(x) for x in np.addr_trace])\r\n```\r\n\r\nThe following shows the result: before and after calling a function at each case. As expected, the second case walks only a single step to get into func1 (0x804844d), whereas the first case does 25 steps. Comparing the two, most seems to be restored as they are except esp and some added values on stack. The right result is that EAX should hold 0x100 (256=156+100). But because of stack discrepancy, the second holds 0x7ffeff9c. \r\n\r\nIf I adjust the esp in test (B) by adding 16 in this case, it shows the same result. Why is this happening? Am I using the base_state in a wrong way? \r\n\r\n```\r\n>>> (1-1) STATE BEFORE CALLING FUNC1\r\n=========  Registers  =========\r\nEAX: 0x9c\r\nEBX: 0x0\r\nECX: 0x7ffeffb0\r\nEDX: 0x0\r\nESI: 0x2\r\nEDI: 0x0\r\nEBP: 0x7ffeff6c\r\nESP: 0x7ffeff3c\r\nEIP: 0x804844d\r\n==========  Stack  ==========\r\n   0 | 0x7ffeff3c 9e 84 04 08 \r\n   4 | 0x7ffeff40 9c 00 00 00 \r\n   8 | 0x7ffeff44 00 00 00 00 \r\n  12 | 0x7ffeff48 00 a0 04 08 \r\n  16 | 0x7ffeff4c 12 85 04 08 \r\n  20 | 0x7ffeff50 02 00 00 00 \r\n  24 | 0x7ffeff54 b0 ff fe 7f \r\n  28 | 0x7ffeff58 9c 00 00 00 \r\n  32 | 0x7ffeff5c 00 00 00 00 \r\n===============================\r\n\r\n>>> (1-2) STATE AFTER CALLING FUNC1\r\n=========  Registers  =========\r\nEAX: 0x100\r\nEBX: 0x0\r\nECX: 0x7ffeffb0\r\nEDX: 0x0\r\nESI: 0x2\r\nEDI: 0x0\r\nEBP: 0x7ffeff6c\r\nESP: 0x7ffeff40\r\nEIP: 0x804849e\r\n==========  Stack  ==========\r\n   0 | 0x7ffeff40 9c 00 00 00 \r\n   4 | 0x7ffeff44 00 00 00 00 \r\n   8 | 0x7ffeff48 00 a0 04 08 \r\n  12 | 0x7ffeff4c 12 85 04 08 \r\n  16 | 0x7ffeff50 02 00 00 00 \r\n  20 | 0x7ffeff54 b0 ff fe 7f \r\n  24 | 0x7ffeff58 9c 00 00 00 \r\n  28 | 0x7ffeff5c 00 00 00 00 \r\n  32 | 0x7ffeff60 00 00 00 00 \r\n===============================\r\n\r\n**25 steps: ['0x8048350', '0x8048330', '0xc000000L', '0x80484c0', '0x8048380', '0x80484cb', '0x80482d4', '0x8048380', '0x80482dd', '0x80482f2', '0x80484e3', '0x80484f2', '0x8048420L', '0x8048448', '0x80483c0', '0x80483d8', '0x8048512', '0x8048519', '0xc000030', '0x8048458', '0x804847e', '0x8048340', '0xc000010L', '0x804848e', '0x804844d']\r\n\r\n>>> (2-1) STATE BEFORE CALLING FUNC1\r\n=========  Registers  =========\r\nEAX: 0x9c\r\nEBX: 0x0\r\nECX: 0x7ffeffb0\r\nEDX: 0x0\r\nESI: 0x2\r\nEDI: 0x0\r\nEBP: 0x7ffeff6c\r\nESP: 0x7ffeff2c\r\nEIP: 0x804844d\r\n==========  Stack  ==========\r\n   0 | 0x7ffeff2c 40 00 00 0c \r\n   4 | 0x7ffeff30 38 ff fe 7f \r\n   8 | 0x7ffeff34 00 00 00 00 \r\n  12 | 0x7ffeff38 31 35 36 00 \r\n  16 | 0x7ffeff3c 9e 84 04 08 \r\n  20 | 0x7ffeff40 9c 00 00 00 \r\n  24 | 0x7ffeff44 00 00 00 00 \r\n  28 | 0x7ffeff48 00 a0 04 08 \r\n  32 | 0x7ffeff4c 12 85 04 08 \r\n===============================\r\n\r\n>>> (2-2) STATE AFTER CALLING FUNC1\r\n=========  Registers  =========\r\nEAX: 0x7ffeff9c\r\nEBX: 0x0\r\nECX: 0x7ffeffb0\r\nEDX: 0x0\r\nESI: 0x2\r\nEDI: 0x0\r\nEBP: 0x7ffeff6c\r\nESP: 0x7ffeff30\r\nEIP: 0xc000040\r\n==========  Stack  ==========\r\n   0 | 0x7ffeff30 38 ff fe 7f \r\n   4 | 0x7ffeff34 00 00 00 00 \r\n   8 | 0x7ffeff38 31 35 36 00 \r\n  12 | 0x7ffeff3c 9e 84 04 08 \r\n  16 | 0x7ffeff40 9c 00 00 00 \r\n  20 | 0x7ffeff44 00 00 00 00 \r\n  24 | 0x7ffeff48 00 a0 04 08 \r\n  28 | 0x7ffeff4c 12 85 04 08 \r\n  32 | 0x7ffeff50 02 00 00 00 \r\n===============================\r\n\r\n**1 steps: ['0x804844d']\r\n```"},"comment":{"url":"https://api.github.com/repos/angr/angr/issues/comments/236257088","html_url":"https://github.com/angr/angr/issues/161#issuecomment-236257088","issue_url":"https://api.github.com/repos/angr/angr/issues/161","id":236257088,"user":{"login":"ltfish","id":5071575,"avatar_url":"https://avatars.githubusercontent.com/u/5071575?v=3","gravatar_id":"","url":"https://api.github.com/users/ltfish","html_url":"https://github.com/ltfish","followers_url":"https://api.github.com/users/ltfish/followers","following_url":"https://api.github.com/users/ltfish/following{/other_user}","gists_url":"https://api.github.com/users/ltfish/gists{/gist_id}","starred_url":"https://api.github.com/users/ltfish/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ltfish/subscriptions","organizations_url":"https://api.github.com/users/ltfish/orgs","repos_url":"https://api.github.com/users/ltfish/repos","events_url":"https://api.github.com/users/ltfish/events{/privacy}","received_events_url":"https://api.github.com/users/ltfish/received_events","type":"User","site_admin":false},"created_at":"2016-07-29T18:26:03Z","updated_at":"2016-07-29T18:26:03Z","body":"```"}}
{"actor":{"display_login":"ltfish"}}