2021-07-06 01:09:46 +02:00
|
|
|
#include <final/final.h>
|
|
|
|
#include <unistd.h>
|
2021-07-08 18:26:55 +02:00
|
|
|
#include <regex>
|
2021-07-06 01:09:46 +02:00
|
|
|
#include <iostream>
|
2021-07-08 12:06:23 +02:00
|
|
|
#include <sstream>
|
2021-07-06 01:09:46 +02:00
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
|
|
|
#include <iomanip>
|
|
|
|
#include <keystone/keystone.h>
|
|
|
|
#include <unicorn/unicorn.h>
|
|
|
|
#include <capstone/capstone.h>
|
|
|
|
#include <vector>
|
2021-07-09 09:39:59 +02:00
|
|
|
#include <zlib.h>
|
2021-07-06 01:09:46 +02:00
|
|
|
#include "ia86.h"
|
2021-07-11 14:17:58 +02:00
|
|
|
#include <exception>
|
2021-07-08 12:06:23 +02:00
|
|
|
#include "struct_mapping/struct_mapping.h"
|
2021-07-06 01:09:46 +02:00
|
|
|
|
2021-07-11 14:17:58 +02:00
|
|
|
|
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Fonctions diverses
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
std::string intToHexString(int intValue, int size) {
|
|
|
|
string hexStr;
|
|
|
|
std::stringstream sstream;
|
2021-07-06 13:14:56 +02:00
|
|
|
sstream << std::uppercase << std::setfill ('0') << std::setw(size) << std::hex << (int)intValue;
|
2021-07-06 01:09:46 +02:00
|
|
|
hexStr= sstream.str();
|
|
|
|
sstream.clear();
|
|
|
|
return hexStr;
|
|
|
|
}
|
|
|
|
|
2021-07-08 12:06:23 +02:00
|
|
|
void mapping()
|
|
|
|
{
|
|
|
|
struct_mapping::reg(&Scenario::title, "scenario_titre");
|
2021-07-08 13:56:42 +02:00
|
|
|
struct_mapping::reg(&Scenario::levels, "scenario_objectifs");
|
2021-07-08 12:06:23 +02:00
|
|
|
struct_mapping::reg(&Level::title, "niveau_titre");
|
|
|
|
struct_mapping::reg(&Level::description, "niveau_description");
|
|
|
|
struct_mapping::reg(&Level::tutorial, "niveau_tutoriel");
|
|
|
|
struct_mapping::reg(&Level::code, "niveau_code");
|
2021-07-08 13:56:42 +02:00
|
|
|
struct_mapping::reg(&Level::rights, "niveau_droits");
|
2021-07-08 12:06:23 +02:00
|
|
|
struct_mapping::reg(&Level::init, "niveau_initial");
|
|
|
|
struct_mapping::reg(&Level::goal, "niveau_objectif");
|
|
|
|
struct_mapping::reg(&State::dump, "registres");
|
2021-07-08 13:56:42 +02:00
|
|
|
struct_mapping::reg(&State::code, "code");
|
2021-07-08 12:06:23 +02:00
|
|
|
struct_mapping::reg(&i386_all_regs::segs, "segments");
|
|
|
|
struct_mapping::reg(&i386_all_regs::regs, "généraux");
|
|
|
|
struct_mapping::reg(&i386_all_regs::flags, "drapeaux");
|
|
|
|
struct_mapping::reg(&i386_segs::cs, "cs");
|
|
|
|
struct_mapping::reg(&i386_segs::ss, "ss");
|
|
|
|
struct_mapping::reg(&i386_segs::ds, "ds");
|
|
|
|
struct_mapping::reg(&i386_segs::es, "es");
|
|
|
|
struct_mapping::reg(&i386_segs::fs, "fs");
|
|
|
|
struct_mapping::reg(&i386_segs::gs, "gs");
|
|
|
|
struct_mapping::reg(&i386_regs::eax, "eax");
|
|
|
|
struct_mapping::reg(&i386_regs::ebx, "ebx");
|
|
|
|
struct_mapping::reg(&i386_regs::ecx, "ecx");
|
|
|
|
struct_mapping::reg(&i386_regs::edx, "edx");
|
|
|
|
struct_mapping::reg(&i386_regs::esi, "esi");
|
|
|
|
struct_mapping::reg(&i386_regs::edi, "edi");
|
|
|
|
struct_mapping::reg(&i386_regs::esp, "esp");
|
|
|
|
struct_mapping::reg(&i386_regs::ebp, "ebp");
|
|
|
|
struct_mapping::reg(&i386_regs::eip, "eip");
|
|
|
|
}
|
|
|
|
|
|
|
|
Scenario readscenario(std::string filename) {
|
|
|
|
|
|
|
|
std::ifstream inFile;
|
|
|
|
inFile.open(filename);
|
|
|
|
std::stringstream strStream;
|
|
|
|
strStream << inFile.rdbuf();
|
|
|
|
std::string json=strStream.str();
|
|
|
|
std::istringstream json_data(json);
|
|
|
|
Scenario scenar;
|
|
|
|
struct_mapping::map_json_to_struct(scenar, json_data);
|
|
|
|
return scenar;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scenario scenario;
|
2021-07-10 19:36:29 +02:00
|
|
|
Unasm unasm;
|
|
|
|
int marker;
|
2021-07-11 14:17:58 +02:00
|
|
|
bool debug=true;
|
2021-07-06 01:09:46 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe ScenarioWindow
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ScenarioWindow::ScenarioWindow (finalcut::FWidget* parent)
|
|
|
|
: finalcut::FDialog{parent}
|
|
|
|
{
|
|
|
|
listview.ignorePadding();
|
2021-07-08 12:06:23 +02:00
|
|
|
listview.addColumn ("*");
|
2021-07-06 01:09:46 +02:00
|
|
|
listview.addColumn ("Intitulé");
|
|
|
|
listview.hideSortIndicator(true);
|
|
|
|
listview.setFocus();
|
|
|
|
listview.addCallback
|
|
|
|
(
|
|
|
|
"row-changed",
|
|
|
|
this, &ScenarioWindow::click
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-07-11 14:17:58 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
void ScenarioWindow::click()
|
|
|
|
{
|
2021-07-08 13:56:42 +02:00
|
|
|
selected=listview.getindex();
|
2021-07-08 12:06:23 +02:00
|
|
|
((Menu*)this->getParent())->loadLevel();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int ScenarioWindow::getselected()
|
|
|
|
{
|
|
|
|
return selected;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScenarioWindow::initLayout()
|
|
|
|
{
|
|
|
|
listview.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1});
|
|
|
|
FDialog::initLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScenarioWindow::adjustSize()
|
|
|
|
{
|
|
|
|
finalcut::FDialog::adjustSize();
|
|
|
|
listview.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1));
|
|
|
|
}
|
|
|
|
|
2021-07-06 15:21:03 +02:00
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe InstructionWindow
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
InstructionWindow::InstructionWindow (finalcut::FWidget* parent)
|
|
|
|
: finalcut::FDialog{parent}
|
|
|
|
{
|
|
|
|
|
|
|
|
listview.ignorePadding();
|
|
|
|
listview.addColumn ("P");
|
|
|
|
listview.addColumn ("Adresse");
|
|
|
|
listview.addColumn ("Opcodes ");
|
|
|
|
listview.addColumn ("Mnémo.");
|
|
|
|
listview.addColumn ("Opérandes");
|
|
|
|
listview.hideSortIndicator(true);
|
|
|
|
listview.setFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::array<std::string, 5>> InstructionWindow::get()
|
|
|
|
{
|
|
|
|
return content;
|
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void InstructionWindow::clear()
|
|
|
|
{
|
|
|
|
listview.clear();
|
|
|
|
listview.redraw();
|
|
|
|
}
|
|
|
|
|
2021-07-09 18:35:13 +02:00
|
|
|
void InstructionWindow::setmark(int index)
|
2021-07-06 15:21:03 +02:00
|
|
|
{
|
2021-07-09 18:35:13 +02:00
|
|
|
listview.setmark(index);
|
2021-07-06 15:21:03 +02:00
|
|
|
}
|
|
|
|
|
2021-07-09 18:35:13 +02:00
|
|
|
int InstructionWindow::getsize()
|
|
|
|
{
|
|
|
|
return listview.getCount();
|
|
|
|
}
|
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
void InstructionWindow::set(std::vector<std::array<std::string, 5>> src)
|
|
|
|
{
|
|
|
|
content=src;
|
|
|
|
listview.clear();
|
|
|
|
for (const auto& place : content)
|
|
|
|
{
|
|
|
|
const finalcut::FStringList line (place.begin(), place.end());
|
|
|
|
listview.insert (line);
|
|
|
|
}
|
2021-07-06 11:44:46 +02:00
|
|
|
listview.redraw();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void InstructionWindow::initLayout()
|
|
|
|
{
|
|
|
|
listview.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1});
|
|
|
|
setMinimumSize (FSize{51, 6});
|
|
|
|
FDialog::initLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void InstructionWindow::adjustSize()
|
|
|
|
{
|
|
|
|
finalcut::FDialog::adjustSize();
|
|
|
|
listview.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1));
|
2021-07-06 11:44:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
//----------------------------------------------------------------------
|
2021-07-06 11:44:46 +02:00
|
|
|
// Classe TextEditWindow
|
2021-07-06 01:09:46 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
TextEditWindow::TextEditWindow (finalcut::FWidget* parent)
|
2021-07-06 01:09:46 +02:00
|
|
|
: finalcut::FDialog{parent}
|
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
scrolltext.ignorePadding();
|
|
|
|
scrolltext.setFocus();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void TextEditWindow::onClose(finalcut::FCloseEvent*)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
return;
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void TextEditWindow::append(const finalcut::FString& str)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
scrolltext.append(str);
|
|
|
|
scrolltext.scrollBy (0, 10);
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
std::string TextEditWindow::get()
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
return scrolltext.getText().toString () ;
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void TextEditWindow::set(const finalcut::FString& str)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
scrolltext.clear();
|
|
|
|
scrolltext.append(str);
|
|
|
|
scrolltext.redraw();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void TextEditWindow::clear()
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
scrolltext.clear();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TextEditWindow::initLayout()
|
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
scrolltext.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1});
|
2021-07-06 01:09:46 +02:00
|
|
|
FDialog::initLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditWindow::adjustSize()
|
|
|
|
{
|
|
|
|
finalcut::FDialog::adjustSize();
|
2021-07-06 11:44:46 +02:00
|
|
|
scrolltext.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1));
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe TextWindow
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
TextWindow::TextWindow (finalcut::FWidget* parent)
|
|
|
|
: finalcut::FDialog{parent}
|
|
|
|
{
|
|
|
|
scrolltext.ignorePadding();
|
|
|
|
scrolltext.setFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextWindow::onClose(finalcut::FCloseEvent*)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextWindow::append(const finalcut::FString& str)
|
|
|
|
{
|
|
|
|
scrolltext.append(str);
|
|
|
|
scrolltext.scrollBy (0, 10);
|
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
std::string TextWindow::get()
|
|
|
|
{
|
|
|
|
return scrolltext.getText().toString () ;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextWindow::set(const finalcut::FString& str)
|
|
|
|
{
|
|
|
|
scrolltext.clear();
|
|
|
|
scrolltext.append(str);
|
|
|
|
scrolltext.redraw();
|
|
|
|
}
|
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
void TextWindow::clear()
|
|
|
|
{
|
|
|
|
scrolltext.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void TextWindow::initLayout()
|
|
|
|
{
|
|
|
|
scrolltext.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1});
|
|
|
|
FDialog::initLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextWindow::adjustSize()
|
|
|
|
{
|
|
|
|
finalcut::FDialog::adjustSize();
|
|
|
|
scrolltext.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe Desassembler
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
Desassembler::Desassembler(TextWindow *log) : log(log)
|
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
|
|
|
|
if (err != CS_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("Désassembleur - initialisation....................[ERREUR]");
|
2021-07-11 14:17:58 +02:00
|
|
|
log->append("Désassembleur - initialisation....................[ OK ]");
|
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
|
|
|
log->append(e.what());
|
|
|
|
}
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-10 19:36:29 +02:00
|
|
|
void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size, Unasm *unasm)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
srcsize=cs_disasm(handle, content, size, address, 0, &insn);
|
|
|
|
if (srcsize == 0)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("Désassembleur - désassemblage.....................[ERREUR]");
|
2021-07-11 14:17:58 +02:00
|
|
|
else
|
|
|
|
{
|
2021-07-11 15:27:07 +02:00
|
|
|
if (debug) log->append("Désassemblage - désassemblage.....................[ "+to_string(srcsize)+"l ]");
|
2021-07-11 14:17:58 +02:00
|
|
|
unasm->src.clear();
|
|
|
|
unasm->pos.clear();
|
|
|
|
for (size_t j = 0; j < srcsize; j++)
|
|
|
|
{
|
|
|
|
std::string *bytes = new std::string("");
|
|
|
|
for (size_t k = 0; k < insn[j].size; k++)
|
|
|
|
*bytes=*bytes+intToHexString((int)insn[j].bytes[k], 2);
|
|
|
|
std::string adresse = intToHexString((int)insn[j].address, 8);
|
|
|
|
std::string *menmonic = new std::string((char *)insn[j].mnemonic);
|
|
|
|
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};
|
|
|
|
unasm->src.push_back(*array);
|
|
|
|
unasm->pos.push_back(insn[j].address);
|
|
|
|
}
|
|
|
|
cs_free(insn, srcsize);
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
catch(exception const& e)
|
|
|
|
{
|
|
|
|
unasm->src.clear();
|
|
|
|
unasm->pos.clear();
|
|
|
|
log->append(e.what());
|
|
|
|
}
|
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe Assembler
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
Assembler::Assembler(TextWindow *log) : log(log)
|
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
err = ks_open(KS_ARCH_X86, KS_MODE_16, &ks);
|
|
|
|
if (err != KS_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("Assembleur - initialisation.......................[ERREUR]");
|
2021-07-11 14:17:58 +02:00
|
|
|
log->append("Assembleur - initialisation.......................[ OK ]");
|
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
|
|
|
log->append(e.what());
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-09 00:51:05 +02:00
|
|
|
std::vector<Code> Assembler::MultiAssemble(std::string source,uint32_t address)
|
2021-07-08 13:56:42 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
try
|
2021-07-08 18:26:55 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
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))
|
2021-07-08 18:26:55 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
if (line.find(".org") != std::string::npos)
|
2021-07-08 18:26:55 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
std::smatch match;
|
|
|
|
if(std::regex_search(line, match, regex))
|
|
|
|
{
|
|
|
|
org=std::stoul(match.str(1), nullptr, 16);
|
|
|
|
}
|
|
|
|
if (!begin)
|
|
|
|
{
|
|
|
|
mcode.push_back(*code);
|
|
|
|
code=new Code;
|
|
|
|
code->address=org;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2021-07-08 18:26:55 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
code->src.append(line+"\n");
|
2021-07-08 18:26:55 +02:00
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
begin=false;
|
|
|
|
}
|
|
|
|
if (code->src.size()>0)
|
|
|
|
mcode.push_back(*code);
|
|
|
|
for(size_t i=0;i<mcode.size();i++)
|
|
|
|
this->Assemble(&mcode[i]);
|
2021-07-11 15:27:07 +02:00
|
|
|
log->append("Assembleur - assemblage...........................[ OK ]");
|
2021-07-11 14:17:58 +02:00
|
|
|
return mcode;
|
|
|
|
}
|
|
|
|
catch(exception const& e)
|
2021-07-08 18:26:55 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
std::vector<Code> mcode;
|
|
|
|
log->append(e.what());
|
|
|
|
return mcode;
|
2021-07-08 18:26:55 +02:00
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
|
2021-07-08 13:56:42 +02:00
|
|
|
}
|
|
|
|
|
2021-07-08 18:26:55 +02:00
|
|
|
void Assembler::Assemble(Code *code)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-08 18:26:55 +02:00
|
|
|
size_t srcsize=code->src.size();
|
2021-07-06 01:09:46 +02:00
|
|
|
unsigned char src_char[srcsize+1];
|
2021-07-08 18:26:55 +02:00
|
|
|
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);
|
2021-07-06 01:09:46 +02:00
|
|
|
if (err2 != KS_ERR_OK)
|
|
|
|
{
|
|
|
|
code->size=0;
|
|
|
|
code->assembled=false;
|
2021-07-11 15:27:07 +02:00
|
|
|
code->loaded=false;
|
|
|
|
throw Error("Assembleur - assemblage...........................[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
code->assembled=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe VMEngine
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
VMEngine::VMEngine(TextWindow *log) : log(log)
|
|
|
|
{
|
2021-07-10 19:36:29 +02:00
|
|
|
code=new uint8_t[500];
|
2021-07-06 11:44:46 +02:00
|
|
|
Init();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
// Level 1 : IP AL
|
|
|
|
// 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
|
2021-07-09 18:35:13 +02:00
|
|
|
std::string VMEngine::getFlags()
|
2021-07-08 12:06:23 +02:00
|
|
|
{
|
|
|
|
int eflags=0;
|
|
|
|
err = uc_reg_read(uc, UC_X86_REG_EFLAGS, &eflags);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - voir EFLAGS.............................[ERREUR]");
|
2021-07-08 12:06:23 +02:00
|
|
|
std::stringstream out;
|
|
|
|
out << " CF:" << std::dec << ((eflags & 0x0001));
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-08 12:06:23 +02:00
|
|
|
out << " RF:" << std::dec << ((eflags & 0x00010000)>>16) << "\n";
|
|
|
|
else
|
|
|
|
out << "\n";
|
|
|
|
out << " PF:" << std::dec << ((eflags & 0x0004)>>2);
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-08 12:06:23 +02:00
|
|
|
out << " VM:" << std::dec << ((eflags & 0x00020000)>>17) << "\n";
|
|
|
|
else
|
|
|
|
out << "\n";
|
|
|
|
out << " AF:" << std::dec << ((eflags & 0x0010)>>4);
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-08 12:06:23 +02:00
|
|
|
out << " AC:" << std::dec << ((eflags & 0x00040000)>>18) << "\n";
|
|
|
|
else
|
|
|
|
out << "\n";
|
|
|
|
out << " ZF:" << std::dec << ((eflags & 0x0040)>>6);
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-08 12:06:23 +02:00
|
|
|
out << " VIF:" << std::dec << ((eflags & 0x00080000)>>19) << "\n";
|
|
|
|
else
|
|
|
|
out << "\n";
|
|
|
|
out << " SF:" << std::dec << ((eflags & 0x0080)>>7);
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-08 12:06:23 +02:00
|
|
|
out << " VIP:" << std::dec << ((eflags & 0x00100000)>>20) << "\n";
|
|
|
|
else
|
|
|
|
out << "\n";
|
|
|
|
out << " TF:" << std::dec << ((eflags & 0x0100)>>8);
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-08 12:06:23 +02:00
|
|
|
out << " ID:" << std::dec << ((eflags & 0x00200000)>>21) << "\n";
|
|
|
|
else
|
|
|
|
out << "\n";
|
|
|
|
out << " IF:" << std::dec << ((eflags & 0x0200)>>9) << "\n";
|
|
|
|
out << " DF:" << std::dec << ((eflags & 0x0400)>>10) << "\n";
|
|
|
|
out << " OF:" << std::dec << ((eflags & 0x0800)>>11) << "\n";
|
|
|
|
out << "IOPL:" << std::dec << ((eflags & 0x3000)>>12) << "\n";
|
|
|
|
out << " NT:" << std::dec << ((eflags & 0x4000)>>13) << "\n";
|
|
|
|
return out.str();
|
|
|
|
}
|
2021-07-06 01:09:46 +02:00
|
|
|
|
2021-07-09 18:35:13 +02:00
|
|
|
std::string VMEngine::getRegs()
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
|
|
|
int regsi836[] = {
|
|
|
|
UC_X86_REG_EAX, UC_X86_REG_EBX, UC_X86_REG_ECX, UC_X86_REG_EDX,
|
|
|
|
UC_X86_REG_ESI, UC_X86_REG_EDI,
|
|
|
|
UC_X86_REG_EBP, UC_X86_REG_ESP,
|
|
|
|
UC_X86_REG_CS,UC_X86_REG_DS,UC_X86_REG_ES,UC_X86_REG_SS,UC_X86_REG_FS,UC_X86_REG_GS,
|
|
|
|
UC_X86_REG_EIP,UC_X86_REG_EFLAGS
|
|
|
|
};
|
|
|
|
void *ptrs[sizeof(regsi836)];
|
|
|
|
uint32_t vals[sizeof(regsi836)];
|
|
|
|
for (size_t i = 0; i < sizeof(regsi836); i++) {
|
|
|
|
ptrs[i] = &vals[i];
|
|
|
|
}
|
|
|
|
err = uc_reg_read_batch(uc, regsi836, ptrs, sizeof(regsi836));
|
|
|
|
if (err > 0) {
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - voir REGISTRES..........................[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
std::stringstream out;
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "EAX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[0] << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 1)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "AX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[0] & 0x0000FFFF) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 1)
|
2021-07-06 01:09:46 +02:00
|
|
|
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";
|
|
|
|
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "EBX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[1] << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "BX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[1] & 0x0000FFFF) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "BH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[1] & 0xFF00) >> 8) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "BL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[1] & 0xFF) << "\n";
|
|
|
|
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "ECX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[2] << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "CX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[2] & 0x0000FFFF) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "CH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[2] & 0xFF00) >> 8) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "CL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[2] & 0xFF) << "\n";
|
|
|
|
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "EDX:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[3] << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "DX:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[3] & 0x0000FFFF) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "DH:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << ((vals[3] & 0xFF00) >> 8) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "DL:" << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (vals[3] & 0xFF) << "\n";
|
|
|
|
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "ESI:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[4] << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 4)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "SI:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[4] & 0x0000FFFF) << "\n";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "EDI:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[5] << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 4)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "DI:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[5] & 0x0000FFFF) << "\n";
|
|
|
|
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "EBP:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[6] << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 5)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "BP:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[6] & 0x0000FFFF) << "\n";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "ESP:" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << vals[7] << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 5)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "SP:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[7] & 0x0000FFFF) << "\n";
|
|
|
|
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 6)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "CS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[8] & 0x0000FFFF) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 6)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "DS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[9] & 0x0000FFFF) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 6)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "ES:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[10] & 0x0000FFFF) << "\n";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 6)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "SS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[11] & 0x0000FFFF) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 7)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "FS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[12] & 0x0000FFFF) << " | ";
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 7)
|
2021-07-06 01:09:46 +02:00
|
|
|
out << "GS:" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << (vals[13] & 0x0000FFFF) << "\n";
|
|
|
|
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 8)
|
2021-07-06 01:09:46 +02:00
|
|
|
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";
|
|
|
|
|
2021-07-08 13:56:42 +02:00
|
|
|
if (rights > 3)
|
|
|
|
if (rights < 9)
|
2021-07-06 01:09:46 +02:00
|
|
|
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();
|
|
|
|
}
|
2021-07-06 11:44:46 +02:00
|
|
|
|
|
|
|
void VMEngine::Init()
|
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
err = uc_open(UC_ARCH_X86, UC_MODE_16, &uc);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - initilisation...........................[ERREUR]");
|
2021-07-11 14:17:58 +02:00
|
|
|
log->append("VM IA86 - initilisation...........................[ OK ]");
|
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
|
|
|
log->append(e.what());
|
2021-07-06 11:44:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-09 00:51:05 +02:00
|
|
|
bool VMEngine::isExecuted()
|
|
|
|
{
|
|
|
|
return this->executed;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VMEngine::isInitialized()
|
|
|
|
{
|
|
|
|
return this->initialized;
|
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void VMEngine::Close()
|
|
|
|
{
|
|
|
|
uc_close(uc);
|
|
|
|
}
|
|
|
|
|
2021-07-09 00:51:05 +02:00
|
|
|
void VMEngine::Halt()
|
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
if (this->executed)
|
2021-07-11 15:27:07 +02:00
|
|
|
log->append("VM IA86 - arret...................................[ INFO ]");
|
2021-07-09 00:51:05 +02:00
|
|
|
this->executed=false;
|
|
|
|
}
|
|
|
|
|
2021-07-09 18:35:13 +02:00
|
|
|
void VMEngine::Unconfigure()
|
2021-07-06 11:44:46 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
this->Halt();
|
2021-07-11 15:27:07 +02:00
|
|
|
if (this->initialized)
|
|
|
|
log->append("VM IA86 - déconfiguration.........................[ INFO ]");
|
2021-07-09 00:51:05 +02:00
|
|
|
this->initialized=false;
|
2021-07-06 11:44:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-10 19:36:29 +02:00
|
|
|
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::vector<std::array<std::string, 5>> VMEngine::getInstr(int segment, int address,int size)
|
2021-07-09 18:35:13 +02:00
|
|
|
{
|
2021-07-10 19:36:29 +02:00
|
|
|
uint32_t realaddress=segment*16+address;
|
2021-07-11 14:17:58 +02:00
|
|
|
if (realaddress<bufferaddress || realaddress+(size*7)>bufferaddress+500)
|
2021-07-09 18:35:13 +02:00
|
|
|
{
|
2021-07-11 16:34:50 +02:00
|
|
|
log->append("read");
|
|
|
|
bufferaddress=realaddress-30;
|
|
|
|
if (bufferaddress<0)
|
|
|
|
bufferaddress=0x00000000;
|
|
|
|
address_old=address-30;
|
|
|
|
if (address_old<0)
|
|
|
|
address_old=0x00000000;
|
2021-07-09 18:35:13 +02:00
|
|
|
}
|
2021-07-11 16:34:50 +02:00
|
|
|
err = uc_mem_read(uc, bufferaddress, code, 500);
|
|
|
|
if (err)
|
|
|
|
throw Error("VM IA86 - cache instructions......................[ERREUR]");
|
2021-07-09 18:35:13 +02:00
|
|
|
crc = crc32(0, code, 500);
|
2021-07-11 16:34:50 +02:00
|
|
|
if (crc != crc_old)
|
2021-07-09 18:35:13 +02:00
|
|
|
{
|
2021-07-11 16:34:50 +02:00
|
|
|
log->append("unasm");
|
|
|
|
unasmer.Desassemble(code, address_old, 500, &unasm);
|
|
|
|
if (unasm.src.size()==0)
|
|
|
|
throw Error("VM IA86 - cache instructions......................[ERREUR]");
|
|
|
|
crc_old=crc;
|
2021-07-10 19:36:29 +02:00
|
|
|
}
|
|
|
|
int line=0;
|
|
|
|
for(int pos: unasm.pos)
|
|
|
|
{
|
|
|
|
if (pos==address)
|
|
|
|
break;
|
|
|
|
line++;
|
|
|
|
}
|
|
|
|
int first=line-((int)size/2);
|
|
|
|
if (first<0) first=0;
|
|
|
|
int last=first+size;
|
|
|
|
marker=0;
|
|
|
|
std::string reference=intToHexString(address, 8);
|
|
|
|
std::vector<std::array<std::string, 5>> result = {unasm.src.begin()+first,unasm.src.begin()+last};
|
|
|
|
for(std::array<std::string, 5> item: result)
|
|
|
|
{
|
|
|
|
if (item[1]==reference)
|
|
|
|
break;
|
|
|
|
marker++;
|
2021-07-09 18:35:13 +02:00
|
|
|
}
|
2021-07-10 19:36:29 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int VMEngine::getLine()
|
|
|
|
{
|
|
|
|
return marker;
|
2021-07-09 18:35:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void VMEngine::Configure(State *init, std::string code)
|
2021-07-06 11:44:46 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
mcode.clear();
|
|
|
|
mcode=asmer.MultiAssemble(code,init->dump.regs.eip);
|
|
|
|
if (mcode.size()==0)
|
|
|
|
return;
|
|
|
|
Close();
|
|
|
|
Init();
|
2021-07-11 16:34:50 +02:00
|
|
|
bufferaddress=-666;
|
2021-07-09 00:51:05 +02:00
|
|
|
this->initialized=false;
|
2021-07-11 14:17:58 +02:00
|
|
|
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++)
|
2021-07-11 15:27:07 +02:00
|
|
|
{
|
|
|
|
if (mcode[i].assembled)
|
|
|
|
SetMem(&mcode[i]);
|
|
|
|
else
|
|
|
|
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");
|
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
status=verify();
|
|
|
|
if (status==0)
|
2021-07-11 15:27:07 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
this->initialized=true;
|
2021-07-11 15:27:07 +02:00
|
|
|
SetRegs(init);
|
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
else
|
|
|
|
this->initialized=false;
|
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
|
|
|
log->append(e.what());
|
|
|
|
this->initialized=false;
|
|
|
|
}
|
2021-07-06 11:44:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-09 00:51:05 +02:00
|
|
|
int VMEngine::verify()
|
2021-07-06 11:44:46 +02:00
|
|
|
{
|
2021-07-09 00:51:05 +02:00
|
|
|
for(Code code: mcode)
|
|
|
|
{
|
|
|
|
if (!code.assembled)
|
|
|
|
return 1;
|
|
|
|
else if (!code.loaded)
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
return 0;
|
2021-07-06 11:44:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-09 18:35:13 +02:00
|
|
|
void VMEngine::setRights(int rights)
|
|
|
|
{
|
|
|
|
this->rights=rights;
|
|
|
|
}
|
|
|
|
|
2021-07-10 19:36:29 +02:00
|
|
|
uint32_t VMEngine::getCurrent()
|
2021-07-06 15:21:03 +02:00
|
|
|
{
|
2021-07-10 19:36:29 +02:00
|
|
|
return getEIP()+getCS()*16;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t VMEngine::getEIP()
|
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
int eip;
|
2021-07-06 15:21:03 +02:00
|
|
|
err = uc_reg_read(uc, UC_X86_REG_EIP, &eip);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - voir EIP................................[ERREUR]");
|
2021-07-06 15:21:03 +02:00
|
|
|
return eip;
|
2021-07-09 00:51:05 +02:00
|
|
|
}
|
2021-07-06 15:21:03 +02:00
|
|
|
|
2021-07-10 19:36:29 +02:00
|
|
|
uint16_t VMEngine::getCS()
|
2021-07-09 18:35:13 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
int cs;
|
2021-07-09 18:35:13 +02:00
|
|
|
err = uc_reg_read(uc, UC_X86_REG_CS, &cs);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - voir CS.................................[ERREUR]");
|
2021-07-09 18:35:13 +02:00
|
|
|
return cs;
|
|
|
|
}
|
|
|
|
|
2021-07-10 19:36:29 +02:00
|
|
|
uint16_t VMEngine::getDS()
|
2021-07-09 18:35:13 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
int ds;
|
2021-07-09 18:35:13 +02:00
|
|
|
err = uc_reg_read(uc, UC_X86_REG_DS, &ds);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - voir DS.................................[ERREUR]");
|
2021-07-09 18:35:13 +02:00
|
|
|
return ds;
|
|
|
|
}
|
|
|
|
|
2021-07-11 14:17:58 +02:00
|
|
|
uint16_t VMEngine::getES()
|
|
|
|
{
|
|
|
|
int es;
|
|
|
|
err = uc_reg_read(uc, UC_X86_REG_ES, &es);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - voir ES.................................[ERREUR]");
|
2021-07-11 14:17:58 +02:00
|
|
|
return es;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t VMEngine::getSS()
|
|
|
|
{
|
|
|
|
int ss;
|
|
|
|
err = uc_reg_read(uc, UC_X86_REG_SS, &ss);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - voir SS.................................[ERREUR]");
|
2021-07-11 14:17:58 +02:00
|
|
|
return ss;
|
|
|
|
}
|
|
|
|
|
2021-07-09 00:51:05 +02:00
|
|
|
void VMEngine::SetMem(Code *code)
|
2021-07-06 11:44:46 +02:00
|
|
|
{
|
|
|
|
|
2021-07-09 00:51:05 +02:00
|
|
|
err = uc_mem_write(uc, code->address, code->content, code->size);
|
2021-07-06 11:44:46 +02:00
|
|
|
if (err)
|
|
|
|
{
|
2021-07-09 00:51:05 +02:00
|
|
|
code->loaded=false;
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - copie mémoire...........................[ERREUR]");
|
2021-07-06 11:44:46 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
code->loaded=true;
|
2021-07-06 11:44:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-09 00:51:05 +02:00
|
|
|
void VMEngine::SetRegs(State *init)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
|
|
|
std::stringstream out;
|
2021-07-11 14:17:58 +02:00
|
|
|
out << "VM IA86 - configuration initiale..................[ OK ]";
|
2021-07-06 01:09:46 +02:00
|
|
|
err = uc_reg_write(uc, UC_X86_REG_EIP, &init->dump.regs.eip);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - configuration initiale EIP..............[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
else
|
|
|
|
if (init->dump.regs.eip != 0x00000000)
|
|
|
|
if ((init->dump.regs.eip & 0xFFFF0000) == 0x00000000)
|
|
|
|
out << " IP=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.ip << " ";
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - configuration initiale EDI..............[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
else
|
|
|
|
if (init->dump.regs.edi != 0x00000000)
|
|
|
|
if ((init->dump.regs.edi & 0xFFFF0000) == 0x00000000)
|
|
|
|
out << " DI=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.di << " ";
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - configuration initiale ESI..............[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
else
|
|
|
|
if (init->dump.regs.esi != 0x00000000)
|
|
|
|
if ((init->dump.regs.esi & 0xFFFF0000) == 0x00000000)
|
|
|
|
out << " SI=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.si << " ";
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - configuration initiale EBP..............[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
else
|
|
|
|
if (init->dump.regs.ebp != 0x00000000)
|
|
|
|
if ((init->dump.regs.ebp & 0xFFFF0000) == 0x00000000)
|
|
|
|
out << " BP=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.bp << " ";
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - configuration initiale ESP..............[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
else
|
|
|
|
if (init->dump.regs.esp != 0x00000000)
|
|
|
|
if ((init->dump.regs.esp & 0xFFFF0000) == 0x00000000)
|
|
|
|
out << " SP=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.sp << " ";
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - configuration initiale EBX..............[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
else
|
|
|
|
if (init->dump.regs.ebx != 0x00000000)
|
|
|
|
if ((init->dump.regs.ebx & 0xFFFF0000) == 0x00000000)
|
|
|
|
out << " BX=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.bx << " ";
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - configuration initiale EDX..............[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
else
|
|
|
|
if (init->dump.regs.edx != 0x00000000)
|
|
|
|
if ((init->dump.regs.edx & 0xFFFF0000) == 0x00000000)
|
|
|
|
out << " DX=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.dx << " ";
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - configuration initiale ECX..............[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
else
|
|
|
|
if (init->dump.regs.ecx != 0x00000000)
|
|
|
|
if ((init->dump.regs.ecx & 0xFFFF0000) == 0x00000000)
|
|
|
|
out << " CX=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.cx << " ";
|
|
|
|
else
|
|
|
|
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);
|
|
|
|
if (err != UC_ERR_OK)
|
2021-07-11 15:27:07 +02:00
|
|
|
throw Error("VM IA86 - configuration initiale EAX..............[ERREUR]");
|
2021-07-06 01:09:46 +02:00
|
|
|
else
|
|
|
|
if (init->dump.regs.eax != 0x00000000)
|
|
|
|
if ((init->dump.regs.eax & 0xFFFF0000) == 0x00000000)
|
|
|
|
out << " AX=" << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << init->dump.regs.ax << " ";
|
|
|
|
else
|
|
|
|
out << "EAX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.eax << " ";
|
|
|
|
log->append(out.str());
|
|
|
|
}
|
|
|
|
|
2021-07-10 19:36:29 +02:00
|
|
|
void VMEngine::Run(uint32_t end,uint64_t timeout)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
try
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-11 15:27:07 +02:00
|
|
|
if (verify()==0 && this->initialized)
|
2021-07-11 14:17:58 +02:00
|
|
|
{
|
2021-07-11 15:27:07 +02:00
|
|
|
err=uc_emu_start(uc, this->getCurrent(), end, timeout, 0);
|
|
|
|
if (err)
|
|
|
|
{
|
|
|
|
this->Halt();
|
|
|
|
throw Error("VM IA86 - execution...............................[ERREUR]");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!this->executed)
|
|
|
|
log->append("VM IA86 - execution...............................[ INFO ]");
|
|
|
|
this->executed="true";
|
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
|
|
|
log->append(e.what());
|
|
|
|
}
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-09 18:35:13 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe Menu
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
Menu::Menu (finalcut::FWidget* parent)
|
|
|
|
: finalcut::FDialog{parent}
|
|
|
|
{
|
|
|
|
initNow();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::initNow()
|
|
|
|
{
|
|
|
|
initWindows();
|
|
|
|
initMisc();
|
|
|
|
initMenus();
|
|
|
|
initMenusCallBack();
|
|
|
|
initCore();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::initCore()
|
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
addTimer (50);
|
2021-07-11 14:17:58 +02:00
|
|
|
if (scenar.load("./scenarios.json"))
|
|
|
|
{
|
|
|
|
log.append("Application - charge scénarios....................[ OK ]");
|
|
|
|
log.append("-={ "+ scenario.title+" }=-");
|
|
|
|
if (scenario.levels.size()>0)
|
2021-07-11 15:27:07 +02:00
|
|
|
loadLevel();
|
2021-07-11 14:17:58 +02:00
|
|
|
maxi();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vm.Unconfigure();
|
2021-07-11 15:27:07 +02:00
|
|
|
log.append("Application - charge scénarios....................[ERREUR]");
|
2021-07-11 14:17:58 +02:00
|
|
|
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()
|
|
|
|
{
|
|
|
|
Options.show();
|
|
|
|
Tools.show();
|
|
|
|
Window.show();
|
|
|
|
Debug.show();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::initWindows()
|
|
|
|
{
|
|
|
|
log.setText ("Journaux");
|
|
|
|
log.setResizeable();
|
|
|
|
log.show();
|
|
|
|
edit.setText ("Code source");
|
|
|
|
edit.setResizeable();
|
|
|
|
edit.show();
|
|
|
|
view.setText ("Objectif");
|
|
|
|
view.setResizeable();
|
|
|
|
view.show();
|
|
|
|
regs.setText ("Registres");
|
|
|
|
regs.show();
|
|
|
|
flags.setText ("Drapeaux");
|
|
|
|
stack.setText ("Pile");
|
|
|
|
mem.setText ("Mémoire");
|
|
|
|
tuto.setText ("Guide");
|
|
|
|
tuto.setResizeable();
|
|
|
|
tuto.show();
|
|
|
|
screen.setText ("Ecran");
|
|
|
|
debug.setText ("Instructions");
|
|
|
|
debug.setResizeable();
|
|
|
|
debug.show();
|
|
|
|
scenar.setText ("Scénarios");
|
|
|
|
scenar.setResizeable();
|
|
|
|
scenar.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Level 1 : IP AL
|
|
|
|
// 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
|
|
|
|
|
|
|
|
void Menu::AdjustWindows()
|
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
log.setGeometry ( FPoint { 63, 45 }, FSize{60, 11} );
|
|
|
|
edit.setGeometry ( FPoint { 01, 17 }, FSize{39, 27} );
|
|
|
|
view.setGeometry ( FPoint { 01, 45 }, FSize{60, 11} );
|
|
|
|
regs.setGeometry ( FPoint { 01, 01 }, FSize{40, 15} );
|
|
|
|
flags.setGeometry ( FPoint { 60, 01 }, FSize{15, 15} );
|
|
|
|
stack.setGeometry ( FPoint { 43, 01 }, FSize{15, 15} );
|
|
|
|
mem.setGeometry ( FPoint { 77, 01 }, FSize{108, 15} );
|
|
|
|
tuto.setGeometry ( FPoint { 125, 45 }, FSize{60, 11} );
|
|
|
|
screen.setGeometry ( FPoint { 105, 18 }, FSize{80, 25} );
|
|
|
|
debug.setGeometry ( FPoint { 42, 17 }, FSize{60, 27} );
|
2021-07-08 12:06:23 +02:00
|
|
|
scenar.setGeometry ( FPoint { 187, 01 }, FSize{25, 55} );
|
2021-07-06 13:14:56 +02:00
|
|
|
this->hide();
|
|
|
|
flags.hide();
|
|
|
|
stack.hide();
|
|
|
|
mem.hide();
|
|
|
|
screen.hide();
|
|
|
|
log.show();
|
|
|
|
edit.show();
|
|
|
|
view.show();
|
|
|
|
regs.show();
|
|
|
|
tuto.show();
|
|
|
|
debug.show();
|
|
|
|
scenar.show();
|
2021-07-08 13:56:42 +02:00
|
|
|
if (scenario.levels[scenar.getselected()].rights > 3)
|
2021-07-06 01:09:46 +02:00
|
|
|
flags.show();
|
2021-07-08 13:56:42 +02:00
|
|
|
if (scenario.levels[scenar.getselected()].rights > 5)
|
2021-07-06 01:09:46 +02:00
|
|
|
stack.show();
|
2021-07-08 13:56:42 +02:00
|
|
|
if (scenario.levels[scenar.getselected()].rights > 2)
|
2021-07-06 01:09:46 +02:00
|
|
|
mem.show();
|
2021-07-08 13:56:42 +02:00
|
|
|
if (scenario.levels[scenar.getselected()].rights > 6)
|
2021-07-06 01:09:46 +02:00
|
|
|
screen.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::initMenus()
|
|
|
|
{
|
|
|
|
Game.setStatusbarMessage ("Menu principal du jeu");
|
|
|
|
Options.setStatusbarMessage ("Options du logiciel IA86");
|
|
|
|
Tools.setStatusbarMessage ("Outils divers");
|
|
|
|
Debug.setStatusbarMessage ("Fonctionnalitées de déboguages");
|
|
|
|
Window.setStatusbarMessage ("Fenêtres en cours d'exécution");
|
|
|
|
Help.setStatusbarMessage ("Aide et informations IA86");
|
|
|
|
Line2.setSeparator();
|
|
|
|
New.addAccelerator (FKey::Meta_n);
|
|
|
|
New.setStatusbarMessage ("Debuter une nouvelle partie");
|
|
|
|
Quit.addAccelerator (FKey::Meta_x);
|
|
|
|
Quit.setStatusbarMessage ("Quitter IA86");
|
2021-07-06 11:44:46 +02:00
|
|
|
Run.addAccelerator (FKey::F9);
|
2021-07-06 01:09:46 +02:00
|
|
|
Run.setStatusbarMessage ("Exécuter le programme - seul un breakpoint arrête");
|
|
|
|
TraceInto.addAccelerator (FKey::F7);
|
|
|
|
TraceInto.setStatusbarMessage ("Pas à pas détaillé - entre dans les CALL");
|
|
|
|
StepOver.addAccelerator (FKey::F8);
|
|
|
|
StepOver.setStatusbarMessage ("Pas à pas - ne rentre pas dans les CALL");
|
|
|
|
Assemble.addAccelerator (FKey::F2);
|
|
|
|
Assemble.setStatusbarMessage ("Assemble le source vers du code machine");
|
2021-07-06 11:44:46 +02:00
|
|
|
Rearange.addAccelerator (FKey::Meta_r);
|
2021-07-06 01:09:46 +02:00
|
|
|
Rearange.setStatusbarMessage ("Reorganise les fenêtres dans leur état initial");
|
|
|
|
Breakpoint.addAccelerator (FKey::F5);
|
|
|
|
Breakpoint.setStatusbarMessage ("Enlève ou met un point d'arrêt");
|
2021-07-06 11:44:46 +02:00
|
|
|
End.addAccelerator (FKey::F6);
|
2021-07-06 01:09:46 +02:00
|
|
|
End.setStatusbarMessage ("Termine le programme et remet à zéro la machine IA86");
|
|
|
|
About.setStatusbarMessage ("A propos de IA86");
|
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void Menu::onTimer (finalcut::FTimerEvent* ev)
|
|
|
|
{
|
|
|
|
refresh();
|
|
|
|
}
|
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
void Menu::initMenusCallBack()
|
|
|
|
{
|
|
|
|
Quit.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
finalcut::getFApplication(),
|
|
|
|
&finalcut::FApplication::cb_exitApp,
|
|
|
|
this
|
|
|
|
);
|
|
|
|
Assemble.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::compile
|
|
|
|
);
|
|
|
|
Run.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::exec
|
|
|
|
);
|
|
|
|
Rearange.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
2021-07-09 18:35:13 +02:00
|
|
|
&Menu::AdjustWindows
|
2021-07-06 01:09:46 +02:00
|
|
|
);
|
|
|
|
TraceInto.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::trace
|
|
|
|
);
|
|
|
|
StepOver.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::step
|
|
|
|
);
|
2021-07-06 11:44:46 +02:00
|
|
|
End.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::end
|
|
|
|
);
|
2021-07-06 13:14:56 +02:00
|
|
|
About.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::about
|
|
|
|
);
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::initMisc()
|
|
|
|
{
|
|
|
|
Info << " █████ █████████ ████████ ████████ \n"
|
|
|
|
<< "░░███ ███░░░░░███ ███░░░░███ ███░░░░███\n"
|
|
|
|
<< " ░███ ░███ ░███ ░███ ░███ ░███ ░░░ \n"
|
|
|
|
<< " ░███ ░███████████ ░░████████ ░█████████ \n"
|
|
|
|
<< " ░███ ░███░░░░░███ ███░░░░███ ░███░░░░███\n"
|
|
|
|
<< " ░███ ░███ ░███ ░███ ░███ ░███ ░███\n"
|
|
|
|
<< " █████ █████ █████░░████████ ░░████████ \n"
|
|
|
|
<< "░░░░░ ░░░░░ ░░░░░ ░░░░░░░░ ░░░░░░░░ \n"
|
|
|
|
<< "THE EVEN MORE PEDAGOGICAL SYSTEM !!\n"
|
|
|
|
<< "\n"
|
|
|
|
<< "Episode 1 : Apprendre l'assembleur X86";
|
|
|
|
Statusbar.setMessage("THE EVEN MORE PEDAGOGICAL SYSTEM !!");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::initLayout()
|
|
|
|
{
|
|
|
|
Info.setGeometry(FPoint{2, 1}, FSize{43, 12});
|
|
|
|
FDialog::initLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::adjustSize()
|
|
|
|
{
|
|
|
|
const auto pw = int(getDesktopWidth());
|
|
|
|
const auto ph = int(getDesktopHeight());
|
|
|
|
setX (1 + (pw - int(getWidth())) / 2, false);
|
|
|
|
setY (1 + (ph - int(getHeight())) / 4, false);
|
|
|
|
finalcut::FDialog::adjustSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::onClose (finalcut::FCloseEvent* ev)
|
|
|
|
{
|
|
|
|
finalcut::FApplication::closeConfirmationDialog (this, ev);
|
|
|
|
}
|
|
|
|
|
2021-07-08 12:06:23 +02:00
|
|
|
void Menu::loadLevel()
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-11 15:27:07 +02:00
|
|
|
vm.Unconfigure();
|
2021-07-11 14:17:58 +02:00
|
|
|
log.append("Application - charge niveau.......................[ INFO ]");
|
2021-07-08 13:56:42 +02:00
|
|
|
view.setText("Objectif: "+scenario.levels[scenar.getselected()].title);
|
2021-07-06 01:09:46 +02:00
|
|
|
view.clear();
|
2021-07-08 13:56:42 +02:00
|
|
|
view.append(scenario.levels[scenar.getselected()].description);
|
2021-07-06 11:44:46 +02:00
|
|
|
tuto.clear();
|
2021-07-08 13:56:42 +02:00
|
|
|
tuto.append(scenario.levels[scenar.getselected()].tutorial);
|
|
|
|
edit.set(scenario.levels[scenar.getselected()].code);
|
2021-07-06 11:44:46 +02:00
|
|
|
debug.clear();
|
2021-07-09 18:35:13 +02:00
|
|
|
vm.setRights(scenario.levels[scenar.getselected()].rights);
|
2021-07-11 15:27:07 +02:00
|
|
|
AdjustWindows();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void Menu::end()
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-09 00:51:05 +02:00
|
|
|
vm.Halt();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void Menu::compile()
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-09 18:35:13 +02:00
|
|
|
vm.Configure(&scenario.levels[scenar.getselected()].init,edit.get());
|
2021-07-10 19:36:29 +02:00
|
|
|
showInstr();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 13:14:56 +02:00
|
|
|
void Menu::about()
|
|
|
|
{
|
|
|
|
log.hide();
|
|
|
|
edit.hide();
|
|
|
|
view.hide();
|
|
|
|
regs.hide();
|
|
|
|
flags.hide();
|
|
|
|
stack.hide();
|
|
|
|
mem.hide();
|
|
|
|
tuto.hide();
|
|
|
|
screen.hide();
|
|
|
|
debug.hide();
|
|
|
|
scenar.hide();
|
|
|
|
this->show();
|
|
|
|
this->redraw();
|
|
|
|
this->Info.redraw();
|
|
|
|
//((finalcut::FApplication*)this->getParent())->sendQueuedEvents();
|
|
|
|
sleep(3);
|
|
|
|
AdjustWindows();
|
|
|
|
}
|
|
|
|
|
2021-07-10 19:36:29 +02:00
|
|
|
void Menu::showInstr()
|
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
try
|
|
|
|
{
|
2021-07-11 15:27:07 +02:00
|
|
|
if (vm.isInitialized())
|
|
|
|
{
|
|
|
|
debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3));
|
|
|
|
debug.setmark(vm.getLine());
|
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
|
|
|
log.append(e.what());
|
|
|
|
vm.Halt();
|
|
|
|
}
|
2021-07-10 19:36:29 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void Menu::refresh()
|
|
|
|
{
|
2021-07-09 00:51:05 +02:00
|
|
|
if (!vm.isInitialized())
|
2021-07-06 15:21:03 +02:00
|
|
|
{
|
2021-07-08 12:06:23 +02:00
|
|
|
regs.set("En attente d'initialisation...");
|
2021-07-10 19:36:29 +02:00
|
|
|
flags.set("Attente...");
|
2021-07-06 15:21:03 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-07-11 14:17:58 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
regs.set(vm.getRegs());
|
|
|
|
flags.set(vm.getFlags());
|
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
|
|
|
log.append(e.what());
|
|
|
|
vm.Halt();
|
|
|
|
}
|
2021-07-06 15:21:03 +02:00
|
|
|
}
|
2021-07-09 00:51:05 +02:00
|
|
|
if (!vm.isExecuted())
|
2021-07-06 13:14:56 +02:00
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
finalcut::FApplication::setDarkTheme();
|
2021-07-06 13:14:56 +02:00
|
|
|
}
|
2021-07-06 11:44:46 +02:00
|
|
|
else
|
2021-07-06 13:14:56 +02:00
|
|
|
{
|
2021-07-06 11:44:46 +02:00
|
|
|
finalcut::FApplication::setDefaultTheme();
|
2021-07-06 13:14:56 +02:00
|
|
|
}
|
2021-07-06 11:44:46 +02:00
|
|
|
auto root_widget = getRootWidget();
|
|
|
|
root_widget->resetColors();
|
|
|
|
root_widget->redraw();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::exec()
|
|
|
|
{
|
2021-07-09 00:51:05 +02:00
|
|
|
if (!vm.isInitialized())
|
|
|
|
compile();
|
2021-07-11 15:27:07 +02:00
|
|
|
vm.Run(0xFFFF,0);
|
|
|
|
showInstr();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::trace()
|
|
|
|
{
|
2021-07-10 19:36:29 +02:00
|
|
|
if (!vm.isInitialized())
|
|
|
|
compile();
|
2021-07-11 15:27:07 +02:00
|
|
|
vm.Run(vm.getNextInstr(),0);
|
2021-07-10 19:36:29 +02:00
|
|
|
showInstr();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::step()
|
|
|
|
{
|
2021-07-10 19:36:29 +02:00
|
|
|
if (!vm.isInitialized())
|
2021-07-11 15:27:07 +02:00
|
|
|
compile();
|
|
|
|
vm.Run(vm.getNextInstr(),0);
|
2021-07-10 19:36:29 +02:00
|
|
|
showInstr();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Fonction Main
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
int main (int argc, char* argv[])
|
|
|
|
{
|
2021-07-08 12:06:23 +02:00
|
|
|
mapping();
|
2021-07-06 01:09:46 +02:00
|
|
|
finalcut::FApplication app {argc, argv};
|
|
|
|
Menu main_dlg {&app};
|
|
|
|
main_dlg.setText ("IA86");
|
|
|
|
main_dlg.setSize ({50, 14});
|
|
|
|
main_dlg.setShadow();
|
|
|
|
main_dlg.show();
|
2021-07-06 11:44:46 +02:00
|
|
|
finalcut::FApplication::setDarkTheme();
|
2021-07-06 01:09:46 +02:00
|
|
|
finalcut::FWidget::setMainWidget (&main_dlg);
|
|
|
|
//usleep(5 * 1000000);
|
|
|
|
main_dlg.hide();
|
|
|
|
return app.exec();
|
|
|
|
}
|