Scanning of data segments for dlls/shared objects produces false positives.
I noticed some false positives happening when finding code addresses in the data segment of shared objects. The code below is responsible.
IRDB code only does this type of scanning for non-shared objects. Shared objects rely on either a runtime relocation or a PC-relative addressing mode for correctness.
void STARS_IDA_Program_t::FindCodeAddressesTaken(SMPProgram *CurrProg) {
STARS_ea_t RecentAddr = STARS_BADADDR;
bool ISA64 = (4 < global_STARS_program->GetSTARS_ISA_Bytewidth());
#if STARS_SEARCHFOR_32BITCODEADDR_IN_64BITDATA
bool Need64BitCodeAddresses = ISA64 && (0xffffffff < HighestCodeAddress);
bool Need32BitCodeAddresses = (0xffffffff >= LowestCodeAddress);
#else
bool Need64BitCodeAddresses = ISA64;
bool Need32BitCodeAddresses = !ISA64;
#endif
bool success;
uint32_t Value32;
uint64_t Value64;
STARS_ea_t AlignmentMask = STARS_CODEADDR_ALIGNMENT - 1;
for (STARS_Segment_t *seg = SMP_get_first_seg(); NULL != seg; seg = SMP_get_next_seg(RecentAddr)) {
STARS_ea_t ea = seg->get_startEA();
RecentAddr = ea;
bool ReadOnlyFlag = ((seg->IsReadableSegment()) && (!(seg->IsWriteableSegment())));
bool DataSegment = ((seg->IsDataSegment()) || (seg->IsCommonSegment()));
#if 0
if (ReadOnlyFlag && DataSegment) {
#else
if (DataSegment) {
#endif
// Loop through each of the segments we are interested in,
// examining all data objects (effective addresses).
// Make sure we start on a multiple of 4 bytes
if (0 != (ea & AlignmentMask)) {
SMP_msg("WARNING: Data segment unaligned: begins at %llx\n", (unsigned long long) ea);
ea -= (ea & AlignmentMask); // zero out lower bits
ea += STARS_CODEADDR_ALIGNMENT; // Get back inside data segment
}
STARS_ea_t EndEA = seg->get_endEA();
while (ea < EndEA) {
if (Need32BitCodeAddresses) {
success = seg->GetReadOnlyMem32BitValue(ea, Value32);
if (success && (STARS_MIN_CODEADDR <= Value32) && IsAddressInCodeRange((STARS_ea_t) Value32)) {
this->CodeAddressesTaken.insert((STARS_ea_t) Value32);
if (!ReadOnlyFlag) {
SMP_msg("INFO: Found 32-bit code addr %llx at writeable data addr %llx\n", (uint64_t) Value32, (uint64_t) ea);
}
bool NewTarget = CurrProg->InsertDataToCodeXref((STARS_ea_t) Value32);
if (NewTarget)
global_STARS_program->PrintDataToCodeXref((STARS_ea_t) ea, (STARS_ea_t) Value32, 0);
}
}
if (Need64BitCodeAddresses) {
success = seg->GetReadOnlyMem64BitValue(ea, Value64);
if (success && (STARS_MIN_CODEADDR <= Value64) && IsAddressInCodeRange((STARS_ea_t)Value64)) {
this->CodeAddressesTaken.insert((STARS_ea_t) Value64);
if (!ReadOnlyFlag) {
SMP_msg("INFO: Found 64-bit code addr %llx at writeable data addr %llx\n", Value64, (uint64_t)ea);
}
bool NewTarget = CurrProg->InsertDataToCodeXref((STARS_ea_t) Value64);
if (NewTarget)
global_STARS_program->PrintDataToCodeXref((STARS_ea_t) ea, (STARS_ea_t) Value64, 0);
}
}
ea += STARS_CODEADDR_ALIGNMENT; // even looking for 64-bit addresses, start on every 4-byte aligned address
}
} // end if read-only data segment
} // end for all segments
return;
} // STARS_IDA_Program_t::FindCodeAddressesTaken()