rarvm.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. #include "rar.hpp"
  2. RarVM::RarVM()
  3. {
  4. Mem=NULL;
  5. }
  6. RarVM::~RarVM()
  7. {
  8. delete[] Mem;
  9. }
  10. void RarVM::Init()
  11. {
  12. if (Mem==NULL)
  13. Mem=new byte[VM_MEMSIZE+4];
  14. }
  15. void RarVM::Execute(VM_PreparedProgram *Prg)
  16. {
  17. memcpy(R,Prg->InitR,sizeof(Prg->InitR));
  18. Prg->FilteredData=NULL;
  19. if (Prg->Type!=VMSF_NONE)
  20. {
  21. bool Success=ExecuteStandardFilter(Prg->Type);
  22. uint BlockSize=Prg->InitR[4] & VM_MEMMASK;
  23. Prg->FilteredDataSize=BlockSize;
  24. if (Prg->Type==VMSF_DELTA || Prg->Type==VMSF_RGB || Prg->Type==VMSF_AUDIO)
  25. Prg->FilteredData=2*BlockSize>VM_MEMSIZE || !Success ? Mem:Mem+BlockSize;
  26. else
  27. Prg->FilteredData=Mem;
  28. }
  29. }
  30. void RarVM::Prepare(byte *Code,uint CodeSize,VM_PreparedProgram *Prg)
  31. {
  32. // Calculate the single byte XOR checksum to check validity of VM code.
  33. byte XorSum=0;
  34. for (uint I=1;I<CodeSize;I++)
  35. XorSum^=Code[I];
  36. if (XorSum!=Code[0])
  37. return;
  38. struct StandardFilters
  39. {
  40. uint Length;
  41. uint CRC;
  42. VM_StandardFilters Type;
  43. } static StdList[]={
  44. 53, 0xad576887, VMSF_E8,
  45. 57, 0x3cd7e57e, VMSF_E8E9,
  46. 120, 0x3769893f, VMSF_ITANIUM,
  47. 29, 0x0e06077d, VMSF_DELTA,
  48. 149, 0x1c2c5dc8, VMSF_RGB,
  49. 216, 0xbc85e701, VMSF_AUDIO
  50. };
  51. uint CodeCRC=CRC32(0xffffffff,Code,CodeSize)^0xffffffff;
  52. for (uint I=0;I<ASIZE(StdList);I++)
  53. if (StdList[I].CRC==CodeCRC && StdList[I].Length==CodeSize)
  54. {
  55. Prg->Type=StdList[I].Type;
  56. break;
  57. }
  58. }
  59. uint RarVM::ReadData(BitInput &Inp)
  60. {
  61. uint Data=Inp.fgetbits();
  62. switch(Data&0xc000)
  63. {
  64. case 0:
  65. Inp.faddbits(6);
  66. return (Data>>10)&0xf;
  67. case 0x4000:
  68. if ((Data&0x3c00)==0)
  69. {
  70. Data=0xffffff00|((Data>>2)&0xff);
  71. Inp.faddbits(14);
  72. }
  73. else
  74. {
  75. Data=(Data>>6)&0xff;
  76. Inp.faddbits(10);
  77. }
  78. return Data;
  79. case 0x8000:
  80. Inp.faddbits(2);
  81. Data=Inp.fgetbits();
  82. Inp.faddbits(16);
  83. return Data;
  84. default:
  85. Inp.faddbits(2);
  86. Data=(Inp.fgetbits()<<16);
  87. Inp.faddbits(16);
  88. Data|=Inp.fgetbits();
  89. Inp.faddbits(16);
  90. return Data;
  91. }
  92. }
  93. void RarVM::SetMemory(size_t Pos,byte *Data,size_t DataSize)
  94. {
  95. if (Pos<VM_MEMSIZE && Data!=Mem+Pos)
  96. {
  97. // We can have NULL Data for invalid filters with DataSize==0. While most
  98. // sensible memmove implementations do not care about data if size is 0,
  99. // let's follow the standard and check the size first.
  100. size_t CopySize=Min(DataSize,VM_MEMSIZE-Pos);
  101. if (CopySize!=0)
  102. memmove(Mem+Pos,Data,CopySize);
  103. }
  104. }
  105. bool RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType)
  106. {
  107. switch(FilterType)
  108. {
  109. case VMSF_E8:
  110. case VMSF_E8E9:
  111. {
  112. byte *Data=Mem;
  113. uint DataSize=R[4],FileOffset=R[6];
  114. if (DataSize>VM_MEMSIZE || DataSize<4)
  115. return false;
  116. const uint FileSize=0x1000000;
  117. byte CmpByte2=FilterType==VMSF_E8E9 ? 0xe9:0xe8;
  118. for (uint CurPos=0;CurPos<DataSize-4;)
  119. {
  120. byte CurByte=*(Data++);
  121. CurPos++;
  122. if (CurByte==0xe8 || CurByte==CmpByte2)
  123. {
  124. uint Offset=CurPos+FileOffset;
  125. uint Addr=RawGet4(Data);
  126. // We check 0x80000000 bit instead of '< 0' comparison
  127. // not assuming int32 presence or uint size and endianness.
  128. if ((Addr & 0x80000000)!=0) // Addr<0
  129. {
  130. if (((Addr+Offset) & 0x80000000)==0) // Addr+Offset>=0
  131. RawPut4(Addr+FileSize,Data);
  132. }
  133. else
  134. if (((Addr-FileSize) & 0x80000000)!=0) // Addr<FileSize
  135. RawPut4(Addr-Offset,Data);
  136. Data+=4;
  137. CurPos+=4;
  138. }
  139. }
  140. }
  141. break;
  142. case VMSF_ITANIUM:
  143. {
  144. byte *Data=Mem;
  145. uint DataSize=R[4],FileOffset=R[6];
  146. if (DataSize>VM_MEMSIZE || DataSize<21)
  147. return false;
  148. uint CurPos=0;
  149. FileOffset>>=4;
  150. while (CurPos<DataSize-21)
  151. {
  152. int Byte=(Data[0]&0x1f)-0x10;
  153. if (Byte>=0)
  154. {
  155. static byte Masks[16]={4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0};
  156. byte CmdMask=Masks[Byte];
  157. if (CmdMask!=0)
  158. for (uint I=0;I<=2;I++)
  159. if (CmdMask & (1<<I))
  160. {
  161. uint StartPos=I*41+5;
  162. uint OpType=FilterItanium_GetBits(Data,StartPos+37,4);
  163. if (OpType==5)
  164. {
  165. uint Offset=FilterItanium_GetBits(Data,StartPos+13,20);
  166. FilterItanium_SetBits(Data,(Offset-FileOffset)&0xfffff,StartPos+13,20);
  167. }
  168. }
  169. }
  170. Data+=16;
  171. CurPos+=16;
  172. FileOffset++;
  173. }
  174. }
  175. break;
  176. case VMSF_DELTA:
  177. {
  178. uint DataSize=R[4],Channels=R[0],SrcPos=0,Border=DataSize*2;
  179. if (DataSize>VM_MEMSIZE/2 || Channels>MAX3_UNPACK_CHANNELS || Channels==0)
  180. return false;
  181. // Bytes from same channels are grouped to continual data blocks,
  182. // so we need to place them back to their interleaving positions.
  183. for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
  184. {
  185. byte PrevByte=0;
  186. for (uint DestPos=DataSize+CurChannel;DestPos<Border;DestPos+=Channels)
  187. Mem[DestPos]=(PrevByte-=Mem[SrcPos++]);
  188. }
  189. }
  190. break;
  191. case VMSF_RGB:
  192. {
  193. uint DataSize=R[4],Width=R[0]-3,PosR=R[1];
  194. if (DataSize>VM_MEMSIZE/2 || DataSize<3 || Width>DataSize || PosR>2)
  195. return false;
  196. byte *SrcData=Mem,*DestData=SrcData+DataSize;
  197. const uint Channels=3;
  198. for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
  199. {
  200. uint PrevByte=0;
  201. for (uint I=CurChannel;I<DataSize;I+=Channels)
  202. {
  203. uint Predicted;
  204. if (I>=Width+3)
  205. {
  206. byte *UpperData=DestData+I-Width;
  207. uint UpperByte=*UpperData;
  208. uint UpperLeftByte=*(UpperData-3);
  209. Predicted=PrevByte+UpperByte-UpperLeftByte;
  210. int pa=abs((int)(Predicted-PrevByte));
  211. int pb=abs((int)(Predicted-UpperByte));
  212. int pc=abs((int)(Predicted-UpperLeftByte));
  213. if (pa<=pb && pa<=pc)
  214. Predicted=PrevByte;
  215. else
  216. if (pb<=pc)
  217. Predicted=UpperByte;
  218. else
  219. Predicted=UpperLeftByte;
  220. }
  221. else
  222. Predicted=PrevByte;
  223. DestData[I]=PrevByte=(byte)(Predicted-*(SrcData++));
  224. }
  225. }
  226. for (uint I=PosR,Border=DataSize-2;I<Border;I+=3)
  227. {
  228. byte G=DestData[I+1];
  229. DestData[I]+=G;
  230. DestData[I+2]+=G;
  231. }
  232. }
  233. break;
  234. case VMSF_AUDIO:
  235. {
  236. uint DataSize=R[4],Channels=R[0];
  237. byte *SrcData=Mem,*DestData=SrcData+DataSize;
  238. // In fact, audio channels never exceed 4.
  239. if (DataSize>VM_MEMSIZE/2 || Channels>128 || Channels==0)
  240. return false;
  241. for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
  242. {
  243. uint PrevByte=0,PrevDelta=0,Dif[7];
  244. int D1=0,D2=0,D3;
  245. int K1=0,K2=0,K3=0;
  246. memset(Dif,0,sizeof(Dif));
  247. for (uint I=CurChannel,ByteCount=0;I<DataSize;I+=Channels,ByteCount++)
  248. {
  249. D3=D2;
  250. D2=PrevDelta-D1;
  251. D1=PrevDelta;
  252. uint Predicted=8*PrevByte+K1*D1+K2*D2+K3*D3;
  253. Predicted=(Predicted>>3) & 0xff;
  254. uint CurByte=*(SrcData++);
  255. Predicted-=CurByte;
  256. DestData[I]=Predicted;
  257. PrevDelta=(signed char)(Predicted-PrevByte);
  258. PrevByte=Predicted;
  259. int D=(signed char)CurByte;
  260. // Left shift of negative value is undefined behavior in C++,
  261. // so we cast it to unsigned to follow the standard.
  262. D=(uint)D<<3;
  263. Dif[0]+=abs(D);
  264. Dif[1]+=abs(D-D1);
  265. Dif[2]+=abs(D+D1);
  266. Dif[3]+=abs(D-D2);
  267. Dif[4]+=abs(D+D2);
  268. Dif[5]+=abs(D-D3);
  269. Dif[6]+=abs(D+D3);
  270. if ((ByteCount & 0x1f)==0)
  271. {
  272. uint MinDif=Dif[0],NumMinDif=0;
  273. Dif[0]=0;
  274. for (uint J=1;J<ASIZE(Dif);J++)
  275. {
  276. if (Dif[J]<MinDif)
  277. {
  278. MinDif=Dif[J];
  279. NumMinDif=J;
  280. }
  281. Dif[J]=0;
  282. }
  283. switch(NumMinDif)
  284. {
  285. case 1: if (K1>=-16) K1--; break;
  286. case 2: if (K1 < 16) K1++; break;
  287. case 3: if (K2>=-16) K2--; break;
  288. case 4: if (K2 < 16) K2++; break;
  289. case 5: if (K3>=-16) K3--; break;
  290. case 6: if (K3 < 16) K3++; break;
  291. }
  292. }
  293. }
  294. }
  295. }
  296. break;
  297. }
  298. return true;
  299. }
  300. uint RarVM::FilterItanium_GetBits(byte *Data,uint BitPos,uint BitCount)
  301. {
  302. uint InAddr=BitPos/8;
  303. uint InBit=BitPos&7;
  304. uint BitField=(uint)Data[InAddr++];
  305. BitField|=(uint)Data[InAddr++] << 8;
  306. BitField|=(uint)Data[InAddr++] << 16;
  307. BitField|=(uint)Data[InAddr] << 24;
  308. BitField >>= InBit;
  309. return BitField & (0xffffffff>>(32-BitCount));
  310. }
  311. void RarVM::FilterItanium_SetBits(byte *Data,uint BitField,uint BitPos,uint BitCount)
  312. {
  313. uint InAddr=BitPos/8;
  314. uint InBit=BitPos&7;
  315. uint AndMask=0xffffffff>>(32-BitCount);
  316. AndMask=~(AndMask<<InBit);
  317. BitField<<=InBit;
  318. for (uint I=0;I<4;I++)
  319. {
  320. Data[InAddr+I]&=AndMask;
  321. Data[InAddr+I]|=BitField;
  322. AndMask=(AndMask>>8)|0xff000000;
  323. BitField>>=8;
  324. }
  325. }