Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix AARCH64 Keystone Vector Instructions bug #316

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,35 @@ def _get_cs_mode_flag(cs_disam: CapstoneDisassemblerType):


def _asm_fixups(base_mnemonic: str, base_operands: str, isa: InstructionSet) -> Tuple[str, str]:
operands = re.sub(RE_REPRESENT_CONSTANTS_HEX, r"\g<1>0x\g<2>", base_operands)
arm64_vector_hexify_exclusion_mnems = [
"movi",
"fdiv",
"fmax",
"fmla",
"fmls",
"fmov",
"fmul",
"fmulx",
"fneg",
]
"""
In AARCH64, vector instructions use numerical constants to reference vectors to perform operations on
These numerical constants shouldn't be converted to hex because keystone will be unable to reassemble them
In every other case we want to to the constants to hex conversion
rbs-alexr marked this conversation as resolved.
Show resolved Hide resolved
"""
hex_operand_fixup = lambda base_operands: re.sub(
RE_REPRESENT_CONSTANTS_HEX, r"\g<1>0x\g<2>", base_operands
)

if isa is InstructionSet.AARCH64:
if base_mnemonic not in arm64_vector_hexify_exclusion_mnems:
operands = hex_operand_fixup(base_operands)
else:
# do not fixup operands to hex
operands = base_operands
else:
operands = hex_operand_fixup(base_operands)

if isa is InstructionSet.ARM:
operands = re.sub(RE_RENAME_FP_TO_R11, r"\1r11\2", operands)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
RegisterAnalyzerTestCase,
RegisterUsageTestPattern,
)
from test_ofrak.constants import ARM32_ARCH
from test_ofrak.constants import ARM32_ARCH, AARCH64_ARCH

pytest_plugins = ["pytest_ofrak.fixtures"]

Expand Down Expand Up @@ -196,13 +196,40 @@ async def _initialize_basic_bloc_resource(self, ofrak) -> Resource:
InstructionSetMode.NONE,
),
],
)
),
UnpackerTestCase(
"AARCH64",
AARCH64_ARCH,
BasicBlock(0x100, 0x14, InstructionSetMode.NONE, False, None),
unhexlify("00E4006F"),
[
Instruction(
0x100,
4,
"movi v0.2d, #0000000000000000",
"movi",
"v0.2d, #0000000000000000",
InstructionSetMode.NONE,
)
],
),
UnpackerTestCase(
"AARCH64",
AARCH64_ARCH,
BasicBlock(0x100, 0x14, InstructionSetMode.NONE, False, None),
unhexlify("02102E1E"),
[
Instruction(
0x100, 4, "fmov s2, #1.00000000", "fmov", "s2, #1.00000000", InstructionSetMode.NONE
)
],
),
]


@pytest.mark.parametrize("test_case", BASIC_BLOCK_TEST_CASES, ids=lambda tc: tc.label)
async def test_capstone_unpacker(test_case, ofrak_context):
await test_case.run_instruction_analzyer_test_case(ofrak_context)
await test_case.run_instruction_unpacker_test_case(ofrak_context)


@pytest.mark.parametrize("test_case", BASIC_BLOCK_TEST_CASES, ids=lambda tc: tc.label)
Expand Down
1 change: 1 addition & 0 deletions ofrak_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Fixed
- Fixed a bug where clicking "Unpack" or "Identify" (for example) too quickly after loading a large resource causes an error that freezes up the whole GUI ([#297](https://github.com/redballoonsecurity/ofrak/pull/297))
- Bump `importlib-metadata` version to fix import errors ([#296](https://github.com/redballoonsecurity/ofrak/pull/296))
- Fixed a bug in assembler_service_keystone that mishandled AARCH64 vector instructions

## [3.0.0](https://github.com/redballoonsecurity/ofrak/compare/ofrak-v2.2.1...ofrak-v3.0.0)
### Added
Expand Down
8 changes: 8 additions & 0 deletions ofrak_core/test_ofrak/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@
Endianness.BIG_ENDIAN,
None,
)

AARCH64_ARCH = ProgramAttributes(
InstructionSet.AARCH64,
None,
BitWidth.BIT_64,
Endianness.LITTLE_ENDIAN,
None,
)