ICMP مٿان ايٽمي شيل

ICMP مٿان ايٽمي شيل

TL، ڊاڪٽر: مان هڪ ڪرنل ماڊل لکي رهيو آهيان جيڪو ICMP پيلي لوڊ مان ڪمانڊ پڙهندو ۽ انهن کي سرور تي ايگزيڪيوٽو ڪندو جيتوڻيڪ توهان جو SSH ڪريش ٿي وڃي. سڀ کان وڌيڪ تڪليف لاء، سڀ ڪوڊ آهي GitHub.

احتياط تجربيڪار سي پروگرامر رت جا ڳوڙها ڦاٽي پوڻ جو خطرو! مان شايد اصطلاحن ۾ غلط به هجان، پر ڪنهن به تنقيد جو استقبال آهي. پوسٽ انهن لاءِ آهي جن کي سي پروگرامنگ جو تمام گهڻو خيال آهي ۽ اهي لينڪس جي اندرين کي ڏسڻ چاهيندا آهن.

تبصرن ۾ منهنجي پهرين مضمون ذڪر ڪيو ويو آهي SoftEther VPN، جيڪو ڪجهه "باقاعده" پروٽوڪول کي نقل ڪري سگهي ٿو، خاص طور تي HTTPS، ICMP ۽ جيتوڻيڪ DNS. مان تصور ڪري سگهان ٿو ته انهن مان صرف پهريون ڪم ڪري رهيو آهي، ڇاڪاڻ ته مان HTTP(S) سان تمام گهڻو واقف آهيان، ۽ مون کي ICMP ۽ DNS تي سرنگنگ سکڻو پيو.

ICMP مٿان ايٽمي شيل

ها، 2020 ۾ مون سکيو ته توهان ICMP پيڪٽس ۾ هڪ صوابديدي پيل لوڊ داخل ڪري سگهو ٿا. پر بهتر دير کان ڪڏهن به نه! ۽ جيئن ته ان بابت ڪجهه ڪري سگهجي ٿو، پوء اهو ڪرڻ جي ضرورت آهي. جيئن ته منهنجي روزاني زندگي ۾ آئون اڪثر ڪري ڪمانڊ لائن استعمال ڪندو آهيان، بشمول SSH ذريعي، هڪ ICMP شيل جو خيال پهريون ڀيرو منهنجي ذهن ۾ آيو. ۽ هڪ مڪمل بيلشيلڊ بنگو گڏ ڪرڻ لاءِ، مون ان کي لکڻ جو فيصلو ڪيو لينڪس ماڊل جي طور تي هڪ ٻوليءَ ۾ جنهن جو مون کي صرف هڪ اندازو آهي. اهڙو شيل پروسيس جي لسٽ ۾ نظر نه ايندو، توهان ان کي ڪرنل ۾ لوڊ ڪري سگهو ٿا ۽ اهو فائل سسٽم تي نه هوندو، توهان کي ٻڌڻ واري بندرگاهن جي فهرست ۾ ڪجهه به مشڪوڪ نظر نه ايندو. ان جي صلاحيتن جي لحاظ کان، هي هڪ مڪمل روٽ ڪٽ آهي، پر مون کي اميد آهي ته ان کي بهتر بڻائي ۽ ان کي آخري ريسٽورٽ جي شيل طور استعمال ڪيو وڃي جڏهن لوڊ اوسط تمام گهڻي آهي SSH ذريعي لاگ ان ٿيڻ ۽ گهٽ ۾ گهٽ عمل ڪرڻ. echo i > /proc/sysrq-triggerريبوٽ ڪرڻ کان سواءِ رسائي بحال ڪرڻ لاءِ.

اسان وٺون ٿا ٽيڪسٽ ايڊيٽر، پائٿون ۽ سي ۾ بنيادي پروگرامنگ مهارتون، گوگل ۽ مجازي جنهن کي توهان چاقو جي هيٺان رکڻ ۾ ڪو اعتراض نه ڪريو جيڪڏهن سڀ ڪجهه ڀڄي وڃي (اختياري - مقامي ورچوئل بڪس/KVM/etc) ۽ اچو ته هلون!

