Préparation d'un affichage bufferisé du désassemblage

This commit is contained in:
Horde Nicolas 2021-07-09 18:35:13 +02:00
parent 5e2288fcc2
commit af4e98a512
3 changed files with 110 additions and 45 deletions

106
ia86.cpp
View File

@ -162,11 +162,17 @@ void InstructionWindow::clear()
listview.redraw(); listview.redraw();
} }
void InstructionWindow::setindex(int index) void InstructionWindow::setmark(int index)
{ {
listview.setindex(index); listview.setmark(index);
} }
int InstructionWindow::getsize()
{
return listview.getCount();
}
void InstructionWindow::set(std::vector<std::array<std::string, 5>> src) void InstructionWindow::set(std::vector<std::array<std::string, 5>> src)
{ {
content=src; content=src;
@ -312,9 +318,9 @@ Desassembler::Desassembler(TextWindow *log) : log(log)
log->append("Initialisation du désassembleur X86"); log->append("Initialisation du désassembleur X86");
} }
std::vector<std::array<std::string, 5>> Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size) Unasm *Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size)
{ {
Unasm *unasm=new Unasm;
std::stringstream out; std::stringstream out;
srcsize=cs_disasm(handle, content, size, address, 0, &insn); srcsize=cs_disasm(handle, content, size, address, 0, &insn);
if (srcsize == 0) if (srcsize == 0)
@ -323,7 +329,7 @@ std::vector<std::array<std::string, 5>> Desassembler::Desassemble(uint8_t *conte
{ {
out << "Désassemblage réussi, taille du source :" << srcsize; out << "Désassemblage réussi, taille du source :" << srcsize;
log->append(out.str()); log->append(out.str());
src.clear(); unasm->src.clear();
for (size_t j = 0; j < srcsize; j++) for (size_t j = 0; j < srcsize; j++)
{ {
std::string *bytes = new std::string(""); std::string *bytes = new std::string("");
@ -333,11 +339,13 @@ std::vector<std::array<std::string, 5>> Desassembler::Desassemble(uint8_t *conte
std::string *menmonic = new std::string((char *)insn[j].mnemonic); std::string *menmonic = new std::string((char *)insn[j].mnemonic);
std::string *op_str = new std::string((char *)insn[j].op_str); std::string *op_str = new std::string((char *)insn[j].op_str);
std::array<std::string, 5> *array = new std::array<std::string, 5>{"", adresse, *bytes, *menmonic, *op_str}; std::array<std::string, 5> *array = new std::array<std::string, 5>{"", adresse, *bytes, *menmonic, *op_str};
src.push_back(*array); unasm->src.push_back(*array);
std::array<int, 2> *array2 = new std::array<int, 2>{(int)insn[j].address,(int)insn[j].size};
unasm->pos.push_back(*array2);
} }
cs_free(insn, srcsize); cs_free(insn, srcsize);
} }
return src; return unasm;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -354,6 +362,7 @@ Assembler::Assembler(TextWindow *log) : log(log)
} }
else else
log->append("Initialisation de l'assembleur X86"); log->append("Initialisation de l'assembleur X86");
ks_option(ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_NASM);
} }
std::vector<Code> Assembler::MultiAssemble(std::string source,uint32_t address) std::vector<Code> Assembler::MultiAssemble(std::string source,uint32_t address)
@ -449,7 +458,7 @@ VMEngine::VMEngine(TextWindow *log) : log(log)
// Level 10 : EIP EAX EBX ECX EDX EFLAGS ESI EDI ESP EBP CS DS ES SS FS GS ST0 ST1 ST2 ST3 ST4 ST5 ST6 ST7 // Level 10 : EIP EAX EBX ECX EDX EFLAGS ESI EDI ESP EBP CS DS ES SS FS GS ST0 ST1 ST2 ST3 ST4 ST5 ST6 ST7
// Level 11 : EIP EAX EBX ECX EDX EFLAGS ESI EDI ESP EBP CS DS ES SS FS GS ST0 ST1 ST2 ST3 ST4 ST5 ST6 ST7 CR0 CR2 CR3 CR4 CR8 // Level 11 : EIP EAX EBX ECX EDX EFLAGS ESI EDI ESP EBP CS DS ES SS FS GS ST0 ST1 ST2 ST3 ST4 ST5 ST6 ST7 CR0 CR2 CR3 CR4 CR8
// Level 12 : EIP EAX EBX ECX EDX EFLAGS ESI EDI ESP EBP CS DS ES SS FS GS ST0 ST1 ST2 ST3 ST4 ST5 ST6 ST7 CR0 CR2 CR3 CR4 CR8 DB0 DB1 DB2 DB3 DB6 DB7 // Level 12 : EIP EAX EBX ECX EDX EFLAGS ESI EDI ESP EBP CS DS ES SS FS GS ST0 ST1 ST2 ST3 ST4 ST5 ST6 ST7 CR0 CR2 CR3 CR4 CR8 DB0 DB1 DB2 DB3 DB6 DB7
std::string VMEngine::getFlags(int rights) std::string VMEngine::getFlags()
{ {
int eflags=0; int eflags=0;
err = uc_reg_read(uc, UC_X86_REG_EFLAGS, &eflags); err = uc_reg_read(uc, UC_X86_REG_EFLAGS, &eflags);
@ -506,7 +515,7 @@ uint8_t *VMEngine::getRamRaw(uint32_t address, uint32_t size)
return code; return code;
} }
std::string VMEngine::getRegs(int rights) std::string VMEngine::getRegs()
{ {
int regsi836[] = { int regsi836[] = {
UC_X86_REG_EAX, UC_X86_REG_EBX, UC_X86_REG_ECX, UC_X86_REG_EDX, UC_X86_REG_EAX, UC_X86_REG_EBX, UC_X86_REG_ECX, UC_X86_REG_EDX,
@ -636,16 +645,34 @@ void VMEngine::Halt()
this->executed=false; this->executed=false;
} }
void VMEngine::Change() void VMEngine::Unconfigure()
{ {
this->executed=false; this->executed=false;
this->initialized=false; this->initialized=false;
} }
void VMEngine::Configure(State *init, std::vector<Code> newmcode) std::vector<std::array<std::string, 5>> VMEngine::getInstr(int address,int size)
{
if (address<alladdress || address+6>alladdress+500)
{
int begin=address-30;
if (begin<0) begin=0x00000000;
code=this->getRamRaw(begin, 500);
alladdress=begin;
}
crc = crc32(0, code, 500);
if (crc != crc_old)
{
unasmer.Desassemble(code, alladdress, 500);
crc_old=crc;
}
}
void VMEngine::Configure(State *init, std::string code)
{ {
int status; int status;
mcode=newmcode; mcode.clear();
mcode=asmer.MultiAssemble(code,init->dump.regs.eip);
Close(); Close();
Init(); Init();
this->initialized=false; this->initialized=false;
@ -674,6 +701,11 @@ int VMEngine::verify()
return 0; return 0;
} }
void VMEngine::setRights(int rights)
{
this->rights=rights;
}
int VMEngine::getEIP() int VMEngine::getEIP()
{ {
int eip=-666; int eip=-666;
@ -685,6 +717,28 @@ int VMEngine::getEIP()
return eip; return eip;
} }
int VMEngine::getCS()
{
int cs=-666;
err = uc_reg_read(uc, UC_X86_REG_CS, &cs);
if (err != UC_ERR_OK)
log->append("Impossible de récupérer le registre: CS");
if (cs<0)
cs=0;
return cs;
}
int VMEngine::getDS()
{
int ds=-666;
err = uc_reg_read(uc, UC_X86_REG_DS, &ds);
if (err != UC_ERR_OK)
log->append("Impossible de récupérer le registre: DS");
if (ds<0)
ds=0;
return ds;
}
void VMEngine::SetMem(Code *code) void VMEngine::SetMem(Code *code)
{ {
@ -805,6 +859,10 @@ void VMEngine::Run(State *init,uint64_t timeout)
} }
} }
//----------------------------------------------------------------------
// Classe
//----------------------------------------------------------------------
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Classe Menu // Classe Menu
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -968,7 +1026,7 @@ void Menu::initMenusCallBack()
( (
"clicked", "clicked",
this, this,
&Menu::initWindows &Menu::AdjustWindows
); );
TraceInto.addCallback TraceInto.addCallback
( (
@ -1044,7 +1102,8 @@ void Menu::loadLevel()
edit.set(scenario.levels[scenar.getselected()].code); edit.set(scenario.levels[scenar.getselected()].code);
AdjustWindows(); AdjustWindows();
debug.clear(); debug.clear();
vm.Change(); vm.Unconfigure();
vm.setRights(scenario.levels[scenar.getselected()].rights);
} }
void Menu::end() void Menu::end()
@ -1054,9 +1113,7 @@ void Menu::end()
void Menu::compile() void Menu::compile()
{ {
std::vector<Code> mcode; vm.Configure(&scenario.levels[scenar.getselected()].init,edit.get());
mcode=asmer.MultiAssemble(edit.get(),scenario.levels[scenar.getselected()].init.dump.regs.eip);
vm.Configure(&scenario.levels[scenar.getselected()].init,mcode);
} }
void Menu::about() void Menu::about()
@ -1090,8 +1147,8 @@ void Menu::refresh()
} }
else else
{ {
regs.set(vm.getRegs(scenario.levels[scenar.getselected()].rights)); regs.set(vm.getRegs());
flags.set(vm.getFlags(scenario.levels[scenar.getselected()].rights)); flags.set(vm.getFlags());
//debug.setindex(vm.getEIP(code)); //debug.setindex(vm.getEIP(code));
} }
if (!vm.isExecuted()) if (!vm.isExecuted())
@ -1101,16 +1158,7 @@ void Menu::refresh()
else else
{ {
finalcut::FApplication::setDefaultTheme(); finalcut::FApplication::setDefaultTheme();
eip=vm.getEIP()-256; //debug.set(vm.getInstr(vm.getCS()*16+vm.getEIP(),debug.getsize()));
if (eip<0) eip=0x00000000;
code=vm.getRamRaw(eip, 512);
crc = crc32(0, code, 512);
if (crc != oldcrc || eip != oldeip)
{
debug.set(unasmer.Desassemble(code, eip,512));
oldcrc=crc;
oldeip=eip;
}
} }
auto root_widget = getRootWidget(); auto root_widget = getRootWidget();
root_widget->resetColors(); root_widget->resetColors();

