Pas à pas & pas à pas détaillé fonctionnel

This commit is contained in:
Horde Nicolas 2021-07-13 09:30:52 +02:00
parent cb1cbae9c9
commit bbb96f6381
3 changed files with 212 additions and 97 deletions

229
ia86.cpp
View File

@ -80,6 +80,17 @@ Scenario scenario;
Unasm unasm; Unasm unasm;
int marker; int marker;
bool debug=true; bool debug=true;
uc_hook uh_mem;
uc_hook uh_code;
uc_hook uh_call;
uc_hook uh_int;
bool step=false;
bool call=false;
bool ok=false;
bool executed=false;
bool initialized=false;
uint32_t hadcall=0x0;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Classe ScenarioWindow // Classe ScenarioWindow
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -153,7 +164,6 @@ InstructionWindow::InstructionWindow (finalcut::FWidget* parent)
{ {
listview.ignorePadding(); listview.ignorePadding();
listview.addColumn ("P");
listview.addColumn ("Adresse"); listview.addColumn ("Adresse");
listview.addColumn ("Opcodes "); listview.addColumn ("Opcodes ");
listview.addColumn ("Mnémo."); listview.addColumn ("Mnémo.");
@ -162,7 +172,7 @@ InstructionWindow::InstructionWindow (finalcut::FWidget* parent)
listview.setFocus(); listview.setFocus();
} }
std::vector<std::array<std::string, 5>> InstructionWindow::get() std::vector<std::array<std::string, 4>> InstructionWindow::get()
{ {
return content; return content;
} }
@ -183,7 +193,7 @@ int InstructionWindow::getsize()
return listview.getCount(); return listview.getCount();
} }
void InstructionWindow::set(std::vector<std::array<std::string, 5>> src) void InstructionWindow::set(std::vector<std::array<std::string, 4>> src)
{ {
content=src; content=src;
listview.clear(); listview.clear();
@ -284,7 +294,7 @@ void TextWindow::append(const finalcut::FString& str)
std::string TextWindow::get() std::string TextWindow::get()
{ {
return scrolltext.getText().toString () ; return scrolltext.getText().toString() ;
} }
void TextWindow::set(const finalcut::FString& str) void TextWindow::set(const finalcut::FString& str)
@ -316,18 +326,18 @@ void TextWindow::adjustSize()
// Classe Desassembler // Classe Desassembler
//---------------------------------------------------------------------- //----------------------------------------------------------------------
Desassembler::Desassembler(TextWindow *log) : log(log) Desassembler::Desassembler(Menu *widget) : widget(widget)
{ {
try 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)
throw Error("Désassembleur - initialisation....................[ERREUR]"); throw Error("Désassembleur - initialisation....................[ERREUR]");
log->append("Désassembleur - initialisation....................[ OK ]"); widget->log.append("Désassembleur - initialisation....................[ OK ]");
} }
catch(exception const& e) catch(exception const& e)
{ {
log->append(e.what()); widget->log.append(e.what());
} }
} }
@ -341,7 +351,7 @@ void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size,
throw Error("Désassembleur - désassemblage.....................[ERREUR]"); throw Error("Désassembleur - désassemblage.....................[ERREUR]");
else else
{ {
if (debug) log->append("Désassemblage - désassemblage.....................[ "+to_string(srcsize)+"l ]"); if (debug) widget->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++)
@ -352,7 +362,7 @@ void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size,
std::string adresse = intToHexString((int)insn[j].address, 8); std::string adresse = intToHexString((int)insn[j].address, 8);
std::string *menmonic = new std::string((char *)insn[j].mnemonic); std::string *menmonic = new std::string((char *)insn[j].mnemonic);
std::string *op_str = new std::string((char *)insn[j].op_str); std::string *op_str = new std::string((char *)insn[j].op_str);
std::array<std::string, 5> *array = new std::array<std::string, 5>{"", adresse, *bytes, *menmonic, *op_str}; std::array<std::string, 4> *array = new std::array<std::string, 4>{adresse, *bytes, *menmonic, *op_str};
unasm->src.push_back(*array); unasm->src.push_back(*array);
unasm->pos.push_back(insn[j].address); unasm->pos.push_back(insn[j].address);
} }
@ -363,7 +373,7 @@ void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size,
{ {
unasm->src.clear(); unasm->src.clear();
unasm->pos.clear(); unasm->pos.clear();
log->append(e.what()); widget->log.append(e.what());
} }
} }
@ -372,18 +382,18 @@ void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size,
// Classe Assembler // Classe Assembler
//---------------------------------------------------------------------- //----------------------------------------------------------------------
Assembler::Assembler(TextWindow *log) : log(log) Assembler::Assembler(Menu *widget) : widget(widget)
{ {
try 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)
throw Error("Assembleur - initialisation.......................[ERREUR]"); throw Error("Assembleur - initialisation.......................[ERREUR]");
log->append("Assembleur - initialisation.......................[ OK ]"); widget->log.append("Assembleur - initialisation.......................[ OK ]");
} }
catch(exception const& e) catch(exception const& e)
{ {
log->append(e.what()); widget->log.append(e.what());
} }
ks_option(ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_NASM); ks_option(ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_NASM);
} }
@ -426,13 +436,13 @@ 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++)
this->Assemble(&mcode[i]); this->Assemble(&mcode[i]);
log->append("Assembleur - assemblage...........................[ OK ]"); widget->log.append("Assembleur - assemblage...........................[ OK ]");
return mcode; return mcode;
} }
catch(exception const& e) catch(exception const& e)
{ {
std::vector<Code> mcode; std::vector<Code> mcode;
log->append(e.what()); widget->log.append(e.what());
return mcode; return mcode;
} }
@ -449,7 +459,7 @@ void Assembler::Assemble(Code *code)
code->size=0; code->size=0;
code->assembled=false; code->assembled=false;
code->loaded=false; code->loaded=false;
throw Error("Assembleur - assemblage...........................[ERREUR]"); throw Error("Assembleur - assemblage...........................[ERREUR]\n Nombre:"+to_string(srcsize)+"\n Erreur:"+std::string(ks_strerror(ks_errno(ks))));
} }
else else
code->assembled=true; code->assembled=true;
@ -459,7 +469,7 @@ void Assembler::Assemble(Code *code)
// Classe VMEngine // Classe VMEngine
//---------------------------------------------------------------------- //----------------------------------------------------------------------
VMEngine::VMEngine(TextWindow *log) : log(log) VMEngine::VMEngine(Menu *widget) : widget(widget)
{ {
code=new uint8_t[500]; code=new uint8_t[500];
Init(); Init();
@ -623,25 +633,26 @@ void VMEngine::Init()
{ {
try try
{ {
hadcall=0;
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)
throw Error("VM IA86 - initilisation...........................[ERREUR]"); throw Error("VM IA86 - initilisation...........................[ERREUR]");
log->append("VM IA86 - initilisation...........................[ OK ]"); widget->log.append("VM IA86 - initilisation...........................[ OK ]");
} }
catch(exception const& e) catch(exception const& e)
{ {
log->append(e.what()); widget->log.append(e.what());
} }
} }
bool VMEngine::isExecuted() bool VMEngine::isExecuted()
{ {
return this->executed; return executed;
} }
bool VMEngine::isInitialized() bool VMEngine::isInitialized()
{ {
return this->initialized; return initialized;
} }
void VMEngine::Close() void VMEngine::Close()
@ -651,31 +662,17 @@ void VMEngine::Close()
void VMEngine::Halt() void VMEngine::Halt()
{ {
if (this->executed) if (executed)
log->append("VM IA86 - arret...................................[ INFO ]"); widget->log.append("VM IA86 - arret...................................[ INFO ]");
this->executed=false; executed=false;
} }
void VMEngine::Unconfigure() void VMEngine::Unconfigure()
{ {
this->Halt(); this->Halt();
if (this->initialized) if (initialized)
log->append("VM IA86 - déconfiguration.........................[ INFO ]"); widget->log.append("VM IA86 - déconfiguration.........................[ INFO ]");
this->initialized=false; initialized=false;
}
uint32_t VMEngine::getNextInstr()
{
uint32_t now=getEIP();
bool flag=false;
for(int pos: unasm.pos)
{
if (pos==now)
flag=true;
else if (flag)
return pos;
}
return 0;
} }
std::string VMEngine::getRam(int segment, int address,int lines, int linesize) std::string VMEngine::getRam(int segment, int address,int lines, int linesize)
@ -708,7 +705,7 @@ std::string VMEngine::getRam(int segment, int address,int lines, int linesize)
return result; return result;
} }
std::vector<std::array<std::string, 5>> VMEngine::getInstr(int segment, int address,int size) std::vector<std::array<std::string, 4>> VMEngine::getInstr(int segment, int address,int size)
{ {
uint32_t realaddress=segment*16+address; uint32_t realaddress=segment*16+address;
if (realaddress<bufferaddress || realaddress+(size*7)>bufferaddress+500) if (realaddress<bufferaddress || realaddress+(size*7)>bufferaddress+500)
@ -743,10 +740,10 @@ std::vector<std::array<std::string, 5>> VMEngine::getInstr(int segment, int addr
int last=first+size; int last=first+size;
marker=0; marker=0;
std::string reference=intToHexString(address, 8); std::string reference=intToHexString(address, 8);
std::vector<std::array<std::string, 5>> result = {unasm.src.begin()+first,unasm.src.begin()+last}; std::vector<std::array<std::string, 4>> result = {unasm.src.begin()+first,unasm.src.begin()+last};
for(std::array<std::string, 5> item: result) for(std::array<std::string, 4> item: result)
{ {
if (item[1]==reference) if (item[0]==reference)
break; break;
marker++; marker++;
} }
@ -758,7 +755,64 @@ int VMEngine::getLine()
{ {
return marker; return marker;
} }
//----------------------------------------------------------------------
// Hook
//----------------------------------------------------------------------
static void hook_int(uc_engine *uc, uint32_t intno, void *user_data)
{
((Menu *)user_data)->tolog("INT "+to_string(intno));
}
static void hook_code (uc_engine *uc, uint64_t address, uint32_t size, void *user_data)
{
if (!ok)
{
ok=true;
return;
}
uint8_t code[2];
uc_err err = uc_mem_read(uc, address, &code, 2);
if (err)
throw Error("VM IA86 - hook instructions.......................[ERREUR]");
//((Menu *)user_data)->tolog(intToHexString(code[0],2));
//((Menu *)user_data)->tolog(intToHexString(code[1],2));
if (code[0]==0xF4)
executed=false;
else if (step && (code[0]==0xE8 || code[0]==0xFF || code[0]==0x9A || (code[0]==0x66 && (code[1]==0xE8 || code[1]==0xFF || code[1]==0x9A))))
hadcall=address+size;
else if (!step || (hadcall>0 && !call)) return;
uc_emu_stop(uc);
}
static void hook_call(uc_engine *uc, uint32_t intno, void *user_data)
{
((Menu *)user_data)->tolog("SYSCALL");
}
static void hook_memory_write(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data)
{
switch (type)
{
case UC_MEM_WRITE:
if ((address>=0xB8000) && (address<=0xB8000+80*25*2))
{
uint16_t offset=address-0xB8000;
uint16_t y=(int)(offset/(80*2));
uint16_t x=offset%(80*2);
char achar;
if (std::isprint(value))
achar=(char)value;
else
achar='.';
if ((size==1) && (x%2==0))
((Menu *)user_data)->SetScreen(x/2,y,achar);
}
}
}
void VMEngine::Configure(State *init, std::string code) void VMEngine::Configure(State *init, std::string code)
{ {
try try
@ -771,31 +825,35 @@ void VMEngine::Configure(State *init, std::string code)
Close(); Close();
Init(); Init();
bufferaddress=-666; bufferaddress=-666;
this->initialized=false; initialized=false;
this->executed=false; executed=false;
//log->append("Mappage de la mémoire virtuelle"); //widget->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);
uc_hook_add(uc, &uh_call, UC_HOOK_INSN, (void*)hook_call, (void*)widget, 1, 0, UC_X86_INS_SYSCALL);
uc_hook_add(uc, &uh_mem, UC_HOOK_MEM_WRITE, (void*)hook_memory_write, (void*)widget, 1, 0);
uc_hook_add(uc, &uh_code, UC_HOOK_CODE, (void*)hook_code, (void*)widget, 1, 0);
uc_hook_add(uc, &uh_int, UC_HOOK_INTR, (void*)hook_int, (void*)widget, 1, 0);
for(size_t i=0;i<mcode.size();i++) for(size_t i=0;i<mcode.size();i++)
{ {
if (mcode[i].assembled) if (mcode[i].assembled)
SetMem(&mcode[i]); SetMem(&mcode[i]);
else else
throw Error("VM IA86 - code non assemblé...................[ERREUR]"); throw Error("VM IA86 - code non assemblé...................[ERREUR]");
if (debug) log->append("Section N°"+std::to_string(i)+" : "+intToHexString(mcode[i].address,8)+" -> "+to_string(mcode[i].size)+" octets"); if (debug) widget->log.append("Section N°"+std::to_string(i)+" : "+intToHexString(mcode[i].address,8)+" -> "+to_string(mcode[i].size)+" octets");
} }
status=verify(); status=verify();
if (status==0) if (status==0)
{ {
this->initialized=true; initialized=true;
SetRegs(init); SetRegs(init);
} }
else else
this->initialized=false; initialized=false;
} }
catch(exception const& e) catch(exception const& e)
{ {
log->append(e.what()); widget->log.append(e.what());
this->initialized=false; initialized=false;
} }
} }
@ -964,37 +1022,42 @@ void VMEngine::SetRegs(State *init)
out << " AX=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.ax << " "; out << " AX=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.ax << " ";
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()); widget->log.append(out.str());
} }
void VMEngine::Run(uint32_t end,uint64_t timeout) void VMEngine::Run(bool astep, bool acall, uint64_t timeout)
{ {
try try
{ {
if (verify()==0 && this->initialized) if (verify()==0 && initialized)
{ {
err=uc_emu_start(uc, this->getCurrent(), end, timeout, 0); ok=false;
step=astep;
call=acall;
if (hadcall==0)
err=uc_emu_start(uc, this->getCurrent(), 0xFFFFFFFF, timeout, 0);
else
{
err=uc_emu_start(uc, this->getCurrent(), hadcall, timeout, 0);
hadcall=0;
}
if (err) if (err)
throw Error("VM IA86 - execution...............................[ERREUR]"); throw Error("VM IA86 - execution...............................[ERREUR]");
else else
{ {
if (!this->executed) if (!executed)
log->append("VM IA86 - execution...............................[ INFO ]"); widget->log.append("VM IA86 - execution...............................[ INFO ]");
this->executed="true"; executed="true";
} }
} }
} }
catch(exception const& e) catch(exception const& e)
{ {
this->Halt(); this->Halt();
log->append(e.what()); widget->log.append(e.what());
} }
} }
//----------------------------------------------------------------------
// Classe
//----------------------------------------------------------------------
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Classe Menu // Classe Menu
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1090,7 +1153,7 @@ void Menu::initWindows()
} }
// Level 1 : IP AL // Level 1 : IP AL
// Level 2 : IP AX // Level 2 : I:P AX
// Level 3 : IP AX BX CX DX // Level 3 : IP AX BX CX DX
// Level 4 : IP AX BX CX DX FLAGS // Level 4 : IP AX BX CX DX FLAGS
// Level 5 : IP AX BX CX DX FLAGS SI DI // Level 5 : IP AX BX CX DX FLAGS SI DI
@ -1112,7 +1175,7 @@ void Menu::AdjustWindows()
stack.setGeometry ( FPoint { 43, 01 }, FSize{15, 15} ); stack.setGeometry ( FPoint { 43, 01 }, FSize{15, 15} );
mem.setGeometry ( FPoint { 77, 01 }, FSize{108, 15} ); mem.setGeometry ( FPoint { 77, 01 }, FSize{108, 15} );
tuto.setGeometry ( FPoint { 125, 45 }, FSize{60, 11} ); tuto.setGeometry ( FPoint { 125, 45 }, FSize{60, 11} );
screen.setGeometry ( FPoint { 105, 18 }, FSize{80, 25} ); screen.setGeometry ( FPoint { 103, 16 }, FSize{82, 28} );
debug.setGeometry ( FPoint { 42, 17 }, FSize{60, 27} ); debug.setGeometry ( FPoint { 42, 17 }, FSize{60, 27} );
scenar.setGeometry ( FPoint { 187, 01 }, FSize{25, 55} ); scenar.setGeometry ( FPoint { 187, 01 }, FSize{25, 55} );
this->hide(); this->hide();
@ -1167,6 +1230,26 @@ void Menu::initMenus()
About.setStatusbarMessage ("A propos de IA86"); About.setStatusbarMessage ("A propos de IA86");
} }
void Menu::ClearScreen()
{
std::string empty="";
for(int i=0;i<80*25;i++)
{
if ((i%80==0) && i!=0)
empty+="\n";
empty+="X";
}
screen.set(empty);
}
void Menu::SetScreen(uint16_t x, uint16_t y, char value)
{
std::string temp=screen.get();
if (x<25 && y<80)
temp[x+y*81]=value;
screen.set(temp);
}
void Menu::onTimer (finalcut::FTimerEvent* ev) void Menu::onTimer (finalcut::FTimerEvent* ev)
{ {
refresh(); refresh();
@ -1284,9 +1367,15 @@ void Menu::end()
void Menu::compile() void Menu::compile()
{ {
vm.Configure(&scenario.levels[scenar.getselected()].init,edit.get()); vm.Configure(&scenario.levels[scenar.getselected()].init,edit.get());
ClearScreen();
showInstr(); showInstr();
} }
void Menu::tolog(std::string str)
{
log.append(str);
}
void Menu::about() void Menu::about()
{ {
log.hide(); log.hide();
@ -1366,7 +1455,7 @@ void Menu::exec()
{ {
if (!vm.isInitialized()) if (!vm.isInitialized())
compile(); compile();
vm.Run(0xFFFF,0); vm.Run(false,false,0);
showInstr(); showInstr();
} }
@ -1374,7 +1463,7 @@ void Menu::trace()
{ {
if (!vm.isInitialized()) if (!vm.isInitialized())
compile(); compile();
vm.Run(vm.getNextInstr(),0); vm.Run(true,false,0);
showInstr(); showInstr();
} }
@ -1382,7 +1471,7 @@ void Menu::step()
{ {
if (!vm.isInitialized()) if (!vm.isInitialized())
compile(); compile();
vm.Run(vm.getNextInstr(),0); vm.Run(true,true,0);
showInstr(); showInstr();
} }

41
ia86.h
View File

@ -139,7 +139,7 @@ struct Code
struct Unasm struct Unasm
{ {
std::vector<std::array<std::string, 5>> src; std::vector<std::array<std::string, 4>> src;
std::vector<uint32_t> pos; std::vector<uint32_t> pos;
}; };
@ -199,14 +199,14 @@ class InstructionWindow final : public finalcut::FDialog
// Disable copy assignment operator (=) // Disable copy assignment operator (=)
InstructionWindow& operator = (const InstructionWindow&) = delete; InstructionWindow& operator = (const InstructionWindow&) = delete;
// Method // Method
std::vector<std::array<std::string, 5>> get(); std::vector<std::array<std::string, 4>> get();
void set(std::vector<std::array<std::string, 5>> src); void set(std::vector<std::array<std::string, 4>> src);
void clear(); void clear();
void setmark(int index); void setmark(int index);
int getsize(); int getsize();
private: private:
// Method // Method
std::vector<std::array<std::string, 5>> content; std::vector<std::array<std::string, 4>> content;
void initLayout() override; void initLayout() override;
void adjustSize() override; void adjustSize() override;
// Data members // Data members
@ -263,50 +263,51 @@ class TextWindow final : public finalcut::FDialog
finalcut::FTextView scrolltext{this}; finalcut::FTextView scrolltext{this};
}; };
class Menu;
class Desassembler class Desassembler
{ {
public: public:
Desassembler(TextWindow *log); Desassembler(Menu *widget);
void Desassemble(uint8_t *content, uint32_t address,uint32_t size, Unasm *unasm); void Desassemble(uint8_t *content, uint32_t address,uint32_t size, Unasm *unasm);
private: private:
csh handle; csh handle;
cs_insn *insn; cs_insn *insn;
int err; int err;
TextWindow *log; Menu *widget;
TextEditWindow *edit; TextEditWindow *edit;
size_t srcsize; size_t srcsize;
size_t codesize; size_t codesize;
std::vector<std::array<std::string, 5>> src; std::vector<std::array<std::string, 4>> src;
unsigned char *src_char = new unsigned char[64*1024]; unsigned char *src_char = new unsigned char[64*1024];
}; };
class Assembler class Assembler
{ {
public: public:
Assembler(TextWindow *log); Assembler(Menu *widget);
void Assemble(Code *code); void Assemble(Code *code);
std::vector<Code> 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; Menu *widget;
TextEditWindow *edit; TextEditWindow *edit;
}; };
class VMEngine class VMEngine
{ {
public: public:
VMEngine(TextWindow *log); VMEngine(Menu *widget);
void Configure(State *init, std::string code); void Configure(State *init, std::string code);
void Halt(); void Halt();
void Unconfigure(); void Unconfigure();
uint32_t getNextInstr();
uint32_t getCurrent(); uint32_t getCurrent();
void Run(uint32_t end,uint64_t timeout); void Run(bool astep, bool acall, uint64_t timeout);
std::string getFlags(); std::string getFlags();
std::string getRegs(); std::string getRegs();
std::vector<std::array<std::string, 5>> getInstr(int segment, int address,int size); std::vector<std::array<std::string, 4>> getInstr(int segment, int address,int size);
void SetMem(Code *code); void SetMem(Code *code);
void SetRegs(State *init); void SetRegs(State *init);
std::string getRam(int segment, int address,int lines, int linesize); std::string getRam(int segment, int address,int lines, int linesize);
@ -314,6 +315,7 @@ class VMEngine
bool isExecuted(); bool isExecuted();
bool isInitialized(); bool isInitialized();
void setRights(int rights); void setRights(int rights);
void ClearScreen();
int getLine(); int getLine();
uint32_t getEIP(); uint32_t getEIP();
uint16_t getCS(); uint16_t getCS();
@ -324,8 +326,6 @@ class VMEngine
int rights; int rights;
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;
int bufferaddress; int bufferaddress;
@ -333,9 +333,9 @@ class VMEngine
uint8_t *code; uint8_t *code;
uLong crc,crc_old; uLong crc,crc_old;
std::vector<Code> mcode; std::vector<Code> mcode;
TextWindow *log; Menu *widget;
Assembler asmer{log}; Assembler asmer{widget};
Desassembler unasmer{log}; Desassembler unasmer{widget};
}; };
class Menu final : public finalcut::FDialog class Menu final : public finalcut::FDialog
@ -351,6 +351,8 @@ class Menu final : public finalcut::FDialog
Menu& operator = (const Menu&) = delete; Menu& operator = (const Menu&) = delete;
// Methods // Methods
void loadLevel(); void loadLevel();
void tolog(std::string str);
void SetScreen(uint16_t x, uint16_t y, char value);
TextWindow log{this}; TextWindow log{this};
private: private:
void onTimer (finalcut::FTimerEvent*) override; void onTimer (finalcut::FTimerEvent*) override;
@ -370,6 +372,7 @@ class Menu final : public finalcut::FDialog
void about(); void about();
void mini(); void mini();
void maxi(); void maxi();
void ClearScreen();
void AdjustWindows(); void AdjustWindows();
void initWindows(); void initWindows();
void initLayout() override; void initLayout() override;
@ -415,7 +418,7 @@ class Menu final : public finalcut::FDialog
TextWindow screen{this}; TextWindow screen{this};
TextEditWindow edit{this}; TextEditWindow edit{this};
ScenarioWindow scenar{this}; ScenarioWindow scenar{this};
VMEngine vm{&log}; VMEngine vm{this};
}; };