ڪلائنٽ جو حصو

مون کي لڳي رهيو هو ته ڪلائنٽ جي حصي لاءِ مون کي اٽڪل 80 لائينن سان هڪ اسڪرپٽ لکڻو پوندو، پر اهڙا مهربان ماڻهو هئا جن مون لاءِ اهو ڪيو. سڀ ڪم. ڪوڊ غير متوقع طور تي سادو نڪتو، 10 اهم لائينن ۾ مناسب:

import sys
from scapy.all import sr1, IP, ICMP

if len(sys.argv) < 3:
    print('Usage: {} IP "command"'.format(sys.argv[0]))
    exit(0)

p = sr1(IP(dst=sys.argv[1])/ICMP()/"run:{}".format(sys.argv[2]))
if p:
    p.show()

اسڪرپٽ ٻه دليلن، هڪ پتو ۽ هڪ پيل لوڊ وٺندو آهي. موڪلڻ کان اڳ، پيل لوڊ هڪ چاٻي کان اڳ آهي run:، اسان کي ان جي ضرورت پوندي بي ترتيب پيل لوڊ سان پيڪيجز کي خارج ڪرڻ لاءِ.

ڪرنل کي پيڪيجز ٺاهڻ لاءِ استحقاق جي ضرورت آهي، تنهنڪري اسڪرپٽ کي سپر يوزر طور هلائڻو پوندو. لڳائڻ جي اجازت ڏيڻ نه وساريو ۽ پاڻ کي اسڪيپي انسٽال ڪريو. ديبين نالي هڪ پيڪيج آهي python3-scapy. هاڻي توهان چيڪ ڪري سگهو ٿا ته اهو سڀ ڪيئن ڪم ڪري ٿو.

حڪم هلائڻ ۽ ٻاھر ڪڍڻ
morq@laptop:~/icmpshell$ sudo ./send.py 45.11.26.232 "Hello, world!"
Begin emission:
.Finished sending 1 packets.
*
Received 2 packets, got 1 answers, remaining 0 packets
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 45
id = 17218
flags =
frag = 0
ttl = 58
proto = icmp
chksum = 0x3403
src = 45.11.26.232
dst = 192.168.0.240
options
###[ ICMP ]###
type = echo-reply
code = 0
chksum = 0xde03
id = 0x0
seq = 0x0
###[ Raw ]###
load = 'run:Hello, world!

اهو اهو آهي جيڪو سنيفر ۾ ڏسڻ ۾ اچي ٿو
morq@laptop:~/icmpshell$ sudo tshark -i wlp1s0 -O icmp -f "icmp and host 45.11.26.232"
Running as user "root" and group "root". This could be dangerous.
Capturing on 'wlp1s0'
Frame 1: 59 bytes on wire (472 bits), 59 bytes captured (472 bits) on interface wlp1s0, id 0
Internet Protocol Version 4, Src: 192.168.0.240, Dst: 45.11.26.232
Internet Control Message Protocol
Type: 8 (Echo (ping) request)
Code: 0
Checksum: 0xd603 [correct] [Checksum Status: Good] Identifier (BE): 0 (0x0000)
Identifier (LE): 0 (0x0000)
Sequence number (BE): 0 (0x0000)
Sequence number (LE): 0 (0x0000)
Data (17 bytes)

0000 72 75 6e 3a 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 run:Hello, world
0010 21 !
Data: 72756e3a48656c6c6f2c20776f726c6421
[Length: 17]

