Affichage des instructions opérationnel
This commit is contained in:
parent
af4e98a512
commit
131d311196
171
ia86.cpp
171
ia86.cpp
|
@ -75,7 +75,8 @@ Scenario readscenario(std::string filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Scenario scenario;
|
Scenario scenario;
|
||||||
|
Unasm unasm;
|
||||||
|
int marker;
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Classe ScenarioWindow
|
// Classe ScenarioWindow
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -172,7 +173,6 @@ int InstructionWindow::getsize()
|
||||||
return listview.getCount();
|
return listview.getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InstructionWindow::set(std::vector<std::array<std::string, 5>> src)
|
void InstructionWindow::set(std::vector<std::array<std::string, 5>> src)
|
||||||
{
|
{
|
||||||
content=src;
|
content=src;
|
||||||
|
@ -308,28 +308,23 @@ void TextWindow::adjustSize()
|
||||||
|
|
||||||
Desassembler::Desassembler(TextWindow *log) : log(log)
|
Desassembler::Desassembler(TextWindow *log) : log(log)
|
||||||
{
|
{
|
||||||
std::stringstream out;
|
|
||||||
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
|
err = cs_open(CS_ARCH_X86, CS_MODE_16, &handle);
|
||||||
if (err != CS_ERR_OK) {
|
if (err != CS_ERR_OK)
|
||||||
out << "Erreur : Initialisation du désassembleur X86" << err;
|
log->append("Erreur : Initialisation du désassembleur X86");
|
||||||
log->append(out.str());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
log->append("Initialisation du désassembleur X86");
|
log->append("Initialisation du désassembleur X86");
|
||||||
}
|
}
|
||||||
|
|
||||||
Unasm *Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size)
|
void Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t size, Unasm *unasm)
|
||||||
{
|
{
|
||||||
Unasm *unasm=new Unasm;
|
|
||||||
std::stringstream out;
|
|
||||||
srcsize=cs_disasm(handle, content, size, address, 0, &insn);
|
srcsize=cs_disasm(handle, content, size, address, 0, &insn);
|
||||||
if (srcsize == 0)
|
if (srcsize == 0)
|
||||||
log->append("Erreur de désassemblage");
|
log->append("Erreur de désassemblage");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out << "Désassemblage réussi, taille du source :" << srcsize;
|
log->append("Désassemblage réussi, taille du source :"+to_string(srcsize));
|
||||||
log->append(out.str());
|
|
||||||
unasm->src.clear();
|
unasm->src.clear();
|
||||||
|
unasm->pos.clear();
|
||||||
for (size_t j = 0; j < srcsize; j++)
|
for (size_t j = 0; j < srcsize; j++)
|
||||||
{
|
{
|
||||||
std::string *bytes = new std::string("");
|
std::string *bytes = new std::string("");
|
||||||
|
@ -340,12 +335,10 @@ Unasm *Desassembler::Desassemble(uint8_t *content, uint32_t address,uint32_t siz
|
||||||
std::string *op_str = new std::string((char *)insn[j].op_str);
|
std::string *op_str = new std::string((char *)insn[j].op_str);
|
||||||
std::array<std::string, 5> *array = new std::array<std::string, 5>{"", adresse, *bytes, *menmonic, *op_str};
|
std::array<std::string, 5> *array = new std::array<std::string, 5>{"", adresse, *bytes, *menmonic, *op_str};
|
||||||
unasm->src.push_back(*array);
|
unasm->src.push_back(*array);
|
||||||
std::array<int, 2> *array2 = new std::array<int, 2>{(int)insn[j].address,(int)insn[j].size};
|
unasm->pos.push_back(insn[j].address);
|
||||||
unasm->pos.push_back(*array2);
|
|
||||||
}
|
}
|
||||||
cs_free(insn, srcsize);
|
cs_free(insn, srcsize);
|
||||||
}
|
}
|
||||||
return unasm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -444,6 +437,7 @@ void Assembler::Assemble(Code *code)
|
||||||
|
|
||||||
VMEngine::VMEngine(TextWindow *log) : log(log)
|
VMEngine::VMEngine(TextWindow *log) : log(log)
|
||||||
{
|
{
|
||||||
|
code=new uint8_t[500];
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
// Level 1 : IP AL
|
// Level 1 : IP AL
|
||||||
|
@ -503,18 +497,6 @@ std::string VMEngine::getFlags()
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *VMEngine::getRamRaw(uint32_t address, uint32_t size)
|
|
||||||
{
|
|
||||||
uint8_t *code=new uint8_t[512];
|
|
||||||
err = uc_mem_read(uc, address, code, size);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
log->append("Erreur de copie mémoire depuis la machine virtuelle");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string VMEngine::getRegs()
|
std::string VMEngine::getRegs()
|
||||||
{
|
{
|
||||||
int regsi836[] = {
|
int regsi836[] = {
|
||||||
|
@ -651,21 +633,66 @@ void VMEngine::Unconfigure()
|
||||||
this->initialized=false;
|
this->initialized=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::array<std::string, 5>> VMEngine::getInstr(int address,int size)
|
uint32_t VMEngine::getNextInstr()
|
||||||
{
|
{
|
||||||
if (address<alladdress || address+6>alladdress+500)
|
uint32_t now=getEIP();
|
||||||
|
bool flag=false;
|
||||||
|
for(int pos: unasm.pos)
|
||||||
{
|
{
|
||||||
int begin=address-30;
|
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)
|
||||||
|
{
|
||||||
|
uint32_t realaddress=segment*16+address;
|
||||||
|
if (realaddress<bufferaddress || realaddress+6>bufferaddress+500)
|
||||||
|
{
|
||||||
|
int begin=realaddress-30;
|
||||||
if (begin<0) begin=0x00000000;
|
if (begin<0) begin=0x00000000;
|
||||||
code=this->getRamRaw(begin, 500);
|
err = uc_mem_read(uc, begin, code, 500);
|
||||||
alladdress=begin;
|
if (err)
|
||||||
|
{
|
||||||
|
log->append("Erreur de copie mémoire depuis la machine virtuelle");
|
||||||
|
}
|
||||||
|
bufferaddress=begin;
|
||||||
}
|
}
|
||||||
crc = crc32(0, code, 500);
|
crc = crc32(0, code, 500);
|
||||||
if (crc != crc_old)
|
if (crc != crc_old)
|
||||||
{
|
{
|
||||||
unasmer.Desassemble(code, alladdress, 500);
|
unasmer.Desassemble(code, address, 500, &unasm);
|
||||||
crc_old=crc;
|
crc_old=crc;
|
||||||
|
}
|
||||||
|
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++;
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int VMEngine::getLine()
|
||||||
|
{
|
||||||
|
return marker;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMEngine::Configure(State *init, std::string code)
|
void VMEngine::Configure(State *init, std::string code)
|
||||||
|
@ -706,36 +733,35 @@ void VMEngine::setRights(int rights)
|
||||||
this->rights=rights;
|
this->rights=rights;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VMEngine::getEIP()
|
uint32_t VMEngine::getCurrent()
|
||||||
{
|
{
|
||||||
int eip=-666;
|
return getEIP()+getCS()*16;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t VMEngine::getEIP()
|
||||||
|
{
|
||||||
|
int eip=0;
|
||||||
err = uc_reg_read(uc, UC_X86_REG_EIP, &eip);
|
err = uc_reg_read(uc, UC_X86_REG_EIP, &eip);
|
||||||
if (err != UC_ERR_OK)
|
if (err != UC_ERR_OK)
|
||||||
log->append("Impossible de récupérer le registre: EIP");
|
log->append("Impossible de récupérer le registre: EIP");
|
||||||
if ((eip<0) || (eip>1*1024*1024))
|
|
||||||
eip=-666;
|
|
||||||
return eip;
|
return eip;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VMEngine::getCS()
|
uint16_t VMEngine::getCS()
|
||||||
{
|
{
|
||||||
int cs=-666;
|
int cs=0;
|
||||||
err = uc_reg_read(uc, UC_X86_REG_CS, &cs);
|
err = uc_reg_read(uc, UC_X86_REG_CS, &cs);
|
||||||
if (err != UC_ERR_OK)
|
if (err != UC_ERR_OK)
|
||||||
log->append("Impossible de récupérer le registre: CS");
|
log->append("Impossible de récupérer le registre: CS");
|
||||||
if (cs<0)
|
|
||||||
cs=0;
|
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
int VMEngine::getDS()
|
uint16_t VMEngine::getDS()
|
||||||
{
|
{
|
||||||
int ds=-666;
|
int ds=9;
|
||||||
err = uc_reg_read(uc, UC_X86_REG_DS, &ds);
|
err = uc_reg_read(uc, UC_X86_REG_DS, &ds);
|
||||||
if (err != UC_ERR_OK)
|
if (err != UC_ERR_OK)
|
||||||
log->append("Impossible de récupérer le registre: DS");
|
log->append("Impossible de récupérer le registre: DS");
|
||||||
if (ds<0)
|
|
||||||
ds=0;
|
|
||||||
return ds;
|
return ds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -844,9 +870,9 @@ void VMEngine::SetRegs(State *init)
|
||||||
log->append(out.str());
|
log->append(out.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VMEngine::Run(State *init,uint64_t timeout)
|
void VMEngine::Run(uint32_t end,uint64_t timeout)
|
||||||
{
|
{
|
||||||
err=uc_emu_start(uc, init->dump.regs.eip, 0xFFFF, timeout, 0);
|
err=uc_emu_start(uc, this->getCurrent(), end, timeout, 0);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log->append("Erreur lors de l'exécution de la machine virtuelle");
|
log->append("Erreur lors de l'exécution de la machine virtuelle");
|
||||||
|
@ -1114,6 +1140,7 @@ void Menu::end()
|
||||||
void Menu::compile()
|
void Menu::compile()
|
||||||
{
|
{
|
||||||
vm.Configure(&scenario.levels[scenar.getselected()].init,edit.get());
|
vm.Configure(&scenario.levels[scenar.getselected()].init,edit.get());
|
||||||
|
showInstr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::about()
|
void Menu::about()
|
||||||
|
@ -1137,19 +1164,23 @@ void Menu::about()
|
||||||
AdjustWindows();
|
AdjustWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::showInstr()
|
||||||
|
{
|
||||||
|
debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3));
|
||||||
|
debug.setmark(vm.getLine());
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::refresh()
|
void Menu::refresh()
|
||||||
{
|
{
|
||||||
if (!vm.isInitialized())
|
if (!vm.isInitialized())
|
||||||
{
|
{
|
||||||
regs.set("En attente d'initialisation...");
|
regs.set("En attente d'initialisation...");
|
||||||
flags.set("Attente...");
|
flags.set("Attente...");
|
||||||
//debug.setindex(-666);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
regs.set(vm.getRegs());
|
regs.set(vm.getRegs());
|
||||||
flags.set(vm.getFlags());
|
flags.set(vm.getFlags());
|
||||||
//debug.setindex(vm.getEIP(code));
|
|
||||||
}
|
}
|
||||||
if (!vm.isExecuted())
|
if (!vm.isExecuted())
|
||||||
{
|
{
|
||||||
|
@ -1158,7 +1189,6 @@ void Menu::refresh()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
finalcut::FApplication::setDefaultTheme();
|
finalcut::FApplication::setDefaultTheme();
|
||||||
//debug.set(vm.getInstr(vm.getCS()*16+vm.getEIP(),debug.getsize()));
|
|
||||||
}
|
}
|
||||||
auto root_widget = getRootWidget();
|
auto root_widget = getRootWidget();
|
||||||
root_widget->resetColors();
|
root_widget->resetColors();
|
||||||
|
@ -1181,17 +1211,46 @@ void Menu::exec()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vm.Run(&scenario.levels[scenar.getselected()].init,0);
|
vm.Run(0xFFFF,0);
|
||||||
|
showInstr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::trace()
|
void Menu::trace()
|
||||||
{
|
{
|
||||||
exec();
|
if (!vm.isInitialized())
|
||||||
|
compile();
|
||||||
|
if (vm.verify()==1)
|
||||||
|
{
|
||||||
|
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (vm.verify()==2)
|
||||||
|
{
|
||||||
|
finalcut::FMessageBox::error(this, "Une erreur de chargement a eu lieu vers la VM !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vm.Run(vm.getNextInstr(),0);
|
||||||
|
showInstr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::step()
|
void Menu::step()
|
||||||
{
|
{
|
||||||
exec();
|
if (!vm.isInitialized())
|
||||||
|
compile();
|
||||||
|
if (vm.verify()==1)
|
||||||
|
{
|
||||||
|
finalcut::FMessageBox::error(this, "Vous devez compiler le source d'abord !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (vm.verify()==2)
|
||||||
|
{
|
||||||
|
finalcut::FMessageBox::error(this, "Une erreur de chargement a eu lieu vers la VM !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vm.Run(vm.getNextInstr(),0);
|
||||||
|
showInstr();
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
30
ia86.h
30
ia86.h
|
@ -140,7 +140,7 @@ struct Code
|
||||||
struct Unasm
|
struct Unasm
|
||||||
{
|
{
|
||||||
std::vector<std::array<std::string, 5>> src;
|
std::vector<std::array<std::string, 5>> src;
|
||||||
std::vector<std::array<int, 2>> pos;
|
std::vector<uint32_t> pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScenarioWindow final : public finalcut::FDialog
|
class ScenarioWindow final : public finalcut::FDialog
|
||||||
|
@ -246,7 +246,7 @@ class Desassembler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Desassembler(TextWindow *log);
|
Desassembler(TextWindow *log);
|
||||||
Unasm *Desassemble(uint8_t *content, uint32_t address,uint32_t size);
|
void Desassemble(uint8_t *content, uint32_t address,uint32_t size, Unasm *unasm);
|
||||||
private:
|
private:
|
||||||
csh handle;
|
csh handle;
|
||||||
cs_insn *insn;
|
cs_insn *insn;
|
||||||
|
@ -280,35 +280,38 @@ class VMEngine
|
||||||
void Configure(State *init, std::string code);
|
void Configure(State *init, std::string code);
|
||||||
void Halt();
|
void Halt();
|
||||||
void Unconfigure();
|
void Unconfigure();
|
||||||
void Run(State *init,uint64_t timeout);
|
uint32_t getNextInstr();
|
||||||
|
uint32_t getCurrent();
|
||||||
|
void Run(uint32_t end,uint64_t timeout);
|
||||||
std::string getFlags();
|
std::string getFlags();
|
||||||
std::string getRegs();
|
std::string getRegs();
|
||||||
std::vector<std::array<std::string, 5>> getInstr(int address,int size);
|
std::vector<std::array<std::string, 5>> getInstr(int segment, int address,int size);
|
||||||
void SetMem(Code *code);
|
void SetMem(Code *code);
|
||||||
void SetRegs(State *init);
|
void SetRegs(State *init);
|
||||||
int verify();
|
int verify();
|
||||||
bool isExecuted();
|
bool isExecuted();
|
||||||
bool isInitialized();
|
bool isInitialized();
|
||||||
void setRights(int rights);
|
void setRights(int rights);
|
||||||
int getEIP();
|
int getLine();
|
||||||
int getCS();
|
uint32_t getEIP();
|
||||||
int getDS();
|
uint16_t getCS();
|
||||||
|
uint16_t getDS();
|
||||||
private:
|
private:
|
||||||
TextWindow *log;
|
|
||||||
Assembler asmer{log};
|
|
||||||
Desassembler unasmer{log};
|
|
||||||
std::vector<Code> mcode;
|
|
||||||
int rights;
|
int rights;
|
||||||
uint8_t *getRamRaw(uint32_t address, uint32_t size);
|
|
||||||
void Init();
|
void Init();
|
||||||
void Close();
|
void Close();
|
||||||
bool executed=false;
|
bool executed=false;
|
||||||
bool initialized=false;
|
bool initialized=false;
|
||||||
uc_engine *uc;
|
uc_engine *uc;
|
||||||
uc_err err;
|
uc_err err;
|
||||||
int alladdress,alladdress_old;
|
int bufferaddress=-555;
|
||||||
|
int address_old;
|
||||||
uint8_t *code;
|
uint8_t *code;
|
||||||
uLong crc,crc_old;
|
uLong crc,crc_old;
|
||||||
|
std::vector<Code> mcode;
|
||||||
|
TextWindow *log;
|
||||||
|
Assembler asmer{log};
|
||||||
|
Desassembler unasmer{log};
|
||||||
};
|
};
|
||||||
|
|
||||||
class Menu final : public finalcut::FDialog
|
class Menu final : public finalcut::FDialog
|
||||||
|
@ -336,6 +339,7 @@ class Menu final : public finalcut::FDialog
|
||||||
void initCore();
|
void initCore();
|
||||||
void compile();
|
void compile();
|
||||||
void end();
|
void end();
|
||||||
|
void showInstr();
|
||||||
void exec();
|
void exec();
|
||||||
void trace();
|
void trace();
|
||||||
void step();
|
void step();
|
||||||
|
|
Loading…
Reference in New Issue