Մի քանի օր առաջ իմ անգլերէն մատեանում գրառել էի թէ ինչպէս Erlangի վիրտուալ մեքենան հետեւել, ու «ցանցառներ ռադիօ»-ի ժամանակ նորայրը հարցրեց եթէ նման բան կարող ենք անել կոմպիլացուած լեզուների վրայ։
Իհարկէ հնարաւոր է, բայց դէ մեզ պէտք է ինչ-որ հետեւելու համակարգ, օրինակ DTrace կամ eBPF։
Իհարկէ DTrace ամէն օր օգտագործում եմ, այնպէս որ մտածեցի, ինչ վատ կը լինի, եթէ փորձեմ վօկ-ի հետ աշխատեցնել ։)
MODULE prog0;
IMPORT Out;
BEGIN
Out.String("Hello, World!"); Out.Ln;
END prog0.
կոմպիլացնենք ու աշխատեցնենք՝
root@illuria-dev:dtrace # voc -m prog0.Mod
prog0.Mod Compiling prog0. Main program. 383 chars.
root@illuria-dev:dtrace # ./prog0
Hello, World!
Շատ լաւ, հրաշալի։
Հիմա ինձ պէտք է իմանալ, թէ prog0
պրոցեսը առհասարակ ինչ ֆունկցիաներ է կանչում։
փորձարկում առաջին՝
փորձեմ տեսնել ամէն ինչ որը կանչում է prog0
-ն, ապա գրում եմ all.d
ֆայլի մէջ՝
pid$target:::
{
printf("%s:%s:%s:%s\n", probeprov, probemod, probefunc, probename);
}
ու հիմա աշխատեցնեմ՝
root@illuria-dev:dtrace # dtrace -s all.d -c ./prog0
dtrace: failed to compile script all.d: line 1: failed to create offset probes in 'ethZip_ReadBytes': Cannot allocate memory
Հմմ, memory allocation խնդիր է։ լաւ, փորձեմ աւելի քիչ բան կանչել։ տեսնես ի՞նչ գրադարաններ եւ/կամ ռանթայմեր է կանչում prog0
-ն։
root@illuria-dev:dtrace # ldd ./prog0
./prog0:
libvoc-O2.so => /usr/local/share/voc/lib/libvoc-O2.so (0x800249000)
libc.so.7 => /lib/libc.so.7 (0x80034f000)
Լաւ, լաւ, կարող եմ միայն libvoc-O2
-ին կանչել ։)
սարքում եմ libvoc.d
ֆայլ, մէջը գրում եմ՝
pid$target:libvoc-O2::entry
{
printf("%s:%s:%s:%s\n", probeprov, probemod, probefunc, probename);
}
ու կանչում եմ՝
root@illuria-dev:dtrace # dtrace -s libvoc.d -c ./prog0 -o libvoc.out
dtrace: script 'libvoc.d' matched 1651 probes
Hello, World!
dtrace: pid 64686 has exited
ահ, 1651 հատ տուեալների մուտք կայ։ դէ կարդանք մեր output-ը՝
1 CPU ID FUNCTION:NAME
2 0 262042 Modules_Init:entry pid64686:libvoc-O2.so:Modules_Init:entry
3 0 261868 Heap_InitHeap:entry pid64686:libvoc-O2.so:Heap_InitHeap:entry
4 0 261751 Platform_OSAllocate:entry pid64686:libvoc-O2.so:Platform_OSAllocate:entry
5 0 261679 Heap__init:entry pid64686:libvoc-O2.so:Heap__init:entry
6 0 262691 Heap_REGMOD:entry pid64686:libvoc-O2.so:Heap_REGMOD:entry
7 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
8 0 262116 Heap_REGCMD:entry pid64686:libvoc-O2.so:Heap_REGCMD:entry
9 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
10 0 262116 Heap_REGCMD:entry pid64686:libvoc-O2.so:Heap_REGCMD:entry
11 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
12 0 262116 Heap_REGCMD:entry pid64686:libvoc-O2.so:Heap_REGCMD:entry
13 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
14 0 262116 Heap_REGCMD:entry pid64686:libvoc-O2.so:Heap_REGCMD:entry
15 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
16 0 262180 SYSTEM_INHERIT:entry pid64686:libvoc-O2.so:SYSTEM_INHERIT:entry
17 0 262180 SYSTEM_INHERIT:entry pid64686:libvoc-O2.so:SYSTEM_INHERIT:entry
18 0 262180 SYSTEM_INHERIT:entry pid64686:libvoc-O2.so:SYSTEM_INHERIT:entry
19 0 262180 SYSTEM_INHERIT:entry pid64686:libvoc-O2.so:SYSTEM_INHERIT:entry
20 0 262570 Modules__init:entry pid64686:libvoc-O2.so:Modules__init:entry
21 0 261679 Heap__init:entry pid64686:libvoc-O2.so:Heap__init:entry
22 0 261970 Heap_INCREF:entry pid64686:libvoc-O2.so:Heap_INCREF:entry
23 0 262511 Platform__init:entry pid64686:libvoc-O2.so:Platform__init:entry
24 0 262691 Heap_REGMOD:entry pid64686:libvoc-O2.so:Heap_REGMOD:entry
25 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
26 0 261924 Heap_REGTYP:entry pid64686:libvoc-O2.so:Heap_REGTYP:entry
27 0 262180 SYSTEM_INHERIT:entry pid64686:libvoc-O2.so:SYSTEM_INHERIT:entry
28 0 262461 SYSTEM_DIV:entry pid64686:libvoc-O2.so:SYSTEM_DIV:entry
29 0 261970 Heap_INCREF:entry pid64686:libvoc-O2.so:Heap_INCREF:entry
30 0 262691 Heap_REGMOD:entry pid64686:libvoc-O2.so:Heap_REGMOD:entry
31 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
32 0 262685 Platform_IdentifyByName:entry pid64686:libvoc-O2.so:Platform_IdentifyByName:entry
33 0 263025 Out__init:entry pid64686:libvoc-O2.so:Out__init:entry
34 0 261679 Heap__init:entry pid64686:libvoc-O2.so:Heap__init:entry
35 0 261970 Heap_INCREF:entry pid64686:libvoc-O2.so:Heap_INCREF:entry
36 0 262511 Platform__init:entry pid64686:libvoc-O2.so:Platform__init:entry
37 0 261970 Heap_INCREF:entry pid64686:libvoc-O2.so:Heap_INCREF:entry
38 0 262691 Heap_REGMOD:entry pid64686:libvoc-O2.so:Heap_REGMOD:entry
39 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
40 0 262116 Heap_REGCMD:entry pid64686:libvoc-O2.so:Heap_REGCMD:entry
41 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
42 0 262116 Heap_REGCMD:entry pid64686:libvoc-O2.so:Heap_REGCMD:entry
43 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
44 0 262116 Heap_REGCMD:entry pid64686:libvoc-O2.so:Heap_REGCMD:entry
45 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
46 0 262886 Platform_IsConsole:entry pid64686:libvoc-O2.so:Platform_IsConsole:entry
47 0 261970 Heap_INCREF:entry pid64686:libvoc-O2.so:Heap_INCREF:entry
48 0 262691 Heap_REGMOD:entry pid64686:libvoc-O2.so:Heap_REGMOD:entry
49 0 261956 Heap_NEWREC:entry pid64686:libvoc-O2.so:Heap_NEWREC:entry
50 0 262286 Out_String:entry pid64686:libvoc-O2.so:Out_String:entry
51 0 262704 Out_Ln:entry pid64686:libvoc-O2.so:Out_Ln:entry
52 0 261895 Platform_Write:entry pid64686:libvoc-O2.so:Platform_Write:entry
53 0 262517 Heap_FINALL:entry pid64686:libvoc-O2.so:Heap_FINALL:entry
ահ, հրաշալի, տող 50-ում կանչում ա Out.String
հիմա կարող ենք փորձել դինամիք կերպով կանչել իրա առաջին արգումենտը ։)
գրում եմ string_arg.d
ֆայլի մէջ՝
pid$target:libvoc-O2:Out_String:entry
{
printf("Function Out.String has run with arguments: %s", copyinstr(arg0));
}
ու աշխատեցնում եմ՝
root@illuria-dev:dtrace # dtrace -qs string_arg.d -c ./prog0
Hello, World!
Function Out.String has run with arguments: Hello, World!
Ահ, հրաշալի՜
Լաւ, հիմա փորձեմ more dirty stuff 😉
ունենք prog1.Mod
→
MODULE prog1;
IMPORT Out, In;
VAR s: ARRAY 32 OF CHAR;
BEGIN
In.Line(s); Out.Ln;
END prog1.
ու նաեւ հետեւլեալ D ծրագիրը՝
pid$target:libvoc-O2:Platform_ReadBuf:entry
{
printf("Function Platform.Readbuf has run with arguments: %s\n", copyinstr(arg1));
}
ահա!
root@illuria-dev:dtrace # voc -m prog1.Mod
prog1.Mod Compiling prog1. Main program. 435 chars.
root@illuria-dev:dtrace # dtrace -qs in.d -c ./prog1
Function Platform.Readbuf has run with arguments:
myinput!
Function Platform.Readbuf has run with arguments: m
Function Platform.Readbuf has run with arguments: y
Function Platform.Readbuf has run with arguments: i
Function Platform.Readbuf has run with arguments: n
Function Platform.Readbuf has run with arguments: p
Function Platform.Readbuf has run with arguments: u
Function Platform.Readbuf has run with arguments: t
Function Platform.Readbuf has run with arguments: !
root@illuria-dev:dtrace #
Այնպէս որ, հա՛։ DTrace-ը փաստացի rootkit է ։)
ասանկ բաներ։
Պատասխանել մեյլով