diff --git a/include/BinaryImage.h b/include/BinaryImage.h index 18872a5..db284dd 100644 --- a/include/BinaryImage.h +++ b/include/BinaryImage.h @@ -3,9 +3,9 @@ #include struct PROG /* Loaded program image parameters */ { - int16_t initCS=0; - int16_t initIP=0; /* These are initial load values */ - int16_t initSS=0; /* Probably not of great interest */ + uint16_t initCS=0; + uint16_t initIP=0; /* These are initial load values */ + uint16_t initSS=0; /* Probably not of great interest */ uint16_t initSP=0; bool fCOM=false; /* Flag set if COM program (else EXE)*/ int cReloc=0; /* No. of relocation table entries */ diff --git a/include/state.h b/include/state.h index 254f267..cbf8f9b 100644 --- a/include/state.h +++ b/include/state.h @@ -11,7 +11,7 @@ struct STATE { uint32_t IP; /* Offset into Image */ - int16_t r[INDEX_BX_SI]; /* Value of segs and AX */ + uint16_t r[INDEX_BX_SI]; /* Value of segs and AX */ bool f[INDEX_BX_SI]; /* True if r[.] has a value */ struct { /* For case stmt indexed reg */ diff --git a/src/DccFrontend.cpp b/src/DccFrontend.cpp index 2e7d462..d9bfc1d 100644 --- a/src/DccFrontend.cpp +++ b/src/DccFrontend.cpp @@ -228,8 +228,7 @@ struct ComLoader : public DosLoader { prog.initSP = 0xFFFE; prog.cReloc = 0; - prepareImage(prog,cb,fp); - + prepareImage(prog, cb, fp); /* Set up memory map */ cb = (prog.cbImage + 3) / 4; @@ -238,6 +237,70 @@ struct ComLoader : public DosLoader { return true; } }; +struct RomLoader { + bool canLoad(QFile &fp) { + fp.seek(0xFFF0); + uint8_t sig[1]; + if(fp.read((char *)sig,1) == 1) + { + return (sig[0] == 0xEA); + } + return false; + } + bool load(PROG &prog,QFile &fp) { + printf("Loading ROM...\n"); + fp.seek(0); + /* ROM file + * In this case the load module size is just the file length + */ + auto cb = fp.size(); + + fp.seek(cb - 0x10); + uint8_t buf[5]; + printf("Going to get CS/IP...\n"); + if(fp.read((char *)buf, 5) != 5) + { + return false; + } + + fp.seek(0); + + /* ROM File, Hard to say where it is suppose to start, so try to trust the + */ + prog.initIP = (buf[2] << 8) | buf[1]; + //prog.initCS = 0; + prog.initCS = (buf[4] << 8) | buf[3]; + + prog.initSS = 0; + prog.initSP = 0xFFFE; + + prog.cReloc = 0; + + prepareImage(prog, cb, fp); + + /* Set up memory map */ + cb = (prog.cbImage + 3) / 4; + prog.map = (uint8_t *)malloc(cb); + memset(prog.map, BM_UNKNOWN, (size_t)cb); + return true; + } + +protected: + void prepareImage(PROG &prog, size_t sz, QFile &fp) + { + int32_t start = 0x100000 - sz; + /* Allocate a block of memory for the program. */ + prog.cbImage = 1 * 1024 * 1024; /* Allocate the whole 1MB memory */ + //prog.cbImage = 64 * 1024; /* Allocate the whole 1MB memory */ + prog.Imagez = new uint8_t [prog.cbImage]; + + if (fp.read((char *)prog.Imagez + start, sz) != sz) + //if (fp.read((char *)prog.Imagez, sz) != sz) + { + fatalError(CANNOT_READ, fp.fileName().toLocal8Bit().data()); + } + } +}; struct ExeLoader : public DosLoader { bool canLoad(QFile &fp) { if(fp.size()IP,16).toUpper(); + qDebug() << "Parsing proc" << name << "at" << QString::number(pstate->IP,16).toUpper(); } while (not done ) @@ -145,6 +145,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) break; LLInst *ll = _Icode.ll(); pstate->IP += (uint32_t)ll->numBytes; + setBits(BM_CODE, ll->label, (uint32_t)ll->numBytes); process_operands(_Icode,pstate); @@ -180,6 +181,7 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) case iJCXZ: { STATE StCopy; + uint32_t lastIp = pstate->IP - 2; int ip = Icode.size()-1; /* Index of this jump */ ICODE &prev(*(++Icode.rbegin())); /* Previous icode */ bool fBranch = false; @@ -200,6 +202,13 @@ void Function::FollowCtrl(CALL_GRAPH * pcallGraph, STATE *pstate) } StCopy = *pstate; + if (pstate->IP > 0x100000) + { + printf("Something wrong with IP...\n"); + } + + printf("From %X condJump to %X\n", lastIp, pstate->IP); + /* Straight line code */ this->FollowCtrl (pcallGraph, &StCopy); // recurrent ? @@ -546,6 +555,7 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra PROG &prog(Project::get()->prog); static uint8_t i2r[4] = {rSI, rDI, rBP, rBX}; ICODE _Icode; + uint32_t lastIp = pstate->IP - 1; uint32_t cs, offTable, endTable; uint32_t i, k, seg, target; @@ -553,7 +563,33 @@ bool Function::process_JMP (ICODE & pIcode, STATE *pstate, CALL_GRAPH * pcallGra { if (pIcode.ll()->getOpcode() == iJMPF) pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); - pstate->IP = pIcode.ll()->src().getImm2(); + + pstate->IP = pIcode.ll()->src().getImm2(); + + if (pstate->IP == 0) + { + printf("debug...\n"); + } + + /* Need to use CS! */ + if ((pIcode.ll()->getOpcode() != iJMPF) && (pIcode.ll()->getOpcode() != iJMP)) + { + printf("debug\n"); + } + if (pstate->IP > 0x10000) + { + printf("debug\n"); + } + + pstate->IP += pstate->r[rCS] << 4; + + if (pstate->IP > 0x100000) + { + printf("Something wrong with IP (was %x)...\n", lastIp); + } + + printf("From %X JMP(F) to %X\n", lastIp, pstate->IP); + int64_t i = pIcode.ll()->src().getImm2(); if (i < 0) { @@ -677,6 +713,7 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta PROG &prog(Project::get()->prog); ICODE &last_insn(Icode.back()); STATE localState; /* Local copy of the machine state */ + uint32_t lastIp = pstate->IP - 2; uint32_t off; /* For Indirect Calls, find the function address */ bool indirect = false; @@ -770,10 +807,21 @@ bool Function::process_CALL(ICODE & pIcode, CALL_GRAPH * pcallGraph, STATE *psta pstate->IP = pIcode.ll()->src().getImm2(); if (pIcode.ll()->getOpcode() == iCALLF) pstate->setState( rCS, LH(prog.image() + pIcode.ll()->label + 3)); + + /* Need to use CS! */ + pstate->IP += pstate->r[rCS] << 4; + x.state = *pstate; /* Insert new procedure in call graph */ - pcallGraph->insertCallGraph (this, iter); +- pcallGraph->insertCallGraph (this, iter); + + if (pstate->IP > 0x100000) + { + printf("Something wrong with IP (was %x)...\n", lastIp); + } + + printf("From %X CALL to %X\n", lastIp, pstate->IP); /* Process new procedure */ x.FollowCtrl (pcallGraph, pstate);