Example #1
0
DWORD ReflectiveLoaderOffset(DWORD BaseAddress){

	PIMAGE_DOS_HEADER pDosHeader;
	PIMAGE_NT_HEADERS pImageHeader;
	PIMAGE_EXPORT_DIRECTORY PExportDirectory;

	//DWORD RDLLAddress;

    pDosHeader = (PIMAGE_DOS_HEADER)BaseAddress;
    pImageHeader = (PIMAGE_NT_HEADERS)(BaseAddress + pDosHeader->e_lfanew);

	DWORD ExportRVA = pImageHeader->OptionalHeader.DataDirectory[0].VirtualAddress;
	PExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(RVAToOffset(pImageHeader,ExportRVA)+BaseAddress);

	PDWORD ExportFunctions = (PDWORD)(RVAToOffset(pImageHeader, PExportDirectory->AddressOfFunctions) + BaseAddress); 
	PDWORD ExportNames = (PDWORD)(RVAToOffset(pImageHeader, PExportDirectory->AddressOfNames) + BaseAddress);
	PWORD ExportOrdinals = (PWORD)(RVAToOffset(pImageHeader, PExportDirectory->AddressOfNameOrdinals) + BaseAddress);

	char *check = nullptr;
	char *tempPointer = nullptr;
	bool gotcha = false;
	DWORD address = 0;
	for (DWORD i =0; i<PExportDirectory->NumberOfFunctions; i++) {
		//std::cout << (char*)(DWORD*)RVAToOffset(pImageHeader,ExportNames[i]) + BaseAddress << std::endl;
		//std::cout << (PDWORD)RVAToOffset(pImageHeader,ExportFunctions[ExportOrdinals[i]]) + BaseAddress << std::endl;
		check = ((char*)(DWORD*)RVAToOffset(pImageHeader,ExportNames[i]) + BaseAddress);
		tempPointer = strstr(check,"ReflectiveLoader");
		if(tempPointer != nullptr && check != nullptr)
		{
			gotcha = true;
			address = (DWORD)RVAToOffset(pImageHeader,ExportFunctions[ExportOrdinals[i]]);
			break;
		}

    } 
	if (gotcha) 
	{
		dprintf(L"[*] ReflectiveDll function offset found: 0x%08x\n", address);
		return address;
	}
	else return 0x153e; //hardcoded from original metsrv.dll... we have not tested these functions thoroughly yet.
};
	ulong GetFunctionOffset(std::string dllPath, std::string functionName)
	{
		// see http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
		// offset to PE header is always at 0x3C
		// PE header starts with "PE\0\0" = 0x50 0x45 0x00 0x00
		// Followed by 2-byte machine type field

		ifstream inFile(dllPath.c_str(), ifstream::in | ifstream::binary);
		std::streamoff size = 0;
		if (inFile.is_open()) {

			char* oData = 0;

			inFile.seekg(0, ios::end);
			size = inFile.tellg();
			inFile.seekg(0, ios::beg);

			oData = new char[size + 1];
			inFile.read(oData, size);
			oData[size] = '\0';

			//IMAGE_DOS_HEADER dosHeader = ReadStruct<IMAGE_DOS_HEADER>(br);
			uint offset = read<uint>(oData, 0x3c, NULL);

			uint cPosition;
			uint pHead = read<uint>(oData, offset, &cPosition);
			if (pHead != PE::IMAGE_NT_SIGNATURE)    // "PE\0\0" little-endian
			{
				// Not a valid portable executable
				return 0;
			}

			//IMAGE_FILE_HEADER fileHeader = IMAGE_FILE_HEADER.FromStream(br);
			IMAGE_FILE_HEADER fileHeader = read<IMAGE_FILE_HEADER>(oData, cPosition, &cPosition);

			ushort machineType = fileHeader.Machine;
			bool is64Bit = false;
			if (machineType != (ushort)UNKNOWN)
			{
				if (machineType == IA64 || machineType == AMD64)
				{
					is64Bit = true;
				}
			}
			else
			{
				return 0;
			}

			IMAGE_DATA_DIRECTORY exportDirectory;
			if (!is64Bit)
			{
				//IMAGE_OPTIONAL_HEADER optionalHeader = IMAGE_OPTIONAL_HEADER.FromStream(br);
				IMAGE_OPTIONAL_HEADER optionalHeader = read<IMAGE_OPTIONAL_HEADER>(oData, cPosition, &cPosition);
				exportDirectory = optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
			}
			else
			{
				IMAGE_OPTIONAL_HEADER64 optionalHeader = read<IMAGE_OPTIONAL_HEADER64>(oData, cPosition, &cPosition);
				exportDirectory = optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
			}
			//UInt32 exportPtr = optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
			//fs.Seek(exportPtr, SeekOrigin.Begin);
			// should now be at the .export section!
			uint nSec = fileHeader.NumberOfSections;
			IMAGE_SECTION_HEADER *sec = new IMAGE_SECTION_HEADER[nSec];
			for (uint i = 0; i < nSec; i++)
			{
				sec[i] = read<IMAGE_SECTION_HEADER>(oData, cPosition, &cPosition);
			}

			// = optionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
			uint exportOffset = RVAToOffset(exportDirectory.VirtualAddress, sec, nSec);
			if (exportOffset > 0)
			{
				cPosition = exportOffset;

				IMAGE_EXPORT_DIRECTORY exports = read<IMAGE_EXPORT_DIRECTORY>(oData, cPosition, &cPosition);

				uint nameOffset = RVAToOffset(exports.AddressOfNames, sec, nSec);
				uint funcOffset = RVAToOffset(exports.AddressOfFunctions, sec, nSec);
				uint ordinalOffset = RVAToOffset(exports.AddressOfNameOrdinals, sec, nSec);

				uint length = min(exports.NumberOfFunctions, exports.NumberOfNames);

				vector<string> names;
				vector<uint> addresses;
				vector<uint> ordinals;

				// Read in all named-function names:
				cPosition = nameOffset;
				for (uint i = 0; i < length; i++)
				{
					uint stringLocation = read<uint>(oData, cPosition, &cPosition);
					uint theStringStart = RVAToOffset(stringLocation, sec, nSec);

					cPosition = theStringStart;
					names.push_back(&oData[cPosition]);

					cPosition = nameOffset + (i + 1) * 4;
				}

				// Read in all named-function offsets:
				cPosition = funcOffset;
				for (uint i = 0; i < length; i++)
				{
					addresses.push_back(read<uint>(oData, cPosition, &cPosition));
				}

				// Read in all named-function ordinals
				cPosition = ordinalOffset;
				for (uint i = 0; i < length; i++)
				{
					ordinals.push_back((uint)(read<ushort>(oData, cPosition, &cPosition) + (exports.Base)));

					uint ord = ordinals[i] - exports.Base;
					if (ord >= 0 && ord < length)
					{
						string name = names[i];
						ulong address = addresses[ord];
						if (name.compare(functionName) == 0){
							return address;
						}
						//printf("%s: %d\n", name.c_str(), address);
					}
				}
			}
		}
		return 0;
	}
Example #3
0
unsigned long long MACHFile::getEntryPointOffset()
{
    return RVAToOffset(getEntryPoint());
}