рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛

рд╣рдо рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░реЗрдВрдЧреЗ - рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рдХреЗ рд╕реНрдерд╛рди рдореЗрдВ рдПрдХ рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ, рдЗрд╕рдореЗрдВ рдХреБрдЫ рдмрд╛рдЗрдирд░реА рдХреЛрдб рдбрд╛рд▓реЗрдВ рдФрд░ рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рдЗрд╕рдореЗрдВ рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдлреВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдмрд╛рдЗрдирд░реА рдХреЛрдб рдХреА рднреВрдорд┐рдХрд╛ рдирд┐рднрд╛рдПрдЧрд╛, рдлрд┐рд░, рдореЙрдбреНрдпреВрд▓_alloc рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдореЗрдореЛрд░реА рдмреНрд▓реЙрдХ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ, рдкреВрд░реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдореЗрдорд╕реАрдкреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрдкреА рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдирд┐рдпрдВрддреНрд░рдг рджреЗрдВред

рдпрд╣рд╛рдБ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:

static noinline int foo(int ret)
{
	return (ret + 2);
}

static int exe_init(void)
{
	int ret = 0;
	int (*new_foo)(int);

	ret = foo(0);
	printk(KERN_INFO "ret=%d\n", ret);

	new_foo = module_alloc(PAGE_SIZE);
	set_memory_x((unsigned long)new_foo, 1);

	printk(KERN_INFO "foo=%lx new_foo=%lx\n",
		(unsigned long)foo, (unsigned long)new_foo);

	memcpy((void *)new_foo, (const void *)foo, PAGE_SIZE);

	ret = new_foo(1);
	printk(KERN_INFO "ret=%d\n", ret);

	vfree(new_foo);
	return 0;
}

рдЬрдм рдореЙрдбреНрдпреВрд▓ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ exe_init рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдХрд░реНрдиреЗрд▓ рд▓реЙрдЧ рдореЗрдВ рдХрд╛рдо рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ:

[ 6972.522422] ret=2
[ 6972.522443] foo=ffffffffc0000000 new_foo=ffffffffc0007000
[ 6972.522457] ret=3

рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред рдФрд░ рдЕрдм рд╣рдо рддрд░реНрдХ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП foo рдореЗрдВ рдкреНрд░рд┐рдВрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:

static noinline int foo(int ret)
{
	printk(KERN_INFO "ret=%d\n", ret);
	return (ret + 2);
}

рдФрд░ рдЗрд╕реЗ рдкрд╛рд╕ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ new_foo () рдлрд╝рдВрдХреНрд╢рди рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЗ 25 рдмрд╛рдЗрдЯреНрд╕ рдбрдВрдк рдХрд░реЗрдВ:

	memcpy((void *)new_foo, (const void *)foo, PAGE_SIZE);
	dump((unsigned long)new_foo);

рдбрдВрдк рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ

static inline void dump(unsigned long x)
{
	int i;
	for (i = 0; i < 25; i++) \
		pr_cont("%.2x ", *((unsigned char *)(x) + i) & 0xFF); \
	pr_cont("\n");
}

рд╣рдо рдореЙрдбреНрдпреВрд▓ рдХреЛ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд▓реЙрдЧ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрджреЗрд╢ рдХреЗ рд╕рд╛рде рдПрдХ рджреБрд░реНрдШрдЯрдирд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:

