EXTERN_C BOOL PALAPI CryptImportKey( HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey) { CryptKey* pKey; BLOBHEADER *pBlobHeader; if (hProv == NULL) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if (hPubKey != NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (dwDataLen < sizeof(BLOBHEADER)) { goto BadKey; } pBlobHeader = (BLOBHEADER*)pbData; if ((pBlobHeader->bVersion != 0x02) || GET_UNALIGNED_VAL16(&pBlobHeader->reserved) != 0x0000) { goto BadKey; } if (!CreateKeyObject(hProv, GET_UNALIGNED_VAL32(&pBlobHeader->aiKeyAlg), &pKey)) { return FALSE; } pKey->SetFlags(dwFlags & CRYPT_EXPORTABLE); if (!pKey->ImportKey(dwFlags, pbData, dwDataLen)) { RELEASE(pKey); return FALSE; } *phKey = (HCRYPTKEY)pKey; return TRUE; BadKey: SetLastError(NTE_BAD_KEY); return FALSE; }
const BYTE *SkipIP(const BYTE *ip, DWORD opcode) { if (opcode == CEE_SWITCH) { unsigned int numcases = GET_UNALIGNED_VAL32(ip); ip += 4; return (ip + (numcases*4)); } else return (ip + argSizes[opcode]); }
//***************************************************************************** // This method will walk the byte codes of an IL method looking for tokens. // For each token found, it will check to see if it has been moved, and if // so, apply the new token value in its place. //***************************************************************************** HRESULT CeeFileGenWriter::MapTokensForMethod( CeeGenTokenMapper *pMapper, BYTE *pCode, LPCWSTR szMethodName) { mdToken tkTo; DWORD PC; COR_ILMETHOD_DECODER method((COR_ILMETHOD*) pCode); // If compressed IL is being emitted, this routine will have no idea how to walk the tokens, // so don't do it if (m_dwMacroDefinitionSize != 0) return S_OK; pCode = const_cast<BYTE*>(method.Code); PC = 0; while (PC < method.GetCodeSize()) { DWORD Len; DWORD i; OPCODE instr; instr = DecodeOpcode(&pCode[PC], &Len); if (instr == CEE_COUNT) { _ASSERTE(0 && "Instruction decoding error\n"); return E_FAIL; } PC += Len; switch (OpcodeInfo[instr].Type) { DWORD tk; default: { _ASSERTE(0 && "Unknown instruction\n"); return E_FAIL; } case InlineNone: break; case ShortInlineI: case ShortInlineVar: case ShortInlineBrTarget: PC++; break; case InlineVar: PC += 2; break; case InlineI: case ShortInlineR: case InlineBrTarget: case InlineRVA: PC += 4; break; case InlineI8: case InlineR: PC += 8; break; case InlinePhi: { DWORD cases = pCode[PC]; PC += 2 * cases + 1; break; } case InlineSwitch: { DWORD cases = pCode[PC] + (pCode[PC+1] << 8) + (pCode[PC+2] << 16) + (pCode[PC+3] << 24); PC += 4; for (i = 0; i < cases; i++) { PC += 4; } // skip bottom of loop which prints szString continue; } case InlineTok: case InlineSig: case InlineMethod: case InlineField: case InlineType: case InlineString: { tk = GET_UNALIGNED_VAL32(&pCode[PC]); if (pMapper->HasTokenMoved(tk, tkTo)) { SET_UNALIGNED_VAL32(&pCode[PC], tkTo); } PC += 4; break; } } } return S_OK; }
/*static*/ SIZE_T DebuggerFunction::Disassemble(BOOL native, SIZE_T offset, BYTE *codeStart, BYTE *codeEnd, WCHAR *buffer, BOOL noAddress, DebuggerModule *module, BYTE *ilCode) { SIZE_T ret; if (!native) { // // Write the address // swprintf(buffer, L"[IL:%.4x] ", offset); buffer += wcslen(buffer); // // Read next opcode // BYTE *ip = codeStart + offset; DWORD opcode; BYTE *prevIP = ip; ip = (BYTE *) ReadNextOpcode(ip, &opcode); // // Get the end of the instruction // BYTE *nextIP = (BYTE *) SkipIP(ip, opcode); BYTE *bytes = prevIP; // // Dump the raw value of the stream // while (bytes < ip) { swprintf(buffer, L"%.2x", *bytes++); buffer += wcslen(buffer); } *buffer++ = ':'; while (bytes < nextIP) { swprintf(buffer, L"%.2x", *bytes++); buffer += wcslen(buffer); } while (bytes++ - prevIP < 8) { *buffer++ = L' '; *buffer++ = L' '; } // // Print the opcode // swprintf(buffer, L"%s\t", opcodeName[opcode]); buffer += wcslen(buffer); int tokenType = operandDescription[opcode]; if (tokenType == InlineSwitch) { *buffer++ = L'\n'; DWORD caseCount = GET_UNALIGNED_VAL32(ip); ip += 4; DWORD index = 0; while (index < caseCount) { swprintf(buffer, L"\t\t\t%.5d:[%.4x]\n", index, GET_UNALIGNED_VAL16(ip)); buffer += wcslen(buffer); index++; ip += 4; } } else if (tokenType == InlinePhi) { *buffer++ = L'\n'; DWORD caseCount = *(unsigned char*)ip; ip += 1; DWORD index = 0; while (index < caseCount) { swprintf(buffer, L"\t\t\t%.5d: [%.4x]\n", index, GET_UNALIGNED_VAL16(ip)); buffer += wcslen(buffer); index++; ip += 2; } } else if (tokenType == InlineTok || tokenType == InlineType || tokenType == InlineField || tokenType == InlineMethod) { DisassembleToken(module->GetMetaData(), GET_UNALIGNED_VAL32(ip), buffer); buffer += wcslen(buffer); } else { DisassembleArgument(ip, ip - ilCode, tokenType, buffer); buffer += wcslen(buffer); } ret = nextIP - ilCode; } else { // Write the address if (!noAddress) { swprintf(buffer, L"[%.4x] ", offset); buffer += wcslen(buffer); } ret = 0xffff; } *buffer++ = L'\n'; *buffer = L'\0'; return (ret); }
void DisassembleArgument(BYTE *ip, DWORD address, int type, WCHAR *buffer) { /* * !!! this code isn't processor portable. */ switch (type) { case InlineNone: *buffer = L'\0'; break; case ShortInlineI: swprintf(buffer, L"%d", *(char *)ip); break; case ShortInlineVar: swprintf(buffer, L"%u", *(unsigned char *)ip); break; case InlineVar: swprintf(buffer, L"%u", GET_UNALIGNED_VAL16(ip)); break; case InlineI: swprintf(buffer, L"%d", GET_UNALIGNED_VAL32(ip)); break; case InlineI8: swprintf(buffer, L"%I64d", GET_UNALIGNED_VAL64(ip)); break; case ShortInlineR: { __int32 Value = GET_UNALIGNED_VAL32(ip); swprintf(buffer, L"%g", (float &)Value); } break; case InlineR: { __int64 Value = GET_UNALIGNED_VAL64(ip); swprintf(buffer, L"%g", (double &) Value); } break; case ShortInlineBrTarget: swprintf(buffer, L"[%.4x]", address + 1 + *(char *)ip); break; case InlineBrTarget: swprintf(buffer, L"[%.4x]", address + 4 + GET_UNALIGNED_VAL32(ip)); break; case InlineSwitch: { DWORD caseCount = GET_UNALIGNED_VAL32(ip); ip += 4; address += caseCount*4 + 4; DWORD index = 0; while (index < caseCount) { int offset = GET_UNALIGNED_VAL32(ip); buffer += wcslen(buffer); swprintf(buffer, L"%d:[%.4x] ", index, address + offset); index++; ip += 4; } } break; case InlinePhi: { DWORD caseCount = *(unsigned char*)ip; ip += 1; DWORD index = 0; while (index < caseCount) { buffer += wcslen(buffer); swprintf(buffer, L"%d:[%.4x] ", index, GET_UNALIGNED_VAL16(ip)); index++; ip += 2; } } break; case InlineTok: case InlineMethod: case InlineField: case InlineType: case InlineSig: swprintf(buffer, L"%d", GET_UNALIGNED_VAL32(ip)); break; case InlineString: swprintf(buffer, L"%08x", GET_UNALIGNED_VAL32(ip)); break; default: swprintf(buffer, L"<unknown type %d>", type); } }
BOOL RSAKey::ImportKey(DWORD dwFlags, CONST BYTE *pbData, DWORD dwDataLen) { BOOL bPrivate; DWORD dwBitLen; DWORD dwByteLen1; DWORD dwByteLen2; DWORD dwBufferSize1; DWORD dwBufferSize2; BYTE *pb; BLOBHEADER *pBlobHeader; RSAPUBKEY* pRSAPubKey; _ASSERTE(dwDataLen >= sizeof(BLOBHEADER)); pBlobHeader = (BLOBHEADER*)pbData; pbData += sizeof(BLOBHEADER); dwDataLen -= sizeof(BLOBHEADER); switch (pBlobHeader->bType) { case PUBLICKEYBLOB: bPrivate = FALSE; break; case PRIVATEKEYBLOB: bPrivate = TRUE; break; default: goto BadKey; } if (dwDataLen < sizeof(RSAPUBKEY)) { goto BadKey; } pRSAPubKey = (RSAPUBKEY*)pbData; pbData += sizeof(RSAPUBKEY); dwDataLen -= sizeof(RSAPUBKEY); if (GET_UNALIGNED_VAL32(&pRSAPubKey->magic) != (bPrivate ? 0x32415352U : 0x31415352U)) // 'RSA2' : 'RSA1' { goto BadKey; } dwBitLen = GET_UNALIGNED_VAL32(&pRSAPubKey->bitlen); if ((dwBitLen == 0) || (dwBitLen % 16 != 0) || (dwBitLen > 16384)) { goto BadKey; } m_dwBitLen = dwBitLen; dwByteLen1 = dwBitLen / 8; dwByteLen2 = dwByteLen1 / 2; if (dwDataLen != (bPrivate ? (9 * dwByteLen2) : dwByteLen1)) { goto BadKey; } dwBufferSize1 = BigNum::GetBufferSize(dwByteLen1); dwBufferSize2 = BigNum::GetBufferSize(dwByteLen2); m_dwSize = BigNum::GetBufferSize(sizeof(DWORD)) + (bPrivate ? (2 * dwBufferSize1 + 5 * dwBufferSize2) : dwBufferSize1); pb = (BYTE*)malloc(m_dwSize); if (pb == NULL) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } m_pBlob = pb; m_pExponent = (BigNum*)pb; pb += BigNum::GetBufferSize(sizeof(DWORD)); BigNum::SetBytes(m_pExponent, (BYTE*)&pRSAPubKey->pubexp, sizeof(DWORD)); #define HELPER(m_pMember, size) \ m_pMember = (BigNum*)pb; \ pb += dwBufferSize##size; \ BigNum::SetBytes(m_pMember, pbData, dwByteLen##size); \ pbData += dwByteLen##size; HELPER(m_pModulus, 1); if (!bPrivate) return TRUE; HELPER(m_pPrime1, 2); HELPER(m_pPrime2, 2); HELPER(m_pExponent1, 2); HELPER(m_pExponent2, 2); HELPER(m_pCoefficient, 2); HELPER(m_pPrivateExponent, 1); #undef HELPER if (!CheckKey()) { ClearStack(); goto BadKey; } ClearStack(); GetProvider()->SetSignatureKey(this); return TRUE; BadKey: SetLastError(NTE_BAD_KEY); return FALSE; }
const BYTE* OpInfo::fetch(const BYTE* instrPtr, OpArgsVal* args) { data = &table[*instrPtr++]; AGAIN: _ASSERTE(data - table == data->opcode); switch(data->format) { case InlineNone: break; case InlineOpcode: _ASSERTE(*instrPtr + 256 < (int) (sizeof(table) / sizeof(OpInfoData))); data = &table[256 + *instrPtr++]; goto AGAIN; case ShortInlineVar: args->i = *instrPtr; instrPtr +=1; break; case InlineVar: args->i = GET_UNALIGNED_VAL16(instrPtr); instrPtr +=2; break; case ShortInlineI: case ShortInlineBrTarget: args->i = *instrPtr; instrPtr +=1; break; case ShortInlineR: { DWORD f = GET_UNALIGNED_VAL32(instrPtr); instrPtr +=4; args->r = *((float*) (&f)); } break; case InlineRVA: case InlineI: case InlineMethod: case InlineField: case InlineType: case InlineString: case InlineSig: case InlineTok: case InlineBrTarget: args->i = GET_UNALIGNED_VAL32(instrPtr); instrPtr +=4; break; case InlineI8: args->i8 = GET_UNALIGNED_VAL64(instrPtr); instrPtr +=8; break; case InlineR: { __int64 d = GET_UNALIGNED_VAL64(instrPtr); instrPtr +=8; instrPtr += 8; args->r = *((double*) (&d)); } break; case InlineSwitch: args->switch_.count = GET_UNALIGNED_VAL32(instrPtr); instrPtr +=4; args->switch_.targets = (int*) instrPtr; instrPtr += (4 * args->switch_.count); break; case InlinePhi: args->phi.count = GET_UNALIGNED_VAL32(instrPtr); instrPtr +=1; args->phi.vars = (unsigned short*) instrPtr; instrPtr += (2 * args->phi.count); break; default: #ifdef _DEBUG _ASSERTE(!"BadType"); #else __assume(0); // we are really certain the default case does not happen #endif break; } return(instrPtr); }