Hello Nadav
This is what I do:
[error checking etc removed]
_pCeeFileGen->CreateCeeFile( &_hCeeFile);
_pCeeFileGen->SetOutputFileN ame(_hCeeFile, fileName);
//call link so we can use GetSectionRVA
_pCeeFileGen->LinkCeeFile(_h CeeFile);
//get il section
HCEESECTION hSection;
_pCeeFileGen->GetIlSection (_hCeeFile, &hSection);
ULONG rva;
_pCeeFileGen->GetSectionRV A (hSection, &rva);
ULONG codeSize =0;
char* pBytes = NULL;
//get a new block just to get a pointer to the section, get 4 bytes for
DWORD alignement
_pCeeFileGen->GetSectionBloc k (hSection, 4, 1,
reinterpret_cas t<void**>(&pByt es));
unsigned int offset;
_pCeeFileGen->ComputeSection Offset(hSection , pBytes, &offset);
//this copies all IL code into a buffer (_pILBuffer), see below
//also calls SetRVA for each method
GetILCode(&code Size, rva + offset);
//get a new block large enough to hold IL Code (codezize - 4 bytes
//allocatd above)
char* pBytes2 = NULL;
_pCeeFileGen->GetSectionBloc k (hSection, codeSize - 4, 1,
reinterpret_cas t<void**>(&pByt es2));
//copy IL Code to section
memcpy(pBytes, _pILBuffer, codeSize);
_pCeeFileGen->EmitMetaDataEx (_hCeeFile, _pMetaDataEmit) ;
_pCeeFileGen->LinkCeeFile(_h CeeFile);
_pCeeFileGen->GenerateCeeFil e(_hCeeFile);
_pCeeFileGen->DestroyCeeFile (&_hCeeFile);
delete[] _pILBuffer;
//==== GetILCode
HRESULT CAssemblyWriter ::GetILCode(ULO NG* pCodeSize, unsigned int offset) {
HRESULT hr = NULL;
//HACK: Allocate enough memory to hold entire .text section
int bufferSize = _pReader->GetPEFile()->_sizeOfTextSec tion;
_pILBuffer = new BYTE[bufferSize];
ZeroMemory(_pIL Buffer, bufferSize);
int codeSize = 0;
//get all method of all types and add ILCode to buffer
std::vector<CTy peDef*> typeDefs = _pReader->_typeDefs;
for (unsigned int ii=0; ii < _pReader->_typeDefs.size (); ii++) {
CTypeDef* pType = _pReader->_typeDefs[ii];
for (unsigned jj = 0; jj < pType->_methodDefs.si ze(); jj++) {
CMethodDef* pMethod = pType->_methodDefs[jj];
if (pMethod->_codeSize > 0) {
int methodSize = pMethod->_codeSize + pMethod->_codeHeaderSiz e;
memcpy(_pILBuff er + codeSize, pMethod->_pCodeHeader , methodSize);
hr = _pMetaDataEmit->SetRVA(pMeth od->_token, offset + codeSize);
if (!SUCCEEDED(hr) ) {
return hr;
}
//HACK
if (pMethod->_name == L"Main") {
hr = _pCeeFileGen->SetEntryPoint( _hCeeFile, pMethod->_token);
if (!SUCCEEDED(hr) ) {
return hr;
}
}
codeSize += methodSize;
codeSize = _ALIGN4(codeSiz e);
if (pMethod->_pStartExtraSe ctions) {
memcpy(_pILBuff er + codeSize, pMethod->_pStartExtraSe ctions,
pMethod->_sizeExtraSect ions);
codeSize += pMethod->_sizeExtraSect ions;
codeSize = _ALIGN4(codeSiz e);
}
}
}
}
*pCodeSize = codeSize;
return hr;
}
as you can see, I have all TypeDefs and methods in std::vectors
pMethod->_codeSize is the size of the IL Code and pMethod->_pCodeHeader
points to the start of the ILCode Header (CorILMethod_Sm allFormat etc)
pMethod->_pStartExtraSe ctions points to the extrasections like exception
handling if present
(
http://msdn.microsoft.com/msdnmag/is...I/default.aspx)
to translate the rva obtained from GetMethodProps I call
ImageRvaToVa(pN THeaders, pBase, rva, NULL);
hth
--
Ben
http://bschwehn.de