[ 8482.806092] ret=0
[ 8482.806092] ret=2
[ 8482.806111] foo=ffffffffc0000000 new_foo=ffffffffc0007000
[ 8482.806113] 53 89 fe 89 fb 48 c7 c7 24 10 00 c0 e8 e8 3d 0b c1 8d 43 02 5b c3 66 2e 0f 
[ 8482.806135] invalid opcode: 0000 [#1] SMP NOPTI
[ 8482.806639] CPU: 0 PID: 5081 Comm: insmod Tainted: G           O      5.4.27 #12
[ 8482.807669] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[ 8482.808560] RIP: 0010:irq_create_direct_mapping+0x79/0x90

рдХрд┐рд╕реА рддрд░рд╣, рд╣рдо irq_create_direct_mapping рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдП, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣рдореЗрдВ рдкреНрд░рд┐рдВрдЯрдХ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдерд╛ред рдЖрдЗрдП рдЬрд╛рдиреЗрдВ рдХреНрдпрд╛ рд╣реБрдЖред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдлреВ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрд╕рдВрддреБрд╖реНрдЯ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред рдЗрд╕реЗ objdump -d рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:

Disassembly of section .text:

0000000000000000 <foo>:
   0:	53                   	push   %rbx
   1:	89 fe                	mov    %edi,%esi
   3:	89 fb                	mov    %edi,%ebx
   5:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi
   c:	e8 00 00 00 00       	callq  11 <foo+0x11>
  11:	8d 43 02             	lea    0x2(%rbx),%eax
  14:	5b                   	pop    %rbx
  15:	c3                   	retq   
  16:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  1d:	00 00 00 

рдлреВ рдлрд╝рдВрдХреНрд╢рди рдкрд╛рда рдЕрдиреБрднрд╛рдЧ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИред рдСрдлрд╝рд╕реЗрдЯ 0xC рдкрд░, рдкрд╛рд╕ рдХреЙрд▓ рдХрдорд╛рдВрдб e8 рдХрд╛ opcode рд╕реНрдерд┐рдд рд╣реИ - рдирд┐рдХрдЯ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕реЗ рд╡рд░реНрддрдорд╛рди рдХреЛрдб рд╕реЗрдЧрдореЗрдВрдЯ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЪрдпрдирдХрд░реНрддрд╛ рдорд╛рди рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред рдЕрдЧрд▓реЗ 4 рдмрд╛рдЗрдЯреНрд╕ рдЖрд░рдЖрдИрдкреА рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рдореВрд▓реНрдп рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдСрдлрд╕реЗрдЯ рд╣реИрдВ, рдЬрд┐рд╕ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЕрд░реНрдерд╛рддред RIP = RIP + рдСрдлрд╕реЗрдЯ, Intel рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг (Intel 64 рдФрд░ IA-32 рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рдореИрдиреБрдЕрд▓, рдирд┐рд░реНрджреЗрд╢ рд╕реЗрдЯ рд╕рдВрджрд░реНрдн AZ) рдХреЗ рдЕрдиреБрд╕рд╛рд░:
рдПрдХ рд░рд┐рд╢реНрддреЗрджрд╛рд░ рдСрдлрд╕реЗрдЯ (rel16 рдпрд╛ rel32) рдЖрдо рддреМрд░ рдкрд░ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЛрдб рдореЗрдВ рдПрдХ рд▓реЗрдмрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдорд╢реАрди рдХреЛрдб рд╕реНрддрд░ рдкрд░, рдпрд╣ рдПрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд, 16- рдпрд╛ 32-рдмрд┐рдЯ рддрддреНрдХрд╛рд▓ рдореВрд▓реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдПрдиреНрдХреЛрдбреЗрдб рд╣реИред
рдпрд╣ рдорд╛рди EIP (RIP) рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рдорд╛рди рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред 64-рдмрд┐рдЯ рдореЛрдб рдореЗрдВ рд╕рд╛рдкреЗрдХреНрд╖ рдСрдлрд╝рд╕реЗрдЯ рд╣рдореЗрд╢рд╛ рдПрдХ 32-рдмрд┐рдЯ рддрд╛рддреНрдХрд╛рд▓рд┐рдХ рдорд╛рди рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рд▓рдХреНрд╖реНрдп рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП RIP рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рдореВрд▓реНрдп рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ 64-рдмрд┐рдЯ рддрдХ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рд╣реЛрддрд╛ рд╣реИред

рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдлреВ рдХрд╛ рдкрддрд╛ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдпрд╣ 0xffffffffc0000000 рд╣реИ, рдЗрд╕рд▓рд┐рдП RIP = 0xffffffcc0000000 + 0xc + 0x5 = 0xffffffffc00000011 (0xc, e8 рдирд┐рд░реНрджреЗрд╢ рдкрд░ рдСрдлрд╝рд╕реЗрдЯ рд╣реИ, рдирд┐рд░реНрджреЗрд╢ рдХреЗ 1 рдмрд╛рдЗрдЯ рдФрд░ рдСрдлрд╝рд╕реЗрдЯ рдСрдлрд╝ 4 рдмрд╛рдЗрдЯреНрд╕)ред рд╣рдо рдСрдлрд╕реЗрдЯ рдЬрд╛рдирддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╢рд░реАрд░ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдмрд╛рдзрд╛ред рдЖрдЗрдП рдЧрдгрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдлрдВрдХреНрд╢рди рдлреВ рдореЗрдВ рд╣рдореЗрдВ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХрд╣рд╛рдВ рднреЗрдЬреЗрдЧрд╛:

0xffffffffc00000011 + 0xffffffffc10b3de8 = 0xffffffff810b3df9

рдпрд╣ рдкреНрд░рд┐рдВрдЯ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рд╣реИ:
# cat /proc/kallsyms | grep ffffffff810b3df9  
ffffffff810b3df9 T printk

рдФрд░ рдЕрдм рд╡рд╣реА new_foo рдХреЗ рд▓рд┐рдП рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдкрддрд╛ 0xffffffcc0007000 рд╣реИ

0xffffffffc0007011 + 0xffffffffc10b3de8 = 0xffffffff810badf9

рдХреЙрд▓реНрд╕ рдЬрд┐рдо рдореЗрдВ рдРрд╕рд╛ рдХреЛрдИ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди 0xffffffff810badf9 рд╣реИ - 0x79 = 0xffffffff810bad80
# cat /proc/kallsyms | grep ffffffff810bad80
ffffffff810bad80 T irq_create_direct_mapping

рдпрд╣ рд╡рд╣реА рдХрд╛рд░реНрдп рд╣реИ рдЬрд┐рд╕ рдкрд░ рджреБрд░реНрдШрдЯрдирд╛ рд╣реБрдИ рдереАред

рдПрдХ рджреБрд░реНрдШрдЯрдирд╛ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рдирдП_рдлреВ рдлрдВрдХреНрд╢рди рдХреЗ рдкрддреЗ рдХреЛ рдЬрд╛рдирдХрд░, рдСрдлрд╕реЗрдЯ рдХреЛ рдкреБрдирд░реНрдЧрдгрдирд╛ рдХрд░реЗрдВ:

memcpy((void *)new_foo, (const void *)foo, PAGE_SIZE);
unsigned int delta = (unsigned long)printk - (unsigned long)new_foo - 0x11;
*(unsigned int *)((void *)new_foo + 0xD) = delta;

рдЗрд╕ рд╕реБрдзрд╛рд░ рдХреЗ рдмрд╛рдж, рдХреЛрдИ рджреБрд░реНрдШрдЯрдирд╛ рдирд╣реАрдВ рд╣реЛрдЧреА, new_foo рдлрд╝рдВрдХреНрд╢рди рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдФрд░ рдирд┐рдпрдВрддреНрд░рдг рд╡рд╛рдкрд╕ рдХрд░реЗрдЧрд╛ред

рд╕рдорд╕реНрдпрд╛ рд╕реБрд▓рдЭ рдЧрдИ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ рдХрд┐ рдИ 8 рдУрдкрдХреЛрдб рд╢реВрдиреНрдп рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдСрдлрд╕реЗрдЯ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдбрд┐рд╕реНрд╕реЗрдореНрдмрд▓рд░ рдореЗрдВ рдХреНрдпреЛрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдбрдВрдк рдореЗрдВ рдХреЛрдИ рдлрд╝рдВрдХреНрд╢рди рдирд╣реАрдВ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреНрдпрд╛ рд╣реИрдВ рдФрд░ рдХрд░реНрдиреЗрд▓ рдЙрдирдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ, рдИрдПрд▓рдПрдл рдкреНрд░рд╛рд░реВрдк рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ред

рдИрдПрд▓рдПрдл рдХрд╛ рдЕрд░реНрде рд╣реИ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдФрд░ рд▓рд┐рдВрдХ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдкреНрд░рд╛рд░реВрдк - рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдФрд░ рд╕рдВрдпреЛрдЬрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдкреНрд░рд╛рд░реВрдкред рдПрдХ рдИрдПрд▓рдПрдл рдлрд╝рд╛рдЗрд▓ рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИред рдЕрдиреБрднрд╛рдЧ рд▓рд┐рдВрдХрд░ рдХреЗ рд▓рд┐рдП рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдЫрд╡рд┐ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ - рдирд┐рд░реНрджреЗрд╢, рдбреЗрдЯрд╛, рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛рдУрдВ, рд░рд┐рд▓реЗрд╢рдВрд╕ рдХреЗ рд░рд┐рдХреЙрд░реНрдб рдЖрджрд┐ред рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрднрд╛рдЧ рдХрд╛ рд╢реАрд░реНрд╖рдХ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╕рднреА рд╣реЗрдбрд░ рдХреЛ рд╣реЗрдбрд░ рдХреА рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдПрдХ рд╕рд░рдгреА рд╣реЛрддреА рд╣реИ рдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХрд╛ рдПрдХ рдЗрдВрдбреЗрдХреНрд╕ рд╣реЛрддрд╛ рд╣реИред рд╕реЗрдХреНрд╢рди рд╣реЗрдбрд░ рдореЗрдВ рд╕реЗрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ рдЕрдиреНрдп рдУрд╡рд░рд╣реЗрдб рд╕реВрдЪрдирд╛рдУрдВ рдХреА рднрд░рдкрд╛рдИ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕реЗ рд╣реЗрдбрд░ рдЯреЗрдмрд▓ рдореЗрдВ рдХрд┐рд╕реА рдЗрдВрдбреЗрдХреНрд╕ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдХреЗ рдЕрдиреНрдп рд╕реЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдВрдХред

рдЬрдм рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдВрдХрд▓рдХ рдХреЛ рдкреНрд░рд┐рдВрдЯ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рдкрддрд╛ рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХреЙрд▓ рд╕реНрдерд╛рди рдХреЛ рд╢реВрдиреНрдп рдорд╛рди рд╕реЗ рднрд░рддрд╛ рд╣реИ рдФрд░, рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рд░рд┐рдХреЙрд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдХрд░реНрдиреЗрд▓ рдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕реНрдерд┐рддрд┐ рдПрдХ рд╡реИрдз рдорд╛рди рд╕реЗ рднрд░реА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред рдПрдХ рд░рд┐рд▓реЛрдХреЗрд╢рди рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ рдЙрд╕ рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдСрдлрд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рд░рд┐рд▓реЛрдХреЗрд╢рди рдкреЛрдЬрд╝рд┐рд╢рди), рд░рд┐рд▓реЛрдХреЗрд╢рди рдХрд╛ рдкреНрд░рдХрд╛рд░ рдФрд░ рд╕рд┐рдВрдмрд▓ рдЯреЗрдмрд▓ рдореЗрдВ рд╕рд┐рдВрдмрд▓ рдХрд╛ рдЗрдВрдбреЗрдХреНрд╕, рдЬрд┐рд╕рдХрд╛ рдкрддрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдСрдлрд╝рд╕реЗрдЯ рдореЗрдВ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рд╣реИ? рд╣рдо рдиреАрдЪреЗ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рд░рд┐рд▓реЛрдХреЗрд╢рди рд░рд┐рдХреЙрд░реНрдбреНрд╕ рдХреЗ рд╕реЗрдХреНрд╢рди рдХрд╛ рд╢реАрд░реНрд╖рдХ рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реЗрдХреНрд╢рди рдХреЗ рд╣реЗрдбрд┐рдВрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реЗрдХреНрд╢рди рдФрд░ рдХреИрд░реЗрдХреНрдЯрд░ рдХреЗ рдЯреЗрдмрд▓ рдХреЗ рд╕рд╛рде рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд░рд┐рд▓реЗрд╢рди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдСрдлрд╕реЗрдЯ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЖрдк -r рд╕реНрд╡рд┐рдЪ рдХреЗ рд╕рд╛рде objdump рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рд░рд┐рдХреЙрд░реНрдб рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред
рдЕрд╕рдВрддреБрд╖реНрдЯ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рд╕реЗ, рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдСрдлрд╕реЗрдЯ 0xD рдкрд░ рдкреНрд░рд┐рдВрдЯрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рд▓рд┐рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдирд┐рдореНрди рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде objdump рдЖрдЙрдЯрдкреБрдЯ рдХреА рддрд▓рд╛рд╢ рдХрд░рддреЗ рд╣реИрдВ:

