Ajout gestion des erreurs, amélioration du chargement des scénarios
This commit is contained in:
parent
131d311196
commit
eaadfa4bc8
449
ia86.cpp
449
ia86.cpp
|
@ -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,25 +87,11 @@ 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();
|
||||||
std::vector<std::string> items;
|
|
||||||
for(size_t i=0; i < scenario.levels.size(); i++)
|
|
||||||
{
|
|
||||||
((Menu*)this->getParent())->log.append(".");
|
|
||||||
items.clear();
|
|
||||||
items.push_back(to_string(i));
|
|
||||||
items.push_back(scenario.levels[i].title);
|
|
||||||
const finalcut::FStringList line (items.begin(), items.end());
|
|
||||||
listview.insert (line);
|
|
||||||
}
|
|
||||||
listview.addCallback
|
listview.addCallback
|
||||||
(
|
(
|
||||||
"row-changed",
|
"row-changed",
|
||||||
|
@ -110,6 +99,27 @@ ScenarioWindow::ScenarioWindow (finalcut::FWidget* parent)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScenarioWindow::load(std::string file)
|
||||||
|
{
|
||||||
|
scenario=readscenario(file);
|
||||||
|
if (scenario.levels.size()>0)
|
||||||
|
{
|
||||||
|
std::vector<std::string> items;
|
||||||
|
for(size_t i=0; i < scenario.levels.size(); i++)
|
||||||
|
{
|
||||||
|
//((Menu*)this->getParent())->log.append(".");
|
||||||
|
items.clear();
|
||||||
|
items.push_back(to_string(i));
|
||||||
|
items.push_back(scenario.levels[i].title);
|
||||||
|
const finalcut::FStringList line (items.begin(), items.end());
|
||||||
|
listview.insert (line);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ScenarioWindow::click()
|
void ScenarioWindow::click()
|
||||||
{
|
{
|
||||||
selected=listview.getindex();
|
selected=listview.getindex();
|
||||||
|
@ -308,37 +318,53 @@ void TextWindow::adjustSize()
|
||||||
|
|
||||||
Desassembler::Desassembler(TextWindow *log) : log(log)
|
Desassembler::Desassembler(TextWindow *log) : log(log)
|
||||||
{
|
{
|
||||||
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
|
try
|
||||||
if (err != CS_ERR_OK)
|
{
|
||||||
log->append("Erreur : Initialisation du désassembleur X86");
|
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
|
||||||
else
|
if (err != CS_ERR_OK)
|
||||||
log->append("Initialisation du désassembleur X86");
|
Error("Désassembleur - initialisation....................[ERREUR]");
|
||||||
|
log->append("Désassembleur - initialisation....................[ OK ]");
|
||||||
|
}
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
srcsize=cs_disasm(handle, content, size, address, 0, &insn);
|
try
|
||||||
if (srcsize == 0)
|
{
|
||||||
log->append("Erreur de désassemblage");
|
srcsize=cs_disasm(handle, content, size, address, 0, &insn);
|
||||||
else
|
if (srcsize == 0)
|
||||||
{
|
Error("Désassembleur - Désassemblage.....................[ERREUR]");
|
||||||
log->append("Désassemblage réussi, taille du source :"+to_string(srcsize));
|
else
|
||||||
unasm->src.clear();
|
{
|
||||||
unasm->pos.clear();
|
if (debug) log->append("Désassemblage - Désassemblage.....................[ "+to_string(srcsize)+"l ]");
|
||||||
for (size_t j = 0; j < srcsize; j++)
|
unasm->src.clear();
|
||||||
{
|
unasm->pos.clear();
|
||||||
std::string *bytes = new std::string("");
|
for (size_t j = 0; j < srcsize; j++)
|
||||||
for (size_t k = 0; k < insn[j].size; k++)
|
{
|
||||||
*bytes=*bytes+intToHexString((int)insn[j].bytes[k], 2);
|
std::string *bytes = new std::string("");
|
||||||
std::string adresse = intToHexString((int)insn[j].address, 8);
|
for (size_t k = 0; k < insn[j].size; k++)
|
||||||
std::string *menmonic = new std::string((char *)insn[j].mnemonic);
|
*bytes=*bytes+intToHexString((int)insn[j].bytes[k], 2);
|
||||||
std::string *op_str = new std::string((char *)insn[j].op_str);
|
std::string adresse = intToHexString((int)insn[j].address, 8);
|
||||||
std::array<std::string, 5> *array = new std::array<std::string, 5>{"", adresse, *bytes, *menmonic, *op_str};
|
std::string *menmonic = new std::string((char *)insn[j].mnemonic);
|
||||||
unasm->src.push_back(*array);
|
std::string *op_str = new std::string((char *)insn[j].op_str);
|
||||||
unasm->pos.push_back(insn[j].address);
|
std::array<std::string, 5> *array = new std::array<std::string, 5>{"", adresse, *bytes, *menmonic, *op_str};
|
||||||
|
unasm->src.push_back(*array);
|
||||||
|
unasm->pos.push_back(insn[j].address);
|
||||||
|
}
|
||||||
|
cs_free(insn, srcsize);
|
||||||
}
|
}
|
||||||
cs_free(insn, srcsize);
|
|
||||||
}
|
}
|
||||||
|
catch(exception const& e)
|
||||||
|
{
|
||||||
|
unasm->src.clear();
|
||||||
|
unasm->pos.clear();
|
||||||
|
log->append(e.what());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -347,88 +373,88 @@ 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);
|
{
|
||||||
if (err != KS_ERR_OK) {
|
err = ks_open(KS_ARCH_X86, KS_MODE_16, &ks);
|
||||||
out << "Erreur : Initialisation de l'assembleur X86" << err;
|
if (err != KS_ERR_OK)
|
||||||
log->append(out.str());
|
Error("Assembleur - initialisation.......................[ERREUR]");
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
std::vector<Code> mcode;
|
try
|
||||||
std::istringstream stream(source);
|
|
||||||
std::string line;
|
|
||||||
std::regex regex("^ *.org 0x([0-F]+)$");
|
|
||||||
Code *code=new Code;
|
|
||||||
bool begin=true;
|
|
||||||
int org=address;
|
|
||||||
code->address=org;
|
|
||||||
while (std::getline(stream, line))
|
|
||||||
{
|
{
|
||||||
if (line.find(".org") != std::string::npos)
|
std::vector<Code> mcode;
|
||||||
|
std::istringstream stream(source);
|
||||||
|
std::string line;
|
||||||
|
std::regex regex("^ *.org 0x([0-F]+)$");
|
||||||
|
Code *code=new Code;
|
||||||
|
bool begin=true;
|
||||||
|
int org=address;
|
||||||
|
code->address=org;
|
||||||
|
while (std::getline(stream, line))
|
||||||
{
|
{
|
||||||
std::smatch match;
|
if (line.find(".org") != std::string::npos)
|
||||||
if(std::regex_search(line, match, regex))
|
|
||||||
{
|
{
|
||||||
org=std::stoul(match.str(1), nullptr, 16);
|
std::smatch match;
|
||||||
}
|
if(std::regex_search(line, match, regex))
|
||||||
if (!begin)
|
{
|
||||||
|
org=std::stoul(match.str(1), nullptr, 16);
|
||||||
|
}
|
||||||
|
if (!begin)
|
||||||
|
{
|
||||||
|
mcode.push_back(*code);
|
||||||
|
code=new Code;
|
||||||
|
code->address=org;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
mcode.push_back(*code);
|
code->src.append(line+"\n");
|
||||||
code=new Code;
|
|
||||||
code->address=org;
|
|
||||||
}
|
}
|
||||||
}
|
begin=false;
|
||||||
else
|
|
||||||
{
|
|
||||||
code->src.append(line+"\n");
|
|
||||||
}
|
}
|
||||||
begin=false;
|
if (code->src.size()>0)
|
||||||
}
|
mcode.push_back(*code);
|
||||||
if (code->src.size()>0)
|
for(size_t i=0;i<mcode.size();i++)
|
||||||
mcode.push_back(*code);
|
{
|
||||||
for(size_t i=0;i<mcode.size();i++)
|
//log->append(mcode[i].src);
|
||||||
|
mcode[i].assembled=false;
|
||||||
|
mcode[i].loaded=false;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
catch(exception const& e)
|
||||||
{
|
{
|
||||||
log->append("Section N°"+std::to_string(i)+" : "+intToHexString(mcode[i].address,8)+" -> "+to_string(mcode[i].src.size())+" octets");
|
std::vector<Code> mcode;
|
||||||
log->append(mcode[i].src);
|
log->append(e.what());
|
||||||
mcode[i].assembled=false;
|
return mcode;
|
||||||
mcode[i].loaded=false;
|
|
||||||
this->Assemble(&mcode[i]);
|
|
||||||
}
|
}
|
||||||
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);
|
{
|
||||||
if (err != UC_ERR_OK) {
|
err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc);
|
||||||
out << "Impossible d'initialiser la machine virtuelle: " << err;
|
if (err != UC_ERR_OK)
|
||||||
log->append(out.str());
|
Error("VM IA86 - initilisation...........................[ERREUR]");
|
||||||
|
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;
|
||||||
|
@ -697,23 +732,33 @@ int VMEngine::getLine()
|
||||||
|
|
||||||
void VMEngine::Configure(State *init, std::string code)
|
void VMEngine::Configure(State *init, std::string code)
|
||||||
{
|
{
|
||||||
int status;
|
try
|
||||||
mcode.clear();
|
{
|
||||||
mcode=asmer.MultiAssemble(code,init->dump.regs.eip);
|
int status;
|
||||||
Close();
|
mcode.clear();
|
||||||
Init();
|
mcode=asmer.MultiAssemble(code,init->dump.regs.eip);
|
||||||
this->initialized=false;
|
if (mcode.size()==0)
|
||||||
this->executed=false;
|
return;
|
||||||
log->append("Mappage de la mémoire virtuelle");
|
Close();
|
||||||
uc_mem_map(uc, 0, 1 * 1024 * 1024, UC_PROT_ALL);
|
Init();
|
||||||
for(size_t i=0;i<mcode.size();i++)
|
|
||||||
SetMem(&mcode[i]);
|
|
||||||
status=verify();
|
|
||||||
if (status==0)
|
|
||||||
this->initialized=true;
|
|
||||||
else
|
|
||||||
this->initialized=false;
|
this->initialized=false;
|
||||||
SetRegs(init);
|
this->executed=false;
|
||||||
|
//log->append("Mappage de la mémoire virtuelle");
|
||||||
|
uc_mem_map(uc, 0, 1 * 1024 * 1024, UC_PROT_ALL);
|
||||||
|
for(size_t i=0;i<mcode.size();i++)
|
||||||
|
SetMem(&mcode[i]);
|
||||||
|
status=verify();
|
||||||
|
if (status==0)
|
||||||
|
this->initialized=true;
|
||||||
|
else
|
||||||
|
this->initialized=false;
|
||||||
|
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)
|
||||||
|
@ -872,17 +931,25 @@ void VMEngine::SetRegs(State *init)
|
||||||
|
|
||||||
void VMEngine::Run(uint32_t end,uint64_t timeout)
|
void VMEngine::Run(uint32_t end,uint64_t timeout)
|
||||||
{
|
{
|
||||||
err=uc_emu_start(uc, this->getCurrent(), end, timeout, 0);
|
try
|
||||||
if (err)
|
|
||||||
{
|
{
|
||||||
log->append("Erreur lors de l'exécution de la machine virtuelle");
|
err=uc_emu_start(uc, this->getCurrent(), end, timeout, 0);
|
||||||
this->executed=false;
|
if (err)
|
||||||
return;
|
{
|
||||||
}
|
this->Halt();
|
||||||
else
|
Error("VM IA86 - execution...............................[ERREUR]");
|
||||||
{
|
}
|
||||||
this->executed="true";
|
else
|
||||||
}
|
{
|
||||||
|
if (!this->executed)
|
||||||
|
log->append("VM IA86 - execution...............................[ INFO ]");
|
||||||
|
this->executed="true";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(exception const& e)
|
||||||
|
{
|
||||||
|
log->append(e.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -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"))
|
||||||
if (scenario.levels.size()>0)
|
{
|
||||||
|
log.append("Application - charge scénarios....................[ OK ]");
|
||||||
|
log.append("-={ "+ scenario.title+" }=-");
|
||||||
|
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);
|
||||||
|
@ -1166,8 +1271,16 @@ void Menu::about()
|
||||||
|
|
||||||
void Menu::showInstr()
|
void Menu::showInstr()
|
||||||
{
|
{
|
||||||
debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3));
|
try
|
||||||
debug.setmark(vm.getLine());
|
{
|
||||||
|
debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3));
|
||||||
|
debug.setmark(vm.getLine());
|
||||||
|
}
|
||||||
|
catch(exception const& e)
|
||||||
|
{
|
||||||
|
log.append(e.what());
|
||||||
|
vm.Halt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::refresh()
|
void Menu::refresh()
|
||||||
|
@ -1179,8 +1292,16 @@ void Menu::refresh()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
regs.set(vm.getRegs());
|
try
|
||||||
flags.set(vm.getFlags());
|
{
|
||||||
|
regs.set(vm.getRegs());
|
||||||
|
flags.set(vm.getFlags());
|
||||||
|
}
|
||||||
|
catch(exception const& e)
|
||||||
|
{
|
||||||
|
log.append(e.what());
|
||||||
|
vm.Halt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!vm.isExecuted())
|
if (!vm.isExecuted())
|
||||||
{
|
{
|
||||||
|
|
25
ia86.h
25
ia86.h
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue