{"id":296575,"date":"2019-12-29T21:00:15","date_gmt":"2019-12-29T21:00:15","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=296575"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=296575","title":{"rendered":"ELF\u0438\u0439\u0441\u043a\u0438\u0435 \u0442\u0440\u044e\u043a\u0438 \u0432 Go"},"content":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/482392\/\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/hd\/mj\/7h\/hdmj7hkb2kyjkyyybccynazhd7s.png\"><\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0437\u0430\u043c\u0435\u0442\u043a\u0435 \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 Go \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u044f\u043c\u043e \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435, \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c \u0435\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0438\u0437\u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0430 \u0438 \u043f\u043e \u043f\u0443\u0442\u0438 \u0443\u0437\u043d\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u043e\u043a\u0443\u0441\u043e\u0432 \u0432\u0440\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0435\u0437 \u0435\u0451 \u0432\u044b\u0437\u043e\u0432\u0430.<\/p>\n<p>  <\/p>\n<p><strong>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435<\/strong>: \u043d\u0438\u0447\u0435\u043c\u0443 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u043c\u0443 \u044d\u0442\u0430 \u043c\u0438\u043d\u0438-\u0441\u0442\u0430\u0442\u044c\u044f \u0432\u0430\u0441 \u043d\u0435 \u043d\u0430\u0443\u0447\u0438\u0442.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h1 id=\"function-value-v-go\">Function value \u0432 Go<\/h1>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 Go \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438 \u0437\u0430\u0447\u0435\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u0438\u0435 <strong>function value<\/strong>.<\/p>\n<p>  <\/p>\n<p>\u041b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 <a href=\"https:\/\/golang.org\/s\/go11func\">Go 1.1 Function Calls<\/a>. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u043d\u0435 \u043d\u043e\u0432\u044b\u0439, \u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 \u043d\u0451\u043c \u0432\u0441\u0451 \u0435\u0449\u0451 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u043d\u0438\u0437\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u043a\u043e\u0434, \u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438\/\u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043a\u0430\u043a <code>interface{}<\/code>, \u044d\u0442\u043e\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<p>  <\/p>\n<p>\u0421\u0430\u043c\u043e \u043f\u043e \u0441\u0435\u0431\u0435 \u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/ https:\/\/play.golang.org\/p\/wXeVLU7nLPs package main func add1(x int) int { return 1 } func main() {     addr := &amp;add1     println(addr) }<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p><code>compile: cannot take the address of add1<\/code><\/p><\/blockquote>\n<p>\u041d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <code>function value<\/code> \u0447\u0435\u0440\u0435\u0437 \u0442\u043e \u0436\u0435 \u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/ https:\/\/play.golang.org\/p\/oWqv_FQq4hy package main func add1(x int) int { return 1 } func main() {     f := add1 \/\/ &lt;--------     addr := &amp;f     println(addr) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u043f\u0435\u0447\u0430\u0442\u0430\u0442\u044c \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0430\u0434\u0440\u0435\u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435, \u0447\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u043e, \u0447\u0435\u0433\u043e \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438. \u041d\u043e, \u043a\u0430\u043a \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432\u044b\u0448\u0435, \u0430\u0434\u0440\u0435\u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0441\u0451 \u0435\u0449\u0451 \u0442\u0430\u043c, \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a \u043a \u043d\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u0438\u0442\u044c\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u041f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/golang.org\/pkg\/reflect\/\"><code>reflect<\/code><\/a> \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u044d\u0442\u043e\u0439 \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c <a href=\"https:\/\/golang.org\/pkg\/reflect\/#Value.Call\"><code>reflect.Value.Call()<\/code><\/a>. <a href=\"https:\/\/github.com\/golang\/go\/blob\/dcd3b2c173b77d93be1c391e3b5f932e0779fb1f\/src\/reflect\/makefunc.go#L56-L60\">\u0422\u0430\u043c \u0436\u0435 (reflect\/makefunc.go)<\/a> \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0448\u0430\u0433 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">dummy := makeFuncStub code := **(**uintptr)(unsafe.Pointer(&amp;dummy))<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u0434 \u0432\u044b\u0448\u0435 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0438\u0434\u0435\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">\/\/ funcAddr returns function value fn executable code address. func funcAddr(fn interface{}) uintptr {     \/\/ emptyInterface is the header for an interface{} value.     type emptyInterface struct {         typ   uintptr         value *uintptr     }     e := (*emptyInterface)(unsafe.Pointer(&amp;fn))     return *e.value }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>add1<\/code> \u043c\u043e\u0436\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 <code>funcAddr(add1)<\/code>.<\/p>\n<p>  <\/p>\n<h1 id=\"poluchenie-bloka-mashinnogo-koda-funkcii\">\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h1>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0435\u0441\u044c \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0417\u0434\u0435\u0441\u044c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043c\u0435\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c, \u0433\u0434\u0435 \u0436\u0435 \u043a\u043e\u0434 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 x86 \u0438\u043c\u0435\u043b\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b, \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435 \u0442\u0430\u043a \u0441\u043b\u043e\u0436\u043d\u043e \u0438 \u043d\u0430\u043c \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u043e\u043c\u043e\u0447\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0432\u0440\u0438\u0441\u0442\u0438\u043a, \u0441\u0440\u0435\u0434\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0435\u0441\u0442\u044c \u043e\u0442\u0431\u0438\u0432\u043a\u0430 \u0438\u0437 <a href=\"https:\/\/en.wikipedia.org\/wiki\/INT_(x86_instruction)#INT3\"><code>INT3<\/code><\/a> \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439. \u042d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043c\u0430\u0440\u043a\u0435\u0440 \u043a\u043e\u043d\u0446\u0430 \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043d\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c.<\/li>\n<li>\u0423 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0441 \u043d\u0435\u043d\u0443\u043b\u0435\u0432\u044b\u043c \u0444\u0440\u0435\u0439\u043c\u043e\u043c \u0434\u043b\u044f \u0441\u0442\u0435\u043a\u0430 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u043b\u043e\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u0442\u0435\u043a. \u0415\u0441\u043b\u0438 \u0434\u0430, \u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u044b\u0436\u043e\u043a \u043d\u0430 \u043a\u043e\u0434 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430 \u043a\u043e\u0434\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u044b\u0436\u043e\u043a \u043d\u0430 \u0441\u0442\u0430\u0440\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0418\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0439 \u043d\u0430\u0441 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041d\u043e \u0432\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0447\u0435\u0441\u0442\u043d\u043e \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0445\u043e\u0434 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0439\u0442\u0438 \u0431\u0430\u0439\u0442 <code>INT3<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u0438\u043d\u044b \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0435\u0451 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430 \u0442\u043e\u0436\u0435 \u043d\u0435 \u0442\u0430\u043a \u043b\u0435\u0433\u043a\u043e, <a href=\"https:\/\/stackoverflow.com\/questions\/45801447\/x86-assembly-how-to-calculate-instruction-opcodes-length-in-bytes\">\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e x86, \u0434\u0435\u0442\u043a\u0430<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0410\u0434\u0440\u0435\u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 <a href=\"https:\/\/golang.org\/pkg\/runtime\"><code>runtime<\/code><\/a> \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 <code>PC<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0447\u0435\u0440\u043a\u043d\u0443\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0433\u0434\u0435-\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0447\u043a\u0443 \u0432\u0445\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <code>funcAddr<\/code> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <a href=\"https:\/\/golang.org\/pkg\/runtime\/#FuncForPC\"><code>runtime.FuncForPC()<\/code><\/a>, \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f <a href=\"https:\/\/golang.org\/pkg\/runtime\/#Func\"><code>runtime.Func<\/code><\/a> \u0431\u0435\u0437 \u0432\u044b\u0437\u043e\u0432\u0430 \u0441\u0430\u043c\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0427\u0435\u0440\u0435\u0437 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0435 \u043d\u043e\u0432\u043e\u0433\u043e\u0434\u043d\u0438\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a <a href=\"https:\/\/play.golang.org\/p\/lQxxK36ZXru\"><code>runtime._func<\/code><\/a>, \u0447\u0442\u043e \u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e: \u0442\u0430\u043c \u043d\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u0431\u043b\u043e\u043a\u0430 \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0445\u043e\u0436\u0435, \u0431\u0435\u0437 \u043f\u043e\u043c\u043e\u0449\u0438 <a href=\"https:\/\/golang.org\/pkg\/debug\/elf\/\">ELF\u043e\u0432<\/a> \u043c\u044b \u043d\u0435 \u0441\u043f\u0440\u0430\u0432\u0438\u043c\u0441\u044f.<\/p>\n<p>  <\/p>\n<blockquote><p>\u0414\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0438\u043c\u0435\u044e\u0442 \u0438\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442, \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u0430, \u043d\u043e \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 <a href=\"https:\/\/golang.org\/pkg\/debug\/elf\/\"><code>debug\/elf<\/code><\/a>, \u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0430\u043a\u0435\u0442 \u0438\u0437 <a href=\"https:\/\/golang.org\/pkg\/debug\/\"><code>debug<\/code><\/a>.<\/p><\/blockquote>\n<p>  <\/p>\n<h1 id=\"elf-kotoryy-pryachetsya-v-vashey-programme\">ELF, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u044f\u0447\u0435\u0442\u0441\u044f \u0432 \u0432\u0430\u0448\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435<\/h1>\n<p>  <\/p>\n<p>\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430, \u0443\u0436\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u0432 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Executable_and_Linkable_Format#File_header\">ELF<\/a> \u0444\u0430\u0439\u043b\u0430.<\/p>\n<p>  <\/p>\n<p>\u0427\u0435\u0440\u0435\u0437 <a href=\"https:\/\/golang.org\/pkg\/os\/#pkg-variables\"><code>os.Args[0]<\/code><\/a> \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u043c\u0443 \u0444\u0430\u0439\u043b\u0443, \u0430 \u0443\u0436\u0435 \u0438\u0437 \u043d\u0435\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func readELF() (*elf.File, error) {     f, err := os.Open(os.Args[0])     if err != nil {         return nil, fmt.Errorf(\"open argv[0]: %w\", err)     }     return elf.NewFile(f) }<\/code><\/pre>\n<p>  <\/p>\n<h1 id=\"poisk-simvola-vnutri-elffilehttpsgolangorgpkgdebugelffile\">\u041f\u043e\u0438\u0441\u043a \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 <a href=\"https:\/\/golang.org\/pkg\/debug\/elf\/#File\"><code>elf.File<\/code><\/a><\/h1>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043c\u043e\u0436\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <a href=\"https:\/\/golang.org\/pkg\/debug\/elf\/#File.Symbols\"><code>File.Symbols()<\/code><\/a>. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <a href=\"https:\/\/golang.org\/pkg\/debug\/elf\/#Symbol\"><code>[]elf.Symbol<\/code><\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043f\u043e\u043b\u0435 <code>Symbol.Size<\/code> \u2014 \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u0438\u0441\u043a\u043e\u043c\u044b\u0439 \u043d\u0430\u043c\u0438 &#171;\u0440\u0430\u0437\u043c\u0435\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438&#187;. \u041f\u043e\u043b\u0435 <code>Symbol.Value<\/code> \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u043c <code>funcAddr<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u043a\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u043c\u043e\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 (<code>Symbol.Value<\/code>), \u043b\u0438\u0431\u043e \u043f\u043e \u0438\u043c\u0435\u043d\u0438 (<code>Symbol.Name<\/code>). \u0415\u0441\u043b\u0438 \u0431\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0431\u044b\u043b\u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043f\u043e \u0438\u043c\u0435\u043d\u0438, \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c <a href=\"https:\/\/golang.org\/pkg\/sort\/#Search\"><code>sort.Search()<\/code><\/a>, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<blockquote><p>The symbols will be listed in the order they appear in file.<\/p><\/blockquote>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0447\u0430\u0441\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u0442\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0435\u0440\u0435\u0437 <code>map[string]*elf.Symbol<\/code> \u0438\u043b\u0438 <code>map[uintptr]*elf.Symbol<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e \u0435\u0451 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e, \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u043f\u043e \u043d\u0435\u043c\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func elfLookup(f *elf.File, value uint64) *elf.Symbol {     symbols, err := f.Symbols()     if err != nil {         return nil     }     for _, sym := range symbols {         if sym.Value == value {             return &amp;sym         }     }     return nil }<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p><strong>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u0415\u0441\u043b\u0438 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u0441\u043e\u0431\u0440\u0430\u043d \u0441 &#8216;<code>-ldflags \"-s\"<\/code>&#8216;, \u0442\u043e <code>elfLookup()<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c <code>nil<\/code>. \u0415\u0441\u043b\u0438 \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0447\u0435\u0440\u0435\u0437 <code>go run<\/code> \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u0441 \u0442\u043e\u0439 \u0436\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c &#8216;<code>go build<\/code>&#8216; \u0438\u043b\u0438 &#8216;<code>go install<\/code>&#8216; \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432.<\/p><\/blockquote>\n<p>  <\/p>\n<h1 id=\"poluchenie-mashinnogo-koda-funkcii\">\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/h1>\n<p>  <\/p>\n<p>\u0417\u043d\u0430\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0430\u0434\u0440\u0435\u0441\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u043a\u043e\u0434, \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u0432\u0438\u0434\u0435 <code>[]byte<\/code> \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func funcCode(addr uintptr) ([]byte, error) {     elffile, err := readELF()     if err != nil {         return nil, fmt.Errorf(\"read elf: %w\", err)     }     sym := elfLookup(elffile, uint64(addr))     if sym == nil {         return nil, fmt.Errorf(\"can't lookup symbol for %x\", addr)     }     code := *(*[]byte)(unsafe.Pointer(&amp;reflect.SliceHeader{         Data: addr,         Len:  int(sym.Size),         Cap:  int(sym.Size),     }))     return code, nil }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438. \u041d\u0435 \u0441\u0442\u043e\u0438\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0447\u0438\u0442\u0430\u0442\u044c <code>ELF<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u043f\u043e\u0438\u0441\u043a \u043f\u043e \u0435\u0433\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u0435.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>funcCode()<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0430\u0439\u0441 \u0441 \u0431\u0430\u0439\u0442\u0430\u043c\u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u041d\u0430 \u0432\u0445\u043e\u0434 \u0435\u0439 \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0437\u043e\u0432\u0430 <code>funcAddr()<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">code, err := funcCode(funcAddr(add1)) if err != nil {     log.Panicf(\"can't get function code: %v\", err) } fmt.Printf(\"% x\\n\", code) \/\/ =&gt; 48 8b 44 24 08 48 ff c0 48 89 44 24 10 c3<\/code><\/pre>\n<p>  <\/p>\n<h1 id=\"dizassemblirovanie-mashinnogo-koda\">\u0414\u0438\u0437\u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430<\/h1>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0449\u0435 \u0447\u0438\u0442\u0430\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434, \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0434\u0438\u0437\u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>\u042f \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u0437\u043d\u0430\u043a\u043e\u043c \u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438 <a href=\"https:\/\/github.com\/zyantific\/zydis\">zydis<\/a> \u0438 <a href=\"https:\/\/github.com\/intelxed\/xed\">Intel XED<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043c\u043e\u0439 \u0432\u044b\u0431\u043e\u0440 \u043f\u0430\u0434\u0430\u0435\u0442 \u043d\u0430 \u043d\u0438\u0445.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f Go \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u0431\u0438\u043d\u0434\u0438\u043d\u0433 <a href=\"https:\/\/github.com\/jpap\/go-zydis\">go-zydis<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448 \u0438 \u043f\u0440\u043e\u0441\u0442 \u0432 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0438\u0448\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e &#171;\u043e\u0431\u0445\u043e\u0434\u0430 \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439&#187;, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func walkDisasm(code []byte, visit func(*zydis.DecodedInstruction) error) error {     dec := zydis.NewDecoder(zydis.MachineMode64, zydis.AddressWidth64)      buf := code     for len(buf) &gt; 0 {         instr, err := dec.Decode(buf)         if err != nil {             return err         }         if err := visit(instr); err != nil {             return err         }         buf = buf[int(instr.Length):]     }      return nil }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u043b\u0430\u0439\u0441 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 callback-\u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u0435\u0451 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u0443\u044e \u043d\u0430\u043c <code>printDisasm<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">func printDisasm(code []byte) error {     const ZYDIS_RUNTIME_ADDRESS_NONE = math.MaxUint64     formatter, err := zydis.NewFormatter(zydis.FormatterStyleIntel)     if err != nil {         return err     }     return walkDisasm(code, func(instr *zydis.DecodedInstruction) error {         s, err := formatter.FormatInstruction(instr, ZYDIS_RUNTIME_ADDRESS_NONE)         if err != nil {             return err         }         fmt.Println(s)         return nil     }) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c <code>printDisasm<\/code> \u043d\u0430 \u043a\u043e\u0434\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>add1<\/code>, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0434\u043e\u043b\u0433\u043e\u0436\u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">mov rax, [rsp+0x08] inc rax mov [rsp+0x10], rax ret<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"validaciya-rezultata\">\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430<\/h2>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0435\u043a\u0446\u0438\u0438, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0441 Go <code>objdump<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">$ go tool objdump -s 'add1' exe TEXT main.add1(SB) example.go   example.go:15    0x4bb760    488b442408    MOVQ 0x8(SP), AX   example.go:15    0x4bb765    48ffc0        INCQ AX   example.go:15    0x4bb768    4889442410    MOVQ AX, 0x10(SP)   example.go:15    0x4bb76d    c3            RET<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u0441\u0451 \u0441\u0445\u043e\u0434\u0438\u0442\u0441\u044f, \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0439, \u0447\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e.<\/p>\n<p>  <\/p>\n<h1 id=\"method-expressions\">Method expressions<\/h1>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0435 \u0441 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438, \u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0438\u043c\u0435\u043d\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/golang.org\/ref\/spec#Method_expressions\">method expression<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043d\u0430\u0448 <code>add1<\/code> \u2014 \u044d\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043d\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0430 \u043c\u0435\u0442\u043e\u0434 \u0442\u0438\u043f\u0430 <code>adder<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"go\">type adder struct{}  func (adder) add1(x int) int { return x + 2 }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0432\u044b\u0437\u043e\u0432 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0430\u043a <code>funcAddr(adder.add1)<\/code>.<\/p>\n<p>  <\/p>\n<h1 id=\"zaklyuchenie\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0448\u0451\u043b \u044f \u043a \u044d\u0442\u0438\u043c \u0432\u0435\u0449\u0430\u043c \u043d\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0438, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u044d\u0442\u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b. \u0410 \u043f\u043e\u043a\u0430 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u043a \u044d\u0442\u043e\u0439 \u0437\u0430\u043c\u0435\u0442\u043a\u0435 \u043a\u0430\u043a \u043a \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u043d\u043e\u043c\u0443 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a <code>runtime<\/code> \u0438 <code>reflect<\/code> \u0441\u043c\u043e\u0442\u0440\u044f\u0442 \u043d\u0430 \u043d\u0430\u0448\u0438 Go \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 function value.<\/p>\n<p>  <\/p>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/golang.org\/s\/go11func\">Go 1.1 Function Calls<\/a><\/li>\n<li><a href=\"https:\/\/www.pnfsoftware.com\/blog\/analyzing-golang-executables\/\">Analyzing Golang Executables<\/a><\/li>\n<li><a href=\"https:\/\/go.googlesource.com\/proposal\/+\/master\/design\/27539-internal-abi.md\">Go &#171;internal ABI&#187; design<\/a><\/li>\n<\/ul>\n<\/div>\n<p>               <script class=\"js-mediator-script\">!function(e){function t(t,n){if(!(n in e)){for(var r,a=e.document,i=a.scripts,o=i.length;o--;)if(-1!==i[o].src.indexOf(t)){r=i[o];break}if(!r){r=a.createElement(\"script\"),r.type=\"text\/javascript\",r.async=!0,r.defer=!0,r.src=t,r.charset=\"UTF-8\";var d=function(){var e=a.getElementsByTagName(\"script\")[0];e.parentNode.insertBefore(r,e)};\"[object Opera]\"==e.opera?a.addEventListener?a.addEventListener(\"DOMContentLoaded\",d,!1):e.attachEvent(\"onload\",d):d() } } }t(\"\/\/mediator.mail.ru\/script\/2820404\/\",\"_mediator\")}(window);<\/script>      <br \/> \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\/482392\/\"> https:\/\/habr.com\/ru\/post\/482392\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/482392\/\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/hd\/mj\/7h\/hdmj7hkb2kyjkyyybccynazhd7s.png\"><\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0437\u0430\u043c\u0435\u0442\u043a\u0435 \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 Go \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u044f\u043c\u043e \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435, \u0440\u0430\u0441\u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c \u0435\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0438\u0437\u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u0430 \u0438 \u043f\u043e \u043f\u0443\u0442\u0438 \u0443\u0437\u043d\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u043e\u043a\u0443\u0441\u043e\u0432 \u0432\u0440\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0435\u0437 \u0435\u0451 \u0432\u044b\u0437\u043e\u0432\u0430.<\/p>\n<p>  <\/p>\n<p><strong>\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435<\/strong>: \u043d\u0438\u0447\u0435\u043c\u0443 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u043c\u0443 \u044d\u0442\u0430 \u043c\u0438\u043d\u0438-\u0441\u0442\u0430\u0442\u044c\u044f \u0432\u0430\u0441 \u043d\u0435 \u043d\u0430\u0443\u0447\u0438\u0442.<\/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-296575","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/296575","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=296575"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/296575\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=296575"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=296575"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=296575"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}