mirror of
https://github.com/mandiant/capa.git
synced 2026-01-21 08:53:27 -08:00
124 lines
4.1 KiB
Vue
124 lines
4.1 KiB
Vue
<template>
|
|
<DataTable
|
|
:value="tableData"
|
|
rowGroupMode="rowspan"
|
|
groupRowsBy="address"
|
|
removableSort
|
|
size="small"
|
|
:filters="filters"
|
|
:filterMode="filterMode"
|
|
:globalFilterFields="['funcaddr', 'ruleName', 'namespace']"
|
|
>
|
|
<template #header>
|
|
<IconField>
|
|
<InputIcon class="pi pi-search" />
|
|
<InputText v-model="filters['global'].value" placeholder="Global search" />
|
|
</IconField>
|
|
</template>
|
|
|
|
<Column field="address" sortable header="Function Address" :rowspan="3" class="w-min">
|
|
<template #body="{ data }">
|
|
<span class="font-monospace">{{ data.address }}</span>
|
|
<span v-if="data.matchCount > 1" class="font-italic">
|
|
({{ data.matchCount }} match{{ data.matchCount > 1 ? "es" : "" }})
|
|
</span>
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="rule" sortable header="Matches" class="w-min">
|
|
<template #body="{ data }">
|
|
{{ data.rule }}
|
|
<LibraryTag v-if="data.lib" />
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="namespace" sortable header="Namespace"></Column>
|
|
</DataTable>
|
|
|
|
<Dialog v-model:visible="sourceDialogVisible" :style="{ width: '50vw' }">
|
|
<highlightjs lang="yml" :code="currentSource" class="bg-white" />
|
|
</Dialog>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted } from "vue";
|
|
import DataTable from "primevue/datatable";
|
|
import Column from "primevue/column";
|
|
import Dialog from "primevue/dialog";
|
|
import IconField from "primevue/iconfield";
|
|
import InputIcon from "primevue/inputicon";
|
|
import InputText from "primevue/inputtext";
|
|
import LibraryTag from "@/components/misc/LibraryTag.vue";
|
|
|
|
import { parseFunctionCapabilities } from "@/utils/rdocParser";
|
|
|
|
const props = defineProps({
|
|
data: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
showLibraryRules: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
});
|
|
|
|
const filters = ref({ global: { value: null, matchMode: "contains" } });
|
|
const filterMode = ref("lenient");
|
|
const sourceDialogVisible = ref(false);
|
|
const currentSource = ref("");
|
|
|
|
const functionCapabilities = ref([]);
|
|
|
|
onMounted(() => {
|
|
const cacheKey = "functionCapabilities";
|
|
let cachedData = sessionStorage.getItem(cacheKey);
|
|
|
|
if (cachedData) {
|
|
// If the data is already in sessionStorage, parse it and use it
|
|
functionCapabilities.value = JSON.parse(cachedData);
|
|
} else {
|
|
// Parse function capabilities and cache the result in sessionStorage
|
|
functionCapabilities.value = parseFunctionCapabilities(props.data);
|
|
try {
|
|
sessionStorage.setItem(cacheKey, JSON.stringify(functionCapabilities.value));
|
|
} catch (e) {
|
|
console.warn("Failed to store parsed data in sessionStorage:", e);
|
|
// If storing fails (e.g., due to storage limits), we can still continue with the parsed data
|
|
}
|
|
}
|
|
});
|
|
|
|
/*
|
|
* tableData is the data passed to the DataTable component
|
|
* it is a computed property (that is because it gets re-executed everytime props.showLibraryRules changes)
|
|
* it is an array of objects, where each object represents a row in the table
|
|
* it also converts the output of parseFunctionCapabilities into a format that can be used by the DataTable component
|
|
*/
|
|
|
|
const tableData = computed(() => {
|
|
const data = [];
|
|
for (const fcaps of functionCapabilities.value) {
|
|
const capabilities = fcaps.capabilities;
|
|
for (const capability of capabilities) {
|
|
if (capability.lib && !props.showLibraryRules) continue;
|
|
data.push({
|
|
address: fcaps.address,
|
|
matchCount: capabilities.length,
|
|
rule: capability.name,
|
|
namespace: capability.namespace,
|
|
lib: capability.lib
|
|
});
|
|
}
|
|
}
|
|
return data;
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* tighten up the spacing between rows */
|
|
:deep(.p-datatable.p-datatable-sm .p-datatable-tbody > tr > td) {
|
|
padding: 0.2rem 0.5rem !important;
|
|
}
|
|
</style>
|