Пример #1
0
BinStr* BinStrToUnicode(BinStr* pSource, bool Swap)
{
    if(pSource)
    {
        pSource->appendInt8(0);
        BinStr* tmp = new BinStr();
        char*   pb = (char*)(pSource->ptr());
        int l=pSource->length(), L = sizeof(WCHAR)*l;
		if(tmp)
		{
			WCHAR*  wz = (WCHAR*)(tmp->getBuff(L));
			if(wz)
			{
				memset(wz,0,L);
				WszMultiByteToWideChar(g_uCodePage,0,pb,-1,wz,l);
				tmp->remove(L-(DWORD)wcslen(wz)*sizeof(WCHAR));
#if BIGENDIAN
				if (Swap)
					SwapStringLength(wz, (DWORD)wcslen(wz));
#endif
				delete pSource;
			}
			else
			{
				delete tmp;
				tmp = NULL;
				fprintf(stderr,"\nOut of memory!\n");
			}
		}
		else
			fprintf(stderr,"\nOut of memory!\n");
        return tmp;
    }
    return NULL;
}
Пример #2
0
static void OnOK(HWND hDlg, LPARAM lParam)
{
   BinStr* s = reinterpret_cast<BinStr*>((LPARAM)GetWindowLongPtr(hDlg, GWLP_USERDATA));
   if (!s)
      return;

   HWND pinCtrl = GetDlgItem(hDlg, IDC_PIN_EDIT);
   int len = GetWindowTextLength(pinCtrl);

   s->resize(len + 1);
   GetWindowText(pinCtrl, reinterpret_cast<LPSTR>(&(*s)[0]), static_cast<int>(s->size()));
   
   // Chop off null cause we don't need it
   s->resize(s->size() - 1);

   EndDialog(hDlg, IDOK);
}
Пример #3
0
void AsmMan::EmitDebuggableAttribute(mdToken tkOwner)
{
    mdToken tkCA;
    Assembler* pAsm = (Assembler*)m_pAssembler;
    mdToken tkTypeSpec, tkMscorlib, tkParamType;
    BinStr  *pbsSig = new BinStr();
    BinStr* bsBytes = new BinStr();;
    char*   szName;
    tkMscorlib = pAsm->m_fIsMscorlib ? 1 : pAsm->GetAsmRef("mscorlib");
    tkTypeSpec = pAsm->ResolveClassRef(tkMscorlib,"System.Diagnostics.DebuggableAttribute",NULL);

    EmitAssemblyRefs(); // just in case we gained 'mscorlib' AsmRef in GetAsmRef above

    BOOL fOldStyle = FALSE;
    if(tkMscorlib == 1)
        fOldStyle = (m_pAssembly->usVerMajor == 1);
    else
    {
        AsmManAssembly *pAssembly = GetAsmRefByName("mscorlib");
        _ASSERTE(pAssembly != NULL);
        PREFIX_ASSUME(pAssembly != NULL);
        fOldStyle = (pAssembly->usVerMajor == 1);
    }

    bsBytes->appendInt8(1);
    bsBytes->appendInt8(0);
    if(fOldStyle)
    {
        pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS);
        corEmitInt(pbsSig,2);
        pbsSig->appendInt8(ELEMENT_TYPE_VOID);
        pbsSig->appendInt8(ELEMENT_TYPE_BOOLEAN);
        pbsSig->appendInt8(ELEMENT_TYPE_BOOLEAN);

        //New to old: 0x101->(true,true),0x03->(true,false),0x103->(true,true)+warning
        bsBytes->appendInt8(1);
        bsBytes->appendInt8((pAsm->m_dwIncludeDebugInfo==0x03 ? 0 : 1));
        if(pAsm->m_dwIncludeDebugInfo == 0x103)
        {
            report->warn("\nOption /DEBUG=IMPL is invalid for legacy DebuggableAttribute, /DEBUG used.\n" );
        }
    }
    else
    {
        BinStr  bsSigArg;
        char buffer[80];
        sprintf_s(buffer,80, 
                "%s%c%s",
                "System.Diagnostics.DebuggableAttribute",
                NESTING_SEP,
                "DebuggingModes"
               );

        tkParamType = pAsm->ResolveClassRef(tkMscorlib,buffer, NULL);

        bsSigArg.appendInt8(ELEMENT_TYPE_VALUETYPE);

        unsigned cnt = CorSigCompressToken(tkParamType, bsSigArg.getBuff(5));
        bsSigArg.remove(5 - cnt);

        pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS);
        corEmitInt(pbsSig,1);
        pbsSig->appendInt8(ELEMENT_TYPE_VOID);
        pbsSig->append(&bsSigArg);

        bsBytes->appendInt32(pAsm->m_dwIncludeDebugInfo);
    }
    bsBytes->appendInt8(0);
    bsBytes->appendInt8(0);

    szName = new char[16];
    strcpy_s(szName,16,".ctor");
    tkCA = pAsm->MakeMemberRef(tkTypeSpec,szName,pbsSig);
    pAsm->DefineCV(new CustomDescr(tkOwner,tkCA,bsBytes));
}
Пример #4
0
HRESULT Assembler::CreatePEFile(WCHAR *pwzOutputFilename)
{
    HRESULT             hr;
	DWORD				mresourceSize = 0;
	BYTE*				mresourceData = NULL;
	//IUnknown *pUnknown = NULL;
//    DWORD               i;

	if(bClock) cMDEmitBegin = GetTickCount();
	if(m_fReportProgress) printf("Creating %s file\n", m_fOBJ ? "COFF" : "PE");
    if (!m_pEmitter)
    {
        printf("Error: Cannot create a PE file with no metadata\n");
        return E_FAIL;
    }
	if(!(m_fDLL || m_fEntryPointPresent))
	{
		printf("Error: No entry point declared for executable\n");
		if(!OnErrGo) return E_FAIL;
	}

    if (DoGlobalFixups() == FALSE)
        return E_FAIL;
	if(bClock) cMDEmit1 = GetTickCount();

	if(m_fOBJ)
	{
		// emit pseudo-relocs to pass file name and build number to PEWriter
		// this should be done BEFORE method emission!
		char* szInFileName = new char[strlen(m_szSourceFileName)+1];
		strcpy(szInFileName,m_szSourceFileName);
		m_pCeeFileGen->AddSectionReloc(m_pILSection,(DWORD)szInFileName,m_pILSection,(CeeSectionRelocType)0x7FFC);
		time_t tm;
		time(&tm);
		struct tm* loct = localtime(&tm);
		DWORD compid = 0x002E0000 | (loct->tm_mday + (loct->tm_mon+1)*100);
		m_pCeeFileGen->AddSectionReloc(m_pILSection,compid,m_pILSection,(CeeSectionRelocType)0x7FFB);
	}

    // Allocate space for a strong name signature if we're delay or full
    // signing the assembly.
    if (m_pManifest->m_sStrongName.m_pbPublicKey)
        if (FAILED(hr = AllocateStrongNameSignature()))
            goto exit;
	if(bClock) cMDEmit2 = GetTickCount();

	// Check undefined local TypeRefs
	if(m_LocalTypeRefDList.COUNT())
	{
		LocalTypeRefDescr*	pLTRD=NULL;
		BOOL	bIsUndefClass = FALSE;
        while((pLTRD = m_LocalTypeRefDList.POP()))
		{
			if(NULL == FindClass(pLTRD->m_szFullName))
			{
				report->msg("%s: Reference to undefined class '%s' (token 0x%08X)\n",
                    "Error", pLTRD->m_szFullName,pLTRD->m_tok);
				bIsUndefClass = TRUE;
			}
			delete pLTRD;
		}
        if(bIsUndefClass && !OnErrGo) return E_FAIL;
	}
	if(bClock) cMDEmit3 = GetTickCount();

	// Emit class members and globals:
	{
        Class *pSearch;
		int i;
		if(m_fReportProgress)	printf("\nEmitting members:\n");
        for (i=0; (pSearch = m_lstClass.PEEK(i)); i++)
		{
			if(m_fReportProgress)
			{
				if(i == 0)	printf("Global \t");
				else		printf("Class %d\t",i);
			}
			if(!EmitMembers(pSearch))
			{
				if(!OnErrGo) return E_FAIL;
			}
		}
	}
	if(bClock) cMDEmit4 = GetTickCount();

	if(m_MethodImplDList.COUNT())
	{
		if(m_fReportProgress) report->msg("Method Implementations (total): %d\n",m_MethodImplDList.COUNT());
		if(!EmitMethodImpls())
		{
			if(!OnErrGo) return E_FAIL;
		}
	}
	if(bClock) cMDEmitEnd = cRef2DefBegin = GetTickCount();
	// Now, when all items defined in this file are emitted, let's try to resolve member refs to member defs:
	if(m_MemberRefDList.COUNT())
	{
		MemberRefDescriptor*	pMRD;
		mdToken			tkMemberDef = 0;
		int i,j;
		unsigned ulTotal=0, ulDefs=0, ulRefs=0;
		Class	*pSearch;

		if(m_fReportProgress) printf("Resolving member refs: ");
        while((pMRD = m_MemberRefDList.POP()))
		{
			tkMemberDef = 0;
			MethodDescriptor* pListMD;
			mdToken			pMRD_tdClass = pMRD->m_tdClass;
			char*			pMRD_szName = pMRD->m_szName;
			ULONG			pMRD_dwCSig = (pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->length() : 0);
			PCOR_SIGNATURE	pMRD_pSig = (PCOR_SIGNATURE)(pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->ptr() : NULL);
			ulTotal++;
			// MemberRef may reference a method or a field
			if((pMRD_pSig==NULL)||(*pMRD_pSig != IMAGE_CEE_CS_CALLCONV_FIELD))
			{
                for (i=0; (pSearch = m_lstClass.PEEK(i)); i++)
				{
					if(pMRD_tdClass != pSearch->m_cl) continue;
                    for(j=0; (pListMD = pSearch->m_MethodDList.PEEK(j)); j++)
					{
						if(pListMD->m_dwCSig  != pMRD_dwCSig)  continue;
						if(memcmp(pListMD->m_pSig,pMRD_pSig,pMRD_dwCSig)) continue;
						if(strcmp(pListMD->m_szName,pMRD_szName)) continue;
						tkMemberDef = pListMD->m_mdMethodTok;
						break;
					}
				}
			}
			if(tkMemberDef == 0)
			{
				if((pMRD_pSig==NULL)||(*pMRD_pSig == IMAGE_CEE_CS_CALLCONV_FIELD))
				{
					FieldDescriptor* pListFD;
                    for (i=0; (pSearch = m_lstClass.PEEK(i)); i++)
					{
						if(pMRD_tdClass != pSearch->m_cl) continue;
                        for(j=0; (pListFD = pSearch->m_FieldDList.PEEK(j)); j++)
						{
							if(pListFD->m_pbsSig)
							{
								if(pListFD->m_pbsSig->length()  != pMRD_dwCSig)  continue;
								if(memcmp(pListFD->m_pbsSig->ptr(),pMRD_pSig,pMRD_dwCSig)) continue;
							}
							else if(pMRD_dwCSig) continue;
							if(strcmp(pListFD->m_szName,pMRD_szName)) continue;
							tkMemberDef = pListFD->m_fdFieldTok;
							break;
						}
					}
				}
			}
			if(tkMemberDef==0)
			{ // could not resolve ref to def, make new ref and leave it this way
                if((pSearch = pMRD->m_pClass))
				{
					mdToken tkRef;
					BinStr* pbs = new BinStr();
					pbs->appendInt8(ELEMENT_TYPE_NAME);
					strcpy((char*)(pbs->getBuff((unsigned int)strlen(pSearch->m_szFQN)+1)),pSearch->m_szFQN);
					if(!ResolveTypeSpecToRef(pbs,&tkRef)) tkRef = mdTokenNil;
					delete pbs;

					if(RidFromToken(tkRef))
					{
						ULONG cTemp = (ULONG)(strlen(pMRD_szName)+1);
						WCHAR* wzMemberName = new WCHAR[cTemp];
						WszMultiByteToWideChar(g_uCodePage,0,pMRD_szName,-1,wzMemberName,cTemp);

						hr = m_pEmitter->DefineMemberRef(tkRef, wzMemberName, pMRD_pSig, 
							pMRD_dwCSig, &tkMemberDef);
						ulRefs++;
						delete [] wzMemberName;
					}
				}
			}
			else ulDefs++;
			if(RidFromToken(tkMemberDef))
			{
				SET_UNALIGNED_VAL32((mdToken *)pMRD->m_ulOffset, tkMemberDef);
				delete pMRD;
			}
			else
			{
				report->msg("Error: unresolved member ref '%s' of class 0x%08X\n",pMRD->m_szName,pMRD->m_tdClass);
				hr = E_FAIL;
				delete pMRD;
				if(!OnErrGo) goto exit;
			}
		}
		if(m_fReportProgress) printf("%d -> %d defs, %d refs\n",ulTotal,ulDefs,ulRefs);
	}
	if(bClock) cRef2DefEnd = GetTickCount();
	// emit manifest info (if any)
	hr = S_OK;
	if(m_pManifest) 
	{
		if (FAILED(hr = m_pManifest->EmitManifest())) goto exit;
	}

	if(g_wzResourceFile)
	    if (FAILED(hr=m_pCeeFileGen->SetResourceFileName(m_pCeeFile, g_wzResourceFile))) goto exit;

	if (FAILED(hr=CreateTLSDirectory())) goto exit;

	if (FAILED(hr=CreateDebugDirectory())) goto exit;
    
    if (FAILED(hr=m_pCeeFileGen->SetOutputFileName(m_pCeeFile, pwzOutputFilename))) goto exit;

		// Reserve a buffer for the meta-data
	DWORD metaDataSize;	
	if (FAILED(hr=m_pEmitter->GetSaveSize(cssAccurate, &metaDataSize))) goto exit;
	BYTE* metaData;
	if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, metaDataSize, sizeof(DWORD), (void**) &metaData))) goto exit; 
	ULONG metaDataOffset;
	if (FAILED(hr=m_pCeeFileGen->GetSectionDataLen(m_pILSection, &metaDataOffset))) goto exit;
	metaDataOffset -= metaDataSize;
	// set managed resource entry, if any
	if(m_pManifest && m_pManifest->m_dwMResSizeTotal)
	{
		mresourceSize = m_pManifest->m_dwMResSizeTotal;

		if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, mresourceSize, 
											sizeof(DWORD), (void**) &mresourceData))) goto exit; 
	    if (FAILED(hr=m_pCeeFileGen->SetManifestEntry(m_pCeeFile, mresourceSize, 0))) goto exit;
	}

	if(m_VTFList.COUNT())
	{
		GlobalLabel *pGlobalLabel;
		VTFEntry*	pVTFEntry;

		if(m_pVTable) delete m_pVTable; // can't have both; list takes precedence
		m_pVTable = new BinStr();
		hr = S_OK;
        for(WORD k=0; (pVTFEntry = m_VTFList.POP()); k++)
		{
            if((pGlobalLabel = FindGlobalLabel(pVTFEntry->m_szLabel)))
			{
				MethodDescriptor*	pMD;
				Class* pClass;
				m_pVTable->appendInt32(pGlobalLabel->m_GlobalOffset);
				m_pVTable->appendInt16(pVTFEntry->m_wCount);
				m_pVTable->appendInt16(pVTFEntry->m_wType);
                for(int i=0; (pClass = m_lstClass.PEEK(i)); i++)
				{
                    for(WORD j = 0; (pMD = pClass->m_MethodDList.PEEK(j)); j++)
					{
						if(pMD->m_wVTEntry == k+1)
						{
							char*	ptr;
							if(SUCCEEDED(hr = m_pCeeFileGen->ComputeSectionPointer(m_pGlobalDataSection,pGlobalLabel->m_GlobalOffset,&ptr)))
							{
								DWORD dwDelta = (pMD->m_wVTSlot-1)*((pVTFEntry->m_wType & COR_VTABLE_32BIT) ? (DWORD) sizeof(DWORD) : (DWORD) sizeof(__int64));
								ptr += dwDelta;
								mdMethodDef* mptr = (mdMethodDef*)ptr;
								*mptr = pMD->m_mdMethodTok;
								if(pMD->m_dwExportOrdinal != 0xFFFFFFFF)
								{
									EATEntry*	pEATE = new EATEntry;
									pEATE->dwOrdinal = pMD->m_dwExportOrdinal;
									pEATE->szAlias = pMD->m_szExportAlias ? pMD->m_szExportAlias : pMD->m_szName;
									pEATE->dwStubRVA = EmitExportStub(pGlobalLabel->m_GlobalOffset+dwDelta);
									m_EATList.PUSH(pEATE);
								}
							}
							else
								report->msg("Error: Failed to get pointer to label '%s' inVTable fixup\n",pVTFEntry->m_szLabel);
						}
					}
				}
			}
			else
			{
				report->msg("Error: Unresolved label '%s' in VTable fixup\n",pVTFEntry->m_szLabel);
				hr = E_FAIL;
			}
			delete pVTFEntry;
		}
		if(FAILED(hr)) goto exit;
	}
	if(m_pVTable)
	{
		//DWORD *pdw = (DWORD *)m_pVTable->ptr();
		ULONG i, N = m_pVTable->length()/sizeof(DWORD);
		ULONG ulVTableOffset;
		m_pCeeFileGen->GetSectionDataLen (m_pILSection, &ulVTableOffset);
		if (FAILED(hr=m_pCeeFileGen->SetVTableEntry(m_pCeeFile, m_pVTable->length(),(ULONG)(m_pVTable->ptr())))) goto exit;
		for(i = 0; i < N; i+=2)
		{
			m_pCeeFileGen->AddSectionReloc(m_pILSection, 
											ulVTableOffset+(i*sizeof(DWORD)),
											m_pGlobalDataSection, 
											srRelocAbsolute);
		}
	}
	if(m_EATList.COUNT())
	{
		if(FAILED(CreateExportDirectory())) goto exit;
	}
    if (m_fWindowsCE)
    {
        if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, 2, 10))) goto exit;

        if (FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, 0x10000))) goto exit;
    }
	else if(m_dwSubsystem)
	{
        if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, m_dwSubsystem, 4, 0))) goto exit;
	}
	
    if (FAILED(hr=m_pCeeFileGen->ClearComImageFlags(m_pCeeFile, COMIMAGE_FLAGS_ILONLY))) goto exit;
    if (FAILED(hr=m_pCeeFileGen->SetComImageFlags(m_pCeeFile, m_dwComImageFlags & ~COMIMAGE_FLAGS_STRONGNAMESIGNED))) goto exit;

	if(m_dwFileAlignment)
	{
		if(FAILED(hr=m_pCeeFileGen->SetFileAlignment(m_pCeeFile, m_dwFileAlignment))) goto exit;
	}
    if(m_stBaseAddress)
    {
        if(FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, m_stBaseAddress))) goto exit;
    }
		//Compute all the RVAs
	if (FAILED(hr=m_pCeeFileGen->LinkCeeFile(m_pCeeFile))) goto exit;

		// Fix up any fields that have RVA associated with them
	if (m_fHaveFieldsWithRvas) {
		hr = S_OK;
		ULONG dataSectionRVA;
		if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pGlobalDataSection, &dataSectionRVA))) goto exit;
		
		ULONG tlsSectionRVA;
		if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pTLSSection, &tlsSectionRVA))) goto exit;

		FieldDescriptor* pListFD;
		Class* pClass;
        for(int i=0; (pClass = m_lstClass.PEEK(i)); i++)
		{
            for(int j=0; (pListFD = pClass->m_FieldDList.PEEK(j)); j++)
			{
				if (pListFD->m_rvaLabel != 0) 
				{
					GlobalLabel *pLabel = FindGlobalLabel(pListFD->m_rvaLabel);
					if (pLabel == 0)
					{
						report->msg("Error:Could not find label '%s' for the field '%s'\n", pListFD->m_rvaLabel, pListFD->m_szName);
						hr = E_FAIL;
						continue;
					}
				
					DWORD rva = pLabel->m_GlobalOffset;
					if (pLabel->m_Section == m_pTLSSection)
						rva += tlsSectionRVA;
					else {
						_ASSERTE(pLabel->m_Section == m_pGlobalDataSection);
						rva += dataSectionRVA;
					}
					if (FAILED(m_pEmitter->SetFieldRVA(pListFD->m_fdFieldTok, rva))) goto exit;
				}
			}
		}
		if (FAILED(hr)) goto exit;
	}

	if(bClock) cFilegenBegin = GetTickCount();
	// actually output the meta-data
    if (FAILED(hr=m_pCeeFileGen->EmitMetaDataAt(m_pCeeFile, m_pEmitter, m_pILSection, metaDataOffset, metaData, metaDataSize))) goto exit;
	// actually output the resources
	if(mresourceSize && mresourceData)
	{
		size_t  i, N = m_pManifest->m_dwMResNum, sizeread, L;
		BYTE	*ptr = (BYTE*)mresourceData;
		BOOL	mrfail = FALSE;
		FILE*	pFile;
		char sz[2048];
		for(i=0; i < N; i++)
		{
			memset(sz,0,2048);
			WszWideCharToMultiByte(CP_ACP,0,m_pManifest->m_wzMResName[i],-1,sz,2047,NULL,NULL);
			L = m_pManifest->m_dwMResSize[i];
			sizeread = 0;
			memcpy(ptr,&L,sizeof(DWORD));
			ptr += sizeof(DWORD);
            if((pFile = fopen(sz,"rb")))
			{
				sizeread = fread((void *)ptr,1,L,pFile);
				fclose(pFile);
				ptr += sizeread;
			}
			else
			{
				report->msg("Error: failed to open mgd resource file '%ls'\n",m_pManifest->m_wzMResName[i]);
				mrfail = TRUE;
			}
			if(sizeread < L)
			{
				report->msg("Error: failed to read expected %d bytes from mgd resource file '%ls'\n",L,m_pManifest->m_wzMResName[i]);
				mrfail = TRUE;
				L -= sizeread;
				memset(ptr,0,L);
				ptr += L;
			}
		}
		if(mrfail) 
		{ 
			hr = E_FAIL;
			goto exit;
		}
	}

	// Generate the file -- moved to main
    //if (FAILED(hr=m_pCeeFileGen->GenerateCeeFile(m_pCeeFile))) goto exit;


    hr = S_OK;

exit:
    return hr;
}