{"id":321531,"date":"2021-04-16T03:00:07","date_gmt":"2021-04-16T03:00:07","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=321531"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=321531","title":{"rendered":"\u041f\u0438\u0448\u0435\u043c \u043f\u043b\u0430\u0433\u0438\u043d \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0434\u043b\u044f SNES \u0438\u0433\u0440 \u0432 IDA v7"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xf\/3x\/of\/xf3xofalflutqv7ki1kwbau5onq.png\"><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e,<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u044f \u043e\u0447\u0435\u043d\u044c \u0441\u0442\u0430\u0440\u0430\u044f \u043c\u0435\u0447\u0442\u0430 \u0441\u0431\u044b\u043b\u0430\u0441\u044c \u2014 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043c\u043e\u0434\u0443\u043b\u044c-\u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c SNES (<em>Super Nintendo<\/em>) \u0438\u0433\u0440\u044b \u043f\u0440\u044f\u043c\u043e \u0432 <code>IDA<\/code>! \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a \u044f \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b, &quot;\u043f\u0440\u043e\u0448\u0443 \u043f\u043e\u0434 \u043a\u0430\u0442&quot; (\u043a\u0430\u043a \u0442\u0443\u0442 \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c).<a name=\"habracut\"><\/a><\/p>\n<p>  <\/p>\n<h1 id=\"vvedenie\">\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<p>\u042f \u0434\u0430\u0432\u043d\u043e \u0443\u0432\u043b\u0435\u043a\u0430\u044e\u0441\u044c \u0440\u0435\u0432\u0435\u0440\u0441-\u0438\u043d\u0436\u0438\u043d\u0438\u0440\u0438\u043d\u0433\u043e\u043c. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0431\u0431\u0438, \u0437\u0430\u0442\u0435\u043c \u0441\u0442\u0430\u043b\u043e \u0440\u0430\u0431\u043e\u0442\u043e\u0439 (\u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0445\u043e\u0431\u0431\u0438 \u043d\u0438\u043a\u0443\u0434\u0430 \u043d\u0435 \u0434\u0435\u043b\u043e\u0441\u044c). \u0422\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0435 &quot;<em>\u0432\u0441\u0451 \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u043e<\/em>&quot;, \u0430 \u0434\u043e\u043c\u0430 \u2014 \u044d\u0442\u043e \u0431\u0430\u043b\u043e\u0432\u0441\u0442\u0432\u043e \u0432 \u0432\u0438\u0434\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0433\u0440 \u043f\u043e\u0434 \u0440\u0435\u0442\u0440\u043e-\u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438: <code>Sega Mega Drive \/ Genesis<\/code>, <code>PS1<\/code>, <code>AmigaOS<\/code>. \u0417\u0430\u0434\u0430\u0447\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f: \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u0433\u0440\u0430, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u0436\u0430\u0442\u0438\u0435 \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u044c \u0435\u0433\u043e, \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0443\u0440\u043e\u0432\u0435\u043d\u044c, \u043a\u0430\u043a \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432\u0440\u0430\u0433\u0438 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438 \u0442.\u0434.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430 \u0442\u043e \u0432\u0440\u0435\u043c\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043a\u0430\u043a \u044f \u043d\u0430\u0447\u0430\u043b \u044d\u0442\u0438\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f, \u043c\u043d\u043e\u044e \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0434\u043e\u0431\u043d\u044b\u0445 \u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0445\u043e\u0442\u0435\u043b \u0440\u0435\u0432\u0435\u0440\u0441\u0438\u0442\u044c \u0438\u0433\u0440\u044b \u043d\u0430 \u0421\u0435\u0433\u0443, \u0421\u043e\u043d\u044c\u043a\u0443, \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.<\/p>\n<p>  <\/p>\n<p>\u041c\u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u0440\u0435\u0432\u0435\u0440\u0441\u0438\u0442\u044c \u043e\u0434\u0438\u043d \u043e\u0447\u0435\u043d\u044c \u043a\u0440\u0443\u0442\u043e\u0439 shoot&#8217;em-up: <em>Thunder Force 3<\/em> (\u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u0439 \u0438\u0433\u0440\u0435 \u044f \u0438 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043b\u0441\u044f \u0441 \u0418\u0434\u043e\u0439). \u042f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0443\u0440\u043e\u0432\u043d\u0435\u0439, \u0440\u0430\u0437\u0440\u0435\u0432\u0435\u0440\u0441\u0438\u043b \u0438\u0433\u0440\u0443 \u0434\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 \u043d\u0430 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0435, \u0438 \u0432\u0441\u0451 \u044d\u0442\u043e \u043f\u043e\u043f\u0443\u0442\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u0438 \u0443\u043b\u0443\u0447\u0448\u0430\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u0438 \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u043b \u0434\u0430\u043d\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u2014 \u043f\u043b\u0430\u0433\u0438\u043d-\u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u0441\u0435\u0433\u043e\u0432\u0441\u043a\u0438\u0445 \u0440\u043e\u043c\u043e\u0432 \u0434\u043b\u044f IDA, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043d\u0430\u0437\u0432\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u043e \u2014 <a href=\"https:\/\/github.com\/lab313ru\/smd_ida_tools2\" rel=\"nofollow noopener noreferrer\">Gensida<\/a> (\u0442.\u043a. \u0432 \u043e\u0441\u043d\u043e\u0432\u0435 \u043b\u0435\u0436\u0430\u043b \u043e\u0434\u0438\u043d \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440 \u044d\u0442\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b GENS, \u0430 \u0442\u043e\u0447\u043d\u0435\u0435 \u0435\u0433\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f).<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/1i\/zp\/uz\/1izpuzybdgzqig8a197wbamiwza.png\"><\/p>\n<p>  <\/p>\n<blockquote><p>\u0411\u0435\u0437 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430 \u0441 \u043e\u0442\u043b\u0430\u0434\u043a\u043e\u0439 \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043f\u043b\u0430\u0433\u0438\u043d, \u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0441 \u043d\u0443\u043b\u044f, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c.<\/p><\/blockquote>\n<p>\u0421\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u044f \u0443\u0437\u043d\u0430\u043b, \u0447\u0442\u043e \u0443 <code>Thunder Force 3<\/code> \u0435\u0441\u0442\u044c \u0438 \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u043b\u044f SNES \u2014 <code>Thunder Spirits<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u043e\u0432\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435. \u0422\u0430\u043a \u0432\u043e\u0442, \u043c\u043d\u0435 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0451 \u044d\u0442\u043e \u043d\u0430 \u0421\u0435\u0433\u0443, \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0432 \u0438\u0433\u0440\u0443. \u041d\u043e, \u0437\u043d\u0430\u043d\u0438\u0439 \u043a\u0430\u043a \u043e \u0441\u0430\u043c\u043e\u0439 Super Nintendo, \u0442\u0430\u043a \u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0435\u0451 \u0440\u0435\u0432\u0435\u0440\u0441\u0438\u0442\u044c, \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u0431\u044b\u043b\u043e. \u042f \u043f\u043e\u0448\u0451\u043b \u0433\u0443\u0433\u043b\u0438\u0442\u044c \u0438 \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e\u2026 \u043a\u0430\u043a-\u0442\u043e \u0432\u0441\u0451 \u043f\u043b\u043e\u0445\u043e \u0441 \u043e\u0442\u043b\u0430\u0434\u043a\u043e\u0439 \u0443 &quot;\u0441\u0435\u0433\u0438 \u043f\u043e\u0434\u043e\u0440\u043e\u0436\u0435&quot;. \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u0441\u0435\u0433\u043e \u0414\u0412\u0410 (!) \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430 SNES \u0441 \u043e\u0442\u043b\u0430\u0434\u043a\u043e\u0439, \u0438 \u0443 \u043e\u0434\u043d\u043e\u0433\u043e \u043d\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432, \u0430 \u0432\u0442\u043e\u0440\u043e\u0439\u2026 \u0432\u0442\u043e\u0440\u043e\u0439 \u0438\u043c\u0435\u0435\u0442 <a href=\"https:\/\/github.com\/devinacker\/bsnes-plus\" rel=\"nofollow noopener noreferrer\">\u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0431\u043e\u0433\u0438\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/a>, \u0447\u0442\u043e \u044f \u0431\u043e\u044f\u043b\u0441\u044f \u0434\u0430\u0436\u0435 \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. <\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043e\u0432\u043b\u0430\u0434\u0435\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0437\u043d\u0430\u043d\u0438\u044f\u043c\u0438 \u0438 \u0443\u043c\u0435\u043d\u0438\u044f\u043c\u0438, \u0438 \u043f\u0435\u0440\u0435\u0431\u043e\u0440\u043e\u0432 \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u043d\u0435 \u0432\u0432\u044f\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0442\u0430\u043a\u043e\u0439 \u0443\u0436\u0430\u0441\u043d\u044b\u0439 \u043a\u043e\u0434 (\u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430), \u044f \u0441\u043c\u043e\u0433 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438 <a href=\"https:\/\/github.com\/lab313ru\/snesida\" rel=\"nofollow noopener noreferrer\">Snesida<\/a> \u2014 \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a SNES \u0440\u043e\u043c\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0434 IDA. \u0418, \u044f \u0441\u0447\u0438\u0442\u0430\u044e, \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u043e \u0443\u0436 \u043d\u0430\u0441\u0442\u0430\u043b \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u044f \u0433\u043e\u0442\u043e\u0432 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435-\u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0432\u0451\u0440\u0441\u0435\u0440\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430.<\/p>\n<p>  <\/p>\n<h1 id=\"chto-nam-potrebuetsya\">\u0427\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f<\/h1>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043f\u043b\u0430\u0433\u0438\u043d-\u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u043f\u043e\u0434 \u0418\u0434\u0443, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f:<\/p>\n<p>  <\/p>\n<ol>\n<li>IDA v7.x<\/li>\n<li>IDA SDK<\/li>\n<li>\u042d\u043c\u0443\u043b\u044f\u0442\u043e\u0440-\u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a (\u043c\u043e\u0436\u043d\u043e \u0438 \u0431\u0435\u0437 \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u0438\u043b\u0438\u0442\u044c)<\/li>\n<li>Thrift (\u0434\u0430, \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u0435\u0433\u043e \u0437\u0430 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438 RPC \u043f\u0440\u044f\u043c\u043e &quot;\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438&quot;)<\/li>\n<li>\u0423\u043c\u0435\u043d\u0438\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 C++<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0414\u0443\u043c\u0430\u044e, \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439. \u0415\u0441\u043b\u0438 \u0447\u0435\u0433\u043e-\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0443 \u0432\u0430\u0441 \u043d\u0435\u0442, \u0442\u043e \u043f\u043b\u0430\u0433\u0438\u043d \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u0443\u0432\u044b.<\/p>\n<p>  <\/p>\n<h1 id=\"a-teper-pishem-kod\">\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434<\/h1>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043d\u0430\u0447\u0430\u0442\u044c, \u0441\u043e\u0432\u0435\u0442\u0443\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441\u043e \u0441\u0442\u0430\u0442\u044c\u0451\u0439 &quot;<a href=\"https:\/\/habr.com\/ru\/post\/435002\/\">\u041c\u043e\u0434\u0435\u0440\u043d\u0438\u0437\u0430\u0446\u0438\u044f IDA Pro. \u041e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u0434\u043b\u044f Sega Mega Drive (\u0447\u0430\u0441\u0442\u044c 2)<\/a>&quot;, \u0442.\u043a. \u043c\u043d\u043e\u0433\u0438\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c\u0441\u044f, \u043d\u043e \u0431\u0443\u0434\u0443\u0442 \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u043e\u0432\u044b\u0435 (\u0442.\u043a. SDK \u0418\u0434\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0438 \u0442\u043e, \u0447\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0440\u0430\u043d\u044c\u0448\u0435, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u043e).<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0434\u043b\u044f IDA \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430-\u0448\u0430\u0431\u043b\u043e\u043d\u0430. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e Visual Studio (\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0441\u0430\u043c\u043e\u0439 \u0441\u0432\u0435\u0436\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0435\u0440\u0441\u0438\u044f 2019).<\/p>\n<p>  <\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0421\u0442\u0443\u0434\u0438\u044e, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 DLL, \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0443\u0442\u0438 \u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u0445 Linker \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><em>d:\\idasdk76\\lib\\x64_win_vc_32\\<\/em> \u2014 \u044d\u0442\u043e \u0434\u043b\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 32-\u0431\u0438\u0442\u043d\u044b\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438 (\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 <code>ida.exe<\/code>)<\/li>\n<li><em>d:\\idasdk76\\lib\\x64_win_vc_64\\<\/em> \u2014 \u044d\u0442\u043e \u0434\u043b\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 64-\u0431\u0438\u0442\u043d\u044b\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438 (\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 <code>ida64.exe<\/code>)<\/li>\n<li>\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043d\u0435 Windows \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 Visual Studio, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u043f\u0430\u043f\u043a\u0438 \u0432 <em>d:\\idasdk76\\lib\\<\/em><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412 \u043b\u0438\u043d\u043a\u0443\u0435\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c <code>ida.lib<\/code>. \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043f\u0443\u0441\u0442\u043e\u0439 cpp-\u0444\u0430\u0439\u043b, \u0447\u0442\u043e\u0431\u044b VS \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 C\/C++ \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li><em>d:\\idasdk76\\include\\<\/em> \u2014 \u0432 \u0441\u043f\u0438\u0441\u043a\u043e\u043a \u043f\u0443\u0442\u0435\u0439 \u043a \u0438\u043d\u043a\u043b\u0443\u0434\u0430\u043c<\/li>\n<li>\u041c\u0435\u043d\u044f\u0435\u043c <code>\/MDd<\/code> \u0438 <code>\/MD<\/code> \u043d\u0430 <code>\/MTd<\/code> \u0438 <code>\/MT<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u0445 <code>Code Generation<\/code> \u2014 \u043f\u0440\u043e\u0441\u0442\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u043b\u0438\u0448\u043d\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b<\/li>\n<li><code>__NT__;__IDP__;__X64__;<\/code> \u2014 \u0432 <code>Preprocessor Definitions<\/code> \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430<\/li>\n<li><code>__EA64__;<\/code> \u2014 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c \u0444\u043b\u0430\u0433\u0430\u043c, \u0435\u0441\u043b\u0438 \u043f\u043b\u0430\u0433\u0438\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 64-\u0431\u0438\u0442\u043d\u044b\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438<\/li>\n<li>\u0423\u0431\u0438\u0440\u0430\u0435\u043c <code>SDL Checks<\/code> \u2014 \u0441 \u043d\u0438\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0421 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u043e\u0439 \u0432\u0440\u043e\u0434\u0435 \u0431\u044b \u0432\u0441\u0451. \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0447\u043d\u0451\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434.<\/p>\n<p>  <\/p>\n<h3 id=\"plagin\">\u041f\u043b\u0430\u0433\u0438\u043d<\/h3>\n<p>  <\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043a\u0430\u043a \u0432\u044b \u0443\u0436\u0435, \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c, \u043f\u043e\u043d\u044f\u043b\u0438, \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u0434\u043b\u044f \u0418\u0434\u044b \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043f\u043b\u0430\u0433\u0438\u043d, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0435\u0439 \u043a\u0430\u043a-\u0442\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0438\u0448\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">ida_plugin.cpp<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &lt;ida.hpp&gt; #include &lt;idp.hpp&gt; #include &lt;dbg.hpp&gt; #include &lt;loader.hpp&gt;  #include &quot;ida_plugin.h&quot;  extern debugger_t debugger;  static bool plugin_inited;  static bool init_plugin(void) {     return (ph.id == PLFM_65C816); }  static void print_version() {     static const char format[] = NAME &quot; debugger plugin v%s;\\nAuthor: DrMefistO [Lab 313] &lt;newinferno@gmail.com&gt;.&quot;;     info(format, VERSION);     msg(format, VERSION); }  static plugmod_t* idaapi init(void) {     if (init_plugin()) {         dbg = &amp;debugger;         plugin_inited = true;          print_version();         return PLUGIN_KEEP;     }      return PLUGIN_SKIP; }  static void idaapi term(void) {     if (plugin_inited) {         plugin_inited = false;     } }  static bool idaapi run(size_t arg) {     return false; }  char comment[] = NAME &quot; debugger plugin by DrMefistO.&quot;;  char help[] =     NAME &quot; debugger plugin by DrMefistO.\\n&quot;     &quot;\\n&quot;     &quot;This module lets you debug SNES roms in IDA.\\n&quot;;  plugin_t PLUGIN = {     IDP_INTERFACE_VERSION,     PLUGIN_PROC | PLUGIN_DBG,     init,     term,     run,     comment,     help,     NAME &quot; debugger plugin&quot;,     &quot;&quot; };<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448 \u043f\u043b\u0430\u0433\u0438\u043d, \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>dbg<\/code>, \u0442.\u043a. \u043c\u044b \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a, \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u0439 <code>PLFM_65C816<\/code> (\u0432 \u043c\u043e\u0451\u043c \u0441\u043b\u0443\u0447\u0430\u0435). \u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u0440\u043e \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u0434\u043b\u044f \u0421\u0435\u0433\u0438.<\/p>\n<p>  <\/p>\n<p>\u0421\u043b\u0435\u0434\u043e\u043c \u0438\u0434\u0451\u0442 <code>ida_plugin.h<\/code>. \u0422\u0443\u0442 \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e \u2014 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u0434\u043b\u044f cpp-\u0444\u0430\u0439\u043b\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#pragma once  #define NAME &quot;snesida&quot; #define VERSION &quot;1.0&quot;<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"kod-samogo-otladchika\">\u041a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u0430<\/h3>\n<p>  <\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043f\u043e\u043a\u0430 \u0443 \u043d\u0430\u0441 \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0434\u0435\u044f \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u0430, \u0438 \u043c\u044b \u0435\u0439 \u0433\u043e\u0440\u0438\u043c, \u0432\u0441\u0451 \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c, \u044d\u0442\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0442\u044c. \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0435\u0441\u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0451\u0439, \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u0434\u0435 \u0438 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u0432 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0438\u0442\u0430\u0435\u043c \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">ida_debug.cpp<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &lt;ida.hpp&gt; #include &lt;dbg.hpp&gt; #include &lt;auto.hpp&gt; #include &lt;deque&gt; #include &lt;mutex&gt;  #include &quot;ida_plugin.h&quot; #include &quot;ida_debmod.h&quot; #include &quot;ida_registers.h&quot;  static ::std::mutex list_mutex; static eventlist_t events;  static const char* const p_reg[] = {     &quot;CF&quot;,     &quot;ZF&quot;,     &quot;IF&quot;,     &quot;DF&quot;,     &quot;XF&quot;,     &quot;MF&quot;,     &quot;VF&quot;,     &quot;NF&quot;, };  static register_info_t registers[] = {     {&quot;A&quot;, 0, RC_CPU, dt_word, NULL, 0},     {&quot;X&quot;, 0, RC_CPU, dt_word, NULL, 0},     {&quot;Y&quot;, 0, RC_CPU, dt_word, NULL, 0},      {&quot;D&quot;, 0, RC_CPU, dt_word, NULL, 0},     {&quot;DB&quot;, 0, RC_CPU, dt_byte, NULL, 0},      {&quot;PC&quot;, REGISTER_IP | REGISTER_ADDRESS, RC_CPU, dt_dword, NULL, 0},   {&quot;S&quot;, REGISTER_SP | REGISTER_ADDRESS, RC_CPU, dt_word, NULL, 0},      {&quot;P&quot;, REGISTER_READONLY, RC_CPU, dt_byte, p_reg, 0xFF},   {&quot;m&quot;, REGISTER_READONLY, RC_CPU, dt_byte, NULL, 0},   {&quot;x&quot;, REGISTER_READONLY, RC_CPU, dt_byte, NULL, 0},     {&quot;e&quot;, REGISTER_READONLY, RC_CPU, dt_byte, NULL, 0}, };  static const char* register_classes[] = {     &quot;General Registers&quot;,     NULL };  static drc_t idaapi init_debugger(const char* hostname, int portnum, const char* password, qstring* errbuf) {   return DRC_OK; }  static drc_t idaapi term_debugger(void) {   return DRC_OK; }  static drc_t s_get_processes(procinfo_vec_t* procs, qstring* errbuf) {   process_info_t info;   info.name.sprnt(&quot;bsnes&quot;);   info.pid = 1;   procs-&gt;add(info);    return DRC_OK; }  static drc_t idaapi s_start_process(const char* path,   const char* args,   const char* startdir,   uint32 dbg_proc_flags,   const char* input_path,   uint32 input_file_crc32,   qstring* errbuf = NULL) {   ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);   events.clear();    return DRC_OK; }  static drc_t idaapi prepare_to_pause_process(qstring* errbuf) {   return DRC_OK; }  static drc_t idaapi emul_exit_process(qstring* errbuf) {   return DRC_OK; }  static gdecode_t idaapi get_debug_event(debug_event_t* event, int timeout_ms) {   while (true)   {     ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);      \/\/ are there any pending events?     if (events.retrieve(event))     {       return events.empty() ? GDE_ONE_EVENT : GDE_MANY_EVENTS;     }     if (events.empty())       break;   }   return GDE_NO_EVENT; }  static drc_t idaapi continue_after_event(const debug_event_t* event) {   dbg_notification_t req = get_running_notification();   switch (event-&gt;eid())   {   case PROCESS_SUSPENDED:     break;   case PROCESS_EXITED:     break;   }    return DRC_OK; }  static drc_t idaapi s_set_resume_mode(thid_t tid, resume_mode_t resmod) \/\/ Run one instruction in the thread {   switch (resmod)   {   case RESMOD_INTO:    \/\/\/&lt; step into call (the most typical single stepping)     break;   case RESMOD_OVER:    \/\/\/&lt; step over call     break;   }    return DRC_OK; }  static drc_t idaapi read_registers(thid_t tid, int clsmask, regval_t* values, qstring* errbuf) {   if (clsmask &amp; RC_CPU)   {      }      return DRC_OK; }  static drc_t idaapi write_register(thid_t tid, int regidx, const regval_t* value, qstring* errbuf) {   if (regidx &gt;= static_cast&lt;int&gt;(SNES_REGS::SR_PC) &amp;&amp; regidx &lt;= static_cast&lt;int&gt;(SNES_REGS::SR_EFLAG)) {      }      return DRC_OK;  }  static drc_t idaapi get_memory_info(meminfo_vec_t&amp; areas, qstring* errbuf) {   memory_info_t info;    info.start_ea = 0x0000;   info.end_ea = 0x01FFF;   info.sclass = &quot;STACK&quot;;   info.bitness = 0;   info.perm = SEGPERM_READ | SEGPERM_WRITE;   areas.push_back(info);    \/\/ Don't remove this loop   for (int i = 0; i &lt; get_segm_qty(); ++i)   {     segment_t* segm = getnseg(i);      info.start_ea = segm-&gt;start_ea;     info.end_ea = segm-&gt;end_ea;      qstring buf;     get_segm_name(&amp;buf, segm);     info.name = buf;      get_segm_class(&amp;buf, segm);     info.sclass = buf;      info.sbase = get_segm_base(segm);      info.perm = segm-&gt;perm;     info.bitness = segm-&gt;bitness;     areas.push_back(info);   }   \/\/ Don't remove this loop      return DRC_OK; }  static ssize_t idaapi read_memory(ea_t ea, void* buffer, size_t size, qstring* errbuf) {   return size; }  static ssize_t idaapi write_memory(ea_t ea, const void* buffer, size_t size, qstring* errbuf) {   return size; }  static int idaapi is_ok_bpt(bpttype_t type, ea_t ea, int len) {   switch (type)   {   case BPT_EXEC:   case BPT_READ:   case BPT_WRITE:   case BPT_RDWR:     return BPT_OK;   }    return BPT_BAD_TYPE; }  static drc_t idaapi update_bpts(int* nbpts, update_bpt_info_t* bpts, int nadd, int ndel, qstring* errbuf) {   for (int i = 0; i &lt; nadd; ++i)   {     ea_t start = bpts[i].ea;     ea_t end = bpts[i].ea + bpts[i].size - 1;      bpts[i].code = BPT_OK;   }    for (int i = 0; i &lt; ndel; ++i)   {     ea_t start = bpts[nadd + i].ea;     ea_t end = bpts[nadd + i].ea + bpts[nadd + i].size - 1;      bpts[nadd + i].code = BPT_OK;   }    *nbpts = (ndel + nadd);   return DRC_OK; }  static ssize_t idaapi idd_notify(void*, int msgid, va_list va) {   drc_t retcode = DRC_NONE;   qstring* errbuf;    switch (msgid)   {   case debugger_t::ev_init_debugger:   {     const char* hostname = va_arg(va, const char*);      int portnum = va_arg(va, int);     const char* password = va_arg(va, const char*);     errbuf = va_arg(va, qstring*);     QASSERT(1522, errbuf != NULL);     retcode = init_debugger(hostname, portnum, password, errbuf);   }   break;    case debugger_t::ev_term_debugger:     retcode = term_debugger();     break;    case debugger_t::ev_get_processes:   {     procinfo_vec_t* procs = va_arg(va, procinfo_vec_t*);     errbuf = va_arg(va, qstring*);     retcode = s_get_processes(procs, errbuf);   }   break;    case debugger_t::ev_start_process:   {     const char* path = va_arg(va, const char*);     const char* args = va_arg(va, const char*);     const char* startdir = va_arg(va, const char*);     uint32 dbg_proc_flags = va_arg(va, uint32);     const char* input_path = va_arg(va, const char*);     uint32 input_file_crc32 = va_arg(va, uint32);     errbuf = va_arg(va, qstring*);     retcode = s_start_process(path,       args,       startdir,       dbg_proc_flags,       input_path,       input_file_crc32,       errbuf);   }   break;    case debugger_t::ev_get_debapp_attrs:   {     debapp_attrs_t* out_pattrs = va_arg(va, debapp_attrs_t*);     out_pattrs-&gt;addrsize = 3;     out_pattrs-&gt;is_be = false;     out_pattrs-&gt;platform = &quot;bsnes&quot;;     out_pattrs-&gt;cbsize = sizeof(debapp_attrs_t);     retcode = DRC_OK;   }   break;    case debugger_t::ev_rebase_if_required_to:   {     ea_t new_base = va_arg(va, ea_t);     retcode = DRC_OK;   }   break;    case debugger_t::ev_request_pause:     errbuf = va_arg(va, qstring*);     retcode = prepare_to_pause_process(errbuf);     break;    case debugger_t::ev_exit_process:     errbuf = va_arg(va, qstring*);     retcode = emul_exit_process(errbuf);     break;    case debugger_t::ev_get_debug_event:   {     gdecode_t* code = va_arg(va, gdecode_t*);     debug_event_t* event = va_arg(va, debug_event_t*);     int timeout_ms = va_arg(va, int);     *code = get_debug_event(event, timeout_ms);     retcode = DRC_OK;   }   break;    case debugger_t::ev_resume:   {     debug_event_t* event = va_arg(va, debug_event_t*);     retcode = continue_after_event(event);   }   break;    case debugger_t::ev_thread_suspend:   {     thid_t tid = va_argi(va, thid_t);     retcode = DRC_OK;   }   break;    case debugger_t::ev_thread_continue:   {     thid_t tid = va_argi(va, thid_t);     retcode = DRC_OK;   }   break;    case debugger_t::ev_set_resume_mode:   {     thid_t tid = va_argi(va, thid_t);     resume_mode_t resmod = va_argi(va, resume_mode_t);     retcode = s_set_resume_mode(tid, resmod);   }   break;    case debugger_t::ev_read_registers:   {     thid_t tid = va_argi(va, thid_t);     int clsmask = va_arg(va, int);     regval_t* values = va_arg(va, regval_t*);     errbuf = va_arg(va, qstring*);     retcode = read_registers(tid, clsmask, values, errbuf);   }   break;    case debugger_t::ev_write_register:   {     thid_t tid = va_argi(va, thid_t);     int regidx = va_arg(va, int);     const regval_t* value = va_arg(va, const regval_t*);     errbuf = va_arg(va, qstring*);     retcode = write_register(tid, regidx, value, errbuf);   }   break;    case debugger_t::ev_get_memory_info:   {     meminfo_vec_t* ranges = va_arg(va, meminfo_vec_t*);     errbuf = va_arg(va, qstring*);     retcode = get_memory_info(*ranges, errbuf);   }   break;    case debugger_t::ev_read_memory:   {     size_t* nbytes = va_arg(va, size_t*);     ea_t ea = va_arg(va, ea_t);     void* buffer = va_arg(va, void*);     size_t size = va_arg(va, size_t);     errbuf = va_arg(va, qstring*);     ssize_t code = read_memory(ea, buffer, size, errbuf);     *nbytes = code &gt;= 0 ? code : 0;     retcode = code &gt;= 0 ? DRC_OK : DRC_NOPROC;   }   break;    case debugger_t::ev_write_memory:   {     size_t* nbytes = va_arg(va, size_t*);     ea_t ea = va_arg(va, ea_t);     const void* buffer = va_arg(va, void*);     size_t size = va_arg(va, size_t);     errbuf = va_arg(va, qstring*);     ssize_t code = write_memory(ea, buffer, size, errbuf);     *nbytes = code &gt;= 0 ? code : 0;     retcode = code &gt;= 0 ? DRC_OK : DRC_NOPROC;   }   break;    case debugger_t::ev_check_bpt:   {     int* bptvc = va_arg(va, int*);     bpttype_t type = va_argi(va, bpttype_t);     ea_t ea = va_arg(va, ea_t);     int len = va_arg(va, int);     *bptvc = is_ok_bpt(type, ea, len);     retcode = DRC_OK;   }   break;    case debugger_t::ev_update_bpts:   {     int* nbpts = va_arg(va, int*);     update_bpt_info_t* bpts = va_arg(va, update_bpt_info_t*);     int nadd = va_arg(va, int);     int ndel = va_arg(va, int);     errbuf = va_arg(va, qstring*);     retcode = update_bpts(nbpts, bpts, nadd, ndel, errbuf);   }   break;    default:     retcode = DRC_NONE;   }    return retcode; }  debugger_t debugger{     IDD_INTERFACE_VERSION,     NAME,     0x8000 + 6581, \/\/ (6)     &quot;65816&quot;,      DBG_FLAG_NOHOST | DBG_FLAG_CAN_CONT_BPT | DBG_FLAG_SAFE | DBG_FLAG_FAKE_ATTACH | DBG_FLAG_NOPASSWORD |     DBG_FLAG_NOSTARTDIR | DBG_FLAG_NOPARAMETERS | DBG_FLAG_ANYSIZE_HWBPT | DBG_FLAG_DEBTHREAD | DBG_FLAG_PREFER_SWBPTS,     DBG_HAS_GET_PROCESSES | DBG_HAS_REQUEST_PAUSE | DBG_HAS_SET_RESUME_MODE | DBG_HAS_THREAD_SUSPEND | DBG_HAS_THREAD_CONTINUE | DBG_HAS_CHECK_BPT,      register_classes,     RC_CPU,     registers,     qnumber(registers),      0x1000,      NULL,     0,     0,      DBG_RESMOD_STEP_INTO | DBG_RESMOD_STEP_OVER,      NULL,     idd_notify };<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435, \u043a\u043e\u0441\u043d\u0443\u0432\u0448\u0435\u0435\u0441\u044f \u043a\u043e\u0434\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u043e\u0432 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u0440\u043e \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u0434\u043b\u044f \u0421\u0435\u0433\u0438, \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u043a\u043e\u043b\u0431\u044d\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u0438\u043d \u2014 <code>idd_notify<\/code>, \u043d\u043e \u043e\u043d \u043e\u0434\u0438\u043d \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u043d\u044c\u0448\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0422\u0430\u043a \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u0434 \u043f\u043b\u0430\u0433\u0438\u043d\u0430-\u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u0430, \u0432\u043e\u0437\u044c\u043c\u0438\u0442\u0435 \u0448\u0430\u0431\u043b\u043e\u043d \u043a\u043e\u043b\u0431\u044d\u043a\u0430 \u0438\u0437 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0438 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0435\u0433\u043e \u043f\u043e\u0434 \u0438\u043c\u0435\u044e\u0449\u0438\u0439\u0441\u044f \u043a\u043e\u0434.<\/p>\n<p>  <\/p>\n<p>\u0412\u0442\u043e\u0440\u044b\u043c \u0432\u0430\u0436\u043d\u044b\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u0442\u0430\u043b\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c &quot;\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445&quot; \u043a\u043e\u0434\u043e\u0432 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u0430 \u2014 <code>drc_t<\/code>. \u0422\u0443\u0442 \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e: \u0435\u0441\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c <code>DRC_OK<\/code>, \u0438\u043d\u0430\u0447\u0435 \u2014 <code>DRC_FAILED<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0438\u043d\u043a\u043b\u0443\u0434\u044b:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">ida_registers.h<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#pragma once  #define RC_CPU (1 &lt;&lt; 0) #define RC_PPU (1 &lt;&lt; 1)  enum class SNES_REGS : uint8_t {     SR_A,     SR_X,     SR_Y,     SR_D,     SR_DB,     SR_PC,     SR_S,     SR_P,     SR_MFLAG,     SR_XFLAG,     SR_EFLAG, };<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">ida_debmod.h<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#pragma once  #include &lt;deque&gt; #include &lt;ida.hpp&gt; #include &lt;idd.hpp&gt;  \/\/-------------------------------------------------------------------------- \/\/ Very simple class to store pending events enum queue_pos_t {     IN_FRONT,     IN_BACK };  struct eventlist_t : public std::deque&lt;debug_event_t&gt; { private:     bool synced; public:     \/\/ save a pending event     void enqueue(const debug_event_t &amp;ev, queue_pos_t pos)     {         if (pos != IN_BACK)             push_front(ev);         else             push_back(ev);     }      \/\/ retrieve a pending event     bool retrieve(debug_event_t *event)     {         if (empty())             return false;         \/\/ get the first event and return it         *event = front();         pop_front();         return true;     } };<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0412 <code>ida_registers.h<\/code> \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u0432 \u0434\u043b\u044f \u0443\u0434\u043e\u0441\u0442\u0432\u0430 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439 \u043a \u043d\u0438\u043c \u0432 \u043a\u043e\u0434\u0435, \u0430 \u0432 <code>ida_debmod.h<\/code> \u043e\u043f\u0438\u0441\u0430\u043d \u0444\u043e\u0440\u043c\u0430\u0442 <code>eventlist_t<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c IDA.<\/p>\n<p>  <\/p>\n<h2 id=\"podgotovka-zavershena\">\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430<\/h2>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u0434 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442\u0441\u044f, \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435. \u0410 \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u043e\u0440\u0443\u0434\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u0435\u0436\u0434\u0443 IDA \u0438 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u042d\u043c\u0443\u043b\u044f\u0442\u043e\u0440 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u043c\u0435\u0442\u044c \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0418\u0434\u044b &quot;<em>\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c\/\u0443\u0431\u0440\u0430\u0442\u044c \u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442<\/em>&quot;, &quot;<em>\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c\/\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c<\/em>&quot;, &quot;<em>\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\/\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b<\/em>&quot;<\/li>\n<li>\u042d\u043c\u0443\u043b\u044f\u0442\u043e\u0440 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u0435\u043d: \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c IDA \u043e \u0442\u043e\u043c, \u0447\u0442\u043e: &quot;<em>\u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b<\/em>&quot;, &quot;<em>\u0448\u0430\u0433 \u043f\u0440\u0438 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e\u0439 \u043e\u0442\u043b\u0430\u0434\u043a\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d<\/em>&quot;, \u0438\u043b\u0438 &quot;<em>\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043d\u0430\u0447\u0430\u0442 \u0438\u043b\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d<\/em>&quot;<\/li>\n<li>\u0418\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0443\u043c\u0435\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0443 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c: &quot;<em>\u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c\/\u0443\u0431\u0440\u0430\u0442\u044c \u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442<\/em>&quot;, &quot;<em>\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c\/\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c<\/em>&quot;, &quot;<em>\u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\/\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b<\/em>&quot;<\/li>\n<li>\u0418\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e: &quot;<em>\u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b<\/em>&quot;, &quot;<em>\u0448\u0430\u0433 \u043f\u0440\u0438 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e\u0439 \u043e\u0442\u043b\u0430\u0434\u043a\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d<\/em>&quot;, \u0438\u043b\u0438 &quot;<em>\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043d\u0430\u0447\u0430\u0442 \u0438\u043b\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d<\/em>&quot;<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0434\u0432\u0430 \u043a\u0430\u043d\u0430\u043b\u0430, \u0442.\u043a. \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0445\u043e\u0442\u0435\u0442\u044c\u0441\u044f &quot;\u043f\u043e\u043e\u0431\u0449\u0430\u0442\u044c\u0441\u044f&quot; \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e:<\/p>\n<p>  <\/p>\n<ol>\n<li>IDA =&gt; \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440<\/li>\n<li>\u042d\u043c\u0443\u043b\u044f\u0442\u043e\u0440 =&gt; IDA<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u044d\u0442\u043e, \u043c\u043e\u0436\u043d\u043e, \u043e\u043f\u044f\u0442\u044c \u0436\u0435, \u043f\u043e\u0439\u0442\u0438 \u043f\u043e \u0441\u0442\u043e\u043f\u0430\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u043e \u0441\u0435\u0433\u043e\u0432\u0441\u043a\u0438\u0439 \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a, \u0430 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0445\u043e\u0442\u0435\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c &quot;\u043c\u043e\u0434\u043d\u044b\u0435 \u0438 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435&quot; \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 RPC \u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u044e\u0431\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u041c\u043e\u0439 \u0432\u044b\u0431\u043e\u0440 \u043f\u0430\u043b \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 <code>Thrift<\/code>, \u0442.\u043a. \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435, \u0438 \u043e\u043d \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 (\u043a\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e\u043a\u043b\u0435\u0438\u0432\u0430\u043d\u0438\u0435 RPC \u0432 protobuf, \u043d\u043e \u0442\u0443\u0442, \u0441\u043a\u043e\u0440\u0435\u0435, \u043d\u0430 \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u044f). \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c, \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0441\u0435\u0433\u043e \u0437\u0432\u0435\u0440\u044f, \u043d\u043e, \u044f \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u044d\u0442\u043e \u0437\u0430 \u0440\u0430\u043c\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>  <\/p>\n<h2 id=\"thrift---pishem-prototip-rpc\">Thrift \u2014 \u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f RPC<\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0449\u0451 \u0440\u0430\u0437 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0442\u0435 4 \u043f\u0443\u043d\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u043e\u043f\u0438\u0441\u0430\u043b \u0432\u044b\u0448\u0435, \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0432\u0441\u0451 \u0435\u0449\u0451 \u0434\u0435\u0440\u0436\u0438\u043c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435, \u043e\u0442\u043a\u0440\u043e\u0435\u043c \u0431\u043b\u043e\u043a\u043d\u043e\u0442, \u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u044d\u0442\u043e\u0433\u043e:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">service IdaClient {   oneway void start_event(),   oneway void add_visited(1:set&lt;i32&gt; visited, 2:bool is_step),   oneway void pause_event(1:i32 address),   oneway void stop_event(), }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u0432 Thrift \u043d\u0435\u0442\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e. \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 <code>IdaClient<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440, \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c\u0441\u044f \u0432 IDA. \u0412\u0441\u0435 \u044d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u044b \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c <code>oneway<\/code>, \u0442.\u043a., \u043f\u043e \u0441\u0443\u0442\u0438, \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0436\u0438\u0434\u0430\u0442\u044c\u0441\u044f \u0438\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0438 \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043e\u0436\u0438\u0434\u0430\u0442\u044c, \u0447\u0442\u043e \u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442.<\/p>\n<p>  <\/p>\n<p><code>start_event()<\/code> \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0418\u0434\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0440\u043e\u043c \u0432\u044b\u0431\u0440\u0430\u043b \u0438 \u0435\u0433\u043e \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u044f \u043d\u0430\u0447\u0430\u043b\u0430\u0441\u044c.<\/p>\n<p>  <\/p>\n<p><code>add_visited()<\/code> \u2014 \u043c\u0435\u0442\u043e\u0434, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0432 \u0418\u0434\u0443 \u043e \u0442\u043e\u043c \u043a\u043e\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u043c. \u042d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043f\u0440\u0438 \u043e\u0442\u043b\u0430\u0434\u043a\u0435 \u043a\u0430\u043a \u0440\u0430\u0437 \u0442\u0430\u043a\u0438 \u0440\u0435\u0442\u0440\u043e-\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c, \u0442.\u043a. \u0432 \u0440\u043e\u043c\u0430\u0445 \u0434\u043b\u044f \u043d\u0438\u0445 \u043a\u043e\u0434 \u0447\u0430\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0436\u0430\u0435\u0442\u0441\u044f \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u0415\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0432\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c \u0432\u0430\u043c\u0438 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0435 \u043d\u0435\u0442, \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438 \u0432 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435.<\/p>\n<p>  <\/p>\n<p><code>pause_event()<\/code> \u2014 \u044d\u0442\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0418\u0434\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043f\u0430\u0443\u0437\u0430 \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u043f\u043e \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435: \u0431\u0443\u0434\u044c \u0442\u043e \u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442, \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u0448\u0430\u0433 \u043f\u0440\u0438 StepInto \u0438\u043b\u0438 StepOver \u0438\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441, \u0433\u0434\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430.<\/p>\n<p>  <\/p>\n<p><code>stop_event()<\/code> \u2014 \u0434\u0443\u043c\u0430\u044e, \u0442\u0443\u0442 \u0432\u0441\u0451 \u043f\u043e\u043d\u044f\u0442\u043d\u043e. \u042d\u043c\u0443\u043b\u044f\u0446\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0430\u0441\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u0421 \u044d\u0442\u0438\u043c \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u0442\u0435\u043f\u0435\u0440\u044c \u0447\u0430\u0441\u0442\u044c \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u2014 \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u044b\u0439 RPC:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">service BsnesDebugger {   i32 get_cpu_reg(1:BsnesRegister reg),   BsnesRegisters get_cpu_regs(),   void set_cpu_reg(1:BsnesRegister reg, 2:i32 value),    binary read_memory(1:DbgMemorySource src, 2:i32 address, 3:i32 size),   void write_memory(1:DbgMemorySource src, 2:i32 address, 3:binary data),    void add_breakpoint(1:DbgBreakpoint bpt),   void del_breakpoint(1:DbgBreakpoint bpt),    void pause(),   void resume(),   void start_emulation(),   void exit_emulation(),    void step_into(),   void step_over(), }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443 \u043d\u0430\u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043a\u0440\u0443\u0442\u0438\u0442\u044c\u0441\u044f \u0432 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0435, \u0438 \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0418\u0434\u0430 \u0432\u0440\u0435\u043c\u044f \u043e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u0430\u0442\u044c. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0435\u0451 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">  i32 get_cpu_reg(1:BsnesRegister reg),   void set_cpu_reg(1:BsnesRegister reg, 2:i32 value),<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0438\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0440\u0435\u0433\u0438\u0441\u0442\u0440. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 enum <code>BsnesRegister<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">enum BsnesRegister {   pc,   a,   x,   y,   s,   d,   db,   p,   mflag,   xflag,   eflag, }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u044d\u0442\u043e \u0442\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0432\u0438\u0434\u0435\u0442\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u0443 \u0432\u0430\u0441 \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0422.\u043a. IDA \u0441\u0430\u043c\u0430 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0443, \u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0432\u0441\u0435 \u0441\u0440\u0430\u0437\u0443, \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0445 \u0432\u0441\u0435 \u0441\u0440\u0430\u0437\u0443 \u0438 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">struct BsnesRegisters {   1:i32 pc,   2:i32 a,   3:i32 x,   4:i32 y,   5:i32 s,   6:i32 d,   7:i16 db,   8:i16 p,   9:i8 mflag,   10:i8 xflag,   11:i8 eflag, }  service BsnesDebugger {   ...   BsnesRegisters get_cpu_regs(),   ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u044f \u0437\u0430\u0432\u0451\u043b \u043e\u0434\u043d\u0443 \u043e\u0431\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u043e\u0434 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b, \u0443\u043a\u0430\u0437\u0430\u0432 \u0438\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0438 \u0443\u043a\u0430\u0437\u0430\u043b \u0435\u0451 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u0430 <code>get_cpu_regs()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u0430\u043c\u044f\u0442\u044c\u044e:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">enum DbgMemorySource {   CPUBus,   APUBus,   APURAM,   DSP,   VRAM,   OAM,   CGRAM,   CartROM,   CartRAM,   SA1Bus,   SFXBus,   SGBBus,   SGBROM,   SGBRAM, }  service BsnesDebugger {   ...   binary read_memory(1:DbgMemorySource src, 2:i32 address, 3:i32 size),   void write_memory(1:DbgMemorySource src, 2:i32 address, 3:binary data),   ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0432 Thrift \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 <code>binary<\/code>, \u0438 \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u044b (\u0432\u0437\u044f\u0442\u043e \u0438\u0437 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430).<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0448\u043b\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">enum BpType {   BP_PC = 1,   BP_READ = 2,   BP_WRITE = 4, }  enum DbgBptSource {   CPUBus,   APURAM,   DSP,   VRAM,   OAM,   CGRAM,   SA1Bus,   SFXBus,   SGBBus, }  struct DbgBreakpoint {   1:BpType type,   2:i32 bstart,   3:i32 bend,   4:bool enabled,   5:DbgBptSource src, }  service BsnesDebugger {   ...   void add_breakpoint(1:DbgBreakpoint bpt),   void del_breakpoint(1:DbgBreakpoint bpt),   ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422.\u043a. \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u043b\u0430\u0441\u0442\u0435\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c, \u0438 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442\u044b \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f, \u0437\u0430\u0432\u043e\u0434\u0438\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a <code>DbgBptSource<\/code>. \u0422\u0430\u043a\u0436\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u0438\u043f \u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442\u0430 <code>BpType<\/code> \u0438 \u0430\u0434\u0440\u0435\u0441 \u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0430\/\u043a\u043e\u043d\u0446\u0430 <code>bstart<\/code>\/<code>bend<\/code>. \u0415\u0449\u0451 \u043d\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442 \u043d\u0435 \u0441\u0440\u0430\u0437\u0443 <code>enabled<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0421 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0436\u043d\u044b\u043c\u0438 \u0447\u0430\u0441\u0442\u044f\u043c\u0438 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">service BsnesDebugger {   ...   void pause(),   void resume(),   void start_emulation(),   void exit_emulation(),    void step_into(),   void step_over(),   ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>pause()<\/code> \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043e\u0442 IDA, <code>resume()<\/code> \u2014 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<p><code>start_emulation()<\/code> \u2014 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b IDA \u043c\u043e\u0433\u043b\u0430 \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0443, \u0447\u0442\u043e \u043e\u043d\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043e\u0442 \u043d\u0435\u0433\u043e \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0447\u0430\u043b\u0430 \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u043c-\u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u043e\u043c \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u043c.<\/p>\n<p>  <\/p>\n<p><code>exit_emulation()<\/code> \u2014 \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u043c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043a\u0443 \u0438\u0437 IDA, \u0430 \u043d\u0435 \u0438\u0437 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430.<\/p>\n<p>  <\/p>\n<p><code>step_into()<\/code> \u0438 <code>step_over()<\/code> \u2014 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u0430\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0430.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 debug_proto.thrift<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">enum BsnesRegister {   pc,   a,   x,   y,   s,   d,   db,   p,   mflag,   xflag,   eflag, }  struct BsnesRegisters {   1:i32 pc,   2:i32 a,   3:i32 x,   4:i32 y,   5:i32 s,   6:i32 d,   7:i16 db,   8:i16 p,   9:i8 mflag,   10:i8 xflag,   11:i8 eflag, }  enum BpType {   BP_PC = 1,   BP_READ = 2,   BP_WRITE = 4, }  enum DbgMemorySource {   CPUBus,   APUBus,   APURAM,   DSP,   VRAM,   OAM,   CGRAM,   CartROM,   CartRAM,   SA1Bus,   SFXBus,   SGBBus,   SGBROM,   SGBRAM, }  enum DbgBptSource {   CPUBus,   APURAM,   DSP,   VRAM,   OAM,   CGRAM,   SA1Bus,   SFXBus,   SGBBus, }  struct DbgBreakpoint {   1:BpType type,   2:i32 bstart,   3:i32 bend,   4:bool enabled,   5:DbgBptSource src, }  service BsnesDebugger {   i32 get_cpu_reg(1:BsnesRegister reg),   BsnesRegisters get_cpu_regs(),   void set_cpu_reg(1:BsnesRegister reg, 2:i32 value),    binary read_memory(1:DbgMemorySource src, 2:i32 address, 3:i32 size),   void write_memory(1:DbgMemorySource src, 2:i32 address, 3:binary data),    void add_breakpoint(1:DbgBreakpoint bpt),   void del_breakpoint(1:DbgBreakpoint bpt),    void pause(),   void resume(),   void start_emulation(),   void exit_emulation(),    void step_into(),   void step_over(), }  service IdaClient {   oneway void start_event(),   oneway void add_visited(1:set&lt;i32&gt; changed, 2:bool is_step),   oneway void pause_event(1:i32 address),   oneway void stop_event(), }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<h2 id=\"ot-rpc-prototipa-k-realizacii\">\u041e\u0442 RPC-\u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430 \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/h2>\n<p>  <\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f RPC-\u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d. \u0427\u0442\u043e\u0431\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 \u043d\u0435\u0433\u043e \u043a\u043e\u0434 \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u0430 C++, \u043a\u0430\u0447\u0430\u0435\u043c <a href=\"https:\/\/thrift.apache.org\/download\" rel=\"nofollow noopener noreferrer\">Thrift-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440<\/a>, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">thrift --gen cpp debug_proto.thrift<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 <code>gen-cpp<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u0436\u0434\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c, \u043d\u043e \u0438 \u0448\u0430\u0431\u043b\u043e\u043d \u043a\u043e\u0434\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u2014 <code>IdaClient<\/code> \u0438 <code>BsnesDebugger<\/code>.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/l_\/o7\/s5\/l_o7s5alyherwwsyfhax3km9sd8.png\"><\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u0441\u0442\u0443\u0434\u0438\u0439\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 (\u043a\u0440\u043e\u043c\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 <code>*_server.skeleton.cpp<\/code>). \u0422\u0430\u043a\u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043b\u0438\u043d\u043a\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 (\u0438 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430) \u0441\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 <code>thrift<\/code>-\u0430 \u0438 <code>libevent<\/code>-\u0430 (\u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c &quot;nonblocking&quot; \u0432\u0430\u0440\u0438\u0430\u043d\u0442 Thrift). \u0423 \u044d\u0442\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438\u043c\u0435\u0435\u0442\u0441\u044f CMake \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441\u0431\u043e\u0440\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441.<\/p>\n<p>  <\/p>\n<h3 id=\"kod-idaclient-hendlera\">\u041a\u043e\u0434 IdaClient \u0445\u044d\u043d\u0434\u043b\u0435\u0440\u0430<\/h3>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u043a\u043e\u0434\u0430, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 <code>IdaClient<\/code>-\u0441\u0435\u0440\u0432\u0438\u0441:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u043d\u043a\u043b\u0443\u0434\u044b \u0438 \u0430\u0434\u0440\u0435\u0441\u043d\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &quot;gen-cpp\/IdaClient.h&quot; #include &quot;gen-cpp\/BsnesDebugger.h&quot; #include &lt;thrift\/protocol\/TBinaryProtocol.h&gt; #include &lt;thrift\/transport\/TSocket.h&gt; #include &lt;thrift\/transport\/TBufferTransports.h&gt; #include &lt;thrift\/server\/TNonblockingServer.h&gt; #include &lt;thrift\/transport\/TNonblockingServerSocket.h&gt; #include &lt;thrift\/concurrency\/ThreadFactory.h&gt;  using namespace ::apache::thrift; using namespace ::apache::thrift::protocol; using namespace ::apache::thrift::transport; using namespace ::apache::thrift::server; using namespace ::apache::thrift::concurrency;  ::std::shared_ptr&lt;BsnesDebuggerClient&gt; client; ::std::shared_ptr&lt;TNonblockingServer&gt; srv; ::std::shared_ptr&lt;TTransport&gt; cli_transport;<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 IdaClient<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">static void pause_execution() {   try {     if (client) {       client-&gt;pause();     }   }   catch (...) {    } }  static void continue_execution() {   try {     if (client) {       client-&gt;resume();     }   }   catch (...) {    } }  static void stop_server() {   try {     srv-&gt;stop();   }   catch (...) {    } }  static void finish_execution() {   try {     if (client) {       client-&gt;exit_emulation();     }   }   catch (...) {    }    stop_server(); }  class IdaClientHandler : virtual public IdaClientIf {  public:     void pause_event(const int32_t address) override {     ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);      debug_event_t ev;     ev.pid = 1;     ev.tid = 1;     ev.ea = address | 0x800000;     ev.handled = true;     ev.set_eid(PROCESS_SUSPENDED);     events.enqueue(ev, IN_BACK);     }      void start_event() override {     ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);      debug_event_t ev;     ev.pid = 1;     ev.tid = 1;     ev.ea = BADADDR;     ev.handled = true;      ev.set_modinfo(PROCESS_STARTED).name.sprnt(&quot;BSNES&quot;);     ev.set_modinfo(PROCESS_STARTED).base = 0;     ev.set_modinfo(PROCESS_STARTED).size = 0;     ev.set_modinfo(PROCESS_STARTED).rebase_to = BADADDR;      events.enqueue(ev, IN_BACK);     }      void stop_event() override {     ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);      debug_event_t ev;     ev.pid = 1;     ev.handled = true;     ev.set_exit_code(PROCESS_EXITED, 0);      events.enqueue(ev, IN_BACK);     }    void add_visited(const std::set&lt;int32_t&gt;&amp; changed, bool is_step) override {    } };<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043a\u043e\u0434\u0435 \u043c\u044b \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u043c \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0438 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u043e \u043d\u0438\u0445 \u0418\u0434\u0435, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044f \u044d\u0442\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u0441\u043f\u0438\u0441\u043e\u043a. \u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e \u043d\u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u0442\u043e\u0439 \u0436\u0435 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u0440\u043e \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u0434\u043b\u044f \u0421\u0435\u0433\u0438. \u041a\u043e\u0434 <code>add_visited()<\/code> \u043f\u043e\u043a\u0430 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0443\u0441\u0442\u044b\u043c. \u041e \u043d\u0451\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0418\u0434\u044b (\u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0440\u0442 <u>9091<\/u>), \u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0443:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">init_ida_server \u0438 init_emu_client<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">static void init_ida_server() {     try {     ::std::shared_ptr&lt;IdaClientHandler&gt; handler(new IdaClientHandler());     ::std::shared_ptr&lt;TProcessor&gt; processor(new IdaClientProcessor(handler));     ::std::shared_ptr&lt;TNonblockingServerTransport&gt; serverTransport(new TNonblockingServerSocket(9091));     ::std::shared_ptr&lt;TFramedTransportFactory&gt; transportFactory(new TFramedTransportFactory());     ::std::shared_ptr&lt;TProtocolFactory&gt; protocolFactory(new TBinaryProtocolFactory());      srv = ::std::shared_ptr&lt;TNonblockingServer&gt;(new TNonblockingServer(processor, protocolFactory, serverTransport));     ::std::shared_ptr&lt;ThreadFactory&gt; tf(new ThreadFactory());     ::std::shared_ptr&lt;Thread&gt; thread = tf-&gt;newThread(srv);     thread-&gt;start();     } catch (...) {      } }  static void init_emu_client() {   ::std::shared_ptr&lt;TTransport&gt; socket(new TSocket(&quot;127.0.0.1&quot;, 9090));   cli_transport = ::std::shared_ptr&lt;TTransport&gt;(new TFramedTransport(socket));   ::std::shared_ptr&lt;TBinaryProtocol&gt; protocol(new TBinaryProtocol(cli_transport));   client = ::std::shared_ptr&lt;BsnesDebuggerClient&gt;(new BsnesDebuggerClient(protocol));    show_wait_box(&quot;Waiting for BSNES-PLUS emulation...&quot;);    while (true) {     if (user_cancelled()) {       break;     }      try {       cli_transport-&gt;open();       break;     }     catch (...) {      }   }    hide_wait_box(); }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0438\u043c\u0435\u044e\u0449\u0438\u0439\u0441\u044f \u0448\u0430\u0431\u043b\u043e\u043d <code>ida_debug.cpp<\/code> \u043a\u043e\u0434\u043e\u043c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e Thrift. \u0412\u043e\u0442 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 ida_debug.cpp<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &quot;gen-cpp\/IdaClient.h&quot; #include &quot;gen-cpp\/BsnesDebugger.h&quot; #include &lt;thrift\/protocol\/TBinaryProtocol.h&gt; #include &lt;thrift\/transport\/TSocket.h&gt; #include &lt;thrift\/transport\/TBufferTransports.h&gt; #include &lt;thrift\/server\/TNonblockingServer.h&gt; #include &lt;thrift\/transport\/TNonblockingServerSocket.h&gt; #include &lt;thrift\/concurrency\/ThreadFactory.h&gt;  using namespace ::apache::thrift; using namespace ::apache::thrift::protocol; using namespace ::apache::thrift::transport; using namespace ::apache::thrift::server; using namespace ::apache::thrift::concurrency;  #include &lt;ida.hpp&gt; #include &lt;dbg.hpp&gt; #include &lt;auto.hpp&gt; #include &lt;deque&gt; #include &lt;mutex&gt;  #include &quot;ida_plugin.h&quot; #include &quot;ida_debmod.h&quot; #include &quot;ida_registers.h&quot;  ::std::shared_ptr&lt;BsnesDebuggerClient&gt; client; ::std::shared_ptr&lt;TNonblockingServer&gt; srv; ::std::shared_ptr&lt;TTransport&gt; cli_transport;  static ::std::mutex list_mutex; static eventlist_t events;  static const char* const p_reg[] = {     &quot;CF&quot;,     &quot;ZF&quot;,     &quot;IF&quot;,     &quot;DF&quot;,     &quot;XF&quot;,     &quot;MF&quot;,     &quot;VF&quot;,     &quot;NF&quot;, };  static register_info_t registers[] = {     {&quot;A&quot;, 0, RC_CPU, dt_word, NULL, 0},     {&quot;X&quot;, 0, RC_CPU, dt_word, NULL, 0},     {&quot;Y&quot;, 0, RC_CPU, dt_word, NULL, 0},      {&quot;D&quot;, 0, RC_CPU, dt_word, NULL, 0},     {&quot;DB&quot;, 0, RC_CPU, dt_byte, NULL, 0},      {&quot;PC&quot;, REGISTER_IP | REGISTER_ADDRESS, RC_CPU, dt_dword, NULL, 0},   {&quot;S&quot;, REGISTER_SP | REGISTER_ADDRESS, RC_CPU, dt_word, NULL, 0},      {&quot;P&quot;, REGISTER_READONLY, RC_CPU, dt_byte, p_reg, 0xFF},   {&quot;m&quot;, REGISTER_READONLY, RC_CPU, dt_byte, NULL, 0},   {&quot;x&quot;, REGISTER_READONLY, RC_CPU, dt_byte, NULL, 0},     {&quot;e&quot;, REGISTER_READONLY, RC_CPU, dt_byte, NULL, 0}, };  static const char* register_classes[] = {     &quot;General Registers&quot;,     NULL };  static struct apply_codemap_req : public exec_request_t { private:   const std::set&lt;int32_t&gt;&amp; _changed;   const bool _is_step; public:   apply_codemap_req(const std::set&lt;int32_t&gt;&amp; changed, bool is_step) : _changed(changed), _is_step(is_step) {};    int idaapi execute(void) override {     auto m = _changed.size();      if (!_is_step) {       show_wait_box(&quot;Applying codemap: %d\/%d...&quot;, 1, m);     }      auto x = 0;     for (auto i = _changed.cbegin(); i != _changed.cend(); ++i) {       if (!_is_step &amp;&amp; user_cancelled()) {         break;       }        if (!_is_step) {         replace_wait_box(&quot;Applying codemap: %d\/%d...&quot;, x, m);       }        ea_t addr = (ea_t)(*i | 0x800000);       auto_make_code(addr);       plan_ea(addr);       show_addr(addr);       x++;     }      if (!_is_step) {       hide_wait_box();     }      return 0;   } };  static void apply_codemap(const std::set&lt;int32_t&gt;&amp; changed, bool is_step) {   if (changed.empty()) return;    apply_codemap_req req(changed, is_step);   execute_sync(req, MFF_FAST); }  static void pause_execution() {   try {     if (client) {       client-&gt;pause();     }   }   catch (...) {    } }  static void continue_execution() {   try {     if (client) {       client-&gt;resume();     }   }   catch (...) {    } }  static void stop_server() {   try {     srv-&gt;stop();   }   catch (...) {    } }  static void finish_execution() {   try {     if (client) {       client-&gt;exit_emulation();     }   }   catch (...) {    }    stop_server(); }  class IdaClientHandler : virtual public IdaClientIf {  public:     void pause_event(const int32_t address) override {     ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);      debug_event_t ev;     ev.pid = 1;     ev.tid = 1;     ev.ea = address | 0x800000;     ev.handled = true;     ev.set_eid(PROCESS_SUSPENDED);     events.enqueue(ev, IN_BACK);     }      void start_event() override {     ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);      debug_event_t ev;     ev.pid = 1;     ev.tid = 1;     ev.ea = BADADDR;     ev.handled = true;      ev.set_modinfo(PROCESS_STARTED).name.sprnt(&quot;BSNES&quot;);     ev.set_modinfo(PROCESS_STARTED).base = 0;     ev.set_modinfo(PROCESS_STARTED).size = 0;     ev.set_modinfo(PROCESS_STARTED).rebase_to = BADADDR;      events.enqueue(ev, IN_BACK);     }      void stop_event() override {     ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);      debug_event_t ev;     ev.pid = 1;     ev.handled = true;     ev.set_exit_code(PROCESS_EXITED, 0);      events.enqueue(ev, IN_BACK);     }    void add_visited(const std::set&lt;int32_t&gt;&amp; changed, bool is_step) override {     apply_codemap(changed, is_step);   } };  static void init_ida_server() {     try {     ::std::shared_ptr&lt;IdaClientHandler&gt; handler(new IdaClientHandler());     ::std::shared_ptr&lt;TProcessor&gt; processor(new IdaClientProcessor(handler));     ::std::shared_ptr&lt;TNonblockingServerTransport&gt; serverTransport(new TNonblockingServerSocket(9091));     ::std::shared_ptr&lt;TFramedTransportFactory&gt; transportFactory(new TFramedTransportFactory());     ::std::shared_ptr&lt;TProtocolFactory&gt; protocolFactory(new TBinaryProtocolFactory());      srv = ::std::shared_ptr&lt;TNonblockingServer&gt;(new TNonblockingServer(processor, protocolFactory, serverTransport));     ::std::shared_ptr&lt;ThreadFactory&gt; tf(new ThreadFactory());     ::std::shared_ptr&lt;Thread&gt; thread = tf-&gt;newThread(srv);     thread-&gt;start();     } catch (...) {      } }  static void init_emu_client() {   ::std::shared_ptr&lt;TTransport&gt; socket(new TSocket(&quot;127.0.0.1&quot;, 9090));   cli_transport = ::std::shared_ptr&lt;TTransport&gt;(new TFramedTransport(socket));   ::std::shared_ptr&lt;TBinaryProtocol&gt; protocol(new TBinaryProtocol(cli_transport));   client = ::std::shared_ptr&lt;BsnesDebuggerClient&gt;(new BsnesDebuggerClient(protocol));    show_wait_box(&quot;Waiting for BSNES-PLUS emulation...&quot;);    while (true) {     if (user_cancelled()) {       break;     }      try {       cli_transport-&gt;open();       break;     }     catch (...) {      }   }    hide_wait_box(); }  static drc_t idaapi init_debugger(const char* hostname, int portnum, const char* password, qstring* errbuf) {   return DRC_OK; }  static drc_t idaapi term_debugger(void) {   finish_execution();   return DRC_OK; }  static drc_t s_get_processes(procinfo_vec_t* procs, qstring* errbuf) {   process_info_t info;   info.name.sprnt(&quot;bsnes&quot;);   info.pid = 1;   procs-&gt;add(info);    return DRC_OK; }  static drc_t idaapi s_start_process(const char* path,   const char* args,   const char* startdir,   uint32 dbg_proc_flags,   const char* input_path,   uint32 input_file_crc32,   qstring* errbuf = NULL) {   ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);   events.clear();    init_ida_server();   init_emu_client();    try {     if (client) {       client-&gt;start_emulation();     }   }   catch (...) {     return DRC_FAILED;   }    return DRC_OK; }  static drc_t idaapi prepare_to_pause_process(qstring* errbuf) {   pause_execution();   return DRC_OK; }  static drc_t idaapi emul_exit_process(qstring* errbuf) {   finish_execution();    return DRC_OK; }  static gdecode_t idaapi get_debug_event(debug_event_t* event, int timeout_ms) {   while (true)   {     ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);      \/\/ are there any pending events?     if (events.retrieve(event))     {       return events.empty() ? GDE_ONE_EVENT : GDE_MANY_EVENTS;     }     if (events.empty())       break;   }   return GDE_NO_EVENT; }  static drc_t idaapi continue_after_event(const debug_event_t* event) {   dbg_notification_t req = get_running_notification();   switch (event-&gt;eid())   {   case STEP:   case PROCESS_SUSPENDED:     if (req == dbg_null || req == dbg_run_to) {       continue_execution();     }     break;   case PROCESS_EXITED:     stop_server();     break;   }    return DRC_OK; }  static drc_t idaapi s_set_resume_mode(thid_t tid, resume_mode_t resmod) \/\/ Run one instruction in the thread {   switch (resmod)   {   case RESMOD_INTO:    \/\/\/&lt; step into call (the most typical single stepping)     try {       if (client) {         client-&gt;step_into();       }     }     catch (...) {       return DRC_FAILED;     }      break;   case RESMOD_OVER:    \/\/\/&lt; step over call     try {       if (client) {         client-&gt;step_over();       }     }     catch (...) {       return DRC_FAILED;     }     break;   }    return DRC_OK; }  static drc_t idaapi read_registers(thid_t tid, int clsmask, regval_t* values, qstring* errbuf) {   if (clsmask &amp; RC_CPU)   {         BsnesRegisters regs;      try {       if (client) {         client-&gt;get_cpu_regs(regs);                  values[static_cast&lt;int&gt;(SNES_REGS::SR_PC)].ival = regs.pc | 0x800000;                 values[static_cast&lt;int&gt;(SNES_REGS::SR_A)].ival = regs.a;                 values[static_cast&lt;int&gt;(SNES_REGS::SR_X)].ival = regs.x;                 values[static_cast&lt;int&gt;(SNES_REGS::SR_Y)].ival = regs.y;                 values[static_cast&lt;int&gt;(SNES_REGS::SR_S)].ival = regs.s;                 values[static_cast&lt;int&gt;(SNES_REGS::SR_D)].ival = regs.d;                 values[static_cast&lt;int&gt;(SNES_REGS::SR_DB)].ival = regs.db;                 values[static_cast&lt;int&gt;(SNES_REGS::SR_P)].ival = regs.p;         values[static_cast&lt;int&gt;(SNES_REGS::SR_MFLAG)].ival = regs.mflag;         values[static_cast&lt;int&gt;(SNES_REGS::SR_XFLAG)].ival = regs.xflag;                 values[static_cast&lt;int&gt;(SNES_REGS::SR_EFLAG)].ival = regs.eflag;       }     }     catch (...) {       return DRC_FAILED;     }     }      return DRC_OK; }  static drc_t idaapi write_register(thid_t tid, int regidx, const regval_t* value, qstring* errbuf) {   if (regidx &gt;= static_cast&lt;int&gt;(SNES_REGS::SR_PC) &amp;&amp; regidx &lt;= static_cast&lt;int&gt;(SNES_REGS::SR_EFLAG)) {     try {       if (client) {         client-&gt;set_cpu_reg(static_cast&lt;BsnesRegister::type&gt;(regidx), value-&gt;ival &amp; 0xFFFFFFFF);       }     }     catch (...) {       return DRC_FAILED;     }     }      return DRC_OK;  }  static drc_t idaapi get_memory_info(meminfo_vec_t&amp; areas, qstring* errbuf) {   memory_info_t info;    info.start_ea = 0x0000;   info.end_ea = 0x01FFF;   info.sclass = &quot;STACK&quot;;   info.bitness = 0;   info.perm = SEGPERM_READ | SEGPERM_WRITE;   areas.push_back(info);    \/\/ Don't remove this loop   for (int i = 0; i &lt; get_segm_qty(); ++i)   {     segment_t* segm = getnseg(i);      info.start_ea = segm-&gt;start_ea;     info.end_ea = segm-&gt;end_ea;      qstring buf;     get_segm_name(&amp;buf, segm);     info.name = buf;      get_segm_class(&amp;buf, segm);     info.sclass = buf;      info.sbase = get_segm_base(segm);      info.perm = segm-&gt;perm;     info.bitness = segm-&gt;bitness;     areas.push_back(info);   }   \/\/ Don't remove this loop      return DRC_OK; }  static ssize_t idaapi read_memory(ea_t ea, void* buffer, size_t size, qstring* errbuf) {   std::string mem;    try {     if (client) {       client-&gt;read_memory(mem, DbgMemorySource::CPUBus, (int32_t)ea, (int32_t)size);        memcpy(&amp;((unsigned char*)buffer)[0], mem.c_str(), size);     }   }   catch (...) {     return DRC_FAILED;   }    return size; }  static ssize_t idaapi write_memory(ea_t ea, const void* buffer, size_t size, qstring* errbuf) {   std::string mem((const char*)buffer);    try {     if (client) {       client-&gt;write_memory(DbgMemorySource::CPUBus, (int32_t)ea, mem);     }   }   catch (...) {     return 0;   }    return size; }  static int idaapi is_ok_bpt(bpttype_t type, ea_t ea, int len) {   DbgMemorySource::type btype = DbgMemorySource::CPUBus;    switch (btype) {   case DbgMemorySource::CPUBus:   case DbgMemorySource::APURAM:   case DbgMemorySource::DSP:   case DbgMemorySource::VRAM:   case DbgMemorySource::OAM:   case DbgMemorySource::CGRAM:   case DbgMemorySource::SA1Bus:   case DbgMemorySource::SFXBus:     break;   default:     return BPT_BAD_TYPE;   }    switch (type)   {   case BPT_EXEC:   case BPT_READ:   case BPT_WRITE:   case BPT_RDWR:     return BPT_OK;   }    return BPT_BAD_TYPE; }  static drc_t idaapi update_bpts(int* nbpts, update_bpt_info_t* bpts, int nadd, int ndel, qstring* errbuf) {   for (int i = 0; i &lt; nadd; ++i)   {     ea_t start = bpts[i].ea;     ea_t end = bpts[i].ea + bpts[i].size - 1;      DbgBreakpoint bp;     bp.bstart = start;     bp.bend = end;     bp.enabled = true;      switch (bpts[i].type)     {     case BPT_EXEC:       bp.type = BpType::BP_PC;       break;     case BPT_READ:       bp.type = BpType::BP_READ;       break;     case BPT_WRITE:       bp.type = BpType::BP_WRITE;       break;     case BPT_RDWR:       bp.type = BpType::BP_READ;       break;     }      DbgMemorySource::type type = DbgMemorySource::CPUBus;      switch (type) {     case DbgMemorySource::CPUBus:       bp.src = DbgBptSource::CPUBus;       break;     case DbgMemorySource::APURAM:       bp.src = DbgBptSource::APURAM;       break;     case DbgMemorySource::DSP:       bp.src = DbgBptSource::DSP;       break;     case DbgMemorySource::VRAM:       bp.src = DbgBptSource::VRAM;       break;     case DbgMemorySource::OAM:       bp.src = DbgBptSource::OAM;       break;     case DbgMemorySource::CGRAM:       bp.src = DbgBptSource::CGRAM;       break;     case DbgMemorySource::SA1Bus:       bp.src = DbgBptSource::SA1Bus;       break;     case DbgMemorySource::SFXBus:       bp.src = DbgBptSource::SFXBus;       break;     default:       continue;     }      try {       if (client) {         client-&gt;add_breakpoint(bp);       }     }     catch (...) {       return DRC_FAILED;     }      bpts[i].code = BPT_OK;   }    for (int i = 0; i &lt; ndel; ++i)   {     ea_t start = bpts[nadd + i].ea;     ea_t end = bpts[nadd + i].ea + bpts[nadd + i].size - 1;      DbgBreakpoint bp;     bp.bstart = start;     bp.bend = end;     bp.enabled = true;      switch (bpts[i].type)     {     case BPT_EXEC:       bp.type = BpType::BP_PC;       break;     case BPT_READ:       bp.type = BpType::BP_READ;       break;     case BPT_WRITE:       bp.type = BpType::BP_WRITE;       break;     case BPT_RDWR:       bp.type = BpType::BP_READ;       break;     }      DbgMemorySource::type type = DbgMemorySource::CPUBus;      switch (type) {     case DbgMemorySource::CPUBus:       bp.src = DbgBptSource::CPUBus;       break;     case DbgMemorySource::APURAM:       bp.src = DbgBptSource::APURAM;       break;     case DbgMemorySource::DSP:       bp.src = DbgBptSource::DSP;       break;     case DbgMemorySource::VRAM:       bp.src = DbgBptSource::VRAM;       break;     case DbgMemorySource::OAM:       bp.src = DbgBptSource::OAM;       break;     case DbgMemorySource::CGRAM:       bp.src = DbgBptSource::CGRAM;       break;     case DbgMemorySource::SA1Bus:       bp.src = DbgBptSource::SA1Bus;       break;     case DbgMemorySource::SFXBus:       bp.src = DbgBptSource::SFXBus;       break;     default:       continue;     }      try {       if (client) {         client-&gt;del_breakpoint(bp);       }     }     catch (...) {       return DRC_FAILED;     }      bpts[nadd + i].code = BPT_OK;   }    *nbpts = (ndel + nadd);   return DRC_OK; }  static ssize_t idaapi idd_notify(void*, int msgid, va_list va) {   drc_t retcode = DRC_NONE;   qstring* errbuf;    switch (msgid)   {   case debugger_t::ev_init_debugger:   {     const char* hostname = va_arg(va, const char*);      int portnum = va_arg(va, int);     const char* password = va_arg(va, const char*);     errbuf = va_arg(va, qstring*);     QASSERT(1522, errbuf != NULL);     retcode = init_debugger(hostname, portnum, password, errbuf);   }   break;    case debugger_t::ev_term_debugger:     retcode = term_debugger();     break;    case debugger_t::ev_get_processes:   {     procinfo_vec_t* procs = va_arg(va, procinfo_vec_t*);     errbuf = va_arg(va, qstring*);     retcode = s_get_processes(procs, errbuf);   }   break;    case debugger_t::ev_start_process:   {     const char* path = va_arg(va, const char*);     const char* args = va_arg(va, const char*);     const char* startdir = va_arg(va, const char*);     uint32 dbg_proc_flags = va_arg(va, uint32);     const char* input_path = va_arg(va, const char*);     uint32 input_file_crc32 = va_arg(va, uint32);     errbuf = va_arg(va, qstring*);     retcode = s_start_process(path,       args,       startdir,       dbg_proc_flags,       input_path,       input_file_crc32,       errbuf);   }   break;    case debugger_t::ev_get_debapp_attrs:   {     debapp_attrs_t* out_pattrs = va_arg(va, debapp_attrs_t*);     out_pattrs-&gt;addrsize = 3;     out_pattrs-&gt;is_be = false;     out_pattrs-&gt;platform = &quot;snes&quot;;     out_pattrs-&gt;cbsize = sizeof(debapp_attrs_t);     retcode = DRC_OK;   }   break;    case debugger_t::ev_rebase_if_required_to:   {     ea_t new_base = va_arg(va, ea_t);     retcode = DRC_OK;   }   break;    case debugger_t::ev_request_pause:     errbuf = va_arg(va, qstring*);     retcode = prepare_to_pause_process(errbuf);     break;    case debugger_t::ev_exit_process:     errbuf = va_arg(va, qstring*);     retcode = emul_exit_process(errbuf);     break;    case debugger_t::ev_get_debug_event:   {     gdecode_t* code = va_arg(va, gdecode_t*);     debug_event_t* event = va_arg(va, debug_event_t*);     int timeout_ms = va_arg(va, int);     *code = get_debug_event(event, timeout_ms);     retcode = DRC_OK;   }   break;    case debugger_t::ev_resume:   {     debug_event_t* event = va_arg(va, debug_event_t*);     retcode = continue_after_event(event);   }   break;    case debugger_t::ev_thread_suspend:   {     thid_t tid = va_argi(va, thid_t);     pause_execution();     retcode = DRC_OK;   }   break;    case debugger_t::ev_thread_continue:   {     thid_t tid = va_argi(va, thid_t);     continue_execution();     retcode = DRC_OK;   }   break;    case debugger_t::ev_set_resume_mode:   {     thid_t tid = va_argi(va, thid_t);     resume_mode_t resmod = va_argi(va, resume_mode_t);     retcode = s_set_resume_mode(tid, resmod);   }   break;    case debugger_t::ev_read_registers:   {     thid_t tid = va_argi(va, thid_t);     int clsmask = va_arg(va, int);     regval_t* values = va_arg(va, regval_t*);     errbuf = va_arg(va, qstring*);     retcode = read_registers(tid, clsmask, values, errbuf);   }   break;    case debugger_t::ev_write_register:   {     thid_t tid = va_argi(va, thid_t);     int regidx = va_arg(va, int);     const regval_t* value = va_arg(va, const regval_t*);     errbuf = va_arg(va, qstring*);     retcode = write_register(tid, regidx, value, errbuf);   }   break;    case debugger_t::ev_get_memory_info:   {     meminfo_vec_t* ranges = va_arg(va, meminfo_vec_t*);     errbuf = va_arg(va, qstring*);     retcode = get_memory_info(*ranges, errbuf);   }   break;    case debugger_t::ev_read_memory:   {     size_t* nbytes = va_arg(va, size_t*);     ea_t ea = va_arg(va, ea_t);     void* buffer = va_arg(va, void*);     size_t size = va_arg(va, size_t);     errbuf = va_arg(va, qstring*);     ssize_t code = read_memory(ea, buffer, size, errbuf);     *nbytes = code &gt;= 0 ? code : 0;     retcode = code &gt;= 0 ? DRC_OK : DRC_NOPROC;   }   break;    case debugger_t::ev_write_memory:   {     size_t* nbytes = va_arg(va, size_t*);     ea_t ea = va_arg(va, ea_t);     const void* buffer = va_arg(va, void*);     size_t size = va_arg(va, size_t);     errbuf = va_arg(va, qstring*);     ssize_t code = write_memory(ea, buffer, size, errbuf);     *nbytes = code &gt;= 0 ? code : 0;     retcode = code &gt;= 0 ? DRC_OK : DRC_NOPROC;   }   break;    case debugger_t::ev_check_bpt:   {     int* bptvc = va_arg(va, int*);     bpttype_t type = va_argi(va, bpttype_t);     ea_t ea = va_arg(va, ea_t);     int len = va_arg(va, int);     *bptvc = is_ok_bpt(type, ea, len);     retcode = DRC_OK;   }   break;    case debugger_t::ev_update_bpts:   {     int* nbpts = va_arg(va, int*);     update_bpt_info_t* bpts = va_arg(va, update_bpt_info_t*);     int nadd = va_arg(va, int);     int ndel = va_arg(va, int);     errbuf = va_arg(va, qstring*);     retcode = update_bpts(nbpts, bpts, nadd, ndel, errbuf);   }   break;   default:     retcode = DRC_NONE;   }    return retcode; }  debugger_t debugger{     IDD_INTERFACE_VERSION,     NAME,     0x8000 + 6581, \/\/ (6)     &quot;65816&quot;,      DBG_FLAG_NOHOST | DBG_FLAG_CAN_CONT_BPT | DBG_FLAG_SAFE | DBG_FLAG_FAKE_ATTACH | DBG_FLAG_NOPASSWORD |     DBG_FLAG_NOSTARTDIR | DBG_FLAG_NOPARAMETERS | DBG_FLAG_ANYSIZE_HWBPT | DBG_FLAG_DEBTHREAD | DBG_FLAG_PREFER_SWBPTS,     DBG_HAS_GET_PROCESSES | DBG_HAS_REQUEST_PAUSE | DBG_HAS_SET_RESUME_MODE | DBG_HAS_THREAD_SUSPEND | DBG_HAS_THREAD_CONTINUE | DBG_HAS_CHECK_BPT,      register_classes,     RC_CPU,     registers,     qnumber(registers),      0x1000,      NULL,     0,     0,      DBG_RESMOD_STEP_INTO | DBG_RESMOD_STEP_OVER,      NULL,     idd_notify };<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0414\u0430\u0431\u044b \u043d\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434, \u0437\u0434\u0435\u0441\u044c \u044f \u043e\u043f\u0438\u0448\u0443 \u043b\u0438\u0448\u044c \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e Thrift \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b IDA:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">    try {       if (client) {         client-&gt;step_over();       }     }     catch (...) {       return DRC_FAILED;     }      return DRC_OK;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422.\u0435. \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c <code>BsnesDebugger<\/code> (\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c) \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043b\u0438\u0431\u043e \u043e\u0448\u0438\u0431\u043a\u0443, \u043b\u0438\u0431\u043e \u041e\u041a.<\/p>\n<p>  <\/p>\n<h3 id=\"kod-bsnesdebugger-hendlera\">\u041a\u043e\u0434 BsnesDebugger \u0445\u044d\u043d\u0434\u043b\u0435\u0440\u0430<\/h3>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0434\u043e\u0448\u043b\u0438 \u0434\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430. \u041a\u0430\u043a \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430, \u0438 \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0431\u043e\u043c\u0431\u0438\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0430\u044f \u0436\u0435 \u0437\u0434\u0435\u0441\u044c \u0443\u0436\u0430\u0441\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u0434\u0430, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0448\u0430\u0431\u043b\u043e\u043d cpp-\u0444\u0430\u0439\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043f\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">remote_debugger.cpp<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &quot;gen-cpp\/IdaClient.h&quot; #include &quot;gen-cpp\/BsnesDebugger.h&quot; #include &lt;thrift\/protocol\/TBinaryProtocol.h&gt; #include &lt;thrift\/transport\/TSocket.h&gt; #include &lt;thrift\/transport\/TBufferTransports.h&gt; #include &lt;thrift\/server\/TNonblockingServer.h&gt; #include &lt;thrift\/transport\/TNonblockingServerSocket.h&gt; #include &lt;thrift\/concurrency\/ThreadFactory.h&gt;  using namespace ::apache::thrift; using namespace ::apache::thrift::protocol; using namespace ::apache::thrift::transport; using namespace ::apache::thrift::server; using namespace ::apache::thrift::concurrency;  #include &quot;..\/ui-base.hpp&quot;  static ::std::shared_ptr&lt;IdaClientClient&gt; client; static ::std::shared_ptr&lt;TNonblockingServer&gt; srv; static ::std::shared_ptr&lt;TTransport&gt; cli_transport;  static ::std::mutex list_mutex; ::std::set&lt;int32_t&gt; visited;  static void send_visited(bool is_step) {   const auto part = visited.size();    ::std::lock_guard&lt;::std::mutex&gt; lock(list_mutex);    try {     if (client) {       client-&gt;add_visited(visited, is_step);     }   }   catch (...) {    }    visited.clear(); }  static void stop_client() {   try {     if (client) {       send_visited(false);       client-&gt;stop_event();     }     cli_transport-&gt;close();   }   catch (...) {    } }  static void init_ida_client() {   ::std::shared_ptr&lt;TTransport&gt; socket(new TSocket(&quot;127.0.0.1&quot;, 9091));   cli_transport = ::std::shared_ptr&lt;TTransport&gt;(new TFramedTransport(socket));   ::std::shared_ptr&lt;TBinaryProtocol&gt; protocol(new TBinaryProtocol(cli_transport));   client = ::std::shared_ptr&lt;IdaClientClient&gt;(new IdaClientClient(protocol));    while (true) {     try {       cli_transport-&gt;open();       break;     }     catch (...) {       Sleep(10);     }   }    atexit(stop_client); }  static void toggle_pause(bool enable) {   application.debug = enable;   application.debugrun = enable;    if (enable) {     audio.clear();   } }  class BsnesDebuggerHandler : virtual public BsnesDebuggerIf {  public:   int32_t get_cpu_reg(const BsnesRegister::type reg) override {     switch (reg) {     case BsnesRegister::pc:     case BsnesRegister::a:     case BsnesRegister::x:     case BsnesRegister::y:     case BsnesRegister::s:     case BsnesRegister::d:     case BsnesRegister::db:     case BsnesRegister::p:       return SNES::cpu.getRegister((SNES::CPUDebugger::Register)reg);     case BsnesRegister::mflag:       return (SNES::cpu.usage[SNES::cpu.regs.pc] &amp; SNES::CPUDebugger::UsageFlagM) ? 1 : 0;     case BsnesRegister::xflag:       return (SNES::cpu.usage[SNES::cpu.regs.pc] &amp; SNES::CPUDebugger::UsageFlagX) ? 1 : 0;     case BsnesRegister::eflag:       return (SNES::cpu.usage[SNES::cpu.regs.pc] &amp; SNES::CPUDebugger::UsageFlagE) ? 1 : 0;     }   }    void get_cpu_regs(BsnesRegisters&amp; _return) override {     _return.pc = SNES::cpu.getRegister(SNES::CPUDebugger::Register::RegisterPC);     _return.a = SNES::cpu.getRegister(SNES::CPUDebugger::Register::RegisterA);     _return.x = SNES::cpu.getRegister(SNES::CPUDebugger::Register::RegisterX);     _return.y = SNES::cpu.getRegister(SNES::CPUDebugger::Register::RegisterY);     _return.s = SNES::cpu.getRegister(SNES::CPUDebugger::Register::RegisterS);     _return.d = SNES::cpu.getRegister(SNES::CPUDebugger::Register::RegisterD);     _return.db = SNES::cpu.getRegister(SNES::CPUDebugger::Register::RegisterDB);     _return.p = SNES::cpu.getRegister(SNES::CPUDebugger::Register::RegisterP);      _return.mflag = (SNES::cpu.usage[SNES::cpu.regs.pc] &amp; SNES::CPUDebugger::UsageFlagM) ? 1 : 0;     _return.xflag = (SNES::cpu.usage[SNES::cpu.regs.pc] &amp; SNES::CPUDebugger::UsageFlagX) ? 1 : 0;     _return.eflag = (SNES::cpu.usage[SNES::cpu.regs.pc] &amp; SNES::CPUDebugger::UsageFlagE) ? 1 : 0;   }    void set_cpu_reg(const BsnesRegister::type reg, const int32_t value) override {     switch (reg) {     case BsnesRegister::pc:     case BsnesRegister::a:     case BsnesRegister::x:     case BsnesRegister::y:     case BsnesRegister::s:     case BsnesRegister::d:     case BsnesRegister::db:     case BsnesRegister::p:       SNES::cpu.setRegister((SNES::CPUDebugger::Register)reg, value);     }   }    void add_breakpoint(const DbgBreakpoint&amp; bpt) override {     SNES::Debugger::Breakpoint add;     add.addr = bpt.bstart;     add.addr_end = bpt.bend;     add.mode = bpt.type;     add.source = (SNES::Debugger::Breakpoint::Source)bpt.src;     SNES::debugger.breakpoint.append(add);   }    void del_breakpoint(const DbgBreakpoint&amp; bpt) override {     for (auto i = 0; i &lt; SNES::debugger.breakpoint.size(); ++i) {       auto b = SNES::debugger.breakpoint[i];        if (b.source == (SNES::Debugger::Breakpoint::Source)bpt.src &amp;&amp; b.addr == bpt.bstart &amp;&amp; b.addr_end == bpt.bend &amp;&amp; b.mode == bpt.type) {         SNES::debugger.breakpoint.remove(i);         break;       }     }   }    void read_memory(std::string&amp; _return, const DbgMemorySource::type src, const int32_t address, const int32_t size) override {     _return.clear();      SNES::debugger.bus_access = true;     for (auto i = 0; i &lt; size; ++i) {       _return += SNES::debugger.read((SNES::Debugger::MemorySource)src, address + i);     }     SNES::debugger.bus_access = false;   }    void write_memory(const DbgMemorySource::type src, const int32_t address, const std::string&amp; data) override {     SNES::debugger.bus_access = true;     for (auto i = 0; i &lt; data.size(); ++i) {       SNES::debugger.write((SNES::Debugger::MemorySource)src, address, data[i]);     }     SNES::debugger.bus_access = false;   }    void exit_emulation() override {     try {       if (client) {         send_visited(false);         client-&gt;stop_event();       }     }     catch (...) {      }      application.app-&gt;exit();   }    void pause() override {     step_into();   }    void resume() override {     toggle_pause(false);   }    void start_emulation() override {     init_ida_client();      try {       if (client) {         client-&gt;start_event();         visited.clear();         client-&gt;pause_event(SNES::cpu.getRegister(SNES::CPUDebugger::RegisterPC));       }     }     catch (...) {      }   }    void step_into() override {     SNES::debugger.step_type = SNES::Debugger::StepType::StepInto;     application.debugrun = true;      SNES::debugger.step_cpu = true;   }    void step_over() override {     SNES::debugger.step_type = SNES::Debugger::StepType::StepOver;     SNES::debugger.step_over_new = true;     SNES::debugger.call_count = 0;     application.debugrun = true;      SNES::debugger.step_cpu = true;   }  };  static void stop_server() {   srv-&gt;stop(); }  void init_dbg_server() {   ::std::shared_ptr&lt;BsnesDebuggerHandler&gt; handler(new BsnesDebuggerHandler());   ::std::shared_ptr&lt;TProcessor&gt; processor(new BsnesDebuggerProcessor(handler));   ::std::shared_ptr&lt;TNonblockingServerTransport&gt; serverTransport(new TNonblockingServerSocket(9090));   ::std::shared_ptr&lt;TFramedTransportFactory&gt; transportFactory(new TFramedTransportFactory());   ::std::shared_ptr&lt;TProtocolFactory&gt; protocolFactory(new TBinaryProtocolFactory());    srv = ::std::shared_ptr&lt;TNonblockingServer&gt;(new TNonblockingServer(processor, protocolFactory, serverTransport));   ::std::shared_ptr&lt;ThreadFactory&gt; tf(new ThreadFactory());   ::std::shared_ptr&lt;Thread&gt; thread = tf-&gt;newThread(srv);   thread-&gt;start();    atexit(stop_server);    SNES::debugger.breakpoint.reset();    SNES::debugger.step_type = SNES::Debugger::StepType::StepInto;   application.debugrun = true;   SNES::debugger.step_cpu = true; }  void send_pause_event(bool is_step) {   try {     if (client) {       client-&gt;pause_event(SNES::cpu.getRegister(SNES::CPUDebugger::RegisterPC));       send_visited(is_step);     }   }   catch (...) {    } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u044f \u0432\u0437\u044f\u043b \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u0431\u044b\u043b \u0432\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u0435, \u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b \u0435\u0433\u043e \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>BsnesDebugger<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0427\u0430\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u044f \u043d\u0435 \u0434\u0435\u043b\u0430\u043b \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u043c\u0438, \u0442.\u043a. \u043a \u043d\u0438\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0438\u0437 \u0434\u0440\u0443\u0433\u0438\u0445 \u0443\u0447\u0430\u0441\u0442\u043a\u043e\u0432 \u043a\u043e\u0434\u0430 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430. \u042d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0441\u043f\u0438\u0441\u043a\u0435:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>::std::set&lt;int32_t&gt; visited;<\/code> \u2014 \u0441\u044e\u0434\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u0438, \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u0418\u0434\u0443<\/li>\n<li><code>void init_dbg_server()<\/code> \u2014 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c RPC-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0435 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0430, \u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u043e\u043c\u0430<\/li>\n<li><code>void send_pause_event(bool is_step)<\/code> \u2014 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0418\u0434\u044b \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u044f \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430, \u043d\u043e \u0438 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u043a\u0430\u0440\u0442\u044b \u043a\u043e\u0434\u0430 (codemap). \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>bool is_step<\/code> \u0438 <code>codemap<\/code> \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0430\u0439\u0442\u0438, \u0433\u0434\u0435 \u0436\u0435 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0443 \u0441\u0442\u043e\u0438\u0442 \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043e \u043f\u0430\u0443\u0437\u0435, \u0433\u0434\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u044f, \u0438 \u0433\u0434\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u0440\u0442\u0430 \u043a\u043e\u0434\u0430. \u0412\u043e\u0442 \u044d\u0442\u0438 \u043c\u0435\u0441\u0442\u0430:<\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">alwaysinline uint8_t CPUDebugger::op_readpc() {   extern std::set&lt;int32_t&gt; visited; \/\/ \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 header   visited.insert(regs.pc); \/\/ \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043a\u0430\u0440\u0442\u0443 \u043a\u043e\u0434\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 PC    usage[regs.pc] |= UsageExec;    int offset = cartridge.rom_offset(regs.pc);   if (offset &gt;= 0) cart_usage[offset] |= UsageExec;    \/\/ execute code without setting read flag   return CPU::op_read((regs.pc.b &lt;&lt; 16) + regs.pc.w++); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 SNES \u0440\u043e\u043c\u0430:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/v6\/zs\/ec\/v6zsecivgeyvhidopvw1zul25is.png\"><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0448\u0430\u0433\u043e\u0432\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/m3\/sz\/km\/m3szkm_smjhsjsvjmk1851as01s.png\"><\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0431\u0440\u0435\u0439\u043a\u043f\u043e\u0438\u043d\u0442\u0430:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/3z\/vp\/to\/3zvptoyhnr_3dnzec1vqtbi2ihy.png\"><\/p>\n<p>  <\/p>\n<h4 id=\"hitrosti-primeneniya-codemap-v-ide\">\u0425\u0438\u0442\u0440\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f codemap \u0432 \u0418\u0434\u0435<\/h4>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0445\u0438\u0442\u0440\u043e\u0441\u0442\u044f\u0445 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0432 IDA, \u0438 \u0437\u0430\u0442\u0435\u043c \u0441\u043e \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e\u0439 (\u043d\u043e \u043f\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u044e\u0449\u0435\u0439 &quot;\u0441\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043b\u0438&quot;) \u0434\u0443\u0448\u043e\u0439 \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 <code>Build Solution<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0432\u0437\u044f\u0442\u044c \u0438 \u0432 \u0446\u0438\u043a\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u0435\u043d\u044f\u044e\u0442 IDB (\u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0432 IDA) \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043d\u0435\u043b\u044c\u0437\u044f \u2014 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043b\u0435\u0442\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0440\u0430\u0437, \u0438 \u0434\u043e\u0432\u043e\u0434\u0438\u0442\u044c \u0441\u0432\u043e\u0438\u043c \u043d\u0435\u043f\u043e\u0441\u0442\u043e\u044f\u043d\u0441\u0442\u0432\u043e\u043c \u0434\u043e \u0441\u0443\u043c\u0430\u0441\u0448\u0435\u0441\u0442\u0432\u0438\u044f. \u041d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e-\u0443\u043c\u043d\u043e\u043c\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c IDB \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">static struct apply_codemap_req : public exec_request_t { private:   const std::set&lt;int32_t&gt;&amp; _changed;   const bool _is_step; public:   apply_codemap_req(const std::set&lt;int32_t&gt;&amp; changed, bool is_step) : _changed(changed), _is_step(is_step) {};    int idaapi execute(void) override {     auto m = _changed.size();      if (!_is_step) {       show_wait_box(&quot;Applying codemap: %d\/%d...&quot;, 1, m);     }      auto x = 0;     for (auto i = _changed.cbegin(); i != _changed.cend(); ++i) {       if (!_is_step &amp;&amp; user_cancelled()) {         break;       }        if (!_is_step) {         replace_wait_box(&quot;Applying codemap: %d\/%d...&quot;, x, m);       }        ea_t addr = (ea_t)(*i | 0x800000);       auto_make_code(addr);       plan_ea(addr);       show_addr(addr);       x++;     }      if (!_is_step) {       hide_wait_box();     }      return 0;   } };  static void apply_codemap(const std::set&lt;int32_t&gt;&amp; changed, bool is_step) {   if (changed.empty()) return;    apply_codemap_req req(changed, is_step);   execute_sync(req, MFF_FAST); }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0442\u043e \u0441\u0443\u0442\u044c \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 <code>execute_sync()<\/code> \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0432\u043e\u0435\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>exec_request_t<\/code> \u0438 \u0435\u0451 \u043a\u043e\u043b\u0431\u044d\u043a\u0430 <code>int idaapi execute(void)<\/code>. \u042d\u0442\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431.<\/p>\n<p>  <\/p>\n<h2 id=\"vyvody-i-kompilyaciya\">\u0412\u044b\u0432\u043e\u0434\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d-\u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u0434\u043b\u044f IDA. \u041c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043a\u0430\u043a \u0440\u0430\u0437 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0418\u0434\u043e\u0439 \u0438 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u043e\u043c \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u0430 Thrift \u043f\u043e\u0434\u043e\u0448\u0451\u043b \u043a\u0430\u043a \u043d\u0435\u043b\u044c\u0437\u044f \u043a\u0441\u0442\u0430\u0442\u0438. \u0421 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0443\u0441\u0438\u043b\u0438\u044f\u043c\u0438 \u043c\u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0443\u044e \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0434\u043b\u044f \u043e\u0431\u0435\u0438\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u0435 \u0433\u043e\u0440\u043e\u0434\u044f \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u044b \u0432 \u0432\u0438\u0434\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0441\u043e\u043a\u0435\u0442\u043e\u0432 \u043f\u043e \u0440\u0430\u0437\u043d\u043e\u043c\u0443 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c, \u0438 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0435\u043d\u0438\u044f RPC \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u043d\u0443\u043b\u044f.<\/p>\n<p>  <\/p>\n<p>\u041a \u0442\u043e\u043c\u0443 \u0436\u0435, \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043b\u0435\u0433\u043a\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u043b\u0435\u0433\u043a\u043e \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c.<\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435\u043c \u0441\u043f\u0430\u0441\u0438\u0431\u043e!<\/p>\n<p>  <\/p>\n<hr>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/lab313ru\/snesida\" rel=\"nofollow noopener noreferrer\">Snesida<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/435002\/\">\u041c\u043e\u0434\u0435\u0440\u043d\u0438\u0437\u0430\u0446\u0438\u044f IDA Pro. \u041e\u0442\u043b\u0430\u0434\u0447\u0438\u043a \u0434\u043b\u044f Sega Mega Drive (\u0447\u0430\u0441\u0442\u044c 2)<\/a><\/li>\n<li><a href=\"https:\/\/thrift.apache.org\/download\" rel=\"nofollow noopener noreferrer\">Thrift<\/a><\/li>\n<\/ul>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/551102\/\"> https:\/\/habr.com\/ru\/post\/551102\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xf\/3x\/of\/xf3xofalflutqv7ki1kwbau5onq.png\"><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e,<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u044f \u043e\u0447\u0435\u043d\u044c \u0441\u0442\u0430\u0440\u0430\u044f \u043c\u0435\u0447\u0442\u0430 \u0441\u0431\u044b\u043b\u0430\u0441\u044c \u2014 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043c\u043e\u0434\u0443\u043b\u044c-\u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c SNES (<em>Super Nintendo<\/em>) \u0438\u0433\u0440\u044b \u043f\u0440\u044f\u043c\u043e \u0432 <code>IDA<\/code>! \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a \u044f \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b, &quot;\u043f\u0440\u043e\u0448\u0443 \u043f\u043e\u0434 \u043a\u0430\u0442&quot; (\u043a\u0430\u043a \u0442\u0443\u0442 \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c).<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-321531","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/321531","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=321531"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/321531\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=321531"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=321531"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=321531"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}