Ajout gestion des erreurs, amélioration du chargement des scénarios

This commit is contained in:
Horde Nicolas 2021-07-11 14:17:58 +02:00
parent 131d311196
commit eaadfa4bc8
2 changed files with 310 additions and 164 deletions

279
ia86.cpp
View File

@ -12,9 +12,11 @@
#include <vector> #include <vector>
#include <zlib.h> #include <zlib.h>
#include "ia86.h" #include "ia86.h"
#include <exception>
#include "struct_mapping/struct_mapping.h" #include "struct_mapping/struct_mapping.h"
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Fonctions diverses // Fonctions diverses
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -77,6 +79,7 @@ Scenario readscenario(std::string filename) {
Scenario scenario; Scenario scenario;
Unasm unasm; Unasm unasm;
int marker; int marker;
bool debug=true;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Classe ScenarioWindow // Classe ScenarioWindow
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -84,30 +87,37 @@ int marker;
ScenarioWindow::ScenarioWindow (finalcut::FWidget* parent) ScenarioWindow::ScenarioWindow (finalcut::FWidget* parent)
: finalcut::FDialog{parent} : finalcut::FDialog{parent}
{ {
((Menu*)this->getParent())->log.append("Chargement des scénarios");
scenario=readscenario("./scenarios.json");
if (scenario.levels.size()==0)
finalcut::FMessageBox::error(this, "Impossible de charger le scénario par défaut !");
listview.ignorePadding(); listview.ignorePadding();
listview.addColumn ("*"); listview.addColumn ("*");
listview.addColumn ("Intitulé"); listview.addColumn ("Intitulé");
listview.hideSortIndicator(true); listview.hideSortIndicator(true);
listview.setFocus(); listview.setFocus();
listview.addCallback
(
"row-changed",
this, &ScenarioWindow::click
);
}
bool ScenarioWindow::load(std::string file)
{
scenario=readscenario(file);
if (scenario.levels.size()>0)
{
std::vector<std::string> items; std::vector<std::string> items;
for(size_t i=0; i < scenario.levels.size(); i++) for(size_t i=0; i < scenario.levels.size(); i++)
{ {
((Menu*)this->getParent())->log.append("."); //((Menu*)this->getParent())->log.append(".");
items.clear(); items.clear();
items.push_back(to_string(i)); items.push_back(to_string(i));
items.push_back(scenario.levels[i].title); items.push_back(scenario.levels[i].title);
const finalcut::FStringList line (items.begin(), items.end()); const finalcut::FStringList line (items.begin(), items.end());
listview.insert (line); listview.insert (line);
} }
listview.addCallback return true;
( }
"row-changed", else
this, &ScenarioWindow::click return false;
);
} }
void ScenarioWindow::click() void ScenarioWindow::click()
@ -307,22 +317,30 @@ void TextWindow::adjustSize()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
Desassembler::Desassembler(TextWindow *log) : log(log) Desassembler::Desassembler(TextWindow *log) : log(log)
{
try
{ {
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)
log->append("Erreur : Initialisation du désassembleur X86"); Error("Désassembleur - initialisation....................[ERREUR]");
else log->append("Désassembleur - initialisation....................[ OK ]");
log->append("Initialisation du désassembleur X86"); }
catch(exception const& e)
{
log->append(e.what());
}
} }
void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size, Unasm *unasm) void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size, Unasm *unasm)
{
try
{ {
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"); Error("Désassembleur - Désassemblage.....................[ERREUR]");
else else
{ {
log->append("Désassemblage réussi, taille du source :"+to_string(srcsize)); if (debug) log->append("Désassemblage - Désassemblage.....................[ "+to_string(srcsize)+"l ]");
unasm->src.clear(); unasm->src.clear();
unasm->pos.clear(); unasm->pos.clear();
for (size_t j = 0; j < srcsize; j++) for (size_t j = 0; j < srcsize; j++)
@ -340,6 +358,14 @@ void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size,
cs_free(insn, srcsize); cs_free(insn, srcsize);
} }
} }
catch(exception const& e)
{
unasm->src.clear();
unasm->pos.clear();
log->append(e.what());
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Classe Assembler // Classe Assembler
@ -347,18 +373,22 @@ void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size,
Assembler::Assembler(TextWindow *log) : log(log) Assembler::Assembler(TextWindow *log) : log(log)
{ {
std::stringstream out; try
{
err = ks_open(KS_ARCH_X86, KS_MODE_16, &ks); err = ks_open(KS_ARCH_X86, KS_MODE_16, &ks);
if (err != KS_ERR_OK) { if (err != KS_ERR_OK)
out << "Erreur : Initialisation de l'assembleur X86" << err; Error("Assembleur - initialisation.......................[ERREUR]");
log->append(out.str()); log->append("Assembleur - initialisation.......................[ OK ]");
}
catch(exception const& e)
{
log->append(e.what());
} }
else
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)
{
try
{ {
std::vector<Code> mcode; std::vector<Code> mcode;
std::istringstream stream(source); std::istringstream stream(source);
@ -394,41 +424,37 @@ std::vector<Code> Assembler::MultiAssemble(std::string source,uint32_t address)
mcode.push_back(*code); mcode.push_back(*code);
for(size_t i=0;i<mcode.size();i++) for(size_t i=0;i<mcode.size();i++)
{ {
log->append("Section N°"+std::to_string(i)+" : "+intToHexString(mcode[i].address,8)+" -> "+to_string(mcode[i].src.size())+" octets"); //log->append(mcode[i].src);
log->append(mcode[i].src);
mcode[i].assembled=false; mcode[i].assembled=false;
mcode[i].loaded=false; mcode[i].loaded=false;
this->Assemble(&mcode[i]); this->Assemble(&mcode[i]);
if (debug) log->append("Section N°"+std::to_string(i)+" : "+intToHexString(mcode[i].address,8)+" -> "+to_string(mcode[i].size)+" octets");
} }
return mcode; return mcode;
} }
catch(exception const& e)
{
std::vector<Code> mcode;
log->append(e.what());
return mcode;
}
}
void Assembler::Assemble(Code *code) void Assembler::Assemble(Code *code)
{ {
std::stringstream out;
size_t srcsize=code->src.size(); size_t srcsize=code->src.size();
unsigned char src_char[srcsize+1]; unsigned char src_char[srcsize+1];
strcpy(reinterpret_cast<char*>(src_char), code->src.c_str()); strcpy(reinterpret_cast<char*>(src_char), code->src.c_str());
err2=ks_asm(ks, reinterpret_cast<const char*>(src_char), code->address, &code->content, &code->size, &srcsize); err2=ks_asm(ks, reinterpret_cast<const char*>(src_char), code->address, &code->content, &code->size, &srcsize);
if (err2 != KS_ERR_OK) if (err2 != KS_ERR_OK)
{ {
log->append("Erreur d'assemblage");
code->size=0; code->size=0;
code->assembled=false; code->assembled=false;
Error("Assembleur - assemblage...........................[ERREUR]");
} }
else else
{
out.clear();
out << "Assemblage réussi, taille du code :" << code->size;
code->assembled=true; code->assembled=true;
if (code->size < 30)
{
out << "\n ";
for (size_t count = 0; count < code->size; count++)
out << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (int)((uint8_t)code->content[count]) ;
log->append(out.str());
}
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -457,7 +483,7 @@ 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);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible de récupérer le registre: EFLAGS"); Error("VM IA86 - voir EFLAGS.............................[ERREUR]");
std::stringstream out; std::stringstream out;
out << " CF:" << std::dec << ((eflags & 0x0001)); out << " CF:" << std::dec << ((eflags & 0x0001));
if (rights > 8) if (rights > 8)
@ -513,7 +539,7 @@ std::string VMEngine::getRegs()
} }
err = uc_reg_read_batch(uc, regsi836, ptrs, sizeof(regsi836)); err = uc_reg_read_batch(uc, regsi836, ptrs, sizeof(regsi836));
if (err > 0) { if (err > 0) {
log->append("Erreur lors de la récupération des registres depuis la VM"); Error("VM IA86 - voir REGISTRES..........................[ERREUR]");
return ""; return "";
} }
std::stringstream out; std::stringstream out;
@ -597,14 +623,17 @@ std::string VMEngine::getRegs()
void VMEngine::Init() void VMEngine::Init()
{ {
std::stringstream out; try
{
err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc); err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc);
if (err != UC_ERR_OK) { if (err != UC_ERR_OK)
out << "Impossible d'initialiser la machine virtuelle: " << err; Error("VM IA86 - initilisation...........................[ERREUR]");
log->append(out.str()); log->append("VM IA86 - initilisation...........................[ OK ]");
}
catch(exception const& e)
{
log->append(e.what());
} }
else
log->append("Initialisation de l'ordinateur IA86");
} }
bool VMEngine::isExecuted() bool VMEngine::isExecuted()
@ -624,12 +653,14 @@ void VMEngine::Close()
void VMEngine::Halt() void VMEngine::Halt()
{ {
if (this->executed)
log->append("VM IA86 - arret...................................[ERREUR]");
this->executed=false; this->executed=false;
} }
void VMEngine::Unconfigure() void VMEngine::Unconfigure()
{ {
this->executed=false; this->Halt();
this->initialized=false; this->initialized=false;
} }
@ -650,21 +681,25 @@ uint32_t VMEngine::getNextInstr()
std::vector<std::array<std::string, 5>> VMEngine::getInstr(int segment, int address,int size) std::vector<std::array<std::string, 5>> VMEngine::getInstr(int segment, int address,int size)
{ {
uint32_t realaddress=segment*16+address; uint32_t realaddress=segment*16+address;
if (realaddress<bufferaddress || realaddress+6>bufferaddress+500) bool changed=false;
if (realaddress<bufferaddress || realaddress+(size*7)>bufferaddress+500)
{ {
changed=true;
int begin=realaddress-30; int begin=realaddress-30;
if (begin<0) begin=0x00000000; if (begin<0) begin=0x00000000;
err = uc_mem_read(uc, begin, code, 500); err = uc_mem_read(uc, begin, code, 500);
if (err) if (err)
{ {
log->append("Erreur de copie mémoire depuis la machine virtuelle"); Error("VM IA86 - cache instructions......................[ERREUR]");
} }
bufferaddress=begin; bufferaddress=begin;
} }
crc = crc32(0, code, 500); crc = crc32(0, code, 500);
if (crc != crc_old) if (crc != crc_old || changed)
{ {
unasmer.Desassemble(code, address, 500, &unasm); unasmer.Desassemble(code, address, 500, &unasm);
if (unasm.src.size()==0)
Error("VM IA86 - cache instructions......................[ERREUR]");
crc_old=crc; crc_old=crc;
} }
int line=0; int line=0;
@ -696,15 +731,19 @@ int VMEngine::getLine()
} }
void VMEngine::Configure(State *init, std::string code) void VMEngine::Configure(State *init, std::string code)
{
try
{ {
int status; int status;
mcode.clear(); mcode.clear();
mcode=asmer.MultiAssemble(code,init->dump.regs.eip); mcode=asmer.MultiAssemble(code,init->dump.regs.eip);
if (mcode.size()==0)
return;
Close(); Close();
Init(); Init();
this->initialized=false; this->initialized=false;
this->executed=false; this->executed=false;
log->append("Mappage de la mémoire virtuelle"); //log->append("Mappage de la mémoire virtuelle");
uc_mem_map(uc, 0, 1 * 1024 * 1024, UC_PROT_ALL); uc_mem_map(uc, 0, 1 * 1024 * 1024, UC_PROT_ALL);
for(size_t i=0;i<mcode.size();i++) for(size_t i=0;i<mcode.size();i++)
SetMem(&mcode[i]); SetMem(&mcode[i]);
@ -715,6 +754,12 @@ void VMEngine::Configure(State *init, std::string code)
this->initialized=false; this->initialized=false;
SetRegs(init); SetRegs(init);
} }
catch(exception const& e)
{
log->append(e.what());
this->initialized=false;
}
}
int VMEngine::verify() int VMEngine::verify()
{ {
@ -740,31 +785,49 @@ uint32_t VMEngine::getCurrent()
uint32_t VMEngine::getEIP() uint32_t VMEngine::getEIP()
{ {
int eip=0; int eip;
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"); Error("VM IA86 - voir EIP................................[ERREUR]");
return eip; return eip;
} }
uint16_t VMEngine::getCS() uint16_t VMEngine::getCS()
{ {
int cs=0; int cs;
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"); Error("VM IA86 - voir CS.................................[ERREUR]");
return cs; return cs;
} }
uint16_t VMEngine::getDS() uint16_t VMEngine::getDS()
{ {
int ds=9; int ds;
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"); Error("VM IA86 - voir DS.................................[ERREUR]");
return ds; return ds;
} }
uint16_t VMEngine::getES()
{
int es;
err = uc_reg_read(uc, UC_X86_REG_ES, &es);
if (err != UC_ERR_OK)
Error("VM IA86 - voir ES.................................[ERREUR]");
return es;
}
uint16_t VMEngine::getSS()
{
int ss;
err = uc_reg_read(uc, UC_X86_REG_SS, &ss);
if (err != UC_ERR_OK)
Error("VM IA86 - voir SS.................................[ERREUR]");
return ss;
}
void VMEngine::SetMem(Code *code) void VMEngine::SetMem(Code *code)
{ {
@ -772,23 +835,19 @@ void VMEngine::SetMem(Code *code)
if (err) if (err)
{ {
code->loaded=false; code->loaded=false;
log->append("Erreur de copie mémoire dans la machine virtuelle"); Error("VM IA86 - copie mémoire...........................[ERREUR]");
return; return;
} }
else
{
code->loaded=true; code->loaded=true;
log->append("Chargement en mémoire de la machine virtuelle, taille: "+to_string(code->size));
}
} }
void VMEngine::SetRegs(State *init) void VMEngine::SetRegs(State *init)
{ {
std::stringstream out; std::stringstream out;
out << "Configuration initiale de l'ordinateur IA86:\n "; out << "VM IA86 - configuration initiale..................[ OK ]";
err = uc_reg_write(uc, UC_X86_REG_EIP, &init->dump.regs.eip); err = uc_reg_write(uc, UC_X86_REG_EIP, &init->dump.regs.eip);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible d'initialiser le registre: EIP"); Error("VM IA86 - configuration initiale EIP..............[ERREUR]");
else else
if (init->dump.regs.eip != 0x00000000) if (init->dump.regs.eip != 0x00000000)
if ((init->dump.regs.eip & 0xFFFF0000) == 0x00000000) if ((init->dump.regs.eip & 0xFFFF0000) == 0x00000000)
@ -797,7 +856,7 @@ void VMEngine::SetRegs(State *init)
out << "EIP=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.eip << " "; out << "EIP=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.eip << " ";
err = uc_reg_write(uc, UC_X86_REG_EDI, &init->dump.regs.edi); err = uc_reg_write(uc, UC_X86_REG_EDI, &init->dump.regs.edi);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible d'initialiser le registre: EDI"); Error("VM IA86 - configuration initiale EDI..............[ERREUR]");
else else
if (init->dump.regs.edi != 0x00000000) if (init->dump.regs.edi != 0x00000000)
if ((init->dump.regs.edi & 0xFFFF0000) == 0x00000000) if ((init->dump.regs.edi & 0xFFFF0000) == 0x00000000)
@ -806,7 +865,7 @@ void VMEngine::SetRegs(State *init)
out << "EDI=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.edi << " "; out << "EDI=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.edi << " ";
err = uc_reg_write(uc, UC_X86_REG_ESI, &init->dump.regs.esi); err = uc_reg_write(uc, UC_X86_REG_ESI, &init->dump.regs.esi);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible d'initialiser le registre: ESE"); Error("VM IA86 - configuration initiale ESI..............[ERREUR]");
else else
if (init->dump.regs.esi != 0x00000000) if (init->dump.regs.esi != 0x00000000)
if ((init->dump.regs.esi & 0xFFFF0000) == 0x00000000) if ((init->dump.regs.esi & 0xFFFF0000) == 0x00000000)
@ -815,7 +874,7 @@ void VMEngine::SetRegs(State *init)
out << "ESI=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.esi << " "; out << "ESI=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.esi << " ";
err = uc_reg_write(uc, UC_X86_REG_EBP, &init->dump.regs.ebp); err = uc_reg_write(uc, UC_X86_REG_EBP, &init->dump.regs.ebp);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible d'initialiser le registre: EBP"); Error("VM IA86 - configuration initiale EBP..............[ERREUR]");
else else
if (init->dump.regs.ebp != 0x00000000) if (init->dump.regs.ebp != 0x00000000)
if ((init->dump.regs.ebp & 0xFFFF0000) == 0x00000000) if ((init->dump.regs.ebp & 0xFFFF0000) == 0x00000000)
@ -824,7 +883,7 @@ void VMEngine::SetRegs(State *init)
out << "EBP=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.ebp << " "; out << "EBP=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.ebp << " ";
err = uc_reg_write(uc, UC_X86_REG_ESP, &init->dump.regs.esp); err = uc_reg_write(uc, UC_X86_REG_ESP, &init->dump.regs.esp);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible d'initialiser le registre: ESP"); Error("VM IA86 - configuration initiale ESP..............[ERREUR]");
else else
if (init->dump.regs.esp != 0x00000000) if (init->dump.regs.esp != 0x00000000)
if ((init->dump.regs.esp & 0xFFFF0000) == 0x00000000) if ((init->dump.regs.esp & 0xFFFF0000) == 0x00000000)
@ -833,7 +892,7 @@ void VMEngine::SetRegs(State *init)
out << "ESP=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.esp << " "; out << "ESP=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.esp << " ";
err = uc_reg_write(uc, UC_X86_REG_EBX, &init->dump.regs.ebx); err = uc_reg_write(uc, UC_X86_REG_EBX, &init->dump.regs.ebx);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible d'initialiser le registre: EBX"); Error("VM IA86 - configuration initiale EBX..............[ERREUR]");
else else
if (init->dump.regs.ebx != 0x00000000) if (init->dump.regs.ebx != 0x00000000)
if ((init->dump.regs.ebx & 0xFFFF0000) == 0x00000000) if ((init->dump.regs.ebx & 0xFFFF0000) == 0x00000000)
@ -842,7 +901,7 @@ void VMEngine::SetRegs(State *init)
out << "EBX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.ebx << " "; out << "EBX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.ebx << " ";
err = uc_reg_write(uc, UC_X86_REG_EDX, &init->dump.regs.edx); err = uc_reg_write(uc, UC_X86_REG_EDX, &init->dump.regs.edx);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible d'initialiser le registre: EDX"); Error("VM IA86 - configuration initiale EDX..............[ERREUR]");
else else
if (init->dump.regs.edx != 0x00000000) if (init->dump.regs.edx != 0x00000000)
if ((init->dump.regs.edx & 0xFFFF0000) == 0x00000000) if ((init->dump.regs.edx & 0xFFFF0000) == 0x00000000)
@ -851,7 +910,7 @@ void VMEngine::SetRegs(State *init)
out << "EDX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.edx << " "; out << "EDX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.edx << " ";
err = uc_reg_write(uc, UC_X86_REG_ECX, &init->dump.regs.ecx); err = uc_reg_write(uc, UC_X86_REG_ECX, &init->dump.regs.ecx);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible d'initialiser le registre: ECX"); Error("VM IA86 - configuration initiale ECX..............[ERREUR]");
else else
if (init->dump.regs.ecx != 0x00000000) if (init->dump.regs.ecx != 0x00000000)
if ((init->dump.regs.ecx & 0xFFFF0000) == 0x00000000) if ((init->dump.regs.ecx & 0xFFFF0000) == 0x00000000)
@ -860,7 +919,7 @@ void VMEngine::SetRegs(State *init)
out << "ECX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.ecx << " "; out << "ECX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.ecx << " ";
err = uc_reg_write(uc, UC_X86_REG_EAX, &init->dump.regs.eax); err = uc_reg_write(uc, UC_X86_REG_EAX, &init->dump.regs.eax);
if (err != UC_ERR_OK) if (err != UC_ERR_OK)
log->append("Impossible d'initialiser le registre: EAX"); Error("VM IA86 - configuration initiale EAX..............[ERREUR]");
else else
if (init->dump.regs.eax != 0x00000000) if (init->dump.regs.eax != 0x00000000)
if ((init->dump.regs.eax & 0xFFFF0000) == 0x00000000) if ((init->dump.regs.eax & 0xFFFF0000) == 0x00000000)
@ -871,19 +930,27 @@ void VMEngine::SetRegs(State *init)
} }
void VMEngine::Run(uint32_t end,uint64_t timeout) void VMEngine::Run(uint32_t end,uint64_t timeout)
{
try
{ {
err=uc_emu_start(uc, this->getCurrent(), end, 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"); this->Halt();
this->executed=false; Error("VM IA86 - execution...............................[ERREUR]");
return;
} }
else else
{ {
if (!this->executed)
log->append("VM IA86 - execution...............................[ INFO ]");
this->executed="true"; this->executed="true";
} }
} }
catch(exception const& e)
{
log->append(e.what());
}
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Classe // Classe
@ -911,9 +978,49 @@ void Menu::initNow()
void Menu::initCore() void Menu::initCore()
{ {
addTimer (50); addTimer (50);
log.append(scenario.title); if (scenar.load("./scenarios.json"))
{
log.append("Application - charge scénarios....................[ OK ]");
log.append("-={ "+ scenario.title+" }=-");
if (scenario.levels.size()>0) if (scenario.levels.size()>0)
loadLevel(); loadLevel();
maxi();
}
else
{
log.append("Application - charge scénarios....................[ERREUR]");
vm.Unconfigure();
mini();
}
}
void Menu::mini()
{
this->hide();
flags.hide();
stack.hide();
mem.hide();
screen.hide();
log.show();
edit.hide();
view.hide();
regs.hide();
tuto.hide();
debug.hide();
scenar.hide();
Options.hide();
Tools.hide();
Window.hide();
Debug.hide();
}
void Menu::maxi()
{
AdjustWindows();
Options.show();
Tools.show();
Window.show();
Debug.show();
} }
void Menu::initWindows() void Menu::initWindows()
@ -1118,15 +1225,13 @@ void Menu::onClose (finalcut::FCloseEvent* ev)
void Menu::loadLevel() void Menu::loadLevel()
{ {
log.append("Chargement du scénario "+scenario.levels[scenar.getselected()].title); log.append("Application - charge niveau.......................[ INFO ]");
view.setText("Objectif: "+scenario.levels[scenar.getselected()].title); view.setText("Objectif: "+scenario.levels[scenar.getselected()].title);
view.clear(); view.clear();
view.append(scenario.levels[scenar.getselected()].description); view.append(scenario.levels[scenar.getselected()].description);
tuto.clear(); tuto.clear();
tuto.append(scenario.levels[scenar.getselected()].tutorial); tuto.append(scenario.levels[scenar.getselected()].tutorial);
regs.set("En attente d'initialisation...");
edit.set(scenario.levels[scenar.getselected()].code); edit.set(scenario.levels[scenar.getselected()].code);
AdjustWindows();
debug.clear(); debug.clear();
vm.Unconfigure(); vm.Unconfigure();
vm.setRights(scenario.levels[scenar.getselected()].rights); vm.setRights(scenario.levels[scenar.getselected()].rights);
@ -1165,10 +1270,18 @@ void Menu::about()
} }
void Menu::showInstr() void Menu::showInstr()
{
try
{ {
debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3)); debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3));
debug.setmark(vm.getLine()); debug.setmark(vm.getLine());
} }
catch(exception const& e)
{
log.append(e.what());
vm.Halt();
}
}
void Menu::refresh() void Menu::refresh()
{ {
@ -1178,10 +1291,18 @@ void Menu::refresh()
flags.set("Attente..."); flags.set("Attente...");
} }
else else
{
try
{ {
regs.set(vm.getRegs()); regs.set(vm.getRegs());
flags.set(vm.getFlags()); flags.set(vm.getFlags());
} }
catch(exception const& e)
{
log.append(e.what());
vm.Halt();
}
}
if (!vm.isExecuted()) if (!vm.isExecuted())
{ {
finalcut::FApplication::setDarkTheme(); finalcut::FApplication::setDarkTheme();

25
ia86.h
View File

@ -143,6 +143,26 @@ struct Unasm
std::vector<uint32_t> pos; std::vector<uint32_t> pos;
}; };
class Error: public exception
{
public:
Error(string const& phrase="") throw()
:m_phrase(phrase)
{}
virtual const char* what() const throw()
{
return m_phrase.c_str();
}
virtual ~Error() throw()
{}
private:
string m_phrase;
};
class ScenarioWindow final : public finalcut::FDialog class ScenarioWindow final : public finalcut::FDialog
{ {
public: public:
@ -156,6 +176,7 @@ class ScenarioWindow final : public finalcut::FDialog
ScenarioWindow& operator = (const ScenarioWindow&) = delete; ScenarioWindow& operator = (const ScenarioWindow&) = delete;
// Method // Method
int getselected(); int getselected();
bool load(std::string file);
private: private:
// Method // Method
int selected; int selected;
@ -296,6 +317,8 @@ class VMEngine
uint32_t getEIP(); uint32_t getEIP();
uint16_t getCS(); uint16_t getCS();
uint16_t getDS(); uint16_t getDS();
uint16_t getES();
uint16_t getSS();
private: private:
int rights; int rights;
void Init(); void Init();
@ -344,6 +367,8 @@ class Menu final : public finalcut::FDialog
void trace(); void trace();
void step(); void step();
void about(); void about();
void mini();
void maxi();
void AdjustWindows(); void AdjustWindows();
void initWindows(); void initWindows();
void initLayout() override; void initLayout() override;