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
���Ђ̒�����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
���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.
�֘A�L��
- �v���O���~���O����C�ɂ��Ēm�낤
�v���O���~���O����̊�{�ƂȂ�uC�v�B���������@���@��g�ɕt���悤�BC�ɂ͊m���Ɋw�Ԃ����̉��l������i�ҏW���j - �V�F���R�[�h��͂ɕK�g�́u5����v
�R���s���[�^�E�C���X�̉�͂ȂǂɌ������Ȃ����o�[�X�G���W�j�A�����O�Z�p�ł����A��������������ȁA�Ƃ�����ۂ�����Ă���l�������̂ł͂Ȃ��ł��傤���B���̘A�ڂł́A�u�V�F���R�[�h�v���ɁA���H�`���ł��̊�b���Љ�Ă����܂��B�i�ҏW���j - �y od �z�R�}���h�\�\�t�@�C����8�i����16�i���Ń_���v����
�{�A�ڂ́ALinux�̃R�}���h�ɂ��āA��{��������I�v�V�����A��̓I�Ȏ��s��܂ł��Љ�Ă����܂��B����́A�uod�v�R�}���h�ł��B