Frame 2: 59 bytes on wire (472 bits), 59 bytes captured (472 bits) on interface wlp1s0, id 0
Internet Protocol Version 4, Src: 45.11.26.232, Dst: 192.168.0.240
Internet Control Message Protocol
Type: 0 (Echo (ping) reply)
Code: 0
Checksum: 0xde03 [correct] [Checksum Status: Good] Identifier (BE): 0 (0x0000)
Identifier (LE): 0 (0x0000)
Sequence number (BE): 0 (0x0000)
Sequence number (LE): 0 (0x0000)
[Request frame: 1] [Response time: 19.094 ms] Data (17 bytes)

0000 72 75 6e 3a 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 run:Hello, world
0010 21 !
Data: 72756e3a48656c6c6f2c20776f726c6421
[Length: 17]

^C2 packets captured

جوابي پيڪيج ۾ پيل لوڊ تبديل نٿو ڪري.

ڪرنل ماڊل

ديبين ورچوئل مشين ٺاهڻ لاءِ توهان کي گهٽ ۾ گهٽ ضرورت پوندي make и linux-headers-amd64، باقي انحصار جي صورت ۾ ايندا. مان مضمون ۾ پورو ڪوڊ مهيا نه ڪندس؛ توھان ان کي ڪلون ڪري سگھوٿا Github.

ٿلهو سيٽ اپ

شروع ڪرڻ سان، اسان کي ماڊل لوڊ ڪرڻ ۽ ان کي لوڊ ڪرڻ لاءِ ٻن ڪمن جي ضرورت آھي. unloading لاء فنڪشن ضروري نه آهي، پر پوء rmmod اهو ڪم نه ڪندو؛ ماڊل صرف ان لوڊ ڪيو ويندو جڏهن بند ڪيو ويندو.

#include <linux/module.h>
#include <linux/netfilter_ipv4.h>

static struct nf_hook_ops nfho;

static int __init startup(void)
{
  nfho.hook = icmp_cmd_executor;
  nfho.hooknum = NF_INET_PRE_ROUTING;
  nfho.pf = PF_INET;
  nfho.priority = NF_IP_PRI_FIRST;
  nf_register_net_hook(&init_net, &nfho);
  return 0;
}

static void __exit cleanup(void)
{
  nf_unregister_net_hook(&init_net, &nfho);
}

MODULE_LICENSE("GPL");
module_init(startup);
module_exit(cleanup);

هتي ڇا ٿي رهيو آهي:

  1. ٻه هيڊر فائلون پاڻ کي ماڊل ۽ نيٽ فلٽر کي هٽائڻ لاءِ کڄي وينديون آهن.
  2. سڀئي آپريشن نيٽ فلٽر ذريعي ٿين ٿا، توھان ان ۾ ٿلها سيٽ ڪري سگھو ٿا. هن کي ڪرڻ لاء، توهان کي ساخت جو اعلان ڪرڻو پوندو جنهن ۾ ٿلهو ترتيب ڏني ويندي. سڀ کان اهم شيء اهو آهي ته فنڪشن کي بيان ڪرڻ لاء جيڪو ٿلهو طور تي عمل ڪيو ويندو: nfho.hook = icmp_cmd_executor; مان پاڻ بعد ۾ فنڪشن تي ويندس.
    پوء مون پيڪيج لاء پروسيسنگ وقت مقرر ڪيو: NF_INET_PRE_ROUTING پيڪيج کي پروسيس ڪرڻ لاءِ وضاحت ڪري ٿو جڏهن اهو پهريون ڀيرو ڪنيل ۾ ظاهر ٿئي ٿو. استعمال ڪري سگهجي ٿو NF_INET_POST_ROUTING پيڪيٽ کي پروسيس ڪرڻ لاءِ جيئن اهو ڪنيل مان نڪرندو آهي.
    مون فلٽر کي IPv4 تي سيٽ ڪيو: nfho.pf = PF_INET;.
    مان پنهنجي ٿلهي کي سڀ کان وڌيڪ ترجيح ڏيان ٿو: nfho.priority = NF_IP_PRI_FIRST;
    ۽ مان ڊيٽا جي جوڙجڪ کي حقيقي ٿلهو طور رجسٽر ڪريان ٿو: nf_register_net_hook(&init_net, &nfho);
  3. آخري فنڪشن ٿلهو هٽائي ٿو.
  4. لائسنس واضح طور تي اشارو ڪيو ويو آهي ته جيئن مرتب ڪندڙ شڪايت نه ڪري.
  5. ڪارڪن module_init() и module_exit() ماڊل کي شروع ڪرڻ ۽ ختم ڪرڻ لاءِ ٻيا ڪم مقرر ڪريو.

