;================================================================================= ; sys_ptrace & sys_kill demonstration. ; ; We attach ourselves using PTRACE_ATTACH to an external process, wait for it to ; stop, obtain its register dump, change one register, and loop. ; ; Instead of PTRACE_ATTACH, PTRACE_TRACEME could be used. In later case we would ; need to fork a child, make child sys_execve external application and execute ; sys_ptrace with PTRACE_TRACEME. ; ; Execute ptrace_dummy prior to running this application!!! ; ; ; The LSCR Project. ;================================================================================= format ELF include '../macros.inc' include '../../include/symbols.inc' include '../../include/structs.inc' extrn error_chk extrn dd2ascii_hex extrn dec_ascii2dd extrn dw2ascii_hex section '.text' executable public _start _start: pop eax ; get number of command-line arguments cmp eax, 2 ; exit if no command-line argument were supplied. jb error0 pop eax ; application name. we don't need it call dec_ascii2dd ; convert PID ascii string to dword add esp, 4 mov [extern_pid], eax mov eax, SYS_PTRACE mov ebx, PTRACE_ATTACH ; attach ourselves to the specified process mov ecx, [extern_pid] int 0x80 ccall error_chk, <"SYS_PTRACE">, exit wait_for_child: ; we need to make sure that child has received the SIGSTOP signal mov eax, SYS_WAITPID mov ebx, [extern_pid] mov ecx, status xor edx, edx int 0x80 ccall error_chk, <"SYS_WAITPID">, exit mov eax, [status] ; if child has exited we should too and eax, 0xff jz child_exited mov eax, [status] ; loop if child received SIGCONT signal cmp ax, 0xffff je wait_for_child mov eax, [status] ; if child has been killed we should exit test al, al jz @f cmp al, 0x7f jne child_exited @@: mov eax, [status] ; if child has stopped execute our code. otherwise waitpid once more. cmp al, 0x7f jne wait_for_child ; if we came here it means that child is currently in a stopped state ; and we might proceed with inspecting it. mov eax, SYS_PTRACE ; obtain full (except FPU) dump of child's registers and display them mov ebx, PTRACE_GETREGS mov ecx, [extern_pid] mov esi, user_regs int 0x80 ccall error_chk, <"SYS_PTRACE">, exit ccall dd2ascii_hex, [user_regs.eax], reg_dump1+7 ccall dd2ascii_hex, [user_regs.ebx], reg_dump1+27 ccall dd2ascii_hex, [user_regs.ecx], reg_dump1+47 ccall dd2ascii_hex, [user_regs.edx], reg_dump2+7 ccall dd2ascii_hex, [user_regs.esi], reg_dump2+27 ccall dd2ascii_hex, [user_regs.edi], reg_dump2+47 ccall dd2ascii_hex, [user_regs.ebp], reg_dump3+7 ccall dd2ascii_hex, [user_regs.esp], reg_dump3+27 ccall dd2ascii_hex, [user_regs.eip], reg_dump3+47 ccall dd2ascii_hex, [user_regs.eflags], reg_dump4+10 mov ax, [user_regs.cs] ccall dw2ascii_hex, eax, reg_dump4+27 mov ax, [user_regs.es] ccall dw2ascii_hex, eax, reg_dump4+39 mov ax, [user_regs.ds] ccall dw2ascii_hex, eax, reg_dump4+51 mov ax, [user_regs.fs] ccall dw2ascii_hex, eax, reg_dump5+6 mov ax, [user_regs.ss] ccall dw2ascii_hex, eax, reg_dump5+18 push word [user_regs.cs] mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, reg_dump mov edx, reg_dump_sz int 0x80 mov [user_regs.edi], 0x12345678 ; change child's edi value so it will print "@" instead of "#" mov eax, SYS_PTRACE mov ebx, PTRACE_SETREGS mov ecx, [extern_pid] mov esi, user_regs int 0x80 ccall error_chk, <"SYS_PTRACE">, exit jmp exit ;-----------------------------------------------; misc. error handlers child_exited: push eax mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, error3_s mov edx, error3_s_sz int 0x80 jmp exit error0: mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, error0_s mov edx, error0_s_sz int 0x80 exit: mov eax, SYS_EXIT xor ebx, ebx int 0x80 section '.data' writeable error0_s db "Execute './ptrace_dummy' first.",0xa db "Then do './ptrace pid' where pid is the process ID of the ptrace_dummy",0xa error0_s_sz = $-error0_s error3_s db "Traced process has exited. We'll be leaving too." error3_s_sz = $-error3_s reg_dump db 0xa,"Child's registers dump:",0xa reg_dump1 db "eax: 0x00000000 ebx: 0x00000000 ecx: 0x00000000",0xa reg_dump2 db "edx: 0x00000000 esi: 0x00000000 edi: 0x00000000",0xa reg_dump3 db "ebp: 0x00000000 esp: 0x00000000 eip: 0x00000000",0xa reg_dump4 db "eflags: 0x00000000 cs: 0x0000 es: 0x0000 ds: 0x0000",0xa reg_dump5 db "fs: 0x0000 ss: 0x0000",0xa,0xa reg_dump_sz = $-reg_dump extern_pid rd 1 status rd 1 user_regs user_regs_struct