TL; DRáĨá á¨á¨ááá ááá áĨá¨áģáአáá ᨠICMP áááĢ áááĩ áĩááááŊá á¨ááĢááĨ áĨá á á áááአáá á¨ááĢáĩááŊáá SSH áĸáĢá ááŊááĸ á áŖá áĩáááĩáĩ áááá¸á, ááá áŽáĩ áá
áĨááá áááĩ áĢáĢá áą á¨C ááŽááĢá á ááááŊ á á°á áĨááŖ ááááą ááŊáá! á áááĩ áááļáŊ ááĩáĨ áĨááŗá á°áŗáĩáŧ ááá ááŊáá, ááá áá ááááá áĩáŊáĩ á°ááŖáááĩ á áá. ááĨá á¨áŗá°á á áĩá ᲠááŽááĢááá á áŖá á¨áá ááŗáĨ ááá¸á áĨá á¨ááááĩá á¨ááĩáĨ ááá áá¨áĩ ááááá áááĸ
á¨áĨá á¨ááááĒáĢ á áĩá°áĢá¨áĩ ááĩáĨ
á ááŖ á 2020 á¨áááá° áááĩ áá° ICMP ááŦáļáŊ ááĩááŖáĩ áĨáá°ááŊá á°áááŠáĸ áá á¨ááŧáá áá ááááļ á¨á°áģá áá! áĨá á ááĩ ááá á áĨáą áá áá°á¨á áĩáááŊá, á¨ááĢá áá°á¨á á áá áĩ. á áááĩ á°áááĩ áááá´ áĨááá áá á¨áĩáĨáá ááĩááá á á¤áĩá¤áĩá¤áŊ á áŠá áĩááá áá ââᨠICMP áŧá ááŗáĨ ááááĒáĢ áá° á áĨááŽáŦ ááŖáĸ áĨá á¨á°áá áĄááŧááĩ áĸááá ááá°áĨá°áĨáŖ áĨá áŖá°áĨáŠáĩ ááá áĨáá° ááááĩ ááá ááŊáá áá°ááŠáĸ áĨáá˛á
ááááą á
áááĩ á áá°áļáŊ áááá ááĩáĨ á ááŗáá, áá° á¨ááá ááĢá ááŊáá áĨá á ááá áĩáááą áá á áááá, á ááŗááĨ áá°áĻáŊ áááá ááĩáĨ ááá á á áĢáŖáĒ ááá á áĢáŠá. á¨áŊááŗá á ááááŖ áá
áá á áá á¨á°áá áŠáĩáĒáĩ áááŖ áá áĨáąá áááģáģá áĨá áĨáá° á¨áá¨á¨áģ á ááĢá áŧá áá ááá áĩ á°áĩá á á°áááá á¨ááĢá á ááĢá á á¤áĩá¤áĩá¤áŊ á áŠá ááááŖáĩ áĨá áĸáĢááĩ áááĩááá á áŖá á¨áá°á áááĸ echo i > /proc/sysrq-trigger
áŗáá áŗáááŗ ááŗá¨áģá áá°áá á¨á áĩ áááááĩ.
á¨áŊáá á ááŗáá áĨáááĩáŗáá, áá°á¨áŗá á¨ááŽááĢá áŊááŗááŊ á Python áĨá C, Google áĨá
á¨á°áá á áá
áá°áá áá áá° 80 á¨áá á ááĩááŽáŊá á¨áĢá áĩááĒááĩ ááģá áĨááŗááĨá ááĩáá áá á áŖ áá áĢá°á¨ááá á°á á°ááŊ áá አáĸ
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 áá ááááĩ ááŊáááĸ
ááá á áááá
ááááá, áááá áááĢá áĨá áááĢáá áááĩ á°ááŖáĢáĩ áĢáĩááááá. á¨ááá¨áĩ á°ááŖá á áĢáĩáááá, áá á¨ááĢ 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);
áĨáá áá áĨá¨áá áá:
- áááá áĨáĢáą áĨá á¨á°áŖáĢ ááŖáĒáĢáá ááááŖá á áááĩ á¨áĢáĩá ááááŊ á°áĩáĻ ááĨá°áááĸ
- ááá áááááŊ á á°áŖáĢ ááŖáĒáĢ ááĩáĨ áĢááá, á ááĩᥠááá áááŊá áááááĩ ááŊáá. áá
áá áááĩá¨á ááá áá á¨ááááá áĩá ááá
á ááá
áĢáĩáááááŗá. á áŖá á áĩáááá ááá áĨáá° ááá á á¨áá áĢáá á°ááŖá ááááŊ áá-
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);
- á¨áá¨á¨áģá á°ááŖá ááá ááá áĢáĩáááŗá.
- á áááŖáĒá á áŦáŗ áĨááŗáĢá°á áááą á ááá á°á ááááĸ
- á°ááŖáŽáŊ
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;
}
áá áĨá¨á°á°á¨á áá:
- á°á¨ááĒ á¨áĢáĩá ááááŊá ááĢá°áĩ áá á¨áĨááŖ á áá áá IP áĨá ICMP áĢáĩáááŊá ááááŖá ááĸ
- á¨áá°ááá á¨ááĩáá ááááĩ á ááá
áģáááĄ-
#define MAX_CMD_LEN 1976
. ááá á áĩááá áá ? ááááĢáąá á áááŖáĒá áĩááĨáą á áŦáŗ á áá! ááá áĨá ááá áá¨áŗáĩ áĨááŗááĨá á áĩááĩáá á ááááááŖ á ááĩ áá á áĨááá áááĩ áá á á á°áááá áĨá ááááŖáĩ áŽáąá á áĩá°áĢáááááĸ áá˛áĢáá áĩáááá á¨áĢááá ááĩáá á ááá áģáááĄ-char cmd_string[MAX_CMD_LEN];
. á ááá á°ááŖáĢáĩ ááĩáĨ ááŗá¨áĩ á áá áĩ, áĩááá ááŗá á á áááŊ 9 áá á á áá áááá áĨáááĢáá. - á áá ááĩááá á ááĨá (
struct work_struct my_work;
) ááá á áĨá á¨áá á°ááŖá áá áĢááááĩ (DECLARE_WORK(my_work, work_handler);
). á áá ááá á áááŊ áá áá ááá á áĩááá áĨáá°áá áĨáááĢáá. - á áá á ááĩ á°ááŖá á áááá, áĨáąá ááá á áááá. ááááĩ áĨá á°ááŖáááĩ áĢáá¸á ááááŽáŊ á netfilter á¨áŗáá áá¸á, áĨá áĨáģ ááááĩ á áá
skb
. áá á¨áļáŦáĩ ááĩ áááŖ áĩá ááŦáĩ áááá á¨ááá áá¨áááŊá á¨áĢá áá á¨áŗá á¨áááĨ ááá á áááĸ - á°ááŖአáĨáá˛á áĢ áááĩ á°á°áááááŊá á¨áᎠáááĩ á ááááŽáŊá áĨá á ááĢáŗ á°ááááŽáŊá áĢáĩáááááŗááĸ
struct iphdr *iph; struct icmphdr *icmph; unsigned char *user_data; unsigned char *tail; unsigned char *i; int j = 0;
- á ááá áááá áĨááŊááááĸ ááá áĨáá˛á°áĢáŖ ᨠICMP Echo áá ááá áĨáŊááŊ á áĢáĩáááááŖ áĩááá
á áĨᎠá¨á°á°áŠ á°ááŖáĢáĩá á áá áá ááąá áĨáá°áá°á áĨá áááá 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; }
á¨á áá áĢáĩáááŊá áŗáá¨áááĨ áá áĨáá°ááá á ááá¨ááŠááĸ áĩá C áĢáá á ááĩá°á áĨáááĩ áĢá á°á¨ááĒ áŧáŽáŊ á ááĩ á áĩá¨á ááá áá¨á°áą á áááá áááááĸ á¨áá áĨáŗáŗááá á°áĩ áááá!
- á áá áĨá
á á¨ááĢáĩáááá áĩáááá á áááĩ áĩááá áááĄá áááŖáĩ ááŊáá. á áĨᎠá¨á°á°áĢ á°ááŖá á¨áá á ááááĒáĢ ááááĢá ááááĒáĢ á áá ááááĩ á ááĨááĩáĸ áá
á á ááĩ áĻáŗ áá¨áááá, á áááá áá° ICMP áĢáĩá ááááĒáĢ ááá°áĩ áĨá áá°áá
áĢáĩá áá á ááá°áĩ áĢáĩáááááŗá. ááá ááá ááá
áá áá ááá
icmph
:user_data = (unsigned char *)((unsigned char *)icmph + (sizeof(icmph)));
á¨áĢáĩáá áá¨á¨áģ á¨á°áĢáá áááĩ áá¨á¨áģ áá ááááĩ á áá áĩáĸskb
, áĩááá áĨá á¨á°ááá ááá á á¨áááá áá´ááŊá á áá áá áĨááááá:tail = skb_tail_pointer(skb);
.
ááĩá á°á°ááááĨáá áŖ áĩá áļáŦáĩ ááĩ á¨á áá ááá áĨ ááŊáááĸ - ááááĒáĢ áĨá áá¨á¨áģ áá á ááááŊ áĢáááĩ á áá áááĄá áá° ááĨá¨ááá áá
áŗáĩ ááŊáááĸ
cmd_string
, á áĩá á áĨáĢ áááŠá áĢá¨áááĄrun:
áĨááŖ áá áĨá áá á¨á á áĢáĩáááąáĩáŖ ááá ááĩááŠá áĨáá°áá ááááŖ áá á á áĩá á áĨáĢ áĢáĩáááąáĸ - áĢ áĨáģ áááŖ á áá áá° áá á°ááŖáŖáĒ áá°áá ááŊáááĄ-
schedule_work(&my_work);
. ááĨáá°áá á áááĩ áĨáĒ áááĒáĢ ááĩá°ááá áĩááááģá á¨áĩáĨáá áá áĢáá ááĩáá ááá á ááá ááá á áá áĩ.schedule_work()
á¨áŗááá ááá á áá á¨á°áĢáĢááá á°ááŖá áá° á°ááŖá áááááĨá á á ááá áá¨á áĢáĩáááŖá áĨá áĢá áá áá, áá á áĩááá áĨáĩáĒá ááá áĩá¨áĩ áĨááŗáá áĨá áĢáĩáŊáááŗá. ááá áá á áŖá ááŖá ááá á áá áĩ ááááĢáąá áá á áĩááá áá. á áá áááĢ áááĢá ááá ááá á ááááá ááá á¨á¨ááá áŊáĨá áá°ááĩáĨááŗá. áááá¨áĩ áĨáá° ááĩ áá! - áĢ áĨáģ áááŖ áĨá áá á á°ááá ááááģ ááá á ááŊáááĸ
á á°á áá áĻáŗ áá ááŽááĢá á áá°áá áá
áá
á°ááŖá á áŖá ááá¨áŗáĩ á¨ááģá áá. ááĩáĨ áĩá á°á°áĨáˇááĸ 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);
}
- ááááŽáŊá áá° á¨ááĨá¨áááááŊ áĩááĩá áĢáááĨáŠ
argv[]
. áĨá áĨáááŗáá ááŽááĢááŊ á áĨáááą á áá ááááĩ áĨáá°ááá¸á áĨá áĨáá° ááŖá ááĩáá áŗááá á¨áĻáŗááŊ áá ááá á°á áĨáá°ááĢáá áĨáááŗáááĸ - á¨á áĢáŖáĸ á°ááááŽáŊá áĢááááĸ PATH áĢáĩááŖááĩ á áĩááš á¨ááááļáŊ áĩáĨáĩáĨ áĨáģ áááŖ ááá ááĩááá á°áŖáá¨á áá á áĨáŦ á°áĩá á ááĩá¨á
/bin
Ņ/usr/bin
и/sbin
Ņ/usr/sbin
. áááŊ ááááļáŊ á á°ááŖá áĨááĨáá á áĩááá á áá°áááĸ - á°á¨áááááŖ áĨááĩááá! á¨á¨ááá á°ááŖá
call_usermodehelper()
áááĸáĢ ááá áá. áá° áááĩáŽáŊ á¨áááĩá°á ááááĩáŖ á¨áááá áĩááĩááŖ á¨á áĢáŖáĸ á°ááááŽáŊ áĩááĩááĸ áĨáá á á°á¨ááĒ ááá á°á áá° ááģáá ááá á¨áááĩá°áá ááááĩ áĨáá° á¨á°áᨠáááĩ á¨áá°áááá áĩááá áĨáá°áá¨áŗá áĨáááŗáá, ááá áá áĨááĩá áá á¨á ááŊáá. á¨áá¨á¨áģá áá¨áĢá¨áĒáĢ áá°áą áĨáĩáĒá ááá áĩá¨áĩ áá á á á ááá á ááá á á á ááááģá (UMH_WAIT_PROC
á¨áá°áą ááááĒáĢ (UMH_WAIT_EXEC
) ááá á¨ááļ á ááá á á (UMH_NO_WAIT
). ááá á á?UMH_KILLABLE
áŖ á áá¨ááĩááĸ
áá°áĨá°áĨ
á¨á¨ááá ááááŊá áá°áĨá°áĨ á¨áá¨áááá á á¨ááá ááááĢ á áŠá áááĸ á°á ááˇááĸ make
á¨á¨ááá áĨáĒáĩ áá á á°áŗá°á¨ áአáááĢ ááĩáĨ (áĨáá
ááááģááĄ) KERNELDIR:=/lib/modules/$(shell uname -r)/build
), áĨá á¨ááá áĻáŗ áá° á°áááá á°áááá M
á áááá ááĩáĨ. ᨠicmpshell.ko áĨá áášá
áĸááááŊ áá
áá áááá áá ááá áá ááááĸ ááĩáĨ 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
áĨá áĨáĢáá á¨á°áá¨á áĩá áá ááá, áá
á áááĩ áááá ááá á áĩááá á á°á¨á áĨá áááá ááá á áĩááá á á°á¨áá áááĩ áá.
áá°áá°ááĢ
á ááááá áááĩ á¨ááááĒáĢ á°áááŽáŦ á¨á á á
áŠáĩ á áá ááá áá ááĸ ááá áĨááŗá á ᲠááĩáĨ áĢá áááĩ áŖ á á áááŖáĒ áááŽáŊ áĨá á Google áá¤áļáŊ áá á áá°áŽá áŖ á¨áá°áĢ ááá áááá áĨá áĨáá° á¨ááá á áá áŖ áĨá á á°ááŗáŗá áá á¨áĩááĒááĩ áá
áá°ááááĸ á á°á¨ááĒááŖ áĨááĩá áá á°ááá¨á áá° Kernel Newbies áģáá áá áá ááĸ schedule_work()
á¨áá°áá ááá
call_usermodehelper()
ááá áá ááĩáĨ áĢáą áĨá ááá áá áá á áá áĢá á á áŗáá¨ááĸ á ááĩ ááļ ááĩáá áŽáĩ á áĨá áá áá ááĩáĨ á ááĩ áŗáááĩ áĢá
á áááĩ ááĒ áĨáá. áĩá áĩáááĩ áááĩ áĨá
á ááĩáĨáĩáĨááĩ áĢááá á¨áá á á áŗáĒá áĢá á á¨á°áŗáĢ á°áááŽáĸ
á ááĩ á°á á Github áá á¨áŽáĩ áááá áááĩá¨á á¨á°áĩáááŖ á ááĩáá áĨáááááĸ áĨááá á áá áĨá á°á°áĨ áĩá á°áļáŊá áĨáá°á°áĢá áĨááá á áá á á°áá á áááĩ áĩá°áĢáĸ
ááá: hab.com