Lancement de la version de production sans Docker, lancement avec Xterm...ajout de la visualisation de la pile
This commit is contained in:
parent
c65dedacf0
commit
74be98f091
|
@ -1,2 +1,4 @@
|
||||||
ia86
|
ia86
|
||||||
*.old
|
*.old
|
||||||
|
lib*
|
||||||
|
a.out
|
||||||
|
|
26
Makefile
26
Makefile
|
@ -1,10 +1,10 @@
|
||||||
CC=g++ -O2
|
CC=g++ -O2
|
||||||
LFLAGS=-lfinal -lkeystone -lstdc++ -lm -lcapstone -lunicorn -lz
|
LFLAGS=-lfinal -lkeystone -lstdc++ -lm -lcapstone -lunicorn -lz
|
||||||
OPTIONS=-std=c++17
|
OPTIONS=-std=c++17
|
||||||
DOCKER=docker run -it -e COLUMNS="$$(tput cols)" -e LINES="$$(tput lines)" --name maker --rm -v $$(pwd):/data maker
|
DOCKER=docker run --name maker --rm -v $$(pwd):/data maker
|
||||||
XTERM=terminator -f -e
|
START=./start.sh
|
||||||
|
|
||||||
all: dockerfile files run
|
all: dockerfile files copy run
|
||||||
|
|
||||||
clean: dockerclean
|
clean: dockerclean
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ ia86: ./ia86.cpp
|
||||||
$(DOCKER) $(CC) $(OPTIONS) -o $@ $^ $(LFLAGS)
|
$(DOCKER) $(CC) $(OPTIONS) -o $@ $^ $(LFLAGS)
|
||||||
|
|
||||||
rerun:
|
rerun:
|
||||||
$(XTERM) '$(DOCKER) bash -c "sleep 0.4;./ia86"'
|
$(START)
|
||||||
|
|
||||||
run: clear delete files rerun
|
run: clear delete files rerun
|
||||||
|
|
||||||
|
@ -36,3 +36,21 @@ stop:
|
||||||
|
|
||||||
delete:
|
delete:
|
||||||
rm -rf ./ia86
|
rm -rf ./ia86
|
||||||
|
|
||||||
|
copy: libcapstone.so.4 libunicorn.so.1 libfinal.so.0.7.2 libkeystone.so.0 libc.musl-x86_64.so.1
|
||||||
|
|
||||||
|
libcapstone.so.4:
|
||||||
|
${DOCKER} cp /usr/lib/libcapstone.so.4 /data/libcapstone.so.4
|
||||||
|
|
||||||
|
libunicorn.so.1:
|
||||||
|
${DOCKER} cp /usr/lib/libunicorn.so.1 /data/libunicorn.so.1
|
||||||
|
|
||||||
|
libfinal.so.0.7.2:
|
||||||
|
${DOCKER} cp /usr/lib/libfinal.so.0.7.2 /data/libfinal.so.0.7.2
|
||||||
|
ln -s ./libfinal.so.0.7.2 ./libfinal.so.0
|
||||||
|
|
||||||
|
libkeystone.so.0:
|
||||||
|
${DOCKER} cp /usr/lib64/libkeystone.so.0 /data/libkeystone.so.0
|
||||||
|
|
||||||
|
libc.musl-x86_64.so.1:
|
||||||
|
${DOCKER} cp /lib/libc.musl-x86_64.so.1 /data/libc.musl-x86_64.so.1
|
||||||
|
|
77
ia86.cpp
77
ia86.cpp
|
@ -531,6 +531,32 @@ std::string VMEngine::getFlags()
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
std::string VMEngine::getRegs()
|
std::string VMEngine::getRegs()
|
||||||
{
|
{
|
||||||
int regsi836[] = {
|
int regsi836[] = {
|
||||||
|
@ -835,7 +861,7 @@ static void hook_code (uc_engine *uc, uint64_t address, uint32_t size, void *use
|
||||||
for(std::array<uint32_t,2> bp: breakpoints)
|
for(std::array<uint32_t,2> bp: breakpoints)
|
||||||
if (address==bp[0]*16+bp[1])
|
if (address==bp[0]*16+bp[1])
|
||||||
breakp=true;
|
breakp=true;
|
||||||
if (!breakp && (!step || (hadcall>0 && !call))) return;
|
if ((!step && !breakp) || (hadcall>0 && !call && !breakp)) return;
|
||||||
uc_emu_stop(uc);
|
uc_emu_stop(uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,7 +975,7 @@ uint32_t VMEngine::getESI()
|
||||||
|
|
||||||
uint32_t VMEngine::getEDI()
|
uint32_t VMEngine::getEDI()
|
||||||
{
|
{
|
||||||
int edi;
|
uint32_t edi;
|
||||||
err = uc_reg_read(uc, UC_X86_REG_EDI, &edi);
|
err = uc_reg_read(uc, UC_X86_REG_EDI, &edi);
|
||||||
if (err != UC_ERR_OK)
|
if (err != UC_ERR_OK)
|
||||||
throw Error("VM IA86 - voir EDI................................[ERREUR]");
|
throw Error("VM IA86 - voir EDI................................[ERREUR]");
|
||||||
|
@ -958,16 +984,25 @@ uint32_t VMEngine::getEDI()
|
||||||
|
|
||||||
uint32_t VMEngine::getESP()
|
uint32_t VMEngine::getESP()
|
||||||
{
|
{
|
||||||
int esp;
|
uint32_t esp;
|
||||||
err = uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
err = uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
||||||
if (err != UC_ERR_OK)
|
if (err != UC_ERR_OK)
|
||||||
throw Error("VM IA86 - voir ESP................................[ERREUR]");
|
throw Error("VM IA86 - voir ESP................................[ERREUR]");
|
||||||
return esp;
|
return esp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t VMEngine::getEIP()
|
uint32_t VMEngine::getEIP()
|
||||||
{
|
{
|
||||||
int eip;
|
uint32_t eip;
|
||||||
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)
|
||||||
throw Error("VM IA86 - voir EIP................................[ERREUR]");
|
throw Error("VM IA86 - voir EIP................................[ERREUR]");
|
||||||
|
@ -976,7 +1011,7 @@ uint32_t VMEngine::getEIP()
|
||||||
|
|
||||||
uint16_t VMEngine::getCS()
|
uint16_t VMEngine::getCS()
|
||||||
{
|
{
|
||||||
int cs;
|
uint16_t cs;
|
||||||
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)
|
||||||
throw Error("VM IA86 - voir CS.................................[ERREUR]");
|
throw Error("VM IA86 - voir CS.................................[ERREUR]");
|
||||||
|
@ -985,7 +1020,7 @@ uint16_t VMEngine::getCS()
|
||||||
|
|
||||||
uint16_t VMEngine::getDS()
|
uint16_t VMEngine::getDS()
|
||||||
{
|
{
|
||||||
int ds;
|
uint16_t ds;
|
||||||
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)
|
||||||
throw Error("VM IA86 - voir DS.................................[ERREUR]");
|
throw Error("VM IA86 - voir DS.................................[ERREUR]");
|
||||||
|
@ -994,7 +1029,7 @@ uint16_t VMEngine::getDS()
|
||||||
|
|
||||||
uint16_t VMEngine::getES()
|
uint16_t VMEngine::getES()
|
||||||
{
|
{
|
||||||
int es;
|
uint16_t es;
|
||||||
err = uc_reg_read(uc, UC_X86_REG_ES, &es);
|
err = uc_reg_read(uc, UC_X86_REG_ES, &es);
|
||||||
if (err != UC_ERR_OK)
|
if (err != UC_ERR_OK)
|
||||||
throw Error("VM IA86 - voir ES.................................[ERREUR]");
|
throw Error("VM IA86 - voir ES.................................[ERREUR]");
|
||||||
|
@ -1003,7 +1038,7 @@ uint16_t VMEngine::getES()
|
||||||
|
|
||||||
uint16_t VMEngine::getSS()
|
uint16_t VMEngine::getSS()
|
||||||
{
|
{
|
||||||
int ss;
|
uint16_t ss;
|
||||||
err = uc_reg_read(uc, UC_X86_REG_SS, &ss);
|
err = uc_reg_read(uc, UC_X86_REG_SS, &ss);
|
||||||
if (err != UC_ERR_OK)
|
if (err != UC_ERR_OK)
|
||||||
throw Error("VM IA86 - voir SS.................................[ERREUR]");
|
throw Error("VM IA86 - voir SS.................................[ERREUR]");
|
||||||
|
@ -1177,6 +1212,7 @@ void Menu::initWindows()
|
||||||
flags.setText ("Drapeaux");
|
flags.setText ("Drapeaux");
|
||||||
stack.setText ("Pile");
|
stack.setText ("Pile");
|
||||||
mem.setText ("Mémoire");
|
mem.setText ("Mémoire");
|
||||||
|
mem.setResizeable();
|
||||||
tuto.setText ("Guide");
|
tuto.setText ("Guide");
|
||||||
tuto.setResizeable();
|
tuto.setResizeable();
|
||||||
tuto.show();
|
tuto.show();
|
||||||
|
@ -1379,7 +1415,7 @@ void Menu::initMenusCallBack()
|
||||||
this,
|
this,
|
||||||
&Menu::changesyntax
|
&Menu::changesyntax
|
||||||
);
|
);
|
||||||
Ds_00.addCallback
|
Ds_000.addCallback
|
||||||
(
|
(
|
||||||
"clicked",
|
"clicked",
|
||||||
this,
|
this,
|
||||||
|
@ -1409,6 +1445,12 @@ void Menu::initMenusCallBack()
|
||||||
this,
|
this,
|
||||||
&Menu::showInstr
|
&Menu::showInstr
|
||||||
);
|
);
|
||||||
|
Ss_FFF.addCallback
|
||||||
|
(
|
||||||
|
"clicked",
|
||||||
|
this,
|
||||||
|
&Menu::showInstr
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::initMisc()
|
void Menu::initMisc()
|
||||||
|
@ -1435,7 +1477,7 @@ void Menu::initLayout()
|
||||||
this->setLeftPadding(0);
|
this->setLeftPadding(0);
|
||||||
this->setRightPadding(0);
|
this->setRightPadding(0);
|
||||||
this->setBottomPadding(0);
|
this->setBottomPadding(0);
|
||||||
Ds_00.setChecked();
|
Ds_000.setChecked();
|
||||||
Log.setGeometry (FPoint{0, 0}, FSize{getWidth(), getHeight()},false);
|
Log.setGeometry (FPoint{0, 0}, FSize{getWidth(), getHeight()},false);
|
||||||
FDialog::initLayout();
|
FDialog::initLayout();
|
||||||
}
|
}
|
||||||
|
@ -1451,6 +1493,14 @@ void Menu::closeLevel()
|
||||||
AdjustWindows();
|
AdjustWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*void Menu::loadBios(std::string file)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::ifstream input(file, std::ios::binary );
|
||||||
|
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
void Menu::loadScenario(std::string file)
|
void Menu::loadScenario(std::string file)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1475,6 +1525,7 @@ void Menu::loadScenario(std::string file)
|
||||||
tolog("Application - charge scénarios....................[ERREUR]");
|
tolog("Application - charge scénarios....................[ERREUR]");
|
||||||
closeLevel();
|
closeLevel();
|
||||||
}
|
}
|
||||||
|
inFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::loadLevel(int alevel)
|
void Menu::loadLevel(int alevel)
|
||||||
|
@ -1545,7 +1596,7 @@ void Menu::showInstr()
|
||||||
debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3));
|
debug.set(vm.getInstr(vm.getCS(),vm.getEIP(),debug.getHeight()-3));
|
||||||
debug.setmark(vm.getLine());
|
debug.setmark(vm.getLine());
|
||||||
debug.setmultimark(vm.getBreapoints());
|
debug.setmultimark(vm.getBreapoints());
|
||||||
if (Ds_00.isChecked())
|
if (Ds_000.isChecked())
|
||||||
mem.set(vm.getRam(vm.getDS(), 0x000000000, mem.getHeight(),mem.getWidth()));
|
mem.set(vm.getRam(vm.getDS(), 0x000000000, mem.getHeight(),mem.getWidth()));
|
||||||
else if (Ds_esi.isChecked())
|
else if (Ds_esi.isChecked())
|
||||||
mem.set(vm.getRam(vm.getDS(), vm.getESI(), mem.getHeight(),mem.getWidth()));
|
mem.set(vm.getRam(vm.getDS(), vm.getESI(), mem.getHeight(),mem.getWidth()));
|
||||||
|
@ -1555,6 +1606,8 @@ void Menu::showInstr()
|
||||||
mem.set(vm.getRam(vm.getCS(), vm.getEIP(), mem.getHeight(),mem.getWidth()));
|
mem.set(vm.getRam(vm.getCS(), vm.getEIP(), mem.getHeight(),mem.getWidth()));
|
||||||
else if (Ss_esp.isChecked())
|
else if (Ss_esp.isChecked())
|
||||||
mem.set(vm.getRam(vm.getSS(), vm.getESP(), mem.getHeight(),mem.getWidth()));
|
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)
|
catch(exception const& e)
|
||||||
|
@ -1580,11 +1633,13 @@ void Menu::refresh()
|
||||||
{
|
{
|
||||||
regs.set(vm.getRegs());
|
regs.set(vm.getRegs());
|
||||||
flags.set(vm.getFlags());
|
flags.set(vm.getFlags());
|
||||||
|
stack.set(vm.getStack());
|
||||||
}
|
}
|
||||||
catch(exception const& e)
|
catch(exception const& e)
|
||||||
{
|
{
|
||||||
tolog(e.what());
|
tolog(e.what());
|
||||||
vm.Halt();
|
vm.Halt();
|
||||||
|
vm.Unconfigure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!vm.isExecuted())
|
if (!vm.isExecuted())
|
||||||
|
|
5
ia86.h
5
ia86.h
|
@ -312,6 +312,7 @@ class VMEngine
|
||||||
void Run(bool astep, bool acall, uint64_t timeout);
|
void Run(bool astep, bool acall, uint64_t timeout);
|
||||||
std::string getFlags();
|
std::string getFlags();
|
||||||
std::string getRegs();
|
std::string getRegs();
|
||||||
|
std::string getStack();
|
||||||
std::vector<std::array<std::string, 4>> getInstr(int segment, int address,int size);
|
std::vector<std::array<std::string, 4>> getInstr(int segment, int address,int size);
|
||||||
void SetMem(Code *code);
|
void SetMem(Code *code);
|
||||||
void SetRegs(State *init);
|
void SetRegs(State *init);
|
||||||
|
@ -329,6 +330,7 @@ class VMEngine
|
||||||
uint32_t getESI();
|
uint32_t getESI();
|
||||||
uint32_t getEDI();
|
uint32_t getEDI();
|
||||||
uint32_t getESP();
|
uint32_t getESP();
|
||||||
|
uint32_t getEBP();
|
||||||
uint16_t getCS();
|
uint16_t getCS();
|
||||||
uint16_t getDS();
|
uint16_t getDS();
|
||||||
uint16_t getES();
|
uint16_t getES();
|
||||||
|
@ -400,11 +402,12 @@ class Menu final : public finalcut::FDialog
|
||||||
finalcut::FMenuItem Quit{"&Quitter", &Game};
|
finalcut::FMenuItem Quit{"&Quitter", &Game};
|
||||||
finalcut::FMenu Options{"&Options", &Menubar};
|
finalcut::FMenu Options{"&Options", &Menubar};
|
||||||
finalcut::FMenu Memory{"&Visualisateur Mémoire", &Options};
|
finalcut::FMenu Memory{"&Visualisateur Mémoire", &Options};
|
||||||
finalcut::FRadioMenuItem Ds_00{"DS:0x00000000", &Memory};
|
finalcut::FRadioMenuItem Ds_000{"DS:0000", &Memory};
|
||||||
finalcut::FRadioMenuItem Ds_esi{"DS:ESI", &Memory};
|
finalcut::FRadioMenuItem Ds_esi{"DS:ESI", &Memory};
|
||||||
finalcut::FRadioMenuItem Es_edi{"ES:EDI", &Memory};
|
finalcut::FRadioMenuItem Es_edi{"ES:EDI", &Memory};
|
||||||
finalcut::FRadioMenuItem Cs_eip{"CS:EIP", &Memory};
|
finalcut::FRadioMenuItem Cs_eip{"CS:EIP", &Memory};
|
||||||
finalcut::FRadioMenuItem Ss_esp{"SS:ESP", &Memory};
|
finalcut::FRadioMenuItem Ss_esp{"SS:ESP", &Memory};
|
||||||
|
finalcut::FRadioMenuItem Ss_FFF{"SS:FFFF", &Memory};
|
||||||
finalcut::FRadioMenuItem Value{"Valeur...", &Memory};
|
finalcut::FRadioMenuItem Value{"Valeur...", &Memory};
|
||||||
finalcut::FMenu Code{"&Syntaxe", &Options};
|
finalcut::FMenu Code{"&Syntaxe", &Options};
|
||||||
finalcut::FCheckMenuItem AsmAtt{"Assembleur AT&T", &Code};
|
finalcut::FCheckMenuItem AsmAtt{"Assembleur AT&T", &Code};
|
||||||
|
|
|
@ -10,6 +10,16 @@
|
||||||
inc dx
|
inc dx
|
||||||
mov esi,0x44440234
|
mov esi,0x44440234
|
||||||
syscall
|
syscall
|
||||||
|
mov ax,0x9000
|
||||||
|
mov ss,ax
|
||||||
|
mov ax,0xFFFF
|
||||||
|
mov sp,ax
|
||||||
|
mov cx,10
|
||||||
|
go:
|
||||||
|
push cx
|
||||||
|
dec cx
|
||||||
|
cmp cx,0
|
||||||
|
jnz go
|
||||||
hlt
|
hlt
|
||||||
jmp 0x14D
|
jmp 0x14D
|
||||||
.org 0x8D
|
.org 0x8D
|
||||||
|
@ -57,7 +67,10 @@ mov es,ax
|
||||||
"niveau_titre" : "Suite",
|
"niveau_titre" : "Suite",
|
||||||
"niveau_description" : "Il faut connaitre...",
|
"niveau_description" : "Il faut connaitre...",
|
||||||
"niveau_tutoriel" : "Ceci vous...",
|
"niveau_tutoriel" : "Ceci vous...",
|
||||||
"niveau_code" : "mov ax,0x545
|
"niveau_code" : "mov ax,0x9000
|
||||||
|
mov ss,ax
|
||||||
|
mov ax,0xFFFF
|
||||||
|
mov sp,ax
|
||||||
_pour:
|
_pour:
|
||||||
lea si,[msg]
|
lea si,[msg]
|
||||||
call show
|
call show
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
X=$(xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f1)
|
||||||
|
Y=$(xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f2)
|
||||||
|
if [ ${X} -ge 1920 ]; then
|
||||||
|
SIZE=11
|
||||||
|
elif [ ${X} -ge 1680 ]; then
|
||||||
|
SIZE=10
|
||||||
|
elif [ ${X} -ge 1440 ]; then
|
||||||
|
SIZE=9
|
||||||
|
elif [ ${X} -ge 1368 ]; then
|
||||||
|
SIZE=8
|
||||||
|
elif [ ${X} -ge 1280 ]; then
|
||||||
|
SIZE=7
|
||||||
|
else
|
||||||
|
SIZE=6
|
||||||
|
fi
|
||||||
|
xterm -fullscreen -fa monaco -fs ${SIZE} -bg black -fg green -e bash -c "docker run -it -e COLUMNS=213 -e LINES=58 --name maker --rm -v $(pwd):/data maker ./ia86"
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
X=$(xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f1)
|
||||||
|
Y=$(xrandr --current | grep '*' | uniq | awk '{print $1}' | cut -d 'x' -f2)
|
||||||
|
if [ ${X} -ge 1920 ]; then
|
||||||
|
SIZE=11
|
||||||
|
elif [ ${X} -ge 1680 ]; then
|
||||||
|
SIZE=10
|
||||||
|
elif [ ${X} -ge 1440 ]; then
|
||||||
|
SIZE=9
|
||||||
|
elif [ ${X} -ge 1368 ]; then
|
||||||
|
SIZE=8
|
||||||
|
elif [ ${X} -ge 1280 ]; then
|
||||||
|
SIZE=7
|
||||||
|
else
|
||||||
|
SIZE=6
|
||||||
|
fi
|
||||||
|
xterm -fullscreen -fa monaco -fs ${SIZE} -bg black -fg green -e bash -c "docker run -it -e COLUMNS=213 -e LINES=58 --name maker --rm -v $(pwd):/data maker ./ia86"
|
Loading…
Reference in New Issue