mirror of
https://github.com/NohamR/LLDBMemView.git
synced 2026-02-22 02:25:43 +00:00
240 lines
15 KiB
HTML
240 lines
15 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" class="light">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>LLDB Memory Region Parser</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link rel="stylesheet" href="style.css">
|
|
<script>
|
|
tailwind.config = {
|
|
darkMode: 'class',
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
slate: { 850: '#1e293b' } // Custom dark shade
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</head>
|
|
|
|
<body
|
|
class="bg-slate-100 dark:bg-slate-900 min-h-screen p-4 md:p-8 text-slate-800 dark:text-slate-200 transition-colors">
|
|
|
|
<div class="max-w-7xl mx-auto space-y-6">
|
|
|
|
<!-- Header -->
|
|
<div
|
|
class="bg-gradient-to-r from-slate-800 to-indigo-900 dark:from-slate-950 dark:to-indigo-950 rounded-xl shadow-lg p-8 text-white text-center relative">
|
|
<!-- Dark Mode Toggle -->
|
|
<button onclick="toggleDarkMode()"
|
|
class="absolute top-4 right-4 p-2 rounded-lg bg-white/10 hover:bg-white/20 transition-colors"
|
|
title="Toggle dark mode">
|
|
<svg id="theme-icon-sun" class="h-6 w-6 hidden" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
|
|
</svg>
|
|
<svg id="theme-icon-moon" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
|
|
</svg>
|
|
</button>
|
|
<h1 class="text-3xl font-bold mb-2 flex items-center justify-center gap-3">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-indigo-300" fill="none" viewBox="0 0 24 24"
|
|
stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
|
|
</svg>
|
|
LLDB Memory Region Parser
|
|
</h1>
|
|
<p class="text-indigo-200 opacity-90">Analyze memory layout, permissions, and dirty pages from LLDB output
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Input Section -->
|
|
<div class="bg-white dark:bg-slate-800 rounded-xl shadow-md overflow-hidden transition-colors">
|
|
<div class="p-6 border-b border-slate-100 dark:border-slate-700">
|
|
<label for="input" class="block text-sm font-semibold text-slate-600 dark:text-slate-300 mb-2">Paste
|
|
'memory region --all'
|
|
output:</label>
|
|
<textarea id="input"
|
|
class="w-full h-48 p-4 font-mono text-xs bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-600 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 transition-all resize-y text-slate-800 dark:text-slate-200"
|
|
placeholder="[0x0000000100000000-0x0000000100004000) r-x __TEXT..."></textarea>
|
|
|
|
<div class="mt-4 flex gap-3 flex-wrap">
|
|
<button onclick="parseMemory()"
|
|
class="flex items-center gap-2 bg-indigo-600 hover:bg-indigo-700 text-white px-6 py-2.5 rounded-lg font-medium transition shadow-sm active:transform active:scale-95">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24"
|
|
stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
Parse Memory
|
|
</button>
|
|
<button onclick="generateCommands()" id="generate-btn"
|
|
class="flex items-center gap-2 bg-emerald-600 hover:bg-emerald-700 text-white px-6 py-2.5 rounded-lg font-medium transition shadow-sm active:transform active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
disabled>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24"
|
|
stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
|
</svg>
|
|
Generate Commands
|
|
</button>
|
|
<button onclick="clearAll()"
|
|
class="flex items-center gap-2 bg-white dark:bg-slate-700 border border-slate-300 dark:border-slate-600 hover:bg-slate-50 dark:hover:bg-slate-600 text-slate-700 dark:text-slate-200 px-6 py-2.5 rounded-lg font-medium transition shadow-sm">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24"
|
|
stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
|
</svg>
|
|
Clear
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Stats Dashboard -->
|
|
<div id="stats"
|
|
class="hidden grid-cols-2 md:grid-cols-5 gap-4 p-6 bg-slate-50 dark:bg-slate-800/50 border-b border-slate-100 dark:border-slate-700">
|
|
<!-- Stat Cards injected by JS -->
|
|
</div>
|
|
|
|
<!-- Filters -->
|
|
<div id="filter-section"
|
|
class="hidden p-6 bg-white dark:bg-slate-800 border-b border-slate-100 dark:border-slate-700 flex flex-wrap gap-4 items-center">
|
|
<div class="flex items-center gap-2 text-slate-600 dark:text-slate-300 font-medium">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24"
|
|
stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" />
|
|
</svg>
|
|
Filters:
|
|
</div>
|
|
<input type="text" id="addressFilter" placeholder="Search Address or Name..."
|
|
class="px-3 py-2 border border-slate-300 dark:border-slate-600 rounded-md text-sm focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 w-48 md:w-64 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-200"
|
|
onkeyup="applyFilters()">
|
|
|
|
<select id="permsFilter" onchange="applyFilters()"
|
|
class="px-3 py-2 border border-slate-300 dark:border-slate-600 rounded-md text-sm focus:ring-1 focus:ring-indigo-500 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-200">
|
|
<option value="">Any Permission</option>
|
|
<option value="r">Readable (R)</option>
|
|
<option value="w">Writable (W)</option>
|
|
<option value="x">Executable (X)</option>
|
|
<option value="rw">Read & Write</option>
|
|
<option value="rx">Read & Exec</option>
|
|
</select>
|
|
|
|
<select id="dirtyFilter" onchange="applyFilters()"
|
|
class="px-3 py-2 border border-slate-300 dark:border-slate-600 rounded-md text-sm focus:ring-1 focus:ring-indigo-500 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-200">
|
|
<option value="">All Pages</option>
|
|
<option value="dirty">Dirty Only</option>
|
|
<option value="clean">Clean Only</option>
|
|
</select>
|
|
|
|
<label
|
|
class="flex items-center gap-2 cursor-pointer select-none text-sm text-slate-700 dark:text-slate-200 bg-slate-100 dark:bg-slate-700 px-3 py-2 rounded-md hover:bg-slate-200 dark:hover:bg-slate-600 transition">
|
|
<input type="checkbox" id="hideEmptyRegions" onchange="applyFilters()" checked
|
|
class="rounded text-indigo-600 focus:ring-indigo-500">
|
|
<span>Hide "---" Regions</span>
|
|
</label>
|
|
</div>
|
|
|
|
<!-- Command Output Section -->
|
|
<div id="command-output"
|
|
class="hidden p-6 bg-slate-50 dark:bg-slate-800/50 border-b border-slate-100 dark:border-slate-700">
|
|
<div class="flex items-center justify-between mb-3">
|
|
<h3 class="text-sm font-semibold text-slate-700 dark:text-slate-300 flex items-center gap-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-indigo-500" fill="none"
|
|
viewBox="0 0 24 24" stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
|
</svg>
|
|
Generated Commands (<span id="selected-count">0</span> selected)
|
|
</h3>
|
|
<button onclick="copyCommands(event)"
|
|
class="flex items-center gap-2 bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg font-medium transition shadow-sm text-sm">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24"
|
|
stroke="currentColor">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
|
</svg>
|
|
Copy All
|
|
</button>
|
|
</div>
|
|
<pre id="commands-text"
|
|
class="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-600 rounded-lg p-4 text-xs font-mono text-slate-800 dark:text-slate-200 overflow-x-auto custom-scrollbar max-h-64"></pre>
|
|
</div>
|
|
|
|
<!-- Table -->
|
|
<div class="overflow-x-auto custom-scrollbar">
|
|
<table class="min-w-full divide-y divide-slate-200 dark:divide-slate-700">
|
|
<thead class="bg-slate-50 dark:bg-slate-800 sticky top-0 z-10">
|
|
<tr>
|
|
<th scope="col" class="px-6 py-3 text-left">
|
|
<input type="checkbox" id="select-all" onchange="toggleSelectAll()"
|
|
class="rounded text-indigo-600 focus:ring-indigo-500 cursor-pointer">
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider cursor-pointer hover:bg-slate-100 dark:hover:bg-slate-700 group"
|
|
onclick="sortBy('start')">
|
|
Start Address
|
|
<span class="sort-icon invisible group-hover:visible ml-1 inline-block">⇅</span>
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider cursor-pointer hover:bg-slate-100 dark:hover:bg-slate-700 group"
|
|
onclick="sortBy('end')">
|
|
End Address
|
|
<span class="sort-icon invisible group-hover:visible ml-1 inline-block">⇅</span>
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider cursor-pointer hover:bg-slate-100 dark:hover:bg-slate-700 group"
|
|
onclick="sortBy('size')">
|
|
Size
|
|
<span class="sort-icon invisible group-hover:visible ml-1 inline-block">⇅</span>
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider cursor-pointer hover:bg-slate-100 dark:hover:bg-slate-700 group"
|
|
onclick="sortBy('perms')">
|
|
Perms
|
|
<span class="sort-icon invisible group-hover:visible ml-1 inline-block">⇅</span>
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider cursor-pointer hover:bg-slate-100 dark:hover:bg-slate-700 group"
|
|
onclick="sortBy('name')">
|
|
Name / Details
|
|
<span class="sort-icon invisible group-hover:visible ml-1 inline-block">⇅</span>
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-left text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider cursor-pointer hover:bg-slate-100 dark:hover:bg-slate-700 group"
|
|
onclick="sortBy('dirty')">
|
|
Dirty
|
|
<span class="sort-icon invisible group-hover:visible ml-1 inline-block">⇅</span>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="table-body"
|
|
class="bg-white dark:bg-slate-800 divide-y divide-slate-200 dark:divide-slate-700">
|
|
<!-- Content injected by JS -->
|
|
<tr class="text-center text-slate-400">
|
|
<td colspan="7" class="py-12">Waiting for input...</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div id="footer-count"
|
|
class="bg-slate-50 dark:bg-slate-800/50 p-3 text-xs text-right text-slate-400 dark:text-slate-500 border-t border-slate-200 dark:border-slate-700">
|
|
0 rows
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="src.js"></script>
|
|
</body>
|
|
|
|
</html> |