
рдЗрд╕ рдиреЛрдЯ рдореЗрдВ, рд╣рдо рд╕реАрдЦреЗрдВрдЧреЗ рдХрд┐ рдПрдХ рд░рди рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдорд╢реАрди рдХреЛрдб рдХреЛ рд╕реАрдзреЗ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ, рдПрдХ рдбрд┐рд╕реНрд╕реЗрдореНрдмрд▓рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдкреНрд░рд┐рдВрдЯ рдХрд░реЗрдВ, рдФрд░ рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рд╣рдо рдмрд┐рдирд╛ рдХреЙрд▓ рдХрд┐рдП рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрддреЗ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдЬреИрд╕реЗ рдХрдИ рддрд░рдХреАрдмреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВрдЧреЗред
рдЪреЗрддрд╛рд╡рдиреА : рдпрд╣ рд▓рдШреБ-рд▓реЗрдЦ рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧреА рдХреБрдЫ рднреА рдирд╣реАрдВ рд╕рд┐рдЦрд╛рдПрдЧрд╛ред
рдЬрд╛рдУ рдореЗрдВ рд╕рдорд╛рд░реЛрд╣ рдореВрд▓реНрдп
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ рдХрд┐ рдПрдХ рдЧреЛ рдлрд╝рдВрдХреНрд╢рди рдХреНрдпрд╛ рд╣реИ рдФрд░ рд╣рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдорд╛рди рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИред
рдпрд╣ рдЧреЛ 1.1 рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рджреНрд╡рд╛рд░рд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдордЭрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдирдпрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЬрд╛рдирдХрд╛рд░реА рдЕрднреА рднреА рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИред
рдирд┐рдореНрдирддрдо рд╕реНрддрд░ рдкрд░, рдпрд╣ рд╣рдореЗрд╢рд╛ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рд╣рдо рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди / рдХреНрд▓реЛрдЬрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ interface{}
рд░реВрдк рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕реВрдЪрдХ рдХреБрдЫ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдЕрдВрджрд░ рдЫрд┐рдкрд╛ рд╣реЛрддрд╛ рд╣реИред
рдлрд╝рдВрдХреНрд╢рди рдирд╛рдо рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдРрд╕рд╛ рдХреЛрдб рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ:
compile: cannot take the address of add1
рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рд╣рдо рдПрдХ рд╣реА рдлрд╝рдВрдХреНрд╢рди рдирд╛рдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ function value
рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
рдпрд╣ рдХреЛрдб рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдЯреИрдХ рдкрд░ рдПрдХ рд╕реНрдерд╛рдиреАрдп рд╡реИрд░рд┐рдПрдмрд▓ рдХреЗ рдкрддреЗ рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░реЗрдЧрд╛, рдЬреЛ рдХрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╣рдо рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рдереЗред рд▓реЗрдХрд┐рди, рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рдЕрднреА рднреА рд╣реИ, рдЖрдкрдХреЛ рдмрд╕ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПред
reflect
рдкреИрдХреЗрдЬ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред reflect.Value.Call()
ред рд╡рд╣рд╛рдБ (рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд / makefunc.go) рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЧрд▓реЗ рдЪрд░рдг рдХреА рдЬрд╛рд╕реВрд╕реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
dummy := makeFuncStub code := **(**uintptr)(unsafe.Pointer(&dummy))
рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдПрдХ рдореВрд▓ рд╡рд┐рдЪрд╛рд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рд╖реНрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
add1
рдлрд╝рдВрдХреНрд╢рди add1
рдХреЛ funcAddr(add1)
рдХреЙрд▓ рдХрд░рдХреЗ add1
рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдорд╢реАрди рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рдХрд╛ рдмреНрд▓реЙрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛
рдЕрдм рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдорд╢реАрди рдХреЛрдб рдХреА рд╢реБрд░реБрдЖрдд рдХрд╛ рдкрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкреВрд░реЗ рдорд╢реАрди рдХреЛрдб рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдпрд╣рд╛рдВ рдЖрдкрдХреЛ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХреЛрдб рдХрд╣рд╛рдВ рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред
рдпрджрд┐ x86 рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдиреЗ рдирд┐рд╢реНрдЪрд┐рдд-рд▓рдВрдмрд╛рдИ рдирд┐рд░реНрджреЗрд╢ рджрд┐рдП рдереЗ, рддреЛ рдпрд╣ рдЗрддрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдФрд░ рдХрдИ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА рд╣рдорд╛рд░реА рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ:
- рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рдХреЗ рдЕрдВрдд рдореЗрдВ
INT3
рдирд┐рд░реНрджреЗрд╢реЛрдВ рд╕реЗ рдПрдХ рдмреАрдЯ рд╣реИред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рдХреЗ рдЕрдВрдд рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫрд╛ рдорд╛рд░реНрдХрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЧрд╛рдпрдм рд╣реЛ рд╕рдХрддрд╛ рд╣реИред - рд╕реНрдЯреИрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧреИрд░-рд╢реВрдиреНрдп рдлреНрд░реЗрдо рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдПрдХ рдкреНрд░реЛрд▓реЙрдЧ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕ рд╕реНрдЯреИрдХ рдХреЛ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рд╣рд╛рдБ, рддреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдХреВрдж рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдлрд╝рдВрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП рдПрдХ рдХреВрджред рдЬрд┐рд╕ рдХреЛрдб рдореЗрдВ рд╣рдо рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рд╡рд╣ рдордзреНрдп рдореЗрдВ рд╣реЛрдЧрд╛ред
рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдбрд┐рдХреЛрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдмрд╛рдЗрдЯ-рджрд░-рдкрд╛рд╕ рджреВрд╕рд░реЗ рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдЕрдВрджрд░ INT3
рдмрд╛рдЗрдЯ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╕реНрдХрд┐рдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рд░реНрджреЗрд╢ рдХреА рд▓рдВрдмрд╛рдИ рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рднреА рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ x86, рдмреЗрдмреА рд╣реИ ред
runtime
рдкреИрдХреЗрдЬ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рдХрднреА-рдХрднреА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░ рдХрд╣реАрдВ рдФрд░ рдкрддреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкрд░ рдЬреЛрд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, PC
рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рди рдХреЗрд╡рд▓ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБред funcAddr
рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ funcAddr
рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред funcAddr
runtime.FuncForPC()
рдлрд╝рдВрдХреНрд╢рди рдХреЛ funcAddr
рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд┐рдП рдмрд┐рдирд╛ред рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдирдП рд╕рд╛рд▓ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рд╣рдо runtime._func
рддрдХ рдкрд╣реБрдБрдЪ рд╕рдХрддреЗ рд╣реИрдВред runtime._func
, рдЬреЛ рдЬрд╛рдирдХрд╛рд░реАрдкреВрд░реНрдг рд╣реИ, рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рд╣реИ: рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рдмреНрд▓реЙрдХ рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИред
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдИрдПрд▓рдПрдл рдХреА рдорджрдж рдХреЗ рдмрд┐рдирд╛ рд╣рдо рд╕рд╛рдордирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред
рдЙрди рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХреЗ рд▓рд┐рдП рдЬрд╣рд╛рдВ рдПрдХреНрдЬрд╝реАрдХреНрдпреВрдЯреЗрдмрд▓реНрд╕ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рдкреНрд░рд╛рд░реВрдк рд╣реИ, рдЕрдзрд┐рдХрд╛рдВрд╢ рд▓реЗрдЦ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд░рд╣реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ debug/elf
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди debug
рд╕реЗ рдПрдХ рдФрд░ рдкреИрдХреЗрдЬред
рдИрдПрд▓рдПрдл рдЬреЛ рдЖрдкрдХреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдЫрд┐рдкрд╛ рд╣реИ
рд╣рдореЗрдВ рдЬреЛ рдЬрд╛рдирдХрд╛рд░реА рдЪрд╛рд╣рд┐рдП рд╡рд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдИрдПрд▓рдПрдл рдлрд╝рд╛рдЗрд▓ рдХреЗ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИред
os.Args[0]
рдорд╛рдзреНрдпрдо рд╕реЗ os.Args[0]
рд╣рдо рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕реНрд╡рдпрдВ рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
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) }
elf.File
рдЕрдВрджрд░ рдПрдХ рдЪрд░рд┐рддреНрд░ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬреЗрдВ
рд╕рднреА рд╡рд░реНрдгреЛрдВ рдХреЛ File.Symbols()
рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ File.Symbols()
рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ рд▓реМрдЯрд╛рддреА рд╣реИ []elf.Symbol
, рдЬрд┐рд╕рдореЗрдВ Symbol.Size
рдлрд╝реАрд▓реНрдб рд╢рд╛рдорд┐рд▓ рд╣реИ - рдпрд╣ "рдлрд╝рдВрдХреНрд╢рди рдЖрдХрд╛рд░" рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо Symbol.Size
ред Symbol.Value
рдлрд╝реАрд▓реНрдб рдХреЛ funcAddr
рджреНрд╡рд╛рд░рд╛ funcAddr
рдЧрдП рдорд╛рди рд╕реЗ рдореЗрд▓ рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЖрдк рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рддреАрдХ (рдкрддреЗ) ( Symbol.Value
) рдпрд╛ рдирд╛рдо ( Symbol.Name
) рджреНрд╡рд╛рд░рд╛ рдЦреЛрдЬ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рд╡рд░реНрдг рдирд╛рдо рд╕реЗ рдХреНрд░рдордмрджреНрдз рд╣реЛрддреЗ рд╣реИрдВ, рддреЛ sort.Search()
рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред sort.Search()
, рд▓реЗрдХрд┐рди рдпрд╣ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ:
рдкреНрд░рддреАрдХреЛрдВ рдХреЛ рдЙрд╕ рдХреНрд░рдо рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬреЛ рд╡реЗ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВред
рдпрджрд┐ рдЖрдкрдХреЛ рдЕрдХреНрд╕рд░ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд╡рд░реНрдг рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реВрдЪрдХрд╛рдВрдХ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, map[string]*elf.Symbol
рдпрд╛ map[uintptr]*elf.Symbol
ред
рдЪреВрдВрдХрд┐ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рдЙрд╕рдХреЗ рдореВрд▓реНрдп рд╕реЗ рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдП, рддреЛ рд╣рдо рдЙрд╕рдХреА рдЦреЛрдЬ рдХрд░реЗрдВрдЧреЗ:
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 &sym } } return nil }
рдиреЛрдЯ : рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рдЪрд░рд┐рддреНрд░ рддрд╛рд▓рд┐рдХрд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдмрд╛рдЗрдирд░реА рдХреЛ ` -ldflags "-s"
'рдХреЗ рд╕рд╛рде рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ elfLookup()
рд╣рдореЗрд╢рд╛ nil
рд▓реМрдЯреЗрдЧрд╛ред рдпрджрд┐ рдЖрдк go run
рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо go run
рддреЛ рдЖрдк рдЙрд╕реА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдЦ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП ' go build
' рдпрд╛ ' go install
' рдХрд░рдиреЗ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреА рдЬрд╛рддреА рд╣реИред
рдорд╢реАрди рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛
рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдХреЛрдб рдХреЗ рдкрддреЗ рдХреА рд╕реАрдорд╛ рдЬрд╛рдирдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рдХреЗрд╡рд▓ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП []byte
рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рдирд╛ рд╣реИред
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(&reflect.SliceHeader{ Data: addr, Len: int(sym.Size), Cap: int(sym.Size), })) return code, nil }
рдпрд╣ рдХреЛрдб рдЬрд╛рдирдмреВрдЭрдХрд░ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдкрдХреЛ рд╣рд░ рдмрд╛рд░ ELF
рдирд╣реАрдВ рдкрдврд╝рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕рдХреА рдореЗрдЬ рдкрд░ рдПрдХ рд░реЗрдЦреАрдп рдЦреЛрдЬ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред
funcCode()
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдорд╢реАрди рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рдХреЗ рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдЯреБрдХрдбрд╝рд╛ рд╣реИред рдЙрд╕реЗ funcAddr()
рдХреЙрд▓ funcAddr()
рдкрд░рд┐рдгрд╛рдо funcAddr()
рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
code, err := funcCode(funcAddr(add1)) if err != nil { log.Panicf("can't get function code: %v", err) } fmt.Printf("% x\n", code)
рдорд╢реАрди рдХреЛрдб рдЬреБрджрд╛ рдХрд░рдирд╛
рдорд╢реАрди рдХреЛрдб рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдбрд┐рд╕реНрд╕реЗрдореНрдмрд▓рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рдореИрдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ zydis рдФрд░ Intel XED рд╕реЗ рд╕рдмрд╕реЗ рдЬреНрдпрд╛рджрд╛ рдкрд░рд┐рдЪрд┐рдд рд╣реВрдВ , рдЗрд╕рд▓рд┐рдП рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдореЗрд░реА рдкрд╕рдВрдж рдЙрди рдкрд░ рдкрдбрд╝рддреА рд╣реИред
Go рдХреЗ рд▓рд┐рдП, рдЖрдк go-zydis рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдФрд░ рдЖрд╕рд╛рди рд╣реИред
рдЖрдЗрдП рд╣рдо "рдорд╢реАрди рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рджрд░рдХрд┐рдирд╛рд░" рдХреЗ рдЕрдореВрд░реНрдд рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреА рдорджрдж рд╕реЗ рдЕрдиреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ:
func walkDisasm(code []byte, visit func(*zydis.DecodedInstruction) error) error { dec := zydis.NewDecoder(zydis.MachineMode64, zydis.AddressWidth64) buf := code for len(buf) > 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 }
рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдорд╢реАрди рдХреЛрдб рд╕реНрд▓рд╛рдЗрд╕ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдбрд┐рдХреЛрдб рдХрд┐рдП рдЧрдП рдирд┐рд░реНрджреЗрд╢ рдХреЗ рд▓рд┐рдП рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо printDisasm
рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ printDisasm
рд╣рдореЗрдВ printDisasm
:
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 }) }
рдпрджрд┐ рд╣рдо add1
рдлрд╝рдВрдХреНрд╢рди add1
рдкрд░ printDisasm
рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд┐рдд рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓рддрд╛ рд╣реИ:
mov rax, [rsp+0x08] inc rax mov [rsp+0x10], rax ret
рдкрд░рд┐рдгрд╛рдо рдорд╛рдиреНрдпрддрд╛
рдЕрдм рд╣рдо рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдкрд┐рдЫрд▓реЗ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХреЛрдбрд╛рдВрддрд░рдХ рдХреЛрдб рд╕рд╣реА рд╣реИред
рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╕рдВрдХрд▓рд┐рдд рдмрд╛рдЗрдирд░реА рд╣реИ, рдЖрдк рдЧреЛ рдХреЗ рд╕рд╛рде рдЖрдкреВрд░реНрддрд┐ рдХреА рдЧрдИ objdump
рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
$ 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
рд╕рдм рдХреБрдЫ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рд╣реИ, рдЬреЛ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИред
рд╡рд┐рдзрд┐ рдХреЗ рднрд╛рд╡
рдпрджрд┐ рд╣рдореЗрдВ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдлрд╝рдВрдХреНрд╢рди рдирд╛рдо рдХреЗ рдмрдЬрд╛рдп рд╣рдо рд╡рд┐рдзрд┐ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░рд╛ add1
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ add1
рдЯрд╛рдЗрдк рд╡рд┐рдзрд┐ рд╣реИ:
type adder struct{} func (adder) add1(x int) int { return x + 2 }
рддрдм рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ funcAddr(adder.add1)
рддрд░рд╣ funcAddr(adder.add1)
рджреЗрдЧрд╛ред
рдирд┐рд╖реНрдХрд░реНрд╖
рдореИрдВ рджреБрд░реНрдШрдЯрдирд╛ рд╕реЗ рдирд╣реАрдВ рдЗрди рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдпрд╛ рдерд╛ рдФрд░, рд╢рд╛рдпрдж, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓реЗрдЦреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдЗрди рд╕рднреА рддрдВрддреНрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдХреИрд╕реЗ рдмрдирд╛рдИ рдЧрдИ рдереАред рдЗрд╕ рдмреАрдЪ, рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рдЗрд╕ рдмрд╛рдд рдХрд╛ рд╕рддрд╣реА рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ runtime
рдФрд░ рдлрдВрдХреНрд╢рди рд╡реИрд▓реНрдпреВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рдорд╛рд░реЗ рдЧреЛ рдлрд╝рдВрдХреНрд╢рдВрд╕ reflect
рдХреИрд╕реЗ reflect
ред
рдкреНрд░рдпреБрдХреНрдд рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рд╕реВрдЪреА: