mirror of
https://github.com/isledecomp/isle.git
synced 2024-11-29 11:06:05 -05:00
Merge branch 'isledecomp:master' into legobackgroundcolor
This commit is contained in:
commit
b0288803a8
7 changed files with 82 additions and 42 deletions
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
@ -60,6 +60,7 @@ jobs:
|
||||||
C:\msys64\usr\bin\wget.exe https://legoisland.org/download/ISLE.EXE
|
C:\msys64\usr\bin\wget.exe https://legoisland.org/download/ISLE.EXE
|
||||||
C:\msys64\usr\bin\wget.exe https://legoisland.org/download/LEGO1.DLL
|
C:\msys64\usr\bin\wget.exe https://legoisland.org/download/LEGO1.DLL
|
||||||
pip install capstone
|
pip install capstone
|
||||||
|
pip install colorama
|
||||||
python3 tools/reccmp/reccmp.py -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB .
|
python3 tools/reccmp/reccmp.py -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB .
|
||||||
python3 tools/reccmp/reccmp.py -H LEGO1PROGRESS.HTML LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB .
|
python3 tools/reccmp/reccmp.py -H LEGO1PROGRESS.HTML LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB .
|
||||||
|
|
||||||
|
|
|
@ -68,18 +68,6 @@ long LegoOmni::Notify(MxParam &p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x10058aa0
|
|
||||||
const char *LegoOmni::GetClassName() const
|
|
||||||
{
|
|
||||||
return "LegoOmni";
|
|
||||||
}
|
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x10058ab0
|
|
||||||
MxBool LegoOmni::IsClass(const char *name) const
|
|
||||||
{
|
|
||||||
return strcmp("LegoOmni", name) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x10058bd0
|
// OFFSET: LEGO1 0x10058bd0
|
||||||
void LegoOmni::Init()
|
void LegoOmni::Init()
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,8 +30,15 @@ class LegoOmni : public MxOmni
|
||||||
virtual ~LegoOmni(); // vtable+00
|
virtual ~LegoOmni(); // vtable+00
|
||||||
|
|
||||||
virtual long Notify(MxParam &p); // vtable+04
|
virtual long Notify(MxParam &p); // vtable+04
|
||||||
virtual const char *GetClassName() const; // vtable+0c
|
|
||||||
virtual MxBool IsClass(const char *name) const; // vtable+10;
|
// OFFSET: LEGO1 0x10058aa0
|
||||||
|
inline virtual const char *GetClassName() const { return "LegoOmni"; }; // vtable+0c
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x10058ab0
|
||||||
|
inline virtual MxBool IsClass(const char *name) const {
|
||||||
|
return !strcmp(name, LegoOmni::GetClassName()) || MxOmni::IsClass(name);
|
||||||
|
}; // vtable+10;
|
||||||
|
|
||||||
virtual void Init(); // vtable+14
|
virtual void Init(); // vtable+14
|
||||||
virtual MxResult Create(MxOmniCreateParam &p); // vtable+18
|
virtual MxResult Create(MxOmniCreateParam &p); // vtable+18
|
||||||
virtual void Destroy(); // vtable+1c
|
virtual void Destroy(); // vtable+1c
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "mxcore.h"
|
#include "mxcore.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// 0x1010141c
|
// 0x1010141c
|
||||||
unsigned int g_mxcoreCount = 0;
|
unsigned int g_mxcoreCount = 0;
|
||||||
|
|
||||||
|
@ -28,15 +26,3 @@ long MxCore::Tickle()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100144c0
|
|
||||||
const char *MxCore::GetClassName() const
|
|
||||||
{
|
|
||||||
return "MxCore";
|
|
||||||
}
|
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100140d0
|
|
||||||
MxBool MxCore::IsClass(const char *name) const
|
|
||||||
{
|
|
||||||
return strcmp(name, "MxCore") == 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef MXCORE_H
|
#ifndef MXCORE_H
|
||||||
#define MXCORE_H
|
#define MXCORE_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "mxbool.h"
|
#include "mxbool.h"
|
||||||
|
|
||||||
class MxParam;
|
class MxParam;
|
||||||
|
@ -12,8 +14,14 @@ class MxCore
|
||||||
__declspec(dllexport) virtual ~MxCore(); // vtable+00
|
__declspec(dllexport) virtual ~MxCore(); // vtable+00
|
||||||
__declspec(dllexport) virtual long Notify(MxParam &p); // vtable+04
|
__declspec(dllexport) virtual long Notify(MxParam &p); // vtable+04
|
||||||
virtual long Tickle(); // vtable+08
|
virtual long Tickle(); // vtable+08
|
||||||
virtual const char *GetClassName() const; // vtable+0c
|
|
||||||
virtual MxBool IsClass(const char *name) const; // vtable+10
|
// OFFSET: LEGO1 0x100144c0
|
||||||
|
inline virtual const char *GetClassName() const { return "MxCore"; }; // vtable+0c
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100140d0
|
||||||
|
inline virtual MxBool IsClass(const char *name) const {
|
||||||
|
return !strcmp(name, MxCore::GetClassName());
|
||||||
|
}; // vtable+10
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_id;
|
unsigned int m_id;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import colorama
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(allow_abbrev=False,
|
parser = argparse.ArgumentParser(allow_abbrev=False,
|
||||||
description='Recompilation Compare: compare an original EXE with a recompiled EXE + PDB.')
|
description='Recompilation Compare: compare an original EXE with a recompiled EXE + PDB.')
|
||||||
|
@ -16,10 +17,14 @@
|
||||||
parser.add_argument('decomp_dir', metavar='decomp-dir', help='The decompiled source tree')
|
parser.add_argument('decomp_dir', metavar='decomp-dir', help='The decompiled source tree')
|
||||||
parser.add_argument('--verbose', '-v', metavar='offset', help='Print assembly diff for specific function (original file\'s offset)')
|
parser.add_argument('--verbose', '-v', metavar='offset', help='Print assembly diff for specific function (original file\'s offset)')
|
||||||
parser.add_argument('--html', '-H', metavar='output-file', help='Generate searchable HTML summary of status and diffs')
|
parser.add_argument('--html', '-H', metavar='output-file', help='Generate searchable HTML summary of status and diffs')
|
||||||
|
parser.add_argument('--no-color', '-n', action='store_true', help='Do not color the output')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
colorama.init()
|
||||||
|
|
||||||
verbose = None
|
verbose = None
|
||||||
|
found_verbose_target = False
|
||||||
if args.verbose:
|
if args.verbose:
|
||||||
try:
|
try:
|
||||||
verbose = int(args.verbose, 16)
|
verbose = int(args.verbose, 16)
|
||||||
|
@ -27,6 +32,8 @@
|
||||||
parser.error('invalid verbose argument')
|
parser.error('invalid verbose argument')
|
||||||
html = args.html
|
html = args.html
|
||||||
|
|
||||||
|
plain = args.no_color
|
||||||
|
|
||||||
original = args.original
|
original = args.original
|
||||||
if not os.path.isfile(original):
|
if not os.path.isfile(original):
|
||||||
parser.error('Original binary does not exist')
|
parser.error('Original binary does not exist')
|
||||||
|
@ -287,6 +294,13 @@ def parse_asm(file, addr, size):
|
||||||
|
|
||||||
addr = int(par[1], 16)
|
addr = int(par[1], 16)
|
||||||
|
|
||||||
|
# Verbose flag handling
|
||||||
|
if verbose:
|
||||||
|
if addr == verbose:
|
||||||
|
found_verbose_target = True
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
find_open_bracket = line
|
find_open_bracket = line
|
||||||
while '{' not in find_open_bracket:
|
while '{' not in find_open_bracket:
|
||||||
find_open_bracket = srcfile.readline()
|
find_open_bracket = srcfile.readline()
|
||||||
|
@ -305,21 +319,51 @@ def parse_asm(file, addr, size):
|
||||||
else:
|
else:
|
||||||
ratio = 0
|
ratio = 0
|
||||||
|
|
||||||
print(' %s (%s / %s) is %.2f%% similar to the original' % (recinfo.name, hex(addr), hex(recinfo.addr), ratio * 100))
|
percenttext = "%.2f%%" % (ratio * 100)
|
||||||
|
if not plain:
|
||||||
|
if ratio == 1.0:
|
||||||
|
percenttext = colorama.Fore.GREEN + percenttext + colorama.Style.RESET_ALL
|
||||||
|
elif ratio > 0.8:
|
||||||
|
percenttext = colorama.Fore.YELLOW + percenttext + colorama.Style.RESET_ALL
|
||||||
|
else:
|
||||||
|
percenttext = colorama.Fore.RED + percenttext + colorama.Style.RESET_ALL
|
||||||
|
|
||||||
|
if not verbose:
|
||||||
|
print(' %s (%s / %s) is %s similar to the original' % (recinfo.name, hex(addr), hex(recinfo.addr), percenttext))
|
||||||
|
|
||||||
function_count += 1
|
function_count += 1
|
||||||
total_accuracy += ratio
|
total_accuracy += ratio
|
||||||
|
|
||||||
if recinfo.size:
|
if recinfo.size:
|
||||||
if verbose == addr or html:
|
udiff = difflib.unified_diff(origasm, recompasm, n=10)
|
||||||
udiff = difflib.unified_diff(origasm, recompasm)
|
|
||||||
|
|
||||||
if verbose == addr:
|
# If verbose, print the diff for that funciton to the output
|
||||||
|
if verbose:
|
||||||
|
if ratio == 1.0:
|
||||||
|
print("%s: %s 100%% match.\n\nOK!" % (hex(addr), recinfo.name))
|
||||||
|
else:
|
||||||
for line in udiff:
|
for line in udiff:
|
||||||
|
if line.startswith("++") or line.startswith("@@") or line.startswith("--"):
|
||||||
|
# Skip unneeded parts of the diff for the brief view
|
||||||
|
pass
|
||||||
|
elif line.startswith("+"):
|
||||||
|
if plain:
|
||||||
print(line)
|
print(line)
|
||||||
print()
|
else:
|
||||||
print()
|
print(colorama.Fore.GREEN + line)
|
||||||
|
elif line.startswith("-"):
|
||||||
|
if plain:
|
||||||
|
print(line)
|
||||||
|
else:
|
||||||
|
print(colorama.Fore.RED + line)
|
||||||
|
else:
|
||||||
|
print(line)
|
||||||
|
if not plain:
|
||||||
|
print(colorama.Style.RESET_ALL, end='')
|
||||||
|
|
||||||
|
print("\n%s is only %s similar to the original, diff above" % (recinfo.name, percenttext))
|
||||||
|
|
||||||
|
# If html, record the diffs to an HTML file
|
||||||
if html:
|
if html:
|
||||||
htmlinsert.append('{address: "%s", name: "%s", matching: %s, diff: "%s"}' % (hex(addr), recinfo.name, str(ratio), '\\n'.join(udiff).replace('"', '\\"').replace('\n', '\\n')))
|
htmlinsert.append('{address: "%s", name: "%s", matching: %s, diff: "%s"}' % (hex(addr), recinfo.name, str(ratio), '\\n'.join(udiff).replace('"', '\\"').replace('\n', '\\n')))
|
||||||
|
|
||||||
|
@ -348,5 +392,9 @@ def gen_html(html, data):
|
||||||
if html:
|
if html:
|
||||||
gen_html(html, htmlinsert)
|
gen_html(html, htmlinsert)
|
||||||
|
|
||||||
if function_count > 0:
|
if verbose:
|
||||||
|
if not found_verbose_target:
|
||||||
|
print('Failed to find the function with address %s' % hex(verbose))
|
||||||
|
else:
|
||||||
|
if function_count > 0:
|
||||||
print('\nTotal accuracy %.2f%% across %i functions' % (total_accuracy / function_count * 100, function_count))
|
print('\nTotal accuracy %.2f%% across %i functions' % (total_accuracy / function_count * 100, function_count))
|
||||||
|
|
2
tools/reccmp/requirements.txt
Normal file
2
tools/reccmp/requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
colorama
|
||||||
|
capstone
|
Loading…
Reference in a new issue