000000000000000d R_X86_64_PC32     printk-0x0000000000000004

рддреЛ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдСрдлрд╕реЗрдЯ 0xD рдкрд░ рд╕реНрдерд┐рддрд┐ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЖрд╡рд╢реНрдпрдХ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рд░рд┐рдХреЙрд░реНрдб рд╣реИ, рдФрд░ рдкреНрд░рддреАрдХ рдХрд╛ рдирд╛рдо рдЬрд┐рд╕рдХрд╛ рдкрддрд╛ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рд▓рд┐рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдорд╛рди (-4)ред рдЬрд┐рд╕реЗ рдкреНрд░рд┐рдВрдЯрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрддреЗ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреЛ рдкрд░рд┐рд╢рд┐рд╖реНрдЯ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреЗ рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╕рдордп рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЕрдм рдкреНрд░рд┐рдВрдЯ рдкреНрд░рддреАрдХ рдХреЛ рджреЗрдЦреЗрдВ:

$ objdump -t exe.ko | grep printk
0000000000000000         *UND*	0000000000000000 printk

рдПрдХ рдкреНрд░рддреАрдХ рд╣реИ, рдпрд╣ рдореЙрдбреНрдпреВрд▓ (рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд) рдХреЗ рдЕрдВрджрд░ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдЦреЛрдЬ рдХрд░реЗрдВрдЧреЗред

