Changeset 2880
- Timestamp:
- Nov 13, 2006, 9:20:19 PM (19 years ago)
- Location:
- trunk/kLdr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdr.h
r2879 r2880 36 36 #include <stddef.h> 37 37 #ifdef _MSC_VER 38 typedef signed char int8_t; 39 typedef unsigned char uint8_t; 40 typedef signed short int16_t; 41 typedef unsigned short uint16_t; 42 typedef signed int int32_t; 43 typedef unsigned int uint32_t; 44 typedef signed __int64 int64_t; 45 typedef unsigned __int64 uint64_t; 46 typedef int64_t intmax_t; 47 typedef uint64_t uintmax_t; 48 #define UINT32_C(c) (c##U) 38 typedef signed char int8_t; 39 typedef unsigned char uint8_t; 40 typedef signed short int16_t; 41 typedef unsigned short uint16_t; 42 typedef signed int int32_t; 43 typedef unsigned int uint32_t; 44 typedef signed __int64 int64_t; 45 typedef unsigned __int64 uint64_t; 46 typedef int64_t intmax_t; 47 typedef uint64_t uintmax_t; 48 # define UINT16_C(c) (c ## U) 49 # define UINT32_C(c) (c ## U) 50 # define UINT64_C(c) (c ## ULL) 49 51 #else 50 52 # include <stdint.h> … … 1073 1075 /** validation of the LX object table failed. */ 1074 1076 #define KLDR_ERR_LX_BAD_OBJECT_TABLE (KLDR_ERR_LX_BASE + 3) 1077 /** A bad page map entry was encountered. */ 1078 #define KLDR_ERR_LX_BAD_PAGE_MAP (KLDR_ERR_LX_BASE + 4) 1079 /** Bad iterdata (EXEPACK) data. */ 1080 #define KLDR_ERR_LX_BAD_ITERDATA (KLDR_ERR_LX_BASE + 5) 1081 /** Bad iterdata2 (EXEPACK2) data. */ 1082 #define KLDR_ERR_LX_BAD_ITERDATA2 (KLDR_ERR_LX_BASE + 6) 1075 1083 /** @} */ 1076 1084 1077 1085 /** End of the valid kLdr status codes. */ 1078 #define KLDR_ERR_END (KLDR_ERR_LX_BASE + 4)1086 #define KLDR_ERR_END (KLDR_ERR_LX_BASE + 7) 1079 1087 1080 1088 /** @} */ -
trunk/kLdr/kLdrHlp.h
r2867 r2880 73 73 /** memcpy */ 74 74 # define kLdrHlpMemCopy(a,b,c) __builtin_memcpy(a,b,c) 75 /** memmove */ 76 # define kLdrHlpMemMove(a,b,c) __builtin_memmove(a,b,c) 75 77 /** memset */ 76 78 # define kLdrHlpMemSet(a,b,c) __builtin_memset(a,b,c) … … 101 103 /** memcpy */ 102 104 # define kLdrHlpMemCopy(a,b,c) memcpy(a,b,c) 105 /** memmove */ 106 # define kLdrHlpMemMove_needed 103 107 /** memset */ 104 108 # define kLdrHlpMemSet(a,b,c) memset(a,b,c) … … 124 128 #ifdef kLdrHlpStrChr_needed 125 129 void *kLdrHlpMemChr(const void *pv, int ch, size_t cb); 130 #endif 131 #ifdef kLdrHlpStrChr_needed 132 void *kLdrHlpMemMove(void *pv1, const void *pv2, size_t cb); 126 133 #endif 127 134 int kLdrHlpMemIComp(const void *pv1, const void *pv2, size_t cb); -
trunk/kLdr/kLdrModLX.c
r2879 r2880 118 118 static int kldrModLXDoCreate(PKLDRRDR pRdr, off_t offNewHdr, PKLDRMODLX *ppModLX); 119 119 static int kldrModLXDoLoadBits(PKLDRMODLX pModLX, void *pvBits); 120 static int kldrModLXDoIterDataUnpacking(uint8_t *pbDst, const uint8_t *pbSrc, int cbSrc); 121 static int kldrModLXDoIterData2Unpacking(uint8_t *pbDst, const uint8_t *pbSrc, int cbSrc); 122 static void kLdrModLXMemCopyW(uint8_t *pbDst, const uint8_t *pbSrc, int cb); 120 123 static int kldrModLXDoProtect(PKLDRMODLX pModLX, void *pvBits, unsigned fUnprotectOrProtect); 121 124 static int kldrModLXDoCallDLL(PKLDRMODLX pModLX, unsigned uOp, uintptr_t uHandle); … … 720 723 static int kldrModLXDoLoadBits(PKLDRMODLX pModLX, void *pvBits) 721 724 { 722 //E32NOLOAD 723 724 return -1; 725 const PKLDRRDR pRdr = pModLX->pMod->pRdr; 726 uint8_t *pbTmpPage = NULL; 727 int rc = 0; 728 uint32_t i; 729 730 /* 731 * Iterate the segments. 732 */ 733 for (i = 0; i < pModLX->Hdr.e32_objcnt; i++) 734 { 735 const struct o32_obj * const pObj = &pModLX->paObjs[i]; 736 const uint32_t cPages = pModLX->pMod->aSegments[i].cbMapped / OBJPAGELEN; 737 uint32_t iPage; 738 uint8_t *pbPage = (uint8_t *)pvBits + (uintptr_t)pModLX->pMod->aSegments[i].RVA; 739 740 /* 741 * Iterate the page map pages. 742 */ 743 for (iPage = 0; !rc && iPage < pObj->o32_mapsize; iPage++, pbPage += OBJPAGELEN) 744 { 745 const struct o32_map *pMap = &pModLX->paPageMappings[iPage + pObj->o32_pagemap - 1]; 746 switch (pMap->o32_pageflags) 747 { 748 case VALID: 749 if (pMap->o32_pagesize == OBJPAGELEN) 750 rc = kLdrRdrRead(pRdr, pbPage, OBJPAGELEN, pMap->o32_pagedataoffset << pModLX->Hdr.e32_pageshift); 751 else if (pMap->o32_pagesize < OBJPAGELEN) 752 { 753 rc = kLdrRdrRead(pRdr, pbPage, pMap->o32_pagesize, pMap->o32_pagedataoffset << pModLX->Hdr.e32_pageshift); 754 kLdrHlpMemSet(pbPage + pMap->o32_pagesize, 0, OBJPAGELEN - pMap->o32_pagesize); 755 } 756 else 757 rc = KLDR_ERR_LX_BAD_PAGE_MAP; 758 break; 759 760 case ITERDATA: 761 case ITERDATA2: 762 /* make sure we've got a temp page .*/ 763 if (!pbTmpPage) 764 { 765 pbTmpPage = kldrHlpAlloc(OBJPAGELEN + 256); 766 if (!pbTmpPage) 767 break; 768 } 769 /* validate the size. */ 770 if (pMap->o32_pagesize > OBJPAGELEN + 252) 771 { 772 rc = KLDR_ERR_LX_BAD_PAGE_MAP; 773 break; 774 } 775 776 /* read it and ensure 4 extra zero bytes. */ 777 rc = kLdrRdrRead(pRdr, pbTmpPage, pMap->o32_pagesize, pMap->o32_pagedataoffset << pModLX->Hdr.e32_pageshift); 778 if (rc) 779 break; 780 kLdrHlpMemSet(pbTmpPage + pMap->o32_pagesize, 0, 4); 781 782 /* unpack it into the image page. */ 783 if (pMap->o32_pageflags == ITERDATA2) 784 rc = kldrModLXDoIterData2Unpacking(pbPage, pbTmpPage, pMap->o32_pagesize); 785 else 786 rc = kldrModLXDoIterDataUnpacking(pbPage, pbTmpPage, pMap->o32_pagesize); 787 break; 788 789 case INVALID: /* we're probably not dealing correctly with INVALID pages... */ 790 case ZEROED: 791 kLdrHlpMemSet(pbPage, 0, OBJPAGELEN); 792 break; 793 794 case RANGE: 795 KLDRMODLX_ASSERT(!"RANGE"); 796 default: 797 rc = KLDR_ERR_LX_BAD_PAGE_MAP; 798 break; 799 } 800 } 801 if (rc) 802 break; 803 804 /* 805 * Zero the remaining pages. 806 */ 807 if (iPage < cPages) 808 kLdrHlpMemSet(pbPage, 0, (cPages - iPage) * OBJPAGELEN); 809 } 810 811 if (pbTmpPage) 812 kldrHlpFree(pbTmpPage); 813 return rc; 814 } 815 816 817 /** 818 * Unpacks iterdata (aka EXEPACK). 819 * 820 * @returns 0 on success, non-zero kLdr status code on failure. 821 * @param pbDst Where to put the uncompressed data. (Assumes OBJPAGELEN size.) 822 * @param pbSrc The compressed source data. 823 * @param cbSrc The file size of the compressed data. The source buffer 824 * contains 4 additional zero bytes. 825 */ 826 static int kldrModLXDoIterDataUnpacking(uint8_t *pbDst, const uint8_t *pbSrc, int cbSrc) 827 { 828 const struct LX_Iter *pIter = (const struct LX_Iter *)pbSrc; 829 int cbDst = OBJPAGELEN; 830 831 /* Validate size of data. */ 832 if (cbSrc >= OBJPAGELEN - 2) 833 return KLDR_ERR_LX_BAD_ITERDATA; 834 835 /* 836 * Expand the page. 837 */ 838 while (cbSrc > 0 && pIter->LX_nIter) 839 { 840 if (pIter->LX_nBytes == 1) 841 { 842 /* 843 * Special case - one databyte. 844 */ 845 cbDst -= pIter->LX_nIter; 846 if (cbDst < 0) 847 return KLDR_ERR_LX_BAD_ITERDATA; 848 849 cbSrc -= 4 + 1; 850 if (cbSrc < -4) 851 return KLDR_ERR_LX_BAD_ITERDATA; 852 853 kLdrHlpMemSet(pbDst, pIter->LX_Iterdata, pIter->LX_nIter); 854 pbDst += pIter->LX_nIter; 855 pIter++; 856 } 857 else 858 { 859 /* 860 * General. 861 */ 862 int i; 863 864 cbDst -= pIter->LX_nIter * pIter->LX_nBytes; 865 if (cbDst < 0) 866 return KLDR_ERR_LX_BAD_ITERDATA; 867 868 cbSrc -= 4 + pIter->LX_nBytes; 869 if (cbSrc < -4) 870 return KLDR_ERR_LX_BAD_ITERDATA; 871 872 for (i = pIter->LX_nIter; i > 0; i--, pbDst += pIter->LX_nBytes) 873 memcpy(pbDst, &pIter->LX_Iterdata, pIter->LX_nBytes); 874 pIter = (struct LX_Iter *)((char*)pIter + 4 + pIter->LX_nBytes); 875 } 876 } 877 878 /* 879 * Zero remainder of the page. 880 */ 881 if (cbDst > 0) 882 kLdrHlpMemSet(pbDst, 0, cbDst); 883 884 return 0; 885 } 886 887 888 /** 889 * Unpacks iterdata (aka EXEPACK). 890 * 891 * @returns 0 on success, non-zero kLdr status code on failure. 892 * @param pbDst Where to put the uncompressed data. (Assumes OBJPAGELEN size.) 893 * @param pbSrc The compressed source data. 894 * @param cbSrc The file size of the compressed data. The source buffer 895 * contains 4 additional zero bytes. 896 */ 897 static int kldrModLXDoIterData2Unpacking(uint8_t *pbDst, const uint8_t *pbSrc, int cbSrc) 898 { 899 int cbDst = OBJPAGELEN; 900 901 while (cbSrc > 0) 902 { 903 /* 904 * Bit 0 and 1 is the encoding type. 905 */ 906 switch (*pbSrc & 0x03) 907 { 908 /* 909 * 910 * 0 1 2 3 4 5 6 7 911 * type | | 912 * ---------------- 913 * cb <cb bytes of data> 914 * 915 * Bits 2-7 is, if not zero, the length of an uncompressed run 916 * starting at the following byte. 917 * 918 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 919 * type | | | | | | 920 * ---------------- ---------------------- ----------------------- 921 * zero cb char to multiply 922 * 923 * If the bits are zero, the following two bytes describes a 1 byte interation 924 * run. First byte is count, second is the byte to copy. A count of zero is 925 * means end of data, and we simply stops. In that case the rest of the data 926 * should be zero. 927 */ 928 case 0: 929 { 930 if (*pbSrc) 931 { 932 const int cb = *pbSrc >> 2; 933 cbDst -= cb; 934 if (cbDst < 0) 935 return KLDR_ERR_LX_BAD_ITERDATA2; 936 cbSrc -= cb; 937 if (cbSrc < 0) 938 return KLDR_ERR_LX_BAD_ITERDATA2; 939 kLdrHlpMemCopy(pbDst, ++pbSrc, cb); 940 pbDst += cb; 941 pbSrc += cb; 942 } 943 else if (cbSrc < 2) 944 return KLDR_ERR_LX_BAD_ITERDATA2; 945 else 946 { 947 const int cb = pbSrc[1]; 948 if (!cb) 949 goto l_endloop; 950 cbDst -= cb; 951 if (cbDst < 0) 952 return KLDR_ERR_LX_BAD_ITERDATA2; 953 cbSrc -= 3; 954 if (cbSrc < 0) 955 return KLDR_ERR_LX_BAD_ITERDATA2; 956 memset(pbDst, pbSrc[2], cb); 957 pbDst += cb; 958 pbSrc += 3; 959 } 960 break; 961 } 962 963 964 /* 965 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 966 * type | | | | | | 967 * ---- ------- ------------------------- 968 * cb1 cb2 - 3 offset <cb1 bytes of data> 969 * 970 * Two bytes layed out as described above, followed by cb1 bytes of data to be copied. 971 * The cb2(+3) and offset describes an amount of data to be copied from the expanded 972 * data relative to the current position. The data copied as you would expect it to be. 973 */ 974 case 1: 975 { 976 cbSrc -= 2; 977 if (cbSrc < 0) 978 return KLDR_ERR_LX_BAD_ITERDATA2; 979 else 980 { 981 const unsigned off = ((unsigned)pbSrc[1] << 1) | (*pbSrc >> 7); 982 const int cb1 = (*pbSrc >> 2) & 3; 983 const int cb2 = ((*pbSrc >> 4) & 7) + 3; 984 985 pbSrc += 2; 986 cbSrc -= cb1; 987 if (cbSrc < 0) 988 return KLDR_ERR_LX_BAD_ITERDATA2; 989 cbDst -= cb1; 990 if (cbDst < 0) 991 return KLDR_ERR_LX_BAD_ITERDATA2; 992 kLdrHlpMemCopy(pbDst, pbSrc, cb1); 993 pbDst += cb1; 994 995 if (off > OBJPAGELEN - cbDst) 996 return KLDR_ERR_LX_BAD_ITERDATA2; 997 cbDst -= cb2; 998 if (cbDst < 0) 999 return KLDR_ERR_LX_BAD_ITERDATA2; 1000 kLdrHlpMemMove(pbDst, pbDst - off, cb2); 1001 pbDst += cb2; 1002 } 1003 break; 1004 } 1005 1006 1007 /* 1008 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1009 * type | | | | 1010 * ---- ---------------------------------- 1011 * cb-3 offset 1012 * 1013 * Two bytes layed out as described above. 1014 * The cb(+3) and offset describes an amount of data to be copied from the expanded 1015 * data relative to the current position. 1016 * 1017 * If offset == 1 the data is not copied as expected, but in the memcpyw manner. 1018 */ 1019 case 2: 1020 { 1021 cbSrc -= 2; 1022 if (cbSrc < 0) 1023 return KLDR_ERR_LX_BAD_ITERDATA2; 1024 else 1025 { 1026 const unsigned off = ((unsigned)pbSrc[2] << 4) | (*pbSrc >> 4); 1027 const int cb = ((*pbSrc >> 2) & 3) + 3; 1028 1029 pbSrc += 2; 1030 if (off > OBJPAGELEN - cbDst) 1031 return KLDR_ERR_LX_BAD_ITERDATA2; 1032 cbDst -= cb; 1033 if (cbDst < 0) 1034 return KLDR_ERR_LX_BAD_ITERDATA2; 1035 kLdrModLXMemCopyW(pbDst, pbDst - off, cb); 1036 pbDst += cb; 1037 } 1038 break; 1039 } 1040 1041 1042 /* 1043 * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1044 * type | | | | | | 1045 * ---------- ---------------- ---------------------------------- 1046 * cb1 cb2 offset <cb1 bytes of data> 1047 * 1048 * Three bytes layed out as described above, followed by cb1 bytes of data to be copied. 1049 * The cb2 and offset describes an amount of data to be copied from the expanded 1050 * data relative to the current position. 1051 * 1052 * If offset == 1 the data is not copied as expected, but in the memcpyw manner. 1053 */ 1054 case 3: 1055 { 1056 cbSrc -= 3; 1057 if (cbSrc < 0) 1058 return KLDR_ERR_LX_BAD_ITERDATA2; 1059 else 1060 { 1061 const int cb1 = (*pbSrc >> 2) & 0xf; 1062 const int cb2 = ((pbSrc[1] & 0xf) << 2) | (*pbSrc >> 6); 1063 const unsigned off = ((unsigned)pbSrc[2] << 4) | (pbSrc[1] >> 4); 1064 1065 pbSrc += 3; 1066 cbSrc -= cb1; 1067 if (cbSrc < 0) 1068 return KLDR_ERR_LX_BAD_ITERDATA2; 1069 cbDst -= cb1; 1070 if (cbDst < 0) 1071 return KLDR_ERR_LX_BAD_ITERDATA2; 1072 kLdrHlpMemCopy(pbDst, pbSrc, cb1); 1073 pbDst += cb1; 1074 1075 if (off > OBJPAGELEN - cbDst) 1076 return KLDR_ERR_LX_BAD_ITERDATA2; 1077 cbDst -= cb2; 1078 if (cbDst < 0) 1079 return KLDR_ERR_LX_BAD_ITERDATA2; 1080 kLdrModLXMemCopyW(pbDst, pbDst - off, cb2); 1081 pbDst += cb2; 1082 } 1083 break; 1084 } 1085 } /* type switch. */ 1086 } /* unpack loop */ 1087 1088 l_endloop: 1089 1090 1091 /* 1092 * Zero remainder of the page. 1093 */ 1094 if (cbDst > 0) 1095 kLdrHlpMemSet(pbDst, 0, cbDst); 1096 1097 return 0; 1098 } 1099 1100 1101 /** 1102 * Special memcpy employed by the iterdata2 algorithm. 1103 * 1104 * Emulate a 16-bit memcpy (copying 16-bit at a time) and the effects this 1105 * has if src is very close to the destination. 1106 * 1107 * @param pbDst Destination pointer. 1108 * @param pbSrc Source pointer. Will always be <= pbDst. 1109 * @param cb Amount of data to be copied. 1110 * @remark This assumes that unaligned word and dword access is fine. 1111 */ 1112 static void kLdrModLXMemCopyW(uint8_t *pbDst, const uint8_t *pbSrc, int cb) 1113 { 1114 switch (pbDst - pbSrc) 1115 { 1116 case 0: 1117 case 1: 1118 case 2: 1119 case 3: 1120 /* 16-bit copy (unaligned) */ 1121 if (cb & 1) 1122 *pbDst++ = *pbDst++; 1123 for (cb >>= 1; cb > 0; cb--, pbDst += 2, pbSrc += 2) 1124 *(uint16_t *)pbDst = *(const uint16_t *)pbSrc; 1125 break; 1126 1127 default: 1128 /* 32-bit copy (unaligned) */ 1129 if (cb & 1) 1130 *pbDst++ = *pbDst++; 1131 if (cb & 2) 1132 { 1133 *(uint16_t *)pbDst = *(const uint16_t *)pbSrc; 1134 pbDst += 2; 1135 pbSrc += 2; 1136 } 1137 for (cb >>= 2; cb > 0; cb--, pbDst += 4, pbSrc += 4) 1138 *(uint32_t *)pbDst = *(const uint32_t *)pbSrc; 1139 break; 1140 } 725 1141 } 726 1142
Note:
See TracChangeset
for help on using the changeset viewer.