Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ

Ndrysho vid pid nga Windows. Përpiquni #2 fusha shtesë PID



Në këtë artikull do të përpiqemi të krijojmë një modul kernel që mund të ndryshojë tashmë PID procesi i ekzekutimit në Linux OS, dhe gjithashtu eksperimentoni me proceset që kanë marrë një PID të ndryshuar.


Paralajmërim: Ndryshimi i PID është një proces jo standard dhe në rrethana të caktuara mund të çojë në një panik të kernelit.

Moduli ynë i testimit do të zbatojë pajisjen e karaktereve /dev/test, e cila do të ndryshojë PID-in e procesit kur lexohet prej tij. Falë këtij artikulli për një shembull të zbatimit të një pajisjeje me karakter. Kodi i plotë moduli është dhënë në fund të artikullit. Sigurisht, më së shumti vendimi i duhur Ishte e mundur të shtohej një thirrje sistemi në vetë kernel, por kjo do të kërkonte rikompilimin e kernelit.

Mjedisi

Të gjitha aktivitetet e testimit të modulit u kryen në një virtual Makina VirtualBox me shpërndarjen 64-bit LInux dhe versionin 4.14.4-1 të kernelit. Komunikimi me makinën u krye duke përdorur SSH.

Përpjekja numër 1 zgjidhje e thjeshtë

Disa fjalë për rrymën: ndryshorja aktuale tregon një strukturë task_struct me një përshkrim të procesit në kernel (PID, UID, GID, cmdline, hapësirat e emrave, etj.)

Ideja e parë ishte thjesht ndryshimi i parametrit aktual->pid nga moduli i kernelit në atë të dëshiruar.

Static ssize_t device_read (skedari i strukturës *filp, char *buffer, madhësia_t gjatësia, loff_t * offset) ( printk("PID: %d.\n",current->pid); aktuale->pid = 1; printk("new PID: %d.\n",current->pid); , )
Për të kontrolluar funksionalitetin e modulit, kam shkruar një program në C++:

#përfshi #përfshi #përfshi int main() ( std::cout<< "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >>rr; std::cout<< "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
Le të ngarkojmë modulin me komandën insmod, të krijojmë /dev/test dhe ta provojmë.

# ./a.out PID prindi im 293 PID im 782 PID im i ri 782
PID nuk ka ndryshuar. Ky mund të mos jetë i vetmi vend ku specifikohet PID.

Përpiquni #2 fusha shtesë PID

Nëse aktuale->pid nuk është identifikuesi i procesit, atëherë çfarë është? Një vështrim i shpejtë në kodin getpid() tregoi një strukturë task_struct që përshkruan procesin Linux dhe skedarin pid.c në kodin burimor të kernelit. Funksioni i kërkuar është __task_pid_nr_ns. Në kodin e funksionit ka një thirrje task->pids.pid, ne do ta ndryshojmë këtë parametër

Përpiloni dhe provoni

Meqenëse testova përmes SSH, munda të merrja daljen e programit përpara se kerneli të rrëzohej:

Prindi im PID 293 PID im 1689 PID im i ri 1689
Rezultati i parë tashmë është diçka. Por PID ende nuk ka ndryshuar.

Përpjekja #3 për simbolet e kernelit të paeksportueshme

Një vështrim më i afërt i pid.c dha një funksion që bën atë që na nevojitet
static void __change_pid(struct task_struct *detyra, enum pid_type type,
struct pid *i ri)
Funksioni pranon një detyrë për të cilën është e nevojshme të ndryshohet PID, lloji PID dhe, në fakt, PID i ri. Funksioni krijon një PID të ri
struct pid *alloc_pid(structur pid_namespace *ns)

Ky funksion pranon vetëm hapësirën e emrave në të cilën do të qëndrojë PID i ri, kjo hapësirë ​​mund të merret duke përdorur task_active_pid_ns.
Por ka një problem: këto simbole të kernelit nuk eksportohen nga kerneli dhe nuk mund të përdoren në module. Një e mrekullueshme më ndihmoi në zgjidhjen e këtij problemi. Nga atje merret kodi i funksionit find_sym.