рдмрд╛рдЗрдирд░реА рд░реВрдк рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдФрд░ рдкреНрд░рддреАрдХреЛрдВ рдХреЗ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рджреЗрдЦрдирд╛ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реАрдкреВрд░реНрдг рд╣реЛрдЧрд╛ред рдпрд╣ рд╡рд╛рдпрд░рд╢рд╛рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдИрдПрд▓рдПрдл рдкреНрд░рд╛рд░реВрдк рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣рд╛рдБ рд╣рдорд╛рд░реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ (рд░рд╛рдЗрдЯрд░реНрд╕ рд╕реЗ рдХреЙрдкреА рдкреЗрд╕реНрдЯ, рдмрд╛рдИрдВ рдУрд░ рдПрд▓рдПрд╕рдмреА) рд╣реИ:

  0d 00 00 00 00 00 00 00  02 00 00 00 22 00 00 00  fc ff ff ff ff ff ff ff
  |                     |  |          ||         |  |                     |
  +----  -------+  +--  ---++---+  +---- addendum  ------+

рдЗрд╕ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреА рддреБрд▓рдирд╛ рдЗрд╕реА рд╕рдВрд░рдЪрдирд╛ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рд╕реЗ рдХрд░реЗрдВ <linux / elf.h>:

typedef struct elf64_rela {
  Elf64_Addr r_offset;	/* Location at which to apply the action */
  Elf64_Xword r_info;	/* index and type of relocation */
  Elf64_Sxword r_addend;	/* Constant addend used to compute value */
} Elf64_Rela;

