ui: more information

This commit is contained in:
Dobin
2024-04-14 21:37:54 +01:00
parent 4901c7b320
commit 70c4a95b1b
7 changed files with 95 additions and 25 deletions
+24 -11
View File
@@ -7,10 +7,30 @@
{% include 'navigation.html' %}
<div class="indent">
<div class="row">
<h2>Sections</h2>
<h2> Exports </h2>
<div class="col-6">
{% if iat|length > 0 %}
<h2> Imports - IAT </h2>
{% for dll in iat %}
<ul>
{% for entry in iat[dll] %}
<li> {{ entry.dll_name }}: {{ entry.func_name }} ({{ entry.iat_vaddr | hexint }})</li>
{% endfor%}
</ul>
{% endfor %}
{% endif %}
</div>
<div class="col-6">
{% if exports|length > 0 %}
<h2> DLL Exports </h2>
<table class="table">
<tr>
<th>Name</th>
@@ -25,19 +45,12 @@
</tr>
{% endfor %}
</table>
{% endif %}
<h2> IAT </h2>
{% for dll in iat %}
<h3>DLL: {{dll}}</h3>
<ul>
{% for entry in iat[dll] %}
<li> {{ entry.dll_name }}: {{ entry.func_name }} ({{ entry.iat_vaddr | hexint }})</li>
{% endfor%}
</ul>
{% endfor %}
</div>
</div>
</div>
</body>
</html>
+15 -11
View File
@@ -10,7 +10,6 @@
<h2> {{project_name}} </h2>
<div class="row">
<!-- Row 1: Buttons -->
<div class="col-3">
@@ -72,7 +71,7 @@
<option value="{{exe}}"
{% if exe in project.settings.inject_exe_in %} selected {% endif %}
>
{{exe}}</option>
{{exe | basename}}</option>
{% endfor %}
</select>
@@ -84,11 +83,10 @@
>
{{export['name']}} ({{export['size']}})</option>
{% endfor %}
</select>
</select>
<a href="/exes/{{project.settings.inject_exe_in | basename}}">INFO</a>
{% endif %}
Is x64: {{ is_64}} <br>
Is Dotnet: {{ is_dotnet}}
</div>
<!-- Row 3: settings -->
@@ -109,10 +107,6 @@
{% endfor %}
</select>
</div>
<!-- Row 4: more settings -->
<div class="col-3">
<select class="form-select" name="decoder_style" aria-label="DECODERESTYLE" onchange="this.form.submit()">
{% for name, value in decoderstyles %}
<option value="{{name}}"
@@ -121,12 +115,22 @@
{% endfor %}
</select>
</div>
<!-- Row 4: more settings -->
<div class="col-3">
EXE/DLL Is: <br>
Is x64: {{ is_64}} <br>
Is Dotnet: {{ is_dotnet}} <br>
Code Section size: {{ code_sect_size}} <br>
Data Section size: {{ data_sect_size}} <br>
Data Section largest: {{ data_sect_largest_gap_size}} <br>
{{ project_dir }} <br>
</div>
</div>
</form>
<div class="row">
<div class="col">
{{ project_dir }}
<div class="custom-line"></div>
</div>
</div>
+5 -1
View File
@@ -37,4 +37,8 @@ def exes_view():
@views.app_template_filter('hexint')
def hex_filter(s):
return hex(s)
return hex(s)
@views.app_template_filter('basename')
def basename(s):
return os.path.basename(s)
+13
View File
@@ -21,6 +21,7 @@ from phases.injector import verify_injected_exe
from helper import run_process_checkret, run_exe
from model.project import prepare_project
from pe.superpe import SuperPe
from model.exehost import ExeHost
logger = logging.getLogger("ViewsProjects")
@@ -51,6 +52,9 @@ def project(name):
exports = []
is_64 = False
is_dotnet = False
code_sect_size = 0
data_sect_size = 0
data_sect_largest_gap_size = 0
# when we selected an input file
if project.settings.inject_exe_in != "":
@@ -59,6 +63,12 @@ def project(name):
is_dotnet = superpe.is_dotnet()
if superpe.is_dll():
exports = superpe.get_exports_full()
code_sect_size = superpe.get_code_section().Misc_VirtualSize
data_sect_size = superpe.get_section_by_name(".rdata").virt_size
exehost = ExeHost(project.settings.inject_exe_in)
exehost.init()
data_sect_largest_gap_size = exehost.get_rdata_relocmanager().find_largest_gap()
project_dir = os.path.dirname(os.path.abspath(project.settings.inject_exe_out))
log_files = get_logfiles(project.settings.main_dir)
@@ -93,6 +103,9 @@ def project(name):
log_files=log_files,
is_64=is_64,
is_dotnet=is_dotnet,
code_sect_size=code_sect_size,
data_sect_size=data_sect_size,
data_sect_largest_gap_size=data_sect_largest_gap_size,
)
+30 -1
View File
@@ -45,4 +45,33 @@ class RangeManager:
last_end = max(last_end, end)
if last_end < self.max and self.max - last_end >= hole_size:
holes.append((last_end + 1, self.max))
return holes
return holes
def find_largest_gap(self):
# First, sort intervals by the starting point
sorted_intervals = sorted(self.intervals, key=lambda x: x.begin)
# Initial largest gap is 0
largest_gap = 0
# Start by considering the gap from min to the first interval's start, if there are any intervals
if sorted_intervals:
largest_gap = sorted_intervals[0].begin - self.min
# Iterate over the intervals and find the gap between consecutive intervals
last_end = sorted_intervals[0].end if sorted_intervals else self.min
for interval in sorted_intervals[1:]:
# Calculate the gap between the current interval's start and the last interval's end
current_gap = interval.begin - last_end
if current_gap > largest_gap:
largest_gap = current_gap
last_end = max(last_end, interval.end) # Update last_end considering overlapping intervals
# Finally consider the gap from the last interval's end to max
if sorted_intervals:
final_gap = self.max - sorted_intervals[-1].end
if final_gap > largest_gap:
largest_gap = final_gap
return largest_gap
+5 -1
View File
@@ -229,7 +229,11 @@ class SuperPe():
"""Return a list of exported functions (names) from the PE file"""
d = [pefile.DIRECTORY_ENTRY["IMAGE_DIRECTORY_ENTRY_EXPORT"]]
self.pe.parse_data_directories(directories=d)
if self.pe.DIRECTORY_ENTRY_EXPORT.symbols == 0:
try:
if self.pe.DIRECTORY_ENTRY_EXPORT.symbols == 0:
return []
except Exception as e:
logger.warn("No exports found")
return []
res = []
for e in self.pe.DIRECTORY_ENTRY_EXPORT.symbols:
+3
View File
@@ -21,6 +21,9 @@ class RangeManagerTest(unittest.TestCase):
holes = rm.find_holes(20)
self.assertEqual([(31, 49), (61, 100)], holes)
largest = rm.find_largest_gap()
self.assertEqual(40, largest)
def test_relocmanager(self):
exehost = ExeHost(PATH_EXES + "procexp64.exe")