Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
23 changes: 2 additions & 21 deletions arch/armv7/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -28,32 +27,14 @@ updates do not automatically uninstall your custom build.**

## Build Example

### acquire repositories
```
mkdir ~/repos/vector35
cd ~/repos/vector35
git clone [email protected]:Vector35/binaryninja-api.git
git clone [email protected]: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):
Expand Down
49 changes: 48 additions & 1 deletion arch/armv7/thumb2_disasm/arch_thumb2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -1403,6 +1411,10 @@ class Thumb2Architecture: public ArmCommonArchitecture
virtual vector<uint32_t> GetAllIntrinsics() override
{
return vector<uint32_t> {
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,
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down
98 changes: 98 additions & 0 deletions arch/armv7/thumb2_disasm/il_thumb2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down