����
�A��

Linux�J�[�l���Ɍ���A�V�X�e���R�[���ԍ��ƈ����A�V�X�e���R�[���E���b�p�[�Ƃ��Fmain()�֐��̑O�ɂ͉�������̂��i7�j�i1/2 �y�[�W�j

C����́uHello World�I�v�v���O�����Ŏg����A�uprintf()�v�umain()�v�֐��̒��g���A�f�o�b�K�ɂ���͂Ƌt�A�Z���u���A�\�[�X�R�[�h�lj��Ȃǂ̂��܂��܂ȑ��ʂ���T��A�ځB�O�񂩂�Aprintf()����write()��int $0x80�̌Ăяo���ɂ‚���Linux�J�[�l���̃\�[�X�R�[�h������T���Ă����B����́A����ɃV�X�e���R�[���ɂ‚��Ċw�ԁB

Share
Tweet
LINE
Hatena

�A�ږڎ�

�n���[�gHello�CWorld�h OS�ƕW�����C�u�����̃V�S�g�Ƃ�����

���Ђ̒�����L�p�ȋZ�p�����s�b�N�A�b�v���ďЉ��{�V���[�Y�B����́A�G�a�V�X�e�����s�̏��Ёw�n���[�gHello, World�h OS�ƕW�����C�u�����̃V�S�g�Ƃ����݁i2015�N9��11�����s�j�x����̔����ł��B

�����ӁF�{�e�́A���ҋy�яo�ŎЂ̋��‚𓾂āA���̂܂ܓ]�ڂ������̂ł��B���̂��ߗp���p��̓��ꃋ�[���Ȃǂ́�IT�̂���Ƃ͈�v���܂���B���炩���߂��������������B


���ҏW�����F�O��L���uLinux�J�[�l���̃\�[�X�R�[�h��ǂ�ŁA�V�X�e���R�[����T���v�͂�����

�V�X�e���R�[���ԍ�

�@�V�X�e���R�[���̃p�����[�^�Ƃ���Linux�J�[�l���ɓn�������̂ɂ́A�ǂ̃V�X�e���R�[�����Ă΂�Ă��邩�̔ԍ��ƁA���̃V�X�e���R�[���̈�����2��ނ�����B

�@�܂��A�V�X�e���R�[���ԍ��ɂ‚��čl���Ă݂悤�B

�@������x�ALinux�J�[�l���ɘb��߂����B�V�X�e���R�[���̏����֐���sys_call_table�Ƃ����V�X�e���R�[���E�e�[�u���i�����ւ���Ɗ֐��ւ̃|�C���^�̔z��j����AEAX���W�X�^���C���f�b�N�X�ɂ��Ď擾����Ă����B���̃C���f�b�N�X���V�X�e���R�[���ԍ��Ƃ������ƂɂȂ�B

�@�O��̕\3.1�ɂ��΁Aint $0x80�̌Ăяo������EAX���W�X�^�̒l��4�ɂȂ��Ă���B

�@syscall_table_32.S��sys_call_table���A������x���Ă݂悤�B

ENTRY(sys_call_table)
	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
	.long sys_exit
	.long ptregs_fork
	.long sys_read
	.long sys_write
	.long sys_open		/* 5 */
	.long sys_close
...

�@�擪���[���Ƃ��ď��ɐ�����4�Ԗڂ́Asys_write�Ƃ����֐����B����͂����炭write�V�X�e���R�[���̏����֐����낤�B�‚܂�Ă΂�Ă���̂�write�V�X�e���R�[���ł���A���̃V�X�e���R�[���ԍ���4�ł���A�Ƃ������Ƃ��ł���킯���B

�@���̓V�X�e���R�[���ԍ��́Aarch/x86/include/asm/unistd_32.h�Ƃ����w�b�_�t�@�C���Œ�`����Ă���B

�@���Ă݂�ƁAwrite�V�X�e���R�[���͈ȉ��̂悤�ɂ��Ē�`����Ă���B��͂�4�Ƃ����l�ō����Ă���悤���B

12:#define __NR_write			4

�V�X�e���R�[���̈���

�@���ɃV�X�e���R�[���̈����ɂ‚��čl���Ă݂悤�B�V�X�e���R�[���̈����͂ǂ̂悤�ɓn����Ă���̂��낤���B

�@Linux�J�[�l���̃V�X�e���R�[�������ł́Asystem_call����syscall_call�ɓ���A�����call���߂ɂ���ăV�X�e���R�[���̏����֐����Ă΂�Ă���B

�@���̐��C����̊֐��ł��邩��A�����܂łɊ֐��Ăяo���̈����̐ݒ肪�s���Ă���͂����B�����ĘA�ڑ�1��Ő��������悤�ɁAx86�ł͊֐��̈����̓X�^�b�N�n�����B�‚܂�X�^�b�N��ɒl��ۑ����Ă���ӏ�������΁A�����������֐��p�Ɉ����̏��������Ă���ꏊ���B

�@���̂悤�Ȏ��_�ŒT����SAVE_ALL�Ƃ����}�N����entry_32.S�ňȉ��̂悤�ɒ�`����Ă���Asystem_call�̓����Ŏg���Ă���B

194:.macro SAVE_ALL
195:	cld
196:	PUSH_GS
197:	pushl %fs
...
218:	pushl %edx
219:	CFI_ADJUST_CFA_OFFSET 4
220:	CFI_REL_OFFSET edx, 0
221:	pushl %ecx
222:	CFI_ADJUST_CFA_OFFSET 4
223:	CFI_REL_OFFSET ecx, 0
224:	pushl %ebx
225:	CFI_ADJUST_CFA_OFFSET 4
226:	CFI_REL_OFFSET ebx, 0
...

�@push���߂ɂ��AEDX�AECX�AEBX���W�X�^�̒l���X�^�b�N�Ɋi�[���Ă���B����炪�X�^�b�N��ɔz�u���ꂽ��Ԃ�call���߂ɂ��V�X�e���R�[���̏����֐����Ă΂�邽�߁AEBX�`EDX�Ɋi�[����Ă����l���V�X�e���R�[���̏����֐��ɁA�����Ƃ��ēn����邱�ƂɂȂ�B

�@�‚܂�Linux/x86�ł́AEAX�ŃV�X�e���R�[���ԍ����AEBX�ȍ~�ň�����n���Ă���Ƃ������ƂɂȂ�B�O��̕\3.1���g�������`�ł܂Ƃ߂�ƁA�\3.2�̂悤�ɂȂ�B

�\3.2: ���W�X�^�̒l�ƈӖ�
���W�X�^ �l �Ӗ�
EAX 4 �V�X�e���R�[���ԍ��iwrite()��4�j
EBX 1 write()�̑�1�����i�o�͐�t�@�C���f�B�X�N���v�^�B�W���o�͂�1�j
ECX 0xb7fff000 write()�̑�2�����i�o�̓f�[�^�̃A�h���X�j
EDX 38 write()�̑�3�����i�o�̓f�[�^�̃T�C�Y�j

�@����̓A�v���P�[�V�����E�v���O���������炷��ƁAEAX�ɃV�X�e���R�[���ԍ��AEBX�ȍ~�Ɉ�����ݒ肵��int $0x80�����s���邱�ƂŃV�X�e���R�[�������s����A���Ƃ�Linux�J�[�l�������Y�̏������s���Ă����Ƃ������ƂɂȂ�B

�@�‚܂�Linux/x86�́A�V�X�e���R�[���ԍ���EAX�ɁA�V�X�e���R�[���̈�����EBX�ȍ~�ɐݒ肵��int $0x80���ĂԂƂ����V�X�e���R�[���̌n���Ƃ�����B

�@�����������Linux/x86���L�̘b�ł����āALinux�ȊO��OS�Ȃ�ΈقȂ邩������Ȃ��B���Ƃ���FreeBSD�ł͓���x86�p�ł��A�����̓n�������͈قȂ�B������x86�ȊO�̃A�[�L�e�N�`���Ȃ�΂����������W�X�^�\�����Ⴄ�̂ŁA�܂��قȂ邱�ƂɂȂ�B

�@�‚܂肱���Linux/x86�̃V�X�e���R�[���d�l�A�Ƃ������Ƃ��ł���B

�V�X�e���R�[���E���b�p�[

�@Linux/x86�ł�EAX���W�X�^�ɃV�X�e���R�[���ԍ��AEBX�ȍ~�̃��W�X�^�Ɉ�����ݒ肵��int $0x80�����s���邱�ƂŃV�X�e���R�[�����Ăяo�����Ƃ��ł���A�Ƃ������Ƃ͂킩�����B

�@�����������̍�Ƃ́AC����ł͋L�q�ł��Ȃ��B�A�Z���u���ŋL�q����K�v������B

�@���������R�[�h���v���O���}�����ׂď������Ƃ͖ʓ|���B�A�Z���u���ŋL�q�͂��邪�AC���ꂩ��Ăяo�����Ƃ��ł���֐��̌`�Ƀ��C�u���������āA�V�X�e��������񋟂��Ă��炢�����B

�@�����đ����̊‹��ł͎��ۂɂ��̂悤�ȃ��C�u�������p�ӂ���񋟂���Ă��邽�߁A��ʂ̃v���O���}�������������Ƃ��C�ɂ���K�v�͖����Bwrite()���Ăяo���΁A���Ƃ̓��C�u�������œK�؂ȏ��������Ă����B���ۂɂ̓��C�u�����̌Ăяo���̐�ŁA���W�X�^�ݒ��int $0x80�̎��s���s���Ă���킯���B

�@���̂悤�Ȗ����̃A�Z���u���ŏ����ꂽ�֐��́A�V�X�e���R�[���E���b�p�[�iSystemCall Wrapper�j�ƌĂ΂��B

�@�v���O���~���O�̐��E�Ń��b�p�[�Ƃ����ƁA���炩�̏����𕢂��Ă���悤�ȏ����̂��ƂɂȂ�B�ꖇ���Ԃ���A�Ƃ��������������������������B�v���O���~���O�̑��ɂ��Ⴆ�ΘA�ڑ�2��Ő�������GDB��GUI�C���^�[�t�F�[�X�Ȃǂ́AGDB��GUI���b�p�[�ł���A�Ȃǂƌ������肷��B����̓��[�U�E�C���^�[�t�F�[�X�̃��b�p�[�̗Ⴞ�B

�@�ł̓V�X�e���R�[���E���b�p�[�̎��̂́A�ǂ��ɂ���̂��낤���B

�@int $0x80���s�O�̃X�^�b�N�̏�Ԃ�������x���Ă݂悤�B

(gdb) x/16x $esp
0xbffff4d8:	0x08053d92	0x00000026	0x08067671	0x00000001
0xbffff4e8:	0xb7fff000	0x00000026	0x080d68c0	0x00000026
0xbffff4f8:	0xb7fff000	0xbffff524	0x0806819b	0x080d68c0
0xbffff508:	0xb7fff000	0x00000026	0xbffff544	0x08069732
(gdb)

�@x86�ł͊֐��Ăяo���̍ۂɂ́A�X�^�b�N�̐擪�ɖ߂��A�h���X���i�[�����B�X�^�b�N�̃_���v�̏�̂ق��ɂ���0x08053d92��0x08067671�Ƃ������l�́A�A�ڑ�1��Ō����@�B��R�[�h�̃A�h���X�l�Ɏ��Ă��āA�߂��A�h���X�̂悤�Ɏv����B

�@�����ŘA�ڑ�1��̃o�b�N�g���[�X�ł́A�ȉ��̂悤�Ɋ֐����Ăяo����Ă������Ƃ��v���o���Ăق����B

(gdb) where
#0	0x00110416	in __kernel_vsyscall ()
#1	0x08053d92	in __write_nocancel ()
#2	0x08067671	in _IO_new_file_write ()
#3	0x0806819b	in _IO_new_do_write ()
#4	0x080683ea	in _IO_new_file_overflow ()
#5	0x080673f4	in _IO_new_file_xsputn ()
#6	0x08059738	in vfprintf ()
#7	0x08049381	in printf ()
#8	0x080482e2	in main (argc=1, argv=0xbffffc14) at hello.c:5
(gdb)

�@__write_nocancel()��_IO_new_file_write()�̃A�h���X�ɒ��ڂ��Ăق����B������0x08053d92��0x08067671�ɂȂ��Ă���A�܂��ɃX�^�b�N�_���v�̒��Ɍ���Ă���B

�@x86�ł͊֐��Ăяo�����ɂ̓X�^�b�N�Ɉ������ς܂�A�֐��Ăяo���ɂ���ăX�^�b�N�ɂ͂���ɖ߂��A�h���X���l�܂��B�‚܂�X�^�b�N��ɂ́A�߂��A�h���X�̎��Ɉ��������邱�ƂɂȂ�B

�@�Ƃ������Ƃ́A_IO_new_file_write()��__write_nocancel()�̂悤�ɌĂ΂ꂽ�Ƃ��̈�����0x00000001�A0xb7fff000�A0x00000026�ɂȂ��Ă���̂��Ɛ����ł���B���Ȃ݂ɃX�^�b�N�������__write_nocancel()��__kernel_vsyscall()�̂悤�ɌĂ΂ꂽ�Ƃ��̈�����0x00000026�ł���悤�ɂ������邪�A����̓A�Z���u���̏���������ƒP��EBX���W�X�^�̒l���X�^�b�N��ɕۑ����Ă��邾���̂��̂ŁA�֐��Ăяo���̈����Ƃ��Ă̈Ӗ��͖����悤���B

�@�����ł���3�‚̒l�ɒ��ڂ���ƁA������int $0x80���Ă΂��Ƃ���EBX�AECX�AEDX�̒l�ɂȂ��Ă���B�‚܂�__write_nocancel()�Ƃ����֐����A�֐����Ăяo���ꂽ�ۂɃX�^�b�N�o�R�œn���ꂽ���������W�X�^�ɐݒ肵�Ă���̂ł́A�Ǝv����킯���B���ꂪwrite�V�X�e���R�[���̃V�X�e���R�[���E���b�p�[���B

�@�t�A�Z���u�����ʂ���A__write_nocancel()��T���Č��Ă݂悤�B

[user@localhost hello]$ objdump -d hello | less

�@__write_nocancel�Ō�������ƁA�ȉ��̂悤�ȕ������������B

08053d70 <__libc_write>:
 8053d70:	65 83 3d 0c 00 00 00	cmpl	$0x0,%gs:0xc
 8053d77:	00
 8053d78:	75 25			jne	8053d9f <__write_nocancel+0x25>
 
08053d7a <__write_nocancel>:
 8053d7a:	53			push	%ebx
 8053d7b:	8b 54 24 10		mov	0x10(%esp),%edx
 8053d7f:	8b 4c 24 0c		mov	0xc(%esp),%ecx
 8053d83:	8b 5c 24 08		mov	0x8(%esp),%ebx
 8053d87:	b8 04 00 00 00		mov	$0x4,%eax
 8053d8c:	ff 15 50 67 0d 08	call	*0x80d6750

�@�O������������A�\�[�X�R�[�h��ǂނƂ��̃R�c�Ƃ��āA�t�߂����Ă݂�悤�ɂ���ƁA���ۂɂ�__libc_write()�Ƃ����֐�������A���̒����__write_nocancel�Ƃ����������p�����s����Ă���悤�ŁA_IO_new_file_write()�����__libc_write()���Ăяo����Ă��邱�ƂɋC���‚��B

�@�A�ڑ�4��Œ��ׂ����ʂł́A__write_nocancel�̒��O�ɂ�write()���������͂����B������readelf�̌��ʂ�����ƁA__libc_write()�Ɠ����A�h���X��write()���z�u����Ă��邽�߁A������write()���Ăяo����Ă���悤���i�O���write()�Ƀu���[�N�|�C���g�𒣂��Ă������Ƃ��v���o���Ăق����j�BGDB�̃o�b�N�g���[�X�ł́u__write_nocancel()�v�̂悤�ɕ\������Ă��邪�A����̓X�^�b�N��ɕۑ�����Ă���߂��A�h���X����A���O�̃V���{����P���Ɍ������ĕ\�����Ă��邽�߂��낤�B

�@������__write_nocancel�̓����ł́Amov���߂ɂ��X�^�b�N��̈�����EDX�AECX�AEBX���W�X�^�ɐݒ肵�A�V�X�e���R�[���ԍ���4��EAX���W�X�^�ɐݒ肵�Ă���B����ɂ��̌��call���߂ɂ��Aint $0x80���s��__kernel_vsyscall()���Ă΂�Ă���̂��낤�B

�@call���߂ɂ��W�����v��́A0x80d6750�Ƃ����A�h���X�Ɋi�[����Ă���A�h���X�ɂȂ��Ă���B�‚܂�C���ꕗ�ɏ����ƁA�ȉ��̂悤�Ȋ֐��Ăяo�����s���Ă���B

int (*f)();
f = (int (*)())0x80d6750;
f();

�@���ꂪ__kernel_vsyscall()�̌Ăяo���ɂȂ��Ă���͂����B

�@�m�F���Ă݂悤�B�O�q�̎菇��write�V�X�e���R�[���̌Ăяo���̂��߂�int $0x80�̎��s�ʒu�Ńu���[�N����B

[user@localhost hello]$ gdb -q hello
Reading symbols from /home/user/hello/hello...done.
(gdb) break write
Breakpoint 1 at 0x8053d70
(gdb) run
Starting program: /home/user/hello/hello
 
Breakpoint 1, 0x08053d70 in write ()
(gdb) break *0x110414
Breakpoint 2 at 0x110414
(gdb) continue
Continuing.
 
Breakpoint 2, 0x00110414 in __kernel_vsyscall ()
(gdb)

�@0x80d6750�̎w������AGDB��ŋt�A�Z���u�����Ă݂悤�B

(gdb) print/x *0x80d6750
$1 = 0x110414
(gdb) disassemble *0x80d6750
Dump of assembler code for function __kernel_vsyscall:
=> 0x00110414 <+0>:	int	$0x80
   0x00110416 <+2>:	ret
End of assembler dump.
(gdb)

�@�m����int $0x80�̏������Ă΂�Ă���悤���B

Copyright © ITmedia, Inc. All Rights Reserved.

�@�@�@�@�@�@ | ���̃y�[�W��

Coding Edge �L�������L���O

�y�[�W�g�b�v�ɖ߂