Affichage des instructions opérationnel

This commit is contained in:
Horde Nicolas 2021-07-10 19:36:29 +02:00
parent af4e98a512
commit 131d311196
2 changed files with 132 additions and 69 deletions

165
ia86.cpp
View File

@ -75,7 +75,8 @@ Scenario readscenario(std::string filename) {
} }
Scenario scenario; Scenario scenario;
Unasm unasm;
int marker;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Classe ScenarioWindow // Classe ScenarioWindow
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -172,7 +173,6 @@ int InstructionWindow::getsize()
return listview.getCount(); 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;
@ -308,28 +308,23 @@ void TextWindow::adjustSize()
Desassembler::Desassembler(TextWindow *log) : log(log) Desassembler::Desassembler(TextWindow *log) : log(log)
{ {
std::stringstream out;
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle); err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
if (err != CS_ERR_OK) { if (err != CS_ERR_OK)
out << "Erreur : Initialisation du désassembleur X86" << err; log->append("Erreur : Initialisation du désassembleur X86");
log->append(out.str());
}
else else
log->append("Initialisation du désassembleur X86"); log->append("Initialisation du désassembleur X86");
} }
Unasm *Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size) void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size, Unasm *unasm)
{ {
Unasm *unasm=new Unasm;
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)
log->append("Erreur de désassemblage"); log->append("Erreur de désassemblage");
else else
{ {
out << "Désassemblage réussi, taille du source :" << srcsize; log->append("Désassemblage réussi, taille du source :"+to_string(srcsize));
log->append(out.str());
unasm->src.clear(); unasm->src.clear();
unasm->pos.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("");
@ -340,12 +335,10 @@ Unasm *Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t siz
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};
unasm->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(insn[j].address);
unasm->pos.push_back(*array2);
} }
cs_free(insn, srcsize); cs_free(insn, srcsize);
} }
return unasm;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -444,6 +437,7 @@ void Assembler::Assemble(Code *code)
VMEngine::VMEngine(TextWindow *log) : log(log) VMEngine::VMEngine(TextWindow *log) : log(log)
{ {
code=new uint8_t[500];
Init(); Init();
} }
// Level 1 : IP AL // Level 1 : IP AL
@ -503,18 +497,6 @@ std::string VMEngine::getFlags()
return out.str(); return out.str();
} }
uint8_t *VMEngine::getRamRaw(uint32_t address, uint32_t size)
{
uint8_t *code=new uint8_t[512];
err = uc_mem_read(uc, address, code, size);
if (err)
{
log->append("Erreur de copie mémoire depuis la machine virtuelle");
return NULL;
}
return code;
}
std::string VMEngine::getRegs() std::string VMEngine::getRegs()
{ {
int regsi836[] = { int regsi836[] = {
@ -651,21 +633,66 @@ void VMEngine::Unconfigure()
this->initialized=false; this->initialized=false;
} }
std::vector<std::array<std::string, 5>> VMEngine::getInstr(int address,int size) uint32_t VMEngine::getNextInstr()
{ {
if (address<alladdress || address+6>alladdress+500) uint32_t now=getEIP();
bool flag=false;
for(int pos: unasm.pos)
{ {
int begin=address-30; if (pos==now)
flag=true;
else if (flag)
return pos;
}
return 0;
}
std::vector<std::array<std::string, 5>> VMEngine::getInstr(int segment, int address,int size)
{
uint32_t realaddress=segment*16+address;
if (realaddress<bufferaddress || realaddress+6>bufferaddress+500)
{
int begin=realaddress-30;
if (begin<0) begin=0x00000000; if (begin<0) begin=0x00000000;
code=this->getRamRaw(begin, 500); err = uc_mem_read(uc, begin, code, 500);
alladdress=begin; if (err)
{
log->append("Erreur de copie mémoire depuis la machine virtuelle");
}
bufferaddress=begin;
} }
crc = crc32(0, code, 500); crc = crc32(0, code, 500);
if (crc != crc_old) if (crc != crc_old)
{ {
unasmer.Desassemble(code, alladdress, 500); unasmer.Desassemble(code, address, 500, &unasm);
crc_old=crc; crc_old=crc;
} }
int line=0;
for(int pos: unasm.pos)
{
if (pos==address)
break;
line++;
}
int first=line-((int)size/2);
if (first<0) first=0;
int last=first+size;
marker=0;
std::string reference=intToHexString(address, 8);
std::vector<std::array<std::string, 5>> result = {unasm.src.begin()+first,unasm.src.begin()+last};
for(std::array<std::string, 5> item: result)
{
if (item[1]==reference)
break;
marker++;
}
return result;
}
int VMEngine::getLine()
{
return marker;
} }
void VMEngine::Configure(State *init, std::string code) void VMEngine::Configure(State *init, std::string code)
@ -706,36 +733,35 @@ void VMEngine::setRights(int rights)
this->rights=rights; this->rights=rights;
} }
int VMEngine::getEIP() uint32_t VMEngine::getCurrent()
{ {
int eip=-666; return getEIP()+getCS()*16;
}
uint32_t VMEngine::getEIP()
{
int eip=0;
err = uc_reg_read(uc, UC_X86_REG_EIP, &eip); err = uc_reg_read(uc, UC_X86_REG_EIP, &eip);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible de récupérer le registre: EIP"); log->append("Impossible de récupérer le registre: EIP");
if ((eip<0) || (eip>1*1024*1024))
eip=-666;
return eip; return eip;
} }
int VMEngine::getCS() uint16_t VMEngine::getCS()
{ {
int cs=-666; int cs=0;
err = uc_reg_read(uc, UC_X86_REG_CS, &cs); err = uc_reg_read(uc, UC_X86_REG_CS, &cs);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible de récupérer le registre: CS"); log->append("Impossible de récupérer le registre: CS");
if (cs<0)
cs=0;
return cs; return cs;
} }
int VMEngine::getDS() uint16_t VMEngine::getDS()
{ {
int ds=-666; int ds=9;
err = uc_reg_read(uc, UC_X86_REG_DS, &ds); err = uc_reg_read(uc, UC_X86_REG_DS, &ds);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible de récupérer le registre: DS"); log->append("Impossible de récupérer le registre: DS");
if (ds<0)
ds=0;
return ds; return ds;
} }
@ -844,9 +870,9 @@ void VMEngine::SetRegs(State *init)
log->append(out.str()); log->append(out.str());
} }
void VMEngine::Run(State *init,uint64_t timeout) void VMEngine::Run(uint32_t end,uint64_t timeout)
{ {
err=uc_emu_start(uc, init->dump.regs.eip, 0xFFFF, timeout, 0); err=uc_emu_start(uc, this->getCurrent(), end, timeout, 0);
if (err) if (err)
{ {
log->append("Erreur lors de l'exécution de la machine virtuelle"); log->append("Erreur lors de l'exécution de la machine virtuelle");
@ -1114,6 +1140,7 @@ void Menu::end()
void Menu::compile() void Menu::compile()
{ {
vm.Configure(&scenario.levels[scenar.getselected()].init,edit.get()); vm.Configure(&scenario.levels[scenar.getselected()].init,edit.get());
showInstr();
} }
void Menu::about() void Menu::about()
@ -1137,19 +1164,23 @@ void Menu::about()
AdjustWindows(); AdjustWindows();
} }
void Menu::showInstr()
{
debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3));
debug.setmark(vm.getLine());
}
void Menu::refresh() void Menu::refresh()
{ {
if (!vm.isInitialized()) if (!vm.isInitialized())
{ {
regs.set("En attente d'initialisation..."); regs.set("En attente d'initialisation...");
flags.set("Attente..."); flags.set("Attente...");
//debug.setindex(-666);
} }
else else
{ {
regs.set(vm.getRegs()); regs.set(vm.getRegs());
flags.set(vm.getFlags()); flags.set(vm.getFlags());
//debug.setindex(vm.getEIP(code));
} }
if (!vm.isExecuted()) if (!vm.isExecuted())
{ {
@ -1158,7 +1189,6 @@ void Menu::refresh()
else else
{ {
finalcut::FApplication::setDefaultTheme(); finalcut::FApplication::setDefaultTheme();
//debug.set(vm.getInstr(vm.getCS()*16+vm.getEIP(),debug.getsize()));
} }
auto root_widget = getRootWidget(); auto root_widget = getRootWidget();
root_widget->resetColors(); root_widget->resetColors();
@ -1181,17 +1211,46 @@ void Menu::exec()
return; return;
} }
else else
vm.Run(&scenario.levels[scenar.getselected()].init,0); vm.Run(0xFFFF,0);
showInstr();
} }
void Menu::trace() void Menu::trace()
{ {
exec(); if (!vm.isInitialized())
compile();
if (vm.verify()==1)
{
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return;
}
else if (vm.verify()==2)
{
finalcut::FMessageBox::error(this, "Une erreur de chargement a eu lieu vers la VM !");
return;
}
else
vm.Run(vm.getNextInstr(),0);
showInstr();
} }
void Menu::step() void Menu::step()
{ {
exec(); if (!vm.isInitialized())
compile();
if (vm.verify()==1)
{
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return;
}
else if (vm.verify()==2)
{
finalcut::FMessageBox::error(this, "Une erreur de chargement a eu lieu vers la VM !");
return;
}
else
vm.Run(vm.getNextInstr(),0);
showInstr();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

30
ia86.h
View File

@ -140,7 +140,7 @@ struct Code
struct Unasm struct Unasm
{ {
std::vector<std::array<std::string, 5>> src; std::vector<std::array<std::string, 5>> src;
std::vector<std::array<int, 2>> pos; std::vector<uint32_t> pos;
}; };
class ScenarioWindow final : public finalcut::FDialog class ScenarioWindow final : public finalcut::FDialog
@ -246,7 +246,7 @@ class Desassembler
{ {
public: public:
Desassembler(TextWindow *log); Desassembler(TextWindow *log);
Unasm *Desassemble(uint8_t *content, uint32_t address,uint32_t size); void Desassemble(uint8_t *content, uint32_t address,uint32_t size, Unasm *unasm);
private: private:
csh handle; csh handle;
cs_insn *insn; cs_insn *insn;
@ -280,35 +280,38 @@ class VMEngine
void Configure(State *init, std::string code); void Configure(State *init, std::string code);
void Halt(); void Halt();
void Unconfigure(); void Unconfigure();
void Run(State *init,uint64_t timeout); uint32_t getNextInstr();
uint32_t getCurrent();
void Run(uint32_t end,uint64_t timeout);
std::string getFlags(); std::string getFlags();
std::string getRegs(); std::string getRegs();
std::vector<std::array<std::string, 5>> getInstr(int address,int size); std::vector<std::array<std::string, 5>> getInstr(int segment, int address,int size);
void SetMem(Code *code); void SetMem(Code *code);
void SetRegs(State *init); void SetRegs(State *init);
int verify(); int verify();
bool isExecuted(); bool isExecuted();
bool isInitialized(); bool isInitialized();
void setRights(int rights); void setRights(int rights);
int getEIP(); int getLine();
int getCS(); uint32_t getEIP();
int getDS(); uint16_t getCS();
uint16_t getDS();
private: private:
TextWindow *log;
Assembler asmer{log};
Desassembler unasmer{log};
std::vector<Code> mcode;
int rights; 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;
int alladdress,alladdress_old; int bufferaddress=-555;
int address_old;
uint8_t *code; uint8_t *code;
uLong crc,crc_old; uLong crc,crc_old;
std::vector<Code> mcode;
TextWindow *log;
Assembler asmer{log};
Desassembler unasmer{log};
}; };
class Menu final : public finalcut::FDialog class Menu final : public finalcut::FDialog
@ -336,6 +339,7 @@ class Menu final : public finalcut::FDialog
void initCore(); void initCore();
void compile(); void compile();
void end(); void end();
void showInstr();
void exec(); void exec();
void trace(); void trace();
void step(); void step();