40
ia86.h
View File

@ -137,6 +137,12 @@ struct Code
std::string src; std::string src;
}; };
struct Unasm
{
std::vector<std::array<std::string, 5>> src;
std::vector<std::array<int, 2>> pos;
};
class ScenarioWindow final : public finalcut::FDialog class ScenarioWindow final : public finalcut::FDialog
{ {
public: public:
@ -175,7 +181,8 @@ class InstructionWindow final : public finalcut::FDialog
std::vector<std::array<std::string, 5>> get(); std::vector<std::array<std::string, 5>> get();
void set(std::vector<std::array<std::string, 5>> src); void set(std::vector<std::array<std::string, 5>> src);
void clear(); void clear();
void setindex(int index); void setmark(int index);
int getsize();
private: private:
// Method // Method
std::vector<std::array<std::string, 5>> content; std::vector<std::array<std::string, 5>> content;
@ -239,7 +246,7 @@ class Desassembler
{ {
public: public:
Desassembler(TextWindow *log); Desassembler(TextWindow *log);
std::vector<std::array<std::string, 5>> Desassemble(uint8_t *content, uint32_t address,uint32_t size); Unasm *Desassemble(uint8_t *content, uint32_t address,uint32_t size);
private: private:
csh handle; csh handle;
cs_insn *insn; cs_insn *insn;
@ -270,28 +277,38 @@ class VMEngine
{ {
public: public:
VMEngine(TextWindow *log); VMEngine(TextWindow *log);
void Configure(State *init, std::vector<Code> mcode); void Configure(State *init, std::string code);
void Halt(); void Halt();
void Change(); void Unconfigure();
void Run(State *init,uint64_t timeout); void Run(State *init,uint64_t timeout);
std::string getFlags(int rights); std::string getFlags();
std::string getRegs(int rights); std::string getRegs();
std::vector<std::array<std::string, 5>> getInstr(int address,int size);
void SetMem(Code *code); void SetMem(Code *code);
void SetRegs(State *init); void SetRegs(State *init);
uint8_t *getRamRaw(uint32_t address, uint32_t size);
int getEIP();
int verify(); int verify();
bool isExecuted(); bool isExecuted();
bool isInitialized(); bool isInitialized();
void setRights(int rights);
int getEIP();
int getCS();
int getDS();
private: private:
TextWindow *log;
Assembler asmer{log};
Desassembler unasmer{log};
std::vector<Code> mcode; std::vector<Code> mcode;
int rights;
uint8_t *getRamRaw(uint32_t address, uint32_t size);
void Init(); void Init();
void Close(); void Close();
bool executed=false; bool executed=false;
bool initialized=false; bool initialized=false;
uc_engine *uc; uc_engine *uc;
uc_err err; uc_err err;
TextWindow *log; int alladdress,alladdress_old;
uint8_t *code;
uLong crc,crc_old;
}; };
class Menu final : public finalcut::FDialog class Menu final : public finalcut::FDialog
@ -309,9 +326,6 @@ class Menu final : public finalcut::FDialog
void loadLevel(); void loadLevel();
TextWindow log{this}; TextWindow log{this};
private: private:
int eip,oldeip;
uint8_t *code;
uLong crc,oldcrc;
void onTimer (finalcut::FTimerEvent*) override; void onTimer (finalcut::FTimerEvent*) override;
void refresh(); void refresh();
void configureFileMenuItems(); void configureFileMenuItems();
@ -367,8 +381,6 @@ class Menu final : public finalcut::FDialog
TextEditWindow edit{this}; TextEditWindow edit{this};
ScenarioWindow scenar{this}; ScenarioWindow scenar{this};
VMEngine vm{&log}; VMEngine vm{&log};
Assembler asmer{&log};
Desassembler unasmer{&log};
}; };

View File

@ -51,9 +51,14 @@ hlt",
"niveau_description" : "Il faut connaitre...", "niveau_description" : "Il faut connaitre...",
"niveau_tutoriel" : "Ceci vous...", "niveau_tutoriel" : "Ceci vous...",
"niveau_code" : "mov ax,0x545 "niveau_code" : "mov ax,0x545
pop:
inc dx inc dx
lea ebx,[pop]
db 'c','e','c','i',' ','e','s','t',' ','u','n',' ','t','e','s','t',0
.org 0x9000 .org 0x9000
pop db 'ceci est un test',0 pop:
db 0x00
lea eax,[pop]
mov esi,0x44441234 mov esi,0x44441234
.org 0x3002 .org 0x3002
hlt", hlt",