2014-08-30 2 views
4

커널 모듈을 작성하여 전체 프로세스 이름과 함께 pid 목록을 가져옵니다. proc_pid_cmdline()은 전체 프로세스 이름을 제공하고 동일한 함수를 사용하면 /proc/*/cmdline은 전체 프로세스 이름을 가져옵니다. (struct task_struct) -> comm은 프로세스가 무엇인지 힌트를 제공하지만 전체 경로는 제공하지 않습니다.커널 모듈에서 proc_pid_cmdline을 사용하는 방법

함수 이름이 포함되어 있지만 함수를 찾을 위치를 알 수 없으므로 오류가 발생합니다.

proc_pid_cmdline()을 모듈로 사용하는 방법은 무엇입니까?

+0

Linux (및 Unix)가 프로세스 이름을 전혀 사용하지 않기 때문에 프로세스 이름을 정의해야합니다. – wallyk

답변

2

proc_pid_cmdline()으로 전화하지 않아도됩니다. 그러나

static int proc_pid_cmdline(struct seq_file *m, struct pid_namespace *ns, 
          struct pid *pid, struct task_struct *task) 

, 그것이 무엇을하는 것은 간단하다 :

IT는이 non-public functionfs/proc/base.c

하지만 전체 경로를 반환 할 가능성이 없습니다
get_cmdline(task, m->buf, PAGE_SIZE); 

그것은을 할 수 없습니다 모든 경우에 전체 경로를 결정하십시오. arg [0] 값은 덮어 쓸 수 있거나 파일을 삭제하거나 옮길 수 있습니다. 프로세스는 원래 명령 줄과 모든 종류의 다른 질병을 가리는 방식으로 exec()를 수행 할 수 있습니다.

/proc 디렉토리/* /있는 CmdLine 덜보다 유용한 결과의 모든 종류를 전환 내 페도라 20 시스템의 스캔 :

-F 
BUG: 
WARNING: at 
WARNING: CPU: 
INFO: possible recursive locking detecte 
ernel BUG at 
list_del corruption 
list_add corruption 
do_IRQ: stack overflow: 
ear stack overflow (cur: 
eneral protection fault 
nable to handle kernel 
ouble fault: 
RTNL: assertion failed 
eek! page_mapcount(page) went negative! 
adness at 
NETDEV WATCHDOG 
ysctl table check failed 
: nobody cared 
IRQ handler type mismatch 
Machine Check Exception: 
Machine check events logged 
divide error: 
bounds: 
coprocessor segment overrun: 
invalid TSS: 
segment not present: 
invalid opcode: 
alignment check: 
stack segment: 
fpu exception: 
simd exception: 
iret exception: 
/var/log/messages 
-- 
/usr/bin/abrt-dump-oops 
-xtD 
+0

openSUSE 13.2에서 작동합니다 :'for I/proc/*/cmdline; do echo $ I; 고양이 $ I | tr '\ 000' " '; 에코; done' – myaut

+0

현재 프로세스의 실행 파일 구조체를 반환하는 proc_exe_link의 소스 코드를보고 있습니다. 위의 cmd가 가짜 일 수 있다는 것에 동의합니다. 원래 원점 바이너리의 메모리 맵인 것처럼 보이기 때문에 mm -> exe_file을 위조하는 것이 얼마나 쉬운가요? –

1

나는이 문제의 버전를 해결하기 위해 관리했다. 나는 모든 PID의 cmdline에 접근하고 싶었지만 커널 자체 내에서 (커널 모듈과 반대) 커널 모듈에도 이러한 원칙을 적용 할 수 있습니까? I이었다 했는가

, 난 내 모든 프로세스의 cmdline에 액세스 할 수 있습니다, 그때 나는이 시점에서
int proc_get_cmdline(struct task_struct *, char *);

include/linux/proc_fs.h에 선언을 추가 fs/proc/base.c

int proc_get_cmdline(struct task_struct *task, char * buffer) { 
    int i; 
    int ret = proc_pid_cmdline(task, buffer); 

    for(i = 0; i < ret - 1; i++) { 
      if(buffer[i] == '\0') 
        buffer[i] = ' '; 
    } 
    return 0; 
} 

에 다음 함수를 추가 커널. task_struct에 액세스하려면 kernel: efficient way to find task_struct by pid?을 참조하십시오. 나는 모든 프로세스의 명령 줄이 방법을 얻을 수 있었다

char cmdline[256];  
proc_get_cmdline(task, cmdline); 
if(strlen(cmdline) > 0) 
    printk(" cmdline :%s\n", cmdline); 
else 
    printk(" cmdline :%s\n", task->comm); 

: 당신이 task_struct이 있으면

, 당신은 같은 일을 할 수 있어야합니다.

0

프로세스 뒤의 바이너리의 전체 경로를 얻으려면. 현재 당신이 관심있는 프로세스에 대한 작업 구조체입니다

char * exepathp; 

struct file * exe_file; 
struct mm_struct *mm; 
char exe_path [1000]; 

//straight up stolen from get_mm_exe_file 
mm = get_task_mm(current); 
down_read(&mm->mmap_sem); //lock read 
exe_file = mm->exe_file; 
if (exe_file) get_file(exe_file); 
up_read(&mm->mmap_sem); //unlock read 

//reduce exe path to a string 
exepathp = d_path(&(exe_file->f_path), exe_path, 1000*sizeof(char)); 

는. 변수 exepathp 전체 경로의 문자열을 가져옵니다. 이것은 프로세스 cmd와 약간 다르며 프로세스를 시작하기 위해로드 된 바이너리 경로입니다. 이 경로를 프로세스 cmd와 결합하면 전체 경로가 제공됩니다.

관련 문제