869 lines
28 KiB
C++
869 lines
28 KiB
C++
// BoschHelper.cpp: implementation of the BoschHelper class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
//Standard Defs
|
|
typedef int BOOL;
|
|
#define FALSE 0
|
|
#define TRUE 1
|
|
#define NULL 0
|
|
|
|
#include <ida.hpp>
|
|
#include <idp.hpp>//str2reg()
|
|
#include <expr.hpp>
|
|
#include <bytes.hpp>
|
|
#include <loader.hpp>
|
|
#include <kernwin.hpp>
|
|
#include <name.hpp>
|
|
#include <offset.hpp>
|
|
#include <search.hpp>
|
|
#include <srarea.hpp> //SetDefaultRegisterValue()
|
|
#include <allins.hpp> // processor instructions
|
|
#include <funcs.hpp> //get_func()
|
|
#include <enum.hpp> //for enumerations
|
|
#include <auto.hpp> // for showaddr
|
|
|
|
#include "BoschHelper.h"
|
|
//#include "FunctionSigs.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
BoschHelper::BoschHelper()
|
|
{
|
|
mSelector = 1;
|
|
|
|
}
|
|
|
|
BoschHelper::~BoschHelper()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Helpers
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// Loops through the binary and makes disassembled code
|
|
bool BoschHelper::CreateDissCode(ea_t eaStartAddr, ea_t eaEndAddr)
|
|
{
|
|
msg("Creating disassembly from 0x%x through to 0x%x\n", eaStartAddr, eaEndAddr);
|
|
|
|
ea_t eaAddr, eaLenOfGeneratedCode;
|
|
int iCount, iReturns;
|
|
ushort uWord;
|
|
|
|
eaAddr = eaStartAddr;
|
|
eaLenOfGeneratedCode = 1;
|
|
iCount = iReturns = 1;
|
|
|
|
show_wait_box("Creating disassembly...");
|
|
for (eaAddr; eaAddr<eaEndAddr; eaAddr += eaLenOfGeneratedCode)
|
|
{
|
|
if ((eaAddr % 0x1000) == 0)
|
|
{
|
|
showAddr(eaAddr);
|
|
if (wasBreak())
|
|
break;
|
|
}
|
|
|
|
//guard against disassembling 0xffff or 0x0000 pairs
|
|
uWord = static_cast<ushort>(get_16bit(eaAddr));//read the word at the current location
|
|
|
|
if(uWord == 0xffff)
|
|
{
|
|
// msg("0xffff read at 0x%x\n", eaAddr);
|
|
doWord(eaAddr, 4);//Convert to data word
|
|
eaAddr+=1;//skip these bytes
|
|
}
|
|
else if(uWord == 0x0000)
|
|
{
|
|
// msg("0x0000 read at 0x%x\n", eaAddr);
|
|
doWord(eaAddr, 4);//Convert to data word
|
|
eaAddr+=1;//skip these bytes
|
|
}
|
|
else if(uWord == 0x8000)
|
|
{
|
|
// msg("0x8000 read at 0x%x\n", eaAddr);
|
|
doWord(eaAddr, 4);//Convert to data word
|
|
eaAddr+=1;//skip these bytes
|
|
}
|
|
else
|
|
{
|
|
//attempt to disassemble the next code
|
|
eaLenOfGeneratedCode = create_insn(eaAddr);//create the disassembled code and return the length of it
|
|
//msg("Code created at 0x%X\n", eaAddr);
|
|
if(eaLenOfGeneratedCode == 0)
|
|
{//guard against nothing happening
|
|
eaLenOfGeneratedCode++;
|
|
}
|
|
else if(iCount >= 0x200)
|
|
{
|
|
iCount=0;
|
|
msg(".");
|
|
}
|
|
else if(iReturns >= 0x4000)
|
|
{
|
|
iReturns=0;
|
|
msg("\n");
|
|
}
|
|
}
|
|
}
|
|
msg("\n");
|
|
hide_wait_box();
|
|
|
|
msg("Looking through code to make subroutines....\n");
|
|
//
|
|
// Look for subroutines within the code
|
|
//
|
|
|
|
eaAddr = eaStartAddr;
|
|
eaLenOfGeneratedCode = 1;
|
|
iCount = iReturns = 1;
|
|
|
|
// Instructions we know that subroutines don't start with.
|
|
int instrs[] = { C166_jmps, C166_jmpr, C166_ret, C166_reti, C166_retp, C166_rets, C166_rol, C166_add, C166_shr, C166_xor, C166_xorb, 0 };
|
|
char mnem[MAXSTR];
|
|
const char *res;
|
|
bool bFound;
|
|
|
|
show_wait_box("Making subroutines...");
|
|
for (eaAddr; eaAddr<eaEndAddr;)
|
|
{
|
|
if ((eaAddr % 0x100) == 0)
|
|
{
|
|
showAddr(eaAddr);
|
|
if (wasBreak())
|
|
break;
|
|
}
|
|
|
|
//Create a function if possible but ignore certain instructions
|
|
//because we know functions will not start with them
|
|
bFound = false;
|
|
|
|
//Get the mnemonic at this address
|
|
res = ua_mnem(eaAddr, mnem, sizeof(mnem)-1);
|
|
|
|
// Check the mnemonic of this address against all
|
|
// mnemonics we're interested in.
|
|
for (int i = 0; instrs[i] != 0; i++)
|
|
{
|
|
if (cmd.itype == instrs[i])
|
|
{
|
|
bFound = true;
|
|
}
|
|
}
|
|
|
|
if(!bFound)
|
|
{
|
|
if(add_func(eaAddr, BADADDR))
|
|
{
|
|
msg("Function created at %x\n", eaAddr);
|
|
func_t *func = get_func(eaAddr);
|
|
if (func != NULL)
|
|
{
|
|
eaAddr += (func->endEA - func->startEA);
|
|
}
|
|
else
|
|
{
|
|
eaAddr++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
eaAddr++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
eaAddr++;
|
|
}
|
|
}
|
|
hide_wait_box();
|
|
return true;
|
|
}
|
|
|
|
// Loops through the binary and searches for where DTC flags are being set.
|
|
bool BoschHelper::EnumDTCflags(ea_t eaStartAddr, ea_t eaEndAddr)
|
|
{
|
|
msg("Searching for DTC setting flags from 0x%x through to 0x%x\n", eaStartAddr, eaEndAddr);
|
|
|
|
// Instructions we know that DTC setting is done by.
|
|
char mnem[MAXSTR];
|
|
const char *res;
|
|
// uval_t uvalOp1Value, uvalOp2Value;
|
|
|
|
ea_t eaAddr;
|
|
|
|
eaAddr = eaStartAddr;// sets the start
|
|
|
|
show_wait_box("Searching for DTCs...");
|
|
for (eaAddr; eaAddr<eaEndAddr;)
|
|
{
|
|
if ((eaAddr % 0x100) == 0)
|
|
{
|
|
showAddr(eaAddr);
|
|
if (wasBreak())
|
|
break;
|
|
}
|
|
|
|
// Get the flags for this address
|
|
flags_t flags = getFlags(eaAddr);
|
|
|
|
// Only look at the address if it's a head byte, i.e.
|
|
// the start of an instruction and is code.
|
|
if (isHead(flags) && isCode(flags))
|
|
{
|
|
//char mnem[MAXSTR];
|
|
|
|
//Get the mnemonic at this address
|
|
res = ua_mnem(eaAddr, mnem, sizeof(mnem)-1);
|
|
// Check the mnemonic of this address against all
|
|
// mnemonics we're interested in.
|
|
|
|
if(cmd.itype == C166_bfldh)//We've found the instruction we're interested in.
|
|
{
|
|
msg("bfldh found at 0x%x\n", eaAddr);
|
|
|
|
//we've found the instruction we're interested in.
|
|
//get_operand_immvals(eaAddr, 1, &uvalOp1Value);
|
|
//get_operand_immvals(eaAddr, 2, &uvalOp2Value);
|
|
|
|
//msg("Instruction Len 0x%x : Op1 Value 0x%x : Op2 Value 0x%x\n", cmd.size, uvalOp1Value, uvalOp2Value);
|
|
|
|
op_enum(eaAddr, 1, get_enum("DTCHBit"), NULL);
|
|
|
|
eaAddr+= cmd.size;//next instruction
|
|
}
|
|
else if(cmd.itype == C166_bfldl)//We've found the instruction we're interested in.
|
|
{
|
|
msg("bfldl found at 0x%x\n", eaAddr);
|
|
|
|
//we've found the instruction we're interested in.
|
|
//get_operand_immvals(eaAddr, 1, &uvalOp1Value);
|
|
//get_operand_immvals(eaAddr, 2, &uvalOp2Value);
|
|
|
|
op_enum(eaAddr, 1, get_enum("DTCLBit"), NULL);
|
|
|
|
eaAddr+= cmd.size;//next instruction
|
|
}
|
|
else
|
|
eaAddr++;
|
|
}
|
|
else
|
|
eaAddr++;
|
|
}
|
|
hide_wait_box();
|
|
return 1;
|
|
}
|
|
|
|
// Sets the default register values on the C16x CPU
|
|
bool BoschHelper::SetC16xRegs(const char *szRegName, sel_t value)
|
|
{
|
|
int iReg;
|
|
|
|
iReg = str2reg(szRegName);
|
|
msg("Setting register %s, number %i to %x", szRegName, iReg, value);
|
|
if (set_default_segreg_value(nullptr, iReg, value))
|
|
msg(" successful.\n");
|
|
else
|
|
{
|
|
msg(" failed.\n");
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Creates a Bosch segment and default registers
|
|
bool BoschHelper::CreateC16xSmallBoschSegments(ea_t eaStartAddr, ea_t eaEndAddr, char* cName, const char *sclass, sel_t dpp0, sel_t dpp1, sel_t dpp2, sel_t dpp3)
|
|
{
|
|
char cBuf[20];
|
|
ea_t eaParagraph;
|
|
|
|
msg("\nBoschHelper::CreateC16xSmallBoschSegments Started\n");
|
|
// msg("Deleting Segments\n");
|
|
// del_segm(eaStartAddr, SEGDEL_KEEP);
|
|
::qsnprintf(cBuf, 17, "%s", cName);
|
|
eaParagraph = eaStartAddr >> 4;// divide by 16
|
|
msg("Creating segment at para %x, start address %x, end address %x, name %s, selector 0x%x\n", eaParagraph, eaStartAddr, eaEndAddr, cBuf, mSelector);
|
|
set_selector(mSelector, eaParagraph);
|
|
// set_selector(mSelector, 0);
|
|
mSelector++;
|
|
msg("Adding new segments\n");
|
|
add_segm(eaParagraph, eaStartAddr, eaEndAddr, cBuf, sclass);
|
|
|
|
//Set the default register values for this segment
|
|
msg("Setting DPPs\n");
|
|
SetC16xRegs("dpp0", dpp0);
|
|
SetC16xRegs("dpp1", dpp1);
|
|
SetC16xRegs("dpp2", dpp2);
|
|
SetC16xRegs("dpp3", dpp3);
|
|
msg("BoschHelper::CreateC16xSmallBoschSegments Finished\n");
|
|
return 1;
|
|
}
|
|
|
|
// Creates the correct Bosch segments and default registers
|
|
bool BoschHelper::CreateC16xBoschSegments(ea_t eaParagraph, unsigned int iNumSegsToCreate, const char *sclass, sel_t dpp0, sel_t dpp1, sel_t dpp2, sel_t dpp3)
|
|
{
|
|
sel_t selSelector = 0;
|
|
ea_t eaStartAddr, eaEndAddr;
|
|
int iDPPNum;
|
|
char cBuf[20];
|
|
|
|
msg("\nBoschHelper::CreateC16xBoschSegments Started\n");
|
|
for(selSelector; selSelector<iNumSegsToCreate; selSelector++)
|
|
{
|
|
eaStartAddr = (eaParagraph * 0x10) + (selSelector * 0x4000);
|
|
eaEndAddr = eaStartAddr + 0x4000;
|
|
iDPPNum = eaStartAddr / 0x4000;//gets the dpp equivalent for the segment label
|
|
qsnprintf(cBuf, 17, "Seg0x%x@%x", iDPPNum, eaStartAddr);
|
|
msg("Creating segment at para %x, start address %x, end address %x, name %s, selector 0x%x\n", eaParagraph, eaStartAddr, eaEndAddr, cBuf, mSelector);
|
|
set_selector(mSelector, eaParagraph);
|
|
// set_selector(mSelector, 0);
|
|
mSelector++;
|
|
add_segm(eaParagraph, eaStartAddr, eaEndAddr, cBuf, sclass);
|
|
|
|
//Set the default register values for this segment
|
|
msg("Setting DPPs\n");
|
|
SetC16xRegs("dpp0", dpp0);
|
|
SetC16xRegs("dpp1", dpp1);
|
|
SetC16xRegs("dpp2", dpp2);
|
|
SetC16xRegs("dpp3", dpp3);
|
|
}
|
|
msg("BoschHelper::CreateC16xBoschSegments Finished\n");
|
|
return 1;
|
|
}
|
|
|
|
// Loops through the binary and tries to make code offsets from arrays
|
|
// e.g. movb [r5+0E0A4h], rl4 = movb [r5+word_E0A4], rl4
|
|
bool BoschHelper::FindAndCreateArrayOffsets(ea_t eaStartAddr, ea_t eaEndAddr)
|
|
{
|
|
msg("Finding array offsets and trying to create them from 0x%x through to 0x%x\n", eaStartAddr, eaEndAddr);
|
|
|
|
ea_t eaAddr, eaLenOfGeneratedCode;
|
|
int iCount, iReturns;
|
|
|
|
//
|
|
// Look for known function that will contain offsets within the code
|
|
//
|
|
|
|
eaAddr = eaStartAddr;
|
|
eaLenOfGeneratedCode = 1;
|
|
iCount = iReturns = 1;
|
|
|
|
// Instructions we know that contain arrays.
|
|
int instrs[] = { C166_mov, C166_movb, 0 };
|
|
char mnem[MAXSTR];
|
|
const char *res;
|
|
bool bFound;
|
|
|
|
show_wait_box("Searching for array offsets...");
|
|
|
|
for (eaAddr; eaAddr<eaEndAddr;)
|
|
{
|
|
//Find instructions we know will have offsets in them
|
|
bFound = 0;
|
|
|
|
if ((eaAddr % 0x100) == 0)
|
|
{
|
|
showAddr(eaAddr);
|
|
if (wasBreak())
|
|
break;
|
|
}
|
|
|
|
//Get the flags for this address
|
|
flags_t flags = getFlags(eaAddr);
|
|
|
|
//Only look at the address if it's a head byte
|
|
//i.e. the start of an instruction and its code
|
|
if(isHead(flags) && isCode(flags))
|
|
{
|
|
//Get the mnemonic at this address
|
|
res = ua_mnem(eaAddr, mnem, sizeof(mnem)-1);
|
|
// Check the mnemonic of this address against all
|
|
// mnemonics we're interested in.
|
|
for (int i = 0; instrs[i] != 0; i++)
|
|
{
|
|
if (cmd.itype == instrs[i])
|
|
{
|
|
bFound = 1;
|
|
}
|
|
}
|
|
//We have an instruction we're interested in
|
|
if(bFound)
|
|
{
|
|
//check the type of mnemonic.
|
|
/* msg("Instruction mnemonic at 0x%x :->\n", eaAddr);
|
|
msg(" Op0: n = %d type = %d reg = %d value = %a addr = %a\n",
|
|
cmd.Operands[0].n,
|
|
cmd.Operands[0].type,
|
|
cmd.Operands[0].reg,
|
|
cmd.Operands[0].value,
|
|
cmd.Operands[0].addr);
|
|
msg(" Op1: n = %d type = %d reg = %d value = %a addr = %a\n",
|
|
cmd.Operands[1].n,
|
|
cmd.Operands[1].type,
|
|
cmd.Operands[1].reg,
|
|
cmd.Operands[1].value,
|
|
cmd.Operands[1].addr);
|
|
*/
|
|
// Is the instruction Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr?
|
|
// If so, then these need converting into offset addresses
|
|
if(cmd.Operands[0].type == o_displ)
|
|
{
|
|
//r0 is a special register and should not be offsetted
|
|
if(cmd.Operands[0].reg!= 0)
|
|
if(cmd.Operands[0].addr >= 0x00ff)
|
|
MakeC166Offset(eaAddr, 0);
|
|
}
|
|
else if(cmd.Operands[1].type == o_displ)
|
|
{
|
|
//r0 is a special register and should not be offsetted
|
|
if(cmd.Operands[1].reg!= 0)
|
|
if(cmd.Operands[1].addr >= 0x00ff)
|
|
MakeC166Offset(eaAddr, 1);
|
|
}
|
|
}
|
|
}
|
|
eaAddr++;
|
|
}
|
|
hide_wait_box();
|
|
return 1;
|
|
}
|
|
|
|
//Makes C166 offsets utilising the correct DPP value
|
|
// eaAddr = Address of the instruction
|
|
// nOp = Operand Number
|
|
void BoschHelper::MakeC166Offset(ea_t eaAddr, int nOp)
|
|
{
|
|
//Translate the address we get into a real address
|
|
int iReg;
|
|
ea_t eaDpp;
|
|
sel_t selSelector;
|
|
|
|
//Find out what DPP the address we've found lives in.
|
|
//The DPP selector is the top two bits
|
|
eaDpp = (cmd.Operands[1].addr & 0xc000) >> 14;
|
|
if(eaDpp == 0)
|
|
{
|
|
iReg = str2reg("DPP0");
|
|
}
|
|
else if (eaDpp==1)
|
|
{
|
|
iReg = str2reg("DPP1");
|
|
}
|
|
else if (eaDpp==2)
|
|
{
|
|
iReg = str2reg("DPP2");
|
|
}
|
|
else
|
|
{
|
|
iReg = str2reg("DPP3");
|
|
}
|
|
//Get the value of the selected register
|
|
//Don't ask me why but the register needs to be multiplied by 16 to become the base
|
|
selSelector = get_segreg(eaAddr, iReg) << 4;
|
|
ea_t eaOffsetBase = get_offbase(eaAddr, nOp);//For information, not used
|
|
msg("**** At address 0x%x DPP number 0x%x for Register 0x%x, is 0x%x. Op is 0x%x. Offset base is 0x%x\n", eaAddr, eaDpp, iReg, selSelector, nOp, eaOffsetBase);
|
|
//Create the offset
|
|
if(op_offset(eaAddr, nOp, REF_OFF16, BADADDR, selSelector) == 0)
|
|
{
|
|
msg("op_offset failed\n");
|
|
}
|
|
}
|
|
|
|
// Loops through the binary and tries to make code offsets from implicit references
|
|
// e.g. movb [r5+0E0A4h], rl4 = movb [r5+word_E0A4], rl4
|
|
//mov r4, #0F9F6h ; Move Word <- Here's the address
|
|
//mov r5, #0 ; Move Word <- Here's the segment
|
|
//movbz r2, rl6 ; Move Byte Zero Extend
|
|
//shl r2, #1 ; Shift Left
|
|
//mov r3, #0 ; Move Word
|
|
//add r4, r2 ; Integer Addition
|
|
//addc r5, r3 ; Integer Addition with Carry
|
|
//exts r5, #1 ; Begin Extended Segment Sequence <- This requires a segment
|
|
//mov r12, [r4] ; Move Word with phrase <- This requires an address
|
|
bool BoschHelper::FindAndCreateImplicitOffsets(ea_t eaStartAddr, ea_t eaEndAddr)
|
|
{
|
|
msg("Finding implicit offsets and trying to create them from 0x%x through to 0x%x\n", eaStartAddr, eaEndAddr);
|
|
|
|
ea_t eaAddr, eaLenOfGeneratedCode;
|
|
int iCount, iReturns;
|
|
|
|
//
|
|
// Look for known function that will contain offsets within the code
|
|
//
|
|
|
|
eaAddr = eaStartAddr;
|
|
eaLenOfGeneratedCode = 1;
|
|
iCount = iReturns = 1;
|
|
|
|
// Instructions we know that contain addresses.
|
|
int instrs[] = { C166_mov, 0 };
|
|
char mnem[MAXSTR];
|
|
const char *res;
|
|
bool bFound;
|
|
|
|
show_wait_box("Searching for implicit offsets...");
|
|
|
|
for (eaAddr; eaAddr<eaEndAddr;)
|
|
{
|
|
//Find instructions we know will have offsets in them
|
|
bFound = 0;
|
|
|
|
if ((eaAddr % 0x100) == 0)
|
|
{
|
|
showAddr(eaAddr);
|
|
if (wasBreak())
|
|
break;
|
|
}
|
|
|
|
//Get the flags for this address
|
|
flags_t flags = getFlags(eaAddr);
|
|
|
|
//Only look at the address if it's a head byte
|
|
//i.e. the start of an instruction and its code
|
|
if(isHead(flags) && isCode(flags))
|
|
{
|
|
//Get the mnemonic at this address
|
|
res = ua_mnem(eaAddr, mnem, sizeof(mnem)-1);
|
|
// Check the mnemonic of this address against all
|
|
// mnemonics we're interested in.
|
|
for (int i = 0; instrs[i] != 0; i++)
|
|
{
|
|
if (cmd.itype == instrs[i])
|
|
{
|
|
bFound = 1;
|
|
}
|
|
}
|
|
//We have an instruction we're interested in
|
|
if(bFound)
|
|
{
|
|
//check the type of mnemonic.
|
|
msg("Instruction mnemonic at 0x%x :->\n", eaAddr);
|
|
msg(" Op0: n = %d type = %d reg = %d value = %a addr = %a\n",
|
|
cmd.Operands[0].n,
|
|
cmd.Operands[0].type,
|
|
cmd.Operands[0].reg,
|
|
cmd.Operands[0].value,
|
|
cmd.Operands[0].addr);
|
|
msg(" Op1: n = %d type = %d reg = %d value = %a addr = %a\n",
|
|
cmd.Operands[1].n,
|
|
cmd.Operands[1].type,
|
|
cmd.Operands[1].reg,
|
|
cmd.Operands[1].value,
|
|
cmd.Operands[1].addr);
|
|
|
|
// Is the instruction a Memory Ref [Base Reg + Index Reg] and not r0?
|
|
// If so, then we need to back track and see when it's loaded with an immediate
|
|
// Need to do this for cmd.Operands[0] and cmd.Operands[1]
|
|
// Also backtrack one instruction and see if there's a "exts"
|
|
if((cmd.Operands[1].type == o_phrase) & (cmd.Operands[1].reg != 0))
|
|
{
|
|
msg("We're at a phrase and need to look for where r%a was immediate loaded.\n", cmd.Operands[1].reg);
|
|
// We need to backtrack & find where this register was loaded immediate at op1
|
|
|
|
//r0 is a special register and should not be offsetted
|
|
// if(cmd.Operands[1].reg!= 0)
|
|
// if(cmd.Operands[1].addr >= 0x00ff)
|
|
// MakeC166Offset(eaAddr, 1);
|
|
}
|
|
}
|
|
}
|
|
eaAddr++;
|
|
}
|
|
hide_wait_box();
|
|
return 1;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Implementation
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//Automatically disassembles the code and tries to make subroutines
|
|
void BoschHelper::MakeDissCode(string sECU)
|
|
{
|
|
if(sECU == "bNewME711")
|
|
{
|
|
CreateDissCode(0x00000, 0xdfff);
|
|
CreateDissCode(0x10000, 0xcffff);
|
|
//CreateDissCode(0x800014, 0x803422);
|
|
CreateDissCode(0x800014, 0x8fffff);
|
|
//CreateDissCode(0x800014, 0x80ffff);
|
|
//RAM is @ 0x380000 - 0x383fff - size 0x4000
|
|
//Data is @0x8
|
|
CreateDissCode(0x81e28c, 0x81ea40);
|
|
}
|
|
else if (sECU == "ME761Astra")
|
|
{
|
|
CreateDissCode(0x0000, 0x3fff);
|
|
CreateDissCode(0x4000, 0x7fff);
|
|
CreateDissCode(0x10000, 0xaffff);
|
|
CreateDissCode(0xc0000, 0xcff00);
|
|
}
|
|
else
|
|
{
|
|
CreateDissCode(0x00000, 0x1ff);
|
|
CreateDissCode(0x700, 0x7fff);
|
|
CreateDissCode(0x800000, 0x810000);
|
|
CreateDissCode(0x830000, 0x8fff00);
|
|
}
|
|
}
|
|
|
|
//No longer used
|
|
//void BoschHelper::MakeSubroutines(void)
|
|
//{
|
|
// ea_t eaResult=0, eaLast=0;
|
|
//
|
|
// add_func(eaResult, BADADDR);
|
|
//
|
|
// while(eaResult != BADADDR)
|
|
// {
|
|
// eaResult = find_unknown(eaLast, SEARCH_DOWN);
|
|
// if(add_func(eaResult, BADADDR))
|
|
// msg("Function created at %x\n", eaResult);
|
|
//
|
|
// if( (eaResult > MAP_AREA_START) & (eaResult < MAP_AREA_FINISH) )
|
|
// {
|
|
// msg("Ignoring data - within MAP area\n");
|
|
// eaResult = MAP_AREA_FINISH;
|
|
// }
|
|
// if(eaResult == BADADDR)
|
|
// msg("End of Auto-Disassemble analysis loop\n");
|
|
//
|
|
// eaLast = eaResult;
|
|
// }
|
|
//
|
|
//}
|
|
|
|
//Makes the segments of the disassembly
|
|
//void BoschHelper::MakeSegments(BOOL bNewME711)
|
|
void BoschHelper::MakeSegments(string sECU)
|
|
{
|
|
//bool BoschHelper::CreateC16xBoschSegments(ea_t eaParagraph, unsigned int iNumSegsToCreate, const char *sclass, sel_t dpp0, sel_t dpp1, sel_t dpp2, sel_t dpp3)
|
|
if(sECU == "bNewME711")
|
|
{
|
|
//CreateC16xBoschSegments(0x0000, 4, "ABS", 0x0, 0x1, 2, 3);
|
|
CreateC16xSmallBoschSegments(0x0000, 0x8000, "MEM_EXT", "CODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
//SFR
|
|
CreateC16xSmallBoschSegments(0x8000, 0xE000, "MEM_EXT", "CODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xSmallBoschSegments(0xE000, 0xE800, "XRAM", "DATA", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xSmallBoschSegments(0xE800, 0xEf00, "RESERVED", "BSS", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xSmallBoschSegments(0xEf00, 0xf000, "CAN1", "DATA", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xSmallBoschSegments(0xf000, 0xf200, "E_SFR", "DATA", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xSmallBoschSegments(0xf200, 0xf600, "RESERVED", "BSS", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xSmallBoschSegments(0xf600, 0xfE00, "IRAM", "CODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xSmallBoschSegments(0xfe00, 0x10000, "SFR", "DATA", 0x23f, 0x3c, 0x0e0, 3);
|
|
|
|
//MPU ROM
|
|
CreateC16xBoschSegments(0x1000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0x2000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0x3000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0x4000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0x5000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0x6000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0x7000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0x8000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0x9000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0xa000, 4, "MPUCODE", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0xb000, 4, "DATA", 0x23f, 0x3c, 0x0e0, 3);
|
|
CreateC16xBoschSegments(0xc000, 4, "DATA", 0x23f, 0x3c, 0x0e0, 3);
|
|
|
|
//RAM
|
|
CreateC16xBoschSegments(0xe000, 4, "CODERAM", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0xf000, 4, "CODERAM", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x38000, 4, "DATARAM", 0x23f, 0x3c, 0xe0, 3);
|
|
|
|
//ROM
|
|
CreateC16xBoschSegments(0x80000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x81000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x82000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x83000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x84000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x85000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x86000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x87000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x88000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x89000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8a000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8b000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8c000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8d000, 4, "CODE", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8e000, 4, "DATA", 0x23f, 0x3c, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8f000, 4, "DATA", 0x23f, 0x3c, 0xe0, 3);
|
|
}
|
|
else if (sECU == "ME761Astra")
|
|
{
|
|
CreateC16xSmallBoschSegments(0x0000, 0x8000, "MEM_EXT", "CODE", 0x0, 0x1, 0x2, 0x3);
|
|
//SFR
|
|
CreateC16xSmallBoschSegments(0x8000, 0xE000, "MEM_EXT", "CODE", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xE000, 0xE800, "XRAM", "DATA", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xE800, 0xEf00, "RESERVED", "BSS", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xEf00, 0xf000, "CAN1", "DATA", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xf000, 0xf200, "E_SFR", "DATA", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xf200, 0xf600, "RESERVED", "BSS", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xf600, 0xfE00, "IRAM", "CODE", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xfe00, 0x10000, "SFR", "DATA", 0x0, 0x1, 0x2, 0x3);
|
|
//RAM
|
|
CreateC16xBoschSegments(0xf000, 4, "DATA" , 0x2c, 0x2d, 0x3c, 3);
|
|
//ROM
|
|
CreateC16xBoschSegments(0x1000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0x2000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0x3000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0x4000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0x5000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0x6000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0x7000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0x8000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0x9000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0xa000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0xb000, 4, "DATA", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0xc000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
CreateC16xBoschSegments(0xd000, 4, "CODE", 0x2c, 0x2d, 0x3c, 3);
|
|
}
|
|
else
|
|
{
|
|
CreateC16xSmallBoschSegments(0x0000, 0x8000, "MEM_EXT", "CODE", 0x0, 0x1, 0x2, 0x3);
|
|
//SFR
|
|
CreateC16xSmallBoschSegments(0x8000, 0xE000, "MEM_EXT", "CODE", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xE000, 0xE800, "XRAM", "DATA", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xE800, 0xEf00, "RESERVED", "BSS", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xEf00, 0xf000, "CAN1", "DATA", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xf000, 0xf200, "E_SFR", "DATA", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xf200, 0xf600, "RESERVED", "BSS", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xf600, 0xfE00, "IRAM", "CODE", 0x0, 0x1, 0x2, 0x3);
|
|
CreateC16xSmallBoschSegments(0xfe00, 0x10000, "SFR", "DATA", 0x0, 0x1, 0x2, 0x3);
|
|
//RAM
|
|
CreateC16xBoschSegments(0x38000, 2, "DATA" , 0x204, 0x205, 0xe0, 3);
|
|
//ROM
|
|
CreateC16xBoschSegments(0x80000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x81000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x82000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x83000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x84000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x85000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x86000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x87000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x88000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x89000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8a000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8b000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8c000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8d000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8e000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
CreateC16xBoschSegments(0x8f000, 4, "CODE", 0x204, 0x205, 0xe0, 3);
|
|
}
|
|
}
|
|
|
|
//Looks for signatures of commonly known functions and set their name.
|
|
//Test routine!
|
|
//void BoschHelper::SearchForFuncSigs(BOOL bNewME711)
|
|
//{
|
|
// //No longer used
|
|
// const uchar test[]={0xfa, 0x82, 0xd8, 0x00, 0xfa, 0xff, 0xDC, 0x00};
|
|
// ea_t eaFound;
|
|
//
|
|
// eaFound = FindBinaryWithDontCare((uchar*)test, 8, 0x800000, 0x80ffff);
|
|
// if(eaFound != BADADDR)
|
|
// msg("Found Sig at 0x%x\n", eaFound);
|
|
// else
|
|
// msg("Sig not found\n");
|
|
//}
|
|
|
|
//Looks for Bosch DTC setting fields.
|
|
void BoschHelper::SearchForDTCFlagSetting(string sECU)
|
|
{
|
|
//Create the enum constants first
|
|
enum_t enumtID;
|
|
|
|
//The DTC enum for low bits
|
|
enumtID = add_enum(BADADDR, "DTCLBit", 0x1100000);//Create the enum
|
|
set_enum_bf(enumtID, 1);//Set the enum to a bitfield
|
|
//Now fill the enum structure
|
|
add_enum_member(enumtID,"DTCBit_L0", 0x1, 0x1);
|
|
add_enum_member(enumtID,"DTCBit_L1", 0x2, 0x2);
|
|
add_enum_member(enumtID,"DTCBit_L2", 0x4, 0x4);
|
|
add_enum_member(enumtID,"DTCBit_L3", 0x8, 0x8);
|
|
add_enum_member(enumtID,"DTCBit_L4", 0x10, 0x10);
|
|
add_enum_member(enumtID,"DTCBit_L5", 0x20, 0x20);
|
|
add_enum_member(enumtID,"DTCBit_L6", 0x40, 0x40);
|
|
add_enum_member(enumtID,"DTCBit_L7", 0x80, 0x80);
|
|
|
|
//The DTC enum for high bits
|
|
enumtID = add_enum(BADADDR, "DTCHBit", 0x1100000);//Create the enum
|
|
set_enum_bf(enumtID, 1);//Set the enum to a bitfield
|
|
//Now fill the enum structure
|
|
add_enum_member(enumtID,"DTCFieldA_H0", 0x1, 0x1);
|
|
set_enum_cmt(get_const(enumtID, 0x1, NULL, 0x1),"Select DTC Group A",1);
|
|
//set_enum_cmt(get_const(enumtID, 0x1, NULL, 0x1), "Select DTC Group A", 1);
|
|
add_enum_member(enumtID, "DTCFieldB_H1", 0x2, 0x2);
|
|
set_enum_cmt(get_const(enumtID, 0x2, NULL, 0x2),"Select DTC Group B",1);
|
|
add_enum_member(enumtID,"DTCFieldC_H2", 0x4, 0x4);
|
|
set_enum_cmt(get_const(enumtID, 0x4, NULL, 0x4),"Select DTC Group C",1);
|
|
add_enum_member(enumtID,"DTCFieldD_H3", 0x8, 0x8);
|
|
set_enum_cmt(get_const(enumtID, 0x8, NULL, 0x8),"Select DTC Group D",1);
|
|
add_enum_member(enumtID,"DTCBit_H4", 0x10, 0x10);
|
|
add_enum_member(enumtID,"DTCBit_H5", 0x20, 0x20);
|
|
add_enum_member(enumtID,"DTCBit_H6", 0x40, 0x40);
|
|
add_enum_member(enumtID,"DTCBit_H7", 0x80, 0x80);
|
|
|
|
//Search the disassembly for enum flag setting
|
|
if(sECU == "bNewME711")
|
|
{
|
|
EnumDTCflags(0x00000, 0xffffff);
|
|
}
|
|
else if (sECU == "ME761Astra")
|
|
{
|
|
EnumDTCflags(0x10000, 0xff000);
|
|
}
|
|
else
|
|
{
|
|
EnumDTCflags(0x820000, 0x8ff000);
|
|
}
|
|
}
|
|
|
|
//Looks for specific binary patterns and then makes a subroutine and comments it
|
|
void BoschHelper::SearchForFuncSigsAndThenCmt(string sECU)
|
|
{
|
|
if (sECU == "ME761Astra")
|
|
{
|
|
msg("*** ME761Astra 1st pass\n");
|
|
functionsigsclass.FindFuncSigsAndComment(0x0, 0x3fff);
|
|
msg("*** ME761Astra 2nd pass\n");
|
|
functionsigsclass.FindFuncSigsAndComment(0x4000, 0x7fff);
|
|
msg("*** ME761Astra 3rd pass\n");
|
|
functionsigsclass.FindFuncSigsAndComment(0x8000, 0xdfff);
|
|
msg("*** ME761Astra 4th pass\n");
|
|
functionsigsclass.FindFuncSigsAndComment(0x10000, 0xdffff);
|
|
}
|
|
else
|
|
{
|
|
msg("Everything Else\n");
|
|
functionsigsclass.FindFuncSigsAndComment(0x0, 0xffffff);
|
|
}
|
|
|
|
// FindFuncSigsAndComment(0x8de4b4, 0x8de566);
|
|
}
|
|
|
|
//Looks for instructions that will probably contain an offset. When found it creates them.
|
|
void BoschHelper::SearchForArrayOffsetsAndThenCreate(string sECU)
|
|
{
|
|
if(sECU == "bNewME711")
|
|
{
|
|
FindAndCreateArrayOffsets(0x0, 0xffffff);
|
|
}
|
|
else if (sECU == "ME761Astra")
|
|
{
|
|
FindAndCreateArrayOffsets(0x0, 0x3fff);
|
|
FindAndCreateArrayOffsets(0x4000, 0x7fff);
|
|
FindAndCreateArrayOffsets(0x8000, 0xdfff);
|
|
FindAndCreateArrayOffsets(0x10000, 0xdffff);
|
|
}
|
|
else
|
|
{
|
|
FindAndCreateArrayOffsets(0x0, 0x8fffff);
|
|
}
|
|
// FindAndCreateImplicitOffsets(0x8694b4, 0x8694ce);
|
|
}
|