autool/DroidBot/resources/stylesheets/droidbotUI.js
2026-06-17 19:44:18 +08:00

315 lines
10 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var network = null;
function draw() {
var utg_div = document.getElementById('utg_div');
var utg_details = document.getElementById('utg_details');
showOverall();
var options = {
autoResize: true,
height: '100%',
width: '100%',
locale: 'en',
nodes: {
shapeProperties: {
useBorderWithImage: true
},
borderWidth: 0,
borderWidthSelected: 5,
color: {
border: '#FFFFFF',
background: '#FFFFFF',
highlight: {
border: '#0000FF',
background: '#0000FF',
}
},
font: {
size: 12,
color: '#000'
}
},
edges: {
color: 'black',
arrows: {
to: {
enabled: true,
scaleFactor: 0.5
}
},
font: {
size: 12,
color: '#000'
}
}
};
// 预处理边为包含GuiAgent事件的边添加黄色高亮
for (var i = 0; i < utg.edges.length; i++) {
var edge = utg.edges[i];
// 检查该边是否包含GuiAgent事件
var hasAgentEvent = false;
if (edge.events) {
for (var j = 0; j < edge.events.length; j++) {
if (edge.events[j].is_guiagent_event) {
hasAgentEvent = true;
break;
}
}
}
// 如果包含GuiAgent事件设置黄色高亮
if (hasAgentEvent) {
edge.color = { color: '#FFD700', highlight: '#FFA500' };
edge.width = 3;
}
}
network = new vis.Network(utg_div, utg, options);
network.on("click", function (params) {
if (params.nodes.length > 0) {
node = params.nodes[0];
if (network.isCluster(node)) {
utg_details.innerHTML = getClusterDetails(node);
}
else {
utg_details.innerHTML = getNodeDetails(node);
}
}
else if (params.edges.length > 0) {
edge = params.edges[0];
baseEdge = network.clustering.getBaseEdge(edge)
if (baseEdge == null || baseEdge == edge) {
utg_details.innerHTML = getEdgeDetails(edge);
} else {
utg_details.innerHTML = getEdgeDetails(baseEdge);
}
}
});
}
function showOverall() {
var utg_details = document.getElementById('utg_details');
utg_details.innerHTML = getOverallResult();
}
function getOverallResult() {
var overallInfo = "<hr />";
overallInfo += "<table class=\"table\">\n"
overallInfo += "<tr class=\"active\"><th colspan=\"2\"><h4>App information</h4></th></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\">Package</th><td class=\"col-md-4\">" + utg.app_package + "</td></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\">SHA-256</th><td class=\"col-md-4\">" + utg.app_sha256 + "</td></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\">Main activity</th><td class=\"col-md-4\">" + utg.app_main_activity + "</td></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\"># activities</th><td class=\"col-md-4\">" + utg.app_num_total_activities + "</td></tr>\n";
overallInfo += "<tr class=\"active\"><th colspan=\"2\"><h4>Device information</h4></th></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\">Device serial</th><td class=\"col-md-4\">" + utg.device_serial + "</td></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\">Model number</th><td class=\"col-md-4\">" + utg.device_model_number + "</td></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\">SDK version</th><td class=\"col-md-4\">" + utg.device_sdk_version + "</td></tr>\n";
overallInfo += "<tr class=\"active\"><th colspan=\"2\"><h4>DroidBot result</h4></th></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\">Test date</th><td class=\"col-md-4\">" + utg.test_date + "</td></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\">Time spent (s)</th><td class=\"col-md-4\">" + utg.time_spent + "</td></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\"># input events</th><td class=\"col-md-4\">" + utg.num_input_events + "</td></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\"># UTG states</th><td class=\"col-md-4\">" + utg.num_nodes + "</td></tr>\n";
overallInfo += "<tr><th class=\"col-md-1\"># UTG edges</th><td class=\"col-md-4\">" + utg.num_edges + "</td></tr>\n";
activity_coverage = 100 * utg.num_reached_activities / utg.app_num_total_activities;
overallInfo += "<tr><th class=\"col-md-1\">Activity_coverage</th><td class=\"col-md-4 progress\"><div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"" + utg.num_reached_activities + "\" aria-valuemin=\"0\" aria-valuemax=\"" + utg.app_num_total_activities + "\" style=\"width: " + activity_coverage + "%;\">" + utg.num_reached_activities + "/" + utg.app_num_total_activities + "</div></td></tr>\n";
overallInfo += "</table>";
return overallInfo;
}
function getEdgeDetails(edgeId) {
var selectedEdge = getEdge(edgeId);
edgeInfo = "<h2>Transition Details</h2><hr/>\n";
fromState = getNode(selectedEdge.from);
toState = getNode(selectedEdge.to);
edgeInfo += "<img class=\"col-md-5\" src=\"" + fromState.image + "\">\n"
edgeInfo += "<div class=\"col-md-2 text-center\">TO</div>\n"
edgeInfo += "<img class=\"col-md-5\" src=\"" + toState.image + "\">\n"
edgeInfo += "<table class=\"table table-striped\">\n"
edgeInfo += "<tr class=\"active\"><th colspan=\"4\"><h4>Events</h4></th></tr>\n";
var i;
edgeInfo += "<tr><th>id</th><th>type</th><th>view</th><th>event_str</th><th>new_domains</th><th>agent</th></tr>\n"
for (i = 0; i < selectedEdge.events.length; i++) {
event = selectedEdge.events[i];
eventStr = event.event_str;
var viewImg = "";
if (event.view_images != null) {
var j;
for (j = 0; j < event.view_images.length; j++) {
viewImg += "<img class=\"viewImg\" src=\"" + event.view_images[j] + "\">\n"
}
}
var domainsCount = event.new_domains_count || 0;
var isAgent = event.is_guiagent_event ? "✓" : "";
edgeInfo += "<tr><td>" + event.event_id + "</td><td>" + event.event_type + "</td><td>" + viewImg + "</td><td>" + event.event_str + "</td><td>" + domainsCount + "</td><td style='color: #FFD700; font-weight: bold;'>" + isAgent + "</td></tr>"
}
edgeInfo += "</table>\n"
return edgeInfo;
}
function getNodeDetails(nodeId) {
var selectedNode = getNode(nodeId);
stateInfo = "<h2>State Details</h2><hr/>\n";
stateInfo += "<img class=\"col-md-5\" src=\"" + selectedNode.image + "\">";
stateInfo += "<div class=\"col-md-7\">" + selectedNode.title;
// 显示新增域名信息
var domains = selectedNode.new_domains || [];
if (domains.length > 0) {
stateInfo += "<h4>New Domains (" + domains.length + ")</h4>";
stateInfo += "<ul>";
for (var i = 0; i < domains.length; i++) {
stateInfo += "<li>" + domains[i] + "</li>";
}
stateInfo += "</ul>";
}
stateInfo += "</div>";
return stateInfo;
}
function getClusterDetails(clusterId) {
clusterInfo = "<h2>Cluster Details</h2><hr/>\n";
var nodeIds = network.getNodesInCluster(clusterId);
for (var i = 0; i < nodeIds.length; i++) {
var selectedNode = getNode(nodeIds[i]);
clusterInfo += "<div class=\"row\">\n"
clusterInfo += "<img class=\"col-md-5\" src=\"" + selectedNode.image + "\">"
clusterInfo += "<div class=\"col-md-7\">" + selectedNode.title + "</div>";
clusterInfo += "</div><br />"
}
return clusterInfo;
}
function getEdge(edgeId) {
var i, numEdges;
numEdges = utg.edges.length;
for (i = 0; i < numEdges; i++) {
if (utg.edges[i].id == edgeId) {
return utg.edges[i];
}
}
console.log("cannot find edge: " + edgeId);
}
function getNode(nodeId) {
var i, numNodes;
numNodes = utg.nodes.length;
for (i = 0; i < numNodes; i++) {
if (utg.nodes[i].id == nodeId) {
return utg.nodes[i];
}
}
console.log("cannot find node: " + nodeId);
}
function showAbout() {
var utg_details = document.getElementById('utg_details');
utg_details.innerHTML = getAboutInfo();
}
function getAboutInfo() {
var aboutInfo = "<hr />";
aboutInfo += "<h2>About</h2>\n"
aboutInfo += "<p>This report is generated using <a href=\"https://github.com/honeynet/droidbot\">DroidBot</a>.</p>\n";
aboutInfo += "<p>Please find copyright information in the project page.</p>";
return aboutInfo;
}
function searchUTG() {
var searchKeyword = document.getElementById("utgSearchBar").value.toUpperCase();
if (searchKeyword == null || searchKeyword == "") {
network.unselectAll()
} else {
var i, numNodes;
nodes = utg.nodes;
numNodes = nodes.length;
selectedNodes = []
for (i = 0; i < numNodes; i++) {
if (nodes[i].content.toUpperCase().indexOf(searchKeyword) > -1) {
selectedNodes.push(nodes[i].id)
}
}
network.unselectAll()
// console.log("Selecting: " + selectedNodes)
network.selectNodes(selectedNodes, false)
}
}
function clusterStructures() {
network.setData(utg)
var structures = [];
for (var i = 0; i < utg.nodes.length; i++) {
node = utg.nodes[i]
if (structures.indexOf(node.structure_str) < 0) {
structures.push(node.structure_str)
}
}
var clusterOptionsByData;
for (var i = 0; i < structures.length; i++) {
var structure = structures[i];
clusterOptionsByData = {
joinCondition: function (childOptions) {
return childOptions.structure_str == structure;
},
processProperties: function (clusterOptions, childNodes, childEdges) {
clusterOptions.title = childNodes[0].title;
clusterOptions.state_str = childNodes[0].state_str;
clusterOptions.label = childNodes[0].label;
clusterOptions.image = childNodes[0].image;
return clusterOptions;
},
clusterNodeProperties: { id: 'structure:' + structure, shape: 'image' }
};
network.cluster(clusterOptionsByData);
}
}
function clusterActivities() {
network.setData(utg)
var activities = [];
for (var i = 0; i < utg.nodes.length; i++) {
node = utg.nodes[i]
if (activities.indexOf(node.activity) < 0) {
activities.push(node.activity)
}
}
var clusterOptionsByData;
for (var i = 0; i < activities.length; i++) {
var activity = activities[i];
clusterOptionsByData = {
joinCondition: function (childOptions) {
return childOptions.activity == activity;
},
processProperties: function (clusterOptions, childNodes, childEdges) {
clusterOptions.title = childNodes[0].title;
clusterOptions.state_str = childNodes[0].state_str;
clusterOptions.label = childNodes[0].label;
clusterOptions.image = childNodes[0].image;
return clusterOptions;
},
clusterNodeProperties: { id: 'activity:' + activity, shape: 'image' }
};
network.cluster(clusterOptionsByData);
}
}
function showOriginalUTG() {
network.setData(utg)
network.redraw()
}