Seregon/Hermes

Hermes/Dyforge is a program written in c++ allows you to inject a dll that can analyze all processes in a program, can be used for mod and reverse engeneering

C/3.8 KB/No license
DyMain/WebServer/dashboard/js/dashboard.js
Hermes / DyMain / WebServer / dashboard / js / dashboard.js
1// Configurazione
2const config = {
3 apiUrl: 'http://localhost:8080',
4 refreshInterval: 1000,
5 memoryPageSize: 256,
6 assemblyPageSize: 64
7};
8
9// Stato globale
10let state = {
11 processInfo: null,
12 memoryData: null,
13 threads: [],
14 modules: [],
15 hooks: [],
16 calls: [],
17 currentMemoryAddress: 0,
18 currentAssemblyAddress: 0
19};
20
21// Inizializzazione
22document.addEventListener('DOMContentLoaded', () => {
23 initializeCharts();
24 initializeNetwork();
25 setupEventListeners();
26 startRefreshLoop();
27});
28
29// Inizializzazione grafici
30function initializeCharts() {
31 const ctx = document.getElementById('memory-chart').getContext('2d');
32 window.memoryChart = new Chart(ctx, {
33 type: 'doughnut',
34 data: {
35 labels: ['Working Set', 'Private Usage'],
36 datasets: [{
37 data: [0, 0],
38 backgroundColor: ['#0d6efd', '#6c757d']
39 }]
40 },
41 options: {
42 responsive: true,
43 maintainAspectRatio: false
44 }
45 });
46}
47
48// Inizializzazione network
49function initializeNetwork() {
50 const container = document.getElementById('calls-network');
51 const data = {
52 nodes: new vis.DataSet([]),
53 edges: new vis.DataSet([])
54 };
55 const options = {
56 nodes: {
57 shape: 'dot',
58 size: 16
59 },
60 edges: {
61 arrows: 'to',
62 smooth: {
63 type: 'continuous'
64 }
65 },
66 physics: {
67 stabilization: false,
68 barnesHut: {
69 gravitationalConstant: -80000,
70 springConstant: 0.001,
71 springLength: 200
72 }
73 }
74 };
75 window.callsNetwork = new vis.Network(container, data, options);
76}
77
78// Setup event listeners
79function setupEventListeners() {
80 // Refresh button
81 document.getElementById('refreshBtn').addEventListener('click', refreshAll);
82
83 // Export button
84 document.getElementById('exportBtn').addEventListener('click', exportData);
85
86 // Memory search
87 document.getElementById('memory-scan').addEventListener('click', () => {
88 const pattern = document.getElementById('memory-search').value;
89 scanMemory(pattern);
90 });
91
92 // Assembly disassemble
93 document.getElementById('assembly-disassemble').addEventListener('click', () => {
94 const address = document.getElementById('assembly-address').value;
95 disassemble(address);
96 });
97
98 // Tab changes
99 document.querySelectorAll('[data-bs-toggle="list"]').forEach(tab => {
100 tab.addEventListener('shown.bs.tab', (e) => {
101 const target = e.target.getAttribute('href').substring(1);
102 refreshTab(target);
103 });
104 });
105}
106
107// Loop di aggiornamento
108function startRefreshLoop() {
109 setInterval(refreshAll, config.refreshInterval);
110}
111
112// Aggiorna tutti i dati
113async function refreshAll() {
114 try {
115 await Promise.all([
116 refreshProcessInfo(),
117 refreshMemoryData(),
118 refreshThreads(),
119 refreshModules(),
120 refreshHooks(),
121 refreshCalls()
122 ]);
123 } catch (error) {
124 console.error('Error refreshing data:', error);
125 }
126}
127
128// Aggiorna tab specifico
129async function refreshTab(tab) {
130 try {
131 switch (tab) {
132 case 'process':
133 await refreshProcessInfo();
134 break;
135 case 'memory':
136 await refreshMemoryData();
137 break;
138 case 'threads':
139 await refreshThreads();
140 break;
141 case 'modules':
142 await refreshModules();
143 break;
144 case 'hooks':
145 await refreshHooks();
146 break;
147 case 'assembly':
148 await refreshAssembly();
149 break;
150 case 'calls':
151 await refreshCalls();
152 break;
153 }
154 } catch (error) {
155 console.error(`Error refreshing ${tab}:`, error);
156 }
157}
158
159// Aggiorna informazioni processo
160async function refreshProcessInfo() {
161 const response = await fetch(`${config.apiUrl}/process`);
162 const data = await response.json();
163 state.processInfo = data.data;
164
165 // Aggiorna UI
166 document.getElementById('process-pid').textContent = state.processInfo.pid;
167 document.getElementById('process-name').textContent = state.processInfo.name;
168 document.getElementById('process-path').textContent = state.processInfo.path;
169 document.getElementById('process-arch').textContent = state.processInfo.architecture;
170
171 // Aggiorna grafico memoria
172 window.memoryChart.data.datasets[0].data = [
173 state.processInfo.workingSetSize,
174 state.processInfo.privateUsage
175 ];
176 window.memoryChart.update();
177}
178
179// Aggiorna dati memoria
180async function refreshMemoryData() {
181 const response = await fetch(`${config.apiUrl}/memory`);
182 const data = await response.json();
183 state.memoryData = data.data;
184
185 // Aggiorna visualizzazione memoria
186 updateMemoryView();
187}
188
189// Aggiorna thread
190async function refreshThreads() {
191 const response = await fetch(`${config.apiUrl}/threads`);
192 const data = await response.json();
193 state.threads = data.data;
194
195 // Aggiorna tabella thread
196 const tbody = document.getElementById('threads-list');
197 tbody.innerHTML = state.threads.map(thread => `
198 <tr>
199 <td>${thread.id}</td>
200 <td>${thread.priority}</td>
201 <td>${thread.state}</td>
202 <td>0x${thread.rip.toString(16)}</td>
203 <td>0x${thread.rsp.toString(16)}</td>
204 <td>0x${thread.rbp.toString(16)}</td>
205 <td>
206 <button class="btn btn-sm btn-primary" onclick="viewThreadStack(${thread.id})">
207 Stack
208 </button>
209 </td>
210 </tr>
211 `).join('');
212}
213
214// Aggiorna moduli
215async function refreshModules() {
216 const response = await fetch(`${config.apiUrl}/modules`);
217 const data = await response.json();
218 state.modules = data.data;
219
220 // Aggiorna tabella moduli
221 const tbody = document.getElementById('modules-list');
222 tbody.innerHTML = state.modules.map(module => `
223 <tr>
224 <td>${module.name}</td>
225 <td>0x${module.base.toString(16)}</td>
226 <td>${module.size}</td>
227 <td>0x${module.entryPoint.toString(16)}</td>
228 <td>
229 <button class="btn btn-sm btn-primary" onclick="viewModuleMemory(${module.base})">
230 Memoria
231 </button>
232 </td>
233 </tr>
234 `).join('');
235}
236
237// Aggiorna hook
238async function refreshHooks() {
239 const response = await fetch(`${config.apiUrl}/hooks`);
240 const data = await response.json();
241 state.hooks = data.data;
242
243 // Aggiorna tabella hook
244 const tbody = document.getElementById('hooks-list');
245 tbody.innerHTML = state.hooks.map(hook => `
246 <tr>
247 <td>0x${hook.target.toString(16)}</td>
248 <td>0x${hook.detour.toString(16)}</td>
249 <td>0x${hook.original.toString(16)}</td>
250 <td>${hook.name}</td>
251 <td>
252 <button class="btn btn-sm btn-primary" onclick="viewHookCode(${hook.target})">
253 Codice
254 </button>
255 </td>
256 </tr>
257 `).join('');
258}
259
260// Aggiorna assembly
261async function refreshAssembly() {
262 if (state.currentAssemblyAddress) {
263 await disassemble(state.currentAssemblyAddress);
264 }
265}
266
267// Aggiorna chiamate
268async function refreshCalls() {
269 const response = await fetch(`${config.apiUrl}/calls`);
270 const data = await response.json();
271 state.calls = data.data;
272
273 // Aggiorna network
274 const nodes = state.calls.map(call => ({
275 id: call.id,
276 label: call.name,
277 title: `0x${call.address.toString(16)}`
278 }));
279
280 const edges = state.calls.flatMap(call =>
281 call.calls.map(target => ({
282 from: call.id,
283 to: target
284 }))
285 );
286
287 window.callsNetwork.setData({ nodes, edges });
288}
289
290// Aggiorna visualizzazione memoria
291function updateMemoryView() {
292 const hexView = document.getElementById('memory-hex');
293 const asciiView = document.getElementById('memory-ascii');
294
295 let hexContent = '';
296 let asciiContent = '';
297
298 for (let i = 0; i < state.memoryData.length; i += 16) {
299 // Indirizzo
300 hexContent += `0x${(state.currentMemoryAddress + i).toString(16).padStart(16, '0')}: `;
301
302 // Bytes esadecimali
303 for (let j = 0; j < 16; j++) {
304 if (i + j < state.memoryData.length) {
305 hexContent += state.memoryData[i + j].toString(16).padStart(2, '0') + ' ';
306 } else {
307 hexContent += ' ';
308 }
309 }
310
311 // Caratteri ASCII
312 asciiContent += ' ';
313 for (let j = 0; j < 16; j++) {
314 if (i + j < state.memoryData.length) {
315 const byte = state.memoryData[i + j];
316 asciiContent += (byte >= 32 && byte <= 126) ? String.fromCharCode(byte) : '.';
317 }
318 }
319
320 hexContent += '\n';
321 asciiContent += '\n';
322 }
323
324 hexView.textContent = hexContent;
325 asciiView.textContent = asciiContent;
326}
327
328// Scansiona memoria
329async function scanMemory(pattern) {
330 const response = await fetch(`${config.apiUrl}/memory/scan`, {
331 method: 'POST',
332 headers: {
333 'Content-Type': 'application/json'
334 },
335 body: JSON.stringify({ pattern })
336 });
337 const data = await response.json();
338
339 if (data.status === 'ok') {
340 state.currentMemoryAddress = data.data.address;
341 await refreshMemoryData();
342 }
343}
344
345// Disassembla
346async function disassemble(address) {
347 const response = await fetch(`${config.apiUrl}/assembly`, {
348 method: 'POST',
349 headers: {
350 'Content-Type': 'application/json'
351 },
352 body: JSON.stringify({ address })
353 });
354 const data = await response.json();
355
356 if (data.status === 'ok') {
357 state.currentAssemblyAddress = address;
358 document.getElementById('assembly-output').textContent = data.data.assembly;
359 }
360}
361
362// Visualizza stack thread
363async function viewThreadStack(threadId) {
364 const response = await fetch(`${config.apiUrl}/thread/${threadId}/stack`);
365 const data = await response.json();
366
367 if (data.status === 'ok') {
368 state.currentMemoryAddress = data.data.address;
369 await refreshMemoryData();
370 }
371}
372
373// Visualizza memoria modulo
374async function viewModuleMemory(moduleBase) {
375 state.currentMemoryAddress = moduleBase;
376 await refreshMemoryData();
377}
378
379// Visualizza codice hook
380async function viewHookCode(hookAddress) {
381 state.currentAssemblyAddress = hookAddress;
382 await refreshAssembly();
383}
384
385// Esporta dati
386function exportData() {
387 const data = {
388 processInfo: state.processInfo,
389 memoryData: state.memoryData,
390 threads: state.threads,
391 modules: state.modules,
392 hooks: state.hooks,
393 calls: state.calls
394 };
395
396 const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
397 const url = URL.createObjectURL(blob);
398 const a = document.createElement('a');
399 a.href = url;
400 a.download = `dymain-export-${new Date().toISOString()}.json`;
401 document.body.appendChild(a);
402 a.click();
403 document.body.removeChild(a);
404 URL.revokeObjectURL(url);
405}