From 0aec412f6bb59f56a856f37ff9ed21116a9dc5d9 Mon Sep 17 00:00:00 2001 From: Antonio Flores Montoya Date: Fri, 8 Dec 2023 09:52:03 -0500 Subject: [PATCH 1/6] Fix symbol assignment for PE exported functions PE symbols have no defined type, so we need to allow non-FUNC symbols to be assigned to functions for their symbolNames. --- src/datalog/symbols.dl | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/datalog/symbols.dl b/src/datalog/symbols.dl index 6a0b3676..b1452d3e 100644 --- a/src/datalog/symbols.dl +++ b/src/datalog/symbols.dl @@ -203,13 +203,26 @@ elf_avoid_symbols("__TMC_END__"). // and no pre-existing function symbols. best_func_symbol(EA,SymbolName):- - symbol_score(EA,SymbolName,"FUNC","Beg",Score), - Score = max S: {symbol_score(EA,_,"FUNC","Beg",S)}. + binary_format("ELF"), + symbol_score(EA,SymbolName,"FUNC","Beg",Score), + Score = max S: {symbol_score(EA,_,"FUNC","Beg",S)}. + +// For non-ELF (e.g. PE), symbols might not have a type +best_func_symbol(EA,SymbolName):- + !binary_format("ELF"), + symbol_score(EA,SymbolName,_,"Beg",Score), + Score = max S: {symbol_score(EA,_,_,"Beg",S)}. inferred_symbol(EA,SymbolName,Scope,"DEFAULT","FUNC","Beg"), best_func_symbol(EA,SymbolName):- function_inference.function_entry(EA), - !symbol_score(EA,_,"FUNC","Beg",_), + ( + binary_format("ELF"), + !symbol_score(EA,_,"FUNC","Beg",_) + ; + !binary_format("ELF"), + !symbol_score(EA,_,_,"Beg",_) + ), SymbolName = cat("FUN_",@to_string_hex(EA)), ( binary_isa("MIPS"), Scope = "GLOBAL"; From f77919114f145692c1c48ee9620a0daa4a263156 Mon Sep 17 00:00:00 2001 From: Antonio Flores Montoya Date: Fri, 8 Dec 2023 11:46:46 -0500 Subject: [PATCH 2/6] add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2959ea9..215955e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ * `$t` symbols in ARM binaries now force creation of Thumb-mode code blocks. * In PE binaries, duplicate imports no longer create duplicate symbols. * Added pattern to match missed symbolic data in pointer arrays. +* Fix symbols associated to functions (Auxdata functionNames) for PE binaries + when Ddisasm is run with option `-F`. * Requires gtirb >=1.12.1, gtirb-pprinter >=2.0.0 # 1.7.0 From 504db9878beb6e5c67e8ab800a486cf4e72698cb Mon Sep 17 00:00:00 2001 From: Antonio Flores Montoya Date: Fri, 8 Dec 2023 12:00:53 -0500 Subject: [PATCH 3/6] test functionNames assignment in PE --- tests/misc_test.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/misc_test.py b/tests/misc_test.py index 866efe91..7080eef6 100644 --- a/tests/misc_test.py +++ b/tests/misc_test.py @@ -627,6 +627,38 @@ def test_symbol_selection(self): self.assertIn("fun", fun_names) self.assertNotIn("_fun", fun_names) + @unittest.skipUnless( + platform.system() == "Windows", "This test is Windows only" + ) + def test_pe_function_symbol_selection(self): + """ + Test that function names are correctly selected + in PE binaries. + """ + library = "baz.dll" + with cd(ex_dir / "ex_ml_sym_mangling"): + proc = subprocess.run(make("all"), stdout=subprocess.DEVNULL) + self.assertEqual(proc.returncode, 0) + for extra_args in ["", "-F"]: + with self.subTest(extra_args=extra_args): + self.assertTrue( + disassemble( + library, format="--ir", extra_args=extra_args + )[0] + ) + + ir_library = gtirb.IR.load_protobuf(library + ".gtirb") + m = ir_library.modules[0] + + # check chosen function names + fun_names = { + sym.name + for sym in m.aux_data["functionNames"].data.values() + } + self.assertIn("Baz", fun_names) + self.assertIn("_Baz", fun_names) + self.assertIn("__Baz", fun_names) + @unittest.skipUnless( platform.system() == "Linux", "This test is linux only." ) From 78aa25532fa96f7d679505313aff4bfa1599f99b Mon Sep 17 00:00:00 2001 From: Antonio Flores Montoya Date: Fri, 8 Dec 2023 13:33:54 -0500 Subject: [PATCH 4/6] define default compiler to cl --- examples/ex_ml_sym_mangling/Makefile.windows | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ex_ml_sym_mangling/Makefile.windows b/examples/ex_ml_sym_mangling/Makefile.windows index 1737a3f9..cb101c34 100644 --- a/examples/ex_ml_sym_mangling/Makefile.windows +++ b/examples/ex_ml_sym_mangling/Makefile.windows @@ -1,4 +1,4 @@ -CC= +CC=cl CFLAGS= EXEC= From 0c6a6b3bb30852e9ee2c02495ae872c1bac9167f Mon Sep 17 00:00:00 2001 From: Antonio Flores Montoya Date: Fri, 8 Dec 2023 14:35:18 -0500 Subject: [PATCH 5/6] fix extra_args param in test --- tests/misc_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/misc_test.py b/tests/misc_test.py index 7080eef6..028b579d 100644 --- a/tests/misc_test.py +++ b/tests/misc_test.py @@ -639,7 +639,7 @@ def test_pe_function_symbol_selection(self): with cd(ex_dir / "ex_ml_sym_mangling"): proc = subprocess.run(make("all"), stdout=subprocess.DEVNULL) self.assertEqual(proc.returncode, 0) - for extra_args in ["", "-F"]: + for extra_args in ([], ["-F"]): with self.subTest(extra_args=extra_args): self.assertTrue( disassemble( From 3b025f122dc9006bdae90f136e52363de5c567b5 Mon Sep 17 00:00:00 2001 From: Antonio Flores Montoya Date: Fri, 8 Dec 2023 15:47:39 -0500 Subject: [PATCH 6/6] clean before rebuilding and do not recompile main program in ex_ml_sym_mangling --- examples/ex_ml_sym_mangling/Makefile.windows | 1 - tests/misc_test.py | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/ex_ml_sym_mangling/Makefile.windows b/examples/ex_ml_sym_mangling/Makefile.windows index cb101c34..69b3dcc0 100644 --- a/examples/ex_ml_sym_mangling/Makefile.windows +++ b/examples/ex_ml_sym_mangling/Makefile.windows @@ -16,7 +16,6 @@ clean: rm -f ex *.dll out.txt *.s *.lib *.exp *.o *.err *.obj *.exe check: - $(CC) ex.c foo.lib baz.lib @ ex > check.txt @ FC out.txt check.txt && echo TEST OK diff --git a/tests/misc_test.py b/tests/misc_test.py index 028b579d..753814cd 100644 --- a/tests/misc_test.py +++ b/tests/misc_test.py @@ -637,6 +637,8 @@ def test_pe_function_symbol_selection(self): """ library = "baz.dll" with cd(ex_dir / "ex_ml_sym_mangling"): + proc = subprocess.run(make("clean"), stdout=subprocess.DEVNULL) + self.assertEqual(proc.returncode, 0) proc = subprocess.run(make("all"), stdout=subprocess.DEVNULL) self.assertEqual(proc.returncode, 0) for extra_args in ([], ["-F"]):