1
0
Fork 0

GUI: fixed BeaTokenizer + fixed CPUSideBar crash + added token to Instruction_t

This commit is contained in:
Mr. eXoDia 2014-06-12 22:34:52 +02:00
parent 4fb85f0c80
commit 3350d26f9d
6 changed files with 244 additions and 66 deletions

View File

@ -92,7 +92,6 @@ public:
signals:
void selectionChanged(int_t parVA);
void repainted();
void disassembledAt(int_t parVA, int_t parCIP, bool history, int_t newTableOffset);
public slots:

View File

@ -1,20 +1,18 @@
#include "BeaTokenizer.h"
#include "Configuration.h"
//variables
QMap<BeaTokenizer::BeaTokenType, BeaTokenizer::BeaTokenColor> BeaTokenizer::colorNamesMap;
QStringList BeaTokenizer::segmentNames;
QMap<int, QString> BeaTokenizer::memSizeNames;
QMap<int, QMap<ARGUMENTS_TYPE, QString>> BeaTokenizer::registerMap;
//functions
BeaTokenizer::BeaTokenizer()
{
}
//djb2 (http://www.cse.yorku.ca/~oz/hash.html)
unsigned long BeaTokenizer::BeaHashInstruction(const DISASM* disasm)
{
const char* str=disasm->CompleteInstr;
unsigned long hash=5381;
int c;
while(c=*str++)
hash=((hash<<5)+hash)+c; /*hash*33+c*/
return hash;
}
void BeaTokenizer::AddToken(BeaInstructionToken* instr, const BeaTokenType type, const QString text, const BeaTokenValue* value)
{
BeaSingleToken token;
@ -91,42 +89,12 @@ QString BeaTokenizer::PrintValue(const BeaTokenValue* value)
QString BeaTokenizer::RegisterToString(int size, int reg)
{
ARGUMENTS_TYPE regValue=(ARGUMENTS_TYPE)(reg&0xFFFF);
QMap<ARGUMENTS_TYPE, int> registerValueMap;
registerValueMap.insert(REG0, 0);
registerValueMap.insert(REG1, 1);
registerValueMap.insert(REG2, 2);
registerValueMap.insert(REG3, 3);
registerValueMap.insert(REG4, 4);
registerValueMap.insert(REG5, 5);
registerValueMap.insert(REG6, 6);
registerValueMap.insert(REG7, 7);
registerValueMap.insert(REG8, 8);
registerValueMap.insert(REG9, 9);
registerValueMap.insert(REG10, 10);
registerValueMap.insert(REG11, 11);
registerValueMap.insert(REG12, 12);
registerValueMap.insert(REG13, 13);
registerValueMap.insert(REG14, 14);
registerValueMap.insert(REG15, 15);
if(!registerValueMap.contains(regValue)) //not a register
return "UNKNOWN_REGISTER";
QMap<int, const char**> registerMap;
#ifdef _WIN64
const char Registers8Bits64[16][8] = {"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"};
registerMap.insert(8, (const char**)Registers8Bits64);
const char Registers64Bits[16][4] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"};
registerMap.insert(64, (const char**)Registers64Bits);
#else //x86
const char Registers8Bits32[8][4] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
registerMap.insert(8, (const char**)Registers8Bits32);
#endif //_WIN64
const char Registers16Bits[16][8] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"};
registerMap.insert(16, (const char**)Registers16Bits);
const char Registers32Bits[16][8] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"};
registerMap.insert(32, (const char**)Registers32Bits);
if(!registerMap.contains(size)) //invalid size
return "UNKNOWN_REGISTER";
return registerMap[size][regValue];
QMap<ARGUMENTS_TYPE, QString>* currentMap=&registerMap.find(size).value();
if(!currentMap->contains(regValue))
return "UNKNOWN_REGISTER";
return currentMap->find(regValue).value();
}
void BeaTokenizer::Argument(BeaInstructionToken* instr, const DISASM* disasm, const ARGTYPE* arg, bool* hadarg)
@ -158,20 +126,11 @@ void BeaTokenizer::Argument(BeaInstructionToken* instr, const DISASM* disasm, co
}
else if((arg->ArgType&MEMORY_TYPE)==MEMORY_TYPE) //memory argument
{
//initialization
QStringList segmentNames;
segmentNames<<""<<"es"<<"ds"<<"fs"<<"gs"<<"cs"<<"ss";
QMap<int, QString> memSizeNames; //lookup table for memory sizes
memSizeNames.insert(8, "byte");
memSizeNames.insert(16, "word");
memSizeNames.insert(32, "dword");
memSizeNames.insert(64, "qword");
memSizeNames.insert(80, "tword");
memSizeNames.insert(128, "dqword");
memSizeNames.insert(256, "yword");
memSizeNames.insert(512, "zword");
//#size ptr #segment:[#BaseRegister + #IndexRegister*#Scale +/- #Displacement]
AddToken(instr, TokenMemorySize, memSizeNames.find(arg->ArgSize).value(), 0);
if(memSizeNames.contains(arg->ArgSize))
AddToken(instr, TokenMemorySize, memSizeNames.find(arg->ArgSize).value(), 0);
else
AddToken(instr, TokenMemorySize, "???", 0);
AddToken(instr, TokenRequiredSpace, " ", 0);
AddToken(instr, TokenMemoryText, "ptr", 0);
AddToken(instr, TokenRequiredSpace, " ", 0);
@ -238,10 +197,173 @@ void BeaTokenizer::Argument(BeaInstructionToken* instr, const DISASM* disasm, co
AddToken(instr, TokenGeneral, argMnemonic, 0);
}
void BeaTokenizer::BeaTokenizeInstruction(BeaInstructionToken* instr, const DISASM* disasm)
void BeaTokenizer::AddColorName(BeaTokenType type, QString color, QString backgroundColor)
{
BeaTokenColor tokenColor;
tokenColor.color=color;
tokenColor.backgroundColor=color;
colorNamesMap.insert(type, tokenColor);
}
void BeaTokenizer::Init()
{
registerMap.clear();
#ifdef _WIN64
QMap<ARGUMENTS_TYPE, QString> Registers8Bits64;
Registers8Bits64.insert(REG0, "al");
Registers8Bits64.insert(REG1, "cl");
Registers8Bits64.insert(REG2, "dl");
Registers8Bits64.insert(REG3, "bl");
Registers8Bits64.insert(REG4, "spl");
Registers8Bits64.insert(REG5, "bpl");
Registers8Bits64.insert(REG6, "sil");
Registers8Bits64.insert(REG7, "dil");
Registers8Bits64.insert(REG8, "r8b");
Registers8Bits64.insert(REG9, "r9b");
Registers8Bits64.insert(REG10, "r10b");
Registers8Bits64.insert(REG11, "r11b");
Registers8Bits64.insert(REG12, "r12b");
Registers8Bits64.insert(REG13, "r13b");
Registers8Bits64.insert(REG14, "r14b");
Registers8Bits64.insert(REG15, "r15b");
registerMap.insert(8, Registers8Bits64);
QMap<ARGUMENTS_TYPE, QString> Registers64Bits;
Registers64Bits.insert(REG0, "rax");
Registers64Bits.insert(REG1, "rcx");
Registers64Bits.insert(REG2, "rdx");
Registers64Bits.insert(REG3, "rbx");
Registers64Bits.insert(REG4, "rsp");
Registers64Bits.insert(REG5, "rbp");
Registers64Bits.insert(REG6, "rsi");
Registers64Bits.insert(REG7, "rdi");
Registers64Bits.insert(REG8, "r8");
Registers64Bits.insert(REG9, "r9");
Registers64Bits.insert(REG10, "r10");
Registers64Bits.insert(REG11, "r11");
Registers64Bits.insert(REG12, "r12");
Registers64Bits.insert(REG13, "r13");
Registers64Bits.insert(REG14, "r14");
Registers64Bits.insert(REG15, "r15");
registerMap.insert(64, Registers64Bits);
#else //x86
QMap<ARGUMENTS_TYPE, QString> Registers8Bits32;
Registers8Bits32.insert(REG0, "al");
Registers8Bits32.insert(REG1, "cl");
Registers8Bits32.insert(REG2, "dl");
Registers8Bits32.insert(REG3, "bl");
Registers8Bits32.insert(REG4, "ah");
Registers8Bits32.insert(REG5, "ch");
Registers8Bits32.insert(REG6, "dh");
Registers8Bits32.insert(REG7, "bh");
registerMap.insert(8, Registers8Bits32);
#endif //_WIN64
QMap<ARGUMENTS_TYPE, QString> Registers16Bits;
Registers16Bits.insert(REG0, "ax");
Registers16Bits.insert(REG1, "cx");
Registers16Bits.insert(REG2, "dx");
Registers16Bits.insert(REG3, "bx");
Registers16Bits.insert(REG4, "sp");
Registers16Bits.insert(REG5, "bp");
Registers16Bits.insert(REG6, "si");
Registers16Bits.insert(REG7, "di");
#ifdef _WIN64
Registers16Bits.insert(REG8, "r8w");
Registers16Bits.insert(REG9, "r9w");
Registers16Bits.insert(REG10, "r10w");
Registers16Bits.insert(REG11, "r11w");
Registers16Bits.insert(REG12, "r12w");
Registers16Bits.insert(REG13, "r13w");
Registers16Bits.insert(REG14, "r14w");
Registers16Bits.insert(REG15, "r15w");
#endif //_WIN64
registerMap.insert(16, Registers16Bits);
QMap<ARGUMENTS_TYPE, QString> Registers32Bits;
Registers32Bits.insert(REG0, "eax");
Registers32Bits.insert(REG1, "ecx");
Registers32Bits.insert(REG2, "edx");
Registers32Bits.insert(REG3, "ebx");
Registers32Bits.insert(REG4, "esp");
Registers32Bits.insert(REG5, "ebp");
Registers32Bits.insert(REG6, "esi");
Registers32Bits.insert(REG7, "edi");
#ifdef _WIN64
Registers32Bits.insert(REG8, "r8d");
Registers32Bits.insert(REG9, "r9d");
Registers32Bits.insert(REG10, "r10d");
Registers32Bits.insert(REG11, "r11d");
Registers32Bits.insert(REG12, "r12d");
Registers32Bits.insert(REG13, "r13d");
Registers32Bits.insert(REG14, "r14d");
Registers32Bits.insert(REG15, "r15d");
#endif //_WIN64
registerMap.insert(32, Registers32Bits);
//memory parser
memSizeNames.clear();
memSizeNames.insert(8, "byte");
memSizeNames.insert(16, "word");
memSizeNames.insert(32, "dword");
memSizeNames.insert(64, "qword");
memSizeNames.insert(80, "tword");
memSizeNames.insert(128, "dqword");
memSizeNames.insert(256, "yword");
memSizeNames.insert(512, "zword");
segmentNames.clear();
segmentNames<<"??"<<"es"<<"ds"<<"fs"<<"gs"<<"cs"<<"ss";
//color names map
colorNamesMap.clear();
//filling
AddColorName(TokenComma, "", "");
AddColorName(TokenComma, "", "");
AddColorName(TokenRequiredSpace, "", "");
AddColorName(TokenOptionalSpace, "", "");
AddColorName(TokenMemorySpace, "", "");
//general instruction parts
AddColorName(TokenPrefix, "", "");
AddColorName(TokenGeneral, "", "");
AddColorName(TokenCodeDest, "", ""); //jump/call destinations
AddColorName(TokenImmediat, "", "");
//mnemonics
AddColorName(TokenMnemonicNormal, "", "");
AddColorName(TokenMnemonicPushPop, "", "");
AddColorName(TokenMnemonicCallRet, "", "");
AddColorName(TokenMnemonicCondJump, "", "");
AddColorName(TokenMnemonicUncondJump, "", "");
AddColorName(TokenMnemonicNop, "", "");
//memory
AddColorName(TokenMemorySize, "", "");
AddColorName(TokenMemoryText, "", "");
AddColorName(TokenMemorySegment, "", "");
AddColorName(TokenMemoryBrackets, "", "");
AddColorName(TokenMemoryBaseRegister, "", "");
AddColorName(TokenMemoryIndexRegister, "", "");
AddColorName(TokenMemoryScale, "", "");
AddColorName(TokenMemoryDisplacement, "", "");
AddColorName(TokenMemoryPlusMinus, "", "");
//registers
AddColorName(TokenGeneralRegister, "", "");
AddColorName(TokenFpuRegister, "", "");
AddColorName(TokenMmxRegister, "", "");
AddColorName(TokenSseRegister, "", "");
}
//djb2 (http://www.cse.yorku.ca/~oz/hash.html)
unsigned long BeaTokenizer::HashInstruction(const DISASM* disasm)
{
const char* str=disasm->CompleteInstr;
unsigned long hash=5381;
int c;
while(c=*str++)
hash=((hash<<5)+hash)+c; /*hash*33+c*/
return hash;
}
void BeaTokenizer::TokenizeInstruction(BeaInstructionToken* instr, const DISASM* disasm)
{
//initialization
instr->hash=BeaHashInstruction(disasm); //hash instruction
instr->hash=HashInstruction(disasm); //hash instruction
instr->tokens.clear(); //clear token list
//base instruction
@ -254,3 +376,37 @@ void BeaTokenizer::BeaTokenizeInstruction(BeaInstructionToken* instr, const DISA
Argument(instr, disasm, &disasm->Argument2, &hadarg);
Argument(instr, disasm, &disasm->Argument3, &hadarg);
}
void BeaTokenizer::TokenToRichText(const BeaInstructionToken* instr, QList<RichTextPainter::CustomRichText_t>* richTextList)
{
for(int i=0; i<instr->tokens.size(); i++)
{
BeaSingleToken token=instr->tokens.at(i);
RichTextPainter::CustomRichText_t richText;
richText.flags=FlagNone;
richText.text=token.text;
if(colorNamesMap.contains(token.type))
{
BeaTokenColor tokenColor=colorNamesMap[token.type];
QString color=tokenColor.color;
QString backgroundColor=tokenColor.backgroundColor;
if(color.length() && backgroundColor.length())
{
richText.flags=FlagAll;
richText.textColor=ConfigColor(color);
richText.textBackground=ConfigColor(backgroundColor);
}
else if(color.length())
{
richText.flags=FlagColor;
richText.textColor=ConfigColor(color);
}
else if(backgroundColor.length())
{
richText.flags=FlagBackground;
richText.textBackground=ConfigColor(backgroundColor);
}
}
richTextList->append(richText);
}
}

View File

@ -8,15 +8,13 @@
#include <QMap>
#include "BeaEngine.h"
#include "NewTypes.h"
#include "RichTextPainter.h"
class BeaTokenizer
class BeaTokenizer : RichTextPainter
{
public:
BeaTokenizer();
static unsigned long BeaHashInstruction(const DISASM* disasm);
static void BeaTokenizeInstruction(BeaInstructionToken* instr, const DISASM* disasm);
enum BeaTokenType
{
//filling
@ -73,7 +71,25 @@ public:
int x; //x of the first character
};
struct BeaTokenColor
{
QString color;
QString backgroundColor;
};
static void Init();
static unsigned long HashInstruction(const DISASM* disasm);
static void TokenizeInstruction(BeaInstructionToken* instr, const DISASM* disasm);
static void TokenToRichText(const BeaInstructionToken* instr, QList<RichTextPainter::CustomRichText_t>* richTextList);
private:
//variables
static QMap<BeaTokenType, BeaTokenColor> colorNamesMap;
static QStringList segmentNames;
static QMap<int, QString> memSizeNames;
static QMap<int, QMap<ARGUMENTS_TYPE, QString>> registerMap;
//functions
static void AddToken(BeaInstructionToken* instr, const BeaTokenType type, const QString text, const BeaTokenValue* value);
static void Prefix(BeaInstructionToken* instr, const DISASM* disasm);
static bool IsNopInstruction(QString mnemonic, const DISASM* disasm);
@ -81,6 +97,7 @@ private:
static QString PrintValue(const BeaTokenValue* value);
static QString RegisterToString(int size, int reg);
static void Argument(BeaInstructionToken* instr, const DISASM* disasm, const ARGTYPE* arg, bool* hadarg);
static void AddColorName(BeaTokenType type, QString color, QString backgroundColor);
};
#endif // BEATOKENIZER_H

View File

@ -5,6 +5,7 @@ QBeaEngine::QBeaEngine()
{
// Reset the Disasm structure
memset(&mDisasmStruct, 0, sizeof(DISASM));
BeaTokenizer::Init();
}
@ -184,6 +185,9 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, uint_t size, uint_t instIn
wInst.lentgh = len;
wInst.disasm = mDisasmStruct;
//tokenize
BeaTokenizer::TokenizeInstruction(&wInst.token, &mDisasmStruct);
return wInst;
}

View File

@ -6,6 +6,7 @@
#include "BeaEngine.h"
#include "NewTypes.h"
#include "BeaTokenizer.h"
typedef struct _Instruction_t
{
@ -14,6 +15,7 @@ typedef struct _Instruction_t
uint_t rva;
int lentgh;
DISASM disasm;
BeaTokenizer::BeaInstructionToken token;
} Instruction_t;
class QBeaEngine

View File

@ -127,7 +127,7 @@ void CPUSideBar::paintEvent(QPaintEvent *event)
else if(destVA <= last_va && destVA >= first_va)
{
int destLine = line;
while(destLine < viewableRows && InstrBuffer->at(destLine).rva+CodePtr->getBase() != destVA)
while(destLine && destLine < InstrBuffer->size() && InstrBuffer->at(destLine).rva+CodePtr->getBase() != destVA)
{
if(destVA>instrVA) //jump goes up
destLine++;