This repository was archived by the owner on Jan 4, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path3 - Method Invocation.js
101 lines (79 loc) · 2.91 KB
/
3 - Method Invocation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
const { getData, setData, generateTag, runAsPkg } = require('./common');
// Avoid actually executing the method
const fake = `string:1 string:1 string:1 string:1 string:1 string:1 string:1 string:1 string:1 string:1 string:1 string:1 string:1 string:1 string:1 string:1`;
async function invoke(_root, runner) {
/*
shelf = [
{dest: "bus.na.me", object: "/", interface: "in.ter.face", method: "MethodName"},
...
]
See 2 - Object Introspection.js for _root structure.
*/
let shelf = [];
Object.entries(_root).forEach(([dest, v]) => {
Object.entries(v).forEach(([object, v]) => {
Object.entries(v).forEach(([interface, v]) => {
Object.entries(v['method'] || {}).forEach(([method, v]) => {
shelf.push({dest, object, interface, method});
});
});
});
});
let callable = []; // metadata shelf array
// Too many methods; do it step by step
const step = 300,
limit = shelf.length;
for(let i=0; i<limit; i+=step) {
console.log(`+ Status: ${i} of ${limit} items were processed.`);
const sh = shelf.slice(i, i+step),
l = sh.length;
// A random tag and delimiter for this iteration
const tag = generateTag(),
delimiter = `[:${tag}:]`;
const cmd = sh.reduce((cmd, v, i) => {
const { dest, object, interface, method } = v;
// Delimiter
cmd += `\necho '${delimiter}';\n`;
// Metadata
const m = JSON.stringify(v);
cmd += `echo '${m}';\n`;
// dlog where we are
cmd += `echo -n -e '\\x03${tag}\\x00${i}/${l} ${m}\\x00' >> /dev/log_main;\n`;
// Call the method
return cmd + `dbus-send --system --type=method_call --print-reply --reply-timeout=5000 --dest=${dest} ${object} ${interface}.${method} ${fake};\n`;
}, '');
const c = (await runner(cmd, tag)) // Run the command
.split(delimiter) // Split by delimiter
.map(block => {
// Parse metadata
let [, m] = /^({.+})$/m.exec(block) || [, '{}'],
v = JSON.parse(m);
if (!v.dest) {
return;
}
// Check the error type
let [, type] = /\nError .+\.([A-Za-z]+):/s.exec(block) || [, '?'];
switch (type) {
// Ignore
case 'ServiceUnknown':
case 'UnknownObject':
case 'UnknownInterface':
case 'UnknownProperty':
case 'AccessDenied':
case 'NoReply':
return;
}
// Assumes callable
v.type = type;
return v;
})
.filter(m => !!m);
callable.push(...c);
}
return callable;
}
async function main() {
// Call every method to determine callable
setData('callable', await invoke(getData('root'), runAsPkg));
}
main();