پيل لوڊ ٻيهر حاصل ڪرڻ

هاڻي اسان کي پيل لوڊ ڪڍڻ جي ضرورت آهي، اهو سڀ کان ڏکيو ڪم ٿي ويو. ڪرنل ۾ پيلي لوڊ سان ڪم ڪرڻ لاءِ بلٽ ان فنڪشن نه آهي؛ توهان صرف اعليٰ سطحي پروٽوڪول جا هيڊر پارس ڪري سگهو ٿا.

#include <linux/ip.h>
#include <linux/icmp.h>

#define MAX_CMD_LEN 1976

char cmd_string[MAX_CMD_LEN];

struct work_struct my_work;

DECLARE_WORK(my_work, work_handler);

static unsigned int icmp_cmd_executor(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
  struct iphdr *iph;
  struct icmphdr *icmph;

  unsigned char *user_data;
  unsigned char *tail;
  unsigned char *i;
  int j = 0;

  iph = ip_hdr(skb);
  icmph = icmp_hdr(skb);

  if (iph->protocol != IPPROTO_ICMP) {
    return NF_ACCEPT;
  }
  if (icmph->type != ICMP_ECHO) {
    return NF_ACCEPT;
  }

  user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
  tail = skb_tail_pointer(skb);

  j = 0;
  for (i = user_data; i != tail; ++i) {
    char c = *(char *)i;

    cmd_string[j] = c;

    j++;

    if (c == '')
      break;

    if (j == MAX_CMD_LEN) {
      cmd_string[j] = '';
      break;
    }

  }

  if (strncmp(cmd_string, "run:", 4) != 0) {
    return NF_ACCEPT;
  } else {
    for (j = 0; j <= sizeof(cmd_string)/sizeof(cmd_string[0])-4; j++) {
      cmd_string[j] = cmd_string[j+4];
      if (cmd_string[j] == '')
	break;
    }
  }

  schedule_work(&my_work);

  return NF_ACCEPT;
}