Asmlinkage static void (*change_pidR)(struct task_struct *detyra, enum pid_type type, struct pid *pid); static asmlinkage struct pid* (*alloc_pidR)(struct pid_namespace *ns); static int __init test_init(void) ( printk(KERN_ALERT "TEST driver ngarkuar!\n"); change_pidR = find_sym("change_pid"); alloc_pidR = find_sym("alloc_pid"); ... ) static ssize_t device_read(structure file * filp, char *buffer, madhësia_t gjatësia, loff_t * offset) ( printk("PID: %d.\n",current->pid); struct pid* newpid; newpid = alloc_pidR(task_active_pid_ns(aktual)); change_pidR(aktuale ,PIDTYPE_PID,newpid); printk("PID i ri: %d.\n",current->pid); ... )
Përpilimi, nisja

Prindi im PID 299 PID im 750 PID im i ri 751
PID ndryshoi! Kerneli caktoi automatikisht një PID falas në programin tonë. Por a është e mundur të përdoret një PID që është zënë nga një proces tjetër, siç është PID 1? Le të shtojmë kodin pas ndarjes

Newpid->numrat.nr = 1;
Përpilimi, nisja

Prindi im PID 314 PID im 1172 PID im i ri 1
Ne marrim PID 1 të vërtetë!

Bash ka hedhur një gabim që pengon funksionimin e ndërrimit të detyrave duke përdorur komandën %n, por të gjitha funksionet e tjera funksionojnë mirë.

Karakteristikat interesante të proceseve me PID të ndryshuar

PID 0: hyrja nuk mund të dalë

Le të kthehemi te kodi dhe të ndryshojmë PID në 0.

Newpid->numrat.nr = 0;
Përpilimi, nisja

Prindi im PID284 PID im 1517 PID im i ri 0
Pra, PID 0 nuk është aq i veçantë? Gëzohemi, shkruajmë dalje dhe...

Topi po bie! Kerneli e përcaktoi detyrën tonë si DETYRËN DETYRUESE dhe, duke parë përfundimin, thjesht u rrëzua. Me sa duket, programi ynë duhet të kthehet në PID "normale" përpara se të dalë.

Procesi i padukshëm

Le të kthehemi te kodi dhe të vendosim një PID që garantohet të mos jetë i zënë
newpid->numrat.nr = 12345;

Përpilimi, nisja

Prindi im PID296 PID im 735 PID im i ri 12345
Le të shohim se çfarë ka në /proc

1 148 19 224 288 37 79 86 93 konsolat fb kcore locks ndarjet këmbimet versioni 10 149 2 226 29 4 8 87 sistemet e skedarëve acpi cpuinfo përdoruesit kyç meminfo sched_debug 58 20 20 20 20 20 8 çelësa asound kripto fs misc schedstat sysrq- aktivizo vmstat 11 16 208 24 291 6 81 89 pajisjet e shokut info ndërpret modulet kmsg scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup monton vetë 637 371 371 0 cgrupe d ma ioports kpagecount mtrr slabinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg loadavg pagetyp
Siç mund ta shohim, /proc nuk e identifikon procesin tonë, edhe nëse kemi zënë një PID të lirë. PID-i i mëparshëm gjithashtu nuk është në /proc, dhe kjo është shumë e çuditshme. Ndoshta ne jemi në një hapësirë ​​tjetër emri dhe për këtë arsye nuk jemi të dukshëm për main /proc. Le të montojmë një /proc të ri dhe të shohim se çfarë ka

1 14 18 210 25 291 738 81 9 pajisje autobusi fs kyç-përdoruesit kyçet e faqes info softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups 29 cgroups diskstats 29 me 29 me 29 info 29 info 7 30 7 6 83 92 cmdline dma iomem kmsg misc sched_debug këmbe kohën e funksionimit 11 15 2 224 28 37 78 84 93 config.gz shoferi sc ioports kpagecgroup modulet schedstat sys versioni 12 16 20 226 288 4 79 85 acdopages infomountrlocir ex 13 17 208 23 29 6 8 86 asound cpuinfo fb ​​'kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 sisteme skedarësh kripto info buddyinfo kcore loadavg net slabinfo thread-self zoneinfo
Procesi ynë ende nuk ekziston, që do të thotë se jemi në hapësirën normale të emrave. Le të kontrollojmë

