Ajout de l'execution de la VM, de niveau d'affichage des registres

This commit is contained in:
Horde Nicolas 2021-07-05 21:48:32 +02:00
parent cca897fc06
commit aff202b8ba
1 changed files with 128 additions and 60 deletions

188
test.cpp
View File

@ -134,7 +134,8 @@ class Goal {
std::string title; std::string title;
std::string description; std::string description;
std::string help; std::string help;
std::string code; std::string code;
int level;
State init; State init;
State goal; State goal;
}; };
@ -146,6 +147,8 @@ class Code
size_t size; size_t size;
unsigned char *content; unsigned char *content;
bool assembled; bool assembled;
bool executed;
bool loaded;
}; };
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -155,8 +158,7 @@ class Code
std::string intToHexString(int intValue, int size) { std::string intToHexString(int intValue, int size) {
string hexStr; string hexStr;
std::stringstream sstream; std::stringstream sstream;
sstream << std::setfill ('0') << std::setw(size) sstream << std::setfill ('0') << std::setw(size) << std::hex << (int)intValue;
<< std::hex << (int)intValue;
hexStr= sstream.str(); hexStr= sstream.str();
sstream.clear(); sstream.clear();
return hexStr; return hexStr;
@ -170,7 +172,7 @@ std::string intToHexString(int intValue, int size) {
Goal goals[]= Goal goals[]=
{ {
{ {
"L'instruction MOV et les registres","Le but est de bouger du registre AX au registre BX, l' ensemble des données", "Aide....", "inc ax\ndec cx\nmov ax,0x33\nadd ax,[bx+2]", "L'instruction MOV et les registres","Le but est de bouger du registre AX au registre BX, l' ensemble des données", "Aide....", "inc ax\ndec cx\nmov ax,0x33\nadd dx,[bx+2]\nmov cx,12", 8,
{ {
{ {
{}, {},
@ -309,15 +311,14 @@ void TextFixedWindow::set(std::string str)
void TextFixedWindow::initLayout() void TextFixedWindow::initLayout()
{ {
fixedtext.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1}); fixedtext.setGeometry (FPoint{2, 3}, FSize{getWidth()-2, getHeight() - 2});
setMinimumSize (FSize{51, 6});
FDialog::initLayout(); FDialog::initLayout();
} }
void TextFixedWindow::adjustSize() void TextFixedWindow::adjustSize()
{ {
finalcut::FDialog::adjustSize(); finalcut::FDialog::adjustSize();
fixedtext.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1)); fixedtext.setGeometry (FPoint{2, 3}, FSize(getWidth()-2, getHeight() - 2));
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -366,13 +367,14 @@ void TextEditWindow::set(std::string str)
void TextEditWindow::initLayout() void TextEditWindow::initLayout()
{ {
fixedtext.setGeometry (FPoint{2, 3}, FSize(12, 12)); fixedtext.setGeometry (FPoint{2, 3}, FSize{getWidth()-2, getHeight() - 2});
FDialog::initLayout(); FDialog::initLayout();
} }
void TextEditWindow::adjustSize() void TextEditWindow::adjustSize()
{ {
finalcut::FDialog::adjustSize(); finalcut::FDialog::adjustSize();
fixedtext.setGeometry (FPoint{2, 3}, FSize{getWidth()-2, getHeight() - 2});
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -422,7 +424,6 @@ void TextWindow::append(const finalcut::FString& str)
void TextWindow::initLayout() void TextWindow::initLayout()
{ {
scrolltext.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1}); scrolltext.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1});
setMinimumSize (FSize{51, 6});
FDialog::initLayout(); FDialog::initLayout();
} }
@ -561,8 +562,8 @@ class VMEngine
public: public:
VMEngine(TextWindow *log); VMEngine(TextWindow *log);
void Configure(State *init,Code *code); void Configure(State *init,Code *code);
void Run(uint32_t start, uint32_t stop); void Run(Code *code, uint32_t start, uint32_t stop, uint64_t timeout);
std::string getRegs(); std::string getRegs(int level);
private: private:
uc_engine *uc; uc_engine *uc;
uc_err err; uc_err err;
@ -580,8 +581,20 @@ VMEngine::VMEngine(TextWindow *log) : log(log)
else else
log->append("Initialisation de l'ordinateur IA86"); log->append("Initialisation de l'ordinateur IA86");
} }
//EAX:00000000 | AX:0000 | AH:00 | AL:00 // Level 1 : IP AL
std::string VMEngine::getRegs() // Level 2 : IP AX
// Level 3 : IP AX BX CX DX
// Level 4 : IP AX BX CX DX FLAGS
// Level 5 : IP AX BX CX DX FLAGS SI DI
// Level 6 : IP AX BX CX DX FLAGS SI DI SP BP
// Level 7 : IP AX BX CX DX FLAGS SI DI SP BP CS DS ES SS
// Level 8 : IP AX BX CX DX FLAGS SI DI SP BP CS DS ES SS FS GS
// Level 9 : EIP EAX EBX ECX EDX EFLAGS ESI EDI ESP EBP CS DS ES SS FS GS
// 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 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::getRegs(int level)
{ {
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,
@ -601,47 +614,81 @@ std::string VMEngine::getRegs()
return ""; return "";
} }
std::stringstream out; std::stringstream out;
out << "EAX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[0] << " | "; if (level > 8)
out << "AX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[0] & 0x0000FFFF) << " | "; out << "EAX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[0] << " | ";
out << "AH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[0] & 0xFF00) >> 8) << " | "; if (level > 1)
out << "AX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[0] & 0x0000FFFF) << " | ";
if (level > 1)
out << "AH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[0] & 0xFF00) >> 8) << " | ";
out << "AL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[0] & 0xFF) << "\n"; out << "AL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[0] & 0xFF) << "\n";
out << "EBX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[1] << " | "; if (level > 8)
out << "BX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[1] & 0x0000FFFF) << " | "; out << "EBX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[1] << " | ";
out << "BH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[1] & 0xFF00) >> 8) << " | "; if (level > 2)
out << "BL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[1] & 0xFF) << "\n"; out << "BX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[1] & 0x0000FFFF) << " | ";
if (level > 2)
out << "BH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[1] & 0xFF00) >> 8) << " | ";
if (level > 2)
out << "BL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[1] & 0xFF) << "\n";
out << "ECX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[2] << " | "; if (level > 8)
out << "CX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[2] & 0x0000FFFF) << " | "; out << "ECX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[2] << " | ";
out << "CH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[2] & 0xFF00) >> 8) << " | "; if (level > 2)
out << "CL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[2] & 0xFF) << "\n"; out << "CX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[2] & 0x0000FFFF) << " | ";
if (level > 2)
out << "CH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[2] & 0xFF00) >> 8) << " | ";
if (level > 2)
out << "CL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[2] & 0xFF) << "\n";
out << "EDX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[3] << " | "; if (level > 8)
out << "DX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[3] & 0x0000FFFF) << " | "; out << "EDX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[3] << " | ";
out << "DH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[3] & 0xFF00) >> 8) << " | "; if (level > 2)
out << "DL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[3] & 0xFF) << "\n"; out << "DX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[3] & 0x0000FFFF) << " | ";
if (level > 2)
out << "DH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[3] & 0xFF00) >> 8) << " | ";
if (level > 2)
out << "DL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[3] & 0xFF) << "\n";
out << "ESI:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[4] << " | "; if (level > 8)
out << "SI:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[4] & 0x0000FFFF) << "\n"; out << "ESI:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[4] << " | ";
out << "EDI:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[5] << " | "; if (level > 4)
out << "DI:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[5] & 0x0000FFFF) << "\n"; out << "SI:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[4] & 0x0000FFFF) << "\n";
if (level > 8)
out << "EDI:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[5] << " | ";
if (level > 4)
out << "DI:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[5] & 0x0000FFFF) << "\n";
out << "EBP:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[6] << " | "; if (level > 8)
out << "BP:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[6] & 0x0000FFFF) << "\n"; out << "EBP:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[6] << " | ";
out << "ESP:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[7] << " | "; if (level > 5)
out << "SP:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[7] & 0x0000FFFF) << "\n"; out << "BP:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[6] & 0x0000FFFF) << "\n";
if (level > 8)
out << "ESP:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[7] << " | ";
if (level > 5)
out << "SP:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[7] & 0x0000FFFF) << "\n";
out << "CS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[8] & 0x0000FFFF) << " | "; if (level > 6)
out << "DS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[9] & 0x0000FFFF) << " | "; out << "CS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[8] & 0x0000FFFF) << " | ";
out << "ES:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[10] & 0x0000FFFF) << "\n"; if (level > 6)
out << "SS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[11] & 0x0000FFFF) << " | "; out << "DS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[9] & 0x0000FFFF) << " | ";
out << "FS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[12] & 0x0000FFFF) << " | "; if (level > 6)
out << "GS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[13] & 0x0000FFFF) << "\n"; out << "ES:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[10] & 0x0000FFFF) << "\n";
if (level > 6)
out << "SS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[11] & 0x0000FFFF) << " | ";
if (level > 7)
out << "FS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[12] & 0x0000FFFF) << " | ";
if (level > 7)
out << "GS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[13] & 0x0000FFFF) << "\n";
out << "EIP:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[14] << " | "; if (level > 8)
out << "EIP:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[14] << " | ";
out << "IP:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[14] & 0x0000FFFF) << "\n"; out << "IP:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[14] & 0x0000FFFF) << "\n";
out << "EFLAGS:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[15] << ""; if (level > 3)
if (level < 9)
out << "FLAGS:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << (vals[15] & 0xFFFF)<< "";
else
out << "EFLAGS:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[15] << "";
return out.str(); return out.str();
} }
@ -731,18 +778,31 @@ void VMEngine::Configure(State *init, Code *code)
else else
out << "EAX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.eax << " "; out << "EAX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.eax << " ";
log->append(out.str()); log->append(out.str());
uc_mem_map(uc, init->dump.regs.eip,code->size, UC_PROT_ALL); uc_mem_map(uc, init->dump.regs.eip, 1 * 1024 * 1024, UC_PROT_ALL);
if (uc_mem_write(uc, init->dump.regs.eip, &code->content, code->size-1)) err = uc_mem_write(uc, init->dump.regs.eip, code->content, code->size);
if (err)
{ {
code->loaded=false;
log->append("Erreur de copie mémoire dans la machine virtuelle"); log->append("Erreur de copie mémoire dans la machine virtuelle");
return; return;
} }
else
code->loaded=true;
} }
void VMEngine::Run(uint32_t start, uint32_t stop) void VMEngine::Run(Code *code,uint32_t start, uint32_t stop, uint64_t timeout)
{ {
err=uc_emu_start(uc, start, stop, 0, 0); err=uc_emu_start(uc, start, stop, timeout, 0);
getRegs(); if (err)
{
log->append("Erreur lors de l'exécution de la machine virtuelle");
code->executed=false;
return;
}
else
{
code->executed="true";
}
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -791,7 +851,7 @@ class Menu final : public finalcut::FDialog
finalcut::FMenuItem New{"&Nouvelle partie", &Game}; finalcut::FMenuItem New{"&Nouvelle partie", &Game};
finalcut::FMenuItem Line2{&Game}; finalcut::FMenuItem Line2{&Game};
finalcut::FMenuItem Quit{"&Quitter", &Game}; finalcut::FMenuItem Quit{"&Quitter", &Game};
finalcut::FMenu Scenarios{"&Scénarios", &Menubar}; finalcut::FMenu Options{"&Options", &Menubar};
finalcut::FMenu Tools{"&Outils", &Menubar}; finalcut::FMenu Tools{"&Outils", &Menubar};
finalcut::FMenuItem Assemble{"&Compilation", &Tools}; finalcut::FMenuItem Assemble{"&Compilation", &Tools};
finalcut::FMenuItem Rearange{"&Ordonne les fenêtres", &Tools}; finalcut::FMenuItem Rearange{"&Ordonne les fenêtres", &Tools};
@ -857,16 +917,16 @@ void Menu::initWindows()
view.setResizeable(); view.setResizeable();
view.show(); view.show();
regs.setText ("Registres"); regs.setText ("Registres");
regs.setGeometry ( FPoint { 01, 01 }, FSize{39, 15} ); regs.setGeometry ( FPoint { 01, 01 }, FSize{40, 15} );
regs.show(); regs.show();
flags.setText ("Drapeaux"); flags.setText ("Drapeaux");
flags.setGeometry ( FPoint { 59, 01 }, FSize{15, 15} ); flags.setGeometry ( FPoint { 60, 01 }, FSize{15, 15} );
flags.show(); flags.show();
stack.setText ("Pile"); stack.setText ("Pile");
stack.setGeometry ( FPoint { 42, 01 }, FSize{15, 15} ); stack.setGeometry ( FPoint { 43, 01 }, FSize{15, 15} );
stack.show(); stack.show();
mem.setText ("Mémoire"); mem.setText ("Mémoire");
mem.setGeometry ( FPoint { 76, 01 }, FSize{109, 15} ); mem.setGeometry ( FPoint { 77, 01 }, FSize{108, 15} );
mem.show(); mem.show();
tuto.setText ("Guide"); tuto.setText ("Guide");
tuto.setGeometry ( FPoint { 125, 45 }, FSize{60, 11} ); tuto.setGeometry ( FPoint { 125, 45 }, FSize{60, 11} );
@ -884,7 +944,7 @@ void Menu::initWindows()
void Menu::initMenus() void Menu::initMenus()
{ {
Game.setStatusbarMessage ("Menu principal du jeu"); Game.setStatusbarMessage ("Menu principal du jeu");
Scenarios.setStatusbarMessage ("Scénario disponibles"); Options.setStatusbarMessage ("Options du logiciel IA86");
Tools.setStatusbarMessage ("Outils divers"); Tools.setStatusbarMessage ("Outils divers");
Debug.setStatusbarMessage ("Fonctionnalitées de déboguages"); Debug.setStatusbarMessage ("Fonctionnalitées de déboguages");
Window.setStatusbarMessage ("Fenêtres en cours d'exécution"); Window.setStatusbarMessage ("Fenêtres en cours d'exécution");
@ -1018,9 +1078,11 @@ void Menu::exec()
{ {
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !"); finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return; return;
} }
vm.Configure(&goals[scenario].init,code); if (!code->executed)
regs.set(vm.getRegs()); vm.Configure(&goals[scenario].init,code);
vm.Run(code,code->address,code->address+code->size,0);
regs.set(vm.getRegs(goals[scenario].level));
} }
void Menu::trace() void Menu::trace()
@ -1029,7 +1091,10 @@ void Menu::trace()
{ {
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !"); finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return; return;
}} }
if (!code->executed)
vm.Configure(&goals[scenario].init,code);
}
void Menu::step() void Menu::step()
{ {
@ -1037,7 +1102,10 @@ void Menu::step()
{ {
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !"); finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return; return;
}} }
if (!code->executed)
vm.Configure(&goals[scenario].init,code);
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Fonction Main // Fonction Main