ڇا ٿي رهيو آهي:

  1. مون کي اضافي هيڊر فائلون شامل ڪرڻيون هيون، هن ڀيري IP ۽ ICMP هيڊرز کي ترتيب ڏيڻ لاءِ.
  2. مون وڌ ۾ وڌ لڪير جي ڊيگهه مقرر ڪئي: #define MAX_CMD_LEN 1976. بلڪل ائين ڇو؟ ڇو ته مرتب ڪندڙ ان بابت شڪايت ڪري ٿو! انهن مون کي اڳ ۾ ئي صلاح ڏني آهي ته مون کي اسٽيڪ ۽ هيپ کي سمجهڻ جي ضرورت آهي، هڪ ڏينهن مان اهو ضرور ڪندس ۽ شايد ڪوڊ کي به درست ڪندس. مون فوري طور تي لڪير مقرر ڪيو جنهن ۾ حڪم هوندو: char cmd_string[MAX_CMD_LEN];. اهو سڀني ڪمن ۾ ظاهر ٿيڻ گهرجي؛ مان هن بابت وڌيڪ تفصيل سان پيراگراف 9 ۾ ڳالهائيندس.
  3. هاڻي اسان کي شروع ڪرڻ جي ضرورت آهي (struct work_struct my_work;) ساخت ۽ ان کي ٻئي فنڪشن سان ڳنڍيو (DECLARE_WORK(my_work, work_handler);). مان اهو به ڳالهائيندس ته اهو نائين پيراگراف ۾ ڇو ضروري آهي.
  4. هاڻي مان هڪ فنڪشن جو اعلان ڪريان ٿو، جيڪو هڪ ٿلهو هوندو. قسم ۽ قبول ٿيل دلائل نيٽ فلٽر طرفان ترتيب ڏنل آهن، اسان کي صرف دلچسپي آهي skb. هي هڪ ساکٽ بفر آهي، هڪ بنيادي ڊيٽا جو ڍانچو جنهن ۾ هڪ پيڪٽ بابت سڀ موجود معلومات شامل آهي.
  5. ڪم ڪرڻ لاءِ فنڪشن لاءِ، توھان کي ضرورت پوندي ٻن اڏاوتن ۽ گھڻن متغيرن، جن ۾ ٻه اِيٽرٽر شامل آھن.
      struct iphdr *iph;
      struct icmphdr *icmph;
    
      unsigned char *user_data;
      unsigned char *tail;
      unsigned char *i;
      int j = 0;
  6. اسان منطق سان شروع ڪري سگهون ٿا. ماڊل کي ڪم ڪرڻ لاءِ، ICMP ايڪو کان سواءِ ڪنهن به پيڪيٽ جي ضرورت نه آهي، تنهنڪري اسان بلٽ ان فنڪشن استعمال ڪندي بفر کي پارس ڪريون ٿا ۽ سڀني غير ICMP ۽ غير ايڪو پيڪيٽ کي ٻاهر ڪڍون ٿا. واپسي NF_ACCEPT مطلب ته پيڪيج جي قبوليت، پر توهان واپسي ذريعي پيڪيجز کي به ڇڏي سگھو ٿا NF_DROP.
      iph = ip_hdr(skb);
      icmph = icmp_hdr(skb);
    
      if (iph->protocol != IPPROTO_ICMP) {
        return NF_ACCEPT;
      }
      if (icmph->type != ICMP_ECHO) {
        return NF_ACCEPT;
      }

    مون جانچ نه ڪئي آهي ته IP هيڊرن کي چيڪ ڪرڻ کان سواءِ ڇا ٿيندو. سي جي منهنجي گهٽ ۾ گهٽ ڄاڻ مون کي ٻڌائي ٿي ته اضافي چيڪن جي بغير، ڪجهه خوفناڪ ٿيڻ جو پابند آهي. مون کي خوشي ٿي ويندي جيڪڏهن توهان مون کي هن کان روڪيو!

  7. هاڻي ته پيڪيج صحيح قسم جو آهي جيڪو توهان کي گهربل آهي، توهان ڊيٽا ڪڍي سگهو ٿا. بغير ڪنهن تعمير ٿيل فنڪشن جي، توهان کي پهريان هڪ پوائنٽر حاصل ڪرڻو پوندو پيلي لوڊ جي شروعات ڏانهن. اهو هڪ جڳهه تي ڪيو ويو آهي، توهان کي پوائنٽر کي ICMP هيڊر جي شروعات ڏانهن وٺي وڃڻ جي ضرورت آهي ۽ ان کي هن هيڊر جي سائيز ڏانهن منتقل ڪرڻ جي ضرورت آهي. هر شي ساخت کي استعمال ڪري ٿو icmph: user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
    هيڊر جي پڇاڙيءَ ۾ پيل لوڊ جي پڇاڙيءَ سان ملڻ گهرجي skbتنهن ڪري اسان ان کي حاصل ڪريون ٿا ايٽمي ذريعن سان لاڳاپيل ساخت مان: tail = skb_tail_pointer(skb);.

    ICMP مٿان ايٽمي شيل

    تصوير چوري ٿي وئي هتي کان، توهان ساکٽ بفر بابت وڌيڪ پڙهي سگهو ٿا.

  8. هڪ دفعو توهان وٽ شروع ۽ آخر ڏانهن اشارو آهي، توهان ڊيٽا کي هڪ تار ۾ نقل ڪري سگهو ٿا cmd_string، ان کي چيڪ ڪريو اڳي جي موجودگي لاءِ run: ۽، يا ته پيڪيج کي رد ڪريو جيڪڏھن اھو غائب آھي، يا ھن اڳياڙي کي ختم ڪندي، لڪير کي ٻيهر لکو.
  9. اھو اھو آھي، ھاڻي توھان ٻئي ھينڊلر کي سڏي سگھو ٿا: schedule_work(&my_work);. جيئن ته اهو ممڪن نه ٿيندو ته اهڙي ڪال تي هڪ پيٽرولر کي منتقل ڪرڻ لاء، حڪم سان لائن گلوبل هجڻ گهرجي. schedule_work() پاس ٿيل ڍانچي سان لاڳاپيل فنڪشن کي ٽاسڪ شيڊولر جي عام قطار ۾ رکي ٿو ۽ مڪمل ڪيو ويندو، توهان کي حڪم جي مڪمل ٿيڻ جو انتظار نه ڪرڻ جي اجازت ڏيندو. اهو ضروري آهي ڇو ته ٿلهو تمام تيز هجڻ گهرجي. ٻي صورت ۾، توهان جي پسند اها آهي ته ڪجھ به شروع نه ٿيندو يا توهان کي ڪنيل خوفناڪ حاصل ٿيندو. دير آهي موت وانگر!
  10. اهو ئي آهي، توهان هڪ لاڳاپيل واپسي سان پيڪيج قبول ڪري سگهو ٿا.

يوزر اسپيس ۾ هڪ پروگرام سڏڻ

هي فنڪشن سڀ کان وڌيڪ سمجھڻ وارو آهي. ان ۾ نالو ڏنو ويو DECLARE_WORK()، قسم ۽ قبول ٿيل دليل دلچسپ نه آهن. اسان لڪير کي حڪم سان وٺي وٺو ۽ ان کي مڪمل طور تي شيل ڏانهن منتقل ڪيو. هن کي پارس ڪرڻ سان معاملو ڪرڻ ڏيو، بائنري ڳولڻ ۽ ٻيو سڀ ڪجهه.

static void work_handler(struct work_struct * work)
{
  static char *argv[] = {"/bin/sh", "-c", cmd_string, NULL};
  static char *envp[] = {"PATH=/bin:/sbin", NULL};

  call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
}

  1. دليلن کي ترتيب ڏيو تارن جي صف ۾ argv[]. مان سمجهان ٿو ته هرڪو ڄاڻي ٿو ته پروگرام اصل ۾ هن طريقي سان عمل ڪيا ويا آهن، ۽ نه ته خالن سان مسلسل قطار جي طور تي.
  2. ماحولياتي متغير مقرر ڪريو. مون صرف PATH داخل ڪيو گهٽ ۾ گهٽ رستن جي سيٽ سان، اميد آهي ته اهي سڀئي اڳ ۾ ئي گڏيل آهن /bin с /usr/bin и /sbin с /usr/sbin. ٻيا رستا گهٽ ۾ گهٽ عملي طور تي اهم آهن.
  3. ٿي ويو، اچو ته اهو ڪريون! ڪرنل فنڪشن call_usermodehelper() داخلا قبول ڪري ٿي. بائنري ڏانهن رستو، دليلن جي صف، ماحول جي متغيرن جي صف. هتي مان اهو به سمجهان ٿو ته هرڪو هڪ الڳ دليل جي طور تي executable فائل ڏانهن رستو پاس ڪرڻ جي معني سمجهي ٿو، پر توهان پڇي سگهو ٿا. آخري دليل بيان ڪري ٿو ته ڇا پروسيس مڪمل ٿيڻ جو انتظار ڪرڻ (UMH_WAIT_PROC)، عمل جي شروعات (UMH_WAIT_EXEC) يا بلڪل انتظار نه ڪريو (UMH_NO_WAIT). ڪجھ وڌيڪ آھي؟ UMH_KILLABLE، مون ان ۾ نه ڏٺو.