Ps -e | grep bash
296 pikë/0 00:00:00 bash

Vetëm një bash, nga i cili nisëm programin. As PID-i i mëparshëm dhe as ai aktual nuk janë në listë.

Kujdes! pas ndryshimit të PID, drejtuesit tanë nuk do të jenë të përshtatshëm për oscill. Do të nevojiten të tjerë. Nëse e harroni këtë, përpjekjet për të instaluar oscill në një kompjuter të ri do të jenë të pasuksesshme.

PID - Identifikuesi i produktit / numri i produktit - një karakteristikë e një pajisjeje USB, së bashku me VID (Identifikuesi i shitësit - numri i prodhuesit) që karakterizon në mënyrë unike këtë pajisje nga pala pritës. Drejtuesit për çdo pajisje të lidhur instalohen dhe funksionojnë duke përdorur VID/PID.

Oshiloskop usb.oscill u është caktuar një VID+PID unike, në përputhje me rrethanat ata janë të pajisur me drejtues për Windows 98, 98SE, ME, 2000, XP, Vista, Seven (dhe janë të disponueshëm për shkarkim në këtë faqe). Megjithatë, për rastet e mëposhtme:

  • duke përdorur oscill në Linux OS (softuer në Makine virtuale) - opsion për FreeBSD
  • lidhja e oshilit me Pocket PC / Windows Mobile nëpërmjet portit virtual COM
  • Windows Seven 64bit me nënshkrim të detyrueshëm të drejtuesit

Ju mund të keni nevojë të përdorni drejtuesit standardë të Silabs, të cilët do të kërkojnë zëvendësimin e PID lëkundje në PID Silabs. Kjo mund të bëhet me një mjet të veçantë SetPID:

Rekomandohet të ndryshoni PID në EA61 dhe të përdorni versionin e ri të softuerit dhe drejtuesit DLL Silabs v3.X. Ky softuer ofron zgjedhje automatike dhe manuale të drejtuesit USB midis v2.0 dhe v3.X. Për zgjedhjen manuale duhet të bëni: Link-Setup-Port-Driver-V3

Kujdes! Ndryshimi i PID me këtë mjet është i mundur vetëm në një kompjuter me Windows, ku drejtuesi që korrespondon me PID aktual është i instaluar tashmë. Përndryshe, SetPID nuk do të shikojë lëkundje. Kjo do të thotë, oshilja duhet të jetë e pranishme në "Menaxherin e Pajisjes" të "Panelit të Kontrollit". Algoritmi:

  1. nëse drejtuesi USB (ose VCP) nga ky seksion është i instaluar tashmë, programi setpid do të tregojë PID=840E dhe mund ta ndryshoni PID në SILABS gjenerike;
  2. SetPID do të humbasë oscilin, do të zhduket gjithashtu në Device Manager;
  3. Windows do të gjejë një pajisje të re për të cilën ju duhet të shkarkoni një drejtues standard nga Silabs për PID EA60 ose për PID EA61
  4. ky drejtues është i nënshkruar dhe guaska duhet të fillojë të punojë me të.

Procedura e kundërt:

  1. pas instalimit të drejtuesit standard, mjeti SetPID zbulon lëkundje me PID=EA60 ose EA61
  2. ju mund të ktheni OSCILL PID të personalizuar duke shtypur butonin përkatës
  3. SetPID do të tregojë PID origjinal lëkundje= 840E

Përveç setpid, për të ndryshuar PID mund të përdorni programin nga Silabs: në këtë faqe zgjidhni an144.pdf Dhe an144sw.zip