рдпрд╣рд╛рдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ 8 рдмрд╛рдЗрдЯреНрд╕ рд╣реИрдВ 0x00000000d, 4 рдмрд╛рдЗрдЯреНрд╕ рдЯрд╛рдЗрдк рдХрд░реЗрдВ 0x00000002, рдХреИрд░реЗрдХреНрдЯрд░ рдЯреЗрдмрд▓ 0x00000022 (рдпрд╛ рджрд╢рдорд▓рд╡ рдореЗрдВ 34) рдФрд░ 8 рдмрд╛рдЗрдЯреНрд╕ рдкрд░рд┐рд╢рд┐рд╖реНрдЯ -4 рдореЗрдВ 4 рдмрд╛рдЗрдЯреНрд╕ рдЗрдВрдбреЗрдХреНрд╕ред

рдФрд░ рдпрд╣рд╛рдБ 34 рдирдВрдмрд░ рдкрд░ рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рд╣реИ:

  01 01 00 00 10 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рд╕рдВрд░рдЪрдирд╛

typedef struct elf64_sym {
  Elf64_Word st_name;		/* Symbol name, index in string tbl */
  unsigned char	st_info;	/* Type and binding attributes */
  unsigned char	st_other;	/* No defined meaning, 0 */
  Elf64_Half st_shndx;		/* Associated section index */
  Elf64_Addr st_value;		/* Value of the symbol */
  Elf64_Xword st_size;		/* Associated symbol size */
} Elf64_Sym;

