{ "info": { "author": "Stefan Marsiske", "author_email": "s@ctrlc.hu", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)" ], "description": "* pyrsp\n\npyrsp is a simple wrapper around the [[https://sourceware.org/gdb/current/onlinedocs/gdb/Remote-Protocol.html#Remote-Protocol][GDB Remote serial\nprotocol]]. Currently ARM Cortex M3 devices can be tested with the\n[[https://github.com/gsmcmullin/blackmagic][Blackmagic JTAG debugger]] and i386 and AMD64 qemu targets are supported\nwith qemu. But it should be very simple to support other devices that\nspeak this protocol e.g. buspirates via OpenOCD.\n\nPossible uses: on-device unit testing, fuzzing, reverse engineering.\n\nCurrently you can load/dump memory, set/clear breakpoints, load extra\ninformation (symbols, debug info, .text segment) from an elf file,\ndispatch callbacks on breakpoints, run the binary associated with the\nelf file and display source code associated with addresses.\n\n** depends\n#+BEGIN_EXAMPLE\npip install pyelftools pyserial construct six\n#+END_EXAMPLE\n\n** changes\n*** v0.4 - Thanks <3 Willem, Vasily and Dmitry from ispras.ru \n - python3 support\n - support for debugging multithreading userspace programs\n - more robust qemu debugging\n - much improved tests\n - RLE data handling in protocol\n - support for new construct api\n*** v0.3\n - support for STLink2 devices\n - rudimentary support for dumping fault status and mpu registers\n - fixes\n*** v0.2\n - refactored rsp parts into elf.py and utils.py\n - support for i386 and AMD64 qemu targets\n - timeout in readpkt\n - extract .text directly from elf, do not require .bin\n - support slice operator for memory ops\n - use reported packetSize\n - threadinfo support\n** python example\n#+BEGIN_EXAMPLE python\n from rsp import RSP\n rsp = RSP('/dev/ttyACM0', 'test.elf') # expects test.elf to exist\n rsp.load() # load test.elf into workarea (.text segment)\n\n def br_cb(self):\n # dump regs\n self.dump_regs()\n\n # retrieve some data\n print self.dump(10, 0x20000000)\n\n # set up some data\n self.store(\"aaaaa\", 0x20000000)\n\n # adjust some register\n self.set_reg('r0',0)\n\n # continue and leave breakpoint intact\n self.step_over_br()\n\n # attach breakpoints to callbacks\n rsp.set_br('rsp_finish', rsp.finish_cb)\n rsp.set_br('rsp_dump', rsp.dump_cb)\n rsp.set_br('my_fun', br_cb)\n\n # run binary in mainloop until rsp_finish is hit\n # or some unhandled signal occurs\n rsp.run()\n#+END_EXAMPLE\n should produce the output in the next part, however a similar\n result, barring the custom callback can also be produced by\n running:\n#+BEGIN_EXAMPLE\n$ rsp.py /dev/ttyACM0 test\n#+END_EXAMPLE\n** Example session\n see the code running below in example/\n#+BEGIN_EXAMPLE\nwork area: 0x20019000\nentry: 0x20019001\nAvailable Targets:\nNo. Att Driver\n 1 STM32F4xx\n\n r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc xpsr msp psp\n2001f6b4 00000004 00000000 00000000 2001f6b4 2001f754 00000020 00008000 000000ff 2001fb9c 00000020 00000000 08001f31 2001f6b0 2001902b 20019036 21000003 2001f6b0 00000000\nload test.bin\nverify test OK\nset break: @rsp_finish (0x20019036) OK\nset break: @rsp_dump (0x20019034) OK\nset new pc: @test (0x20019001) OK\ncontinuing\n\n r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc xpsr msp psp\n2001f6a4 00000004 00000000 00000000 2001f6a4 2001f754 00000020 00008000 000000ff 2001fb9c 00000020 00000000 08001f31 2001f6a0 20019013 20019034 21000003 2001f6a0 00000000\nbreakpoint hit: rsp_dump\ntest.c:5 rsp_dump((unsigned char*) &number, 4);\n 00000000 ....\n\n r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc xpsr msp psp\n20019038 0000000b 00000000 00000000 2001f6a4 2001f754 00000020 00008000 000000ff 2001fb9c 00000020 00000000 08001f31 2001f6a0 2001901b 20019034 21000003 2001f6a0 00000000\nbreakpoint hit: rsp_dump\ntest.c:6 rsp_dump((unsigned char*) \"hello world\",11);\n 68656c6c6f20776f 726c64 hello.world\n\n r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc xpsr msp psp\n2001f6a4 00000004 00000000 00000000 2001f6a4 2001f754 00000020 00008000 000000ff 2001fb9c 00000020 00000000 08001f31 2001f6a0 20019027 20019034 21000003 2001f6a0 00000000\nbreakpoint hit: rsp_dump\ntest.c:8 rsp_dump((unsigned char*) &number, 4);\n 55aa55aa U.U.\n\n r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc xpsr msp psp\n2001f6a4 00000004 00000000 00000000 2001f6a4 2001f754 00000020 00008000 000000ff 2001fb9c 00000020 00000000 08001f31 2001f6a0 2001902b 20019036 21000003 2001f6a0 00000000\nbreakpoint hit: rsp_finish\nclear breakpoint: @rsp_dump (0x20019034) OK\nclear breakpoint: @rsp_finish (0x20019036) OK\ncontinuing and detaching\n#+END_EXAMPLE\n** Python API\n#+BEGIN_EXAMPLE python\nRSP(self, port, elffile=None, verbose=False)\n#+END_EXAMPLE\nreads the elf file if given by elffile, connects to the debugging\ndevice specified by port, and initializes itself.\n\n#+BEGIN_EXAMPLE python\nsend(self, data, retries=50)\n#+END_EXAMPLE\nsends data via the RSP protocol to the device\n\n#+BEGIN_EXAMPLE python\nreadpkt(self, timeout=0)\n#+END_EXAMPLE\nblocks until it reads an RSP packet and returns it's data or timeout>0 expires\n\n#+BEGIN_EXAMPLE python\nstore(self, data, addr=None)\n#+END_EXAMPLE\nstores data at addr if given otherwise at beginning of .text segment\naka self.workarea\n\n#+BEGIN_EXAMPLE python\ndump(self, size, addr = None)\n#+END_EXAMPLE\ndumps data from addr if given otherwise at beginning of .text segment\naka self.workarea\n\n#+BEGIN_EXAMPLE python\nfetch(self,data)\n#+END_EXAMPLE\nsends data and returns reply\n\n#+BEGIN_EXAMPLE python\nfetchOK(self,data,ok='OK')\n#+END_EXAMPLE\nsends data and expects success\n\n#+BEGIN_EXAMPLE python\nset_reg(self, reg, val)\n#+END_EXAMPLE\nsets value of register reg to val on device\n\n#+BEGIN_EXAMPLE python\nrefresh_regs(self)\n#+END_EXAMPLE\nloads and caches values of the registers on the device\n\n#+BEGIN_EXAMPLE python\ndump_regs(self)\n#+END_EXAMPLE\nrefreshes and dumps registers via stdout\n\n#+BEGIN_EXAMPLE python\nconnect(self)\n#+END_EXAMPLE\nImplements device specific connection procedure, e.g. attaches to\nblackmagic jtag debugger in swd mode\n\n#+BEGIN_EXAMPLE python\nrun(self, start=None)\n#+END_EXAMPLE\nsets pc to start if given or to entry address from elf header, passes\ncontrol to the device and handles breakpoints\n\n#+BEGIN_EXAMPLE python\nhandle_br(self)\n#+END_EXAMPLE\ndumps register on breakpoint/signal, continues if unknown,\notherwise it calls the appropriate callback.\n\n#+BEGIN_EXAMPLE python\nset_br(self, sym, cb, quiet=False)\n#+END_EXAMPLE\nsets a breakpoint at symbol sym, and install callback cb for it\n\n#+BEGIN_EXAMPLE python\ndel_br(self, addr, quiet=False)\n#+END_EXAMPLE\ndeletes breakpoint at address addr\n\n#+BEGIN_EXAMPLE python\nfinish_cb(self)\n#+END_EXAMPLE\nfinal breakpoint, if hit it deletes all breakpoints, continues running\nthe cpu, and detaches from the debugging device\n\n#+BEGIN_EXAMPLE python\nget_src_line(self, addr)\n#+END_EXAMPLE\nreturns the source-code line associated with address addr\n\n#+BEGIN_EXAMPLE python\ndump_cb(self)\n#+END_EXAMPLE\nrsp_dump callback, hit if rsp_dump is called. Outputs to stdout the\nsource line, and a hexdump of the memory pointed by $r0 with a size of\n$r1 bytes. Then it resumes running.\n\n#+BEGIN_EXAMPLE python\nload(self, verify)\n#+END_EXAMPLE\nloads binary belonging to elf to beginning of .text segment (alias\nself.workarea), and if verify is set read it back and check if it\nmatches with the uploaded binary.\n\n#+BEGIN_EXAMPLE python\ncall(self, start=None, finish='rsp_finish', dump='rsp_dump', verify=True)\n#+END_EXAMPLE\n 1. Loads the .text segment given by self.elf into the device at the workarea (.text seg) of the device.\n 2. and starts execution at the function specified by start or elf e_entry.\n 3. After the breakpoint of rsp_dump is hit, r1 bytes are dumped from the buffer pointed to by r0.\n 4. After the breakpoint of rsp_finish is hit, it removes all break points, and detaches\n\n#+BEGIN_EXAMPLE python\nget_thread_info()\n#+END_EXAMPLE\nreturns a tuple consisting of:\n - current thread id,\n - extra thread info,\n - list of all threads\n\n#+BEGIN_EXAMPLE python\nrsp[0:100]\n#+END_EXAMPLE\nreturns 1st 100 bytes from memory\n\n#+BEGIN_EXAMPLE python\nrsp[100]=\"hello world\"\n#+END_EXAMPLE\nStores the string \"hello world\" at address 100 in memory\n\n** trigger functions for breakpoints\nIf you run your code on an ARMv7, you can call and link the code in\nrsp.s and rsp.h. It only costs you 4 bytes.\n\nIf you use C language for instrumentation GCC might optimize out very\nsimple finish functions, to avoid this you can use the example below:\n#+BEGIN_EXAMPLE\n__attribute__ ((noinline)) void rsp_finish(void) {\n while(1);\n}\n__attribute__ ((noinline)) void rsp_dump(void) {\n __asm__(\"nop;\");\n}\n#+END_EXAMPLE\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/stef/pyrsp", "keywords": "GDB remote debugging JTAG embedded scripting", "license": "AGPLv3", "maintainer": "", "maintainer_email": "", "name": "pyrsp", "package_url": "https://pypi.org/project/pyrsp/", "platform": "", "project_url": "https://pypi.org/project/pyrsp/", "project_urls": { "Homepage": "https://github.com/stef/pyrsp" }, "release_url": "https://pypi.org/project/pyrsp/0.4.0.1/", "requires_dist": null, "requires_python": "", "summary": "simple GDB remote serial protocol wrapper", "version": "0.4.0.1" }, "last_serial": 4925735, "releases": { "0.2.1": [ { "comment_text": "", "digests": { "md5": "ddb7a3c8705419778ea0f73615cb5961", "sha256": "3099d4595f54926eaaae8f2073990bd10d0334d2845fe9feadc27bb7fdf67b01" }, "downloads": -1, "filename": "pyrsp-0.2.1-py2.7.egg", "has_sig": true, "md5_digest": "ddb7a3c8705419778ea0f73615cb5961", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 23679, "upload_time": "2014-09-22T21:18:08", "url": "https://files.pythonhosted.org/packages/e5/20/1ce2b3389bdf34ba581660043cee3f38a0da293d083fa2b0cecdde229fed/pyrsp-0.2.1-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "cc0e9523b767e3b9f83cb7ceeebfe861", "sha256": "c6f6dc3a13b123bf35f4e3bdfb9a875281fb2243eeb8c1e09cd20fb8b06acedf" }, "downloads": -1, "filename": "pyrsp-0.2.1.tar.gz", "has_sig": true, "md5_digest": "cc0e9523b767e3b9f83cb7ceeebfe861", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10401, "upload_time": "2014-09-22T21:17:54", "url": "https://files.pythonhosted.org/packages/22/36/6d096bd0c2179523f0b8738466faa6779f6a1ffb4bf77855c405362e076a/pyrsp-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "624aa2b6741ec2f0d3f7e041a345d061", "sha256": "59e9094f3a1095c119f35ff3f1e9b80a91a73a7fe160411935cec16e3f38d819" }, "downloads": -1, "filename": "pyrsp-0.2.2-py2.7.egg", "has_sig": true, "md5_digest": "624aa2b6741ec2f0d3f7e041a345d061", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 23689, "upload_time": "2014-09-22T21:19:56", "url": "https://files.pythonhosted.org/packages/b7/38/d6367d78c7bcf7f2e7c4848163430eb4c5e431383581654cf09813649d69/pyrsp-0.2.2-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "aeaa89bba412d62d56e45a836a55e695", "sha256": "d986a43a12ce1f9d658504c0af204cc91ef6f2fd20c03810ff2e4ef336afa37e" }, "downloads": -1, "filename": "pyrsp-0.2.2.tar.gz", "has_sig": true, "md5_digest": "aeaa89bba412d62d56e45a836a55e695", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11039, "upload_time": "2014-09-22T21:19:42", "url": "https://files.pythonhosted.org/packages/c6/c8/449c0c535a22332bbf9186a59dd1db8424d1ffd1578d13eee692bf041ab8/pyrsp-0.2.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "fb639b483474e3e71290dcaec9f18a1d", "sha256": "9120b09a203302bfb03489bcb6d7d7f591f78d0fa4452d6c7e0e9a8390c1ed12" }, "downloads": -1, "filename": "pyrsp-0.3-py2.7.egg", "has_sig": true, "md5_digest": "fb639b483474e3e71290dcaec9f18a1d", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 29759, "upload_time": "2016-04-14T19:36:47", "url": "https://files.pythonhosted.org/packages/b9/0c/5f3b29960e790eacfa9b1553c9d2ca02c6e25c94835fc74994fd3d177e30/pyrsp-0.3-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "96ab8f31200c4a22d17c127581f69ecd", "sha256": "57ba3c22b550bc544cbd58c1cd29052f75a8e15fb1b75eac732c9b0a9802c73c" }, "downloads": -1, "filename": "pyrsp-0.3.tar.gz", "has_sig": true, "md5_digest": "96ab8f31200c4a22d17c127581f69ecd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13319, "upload_time": "2016-04-14T19:36:22", "url": "https://files.pythonhosted.org/packages/99/8e/76c1bf770f3be383e7d0b7472ec275eed23c22c7700e02f3a8d171e20003/pyrsp-0.3.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "b3b83436650c859e14151b1f098dac26", "sha256": "9f6701c98eaa466a1d6fbf6209a295cc3e4761da3f52e2abdad0ab8ede0c8d7f" }, "downloads": -1, "filename": "pyrsp-0.3.1-py2.7.egg", "has_sig": true, "md5_digest": "b3b83436650c859e14151b1f098dac26", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 29812, "upload_time": "2016-04-14T19:39:42", "url": "https://files.pythonhosted.org/packages/f0/87/5558813c54c950e11d4931fc713801c7cd33fb11e8f1aca91b82668b67ac/pyrsp-0.3.1-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "e7e99837c4c74d282d58697d854cd1dd", "sha256": "183476fae33e636e72a8c510f4edee943b9ec35816093ad223317fe2326a523c" }, "downloads": -1, "filename": "pyrsp-0.3.1.tar.gz", "has_sig": true, "md5_digest": "e7e99837c4c74d282d58697d854cd1dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13388, "upload_time": "2016-04-14T19:39:30", "url": "https://files.pythonhosted.org/packages/f9/ed/2ddfb2bda1b5f6ca556f19a6269bc67b696cfea501ece987fbb9690e92ce/pyrsp-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "3172906f3f249269340f98ab161017fb", "sha256": "a4df55dd7538620dae11b77ff0c7a2bdf714d637d66753f4c3991ac333c65ed8" }, "downloads": -1, "filename": "pyrsp-0.3.2-py2.7.egg", "has_sig": false, "md5_digest": "3172906f3f249269340f98ab161017fb", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 30838, "upload_time": "2016-11-13T18:18:42", "url": "https://files.pythonhosted.org/packages/8c/5d/8e6d55f6e517c11919744878352c1d330ccb4d285cdee32b8d7d2b39c49a/pyrsp-0.3.2-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "30d9245de3227f9a597162511ddb0745", "sha256": "7017894681c81f8271da578fd0fd9c424968a960a7c69d778cfd9598e13aefdc" }, "downloads": -1, "filename": "pyrsp-0.3.2.tar.gz", "has_sig": false, "md5_digest": "30d9245de3227f9a597162511ddb0745", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13736, "upload_time": "2016-11-13T18:18:33", "url": "https://files.pythonhosted.org/packages/35/c6/be0ab96dbd4828de779da996fd6b0e05cee246ec97b8394787c6f1d9ce36/pyrsp-0.3.2.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "66305e6205001c811384f4bcc8f2511c", "sha256": "8d80eadf7bf92cf5c4f00dc545d5b5fbfc78e0b06d5df87dc38d263375c6885a" }, "downloads": -1, "filename": "pyrsp-0.4.tar.gz", "has_sig": true, "md5_digest": "66305e6205001c811384f4bcc8f2511c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20236, "upload_time": "2019-03-11T15:21:05", "url": "https://files.pythonhosted.org/packages/a2/d5/8882913869db3c42563b40a3c2c40a1a3899193da3f7e034f2024d27710a/pyrsp-0.4.tar.gz" } ], "0.4.0.1": [ { "comment_text": "", "digests": { "md5": "4ff6b89f96658effe6c5d2fc5b71ef01", "sha256": "346e1019feb79edc98ad113eecd10e5983bf394dcaa46001f456f4cb00484606" }, "downloads": -1, "filename": "pyrsp-0.4.0.1.tar.gz", "has_sig": true, "md5_digest": "4ff6b89f96658effe6c5d2fc5b71ef01", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20385, "upload_time": "2019-03-11T15:30:45", "url": "https://files.pythonhosted.org/packages/98/a0/a38194b5ba6e6f602e9aaaedd57b389f09feb7345d8ec6054a67960c1c95/pyrsp-0.4.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4ff6b89f96658effe6c5d2fc5b71ef01", "sha256": "346e1019feb79edc98ad113eecd10e5983bf394dcaa46001f456f4cb00484606" }, "downloads": -1, "filename": "pyrsp-0.4.0.1.tar.gz", "has_sig": true, "md5_digest": "4ff6b89f96658effe6c5d2fc5b71ef01", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20385, "upload_time": "2019-03-11T15:30:45", "url": "https://files.pythonhosted.org/packages/98/a0/a38194b5ba6e6f602e9aaaedd57b389f09feb7345d8ec6054a67960c1c95/pyrsp-0.4.0.1.tar.gz" } ] }