اسيمبلي

ڪنيل ماڊلز جي اسيمبلي کي ڪنيل ميڪ فريم ورڪ ذريعي ڪيو ويندو آهي. سڏيو ويو make هڪ خاص ڊاريڪٽري اندر ڪنييل ورزن سان ڳنڍيل آهي (هتي بيان ڪيو ويو آهي: KERNELDIR:=/lib/modules/$(shell uname -r)/build)، ۽ ماڊل جو مقام variable ڏانهن منتقل ڪيو ويو آهي M دليلن ۾. icmpshell.ko ۽ صاف مقصد هي فريم ورڪ مڪمل طور تي استعمال ڪن ٿا. IN obj-m اعتراض واري فائل کي اشارو ڪري ٿو جيڪو ماڊل ۾ تبديل ڪيو ويندو. نحو جيڪو ٻيهر ٺاهي ٿو main.o в icmpshell.o (icmpshell-objs = main.o) مون کي تمام منطقي نظر نٿو اچي، پر ائين ئي هجي.

KERNELDIR:=/lib/modules/$(shell uname -r)/build

obj-m = icmpshell.o
icmpshell-objs = main.o

all: icmpshell.ko

icmpshell.ko: main.c
make -C $(KERNELDIR) M=$(PWD) modules

clean:
make -C $(KERNELDIR) M=$(PWD) clean

اسان گڏ ڪريون ٿا: make. لوڊ ڪندي: insmod icmpshell.ko. ٿي ويو، توهان چيڪ ڪري سگهو ٿا: sudo ./send.py 45.11.26.232 "date > /tmp/test". جيڪڏهن توهان وٽ توهان جي مشين تي فائل آهي /tmp/test ۽ اهو تاريخ تي مشتمل آهي درخواست موڪلي وئي، جنهن جو مطلب آهي ته توهان سڀ ڪجهه صحيح ڪيو ۽ مون سڀ ڪجهه صحيح ڪيو.

ٿڪل

ايٽمي ترقي سان منهنجو پهريون تجربو منهنجي توقع کان گهڻو آسان هو. جيتوڻيڪ سي ۾ ترقي ڪرڻ جي تجربي کان سواءِ، ڪمپيلر اشارن ۽ گوگل جي نتيجن تي توجهه ڏيڻ، مان هڪ ڪم ڪندڙ ماڊل لکڻ جي قابل ٿيس ۽ هڪ ڪرنل هيڪر وانگر محسوس ڪري رهيو هوس، ۽ ساڳئي وقت هڪ اسڪرپٽ ٻار. ان کان علاوه، مان ڪينل نيوبيز چينل ڏانهن ويو، جتي مون کي استعمال ڪرڻ لاء چيو ويو schedule_work() سڏڻ بدران call_usermodehelper() پاڻ کي ٿلهو اندر ۽ کيس شرمسار ڪيو، صحيح طور تي هڪ اسڪيم تي شڪ ڪيو. ڪوڊ جون هڪ سؤ لائينون مون کي منهنجي مفت وقت ۾ ترقي جي هڪ هفتي بابت خرچ ڪري ٿي. هڪ ڪامياب تجربو جيڪو سسٽم جي ترقي جي زبردست پيچيدگي بابت منهنجي ذاتي افسانه کي تباهه ڪري ڇڏيو.

جيڪڏهن ڪو ماڻهو Github تي ڪوڊ جو جائزو وٺڻ تي متفق آهي، مان شڪرگذار ٿيندس. مون کي پڪ آهي ته مون ڪيتريون ئي بيوقوف غلطيون ڪيون آهن، خاص طور تي جڏهن تارن سان ڪم ڪندي.

ICMP مٿان ايٽمي شيل

جو ذريعو: www.habr.com

تبصرو شامل ڪريو