Finalisation du multi section

This commit is contained in:
Horde Nicolas 2021-07-09 00:51:05 +02:00
parent 65a871151a
commit 6229019b75
2 changed files with 113 additions and 92 deletions

161
ia86.cpp
View File

@ -311,10 +311,11 @@ Desassembler::Desassembler(TextWindow *log) : log(log)
log->append("Initialisation du désassembleur X86"); log->append("Initialisation du désassembleur X86");
} }
std::vector<std::array<std::string, 5>> Desassembler::Desassemble(Code *code) std::vector<std::array<std::string, 5>> Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size)
{ {
std::stringstream out; std::stringstream out;
srcsize=cs_disasm(handle, code->content, code->size, code->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
@ -352,12 +353,11 @@ Assembler::Assembler(TextWindow *log) : log(log)
} }
else else
log->append("Initialisation de l'assembleur X86"); log->append("Initialisation de l'assembleur X86");
code->assembled=false;
} }
MultiCode *Assembler::MultiAssemble(std::string source,uint32_t address) std::vector<Code> Assembler::MultiAssemble(std::string source,uint32_t address)
{ {
MultiCode *mcode=new MultiCode; std::vector<Code> mcode;
std::istringstream stream(source); std::istringstream stream(source);
std::string line; std::string line;
std::regex regex("^ *.org 0x([0-F]+)$"); std::regex regex("^ *.org 0x([0-F]+)$");
@ -376,7 +376,7 @@ MultiCode *Assembler::MultiAssemble(std::string source,uint32_t address)
} }
if (!begin) if (!begin)
{ {
mcode->zones.push_back(*code); mcode.push_back(*code);
code=new Code; code=new Code;
code->address=org; code->address=org;
} }
@ -388,16 +388,15 @@ MultiCode *Assembler::MultiAssemble(std::string source,uint32_t address)
begin=false; begin=false;
} }
if (code->src.size()>0) if (code->src.size()>0)
mcode->zones.push_back(*code); mcode.push_back(*code);
for(size_t i=0;i<mcode->zones.size();i++) for(size_t i=0;i<mcode.size();i++)
{ {
log->append("Section N°"+std::to_string(i)+" : "+intToHexString(mcode->zones[i].address,8)+" -> "+to_string(mcode->zones[i].src.size())+" octets"); log->append("Section N°"+std::to_string(i)+" : "+intToHexString(mcode[i].address,8)+" -> "+to_string(mcode[i].src.size())+" octets");
log->append(mcode->zones[i].src); log->append(mcode[i].src);
mcode->zones[i].assembled=false; mcode[i].assembled=false;
mcode->zones[i].initialized=false; mcode[i].loaded=false;
this->Assemble(&mcode->zones[i]); this->Assemble(&mcode[i]);
} }
mcode->executed=false;
return mcode; return mcode;
} }
@ -494,6 +493,11 @@ std::string VMEngine::getFlags(int rights)
return out.str(); return out.str();
} }
uint8_t *VMEngine::getRamRaw(uint32_t address, uint32_t size)
{
}
std::string VMEngine::getRegs(int rights) std::string VMEngine::getRegs(int rights)
{ {
int regsi836[] = { int regsi836[] = {
@ -604,62 +608,93 @@ void VMEngine::Init()
log->append("Initialisation de l'ordinateur IA86"); log->append("Initialisation de l'ordinateur IA86");
} }
bool VMEngine::isExecuted()
{
return this->executed;
}
bool VMEngine::isInitialized()
{
return this->initialized;
}
void VMEngine::Close() void VMEngine::Close()
{ {
uc_close(uc); uc_close(uc);
} }
void VMEngine::Halt(Code *code) void VMEngine::Halt()
{ {
code->executed=false; this->executed=false;
} }
void VMEngine::Configure(State *init, Code *code) void VMEngine::Change()
{ {
this->executed=false;
this->initialized=false;
}
void VMEngine::Configure(State *init, std::vector<Code> newmcode)
{
int status;
mcode=newmcode;
Close(); Close();
Init(); Init();
code->assembled=false; this->initialized=false;
code->initialized=false; this->executed=false;
code->executed=false;
log->append("Mappage de la mémoire virtuelle"); log->append("Mappage de la mémoire virtuelle");
uc_mem_map(uc, init->dump.regs.eip, 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++)
SetMem(&mcode[i]);
status=verify();
if (status==0)
this->initialized=true;
else
this->initialized=false;
SetRegs(init);
} }
void VMEngine::Prepare(State *init, Code *code) int VMEngine::verify()
{ {
SetMem(init, code); for(Code code: mcode)
SetRegs(init, code); {
if (!code.assembled)
return 1;
else if (!code.loaded)
return 2;
}
return 0;
} }
int VMEngine::getEIP(Code *code) int VMEngine::getEIP()
{ {
int eip=-666; int eip=-666;
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<code->address) || (eip>code->address+code->size)) if ((eip<0) || (eip>1*1024*1024))
eip=-666; eip=-666;
return eip; return eip;
} }
void VMEngine::SetMem(State *init, Code *code) void VMEngine::SetMem(Code *code)
{ {
err = uc_mem_write(uc, init->dump.regs.eip, code->content, code->size); err = uc_mem_write(uc, code->address, code->content, code->size);
if (err) if (err)
{ {
code->initialized=false; 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 else
{ {
code->initialized=true; code->loaded=true;
log->append("Chargement en mémoire de la machine virtuelle, taille: "+to_string(code->size)); log->append("Chargement en mémoire de la machine virtuelle, taille: "+to_string(code->size));
} }
} }
void VMEngine::SetRegs(State *init, Code *code) void VMEngine::SetRegs(State *init)
{ {
std::stringstream out; std::stringstream out;
out << "Configuration initiale de l'ordinateur IA86:\n "; out << "Configuration initiale de l'ordinateur IA86:\n ";
@ -747,18 +782,18 @@ void VMEngine::SetRegs(State *init, Code *code)
log->append(out.str()); log->append(out.str());
} }
void VMEngine::Run(Code *code,uint32_t start, uint32_t stop, uint64_t timeout) void VMEngine::Run(State *init,uint64_t timeout)
{ {
err=uc_emu_start(uc, start, stop, timeout, 0); err=uc_emu_start(uc, init->dump.regs.eip, 0xFFFF, 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");
code->executed=false; this->executed=false;
return; return;
} }
else else
{ {
code->executed="true"; this->executed="true";
} }
} }
@ -892,8 +927,6 @@ void Menu::initMenus()
Breakpoint.setStatusbarMessage ("Enlève ou met un point d'arrêt"); Breakpoint.setStatusbarMessage ("Enlève ou met un point d'arrêt");
End.addAccelerator (FKey::F6); End.addAccelerator (FKey::F6);
End.setStatusbarMessage ("Termine le programme et remet à zéro la machine IA86"); End.setStatusbarMessage ("Termine le programme et remet à zéro la machine IA86");
Init.addAccelerator (FKey::F3);
Init.setStatusbarMessage ("Initialise la machine IA86");
About.setStatusbarMessage ("A propos de IA86"); About.setStatusbarMessage ("A propos de IA86");
} }
@ -953,11 +986,6 @@ void Menu::initMenusCallBack()
this, this,
&Menu::about &Menu::about
); );
Init.addCallback (
"clicked",
this,
&Menu::verify
);
} }
void Menu::initMisc() void Menu::initMisc()
@ -1008,18 +1036,19 @@ void Menu::loadLevel()
edit.set(scenario.levels[scenar.getselected()].code); edit.set(scenario.levels[scenar.getselected()].code);
AdjustWindows(); AdjustWindows();
debug.clear(); debug.clear();
vm.Configure(&scenario.levels[scenar.getselected()].init,code); vm.Change();
end();
} }
void Menu::end() void Menu::end()
{ {
vm.Halt(code); vm.Halt();
} }
void Menu::compile() void Menu::compile()
{ {
mcode=asmer.MultiAssemble(edit.get(),scenario.levels[scenar.getselected()].init.dump.regs.eip); std::vector<Code> mcode;
mcode=asmer.MultiAssemble(edit.get(),scenario.levels[scenar.getselected()].init.dump.regs.eip);
vm.Configure(&scenario.levels[scenar.getselected()].init,mcode);
} }
void Menu::about() void Menu::about()
@ -1043,23 +1072,9 @@ void Menu::about()
AdjustWindows(); AdjustWindows();
} }
bool Menu::verify()
{
if (!code->assembled)
{
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
return false;
}
if (!code->initialized)
vm.Prepare(&scenario.levels[scenar.getselected()].init,code);
if (!code->initialized)
return false;
return true;
}
void Menu::refresh() void Menu::refresh()
{ {
if (!code->initialized) if (!vm.isInitialized())
{ {
regs.set("En attente d'initialisation..."); regs.set("En attente d'initialisation...");
flags.set("Attente..."); flags.set("Attente...");
@ -1071,7 +1086,7 @@ void Menu::refresh()
flags.set(vm.getFlags(scenario.levels[scenar.getselected()].rights)); flags.set(vm.getFlags(scenario.levels[scenar.getselected()].rights));
//debug.setindex(vm.getEIP(code)); //debug.setindex(vm.getEIP(code));
} }
if (!code->executed) if (!vm.isExecuted())
{ {
finalcut::FApplication::setDarkTheme(); finalcut::FApplication::setDarkTheme();
} }
@ -1087,18 +1102,30 @@ void Menu::refresh()
void Menu::exec() void Menu::exec()
{ {
if (!verify()) return; if (!vm.isInitialized())
vm.Run(code,code->address,code->address+code->size,0); 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(&scenario.levels[scenar.getselected()].init,0);
} }
void Menu::trace() void Menu::trace()
{ {
if (!verify()) return; exec();
} }
void Menu::step() void Menu::step()
{ {
if (!verify()) return; exec();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

44
ia86.h
View File

@ -133,18 +133,10 @@ struct Code
size_t size; size_t size;
uint8_t *content; uint8_t *content;
bool assembled; bool assembled;
bool initialized; bool loaded;
bool executed;
std::string src; std::string src;
}; };
struct MultiCode
{
std::vector<Code> zones;
uint32_t entrypoint;
bool executed;
};
class ScenarioWindow final : public finalcut::FDialog class ScenarioWindow final : public finalcut::FDialog
{ {
public: public:
@ -247,7 +239,7 @@ class Desassembler
{ {
public: public:
Desassembler(TextWindow *log); Desassembler(TextWindow *log);
std::vector<std::array<std::string, 5>> Desassemble(Code *code); std::vector<std::array<std::string, 5>> Desassemble(uint8_t *content, uint32_t address,uint32_t size);
private: private:
csh handle; csh handle;
cs_insn *insn; cs_insn *insn;
@ -265,32 +257,38 @@ class Assembler
public: public:
Assembler(TextWindow *log); Assembler(TextWindow *log);
void Assemble(Code *code); void Assemble(Code *code);
MultiCode *MultiAssemble(std::string source,uint32_t address); std::vector<Code> MultiAssemble(std::string source,uint32_t address);
private: private:
ks_engine *ks; ks_engine *ks;
ks_err err; ks_err err;
int err2; int err2;
TextWindow *log; TextWindow *log;
TextEditWindow *edit; TextEditWindow *edit;
Code *code = new Code;
}; };
class VMEngine class VMEngine
{ {
public: public:
VMEngine(TextWindow *log); VMEngine(TextWindow *log);
void Configure(State *init,Code *code); void Configure(State *init, std::vector<Code> mcode);
void Halt(Code *code); void Halt();
void Run(Code *code, uint32_t start, uint32_t stop, uint64_t timeout); void Change();
std::string getFlags(int level); void Run(State *init,uint64_t timeout);
std::string getRegs(int level); std::string getFlags(int rights);
void Prepare(State *init, Code *code); std::string getRegs(int rights);
void SetMem(State *init, Code *code); void SetMem(Code *code);
void SetRegs(State *init, Code *code); void SetRegs(State *init);
int getEIP(Code *code); uint8_t *getRamRaw(uint32_t address, uint32_t size);
int getEIP();
int verify();
bool isExecuted();
bool isInitialized();
private: private:
std::vector<Code> mcode;
void Init(); void Init();
void Close(); void Close();
bool executed=false;
bool initialized=false;
uc_engine *uc; uc_engine *uc;
uc_err err; uc_err err;
TextWindow *log; TextWindow *log;
@ -311,8 +309,6 @@ class Menu final : public finalcut::FDialog
void loadLevel(); void loadLevel();
TextWindow log{this}; TextWindow log{this};
private: private:
MultiCode *mcode = new MultiCode();
Code *code=new Code();
void onTimer (finalcut::FTimerEvent*) override; void onTimer (finalcut::FTimerEvent*) override;
void refresh(); void refresh();
void configureFileMenuItems(); void configureFileMenuItems();
@ -326,7 +322,6 @@ class Menu final : public finalcut::FDialog
void exec(); void exec();
void trace(); void trace();
void step(); void step();
bool verify();
void about(); void about();
void AdjustWindows(); void AdjustWindows();
void initWindows(); void initWindows();
@ -348,7 +343,6 @@ class Menu final : public finalcut::FDialog
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};
finalcut::FMenu Debug{"&Déboguage", &Menubar}; finalcut::FMenu Debug{"&Déboguage", &Menubar};
finalcut::FMenuItem Init{"&Initialiser", &Debug};
finalcut::FMenuItem Run{"&Exécuter", &Debug}; finalcut::FMenuItem Run{"&Exécuter", &Debug};
finalcut::FMenuItem End{"&Terminer", &Debug}; finalcut::FMenuItem End{"&Terminer", &Debug};
finalcut::FMenuItem TraceInto{"Pas à pas &détaillé", &Debug}; finalcut::FMenuItem TraceInto{"Pas à pas &détaillé", &Debug};