Shënim: Përdoruesi Usatenko në forum publikoi një recetë për ndryshimin e PID në një kompjuter të vetëm me Win7 64

  • Programim jonormal,
  • Programimi
  • Në këtë artikull, ne do të përpiqemi të krijojmë një modul kernel që mund të ndryshojë PID-në e një procesi tashmë të ekzekutuar në Linux, dhe gjithashtu të eksperimentojmë me proceset që kanë marrë një PID të ndryshuar.


    Paralajmërim: Ndryshimi i PID është një proces jo standard dhe në rrethana të caktuara mund të çojë në një panik të kernelit.

    Moduli ynë i testimit do të zbatojë pajisjen e karaktereve /dev/test, e cila do të ndryshojë PID-in e procesit kur lexohet prej tij. Faleminderit artikullit për shembullin e zbatimit të një pajisjeje karakteri. Kodi i plotë i modulit është dhënë në fund të artikullit. Sigurisht, zgjidhja më e saktë ishte shtimi i një thirrjeje sistemi në vetë kernel, por kjo do të kërkonte rikompilimin e kernelit.

    Mjedisi

    Të gjitha aktivitetet e testimit të modulit u kryen në një makinë virtuale VirtualBox me një shpërndarje LInux 64-bit dhe versionin 4.14.4-1 të kernelit. Komunikimi me makinën u krye duke përdorur SSH.

    Përpjekja numër 1 zgjidhje e thjeshtë

    Disa fjalë për rrymën: ndryshorja aktuale tregon një strukturë task_struct me një përshkrim të procesit në kernel (PID, UID, GID, cmdline, hapësirat e emrave, etj.)

    Ideja e parë ishte thjesht ndryshimi i parametrit aktual->pid nga moduli i kernelit në atë të dëshiruar.

    Static ssize_t device_read (skedari i strukturës *filp, char *buffer, madhësia_t gjatësia, loff_t * offset) ( printk("PID: %d.\n",current->pid); aktuale->pid = 1; printk("new PID: %d.\n",current->pid); , )
    Për të kontrolluar funksionalitetin e modulit, kam shkruar një program në C++:

    #përfshi #përfshi #përfshi int main() ( std::cout<< "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >>rr; std::cout<< "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
    Le të ngarkojmë modulin me komandën insmod, të krijojmë /dev/test dhe ta provojmë.

    # ./a.out PID prindi im 293 PID im 782 PID im i ri 782
    PID nuk ka ndryshuar. Ky mund të mos jetë i vetmi vend ku specifikohet PID.

    Përpiquni #2 fusha shtesë PID

    Nëse aktuale->pid nuk është identifikuesi i procesit, atëherë çfarë është? Një vështrim i shpejtë në kodin getpid() tregoi një strukturë task_struct që përshkruan procesin Linux dhe skedarin pid.c në kodin burimor të kernelit. Funksioni i kërkuar është __task_pid_nr_ns. Në kodin e funksionit ka një thirrje task->pids.pid, ne do ta ndryshojmë këtë parametër

    Përpiloni dhe provoni

    Meqenëse testova përmes SSH, munda të merrja daljen e programit përpara se kerneli të rrëzohej:

    Prindi im PID 293 PID im 1689 PID im i ri 1689
    Rezultati i parë tashmë është diçka. Por PID ende nuk ka ndryshuar.

    Përpjekja #3 për simbolet e kernelit të paeksportueshme

    Një vështrim më i afërt i pid.c dha një funksion që bën atë që na nevojitet
    static void __change_pid(struct task_struct *detyra, enum pid_type type,
    struct pid *i ri)
    Funksioni pranon një detyrë për të cilën është e nevojshme të ndryshohet PID, lloji PID dhe, në fakt, PID i ri. Funksioni krijon një PID të ri
    struct pid *alloc_pid(structur pid_namespace *ns)

    Ky funksion pranon vetëm hapësirën e emrave në të cilën do të qëndrojë PID i ri, kjo hapësirë ​​mund të merret duke përdorur task_active_pid_ns.
    Por ka një problem: këto simbole të kernelit nuk eksportohen nga kerneli dhe nuk mund të përdoren në module. Një e mrekullueshme më ndihmoi në zgjidhjen e këtij problemi. Nga atje merret kodi i funksionit find_sym.

    Asmlinkage static void (*change_pidR)(struct task_struct *detyra, enum pid_type type, struct pid *pid); static asmlinkage struct pid* (*alloc_pidR)(struct pid_namespace *ns); static int __init test_init(void) ( printk(KERN_ALERT "TEST driver ngarkuar!\n"); change_pidR = find_sym("change_pid"); alloc_pidR = find_sym("alloc_pid"); ... ) static ssize_t device_read(structure file * filp, char *buffer, madhësia_t gjatësia, loff_t * offset) ( printk("PID: %d.\n",current->pid); struct pid* newpid; newpid = alloc_pidR(task_active_pid_ns(aktual)); change_pidR(aktuale ,PIDTYPE_PID,newpid); printk("PID i ri: %d.\n",current->pid); ... )
    Përpilimi, nisja

    Prindi im PID 299 PID im 750 PID im i ri 751
    PID ndryshoi! Kerneli caktoi automatikisht një PID falas në programin tonë. Por a është e mundur të përdoret një PID që është zënë nga një proces tjetër, siç është PID 1? Le të shtojmë kodin pas ndarjes

    Newpid->numrat.nr = 1;
    Përpilimi, nisja

    Prindi im PID 314 PID im 1172 PID im i ri 1
    Ne marrim PID 1 të vërtetë!

    Bash ka hedhur një gabim që pengon funksionimin e ndërrimit të detyrave duke përdorur komandën %n, por të gjitha funksionet e tjera funksionojnë mirë.

    Karakteristikat interesante të proceseve me PID të ndryshuar

    PID 0: hyrja nuk mund të dalë

    Le të kthehemi te kodi dhe të ndryshojmë PID në 0.

    Newpid->numrat.nr = 0;
    Përpilimi, nisja

    Prindi im PID284 PID im 1517 PID im i ri 0
    Pra, PID 0 nuk është aq i veçantë? Gëzohemi, shkruajmë dalje dhe...

    Topi po bie! Kerneli e përcaktoi detyrën tonë si DETYRËN DETYRUESE dhe, duke parë përfundimin, thjesht u rrëzua. Me sa duket, programi ynë duhet të kthehet në PID "normale" përpara se të dalë.

    Procesi i padukshëm

    Le të kthehemi te kodi dhe të vendosim një PID që garantohet të mos jetë i zënë
    newpid->numrat.nr = 12345;

    Përpilimi, nisja

    Prindi im PID296 PID im 735 PID im i ri 12345
    Le të shohim se çfarë ka në /proc

    1 148 19 224 288 37 79 86 93 konsolat fb kcore locks ndarjet këmbimet versioni 10 149 2 226 29 4 8 87 sistemet e skedarëve acpi cpuinfo përdoruesit kyç meminfo sched_debug 58 20 20 20 20 20 8 çelësa asound kripto fs misc schedstat sysrq- aktivizo vmstat 11 16 208 24 291 6 81 89 pajisjet e shokut info ndërpret modulet kmsg scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup monton vetë 637 371 371 0 cgrupe d ma ioports kpagecount mtrr slabinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg loadavg pagetyp
    Siç mund ta shohim, /proc nuk e identifikon procesin tonë, edhe nëse kemi zënë një PID të lirë. PID-i i mëparshëm gjithashtu nuk është në /proc, dhe kjo është shumë e çuditshme. Ndoshta ne jemi në një hapësirë ​​tjetër emri dhe për këtë arsye nuk jemi të dukshëm për main /proc. Le të montojmë një /proc të ri dhe të shohim se çfarë ka

    1 14 18 210 25 291 738 81 9 pajisje autobusi fs kyç-përdoruesit kyçet e faqes info softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups 29 cgroups diskstats 29 me 29 me 29 info 29 info 7 30 7 6 83 92 cmdline dma iomem kmsg misc sched_debug këmbe kohën e funksionimit 11 15 2 224 28 37 78 84 93 config.gz shoferi sc ioports kpagecgroup modulet schedstat sys versioni 12 16 20 226 288 4 79 85 acdopages infomountrlocir ex 13 17 208 23 29 6 8 86 asound cpuinfo fb ​​'kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 sisteme skedarësh kripto info buddyinfo kcore loadavg net slabinfo thread-self zoneinfo
    Procesi ynë ende nuk ekziston, që do të thotë se jemi në hapësirën normale të emrave. Le të kontrollojmë

    Ps -e | grep bash
    296 pikë/0 00:00:00 bash

    Vetëm një bash, nga i cili nisëm programin. As PID-i i mëparshëm dhe as ai aktual nuk janë në listë.

    Artikujt më të mirë mbi këtë temë