// ----------------------------------------------------------------------------------------------
// Copyright (c) Mattias H�gstr�m.
// ----------------------------------------------------------------------------------------------
// This source code is subject to terms and conditions of the Microsoft Public License. A
// copy of the license can be found in the License.html file at the root of this distribution.
// If you cannot locate the Microsoft Public License, please send an email to
// dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
// by the terms of the Microsoft Public License.
// ----------------------------------------------------------------------------------------------
// You must not remove this notice, or any other, from this software.
// ----------------------------------------------------------------------------------------------
#include "stdafx.h"
#include "ILRewriteHelper.h"
#include "ILRewriter.h"
#include "NullILRewriter.h"
#include "FunctionInfo.h"
//#include "TinyILWriter.h"
//#include "FatILWriter.h"
#include "DummyILRewriter.h"
#include "ProfilerLoggers.h"
#include <cor.h>
#include <corhlpr.h>
#include <sstream>
#include <map>
ILRewriteHelper::ILRewriteHelper()
{
m_info = nullptr;
m_systemObjectTypeDef = mdTypeDefNil;
m_systemDateTimeTypeDef = mdTypeDefNil;
m_mscorlibModuleID = 0;
}
ILRewriteHelper::ILRewriteHelper(ICorProfilerInfo* info)
{
m_info = info;
m_systemObjectTypeDef = mdTypeDefNil;
m_systemDateTimeTypeDef = mdTypeDefNil;
m_mscorlibModuleID = 0;
}
ILRewriteHelper::~ILRewriteHelper()
{
m_info = nullptr;
}
void ILRewriteHelper::SetCorProfilerInfo(ICorProfilerInfo* info)
{
m_info = info;
}
bool ILRewriteHelper::IsTiny(LPCBYTE methodBytes)
{
const void* pek = methodBytes;
const COR_ILMETHOD_TINY* objPek = static_cast<const COR_ILMETHOD_TINY*>(pek);
return objPek->IsTiny();
}
bool ILRewriteHelper::OptionalCheck(HRESULT hr)
{
switch (hr)
{
case S_OK:
case S_FALSE:
case META_S_DUPLICATE:
return true;
default:
return false;
}
}
void ILRewriteHelper::Check(HRESULT hr)
{
switch (hr)
{
case S_OK:
case S_FALSE:
return;
case META_S_DUPLICATE:
//case 0x00131197:
return;
default:
__debugbreak();
}
}
ILRewriter* ILRewriteHelper::CreateILRewriter(PreludeILRewriter* preludeILRewriter, FunctionInfo* functionInfo)
{
if (functionInfo == nullptr)
return new NullILRewriter();
if (functionInfo->GetFunctionID() == 0)
return new NullILRewriter();
LPCBYTE oldMethodBytes;
ULONG oldMethodSize;
Check(m_info->GetILFunctionBody(functionInfo->GetModuleID(), functionInfo->GetToken(), &oldMethodBytes, &oldMethodSize));
g_debugLogger << functionInfo->GetFunctionName() << std::endl;
return new DummyILRewriter(m_info, functionInfo, oldMethodBytes, oldMethodSize);
//return new NullILRewriter();
//if(IsTiny(oldMethodBytes))
//{
// g_debugLogger << " Tiny Header";
// if(oldMethodSize > (MAX_TINY_FORMAT_SIZE - preludeILRewriter->GetPreludeSize()))
// {
// g_debugLogger << " Converted to fat header" << std::endl;
// }
// return new TinyILWriter(m_info, functionInfo, preludeILRewriter, oldMethodBytes, oldMethodSize);
//}
//else
//{
// g_debugLogger << " Fat Header" << std::endl;
// return new FatILWriter(m_info, functionInfo, preludeILRewriter, oldMethodBytes, oldMethodSize);
//}
}
const int MAX_LENGTH = 1024;
FunctionInfo* ILRewriteHelper::CreateFunctionInfo(FunctionID functionID)
{
ClassID classID = 0;
ModuleID moduleID = 0;
mdToken tkMethod = 0;
Check(m_info->GetFunctionInfo(functionID, &classID, &moduleID, &tkMethod));
WCHAR moduleName[MAX_LENGTH];
AssemblyID assemblyID;
Check(m_info->GetModuleInfo(moduleID, NULL, MAX_LENGTH, 0, moduleName, &assemblyID));
WCHAR assemblyName[MAX_LENGTH];
Check(m_info->GetAssemblyInfo(assemblyID, MAX_LENGTH, 0, assemblyName, NULL, NULL));
if(wcscmp(assemblyName, L"InterceptLib") == 0 ||
wcscmp(assemblyName, L"mscorlib") == 0 ||
wcscmp(assemblyName, L"System") == 0)
{
return FunctionInfo::GetNullObject();
}
IMetaDataImport* metaDataImport = NULL;
mdToken token = NULL;
Check(m_info->GetTokenAndMetaDataFromFunction(functionID, IID_IMetaDataImport, (LPUNKNOWN *) &metaDataImport, &token));
mdTypeDef classTypeDef;
WCHAR functionName[MAX_LENGTH];
WCHAR className[MAX_LENGTH];
PCCOR_SIGNATURE signatureBlob;
ULONG signatureBlobLength;
DWORD methodAttributes = 0;
Check(metaDataImport->GetMethodProps(token, &classTypeDef, functionName, MAX_LENGTH, 0, &methodAttributes, &signatureBlob, &signatureBlobLength, NULL, NULL));
Check(metaDataImport->GetTypeDefProps(classTypeDef, className, MAX_LENGTH, 0, NULL, NULL));
metaDataImport->Release();
FunctionInfo* result = new FunctionInfo(functionID, classID, moduleID, tkMethod, functionName, className, assemblyName);
return result;
}
void* ILRewriteHelper::AllocateNewMethodBody(ICorProfilerInfo* info, ModuleID moduleId, ULONG newMethodSize)
{
IMethodMalloc* methodMalloc = NULL;
Check(info->GetILFunctionBodyAllocator(moduleId, &methodMalloc));
void *result = methodMalloc->Alloc(newMethodSize);
ZeroMemory(result, newMethodSize);
//memset((BYTE*)result+newMethodSize, 0xFEEDBEEF, 100);
methodMalloc->Release();
return result;
}