.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 }
.Net Core CLR FileFormat Call Method( Include MetaData, Stream, #~)的更多相关文章
- Core CLR 自定义的Host官方推荐的一种形式(第一种)
.Net Core CLR提供两种Host API访问 托管代码的形式,按照微软官方的说法,一种是通过CoreClr.DLL来直接调用托管生成的DLL程序集,另外一种是通过CoreClr里面的C导出函 ...
- EF Core 1.0中使用Include的小技巧
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:由于EF Core暂时不支持Lazy Loading,所以利用Include来加载额外 ...
- class net.sf.cglib.core.DebuggingClassWriter overrides final method visit
在使用CGLIB进行动态代理的时候,报了[java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter overrides f ...
- .net Core CLR
.net Core CLR是开源的.大部分文件是C++写成.这样他就可以编译后再不同的平台运行. https://github.com/dotnet/coreclr
- Core CLR Host 源码简单分析
在定制 CLR Host的时候,可以通过调用如下代码,来获取当前需要被宿主的程序调用入口: hr = Host->CreateDelegate( domainId, L"Main,Ve ...
- Core 1.0中publishOptions Include的bug
"publishOptions": { "include": [ "wwwroot", "Views", "A ...
- CLR via C# 3rd - 08 - Methods
Kinds of methods Constructors Type constructors Overload operators Type con ...
- .NET CLR 运行原理
原文: Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects 文章讨论了: SystemDoma ...
- CLR 这些年有啥变化吗?
引言 首先想给初学者推荐下<CLR via C#>这本好书,做.Net开发的开发者应该都读一下.为避免广告之嫌,所以这里只提供豆瓣书评的链接. CLR 作为.Net 程序跨平台运行的载体, ...
随机推荐
- angular安装
安装时间:20190703安装环境:win10 1 安装Nodejs 1.1 下载地址:https://nodejs.org/en/ 1.2 下载完成之后双击安装,安装完成之后无需配置环境变量(安装的 ...
- Django生成PDF显示在网页上以及解决中文显示乱码的问题
项目地址:https://github.com/PythonerKK/django-generate-pdf/tree/master 这个demo实现了通过用户输入自己的个人信息生成一份简历pdf,来 ...
- kubernetes实战篇之helm填坑与基本命令
系列目录 其实前面安装部分我们已经分享一些互联网上其它网友分享的一些坑,本篇介绍helm的基本使用以及在使用过程中碰到的一些坑. 客户端版本和服务端版本不一致问题 有些朋友可能在使用helm init ...
- docker安装gitlab-runner
docker安装gitlab-runner docker pull gitlab/gitlab-runner:latest安装gitlab-runner 打开自己搭建的GitLab网站,点击顶栏的Sn ...
- CentOS 7 使用 HP 打印机
通常 hp 打印机应该是直接就能用的,但 centos 7 就一直遇到 printing job stopped 的情况.查看 http://localhost:631/printers/ 并没什么用 ...
- lower_bound 和 upper_bound 功能和用法
以前用这两个函数的时候,简单看了几句别人的博客,记住了大概,用的时候每用一次就弄混一次,相当难受,今天对照着这两个函数的源码和自己的尝试发现:其实这两个函数只能用于 "升序" 序列 ...
- Spring Dl解释
在UserService中提供一个get/set的name方法,在beans.xml中通过property去注入 一个实现类的属性 name; 3.1 类路径获得配置文件 3.4 BeanFactor ...
- TPL DataFlow .Net 数据流组件,了解一下
回顾上文 作为单体程序,依赖的第三方服务虽不多,但是2C的程序还是有不少内容可讲: 作为一个常规互联网系统,无外乎就是接受请求.处理请求,输出响应. 由于业务渐渐增长,数据处理的过程会越来越复杂和冗长 ...
- 【POJ - 1426】Find The Multiple(dfs)
-->Find The Multiple 原文是英语,直接上中文了 Descriptions: 给定一个正整数n,请编写一个程序来寻找n的一个非零的倍数m,这个m应当在十进制表示时每一位上只包含 ...
- Redis复制流程:图解
一.新版复制PSYNC命令实现:复制实现总流程 (1)通过客户端向从服务器发送 slaveof <master_ip> <master_port>:此为异步执行,从服务器设置好 ...