View File

@ -9,6 +9,7 @@
"niveau_code" : "mov ax,0x545 "niveau_code" : "mov ax,0x545
inc dx inc dx
mov esi,0x44440234 mov esi,0x44440234
syscall
hlt hlt
jmp 0x14D jmp 0x14D
.org 0x8D .org 0x8D
@ -58,15 +59,37 @@ mov es,ax
"niveau_tutoriel" : "Ceci vous...", "niveau_tutoriel" : "Ceci vous...",
"niveau_code" : "mov ax,0x545 "niveau_code" : "mov ax,0x545
_pour: _pour:
inc dx lea si,[msg]
lea ebx,[_pour] call show
int 21
hlt
show:
push ax
push es
push di
push cx
mov ax,0xB800
mov es,ax
mov di,(80*2+40)*2
mov cx,16
mov al,0
boucle:
movsb
stosb
dec cx
cmp cx,0
jnz boucle
pop cx
pop di
pop es
pop ax
ret
msg:
db 'c','e','c','i',' ','e','s','t',' ','u','n',' ','t','e','s','t',0 db 'c','e','c','i',' ','e','s','t',' ','u','n',' ','t','e','s','t',0
.org 0x9000
_pour: .org 0x1000
db 0x00
lea eax,[_pour]
mov esi,0x44441234
.org 0x3002
hlt", hlt",
"niveau_droits" : 10, "niveau_droits" : 10,
"niveau_initial" : "niveau_initial" :