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 scenario;
|
2021-07-13 19:29:49 +02:00
|
|
|
Level level;
|
2021-07-10 19:36:29 +02:00
|
|
|
Unasm unasm;
|
|
|
|
int marker;
|
2021-07-16 19:42:49 +02:00
|
|
|
bool debugnow;
|
2021-07-13 09:30:52 +02:00
|
|
|
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;
|
2021-07-14 13:15:49 +02:00
|
|
|
std::vector<std::array<uint32_t,2>> breakpoints;
|
2021-07-13 09:30:52 +02:00
|
|
|
|
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-13 19:29:49 +02:00
|
|
|
void ScenarioWindow::click()
|
2021-07-11 14:17:58 +02:00
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
((Menu*)this->getParent())->loadLevel(listview.getindex());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScenarioWindow::Load(std::vector<Level> levels)
|
|
|
|
{
|
|
|
|
vector<std::string> items;
|
|
|
|
for(size_t i=0; i < levels.size(); i++)
|
2021-07-11 14:17:58 +02:00
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
//((Menu*)this->getParent())->tolog(".");
|
2021-07-11 14:17:58 +02:00
|
|
|
items.clear();
|
|
|
|
items.push_back(to_string(i));
|
2021-07-13 19:29:49 +02:00
|
|
|
items.push_back(levels[i].title);
|
2021-07-11 14:17:58 +02:00
|
|
|
const finalcut::FStringList line (items.begin(), items.end());
|
2021-07-13 19:29:49 +02:00
|
|
|
listview.insert(line);
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
2021-07-13 19:29:49 +02:00
|
|
|
}
|
2021-07-06 01:09:46 +02:00
|
|
|
|
|
|
|
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 ("Adresse");
|
|
|
|
listview.addColumn ("Opcodes ");
|
|
|
|
listview.addColumn ("Mnémo.");
|
|
|
|
listview.addColumn ("Opérandes");
|
|
|
|
listview.hideSortIndicator(true);
|
|
|
|
listview.setFocus();
|
|
|
|
}
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
std::vector<std::array<std::string, 4>> InstructionWindow::get()
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
|
|
|
return content;
|
|
|
|
}
|
|
|
|
|
2021-07-06 11:44:46 +02:00
|
|
|
void InstructionWindow::clear()
|
|
|
|
{
|
|
|
|
listview.clear();
|
|
|
|
listview.redraw();
|
|
|
|
}
|
|
|
|
|
2021-07-14 13:15:49 +02:00
|
|
|
std::string InstructionWindow::getaddress()
|
2021-07-14 01:15:38 +02:00
|
|
|
{
|
2021-07-14 13:15:49 +02:00
|
|
|
return listview.getCurrentItem()->getText(1).c_str();
|
2021-07-14 01:15:38 +02:00
|
|
|
}
|
|
|
|
|
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-14 01:15:38 +02:00
|
|
|
int InstructionWindow::getindex()
|
|
|
|
{
|
|
|
|
return listview.getindex();
|
|
|
|
}
|
|
|
|
|
|
|
|
void InstructionWindow::setmultimark(std::vector<int> mark)
|
|
|
|
{
|
|
|
|
listview.setmultimark(mark);
|
|
|
|
}
|
|
|
|
|
2021-07-09 18:35:13 +02:00
|
|
|
int InstructionWindow::getsize()
|
|
|
|
{
|
|
|
|
return listview.getCount();
|
|
|
|
}
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
void InstructionWindow::set(std::vector<std::array<std::string, 4>> src)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
|
|
|
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-14 13:15:49 +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()
|
|
|
|
{
|
2021-07-13 09:30:52 +02:00
|
|
|
return scrolltext.getText().toString() ;
|
2021-07-06 11:44:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
Desassembler::Desassembler(Menu *widget) : widget(widget)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
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-16 19:42:49 +02:00
|
|
|
if (debugnow)
|
|
|
|
widget->tolog("Désassembleur - initialisation....................[ OK ]");
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog(e.what());
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-14 13:15:49 +02:00
|
|
|
void Desassembler::setSyntax(int syntax)
|
|
|
|
{
|
|
|
|
cs_option(handle, CS_OPT_SYNTAX, syntax);
|
|
|
|
}
|
|
|
|
|
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);
|
2021-07-11 18:51:41 +02:00
|
|
|
cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON);
|
2021-07-11 14:17:58 +02:00
|
|
|
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-16 19:42:49 +02:00
|
|
|
if (debugnow) widget->tolog("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);
|
2021-07-13 09:30:52 +02:00
|
|
|
std::array<std::string, 4> *array = new std::array<std::string, 4>{adresse, *bytes, *menmonic, *op_str};
|
2021-07-11 14:17:58 +02:00
|
|
|
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();
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog(e.what());
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe Assembler
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
Assembler::Assembler(Menu *widget) : widget(widget)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
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-16 19:42:49 +02:00
|
|
|
if (debugnow)
|
|
|
|
widget->tolog("Assembleur - initialisation.......................[ OK ]");
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog(e.what());
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
2021-07-11 18:51:41 +02:00
|
|
|
ks_option(ks, KS_OPT_SYNTAX, KS_OPT_SYNTAX_NASM);
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-14 13:15:49 +02:00
|
|
|
void Assembler::setSyntax(int syntax)
|
|
|
|
{
|
|
|
|
ks_option(ks, KS_OPT_SYNTAX, syntax);
|
|
|
|
}
|
|
|
|
|
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;
|
2021-07-16 13:14:48 +02:00
|
|
|
std::regex regex_org("^ *.org 0x([0-F]+)$");
|
|
|
|
std::regex regex_name("^ *.title ([a-zA-Z0-9_]+)$");
|
2021-07-11 14:17:58 +02:00
|
|
|
Code *code=new Code;
|
|
|
|
bool begin=true;
|
|
|
|
int org=address;
|
2021-07-16 13:14:48 +02:00
|
|
|
std::string name="/";
|
2021-07-11 14:17:58 +02:00
|
|
|
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;
|
2021-07-16 13:14:48 +02:00
|
|
|
if(std::regex_search(line, match, regex_org))
|
2021-07-11 14:17:58 +02:00
|
|
|
{
|
|
|
|
org=std::stoul(match.str(1), nullptr, 16);
|
|
|
|
}
|
|
|
|
if (!begin)
|
|
|
|
{
|
|
|
|
mcode.push_back(*code);
|
|
|
|
code=new Code;
|
2021-07-16 13:14:48 +02:00
|
|
|
code->address=org;
|
|
|
|
code->name=name;
|
|
|
|
name="/";
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-16 13:14:48 +02:00
|
|
|
else if (line.find(".title") != std::string::npos)
|
|
|
|
{
|
|
|
|
std::smatch match;
|
|
|
|
if(std::regex_search(line, match, regex_name))
|
|
|
|
{
|
|
|
|
name=match.str(1);
|
|
|
|
}
|
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
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-13 19:29:49 +02:00
|
|
|
widget->tolog("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;
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog(e.what());
|
2021-07-11 14:17:58 +02:00
|
|
|
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;
|
2021-07-13 09:30:52 +02:00
|
|
|
throw Error("Assembleur - assemblage...........................[ERREUR]\n Nombre:"+to_string(srcsize)+"\n Erreur:"+std::string(ks_strerror(ks_errno(ks))));
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
code->assembled=true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe VMEngine
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
VMEngine::VMEngine(Menu *widget) : widget(widget)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
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-15 23:29:31 +02:00
|
|
|
std::string VMEngine::getStack()
|
|
|
|
{
|
|
|
|
uint16_t *code=new uint16_t[12];
|
|
|
|
std::string result="";
|
|
|
|
uint16_t SS=getSS();
|
|
|
|
uint32_t ESP=getESP();
|
|
|
|
uint32_t EBP=getEBP();
|
|
|
|
int realaddress=SS*16+ESP-12;
|
|
|
|
if (realaddress<0)
|
|
|
|
realaddress=0;
|
|
|
|
//((Menu *)widget)->tolog(intToHexString(realaddress,8));
|
|
|
|
err = uc_mem_read(uc, realaddress, code, 2*12);
|
|
|
|
if (err)
|
|
|
|
throw Error("VM IA86 - voir pile...............................[ERREUR]");
|
|
|
|
for(int i=11;i>=0;i--)
|
|
|
|
{
|
|
|
|
result+=intToHexString(code[i],4);
|
|
|
|
if (realaddress+i*2==SS*16+ESP)
|
|
|
|
result+="<ESP";
|
|
|
|
if (realaddress+i*2==SS*16+EBP)
|
|
|
|
result+="<EBP";
|
|
|
|
result+="\n";
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
{
|
2021-07-13 09:30:52 +02:00
|
|
|
hadcall=0;
|
2021-07-11 14:17:58 +02:00
|
|
|
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-16 19:42:49 +02:00
|
|
|
if (debugnow)
|
|
|
|
widget->tolog("VM IA86 - initilisation...........................[ OK ]");
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog(e.what());
|
2021-07-06 11:44:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-09 00:51:05 +02:00
|
|
|
bool VMEngine::isExecuted()
|
|
|
|
{
|
2021-07-13 09:30:52 +02:00
|
|
|
return executed;
|
2021-07-09 00:51:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool VMEngine::isInitialized()
|
|
|
|
{
|
2021-07-13 09:30:52 +02:00
|
|
|
return initialized;
|
2021-07-09 00:51:05 +02:00
|
|
|
}
|
|
|
|
|
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-13 09:30:52 +02:00
|
|
|
if (executed)
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog("VM IA86 - arret...................................[ INFO ]");
|
2021-07-13 09:30:52 +02:00
|
|
|
executed=false;
|
2021-07-09 00:51:05 +02:00
|
|
|
}
|
|
|
|
|
2021-07-09 18:35:13 +02:00
|
|
|
void VMEngine::Unconfigure()
|
2021-07-06 11:44:46 +02:00
|
|
|
{
|
2021-07-14 01:15:38 +02:00
|
|
|
this->clearbreakpoints();
|
2021-07-11 14:17:58 +02:00
|
|
|
this->Halt();
|
2021-07-13 09:30:52 +02:00
|
|
|
if (initialized)
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog("VM IA86 - déconfiguration.........................[ INFO ]");
|
2021-07-13 09:30:52 +02:00
|
|
|
initialized=false;
|
2021-07-10 19:36:29 +02:00
|
|
|
}
|
|
|
|
|
2021-07-11 18:20:28 +02:00
|
|
|
std::string VMEngine::getRam(int segment, int address,int lines, int linesize)
|
|
|
|
{
|
|
|
|
int reallinesize=(int)((linesize-16)/4);
|
|
|
|
int size=reallinesize*(lines-3);
|
|
|
|
uint32_t realaddress=segment*16+address;
|
2021-07-14 13:15:49 +02:00
|
|
|
if (realaddress>1024*1024)
|
|
|
|
return "Zone en dehors de la mémorie";
|
2021-07-11 18:20:28 +02:00
|
|
|
uint8_t *code=new uint8_t[512];
|
|
|
|
std::string result="";
|
|
|
|
std::string line;
|
|
|
|
err = uc_mem_read(uc, realaddress, code, 500);
|
|
|
|
if (err)
|
|
|
|
throw Error("VM IA86 - voir mémoire............................[ERREUR]");
|
|
|
|
for(size_t i=0;i<size;i++)
|
|
|
|
{
|
|
|
|
if ((i%reallinesize)==0)
|
|
|
|
{
|
|
|
|
if (i!=0)
|
|
|
|
result+=" | "+line+"\n";
|
|
|
|
result+=intToHexString(address+i,8)+" | ";
|
|
|
|
line="";
|
|
|
|
}
|
|
|
|
result+=intToHexString(code[i],2)+" ";
|
|
|
|
if (std::isprint(code[i]))
|
|
|
|
line+=(char)code[i];
|
|
|
|
else
|
|
|
|
line+='.';
|
|
|
|
}
|
|
|
|
result+=" | "+line+"\n";
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-07-16 13:14:48 +02:00
|
|
|
std::vector<std::array<std::string, 7>> VMEngine::getCode()
|
|
|
|
{
|
|
|
|
int line=0;
|
|
|
|
std::vector<std::array<std::string, 7>> result;
|
|
|
|
for(Code code: mcode)
|
|
|
|
{
|
|
|
|
std::string *linestr = new std::string(to_string(line++));
|
|
|
|
std::string *name = new std::string(code.name);
|
|
|
|
std::string *address = new std::string(intToHexString(code.address,8));
|
|
|
|
std::string *size = new std::string(to_string(code.size));
|
|
|
|
std::string *srcsize = new std::string(to_string(code.src.size()));
|
|
|
|
std::string *assembled = new std::string;
|
|
|
|
if (code.assembled)
|
|
|
|
*assembled="X";
|
|
|
|
std::string *loaded = new std::string;
|
|
|
|
if (code.loaded)
|
|
|
|
*loaded="X";
|
|
|
|
std::array<std::string, 7> *array = new std::array<std::string, 7>{*linestr,*name,*address,*size,*srcsize,*assembled,*loaded};
|
|
|
|
result.push_back(*array);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
std::vector<std::array<std::string, 4>> 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
|
|
|
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
|
|
|
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);
|
2021-07-13 09:30:52 +02:00
|
|
|
std::vector<std::array<std::string, 4>> result = {unasm.src.begin()+first,unasm.src.begin()+last};
|
|
|
|
for(std::array<std::string, 4> item: result)
|
2021-07-10 19:36:29 +02:00
|
|
|
{
|
2021-07-13 09:30:52 +02:00
|
|
|
if (item[0]==reference)
|
2021-07-10 19:36:29 +02:00
|
|
|
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
|
|
|
}
|
2021-07-13 19:29:49 +02:00
|
|
|
|
|
|
|
void VMEngine::clearbreakpoints()
|
|
|
|
{
|
|
|
|
breakpoints.clear();
|
|
|
|
}
|
|
|
|
|
2021-07-14 13:15:49 +02:00
|
|
|
void VMEngine::addbreakpoint(uint16_t segment,uint32_t address)
|
2021-07-13 19:29:49 +02:00
|
|
|
{
|
2021-07-14 13:15:49 +02:00
|
|
|
for(std::array<uint32_t,2> item: breakpoints)
|
|
|
|
if (item[1]==address && item[0]==segment) return;
|
|
|
|
breakpoints.push_back({segment,address});
|
2021-07-13 19:29:49 +02:00
|
|
|
}
|
|
|
|
|
2021-07-14 13:15:49 +02:00
|
|
|
void VMEngine::removebreakpoint(uint16_t segment,uint32_t address)
|
2021-07-13 19:29:49 +02:00
|
|
|
{
|
|
|
|
int i=0;
|
2021-07-14 13:15:49 +02:00
|
|
|
for(std::array<uint32_t,2> item: breakpoints)
|
|
|
|
if (item[1]==address && item[0]==segment)
|
2021-07-13 19:29:49 +02:00
|
|
|
{
|
|
|
|
breakpoints.erase(breakpoints.begin()+i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<int> VMEngine::getBreapoints()
|
|
|
|
{
|
|
|
|
std::vector<int> list;
|
2021-07-14 01:15:38 +02:00
|
|
|
std::vector<std::array<std::string, 4>> items=((Menu*)widget)->getsrc();
|
2021-07-14 13:15:49 +02:00
|
|
|
for(std::array<uint32_t,2> bp: breakpoints)
|
2021-07-14 01:15:38 +02:00
|
|
|
{
|
|
|
|
int line=0;
|
|
|
|
for(std::array<std::string, 4> item: items)
|
|
|
|
{
|
2021-07-16 18:27:29 +02:00
|
|
|
if (item[0]==intToHexString(bp[1],8) && getCS()==bp[0])
|
2021-07-14 01:15:38 +02:00
|
|
|
{
|
2021-07-16 18:27:29 +02:00
|
|
|
//((Menu*)widget)->tolog(to_string(line));
|
2021-07-14 13:15:49 +02:00
|
|
|
list.push_back(line);
|
2021-07-14 01:15:38 +02:00
|
|
|
break;
|
|
|
|
}
|
2021-07-14 13:15:49 +02:00
|
|
|
line++;
|
2021-07-14 01:15:38 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-13 19:29:49 +02:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// 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));
|
2021-07-14 13:15:49 +02:00
|
|
|
bool breakp=false;
|
|
|
|
for(std::array<uint32_t,2> bp: breakpoints)
|
|
|
|
if (address==bp[0]*16+bp[1])
|
2021-07-16 18:27:29 +02:00
|
|
|
{
|
2021-07-14 13:15:49 +02:00
|
|
|
breakp=true;
|
2021-07-16 18:27:29 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!breakp && (!step || (hadcall>0 && !call))) return;
|
|
|
|
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
|
|
|
|
hadcall=0;
|
2021-07-13 09:30:52 +02:00
|
|
|
uc_emu_stop(uc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void hook_call(uc_engine *uc, uint32_t intno, void *user_data)
|
|
|
|
{
|
|
|
|
((Menu *)user_data)->tolog("SYSCALL");
|
|
|
|
}
|
|
|
|
|
2021-07-09 18:35:13 +02:00
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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-13 19:29:49 +02:00
|
|
|
bufferaddress=-1;
|
2021-07-13 09:30:52 +02:00
|
|
|
initialized=false;
|
|
|
|
executed=false;
|
2021-07-13 19:29:49 +02:00
|
|
|
hadcall=0x0;
|
|
|
|
//widget->tolog("Mappage de la mémoire virtuelle");
|
2021-07-11 14:17:58 +02:00
|
|
|
uc_mem_map(uc, 0, 1 * 1024 * 1024, UC_PROT_ALL);
|
2021-07-13 09:30:52 +02:00
|
|
|
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);
|
2021-07-11 14:17:58 +02:00
|
|
|
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]");
|
2021-07-16 19:42:49 +02:00
|
|
|
if (debugnow) widget->tolog("Section N°"+std::to_string(i)+" : "+intToHexString(mcode[i].address,8)+" -> "+to_string(mcode[i].size)+" octets");
|
2021-07-11 15:27:07 +02:00
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
status=verify();
|
|
|
|
if (status==0)
|
2021-07-11 15:27:07 +02:00
|
|
|
{
|
2021-07-13 09:30:52 +02:00
|
|
|
initialized=true;
|
2021-07-11 15:27:07 +02:00
|
|
|
SetRegs(init);
|
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
else
|
2021-07-13 09:30:52 +02:00
|
|
|
initialized=false;
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog(e.what());
|
2021-07-13 09:30:52 +02:00
|
|
|
initialized=false;
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
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-14 13:15:49 +02:00
|
|
|
void VMEngine::setSyntax(int asmsyntax,int unasmsyntax)
|
|
|
|
{
|
|
|
|
asmer.setSyntax(asmsyntax);
|
|
|
|
unasmer.setSyntax(unasmsyntax);
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-07-14 13:15:49 +02:00
|
|
|
uint32_t VMEngine::getESI()
|
|
|
|
{
|
|
|
|
int esi;
|
|
|
|
err = uc_reg_read(uc, UC_X86_REG_ESI, &esi);
|
|
|
|
if (err != UC_ERR_OK)
|
|
|
|
throw Error("VM IA86 - voir ESI................................[ERREUR]");
|
|
|
|
return esi;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t VMEngine::getEDI()
|
|
|
|
{
|
2021-07-15 23:29:31 +02:00
|
|
|
uint32_t edi;
|
2021-07-14 13:15:49 +02:00
|
|
|
err = uc_reg_read(uc, UC_X86_REG_EDI, &edi);
|
|
|
|
if (err != UC_ERR_OK)
|
|
|
|
throw Error("VM IA86 - voir EDI................................[ERREUR]");
|
|
|
|
return edi;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t VMEngine::getESP()
|
|
|
|
{
|
2021-07-15 23:29:31 +02:00
|
|
|
uint32_t esp;
|
2021-07-14 13:15:49 +02:00
|
|
|
err = uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
|
|
|
if (err != UC_ERR_OK)
|
|
|
|
throw Error("VM IA86 - voir ESP................................[ERREUR]");
|
|
|
|
return esp;
|
|
|
|
}
|
|
|
|
|
2021-07-15 23:29:31 +02:00
|
|
|
uint32_t VMEngine::getEBP()
|
|
|
|
{
|
|
|
|
uint32_t ebp;
|
|
|
|
err = uc_reg_read(uc, UC_X86_REG_EBP, &ebp);
|
|
|
|
if (err != UC_ERR_OK)
|
|
|
|
throw Error("VM IA86 - voir EBP................................[ERREUR]");
|
|
|
|
return ebp;
|
|
|
|
}
|
|
|
|
|
2021-07-10 19:36:29 +02:00
|
|
|
uint32_t VMEngine::getEIP()
|
|
|
|
{
|
2021-07-15 23:29:31 +02:00
|
|
|
uint32_t 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-15 23:29:31 +02:00
|
|
|
uint16_t 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-15 23:29:31 +02:00
|
|
|
uint16_t 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()
|
|
|
|
{
|
2021-07-15 23:29:31 +02:00
|
|
|
uint16_t es;
|
2021-07-11 14:17:58 +02:00
|
|
|
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()
|
|
|
|
{
|
2021-07-15 23:29:31 +02:00
|
|
|
uint16_t ss;
|
2021-07-11 14:17:58 +02:00
|
|
|
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
|
2021-07-16 19:42:49 +02:00
|
|
|
out << "EAX=" << std::uppercase << std::setfill('0') << std::setw(8) << std::hex << init->dump.regs.eax << " ";
|
|
|
|
if (debugnow)
|
|
|
|
widget->tolog(out.str());
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
void VMEngine::Run(bool astep, bool acall, 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-13 09:30:52 +02:00
|
|
|
if (verify()==0 && initialized)
|
2021-07-11 14:17:58 +02:00
|
|
|
{
|
2021-07-13 09:30:52 +02:00
|
|
|
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;
|
|
|
|
}
|
2021-07-11 15:27:07 +02:00
|
|
|
if (err)
|
|
|
|
throw Error("VM IA86 - execution...............................[ERREUR]");
|
|
|
|
else
|
|
|
|
{
|
2021-07-13 09:30:52 +02:00
|
|
|
if (!executed)
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog("VM IA86 - execution...............................[ INFO ]");
|
2021-07-13 09:30:52 +02:00
|
|
|
executed="true";
|
2021-07-11 15:27:07 +02:00
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
2021-07-11 18:20:28 +02:00
|
|
|
this->Halt();
|
2021-07-13 19:29:49 +02:00
|
|
|
widget->tolog(e.what());
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Classe Menu
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
Menu::Menu (finalcut::FWidget* parent)
|
|
|
|
: finalcut::FDialog{parent}
|
|
|
|
{
|
|
|
|
initWindows();
|
|
|
|
initMisc();
|
|
|
|
initMenus();
|
|
|
|
initMenusCallBack();
|
2021-07-13 19:29:49 +02:00
|
|
|
loadScenario("./scenarios.json");
|
|
|
|
addTimer(50);
|
2021-07-16 19:42:49 +02:00
|
|
|
if (debugnow)
|
|
|
|
tolog("DEBOGUAGE ACTIVE !");
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::initWindows()
|
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
this->setText ("Journaux");
|
|
|
|
this->show();
|
|
|
|
info.setText ("Informations");
|
|
|
|
info.setResizeable();
|
|
|
|
info.show();
|
2021-07-06 01:09:46 +02:00
|
|
|
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");
|
2021-07-15 23:29:31 +02:00
|
|
|
mem.setResizeable();
|
2021-07-06 01:09:46 +02:00
|
|
|
tuto.setText ("Guide");
|
|
|
|
tuto.setResizeable();
|
|
|
|
tuto.show();
|
|
|
|
screen.setText ("Ecran");
|
|
|
|
debug.setText ("Instructions");
|
|
|
|
debug.setResizeable();
|
|
|
|
debug.show();
|
|
|
|
scenar.setText ("Scénarios");
|
|
|
|
scenar.show();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Level 1 : IP AL
|
2021-07-13 09:30:52 +02:00
|
|
|
// Level 2 : I:P AX
|
2021-07-06 01:09:46 +02:00
|
|
|
// 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-14 01:15:38 +02:00
|
|
|
//this->setGeometry ( FPoint { 63, 45 }, FSize{60, 11} );
|
2021-07-06 11:44:46 +02:00
|
|
|
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} );
|
2021-07-13 09:30:52 +02:00
|
|
|
screen.setGeometry ( FPoint { 103, 16 }, FSize{82, 28} );
|
2021-07-06 11:44:46 +02:00
|
|
|
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-13 19:29:49 +02:00
|
|
|
info.setGeometry (FPoint { 55, 25 }, FSize{50, 14});
|
2021-07-14 01:15:38 +02:00
|
|
|
//this->show();
|
2021-07-13 19:29:49 +02:00
|
|
|
info.hide();
|
2021-07-06 13:14:56 +02:00
|
|
|
flags.hide();
|
|
|
|
stack.hide();
|
|
|
|
mem.hide();
|
|
|
|
screen.hide();
|
2021-07-13 19:29:49 +02:00
|
|
|
if (scenario.loaded)
|
|
|
|
{
|
|
|
|
info.show();
|
|
|
|
edit.show();
|
|
|
|
view.show();
|
|
|
|
regs.show();
|
|
|
|
tuto.show();
|
|
|
|
debug.show();
|
|
|
|
scenar.show();
|
|
|
|
if (level.rights > 3)
|
|
|
|
flags.show();
|
|
|
|
if (level.rights > 5)
|
|
|
|
stack.show();
|
|
|
|
if (level.rights > 2)
|
|
|
|
mem.show();
|
|
|
|
if (level.rights > 6)
|
|
|
|
screen.show();
|
2021-07-14 01:15:38 +02:00
|
|
|
/*Options.setEnable();
|
2021-07-13 19:29:49 +02:00
|
|
|
Tools.setEnable();
|
|
|
|
Window.setEnable();
|
|
|
|
Debug.setEnable();
|
2021-07-15 23:29:31 +02:00
|
|
|
Breakpoint.setEnable(); */
|
2021-07-13 19:29:49 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
edit.hide();
|
|
|
|
view.hide();
|
|
|
|
regs.hide();
|
|
|
|
tuto.hide();
|
|
|
|
debug.hide();
|
|
|
|
scenar.hide();
|
2021-07-14 01:15:38 +02:00
|
|
|
/*Options.setDisable();
|
2021-07-13 19:29:49 +02:00
|
|
|
Tools.setDisable();
|
|
|
|
Window.setDisable();
|
|
|
|
Debug.setDisable();
|
2021-07-15 23:29:31 +02:00
|
|
|
Breakpoint.setDisable(); */
|
2021-07-13 19:29:49 +02:00
|
|
|
}
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
2021-07-14 13:15:49 +02:00
|
|
|
About.setStatusbarMessage ("A propos de IA86");
|
|
|
|
AddBp.addAccelerator (FKey::F4);
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
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-14 01:15:38 +02:00
|
|
|
AddBp.addCallback
|
2021-07-06 13:14:56 +02:00
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
2021-07-14 13:15:49 +02:00
|
|
|
&Menu::addbp
|
|
|
|
);
|
|
|
|
AsmAtt.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::changesyntax
|
|
|
|
);
|
|
|
|
UnasmAtt.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::changesyntax
|
|
|
|
);
|
2021-07-15 23:29:31 +02:00
|
|
|
Ds_000.addCallback
|
2021-07-14 13:15:49 +02:00
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::showInstr
|
|
|
|
);
|
|
|
|
Ds_esi.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::showInstr
|
|
|
|
);
|
|
|
|
Es_edi.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::showInstr
|
|
|
|
);
|
|
|
|
Cs_eip.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::showInstr
|
|
|
|
);
|
|
|
|
Ss_esp.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::showInstr
|
2021-07-06 13:14:56 +02:00
|
|
|
);
|
2021-07-15 23:29:31 +02:00
|
|
|
Ss_FFF.addCallback
|
|
|
|
(
|
|
|
|
"clicked",
|
|
|
|
this,
|
|
|
|
&Menu::showInstr
|
|
|
|
);
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::initMisc()
|
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
info.set("\
|
|
|
|
█████ █████████ ████████ ████████ \n\
|
|
|
|
░░███ ███░░░░░███ ███░░░░███ ███░░░░███\n\
|
|
|
|
░███ ░███ ░███ ░███ ░███ ░███ ░░░ \n\
|
|
|
|
░███ ░███████████ ░░████████ ░█████████ \n\
|
|
|
|
░███ ░███░░░░░███ ███░░░░███ ░███░░░░███\n\
|
|
|
|
░███ ░███ ░███ ░███ ░███ ░███ ░███\n\
|
|
|
|
█████ █████ █████░░████████ ░░████████ \n\
|
|
|
|
░░░░░ ░░░░░ ░░░░░ ░░░░░░░░ ░░░░░░░░ \n\
|
|
|
|
THE EVEN MORE PEDAGOGICAL SYSTEM !!\n\
|
|
|
|
\n\
|
|
|
|
Episode 1 : Apprendre l'assembleur X86");
|
2021-07-06 01:09:46 +02:00
|
|
|
Statusbar.setMessage("THE EVEN MORE PEDAGOGICAL SYSTEM !!");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::initLayout()
|
|
|
|
{
|
2021-07-14 01:15:38 +02:00
|
|
|
this->setGeometry ( FPoint { 63, 45 }, FSize{60, 11}, false);
|
|
|
|
this->setTopPadding(1);
|
|
|
|
this->setLeftPadding(0);
|
|
|
|
this->setRightPadding(0);
|
|
|
|
this->setBottomPadding(0);
|
2021-07-15 23:29:31 +02:00
|
|
|
Ds_000.setChecked();
|
2021-07-14 01:15:38 +02:00
|
|
|
Log.setGeometry (FPoint{0, 0}, FSize{getWidth(), getHeight()},false);
|
2021-07-06 01:09:46 +02:00
|
|
|
FDialog::initLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::onClose (finalcut::FCloseEvent* ev)
|
|
|
|
{
|
|
|
|
finalcut::FApplication::closeConfirmationDialog (this, ev);
|
|
|
|
}
|
|
|
|
|
2021-07-13 19:29:49 +02:00
|
|
|
void Menu::closeLevel()
|
|
|
|
{
|
|
|
|
vm.Unconfigure();
|
|
|
|
AdjustWindows();
|
|
|
|
}
|
|
|
|
|
2021-07-15 23:29:31 +02:00
|
|
|
/*void Menu::loadBios(std::string file)
|
|
|
|
{
|
|
|
|
|
|
|
|
std::ifstream input(file, std::ios::binary );
|
|
|
|
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
|
|
|
|
|
|
|
|
}*/
|
|
|
|
|
2021-07-13 19:29:49 +02:00
|
|
|
void Menu::loadScenario(std::string file)
|
|
|
|
{
|
|
|
|
|
|
|
|
scenario.loaded=false;
|
|
|
|
std::ifstream inFile;
|
|
|
|
inFile.open(file);
|
|
|
|
std::stringstream strStream;
|
|
|
|
strStream << inFile.rdbuf();
|
|
|
|
std::string json=strStream.str();
|
|
|
|
std::istringstream json_data(json);
|
|
|
|
struct_mapping::map_json_to_struct(scenario, json_data);
|
|
|
|
if (scenario.levels.size()>0)
|
|
|
|
{
|
|
|
|
scenar.Load(scenario.levels);
|
|
|
|
scenario.loaded=true;
|
2021-07-16 19:42:49 +02:00
|
|
|
if (debugnow)
|
|
|
|
tolog("Application - charge scénarios....................[ OK ]");
|
2021-07-13 19:29:49 +02:00
|
|
|
tolog("-={ "+ scenario.title+" }=-");
|
|
|
|
loadLevel(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tolog("Application - charge scénarios....................[ERREUR]");
|
|
|
|
closeLevel();
|
|
|
|
}
|
2021-07-15 23:29:31 +02:00
|
|
|
inFile.close();
|
2021-07-13 19:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::loadLevel(int alevel)
|
2021-07-06 01:09:46 +02:00
|
|
|
{
|
2021-07-16 19:42:49 +02:00
|
|
|
if (scenario.levels[alevel].title!=level.title)
|
|
|
|
{
|
|
|
|
vm.Unconfigure();
|
|
|
|
level=scenario.levels[alevel];
|
|
|
|
if (debugnow)
|
|
|
|
tolog("Application - charge niveau.......................[ INFO ]");
|
|
|
|
view.setText("Objectif: "+level.title);
|
|
|
|
view.clear();
|
|
|
|
view.append(level.description);
|
|
|
|
tuto.clear();
|
|
|
|
tuto.append(level.tutorial);
|
|
|
|
edit.set(level.code);
|
|
|
|
debug.clear();
|
|
|
|
vm.setRights(level.rights);
|
|
|
|
AdjustWindows();
|
|
|
|
showInstr();
|
|
|
|
}
|
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-13 19:29:49 +02:00
|
|
|
vm.Configure(&level.init,edit.get());
|
2021-07-13 09:30:52 +02:00
|
|
|
ClearScreen();
|
2021-07-10 19:36:29 +02:00
|
|
|
showInstr();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-13 09:30:52 +02:00
|
|
|
void Menu::tolog(std::string str)
|
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
this->Log.append(str);
|
2021-07-14 01:15:38 +02:00
|
|
|
this->Log.scrollBy (0, 10);
|
2021-07-13 09:30:52 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 13:14:56 +02:00
|
|
|
void Menu::about()
|
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
this->hide();
|
2021-07-06 13:14:56 +02:00
|
|
|
edit.hide();
|
|
|
|
view.hide();
|
|
|
|
regs.hide();
|
|
|
|
flags.hide();
|
|
|
|
stack.hide();
|
|
|
|
mem.hide();
|
|
|
|
tuto.hide();
|
|
|
|
screen.hide();
|
|
|
|
debug.hide();
|
|
|
|
scenar.hide();
|
2021-07-13 19:29:49 +02:00
|
|
|
info.show();
|
|
|
|
info.redraw();
|
2021-07-06 13:14:56 +02:00
|
|
|
//((finalcut::FApplication*)this->getParent())->sendQueuedEvents();
|
|
|
|
sleep(3);
|
|
|
|
AdjustWindows();
|
|
|
|
}
|
|
|
|
|
2021-07-14 01:15:38 +02:00
|
|
|
std::vector<std::array<std::string, 4>> Menu::getsrc()
|
|
|
|
{
|
|
|
|
return debug.get();
|
|
|
|
}
|
|
|
|
|
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())
|
|
|
|
{
|
2021-07-16 13:14:48 +02:00
|
|
|
try
|
|
|
|
{
|
|
|
|
debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3));
|
|
|
|
debug.setmark(vm.getLine());
|
|
|
|
debug.setmultimark(vm.getBreapoints());
|
|
|
|
regs.set(vm.getRegs());
|
|
|
|
flags.set(vm.getFlags());
|
|
|
|
stack.set(vm.getStack());
|
|
|
|
if (Ds_000.isChecked())
|
|
|
|
mem.set(vm.getRam(vm.getDS(), 0x000000000, mem.getHeight(),mem.getWidth()));
|
|
|
|
else if (Ds_esi.isChecked())
|
|
|
|
mem.set(vm.getRam(vm.getDS(), vm.getESI(), mem.getHeight(),mem.getWidth()));
|
|
|
|
else if (Es_edi.isChecked())
|
|
|
|
mem.set(vm.getRam(vm.getES(), vm.getEDI(), mem.getHeight(),mem.getWidth()));
|
|
|
|
else if (Cs_eip.isChecked())
|
|
|
|
mem.set(vm.getRam(vm.getCS(), vm.getEIP(), mem.getHeight(),mem.getWidth()));
|
|
|
|
else if (Ss_esp.isChecked())
|
|
|
|
mem.set(vm.getRam(vm.getSS(), vm.getESP(), mem.getHeight(),mem.getWidth()));
|
|
|
|
else if (Ss_FFF.isChecked())
|
|
|
|
mem.set(vm.getRam(vm.getSS(), 0x0000FF20, mem.getHeight(),mem.getWidth()));
|
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
|
|
|
tolog(e.what());
|
|
|
|
vm.Halt();
|
|
|
|
vm.Unconfigure();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
regs.set("En attente d'initialisation...");
|
|
|
|
flags.set("Attente...");
|
|
|
|
stack.set("Attente...");
|
|
|
|
mem.set("En attente d'initialisation...");
|
|
|
|
screen.set("En attente d'initialisation...");
|
2021-07-11 15:27:07 +02:00
|
|
|
}
|
2021-07-11 14:17:58 +02:00
|
|
|
}
|
|
|
|
catch(exception const& e)
|
|
|
|
{
|
2021-07-13 19:29:49 +02:00
|
|
|
tolog(e.what());
|
2021-07-11 14:17:58 +02:00
|
|
|
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.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-16 18:27:29 +02:00
|
|
|
auto root_widget = getRootWidget();
|
2021-07-06 11:44:46 +02:00
|
|
|
root_widget->resetColors();
|
2021-07-16 18:27:29 +02:00
|
|
|
root_widget->redraw();
|
2021-07-06 11:44:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Menu::exec()
|
|
|
|
{
|
2021-07-09 00:51:05 +02:00
|
|
|
if (!vm.isInitialized())
|
|
|
|
compile();
|
2021-07-13 09:30:52 +02:00
|
|
|
vm.Run(false,false,0);
|
2021-07-11 15:27:07 +02:00
|
|
|
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-13 09:30:52 +02:00
|
|
|
vm.Run(true,false,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();
|
2021-07-13 09:30:52 +02:00
|
|
|
vm.Run(true,true,0);
|
2021-07-10 19:36:29 +02:00
|
|
|
showInstr();
|
2021-07-06 01:09:46 +02:00
|
|
|
}
|
|
|
|
|
2021-07-14 13:15:49 +02:00
|
|
|
void Menu::changesyntax()
|
2021-07-14 01:15:38 +02:00
|
|
|
{
|
2021-07-14 13:15:49 +02:00
|
|
|
int asmsyntax,unasmsyntax;
|
|
|
|
if (AsmAtt.isChecked())
|
|
|
|
asmsyntax=KS_OPT_SYNTAX_ATT;
|
|
|
|
else
|
|
|
|
asmsyntax=KS_OPT_SYNTAX_INTEL;
|
|
|
|
if (UnasmAtt.isChecked())
|
|
|
|
unasmsyntax=CS_OPT_SYNTAX_ATT;
|
|
|
|
else
|
|
|
|
unasmsyntax=CS_OPT_SYNTAX_INTEL;
|
|
|
|
vm.setSyntax(asmsyntax,unasmsyntax);
|
2021-07-14 01:15:38 +02:00
|
|
|
showInstr();
|
|
|
|
}
|
|
|
|
|
2021-07-14 13:15:49 +02:00
|
|
|
void Menu::addbp()
|
|
|
|
{
|
|
|
|
if (vm.isInitialized())
|
|
|
|
{
|
|
|
|
std::string address=debug.getaddress();
|
2021-07-16 19:42:49 +02:00
|
|
|
if (debugnow)
|
|
|
|
tolog("VM IA86 - ajout breakpoint.....................["+address+"]");
|
2021-07-14 13:15:49 +02:00
|
|
|
vm.addbreakpoint(vm.getCS(),stoi(address,nullptr,16));
|
|
|
|
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-16 19:42:49 +02:00
|
|
|
std::vector<std::string> args(argv, argv+argc);
|
|
|
|
for (size_t i = 1; i < args.size(); ++i) {
|
|
|
|
debugnow=(args[i] == "debug");
|
|
|
|
}
|
2021-07-06 01:09:46 +02:00
|
|
|
finalcut::FApplication app {argc, argv};
|
|
|
|
Menu main_dlg {&app};
|
|
|
|
finalcut::FWidget::setMainWidget (&main_dlg);
|
|
|
|
return app.exec();
|
|
|
|
}
|