.Net Core CLR FileFormat Call Method( Include MetaData, Stream, #~)

.Net Core  CLR PE 文件启动方法,找到函数入口点,调用整个.Net 程式宿主。

使用方法:可以利用Visual Studio新建一个控制台应用程序,然后生成DLL,替换掉本程序DLL,新建C++ .CPP 文件

然后即可运行看到效果。

整个代码情况如下

包括 IMIAGE_CORE20_HEADER

MetaData, 表格对其方式等待


   4 #include "pch.h"
   5 #include <iostream>
   6 #include <Windows.h>
   7
   8 #define VAL32(x) x
   9 #define VAL16(x) x
  10 #define DPTR(type) type*
  11 typedef DPTR(IMAGE_DOS_HEADER)      PTR_IMAGE_DOS_HEADER;
  12 typedef DPTR(IMAGE_NT_HEADERS)      PTR_IMAGE_NT_HEADERS;
  13 typedef DPTR(IMAGE_NT_HEADERS64)    PTR_IMAGE_NT_HEADERS64;
  14 typedef ULONG_PTR TADDR;
  15 typedef DPTR(IMAGE_DATA_DIRECTORY)  PTR_IMAGE_DATA_DIRECTORY;
  16 typedef void* PTR_VOID;
  17 typedef DPTR(IMAGE_COR20_HEADER)    PTR_IMAGE_COR20_HEADER;
  18 typedef CONST void far      *LPCVOID;
  19
  20
  21
  22
  23 template <typename Tgt, typename Src>
  24 inline Tgt dac_cast(Src src)
  25 {
  26 #ifdef DACCESS_COMPILE
  27     // In DAC builds, first get a TADDR for the source, then create the
  28     // appropriate destination instance.
  29     TADDR addr = dac_imp::getTaddr(src);
  30     return dac_imp::makeDacInst<Tgt>::fromTaddr(addr);
  31 #else
  32     // In non-DAC builds, dac_cast is the same as a C-style cast because we need to support:
  33     //  - casting away const
  34     //  - conversions between pointers and TADDR
  35     // Perhaps we should more precisely restrict it‘s usage, but we get the precise
  36     // restrictions in DAC builds, so it wouldn‘t buy us much.
  37     return (Tgt)(src);
  38 #endif
  39 }
  40 TADDR m_base;
  41 TADDR m_b;
  42
  43
  44
  45 #define ALIGN4BYTE(val) (((val) + 3) & ~0x3)
  46
  47 struct STORAGEHEADER
  48 {
  49 public:
  50     BYTE        fFlags;                 // STGHDR_xxx flags.
  51     BYTE        pad;
  52     USHORT      iStreams;               // How many streams are there.
  53 public:
  54     BYTE GetFlags()
  55     {
  56         return fFlags;
  57     }
  58     void SetFlags(BYTE flags)
  59     {
  60         fFlags = flags;
  61     }
  62     void AddFlags(BYTE flags)
  63     {
  64         fFlags |= flags;
  65     }
  66
  67
  68     USHORT GetiStreams()
  69     {
  70         return VAL16(iStreams);
  71     }
  72     void SetiStreams(USHORT iStreamsCount)
  73     {
  74         iStreams = VAL16(iStreamsCount);
  75     }
  76 };
  77
  78 struct STORAGESIGNATURE
  79 {
  80 public:
  81     ULONG       lSignature;             // "Magic" signature.
  82     USHORT      iMajorVer;              // Major file version.
  83     USHORT      iMinorVer;              // Minor file version.
  84     ULONG       iExtraData;             // Offset to next structure of information
  85     ULONG       iVersionString;         // Length of version string
  86 public:
  87     BYTE        pVersion[0];            // Version string
  88     ULONG GetSignature()
  89     {
  90         return VAL32(lSignature);
  91     }
  92     void SetSignature(ULONG Signature)
  93     {
  94         lSignature = VAL32(Signature);
  95     }
  96
  97     USHORT GetMajorVer()
  98     {
  99         return VAL16(iMajorVer);
 100     }
 101     void SetMajorVer(USHORT MajorVer)
 102     {
 103         iMajorVer = VAL16(MajorVer);
 104     }
 105
 106     USHORT GetMinorVer()
 107     {
 108         return VAL16(iMinorVer);
 109     }
 110     void SetMinorVer(USHORT MinorVer)
 111     {
 112         iMinorVer = VAL16(MinorVer);
 113     }
 114
 115     ULONG GetExtraDataOffset()
 116     {
 117         return VAL32(iExtraData);
 118     }
 119     void SetExtraDataOffset(ULONG ExtraDataOffset)
 120     {
 121         iExtraData = VAL32(ExtraDataOffset);
 122     }
 123
 124     ULONG GetVersionStringLength()
 125     {
 126         return VAL32(iVersionString);
 127     }
 128     void SetVersionStringLength(ULONG VersionStringLength)
 129     {
 130         iVersionString = VAL32(VersionStringLength);
 131     }
 132 };
 133
 134 struct PSTORAGESIGNATURE
 135 {
 136    public:
 137     ULONG       lSignature;             // "Magic" signature.
 138     USHORT      iMajorVer;              // Major file version.
 139     USHORT      iMinorVer;              // Minor file version.
 140     ULONG       iExtraData;             // Offset to next structure of information
 141     ULONG       iVersionString;         // Length of version string
 142 public:
 143     BYTE        pVersion[0];            // Version string
 144     ULONG GetSignature()
 145     {
 146         return VAL32(lSignature);
 147     }
 148     void SetSignature(ULONG Signature)
 149     {
 150         lSignature = VAL32(Signature);
 151     }
 152
 153     USHORT GetMajorVer()
 154     {
 155         return VAL16(iMajorVer);
 156     }
 157     void SetMajorVer(USHORT MajorVer)
 158     {
 159         iMajorVer = VAL16(MajorVer);
 160     }
 161
 162     USHORT GetMinorVer()
 163     {
 164         return VAL16(iMinorVer);
 165     }
 166     void SetMinorVer(USHORT MinorVer)
 167     {
 168         iMinorVer = VAL16(MinorVer);
 169     }
 170
 171     ULONG GetExtraDataOffset()
 172     {
 173         return VAL32(iExtraData);
 174     }
 175     void SetExtraDataOffset(ULONG ExtraDataOffset)
 176     {
 177         iExtraData = VAL32(ExtraDataOffset);
 178     }
 179
 180     ULONG GetVersionStringLength()
 181     {
 182         return VAL32(iVersionString);
 183     }
 184     void SetVersionStringLength(ULONG VersionStringLength)
 185     {
 186         iVersionString = VAL32(VersionStringLength);
 187     }
 188 };
 189
 190 struct STORAGESTREAM;
 191 typedef STORAGESTREAM UNALIGNED * PSTORAGESTREAM;
 192
 193
 194 struct STORAGESTREAM
 195 {
 196 public:
 197     ULONG       iOffset;                // Offset in file for this stream.
 198     ULONG       iSize;                  // Size of the file.
 199     char        rcName[32];  // Start of name, null terminated.
 200 public:
 201     // Returns pointer to the next stream. Doesn‘t validate the structure.
 202     inline PSTORAGESTREAM NextStream()
 203     {
 204         int         iLen = (int)(strlen(rcName) + 1);
 205         iLen = ALIGN4BYTE(iLen);
 206         return ((PSTORAGESTREAM)(((BYTE*)this) + (sizeof(ULONG) * 2) + iLen));
 207     }
 208     // Returns pointer to the next stream.
 209     // Returns NULL if the structure has invalid format.
 210     inline PSTORAGESTREAM NextStream_Verify()
 211     {
 212         // Check existence of null-terminator in the name
 213         if (memchr(rcName, 0, 32) == NULL)
 214         {
 215             return NULL;
 216         }
 217         return NextStream();
 218     }
 219
 220     inline ULONG GetStreamSize()
 221     {
 222         return (ULONG)(strlen(rcName) + 1 + (sizeof(STORAGESTREAM) - sizeof(rcName)));
 223     }
 224
 225     inline char* GetName()
 226     {
 227         return rcName;
 228     }
 229     inline LPCWSTR GetName(__inout_ecount(iMaxSize) LPWSTR szName, int iMaxSize)
 230     {
 231         //VERIFY(::WszMultiByteToWideChar(CP_ACP, 0, rcName, -1, szName, iMaxSize));
 232         return (szName);
 233     }
 234     inline void SetName(LPCWSTR szName)
 235     {
 236         int size;
 237         //size = WszWideCharToMultiByte(CP_ACP, 0, szName, -1, rcName, MAXSTREAMNAME, 0, 0);
 238         _ASSERTE(size > 0);
 239     }
 240
 241     ULONG GetSize()
 242     {
 243         return VAL32(iSize);
 244     }
 245     void SetSize(ULONG Size)
 246     {
 247         iSize = VAL32(Size);
 248     }
 249
 250     ULONG GetOffset()
 251     {
 252         return VAL32(iOffset);
 253     }
 254     void SetOffset(ULONG Offset)
 255     {
 256         iOffset = VAL32(Offset);
 257     }
 258 };
 259
 260
 261 #define UI64_HELPER(x) x ## ui64
 262 #define UI64(x)        UI64_HELPER(x)
 263
 264 class CMiniMdSchemaBase
 265 {
 266 public:
 267     ULONG       m_ulReserved;           // Reserved, must be zero.
 268     BYTE        m_major;                // Version numbers.
 269     BYTE        m_minor;
 270     BYTE        m_heaps;                // Bits for heap sizes.
 271     BYTE        m_rid;                  // log-base-2 of largest rid.
 272
 273     // Bits for heap sizes.
 274     enum {
 275         HEAP_STRING_4 = 0x01,
 276         HEAP_GUID_4 = 0x02,
 277         HEAP_BLOB_4 = 0x04,
 278
 279         PADDING_BIT = 0x08,       // Tables can be created with an extra bit in columns, for growth.
 280
 281         DELTA_ONLY = 0x20,       // If set, only deltas were persisted.
 282         EXTRA_DATA = 0x40,       // If set, schema persists an extra 4 bytes of data.
 283         HAS_DELETE = 0x80,       // If set, this metadata can contain _Delete tokens.
 284     };
 285
 286     unsigned __int64    m_maskvalid;            // Bit mask of present table counts.
 287
 288     unsigned __int64    m_sorted;               // Bit mask of sorted tables.
 289     FORCEINLINE bool IsSorted(ULONG ixTbl)
 290     {
 291         return m_sorted & BIT(ixTbl) ? true : false;
 292     }
 293     void SetSorted(ULONG ixTbl, int bVal)
 294     {
 295         if (bVal) m_sorted |= BIT(ixTbl);
 296         else      m_sorted &= ~BIT(ixTbl);
 297     }
 298
 299 #if BIGENDIAN
 300     // Verify that the size hasn‘t changed (Update if necessary)
 301     void ConvertEndianness()
 302     {
 303         _ASSERTE(sizeof(CMiniMdSchemaBase) == 0x18);
 304         m_ulReserved = VAL32(m_ulReserved);
 305         m_maskvalid = VAL64(m_maskvalid);
 306         m_sorted = VAL64(m_sorted);
 307     }
 308 #else
 309     // Nothing to do on little endian machine
 310     void ConvertEndianness() { return; }
 311 #endif
 312
 313 private:
 314     FORCEINLINE unsigned __int64 BIT(ULONG ixBit)
 315     {
 316         _ASSERTE(ixBit < (sizeof(__int64)*CHAR_BIT));
 317         return UI64(1) << ixBit;
 318     }
 319
 320 };
 321
 322 typedef enum MetadataVersion
 323 {
 324     MDVersion1 = 0x00000001,
 325     MDVersion2 = 0x00000002,
 326
 327     // @TODO - this value should be updated when we increase the version number
 328     MDDefaultVersion = 0x00000002
 329 } MetadataVersion;
 330 class CMiniMdSchema : public CMiniMdSchemaBase
 331 {
 332 public:
 333     // These are not all persisted to disk.  See LoadFrom() for details.
 334     ULONG       m_cRecs[45];     // Counts of various tables.
 335
 336     ULONG       m_ulExtra;              // Extra data, only persisted if non-zero.  (m_heaps&EXTRA_DATA flags)
 337
 338     ULONG LoadFrom(const void*, ULONG); // Load from a compressed version.  Return bytes consumed.
 339     ULONG SaveTo(void *);               // Store a compressed version.  Return bytes used in buffer.
 340     __checkReturn
 341         HRESULT InitNew(MetadataVersion);
 342 };
 343 #define GET_UNALIGNED_32(_pObject)  (*(UINT32 UNALIGNED *)(_pObject))
 344 #define GET_UNALIGNED_VAL32(_pObject) VAL32(GET_UNALIGNED_32(_pObject))
 345
 346 template<typename T> class ClrSafeInt
 347 {
 348 public:
 349     // Default constructor - 0 value by default
 350     ClrSafeInt() :
 351         m_value(0),
 352         m_overflow(false)
 353         COMMA_INDEBUG(m_checkedOverflow(false))
 354     {
 355     }
 356
 357     // Value constructor
 358     // This is explicit because otherwise it would be harder to
 359     // differentiate between checked and unchecked usage of an operator.
 360     // I.e. si + x + y  vs. si + ( x + y )
 361     //
 362     // Set the m_checkedOverflow bit to true since this is being initialized
 363     // with a constant value and we know that it is valid. A scenario in
 364     // which this is useful is when an overflow causes a fallback value to
 365     // be used:
 366     //      if (val.IsOverflow())
 367     //          val = ClrSafeInt<T>(some_value);
 368     explicit ClrSafeInt(T v) :
 369         m_value(v),
 370         m_overflow(false)
 371         COMMA_INDEBUG(m_checkedOverflow(true))
 372     {
 373     }
 374
 375     template <typename U>
 376     explicit ClrSafeInt(U u) :
 377         m_value(0),
 378         m_overflow(false)
 379         COMMA_INDEBUG(m_checkedOverflow(false))
 380     {
 381         if (!FitsIn<T>(u))
 382         {
 383             m_overflow = true;
 384         }
 385         else
 386         {
 387             m_value = (T)u;
 388         }
 389     }
 390
 391     template <typename U>
 392     ClrSafeInt(ClrSafeInt<U> u) :
 393         m_value(0),
 394         m_overflow(false)
 395         COMMA_INDEBUG(m_checkedOverflow(false))
 396     {
 397         if (u.IsOverflow() || !FitsIn<T>(u.Value()))
 398         {
 399             m_overflow = true;
 400         }
 401         else
 402         {
 403             m_value = (T)u.Value();
 404         }
 405     }
 406
 407     // Note: compiler-generated copy constructor and assignment operator
 408     // are correct for our purposes.
 409
 410     // Note: The MS compiler will sometimes silently perform value-destroying
 411     // conversions when calling the operators below.
 412     // Eg. "ClrSafeInt<unsigned> s(0); s += int(-1);" will result in s
 413     // having the value 0xffffffff without generating a compile-time warning.
 414     // Narrowing conversions are generally level 4 warnings so may or may not
 415     // be visible.
 416     //
 417     // In the original SafeInt class, all operators have an
 418     // additional overload that takes an arbitrary type U and then safe
 419     // conversions are performed (resulting in overflow whenever the value
 420     // cannot be preserved).
 421     // We could do the same thing, but currently don‘t because:
 422     //  - we don‘t believe there are common cases where this would result in a
 423     //    security hole.
 424     //  - the extra complexity isn‘t worth the benefits
 425     //  - it would prevent compiler warnings in the cases we do get warnings for.
 426
 427
 428     // true if there has been an overflow leading up to the creation of this
 429     // value, false otherwise.
 430     // Note that in debug builds we track whether our client called this,
 431     // so we should not be calling this method ourselves from within this class.
 432     inline bool IsOverflow() const
 433     {
 434         INDEBUG(m_checkedOverflow = true; )
 435             return m_overflow;
 436     }
 437
 438     // Get the value of this integer.
 439     // Must only be called when IsOverflow()==false.  If this is called
 440     // on overflow we‘ll assert in Debug and return 0 in release.
 441     inline T Value() const
 442     {
 443         _ASSERTE_SAFEMATH(m_checkedOverflow);  // Ensure our caller first checked the overflow bit
 444         _ASSERTE_SAFEMATH(!m_overflow);
 445         return m_value;
 446     }
 447
 448     // force the value into the overflow state.
 449     inline void SetOverflow()
 450     {
 451         INDEBUG(this->m_checkedOverflow = false; )
 452             this->m_overflow = true;
 453         // incase someone manages to call Value in release mode - should be optimized out
 454         this->m_value = 0;
 455     }
 456
 457
 458     //
 459     // OPERATORS
 460     //
 461
 462     // Addition and multiplication.  Only permitted when both sides are explicitly
 463     // wrapped inside of a ClrSafeInt and when the types match exactly.
 464     // If we permitted a RHS of type ‘T‘, then there would be differences
 465     // in correctness between mathematically equivalent expressions such as
 466     // "si + x + y" and "si + ( x + y )".  Unfortunately, not permitting this
 467     // makes expressions involving constants tedius and ugly since the constants
 468     // must be wrapped in ClrSafeInt instances.  If we become confident that
 469     // our tools (PreFast) will catch all integer overflows, then we can probably
 470     // safely add this.
 471     inline ClrSafeInt<T> operator +(ClrSafeInt<T> rhs) const
 472     {
 473         ClrSafeInt<T> result;       // value is initialized to 0
 474         if (this->m_overflow ||
 475             rhs.m_overflow ||
 476             !addition(this->m_value, rhs.m_value, result.m_value))
 477         {
 478             result.m_overflow = true;
 479         }
 480
 481         return result;
 482     }
 483
 484     inline ClrSafeInt<T> operator -(ClrSafeInt<T> rhs) const
 485     {
 486         ClrSafeInt<T> result;       // value is initialized to 0
 487         if (this->m_overflow ||
 488             rhs.m_overflow ||
 489             !subtraction(this->m_value, rhs.m_value, result.m_value))
 490         {
 491             result.m_overflow = true;
 492         }
 493
 494         return result;
 495     }
 496
 497     inline ClrSafeInt<T> operator *(ClrSafeInt<T> rhs) const
 498     {
 499         ClrSafeInt<T> result;       // value is initialized to 0
 500         if (this->m_overflow ||
 501             rhs.m_overflow ||
 502             !multiply(this->m_value, rhs.m_value, result.m_value))
 503         {
 504             result.m_overflow = true;
 505         }
 506
 507         return result;
 508     }
 509
 510     // Accumulation operators
 511     // Here it‘s ok to have versions that take a value of type ‘T‘, however we still
 512     // don‘t allow any mixed-type operations.
 513     inline ClrSafeInt<T>& operator +=(ClrSafeInt<T> rhs)
 514     {
 515         INDEBUG(this->m_checkedOverflow = false; )
 516             if (this->m_overflow ||
 517                 rhs.m_overflow ||
 518                 !ClrSafeInt<T>::addition(this->m_value, rhs.m_value, this->m_value))
 519             {
 520                 this->SetOverflow();
 521             }
 522         return *this;
 523     }
 524
 525     inline ClrSafeInt<T>& operator +=(T rhs)
 526     {
 527         INDEBUG(this->m_checkedOverflow = false; )
 528             if (this->m_overflow ||
 529                 !ClrSafeInt<T>::addition(this->m_value, rhs, this->m_value))
 530             {
 531                 this->SetOverflow();
 532             }
 533         return *this;
 534     }
 535
 536     inline ClrSafeInt<T>& operator *=(ClrSafeInt<T> rhs)
 537     {
 538         INDEBUG(this->m_checkedOverflow = false; )
 539             if (this->m_overflow ||
 540                 rhs.m_overflow ||
 541                 !ClrSafeInt<T>::multiply(this->m_value, rhs.m_value, this->m_value))
 542             {
 543                 this->SetOverflow();
 544             }
 545         return *this;
 546     }
 547
 548     inline ClrSafeInt<T>& operator *=(T rhs)
 549     {
 550         INDEBUG(this->m_checkedOverflow = false; )
 551             if (this->m_overflow ||
 552                 !ClrSafeInt<T>::multiply(this->m_value, rhs, this->m_value))
 553             {
 554                 this->SetOverflow();
 555             }
 556
 557         return *this;
 558     }
 559
 560     //
 561     // STATIC HELPER METHODS
 562     //these compile down to something as efficient as macros and allow run-time testing
 563     //of type by the developer
 564     //
 565
 566     template <typename U> static bool IsSigned(U)
 567     {
 568         return std::is_signed<U>::value;
 569     }
 570
 571     static bool IsSigned()
 572     {
 573         return std::is_signed<T>::value;
 574     }
 575
 576     static bool IsMixedSign(T lhs, T rhs)
 577     {
 578         return ((lhs ^ rhs) < 0);
 579     }
 580
 581     static unsigned char BitCount() { return (sizeof(T) * 8); }
 582
 583     static bool Is64Bit() { return sizeof(T) == 8; }
 584     static bool Is32Bit() { return sizeof(T) == 4; }
 585     static bool Is16Bit() { return sizeof(T) == 2; }
 586     static bool Is8Bit() { return sizeof(T) == 1; }
 587
 588     //both of the following should optimize away
 589     static T MaxInt()
 590     {
 591         if (IsSigned())
 592         {
 593             return (T)~((T)1 << (BitCount() - 1));
 594         }
 595         //else
 596         return (T)(~(T)0);
 597     }
 598
 599     static T MinInt()
 600     {
 601         if (IsSigned())
 602         {
 603             return (T)((T)1 << (BitCount() - 1));
 604         }
 605         else
 606         {
 607             return ((T)0);
 608         }
 609     }
 610
 611     // Align a value up to the nearest boundary, which must be a power of 2
 612     inline void AlignUp(T alignment)
 613     {
 614         _ASSERTE_SAFEMATH(IsPowerOf2(alignment));
 615         *this += (alignment - 1);
 616         if (!this->m_overflow)
 617         {
 618             m_value &= ~(alignment - 1);
 619         }
 620     }
 621
 622     //
 623     // Arithmetic implementation functions
 624     //
 625
 626     //note - this looks complex, but most of the conditionals
 627     //are constant and optimize away
 628     //for example, a signed 64-bit check collapses to:
 629 /*
 630     if(lhs == 0 || rhs == 0)
 631         return 0;
 632
 633     if(MaxInt()/+lhs < +rhs)
 634     {
 635         //overflow
 636         throw SafeIntException(ERROR_ARITHMETIC_OVERFLOW);
 637     }
 638     //ok
 639     return lhs * rhs;
 640
 641     Which ought to inline nicely
 642 */
 643 // Returns true if safe, false for overflow.
 644     static bool multiply(T lhs, T rhs, T &result)
 645     {
 646         if (Is64Bit())
 647         {
 648             //fast track this one - and avoid DIV_0 below
 649             if (lhs == 0 || rhs == 0)
 650             {
 651                 result = 0;
 652                 return true;
 653             }
 654
 655             //we‘re 64 bit - slow, but the only way to do it
 656             if (IsSigned())
 657             {
 658                 if (!IsMixedSign(lhs, rhs))
 659                 {
 660                     //both positive or both negative
 661                     //result will be positive, check for lhs * rhs > MaxInt
 662                     if (lhs > 0)
 663                     {
 664                         //both positive
 665                         if (MaxInt() / lhs < rhs)
 666                         {
 667                             //overflow
 668                             return false;
 669                         }
 670                     }
 671                     else
 672                     {
 673                         //both negative
 674
 675                         //comparison gets tricky unless we force it to positive
 676                         //EXCEPT that -MinInt is undefined - can‘t be done
 677                         //And MinInt always has a greater magnitude than MaxInt
 678                         if (lhs == MinInt() || rhs == MinInt())
 679                         {
 680                             //overflow
 681                             return false;
 682                         }
 683
 684 #ifdef _MSC_VER
 685 #pragma warning( disable : 4146 )   // unary minus applied to unsigned is still unsigned
 686 #endif
 687                         if (MaxInt() / (-lhs) < (-rhs))
 688                         {
 689                             //overflow
 690                             return false;
 691                         }
 692 #ifdef _MSC_VER
 693 #pragma warning( default : 4146 )
 694 #endif
 695                     }
 696                 }
 697                 else
 698                 {
 699                     //mixed sign - this case is difficult
 700                     //test case is lhs * rhs < MinInt => overflow
 701                     //if lhs < 0 (implies rhs > 0),
 702                     //lhs < MinInt/rhs is the correct test
 703                     //else if lhs > 0
 704                     //rhs < MinInt/lhs is the correct test
 705                     //avoid dividing MinInt by a negative number,
 706                     //because MinInt/-1 is a corner case
 707
 708                     if (lhs < 0)
 709                     {
 710                         if (lhs < MinInt() / rhs)
 711                         {
 712                             //overflow
 713                             return false;
 714                         }
 715                     }
 716                     else
 717                     {
 718                         if (rhs < MinInt() / lhs)
 719                         {
 720                             //overflow
 721                             return false;
 722                         }
 723                     }
 724                 }
 725
 726                 //ok
 727                 result = lhs * rhs;
 728                 return true;
 729             }
 730             else
 731             {
 732                 //unsigned, easy case
 733                 if (MaxInt() / lhs < rhs)
 734                 {
 735                     //overflow
 736                     return false;
 737                 }
 738                 //ok
 739                 result = lhs * rhs;
 740                 return true;
 741             }
 742         }
 743         else if (Is32Bit())
 744         {
 745             //we‘re 32-bit
 746             if (IsSigned())
 747             {
 748                 INT64 tmp = (INT64)lhs * (INT64)rhs;
 749
 750                 //upper 33 bits must be the same
 751                 //most common case is likely that both are positive - test first
 752                 if ((tmp & 0xffffffff80000000LL) == 0 ||
 753                     (tmp & 0xffffffff80000000LL) == 0xffffffff80000000LL)
 754                 {
 755                     //this is OK
 756                     result = (T)tmp;
 757                     return true;
 758                 }
 759
 760                 //overflow
 761                 return false;
 762
 763             }
 764             else
 765             {
 766                 UINT64 tmp = (UINT64)lhs * (UINT64)rhs;
 767                 if (tmp & 0xffffffff00000000ULL) //overflow
 768                 {
 769                     //overflow
 770                     return false;
 771                 }
 772                 result = (T)tmp;
 773                 return true;
 774             }
 775         }
 776         else if (Is16Bit())
 777         {
 778             //16-bit
 779             if (IsSigned())
 780             {
 781                 INT32 tmp = (INT32)lhs * (INT32)rhs;
 782                 //upper 17 bits must be the same
 783                 //most common case is likely that both are positive - test first
 784                 if ((tmp & 0xffff8000) == 0 || (tmp & 0xffff8000) == 0xffff8000)
 785                 {
 786                     //this is OK
 787                     result = (T)tmp;
 788                     return true;
 789                 }
 790
 791                 //overflow
 792                 return false;
 793             }
 794             else
 795             {
 796                 UINT32 tmp = (UINT32)lhs * (UINT32)rhs;
 797                 if (tmp & 0xffff0000) //overflow
 798                 {
 799                     return false;
 800                 }
 801                 result = (T)tmp;
 802                 return true;
 803             }
 804         }
 805         else //8-bit
 806         {
 807             _ASSERTE_SAFEMATH(Is8Bit());
 808
 809             if (IsSigned())
 810             {
 811                 INT16 tmp = (INT16)lhs * (INT16)rhs;
 812                 //upper 9 bits must be the same
 813                 //most common case is likely that both are positive - test first
 814                 if ((tmp & 0xff80) == 0 || (tmp & 0xff80) == 0xff80)
 815                 {
 816                     //this is OK
 817                     result = (T)tmp;
 818                     return true;
 819                 }
 820
 821                 //overflow
 822                 return false;
 823             }
 824             else
 825             {
 826                 UINT16 tmp = ((UINT16)lhs) * ((UINT16)rhs);
 827
 828                 if (tmp & 0xff00) //overflow
 829                 {
 830                     return false;
 831                 }
 832                 result = (T)tmp;
 833                 return true;
 834             }
 835         }
 836     }
 837
 838     // Returns true if safe, false on overflow
 839     static inline bool addition(T lhs, T rhs, T &result)
 840     {
 841         if (IsSigned())
 842         {
 843             //test for +/- combo
 844             if (!IsMixedSign(lhs, rhs))
 845             {
 846                 //either two negatives, or 2 positives
 847 #ifdef __GNUC__
 848                 // Workaround for GCC warning: "comparison is always
 849                 // false due to limited range of data type."
 850                 if (!(rhs == 0 || rhs > 0))
 851 #else
 852                 if (rhs < 0)
 853 #endif // __GNUC__ else
 854                 {
 855                     //two negatives
 856                     if (lhs < (T)(MinInt() - rhs)) //remember rhs < 0
 857                     {
 858                         return false;
 859                     }
 860                     //ok
 861                 }
 862                 else
 863                 {
 864                     //two positives
 865                     if ((T)(MaxInt() - lhs) < rhs)
 866                     {
 867                         return false;
 868                     }
 869                     //OK
 870                 }
 871             }
 872             //else overflow not possible
 873             result = lhs + rhs;
 874             return true;
 875         }
 876         else //unsigned
 877         {
 878             if ((T)(MaxInt() - lhs) < rhs)
 879             {
 880                 return false;
 881
 882             }
 883             result = lhs + rhs;
 884             return true;
 885         }
 886     }
 887
 888     // Returns true if safe, false on overflow
 889     static inline bool subtraction(T lhs, T rhs, T& result)
 890     {
 891         T tmp = lhs - rhs;
 892
 893         if (IsSigned())
 894         {
 895             if (IsMixedSign(lhs, rhs)) //test for +/- combo
 896             {
 897                 //mixed positive and negative
 898                 //two cases - +X - -Y => X + Y - check for overflow against MaxInt()
 899                 //            -X - +Y - check for overflow against MinInt()
 900
 901                 if (lhs >= 0) //first case
 902                 {
 903                     //test is X - -Y > MaxInt()
 904                     //equivalent to X > MaxInt() - |Y|
 905                     //Y == MinInt() creates special case
 906                     //Even 0 - MinInt() can‘t be done
 907                     //note that the special case collapses into the general case, due to the fact
 908                     //MaxInt() - MinInt() == -1, and lhs is non-negative
 909                     //OR tmp should be GTE lhs
 910
 911                     // old test - leave in for clarity
 912                     //if(lhs > (T)(MaxInt() + rhs)) //remember that rhs is negative
 913                     if (tmp < lhs)
 914                     {
 915                         return false;
 916                     }
 917                     //fall through to return value
 918                 }
 919                 else
 920                 {
 921                     //second case
 922                     //test is -X - Y < MinInt()
 923                     //or      -X < MinInt() + Y
 924                     //we do not have the same issues because abs(MinInt()) > MaxInt()
 925                     //tmp should be LTE lhs
 926
 927                     //if(lhs < (T)(MinInt() + rhs)) // old test - leave in for clarity
 928                     if (tmp > lhs)
 929                     {
 930                         return false;
 931                     }
 932                     //fall through to return value
 933                 }
 934             }
 935             // else
 936             //both negative, or both positive
 937             //no possible overflow
 938             result = tmp;
 939             return true;
 940         }
 941         else
 942         {
 943             //easy unsigned case
 944             if (lhs < rhs)
 945             {
 946                 return false;
 947             }
 948             result = tmp;
 949             return true;
 950         }
 951     }
 952
 953 private:
 954     // Private helper functions
 955     // Note that‘s it occasionally handy to call the arithmetic implementation
 956     // functions above so we leave them public, even though we almost always use
 957     // the operators instead.
 958
 959     // True if the specified value is a power of two.
 960     static inline bool IsPowerOf2(T x)
 961     {
 962         // find the smallest power of 2 >= x
 963         T testPow = 1;
 964         while (testPow < x)
 965         {
 966             testPow = testPow << 1;           // advance to next power of 2
 967             if (testPow <= 0)
 968             {
 969                 return false;       // overflow
 970             }
 971         }
 972
 973         return(testPow == x);
 974     }
 975
 976     //
 977     // Instance data
 978     //
 979
 980     // The integer value this instance represents, or 0 if overflow.
 981     T m_value;
 982
 983     // True if overflow has been reached.  Once this is set, it cannot be cleared.
 984     bool m_overflow;
 985
 986     // In debug builds we verify that our caller checked the overflow bit before
 987     // accessing the value.  This flag is cleared on initialization, and whenever
 988     // m_value or m_overflow changes, and set only when IsOverflow
 989     // is called.
 990     INDEBUG(mutable bool m_checkedOverflow; )
 991 };
 992
 993 ULONG
 994 CMiniMdSchema::LoadFrom(
 995     const void *pvData,     // Data to load from.
 996     ULONG       cbData)     // Amount of data available.
 997 {
 998     ULONG ulData;   // Bytes consumed.
 999
1000     ulData = sizeof(CMiniMdSchemaBase);
1001
1002     // Be sure we can get the base part.
1003     if (cbData < ulData)
1004         return (ULONG)(-1);
1005
1006     // Transfer the fixed fields. The (void*) casts prevents the compiler
1007     // from making bad assumptions about the alignment.
1008     memcpy((void *)this, (void *)pvData, sizeof(CMiniMdSchemaBase));
1009     static_cast<CMiniMdSchemaBase*>(this)->ConvertEndianness();
1010
1011     unsigned __int64 maskvalid = m_maskvalid;
1012
1013     // Transfer the variable fields.
1014     memset(m_cRecs, 0, sizeof(m_cRecs));
1015     int iDst;
1016     for (iDst = 0; iDst < 45; ++iDst, maskvalid >>= 1)
1017     {
1018         if ((maskvalid & 1) != 0)
1019         {
1020             // Check integer overflow for: ulData + sizeof(UINT32)
1021             ULONG ulDataTemp;
1022             if (!ClrSafeInt<ULONG>::addition(ulData, sizeof(UINT32), ulDataTemp))
1023             {
1024                 return (ULONG)(-1);
1025             }
1026             // Verify that the data is there before touching it.
1027             if (cbData < (ulData + sizeof(UINT32)))
1028                 return (ULONG)(-1);
1029
1030             m_cRecs[iDst] = GET_UNALIGNED_VAL32((const BYTE *)pvData + ulData);
1031             // It‘s safe to sum, because we checked integer overflow above
1032             ulData += sizeof(UINT32);
1033         }
1034     }
1035     // Also accumulate the sizes of any counters that we don‘t understand.
1036
1037
1038     // Retrieve the extra 4 bytes data.
1039     // Did we go past end of buffer?
1040     if (cbData < ulData)
1041         return (ULONG)(-1);
1042
1043     return ulData;
1044 } // CMiniMdSchema::LoadFrom
1045
1046 int main()
1047 {
1048     HMODULE HE=LoadLibraryExW(L"C:\\Users\\Administrator\\Desktop\\Consletest\\ConsoleApp5.dll", NULL, 8);
1049     //0x00007ff82c940000
1050     //0x00007ff82e1c0000
1051
1052     m_base=TADDR((void *)HE);
1053
1054     IMAGE_DOS_HEADER *SR =dac_cast<PTR_IMAGE_DOS_HEADER>(PTR_IMAGE_DOS_HEADER(HE));
1055
1056     IMAGE_NT_HEADERS *HR =dac_cast<PTR_IMAGE_NT_HEADERS64>(PTR_IMAGE_NT_HEADERS(m_base + VAL32(SR->e_lfanew)));
1057
1058     IMAGE_DATA_DIRECTORY *pDir=dac_cast<PTR_IMAGE_DATA_DIRECTORY>(dac_cast<TADDR>(dac_cast<PTR_IMAGE_NT_HEADERS64>(PTR_IMAGE_NT_HEADERS(m_base + VAL32(PTR_IMAGE_DOS_HEADER(HE)->e_lfanew)))) +
1059         offsetof(IMAGE_NT_HEADERS64, OptionalHeader.DataDirectory) + 14 * sizeof(IMAGE_DATA_DIRECTORY));
1060
1061
1062     IMAGE_COR20_HEADER *OR = PTR_IMAGE_COR20_HEADER(m_base + VAL32(pDir->VirtualAddress));
1063
1064     IMAGE_DATA_DIRECTORY  *DR =&(OR->MetaData);
1065
1066     const void* pMeta = NULL;
1067
1068     pMeta=dac_cast<PTR_VOID>(VAL32(m_base+DR->VirtualAddress));
1069
1070     ULONG cbStreamBuffer;
1071
1072     const BYTE *pbMd;
1073
1074     pbMd = (const BYTE *)pMeta;
1075
1076
1077     pbMd += sizeof(STORAGESIGNATURE);
1078
1079     ULONG cbVersionString = ((STORAGESIGNATURE *)pMeta)->GetVersionStringLength();
1080
1081     pbMd += cbVersionString;
1082
1083     pbMd += sizeof(STORAGEHEADER);
1084
1085     PSTORAGESTREAM pStream;
1086
1087     pStream = (PSTORAGESTREAM)pbMd;
1088
1089     int i;
1090     CMiniMdSchema   m_Schema;
1091     ULONG   cbData;
1092     ULONG   cb;
1093     for (i = 0; i < 5; i++)
1094     {
1095         void *pvCurrentData = (void *)((BYTE *)pMeta + pStream->GetOffset());
1096
1097         ULONG cbCurrentData = pStream->GetSize();
1098
1099         PSTORAGESTREAM pNext = pStream->NextStream_Verify();
1100
1101         if (pStream->GetName() == "#~")
1102         {
1103             cbData = sizeof(CMiniMdSchemaBase);
1104             cb=m_Schema.LoadFrom(pvCurrentData, cbCurrentData);
1105         }
1106         pStream = pNext;
1107     }
1108
1109
1110     std::cout << "Hello World!\n";
1111 }

原文地址:https://www.cnblogs.com/tangyanzhi1111/p/11283011.html

时间: 2024-10-12 22:06:37

.Net Core CLR FileFormat Call Method( Include MetaData, Stream, #~)的相关文章

Core CLR 自定义的Host官方推荐的一种形式(第一种)

.Net Core CLR提供两种Host API访问 托管代码的形式,按照微软官方的说法,一种是通过CoreClr.DLL来直接调用托管生成的DLL程序集,另外一种是通过CoreClr里面的C导出函数GetCLRRuntimeHost获取到IID_ICLRRuntimeHost4然后访问托管代码. 其实这两种形式可以合二为一,第一种更简单,更方便的控制托管代码.第二种更灵活些,在一些老旧的主机上会用到这些代码,实际上第一种形式是扩充了第二种访问形式,进行了一个整体封装,原理上其实还是一样的.

class net.sf.cglib.core.DebuggingClassWriter overrides final method visit

在使用CGLIB进行动态代理的时候,报了[java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter overrides final method visit. (IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V]错误. 原因是因为我做的是SpringBoot的项目,在SpringBoot的架构中已经存在了cglib

CLR 这些年有啥变化吗?

引言 首先想给初学者推荐下<CLR via C#>这本好书,做.Net开发的开发者应该都读一下.不说原因啦,也是为了做广告.这里提供豆瓣书评的链接. CLR 作为.Net 程序跨平台运行的载体,和Java的JVM有着类似的功能(JAVA为跨平台而生,实现这一目标离不开JVM). 随着.NET Framework的日益发展CLR也有日新月异的变化.这些变化为开发带来更多有用的特性,在提高开发效率的同时也提高了程序的性能和稳定性.   如果大家觉得还有必要把这块更新的更好,还请多多反馈. 如果觉的

魅力 .NET:从 Mono、.NET Core 说起

转自:http://kb.cnblogs.com/page/514268/ 前段时间,被问了这样一个问题:.NET 应用程序是怎么运行的? 当时大概愣了好久,好像也没说出个所以然,得到的回复是:这是 .NET 程序员最基本的...呵呵! 微软开源,其实不只是对 .NET 本身有利,从另一方面讲,对于 .NET 程序员来说,因为开源,你可以想了解到你想要的任何事.在之前的岁月,你可以“平凡”做一个默默无闻的 C# 代码撰写者,可以不用考虑任何事,使用宇宙最强大的 IDE - Visual Stud

魅力 .NET:从 Mono、.NET Core[转]

前段时间,被问了这样一个问题:.NET 应用程序是怎么运行的? 当时大概愣了好久,好像也没说出个所以然,得到的回复是:这是 .NET 程序员最基本的...呵呵! 微软开源,其实不只是对 .NET 本身有利,从另一方面讲,对于 .NET 程序员来说,因为开源,你可以想了解到你想要的任何事.在之前的岁月,你可以“平凡”做一个默默无闻的 C# 代码撰写者,可以不用考虑任何事,使用宇宙最强大的 IDE - Visual Studio 编写代码后,发布到 IIS 即可,就是这么简单,甚至你不需要知道 II

Cryptographic method and system

The present invention relates to the field of security of electronic data and/or communications. In one form, the invention relates to data security and/or privacy in a distributed and/or decentralised network environment. In another form, the invent

了解ASP.NET Core端点路由

原作者Areg Sarkissian 介绍 在这篇文章中,我将说明从版本2.2开始已添加到ASP.NET Core中间件管道中的新的端点路由功能,以及它如何演进到当前在预览版3的即将发布的版本3.0. 端点路由背后的动机 在端点路由之前,在HTTP请求处理管道的末尾,在ASP.NET Core MVC中间件中完成了ASP.NET Core应用程序的路由解析.这意味着在中间件管道中的MVC中间件之前,路由信息(例如将执行哪些控制器操作)对于处理请求的中间件不可用. 例如在CORS或授权中间件中提供

asp.net core mvc 3.1 源码分析(五)

创建完ApplicationModel后,调用ControllerActionDescriptorBuilder类的Build方法创建对应的ControllerActionDescriptor internal static class ControllerActionDescriptorBuilder { public static IList<ControllerActionDescriptor> Build(ApplicationModel application) { return A

.NET Core R2安装及示例教程

.NET Core R2安装及示例教程 前言 前几天.NET Core发布了.NET Core 1.0.1 R2 预览版,之前想着有时间尝试下.NET Core.由于各种原因,就没有初试.刚好,前几天看到.NET Core发布新版本了,决定要去一探究竟.于是乎,就立马去官网查找相关的信息,为初探做准备. 下面就开始今天的内容,有两个部分:安装和创建示例程序. 安装 本人使用的是Windows 10 64位系统,安装过Visual Studio 2015,如果没有安装,请先安装. 下载安装文件 进