рдкрд╣рд▓реЗ 4 рдмрд╛рдЗрдЯреНрд╕ 0x00000101 рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреА рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд╕реВрдЪрдХрд╛рдВрдХ рд╣реИред рдЗрд╕ рдЪрд░рд┐рддреНрд░ рдХреЗ рдирд╛рдо рдХреЗ рд▓рд┐рдПред printkред St_info рдлрд╝реАрд▓реНрдб рдкреНрд░рддреАрдХ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдПрдХ рдлрд╝рдВрдХреНрд╢рди, рдбреЗрдЯрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдЖрджрд┐ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдИрдПрд▓рдПрдл рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рджреЗрдЦреЗрдВред рд╣рдо st_other рдлрд╝реАрд▓реНрдб рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗ, рдЕрдм рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХреЛрдИ рджрд┐рд▓рдЪрд╕реНрдкреА рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЕрдВрддрд┐рдо рддреАрди рдлрд╝реАрд▓реНрдб st_shndx, st_value рдФрд░ st_size рджреЗрдЦреЗрдВред st_shndx - рдЙрд╕ рдЦрдВрдб рдХрд╛ рд╣реЗрдбрд░ рдЗрдВрдбреЗрдХреНрд╕ рдЬрд┐рд╕рдореЗрдВ рд╡рд░реНрдг рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╣рдо рдпрд╣рд╛рдВ рдПрдХ рд╢реВрдиреНрдп рдорд╛рди рджреЗрдЦрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреАрдХ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдЙрдкрд▓рдмреНрдз рд╡рд░реНрдЧреЛрдВ рдореЗрдВ рдирд╣реАрдВ рд╣реИред
рддрджрдиреБрд╕рд╛рд░, рдЗрд╕рдХрд╛ st_value рдорд╛рди рдФрд░ st_size рдХрд╛ рдЖрдХрд╛рд░ рднреА рд╢реВрдиреНрдп рд╣реИред рдореЙрдбреНрдпреВрд▓ рд▓реЛрдб рдХрд░рддреЗ рд╕рдордп рдпреЗ рдлрд╝реАрд▓реНрдб рдХрд░реНрдиреЗрд▓ рджреНрд╡рд╛рд░рд╛ рднрд░реЗ рдЬрд╛рдПрдВрдЧреЗред

рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП, рдкреНрд░рддреАрдХ рдлреВ рдХреЛ рджреЗрдЦреЗрдВ, рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдореМрдЬреВрдж рд╣реИ:

  08 00 00 00 02 00 02 00  00 00 00 00 00 00 00 00  16 00 00 00 00 00 00 00

рдкреНрд░рддреАрдХ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдХрд┐ 0x00000000 рдЕрдиреБрднрд╛рдЧ рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдкрддреЗ рдкрд░ .text рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ, рдЕрд░реНрдерд╛рддреНред рдЦрдВрдб рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдЕрд╕рдВрддреБрд╖реНрдЯ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдореЗрдВ рджреЗрдЦрд╛, рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЖрдХрд╛рд░ 22 рдмрд╛рдЗрдЯреНрд╕ рд╣реИред

рдУрдмрдЬрдбрдореНрдк рд╣рдореЗрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕рдорд╛рди рдЬрд╛рдирдХрд╛рд░реА рджрд┐рдЦрд╛рдПрдВрдЧреЗ:

$ objdump -t exe.ko | grep foo
0000000000000000 l     F .text	0000000000000016 foo

рдЬрдм рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдХреЛ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕рднреА рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдЕрдХреНрд╖рд░ рдкрд╛рддрд╛ рд╣реИ рдФрд░ рдорд╛рдиреНрдп рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде st_value рдФрд░ st_size рдлрд╝реАрд▓реНрдб рднрд░рддрд╛ рд╣реИред рдпрд╣ simpleify_symbols рдлрд╝рдВрдХреНрд╢рди, рдХрд░реНрдиреЗрд▓ / рдореЙрдбреНрдпреВрд▓.рд╕реА. рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

