/*============================================================================== * FUNCTION: RtlTest::testIsCompare * OVERVIEW: Test the isCompare function *============================================================================*/ void RtlTest::testIsCompare () { BinaryFileFactory bff; BinaryFile *pBF = bff.Load(SWITCH_SPARC); CPPUNIT_ASSERT(pBF != 0); CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC); Prog* prog = new Prog; FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff); prog->setFrontEnd(pFE); // Decode second instruction: "sub %i0, 2, %o1" int iReg; Exp* eOperand = NULL; DecodeResult inst = pFE->decodeInstruction(0x10910); CPPUNIT_ASSERT(inst.rtl != NULL); CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == false); // Decode fifth instruction: "cmp %o1, 5" inst = pFE->decodeInstruction(0x1091c); CPPUNIT_ASSERT(inst.rtl != NULL); CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == true); CPPUNIT_ASSERT_EQUAL(9, iReg); std::string expected("5"); std::ostringstream ost1; eOperand->print(ost1); std::string actual(ost1.str()); CPPUNIT_ASSERT_EQUAL(expected, actual); pBF->UnLoad(); delete pBF; delete pFE; pBF = bff.Load(SWITCH_PENT); CPPUNIT_ASSERT(pBF != 0); CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_PENTIUM); pFE = new PentiumFrontEnd(pBF, prog, &bff); prog->setFrontEnd(pFE); // Decode fifth instruction: "cmp $0x5,%eax" inst = pFE->decodeInstruction(0x80488fb); CPPUNIT_ASSERT(inst.rtl != NULL); CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == true); CPPUNIT_ASSERT_EQUAL(24, iReg); std::ostringstream ost2; eOperand->print(ost2); actual = ost2.str(); CPPUNIT_ASSERT_EQUAL(expected, actual); // Decode instruction: "add $0x4,%esp" inst = pFE->decodeInstruction(0x804890c); CPPUNIT_ASSERT(inst.rtl != NULL); CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == false); pBF->UnLoad(); delete pFE; }
/*============================================================================== * FUNCTION: LoaderTest::testPentiumLoad * OVERVIEW: Test loading the pentium (Solaris) hello world program *============================================================================*/ void LoaderTest::testPentiumLoad () { std::ostringstream ost; // Load Pentium hello world BinaryFileFactory bff; BinaryFile* pBF = bff.Load(HELLO_PENTIUM); CPPUNIT_ASSERT(pBF != NULL); int n; SectionInfo* si; n = pBF->GetNumSections(); ost << "Number of sections = " << std::dec << n << "\r\n\t"; si = pBF->GetSectionInfo(1); ost << si->pSectionName << "\t"; si = pBF->GetSectionInfo(n-1); ost << si->pSectionName; pBF->UnLoad(); // Note: the string below needs to have embedded tabs. Edit with caution! // (And slightly different string to the sparc test, e.g. rel vs rela) std::string expected("Number of sections = 34\r\n\t" ".interp .strtab"); CPPUNIT_ASSERT_EQUAL(expected, ost.str()); bff.UnLoad(); }
/*============================================================================== * FUNCTION: LoaderTest::testPalmLoad * OVERVIEW: Test loading the Palm 68328 Starter.prc program *============================================================================*/ void LoaderTest::testPalmLoad () { std::ostringstream ost; // Load Palm Starter.prc BinaryFileFactory bff; BinaryFile* pBF = bff.Load(STARTER_PALM); CPPUNIT_ASSERT(pBF != NULL); int n; SectionInfo* si; n = pBF->GetNumSections(); ost << "Number of sections = " << std::dec << n << "\r\n"; for (int i=0; i < n; i++) { si = pBF->GetSectionInfo(i); ost << si->pSectionName << "\t"; } pBF->UnLoad(); // Note: the string below needs to have embedded tabs. Edit with caution! std::string expected("Number of sections = 8\r\n" "code1 MBAR1000 tFRM1000 Talt1001 " "data0 code0 tAIN1000 tver1000 "); CPPUNIT_ASSERT_EQUAL(expected, ost.str()); bff.UnLoad(); }
void CfgTest::testDominators () { BinaryFileFactory bff; BinaryFile *pBF = bff.Load(FRONTIER_PENTIUM); CPPUNIT_ASSERT(pBF != 0); Prog* prog = new Prog; FrontEnd *pFE = new PentiumFrontEnd(pBF, prog, &bff); Type::clearNamedTypes(); prog->setFrontEnd(pFE); pFE->decode(prog); bool gotMain; ADDRESS addr = pFE->getMainEntryPoint(gotMain); CPPUNIT_ASSERT (addr != NO_ADDRESS); UserProc* pProc = (UserProc*) prog->getProc(0); Cfg* cfg = pProc->getCFG(); DataFlow* df = pProc->getDataFlow(); df->dominators(cfg); // Find BB "5" (as per Appel, Figure 19.5). BB_IT it; PBB bb = cfg->getFirstBB(it); while (bb && bb->getLowAddr() != FRONTIER_FIVE) { bb = cfg->getNextBB(it); } CPPUNIT_ASSERT(bb); std::ostringstream expected, actual; //expected << std::hex << FRONTIER_FIVE << " " << FRONTIER_THIRTEEN << " " << FRONTIER_TWELVE << " " << // FRONTIER_FOUR << " "; expected << std::hex << FRONTIER_THIRTEEN << " " << FRONTIER_FOUR << " " << FRONTIER_TWELVE << " " << FRONTIER_FIVE << " "; int n5 = df->pbbToNode(bb); std::set<int>::iterator ii; std::set<int>& DFset = df->getDF(n5); for (ii=DFset.begin(); ii != DFset.end(); ii++) actual << std::hex << (unsigned)df->nodeToBB(*ii)->getLowAddr() << " "; CPPUNIT_ASSERT_EQUAL(expected.str(), actual.str()); pBF->UnLoad(); delete pFE; }
/*============================================================================== * FUNCTION: LoaderTest::testSparcLoad * OVERVIEW: Test loading the sparc hello world program *============================================================================*/ void LoaderTest::testSparcLoad () { std::ostringstream ost; // Load SPARC hello world BinaryFileFactory bff; BinaryFile* pBF = bff.Load(HELLO_SPARC); CPPUNIT_ASSERT(pBF != NULL); int n; SectionInfo* si; n = pBF->GetNumSections(); ost << "Number of sections = " << std::dec << n << "\r\n\t"; // Just use the first (real one) and last sections si = pBF->GetSectionInfo(1); ost << si->pSectionName << "\t"; si = pBF->GetSectionInfo(n-1); ost << si->pSectionName; pBF->UnLoad(); // Note: the string below needs to have embedded tabs. Edit with caution! std::string expected("Number of sections = 29\r\n\t" ".interp .stab.indexstr"); CPPUNIT_ASSERT_EQUAL(expected, ost.str()); bff.UnLoad(); }
/*============================================================================== * FUNCTION: LoaderTest::testHppaLoad * OVERVIEW: Test loading the sparc hello world program *============================================================================*/ void LoaderTest::testHppaLoad () { std::ostringstream ost; // Load HPPA hello world BinaryFileFactory bff; BinaryFile* pBF = bff.Load(HELLO_HPPA); CPPUNIT_ASSERT(pBF != NULL); int n; SectionInfo* si; n = pBF->GetNumSections(); ost << "Number of sections = " << std::dec << n << "\r\n"; for (int i=0; i < n; i++) { si = pBF->GetSectionInfo(i); ost << si->pSectionName << "\t"; } pBF->UnLoad(); // Note: the string below needs to have embedded tabs. Edit with caution! std::string expected("Number of sections = 4\r\n" "$HEADER$ $TEXT$ $DATA$ $BSS$ "); CPPUNIT_ASSERT_EQUAL(expected, ost.str()); bff.UnLoad(); }
int main(int argc, char* argv[]) { // Usage if (argc != 2) { printf ("Usage: %s <filename>\n", argv[0]); printf ("%s dumps the contents of the given executable file\n", argv[0]); return 1; } // Load the file BinaryFile *pbf = NULL; BinaryFileFactory bff; pbf = bff.Load(argv[1]); if (pbf == NULL) { return 2; } // Display program and section information // If the DisplayDetails() function has not been implemented // in the derived class (ElfBinaryFile in this case), then // uncomment the commented code below to display section information. pbf->DisplayDetails (argv[0]); // This is an alternative way of displaying binary-file information // by using individual sections. The above approach is more general. /* printf ("%d sections:\n", pbf->GetNumSections()); for (int i=0; i < pbf->GetNumSections(); i++) { SectionInfo* pSect = pbf->GetSectionInfo(i); printf(" Section %s at %X\n", pSect->pSectionName, pSect->uNativeAddr); } printf("\n"); */ // Display the code section in raw hexadecimal notation // Note: this is traditionally the ".text" section in Elf binaries. // In the case of Prc files (Palm), the code section is named "code0". for (int i=0; i < pbf->GetNumSections(); i++) { SectionInfo* pSect = pbf->GetSectionInfo(i); if (pSect->bCode) { printf(" Code section:\n"); ADDRESS a = pSect->uNativeAddr; unsigned char* p = (unsigned char*) pSect->uHostAddr; for (unsigned off = 0; off < pSect->uSectionSize; ) { printf("%04X: ", a); for (int j=0; (j < 16) && (off < pSect->uSectionSize); j++) { printf("%02X ", *p++); a++; off++; } printf("\n"); } printf("\n"); } } // Display the data section(s) in raw hexadecimal notation for (int i=0; i < pbf->GetNumSections(); i++) { SectionInfo* pSect = pbf->GetSectionInfo(i); if (pSect->bData) { printf(" Data section: %s\n", pSect->pSectionName); ADDRESS a = pSect->uNativeAddr; unsigned char* p = (unsigned char*) pSect->uHostAddr; for (unsigned off = 0; off < pSect->uSectionSize; ) { printf("%04X: ", a); for (int j=0; (j < 16) && (off < pSect->uSectionSize); j++) { printf("%02X ", *p++); a++; off++; } printf("\n"); } printf("\n"); } } pbf->UnLoad(); return 0; }
/*============================================================================== * FUNCTION: LoaderTest::testWinLoad * OVERVIEW: Test loading Windows programs *============================================================================*/ void LoaderTest::testWinLoad () { std::ostringstream ost; #if 0 /* FIXME: these tests should use non-proprietary programs */ // Load Windows program calc.exe BinaryFileFactory bff; BinaryFile* pBF = bff.Load(CALC_WINDOWS); CPPUNIT_ASSERT(pBF != NULL); int n; SectionInfo* si; n = pBF->GetNumSections(); ost << "Number of sections = " << std::dec << n << "\r\n"; for (int i=0; i < n; i++) { si = pBF->GetSectionInfo(i); ost << si->pSectionName << "\t"; } // Note: the string below needs to have embedded tabs. Edit with caution! std::string expected("Number of sections = 5\r\n" ".text .rdata .data .rsrc .reloc "); std::string actual(ost.str()); CPPUNIT_ASSERT_EQUAL(expected, actual); ADDRESS addr = pBF->GetMainEntryPoint(); CPPUNIT_ASSERT(addr != NO_ADDRESS); // Test symbol table (imports) const char* s = pBF->SymbolByAddress(0x1292060U); if (s == 0) actual = "<not found>"; else actual = std::string(s); expected = std::string("SetEvent"); CPPUNIT_ASSERT_EQUAL(expected, actual); ADDRESS a = pBF->GetAddressByName("SetEvent"); ADDRESS expectedAddr = 0x1292060; CPPUNIT_ASSERT_EQUAL(expectedAddr, a); pBF->UnLoad(); bff.UnLoad(); // Test loading the "new style" exes, as found in winXP etc pBF = bff.Load(CALC_WINXP); CPPUNIT_ASSERT(pBF != NULL); addr = pBF->GetMainEntryPoint(); std::ostringstream ost1; ost1 << std::hex << addr; actual = ost1.str(); expected = "1001f51"; CPPUNIT_ASSERT_EQUAL(expected, actual); pBF->UnLoad(); bff.UnLoad(); // Test loading the calc.exe found in Windows 2000 (more NT based) pBF = bff.Load(CALC_WIN2000); CPPUNIT_ASSERT(pBF != NULL); expected = "1001680"; addr = pBF->GetMainEntryPoint(); std::ostringstream ost2; ost2 << std::hex << addr; actual = ost2.str(); CPPUNIT_ASSERT_EQUAL(expected, actual); pBF->UnLoad(); bff.UnLoad(); // Test loading the lpq.exe program - console mode PE file pBF = bff.Load(LPQ_WINDOWS); CPPUNIT_ASSERT(pBF != NULL); addr = pBF->GetMainEntryPoint(); std::ostringstream ost3; ost3 << std::hex << addr; actual = ost3.str(); expected = "18c1000"; CPPUNIT_ASSERT_EQUAL(expected, actual); pBF->UnLoad(); bff.UnLoad(); #endif // Borland BinaryFileFactory bff; BinaryFile* pBF = bff.Load(SWITCH_BORLAND); CPPUNIT_ASSERT(pBF != NULL); ADDRESS addr = pBF->GetMainEntryPoint(); std::ostringstream ost4; ost4 << std::hex << addr; std::string actual(ost4.str()); std::string expected("401150"); CPPUNIT_ASSERT_EQUAL(expected, actual); pBF->UnLoad(); bff.UnLoad(); }