Exemple #1
0
bool A5InitLoader::isSupported(const CodeSegment &code, const uint32 offset, const uint32 size) throw() {
	// Check whether the name matches
	if (code.getName() != "%A5Init")
		return false;

	const byte *memory = _executable.getMemory();
	const uint32 memorySize = _executable.getMemorySize();

	// Check whether it only exports one function
	if (!code.is32BitSegment() && READ_UINT16_BE(memory + offset + 2) != 0x0001)
		return false;
	else if (READ_UINT32_BE(memory + offset + 8) != 0x00000001)
		return false;

	const uint32 internalOffset = (code.is32BitSegment() ? 46 : 10);
	const uint32 infoOffset = READ_UINT16_BE(memory + offset + internalOffset) + internalOffset;

	// Check whether the information area is still inside the memory dump
	if (offset + infoOffset + 16 >= memorySize)
		return false;

	const uint32 dataOffset = READ_UINT32_BE(memory + offset + infoOffset + 8);
	const uint32 relocationDataOffset = READ_UINT32_BE(memory + offset + infoOffset + 12);

	// Check whether the compressed data is still in the memory dump
	if (offset + dataOffset >= memorySize)
		return false;
	// Check whether the relocation data is still in the memory dump
	if (offset + relocationDataOffset >= memorySize)
		return false;

	// Looks like it is an %A5Init segment
	return true;
}
Exemple #2
0
void A5InitLoader::load(const CodeSegment &code, const uint32 offset, const uint32 size, std::ostream &out) throw(std::exception) {
	byte *memory = _executable.getMemory();

	const uint32 internalOffset = (code.is32BitSegment() ? 46 : 10);
	const uint32 infoOffset = READ_UINT16_BE(memory + offset + internalOffset) + internalOffset;
	const uint32 dataSize = READ_UINT32_BE(memory + offset + infoOffset + 0);
	const uint16 needLoadBit = READ_UINT16_BE(memory + offset + infoOffset + 4);
	const uint32 dataOffset = READ_UINT32_BE(memory + offset + infoOffset + 8);
	const uint32 relocationDataOffset = READ_UINT32_BE(memory + offset + infoOffset + 12);

	// Output various information about the %A5Init segment
	out << "%A5Init info data:\n"
	       "\tData size: " << dataSize << "\n"
	       "\tNeed to load: " << needLoadBit << "\n"
	       "\tData offset: " << dataOffset << "\n"
	       "\tRelocation offset: " << relocationDataOffset << std::endl;

	// Check whether we actually have to do some work
	if (needLoadBit != 1) {
		out << "A5 data does not need any initialization" << std::endl;
		return;
	}

	const Code0Segment &code0 = _executable.getCode0Segment();
	uint8 *dst = memory + code0.getApplicationGlobalsSize() - dataSize;

	// uncompress the world
	uncompressA5World(dst, memory + offset + infoOffset + dataOffset);

	// relocate the world
	relocateWorld(code0.getApplicationGlobalsSize(), dst, memory + offset + infoOffset + relocationDataOffset, out);

	// Mark segment as initialized
	WRITE_UINT16_BE(memory + offset + infoOffset + 4, 0);
}