/* Change all symbols so that st_value encodes the pointer directly. */
static int simplify_symbols(struct module *mod, const struct load_info *info)
{
...

рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлреЙрд░реНрдо рдХрд╛ load_info рд╕рдВрд░рдЪрдирд╛ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ

struct load_info {
	const char *name;
	/* pointer to module in temporary copy, freed at end of load_module() */
	struct module *mod;
	Elf_Ehdr *hdr;
	unsigned long len;
	Elf_Shdr *sechdrs;
	char *secstrings, *strtab;
	unsigned long symoffs, stroffs, init_typeoffs, core_typeoffs;
	struct _ddebug *debug;
	unsigned int num_debug;
	bool sig_ok;
#ifdef CONFIG_KALLSYMS
	unsigned long mod_kallsyms_init_off;
#endif
	struct {
		unsigned int sym, str, mod, vers, info, pcpu;
	} index;
};

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝реАрд▓реНрдб рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ:
-
рдПрдЪрдбреАрдЖрд░ - рдИрдПрд▓рдПрдл рдлрд╝рд╛рдЗрд▓ рд╣реЗрдбрд░ - рд╕реАрдЪрдбреНрд░реНрд╕ - рд╕реЗрдХреНрд╢рди рд╣реЗрдбрд░ рдЯреЗрдмрд▓ рдХреЗ рд▓рд┐рдП рд╕реВрдЪрдХ
- рд╕реНрдЯреНрд░реИрдЯрдм - рдкреНрд░рддреАрдХ рдирд╛рдо рддрд╛рд▓рд┐рдХрд╛ - рд╢реВрдиреНрдп рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдП рдЧрдП рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХрд╛ рдПрдХ рд╕реЗрдЯ
- index.sym - рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рд╡рд╛рд▓реЗ рдЕрдиреБрднрд╛рдЧ рд╣реЗрдбрд░ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХреНрд╕реЗрд╕ рдорд┐рд▓реЗрдЧрд╛ред рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рд╛рде рдЕрдиреБрднрд╛рдЧред рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ Elf64_Sym рдкреНрд░рдХрд╛рд░ рдХреЗ рддрддреНрд╡реЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рд╣реИ:

Elf64_Shdr *symsec = &info->sechdrs[info->index.sym];
Elf64_Sym *sym = (void *)symsec->sh_addr;

рдЕрдЧрд▓рд╛, рд▓реВрдк рдореЗрдВ, рд╣рдо рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рднреА рд╡рд░реНрдгреЛрдВ рд╕реЗ рдЧреБрдЬрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдЗрд╕рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдирд╛рдо рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) {
	const char *name = info->strtab + sym[i].st_name;

St_shndx рдлрд╝реАрд▓реНрдб рдореЗрдВ рдЙрд╕ рдЕрдиреБрднрд╛рдЧ рдХрд╛ рд╣реЗрдбрд░ рдЗрдВрдбреЗрдХреНрд╕ рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рд╡рд░реНрдг рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ рд╢реВрдиреНрдп рдорд╛рди (рд╣рдорд╛рд░рд╛ рдорд╛рдорд▓рд╛) рд╣реИ, рддреЛ рдпрд╣ рдкреНрд░рддреАрдХ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЕрдВрджрд░ рдирд╣реАрдВ рд╣реИ, рдЖрдкрдХреЛ рдЗрд╕реЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рджреЗрдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

	switch (sym[i].st_shndx) {
	.....
	 case SHN_UNDEF: //  0
	ksym = resolve_symbol_wait(mod, info, name);
 	/* Ok if resolved.  */
	if (ksym && !IS_ERR(ksym)) {
		sym[i].st_value = kernel_symbol_value(ksym);
		break;
	}

рдЙрд╕рдХреЗ рдмрд╛рдж apply_relocations рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХрддрд╛рд░ рдЖрддреА рд╣реИ:

static int apply_relocations(struct module *mod, const struct load_info *info)
{
	unsigned int i;
	int err = 0;

	/* Now do relocations. */
	for (i = 1; i < info->hdr->e_shnum; i++) {
	.....

рд▓реВрдк рдореЗрдВ, рд╣рдо рд░рд┐рд▓реЛрдХреЗрд╢рди рд╕реЗрдХреНрд╢рди рдХреА рддрд▓рд╛рд╢ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдХреНрд╢рди рдХреЗ рд░рд┐рдХреЙрд░реНрдбреНрд╕ рдХреЛ apply_relocate_add рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:

if (info->sechdrs[i].sh_type == SHT_RELA) //   
	err = apply_relocate_add(info->sechdrs, info->strtab,
				info->index.sym, i, mod);

рд╕реЗрдХреНрд╢рди рд╣реЗрдбрд░ рдЯреЗрдмрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░, рд╕рд┐рдВрдмрд▓ рдиреЗрдо рдЯреЗрдмрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░, рд╕рд┐рдВрдмрд▓ рдЯреЗрдмрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рд╕реЗрдХреНрд╢рди рд╣реИрдбрд░ рдЗрдВрдбреЗрдХреНрд╕, рдФрд░ рдПрдХ рд░реАрд╡реЛрдХреЗрд╢рди рд╕реЗрдХреНрд╢рди рд╣реЗрдбрд░ рдЗрдВрдбреЗрдХреНрд╕ рдХреЛ apply_relocate_add рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

int apply_relocate_add(Elf64_Shdr *sechdrs,
	   const char *strtab,
	   unsigned int symindex,
	   unsigned int relsec,
	   struct module *me)
{

рдкрд╣рд▓реЗ рд╣рдо рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдЦрдВрдб рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;

рдлрд┐рд░, рдПрдХ рд▓реВрдк рдореЗрдВ, рд╣рдо рдЗрд╕рдХреА рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реЙрд░реНрдЯ рдХрд░рддреЗ рд╣реИрдВ:

for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {

рд╣рдо рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП рдЕрдиреБрднрд╛рдЧ рдвреВрдВрдврддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдореЗрдВ рд╕реНрдерд┐рддрд┐, рдЕрд░реНрдерд╛рддреНред рдЬрд╣рд╛рдВ рд╣рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдЕрдиреБрднрд╛рдЧ рд╣реЗрдбрд░ рдХрд╛ sh_info рдХреНрд╖реЗрддреНрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП рдЕрдиреБрднрд╛рдЧ рд╢реАрд░реНрд╖рд▓реЗрдЦ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рд╣реИ, рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рд░рд┐рдХреЙрд░реНрдб рдХрд╛ r_offset рдХреНрд╖реЗрддреНрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП рдЦрдВрдб рдХреЗ рдЕрдВрджрд░ рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдСрдлрд╕реЗрдЯ рд╣реИ:

/* This is where to make the change */
loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;

рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЪрд░рд┐рддреНрд░ рдХрд╛ рдкрддрд╛, рдкрд░рд┐рд╢рд┐рд╖реНрдЯ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдПред рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ r_info рдлрд╝реАрд▓реНрдб рдореЗрдВ рдкреНрд░рддреАрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдЗрд╕ рдЪрд┐рд╣реНрди рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рд╢рд╛рдорд┐рд▓ рд╣реИ:

	/* This is the symbol it is referring to.  Note that all
	   undefined symbols have been resolved.  */
	sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
		+ ELF64_R_SYM(rel[i].r_info);

	val = sym->st_value + rel[i].r_addend;

рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдХрд╛ рдкреНрд░рдХрд╛рд░ рдЧрдгрдирд╛ рдХреЗ рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдпрд╣ R_X86_64_PLT32 рд╣реИ:

	switch (ELF64_R_TYPE(rel[i].r_info)) {
	......
	case R_X86_64_PLT32:	
		if (*(u32 *)loc != 0)
			goto invalid_relocation;
		val -= (u64)loc;	//   
		*(u32 *)loc = val;  //    
		break;
	.....

рдЕрдм рд╣рдо рдЦреБрдж рдЕрдВрддрд┐рдо рд╡реИрд▓ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдЬрд╛рдирддреЗ рд╣реБрдП рдХрд┐ sym-> st_value рдкреНрд░рд┐рдВрдЯрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкрддрд╛ рд╣реИ 0xffffffff810b3df9, r_addend (-4) рд╣реИ, рд░рд┐рд▓реЛрдХреЗрд╢рди рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рднрд░рдкрд╛рдИ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЯреЗрдХреНрд╕реНрдЯ рд╕реЗрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ 0xd рдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдлреВ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ ix, i.e. ffffffffc000000d рд╣реЛрдЧрд╛ред рдЗрди рд╕рднреА рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:

val = (u32)(0xffffffff810b3df9 - 0x4 - 0xffffffffc000000d) = 0xc10b3de8

рдЖрдЗрдП foo рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдбрдВрдк рдХреЛ рджреЗрдЦреЗрдВ, рдЬреЛ рд╣рдореЗрдВ рдмрд╣реБрдд рд╢реБрд░реБрдЖрдд рдореЗрдВ рдорд┐рд▓рд╛ рдерд╛:

53 89 fe 89 fb 48 c7 c7 24 10 00 c0 e8 e8 3d 0b c1 8d 43 02 5b c3 66 2e 0f

рдСрдлрд╕реЗрдЯ 0xD рдкрд░, рдорд╛рди 0xc10b3de8 рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдЧрдгрдирд╛ рдХреА рдЧрдИ рдХреЗ рд╕рдорд╛рди рд╣реИред

рдпрд╣ рд╣реИ рдХрд┐ рдХрд░реНрдиреЗрд▓ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХреИрд╕реЗ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХрд░реАрдмреА рдХреЙрд▓ рдХрдорд╛рдВрдб рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдСрдлрд╕реЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред

рд▓реЗрдЦ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдореЗрдВ, рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг 5.4.27 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

All Articles