Complete system calls with embedded assembly

Source: Internet
Author: User

This is NetEase cloud classroom "Linux kernel Analysis" This course of homework

Look at the following procedure:

What is done in the else block and what is done in the If block is the same thing, it's all done getuid this system call gets the UID of the current user. Now the branch explains:

mov $0,%%ebx\n\t

This line is to clear the value of the EBX register by 0, and the first parameter from the EBX when the system is called, which is equivalent to passing null.

By querying the system call table we know that the system call function number of the Getuid () is 24,16 binary to 0x18. The system call function number is passed by the EAX register, so the following line has a clear meaning:

mov $0x18,%%eax\n\t

Then send the soft interrupt signal to the kernel, the system calls the interrupt number is 0x80, so:

int $0x80\n\t

The int command throws a programming exception that is trapped by the kernel. Remember when we had trap_init in the Start_kernel?

#ifdef config_ia32_emulation    set_system_intr_gate (Ia32_syscall_vector, ia32_syscall);    Set_bit (Ia32_syscall_vector, used_vectors); #endif

Ia32_syscall_vector the definition of this macro in Irq_vectors.h

#define Ia32_syscall_vector        0x80#ifdef config_x86_32# define syscall_vector            0x80#endif

Interrupts let the program into the kernel state, the kernel through the interrupt vector table know the current is to make a system call. Then enter the system call entry System_call:

ENTRY (System_call) Ring0_int_frame # can't unwind into user space anyway Asm_clac pushl_cfi%eax # Save Orig_eax save_all get_t Hread_info (%EBP) # system call tracing in Operation/emulation Testl $_TIF_WORK_SYSCALL_ENTRY,TI_FL AGS (%EBP) jnz syscall_trace_entry Cmpl $ (nr_syscalls),%eax Jae Syscall_badsyssyscall_call: Call *sys_call    _table (,%eax,4)syscall_after_call: movl%eax,pt_eax (%ESP) # Store The return valuesyscall_exit: Lockdep_sys_exit disable_interrupts (clbr_any) # Make sure we don'T miss an interrupt # setting need_reschedorsigpending # between sampling andTheIrettrace_irqs_off movl ti_flags (%EBP),%ecx testl $_tif_allwork_mask,%ecx # current->workjnesyscall_exit_workRestore_all:Trace_irqs_iretRestore_all_notrace:#ifdef config_x86_espfix32 movl pt_eflags (%ESP),%eax # Mix eflags, SS andCS #Warning:Pt_oldss (%ESP) contains the wrong/random values if we # is returning to the kernel. # See commentsinchProcess.C:Copy_thread () for details. Movb Pt_oldss (%ESP),%ah movb Pt_cs (%ESP),%al Andl $ (X86_EFLAGS_VM | (Segment_ti_mask <<8) | Segment_rpl_mask),%eax Cmpl $ ((Segment_ldt <<8) | USER_RPL),%eax cfi_remember_stateJELDT_SS # Returning to User-space with Ldt Ss#endifRestore_nocheck:Restore_regs4# Skip Orig_eax/error_codeIrq_return:interrupt_return.section. Fixup,"Ax"ENTRY (IRET_EXC) PUSHL $0# no error code PUSHL $do _iret_errorjmperror_code.previous _asm_extable (irq_return,iret_exc) #ifdef config_x86_espfix32 cfi_restore_stateLDT_SS:#ifdef CONFIG_PARAVIRT/* * The kernel can'T run on a non-flat stack if paravirt mode * is active.  Rather than try to fixup the high bits of * ESP, bypass this code entirely. This could break Dosemu * and/or Wine with a paravirt VM, although the option * is still available to Implemen     t the setting of the high * 16-bits in the Interrupt_return paravirt-op. */Cmpl $, pv_info+paravirt_enabled jne restore_nocheck#endif

You can see that the Save_all protection field is called in System_call, the current stack top, CS:EIP, and the status number are stacked.

. Macro Save_allCLDpush_gs PUSHL_CFI%fs/*cfi_rel_offset FS,0;*/PUSHL_CFI%es/*cfi_rel_offset es,0;*/PUSHL_CFI%ds/*cfi_rel_offset ds,0;*/PUSHL_CFI%eax cfi_rel_offset eax,0PUSHL_CFI%ebp cfi_rel_offset ebp,0PUSHL_CFI%edi cfi_rel_offset EDI,0PUSHL_CFI%esi cfi_rel_offset esi,0PUSHL_CFI%edx cfi_rel_offset edx,0PUSHL_CFI%ecx cfi_rel_offset ecx,0PUSHL_CFI%ebx cfi_rel_offset ebx,0MOVL $ (__user_ds),%edx movl%edx,%ds movl%edx,%es movl $ (__kernel_percpu),%edx movl%edx,%fs Set_kernel_gs%EDX.ENDM

Then check the table to find the system call service program and execute:

Syscall_call:     Call *sys_call_table (,%eax,4)

You know from EAX that the system call function number is 24, and 24 corresponds to GETUID (defined in unistd32.h).

#define __nr_getuid__syscall (__nr_getuid, Sys_getuid16)

After executing the system invoke service, write the return value back to the EAX register:

Syscall_after_call:     movl%eax,pt_eax (%ESP)        # Store the return value

Then either the process is dispatched, or the user state is returned and executed (this piece of code is not very well understood).

So we can get the return value of Getuid from the EAX register. and write to the memory variable UID.

mov %%eax,%0

Compile the program and test it.

The resulting user ID and ID are consistent with this command.

Liu Cong + original works reproduced please specify the source + "Linux kernel analysis" MOOC course http://mooc.study.163.com/course/USTC-1000029000

Complete system calls with embedded assembly

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.