From d2f93094b2c848b839b25b7565cb6d4bde7f15c2 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Mon, 2 Dec 2019 09:42:36 -0500 Subject: [PATCH] mips updates --- include/arch/arch_mips32.hpp | 4 +-- src/patcher_mips32.cpp | 57 +++++++++++++----------------------- src/pinner_mips32.cpp | 7 +++-- 3 files changed, 27 insertions(+), 41 deletions(-) diff --git a/include/arch/arch_mips32.hpp b/include/arch/arch_mips32.hpp index 0d1bf4352..5746425db 100644 --- a/include/arch/arch_mips32.hpp +++ b/include/arch/arch_mips32.hpp @@ -10,8 +10,8 @@ class ZiprArchitectureHelperMIPS32_t : public ZiprArchitectureHelperBase_t virtual IRDB_SDK::Instruction_t* createNewJumpInstruction(IRDB_SDK::FileIR_t *p_firp, IRDB_SDK::Instruction_t* p_existing) override { - // bytes = 0b00000000 0b00000000 0b00000000 0b00010000 - // jump always with 26bit offset + // create a beq $0, $0, imm16 instruction + // to be PC-relative. const auto bits =string("\x10\x00\x00\x000",4); auto ret=IRDB_SDK::addNewDataBits(p_firp, p_existing, bits); const auto d=IRDB_SDK::DecodedInstruction_t::factory(ret); diff --git a/src/patcher_mips32.cpp b/src/patcher_mips32.cpp index ec147ecd4..392a57175 100644 --- a/src/patcher_mips32.cpp +++ b/src/patcher_mips32.cpp @@ -64,43 +64,28 @@ void ZiprPatcherMIPS32_t::ApplyNopToPatch(RangeAddress_t addr) void ZiprPatcherMIPS32_t::ApplyPatch(RangeAddress_t from_addr, RangeAddress_t to_addr) { +#if 0 const auto first_byte = (uint8_t)memory_space[from_addr+0]; - const auto new_offset = (int32_t)((to_addr) - (from_addr+8)) >> 2; - - // A Branch in binary is: op= 000010 imm26=0000 00000000 00000000 00000000 - // it includes a 26-bit immediate, which is +/- 128mb, which should be a good enough "jump anywhere" - // for now. - const auto mask6 = (0b111111); - const auto is_uncond_branch = ((first_byte >> 2) & mask6) == (0b000010); // jump branch - - if(is_uncond_branch) - { - cout<<"Applying uncond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl; - const auto non_imm_bits = 32U-26U; // 32 bits - imm26 - // assert there's no overflow. - assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits); - // or in opcode for first byte. set remaining bytes. - const auto mask26 = ((1<<26)-1); - const auto trimmed_offset = new_offset & mask26; - memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff; - memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff; - memory_space[from_addr+1] = (trimmed_offset>>16)&0xff; - memory_space[from_addr+0] |= (trimmed_offset>>24)&0x02; - } - else - { - cout<<"Applying cond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl; - const auto non_imm_bits = 32U-24U; // 32 bits - imm24 - // assert there's no overflow. - assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits); - // or in opcode for first byte. set remaining bytes. - const auto mask24 = ((1<<24)-1); - const auto trimmed_offset = new_offset & mask24; - memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff; - memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff; - memory_space[from_addr+1] = (trimmed_offset>>16)&0xff; - memory_space[from_addr+0] |= (trimmed_offset>>24)&0x02; - } + assert(first_byte == 0x10); // beq $0 +#endif + + const auto new_offset = (int32_t)((to_addr) - (from_addr+4)) >> 2; + + + // Use a branch always. In mips, this will be a beq $0, $0, <label> as there is no branch always. + // format: 0001 00ss sstt iiii iiii iiii iiii iiii + // ssss=0b0000 + // tttt=0b0000 + // i...i = (from_addr-to_addr)>>2 + cout<<"Applying cond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl; + const auto non_imm_bits = 16; + // assert there's no overflow. + assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits); + // or in opcode for first byte. set remaining bytes. + const auto mask16 = ((1<<16)-1); + const auto trimmed_offset = new_offset & mask16; + memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff; + memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff; } diff --git a/src/pinner_mips32.cpp b/src/pinner_mips32.cpp index f006e3a6b..2627aa1b1 100644 --- a/src/pinner_mips32.cpp +++ b/src/pinner_mips32.cpp @@ -41,9 +41,10 @@ void ZiprPinnerMIPS32_t::doPinning() auto ibta_addr=(RangeAddress_t)insn-> getIndirectBranchTargetAddress()-> getVirtualOffset(); - // put unconditional branch with 24-bit offset in memory - // 1110 1010 0000 0000 0000 0000 0000 0000 - uint8_t bytes[]={'\x18','\x00','\x00','\x00'}; + // put branch with 16-bit offset in memory + // i.e., beq $0, $0, imm16 + // including putting a nop in the delay slot. + uint8_t bytes[]={'\x10','\x00','\x00','\x00', '\x00', '\x00', '\x00', '\x00'}; for(auto i=0U;i<sizeof(bytes);i++) { const auto ibta_byte_addr = ibta_addr+i; -- GitLab