//***************************************************************************** // Return a pointer to a null terminated blob given an offset previously // handed out by Addblob or Findblob. //***************************************************************************** void *StgPoolReadOnly::GetBlob( // Pointer to blob's bytes. ULONG iOffset, // Offset of blob in pool. ULONG *piSize) // Return size of blob. { void const *pData = NULL; // Pointer to blob's bytes. if (iOffset == 0) { *piSize = 0; return (const_cast<BYTE*>(m_zeros)); } // Is the offset within this heap? //_ASSERTE(IsValidOffset(iOffset)); if(!IsValidOffset(iOffset)) { _ASSERTE(!"Invalid Blob Offset"); iOffset = 0; } // Get size of the blob (and pointer to data). *piSize = CPackedLen::GetLength(GetData(iOffset), &pData); // Return pointer to data. return (const_cast<void*>(pData)); }
//***************************************************************************** // Return a pointer to a Guid given an index previously handed out by // AddGuid or FindGuid. //***************************************************************************** GUID *StgPoolReadOnly::GetGuidi( // Pointer to guid in pool. ULONG iIndex) // 0-based index of Guid in pool. { ULONG iOffset = iIndex * sizeof(GUID); _ASSERTE(IsValidOffset(iOffset)); return (reinterpret_cast<GUID*>(GetData(iOffset))); }
size_t ReplBacklog::WriteChannel(Channel* channle, int64 offset, size_t len) { if (!IsValidOffset(offset)) { return 0; } int64 total = m_state->master_repl_offset - offset; size_t write_len = 0; if (m_state->repl_backlog_idx >= total) { write_len = total > len ? len : total; Buffer buf(m_repl_backlog + m_state->repl_backlog_idx - total, 0, write_len); channle->Write(buf); } else { int64 start_pos = m_state->repl_backlog_size - total + m_state->repl_backlog_idx; total = total - m_state->repl_backlog_idx; if (total <= len) { write_len = total; }else { write_len = len; } Buffer buf1(m_repl_backlog + start_pos, 0, write_len); channle->Write(buf1); } return write_len; }
bool ReplBacklog::IsValidOffset(const std::string& server_key, int64 offset) { if (strcmp(server_key.c_str(), m_state->serverkey)) { INFO_LOG("Partial resynchronization not accepted: " "Serverkey mismatch (Client asked for '%s', I'm '%s')", server_key.c_str(), m_state->serverkey); return false; } return IsValidOffset(offset); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Operand* ConstantFolder::LoadFromGlobal(Operand* op, const Type* loadType, __int64 offset) { // If the operand is not a reference to a global variable then we can't do anything, // even if the variable may be a constant. auto variableRef = op->As<VariableReference>(); if(variableRef == nullptr) { return nullptr; } auto globalVar = variableRef->GetGlobal(); if(globalVar == nullptr) { return nullptr; } // It's a global variable, now make sure that it's a constant // with an initializer that is not a tentative definition. if((globalVar->HasInitializer() == false) || (globalVar->IsConstant() == false) || globalVar->IsTentative()) { return nullptr; } // If the offset is negative or larger than the size of the type we give up // (some bytes may be available, but it's not worth the effort trying to extract them). if(IsValidOffset(globalVar, loadType, offset) == false) { return nullptr; } // If this is a simple value load it now; this is the common case. // Note that we can't load the value if it originates from something like // 'int a = (int)&a;', because it's not a compile-time constant. // An exception is when we the converted operand is 0 or a null pointer. if(globalVar->HasZeroInitializer()) { // The variable is initialized only with zeros, so the offset // doesn't matter as long as it's valid (and we checked that above). __int64 data = 0; return GetOperandHavingData((unsigned char*)&data, 8, loadType); } Initializer* initializer = globalVar->GetInitializer(); DebugValidator::IsNotNull(initializer); if(initializer->IsInitializerList() == false) { return LoadFromInitializer(initializer, loadType, offset); } // We have an initializer list, try to compute the index // of the initializer from which we should load. return LoadFromOffset(initializer, globalVar->GetType(), loadType, offset); }
// Sappy sound engine detector (c) 2014 by Bregalad, loveemu bool MP2kScanner::Mp2kDetector(RawFile *file, uint32_t &mp2k_offset) { const uint8_t CODESEG_SELECTSONG[0x1E] = { 0x00, 0xB5, 0x00, 0x04, 0x07, 0x4A, 0x08, 0x49, 0x40, 0x0B, 0x40, 0x18, 0x83, 0x88, 0x59, 0x00, 0xC9, 0x18, 0x89, 0x00, 0x89, 0x18, 0x0A, 0x68, 0x01, 0x68, 0x10, 0x1C, 0x00, 0xF0, }; const int M4A_MAIN_PATT_COUNT = 1; const int M4A_MAIN_LEN = 2; const uint8_t CODESEG_MAIN[M4A_MAIN_PATT_COUNT][M4A_MAIN_LEN] = { {0x00, 0xB5} }; const int M4A_INIT_PATT_COUNT = 2; const int M4A_INIT_LEN = 2; const off_t M4A_OFFSET_SONGTABLE = 40; off_t m4a_selectsong_offset = -1; off_t m4a_main_offset = -1; off_t m4a_selectsong_search_offset = 0; while (m4a_selectsong_search_offset != -1) { m4a_selectsong_offset = LooseSearch(file, CODESEG_SELECTSONG, sizeof(CODESEG_SELECTSONG), m4a_selectsong_search_offset, 1, 0); if (m4a_selectsong_offset != -1) { // obtain song table address uint32_t m4a_songtable_address = file->GetWord(m4a_selectsong_offset + M4A_OFFSET_SONGTABLE); if (!IsGBAROMAddress(m4a_songtable_address)) { m4a_selectsong_search_offset = m4a_selectsong_offset + 1; continue; } uint32_t m4a_songtable_offset_tmp = GBAAddressToOffset(m4a_songtable_address); if (!IsValidOffset(m4a_songtable_offset_tmp + 4 - 1, file->size())) { m4a_selectsong_search_offset = m4a_selectsong_offset + 1; continue; } // song table must have more than one song int validsongcount = 0; for (int songindex = 0; validsongcount < 1; songindex++) { uint32_t songaddroffset = m4a_songtable_offset_tmp + (songindex * 8); if (!IsValidOffset(songaddroffset + 4 - 1, file->size())) { break; } uint32_t songaddr = file->GetWord(songaddroffset); if (songaddr == 0) { continue; } if (!IsGBAROMAddress(songaddr)) { break; } if (!IsValidOffset(GBAAddressToOffset(songaddr) + 4 - 1, file->size())) { break; } validsongcount++; } if (validsongcount < 1) { m4a_selectsong_search_offset = m4a_selectsong_offset + 1; continue; } break; } else { m4a_selectsong_search_offset = -1; } } if (m4a_selectsong_offset == -1) { return false; } uint32_t m4a_main_offset_tmp = m4a_selectsong_offset; if (!IsValidOffset(m4a_main_offset_tmp + M4A_MAIN_LEN - 1, file->size())) { return false; } while (m4a_main_offset_tmp > 0 && m4a_main_offset_tmp > ((uint32_t) m4a_selectsong_offset - 0x20)) { for (int mainpattern = 0; mainpattern < M4A_MAIN_PATT_COUNT; mainpattern++) { if (file->MatchBytes(CODESEG_MAIN[mainpattern], m4a_main_offset_tmp, M4A_INIT_LEN)) { m4a_main_offset = (long) m4a_main_offset_tmp; break; } } m4a_main_offset_tmp--; } // Test validity of engine offset with -16 and -32 bool valid_m16 = test_pointer_validity(file, m4a_main_offset - 16, file->size()); // For most games bool valid_m32 = test_pointer_validity(file, m4a_main_offset - 32, file->size()); // For pokemon // If neither is found there is an error if (!valid_m16 && !valid_m32) { // Only a partial sound engine was found return false; } mp2k_offset = m4a_main_offset - (valid_m16 ? 16 : 32); return true; }