From 6871bc7e18e25fbc35ed7db001c0e2ac46cf9b69 Mon Sep 17 00:00:00 2001 From: jonathanzetier <207571460+jonathanzetier@users.noreply.github.com> Date: Mon, 14 Apr 2025 08:17:29 -0700 Subject: [PATCH 1/2] Update README.md It looks like the build instructions hadn't been updated after the arch plugins were moved back to binaryninja-api. --- arch/armv7/README.md | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/arch/armv7/README.md b/arch/armv7/README.md index e8b263f204..23feeedb04 100644 --- a/arch/armv7/README.md +++ b/arch/armv7/README.md @@ -7,8 +7,7 @@ If you're interested in contributing when you submit your first PR, you'll recei ## Building -Building the architecture plugin requires `cmake` 3.9 or above. You will also need the -[Binary Ninja API source](https://github.com/Vector35/binaryninja-api). +Building the architecture plugin requires `cmake` 3.9 or above Run `cmake`. This can be done either from a separate build directory or from the source directory. Once that is complete, run `make` in the build directory to compile the plugin. @@ -28,32 +27,14 @@ updates do not automatically uninstall your custom build.** ## Build Example -### acquire repositories -``` -mkdir ~/repos/vector35 -cd ~/repos/vector35 -git clone git@github.com:Vector35/binaryninja-api.git -git clone git@github.com:Vector35/arch-armv7.git -``` -### environment variables - -`export BN_API_PATH=~/repos/vector35/binaryninja-api` - ### cmake, make ``` -cd arch-armv7 +cd binaryninja-api/arch/armv7 cmake -DBN_INSTALL_DIR=/Applications/Binary\ Ninja\ DEV.app/ . make ``` ## Build Troubleshooting -### example - - CMake Error at CMakeLists.txt:8 (message): - Provide path to Binary Ninja API source in BN_API_PATH - resolution: - ensure BN_API_PATH is in your environment - ### example CMake Error at /Users/andrewl/repos/vector35/binaryninja-api/CMakeLists.txt:53 (message): From 87a7de587bedeb3e18103cb3e3cd773e134d68db Mon Sep 17 00:00:00 2001 From: jonathanzetier <207571460+jonathanzetier@users.noreply.github.com> Date: Mon, 14 Apr 2025 08:17:34 -0700 Subject: [PATCH 2/2] Add IL for thumb2 CP instructions --- arch/armv7/thumb2_disasm/arch_thumb2.cpp | 49 +++++++++++- arch/armv7/thumb2_disasm/il_thumb2.cpp | 98 ++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 1 deletion(-) diff --git a/arch/armv7/thumb2_disasm/arch_thumb2.cpp b/arch/armv7/thumb2_disasm/arch_thumb2.cpp index 1c38fc2c18..420dcbbbb9 100644 --- a/arch/armv7/thumb2_disasm/arch_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/arch_thumb2.cpp @@ -1177,7 +1177,7 @@ class Thumb2Architecture: public ArmCommonArchitecture if(reg == 15) result.emplace_back(RegisterToken, "apsr_nzcv"); else { - snprintf(regname, sizeof(regname), "R%d", reg); + get_reg_name(REG_R0 + reg, regname); result.emplace_back(RegisterToken, regname); } break; @@ -1347,6 +1347,14 @@ class Thumb2Architecture: public ArmCommonArchitecture { switch (intrinsic) { + case ARMV7_INTRIN_COPROC_GETONEWORD: + return "Coproc_GetOneWord"; + case ARMV7_INTRIN_COPROC_GETTWOWORDS: + return "Coproc_GetTwoWords"; + case ARMV7_INTRIN_COPROC_SENDONEWORD: + return "Coproc_SendOneWord"; + case ARMV7_INTRIN_COPROC_SENDTWOWORDS: + return "Coproc_SendTwoWords"; case ARMV7_INTRIN_DBG: return "__dbg"; case ARMV7_INTRIN_DMB_SY: @@ -1403,6 +1411,10 @@ class Thumb2Architecture: public ArmCommonArchitecture virtual vector GetAllIntrinsics() override { return vector { + ARMV7_INTRIN_COPROC_GETONEWORD, + ARMV7_INTRIN_COPROC_GETTWOWORDS, + ARMV7_INTRIN_COPROC_SENDONEWORD, + ARMV7_INTRIN_COPROC_SENDTWOWORDS, ARMV7_INTRIN_DBG, ARMV7_INTRIN_DMB_SY, ARMV7_INTRIN_DMB_ST, @@ -1433,6 +1445,37 @@ class Thumb2Architecture: public ArmCommonArchitecture { switch (intrinsic) { + case ARMV7_INTRIN_COPROC_GETONEWORD: + return { + NameAndType("cp", Type::IntegerType(1, false)), + NameAndType(Type::IntegerType(1, false)), + NameAndType("n", Type::IntegerType(1, false)), + NameAndType("m", Type::IntegerType(1, false)), + NameAndType(Type::IntegerType(1, false)), + }; + case ARMV7_INTRIN_COPROC_GETTWOWORDS: + return { + NameAndType("cp", Type::IntegerType(1, false)), + NameAndType(Type::IntegerType(1, false)), + NameAndType("m", Type::IntegerType(1, false)), + }; + case ARMV7_INTRIN_COPROC_SENDONEWORD: + return { + NameAndType(Type::IntegerType(4, false)), + NameAndType("cp", Type::IntegerType(1, false)), + NameAndType(Type::IntegerType(1, false)), + NameAndType("n", Type::IntegerType(1, false)), + NameAndType("m", Type::IntegerType(1, false)), + NameAndType(Type::IntegerType(1, false)), + }; + case ARMV7_INTRIN_COPROC_SENDTWOWORDS: + return { + NameAndType(Type::IntegerType(4, false)), + NameAndType(Type::IntegerType(4, false)), + NameAndType("cp", Type::IntegerType(1, false)), + NameAndType(Type::IntegerType(1, false)), + NameAndType("m", Type::IntegerType(1, false)), + }; case ARMV7_INTRIN_MRS: return {NameAndType(Type::IntegerType(4, false))}; case ARMV7_INTRIN_MSR: @@ -1448,6 +1491,10 @@ class Thumb2Architecture: public ArmCommonArchitecture { switch (intrinsic) { + case ARMV7_INTRIN_COPROC_GETONEWORD: + return { Type::IntegerType(4, false) }; + case ARMV7_INTRIN_COPROC_GETTWOWORDS: + return { Type::IntegerType(4, false), Type::IntegerType(4, false) }; case ARMV7_INTRIN_MRS: return {Type::IntegerType(4, false)}; case ARMV7_INTRIN_MSR: diff --git a/arch/armv7/thumb2_disasm/il_thumb2.cpp b/arch/armv7/thumb2_disasm/il_thumb2.cpp index d62f14777e..9eca80630d 100644 --- a/arch/armv7/thumb2_disasm/il_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/il_thumb2.cpp @@ -973,6 +973,44 @@ bool GetLowLevelILForThumbInstruction(Architecture* arch, LowLevelILFunction& il il.AddInstruction(WriteArithOperand(il, instr, il.LogicalShiftRight(4, ReadArithOperand(il, instr, 0), ReadArithOperand(il, instr, 1), ifThenBlock ? 0 : IL_FLAGWRITE_CNZ))); break; + case armv7::ARMV7_MCR: + case armv7::ARMV7_MCR2: + { + int dest_reg_field = instr->fields[instr->format->operands[2].field0]; + int dest_reg = GetRegisterByIndex(dest_reg_field, instr->format->operands[2].prefix); + + il.AddInstruction( + il.Intrinsic({ }, ARMV7_INTRIN_COPROC_SENDONEWORD, + { + il.Register(4, dest_reg), + il.Const(1, instr->fields[instr->format->operands[0].field0]), + il.Const(1, instr->fields[instr->format->operands[1].field0]), + il.Const(1, instr->fields[instr->format->operands[3].field0]), + il.Const(1, instr->fields[instr->format->operands[4].field0]), + il.Const(1, instr->fields[instr->format->operands[5].field0]), + } + ) + ); + break; + } + case ARMV7_MCRR: + case ARMV7_MCRR2: + { + int rt = instr->fields[instr->format->operands[2].field0]; + int rt2 = instr->fields[instr->format->operands[3].field0]; + il.AddInstruction( + il.Intrinsic({ }, ARMV7_INTRIN_COPROC_SENDTWOWORDS, + { + il.Register(4, rt2), + il.Register(4, rt), + il.Const(1, instr->fields[instr->format->operands[0].field0]), + il.Const(1, instr->fields[instr->format->operands[1].field0]), + il.Const(1, instr->fields[instr->format->operands[4].field0]), + } + ) + ); + break; + } case armv7::ARMV7_MLA: il.AddInstruction(WriteILOperand(il, instr, 0, il.Add(4, ReadILOperand(il, instr, 3), il.Mult(4, ReadILOperand(il, instr, 1), ReadILOperand(il, instr, 2))))); break; @@ -992,6 +1030,66 @@ bool GetLowLevelILForThumbInstruction(Architecture* arch, LowLevelILFunction& il il.ShiftLeft(4, il.Const(2, instr->fields[instr->format->operands[1].field0]), il.Const(1, 16)), il.And(4, il.Const(4, 0x0000ffff), ReadILOperand(il, instr, 0))))); break; + case armv7::ARMV7_MRC: + case armv7::ARMV7_MRC2: + { + auto params = { + il.Const(1, instr->fields[instr->format->operands[0].field0]), /* cp */ + il.Const(1, instr->fields[instr->format->operands[1].field0]), /* opc1 */ + il.Const(1, instr->fields[instr->format->operands[3].field0]), /* crn */ + il.Const(1, instr->fields[instr->format->operands[4].field0]), /* crm */ + il.Const(1, instr->fields[instr->format->operands[5].field0]), /* opc2 */ + }; + + int dest_reg_field = instr->fields[instr->format->operands[2].field0]; + if (dest_reg_field == 15) + { + il.AddInstruction( + il.Intrinsic( + { RegisterOrFlag::Register(LLIL_TEMP(0)) }, + ARMV7_INTRIN_COPROC_GETONEWORD, + params + ) + ); + il.AddInstruction(il.SetFlag(IL_FLAG_N, il.TestBit(4, il.Register(4, LLIL_TEMP(0)), il.Const(1, 31)))); + il.AddInstruction(il.SetFlag(IL_FLAG_Z, il.TestBit(4, il.Register(4, LLIL_TEMP(0)), il.Const(1, 30)))); + il.AddInstruction(il.SetFlag(IL_FLAG_C, il.TestBit(4, il.Register(4, LLIL_TEMP(0)), il.Const(1, 29)))); + il.AddInstruction(il.SetFlag(IL_FLAG_V, il.TestBit(4, il.Register(4, LLIL_TEMP(0)), il.Const(1, 28)))); + break; + } + + int dest_reg = GetRegisterByIndex(dest_reg_field, instr->format->operands[2].prefix); + + il.AddInstruction( + il.Intrinsic( + {RegisterOrFlag::Register(dest_reg)}, /* outputs */ + ARMV7_INTRIN_COPROC_GETONEWORD, + params /* inputs */ + ) + ); + break; + } + + case ARMV7_MRRC: + case ARMV7_MRRC2: + { + int rt = instr->fields[instr->format->operands[2].field0]; + int rt2 = instr->fields[instr->format->operands[3].field0]; + + il.AddInstruction( + il.Intrinsic( + { RegisterOrFlag::Register(rt2), RegisterOrFlag::Register(rt) }, + ARMV7_INTRIN_COPROC_GETTWOWORDS, + { + il.Const(1, instr->fields[instr->format->operands[0].field0]), + il.Const(1, instr->fields[instr->format->operands[1].field0]), + il.Const(1, instr->fields[instr->format->operands[4].field0]), + } + ) + ); + break; + } + case armv7::ARMV7_MRS: { int dest_reg = GetRegisterByIndex(instr->fields[instr->format->operands[0].field0], instr->format->operands[0].prefix);