void LoaderTest::testMicroDis2 () { // Now a special test: // 8048910: 0f be 00 movsbl (%eax),%eax // 8048913: 0f bf 00 movswl (%eax),%eax unsigned char movsbl[3] = {0x0f, 0xbe, 0x00}; unsigned char movswl[3] = {0x0f, 0xbf, 0x00}; int size = microX86Dis(movsbl); CPPUNIT_ASSERT_EQUAL(3, size); size = microX86Dis(movswl); CPPUNIT_ASSERT_EQUAL(3, size); }
void LoaderTest::testMicroDis1 () { std::ostringstream ost; int i; unsigned int n = sizeof(pent_hello_text); int totalSize = 0; void* p = pent_hello_text; i = 0; while (totalSize < (int)n) { int size = microX86Dis(p); if (size >= 0x40) { std::cout << "Not handled instruction at offset 0x" << std::hex << (ADDRESS)p - (ADDRESS)pent_hello_text << std::endl; CPPUNIT_ASSERT(size != 0x40); return; } int expected = lengths[i++]; if (expected != size) { std::cout << "At offset 0x" << std::hex << (ADDRESS)p - (ADDRESS)pent_hello_text << " (" << (int)*((unsigned char*)p) << " " << (int)*((unsigned char*)p+1) << " " << (int)*((unsigned char*)p+2) << " " << (int)*((unsigned char*)p+3) << " " << ") expected " << std::dec << expected << ", actual " << size << std::endl; CPPUNIT_ASSERT_EQUAL(expected, size); } p = (void*) ((char*)p + size); totalSize += size; } CPPUNIT_ASSERT_EQUAL((int)n, totalSize); }
ADDRESS DOS4GWBinaryFile::GetMainEntryPoint() { ADDRESS aMain = GetAddressByName ("main", true); if (aMain != NO_ADDRESS) return aMain; aMain = GetAddressByName ("__CMain", true); if (aMain != NO_ADDRESS) return aMain; // Search with this crude pattern: call, sub ebp, ebp, call __Cmain in the first 0x300 bytes // Start at program entry point unsigned p = LMMH(m_pLXHeader->eip); unsigned lim = p + 0x300; unsigned char op1, op2; ADDRESS addr; //unsigned lastOrdCall = 0; //TODO: identify the point of setting this variable bool gotSubEbp = false; // True if see sub ebp, ebp bool lastWasCall = false; // True if the last instruction was a call SectionInfo* si = GetSectionInfoByName("seg0"); // Assume the first section is text if (si == nullptr) si = GetSectionInfoByName(".text"); if (si == nullptr) si = GetSectionInfoByName("CODE"); assert(si); ADDRESS nativeOrigin = si->uNativeAddr; unsigned textSize = si->uSectionSize; if (textSize < 0x300) lim = p + textSize; while (p < lim) { op1 = *(unsigned char*)(p + base); op2 = *(unsigned char*)(p + base + 1); //std::cerr << std::hex << "At " << p << ", ops " << (unsigned)op1 << ", " << (unsigned)op2 << std::dec << "\n"; switch (op1) { case 0xE8: { // An ordinary call if (gotSubEbp) { // This is the call we want. Get the offset from the call instruction addr = nativeOrigin + p + 5 + LMMH(*(p + base + 1)); // std::cerr << "__CMain at " << std::hex << addr << "\n"; return addr; } //lastOrdCall = p; lastWasCall = true; break; } case 0x2B: // 0x2B 0xED is sub ebp,ebp if (op2 == 0xED && lastWasCall) gotSubEbp = true; lastWasCall = false; break; default: gotSubEbp = false; lastWasCall = false; break; case 0xEB: // Short relative jump if (op2 >= 0x80) // Branch backwards? break; // Yes, just ignore it // Otherwise, actually follow the branch. May have to modify this some time... p += op2+2; // +2 for the instruction itself, and op2 for the displacement continue; // Don't break, we have the new "pc" set already } int size = microX86Dis(p + base); if (size == 0x40) { fprintf(stderr, "Warning! Microdisassembler out of step at offset 0x%x\n", p); size = 1; } p += size; } return NO_ADDRESS; }