-
Notifications
You must be signed in to change notification settings - Fork 1
/
dynspect.js
104 lines (94 loc) · 3.02 KB
/
dynspect.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
102
103
104
var GST_OBJECT_OFFSET_PARENT = 40;
var GST_ELEMENT_OFFSET_CLOCK = 152;
var GST_ELEMENT_OFFSET_BASE_TIME = 160;
var GST_BUFFER_OFFSET_PTS = 72;
var GST_BUFFER_OFFSET_DTS = GST_BUFFER_OFFSET_PTS + Process.pointerSize;
var api = resolve([{
module: /gstreamer-1\.0/,
functions: {
"gst_clock_get_time": ['pointer', ['pointer']],
"gst_pad_push": ['int', ['pointer', 'pointer']]
}
}
]);
if (api === null) {
throw new Error("GStreamer not loaded");
}
var pipeline = null;
var clock = null;
var baseTime = null;
Interceptor.attach(api.gst_pad_push, {
onEnter: function (args) {
var pad = args[0];
var buf = args[1];
if (pipeline === null) {
pipeline = getPipeline(pad);
clock = getClock(pipeline);
baseTime = getBaseTime(pipeline);
}
var now = api.gst_clock_get_time(clock);
var runningTime = now.sub(baseTime);
var pts = getPts(buf);
var delta = pts.sub(runningTime).toInt32();
send("gst_pad_push(" + buf + "): pts vs running_time: " + delta + " ns");
}
});
function getPipeline(obj) {
while (true) {
var p = getParent(obj);
if (p.isNull()) {
return obj;
}
obj = p;
}
}
function getParent(obj) {
return Memory.readPointer(obj.add(GST_OBJECT_OFFSET_PARENT));
}
function getClock(element) {
return Memory.readPointer(element.add(GST_ELEMENT_OFFSET_CLOCK));
}
function getBaseTime(element) {
return Memory.readPointer(element.add(GST_ELEMENT_OFFSET_BASE_TIME));
}
function getPts(buffer) {
return Memory.readPointer(buffer.add(GST_BUFFER_OFFSET_PTS));
}
function resolve(apis) {
var result = {};
var remaining = 0;
apis.forEach(function (api) {
var pendingFunctions = api.functions;
remaining += Object.keys(pendingFunctions).length;
Process.enumerateModules({
onMatch: function (mod) {
if (api.module.test(mod.name)) {
Module.enumerateExports(mod.name, {
onMatch: function (exp) {
var name = exp.name;
if (exp.type === 'function') {
var signature = pendingFunctions[name];
if (signature) {
result[name] = new NativeFunction(exp.address, signature[0], signature[1]);
delete pendingFunctions[name];
if (--remaining === 0) {
return 'stop';
}
}
}
},
onComplete: function () {
}
});
return 'stop';
}
},
onComplete: function () {
}
});
});
if (remaining > 0) {
return null;
}
return result;
}