RarVM.cs 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. using System;
  2. using System.Collections.Generic;
  3. using SharpCompress.Converters;
  4. namespace SharpCompress.Compressors.Rar.VM
  5. {
  6. internal class RarVM : BitInput
  7. {
  8. //private void InitBlock()
  9. //{
  10. // Mem.set_Renamed(offset + 0, Byte.valueOf((sbyte) (value_Renamed & 0xff)));
  11. // Mem.set_Renamed(offset + 1, Byte.valueOf((sbyte) ((Utility.URShift(value_Renamed, 8)) & 0xff)));
  12. // Mem.set_Renamed(offset + 2, Byte.valueOf((sbyte) ((Utility.URShift(value_Renamed, 16)) & 0xff)));
  13. // Mem.set_Renamed(offset + 3, Byte.valueOf((sbyte) ((Utility.URShift(value_Renamed, 24)) & 0xff)));
  14. //}
  15. internal byte[] Mem { get; private set; }
  16. public const int VM_MEMSIZE = 0x40000;
  17. //UPGRADE_NOTE: Final was removed from the declaration of 'VM_MEMMASK '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  18. public static readonly int VM_MEMMASK = (VM_MEMSIZE - 1);
  19. public const int VM_GLOBALMEMADDR = 0x3C000;
  20. public const int VM_GLOBALMEMSIZE = 0x2000;
  21. public const int VM_FIXEDGLOBALSIZE = 64;
  22. private const int regCount = 8;
  23. private const long UINT_MASK = 0xffffFFFF; //((long)2*(long)Integer.MAX_VALUE);
  24. private readonly int[] R = new int[regCount];
  25. private VMFlags flags;
  26. private int maxOpCount = 25000000;
  27. private int codeSize;
  28. private int IP;
  29. internal RarVM()
  30. {
  31. //InitBlock();
  32. Mem = null;
  33. }
  34. internal void init()
  35. {
  36. if (Mem == null)
  37. {
  38. Mem = new byte[VM_MEMSIZE + 4];
  39. }
  40. }
  41. private bool IsVMMem(byte[] mem)
  42. {
  43. return Mem == mem;
  44. }
  45. private int GetValue(bool byteMode, byte[] mem, int offset)
  46. {
  47. if (byteMode)
  48. {
  49. if (IsVMMem(mem))
  50. {
  51. return (mem[offset]);
  52. }
  53. return (mem[offset] & 0xff);
  54. }
  55. if (IsVMMem(mem))
  56. {
  57. return DataConverter.LittleEndian.GetInt32(mem, offset);
  58. }
  59. return DataConverter.BigEndian.GetInt32(mem, offset);
  60. }
  61. private void SetValue(bool byteMode, byte[] mem, int offset, int value)
  62. {
  63. if (byteMode)
  64. {
  65. if (IsVMMem(mem))
  66. {
  67. mem[offset] = (byte)value;
  68. }
  69. else
  70. {
  71. mem[offset] = (byte)((mem[offset] & 0x00) | (byte)(value & 0xff));
  72. }
  73. }
  74. else
  75. {
  76. if (IsVMMem(mem))
  77. {
  78. DataConverter.LittleEndian.PutBytes(mem, offset, value);
  79. }
  80. else
  81. {
  82. DataConverter.BigEndian.PutBytes(mem, offset, value);
  83. }
  84. }
  85. // #define SET_VALUE(ByteMode,Addr,Value) SetValue(ByteMode,(uint
  86. // *)Addr,Value)
  87. }
  88. internal void SetLowEndianValue(List<byte> mem, int offset, int value)
  89. {
  90. mem[offset + 0] = (byte)(value & 0xff);
  91. mem[offset + 1] = (byte)(Utility.URShift(value, 8) & 0xff);
  92. mem[offset + 2] = (byte)(Utility.URShift(value, 16) & 0xff);
  93. mem[offset + 3] = (byte)(Utility.URShift(value, 24) & 0xff);
  94. }
  95. private int GetOperand(VMPreparedOperand cmdOp)
  96. {
  97. int ret = 0;
  98. if (cmdOp.Type == VMOpType.VM_OPREGMEM)
  99. {
  100. int pos = (cmdOp.Offset + cmdOp.Base) & VM_MEMMASK;
  101. ret = DataConverter.LittleEndian.GetInt32(Mem, pos);
  102. }
  103. else
  104. {
  105. int pos = cmdOp.Offset;
  106. ret = DataConverter.LittleEndian.GetInt32(Mem, pos);
  107. }
  108. return ret;
  109. }
  110. public void execute(VMPreparedProgram prg)
  111. {
  112. for (int i = 0; i < prg.InitR.Length; i++)
  113. // memcpy(R,Prg->InitR,sizeof(Prg->InitR));
  114. {
  115. R[i] = prg.InitR[i];
  116. }
  117. long globalSize = Math.Min(prg.GlobalData.Count, VM_GLOBALMEMSIZE) & 0xffFFffFF;
  118. if (globalSize != 0)
  119. {
  120. for (int i = 0; i < globalSize; i++)
  121. // memcpy(Mem+VM_GLOBALMEMADDR,&Prg->GlobalData[0],GlobalSize);
  122. {
  123. Mem[VM_GLOBALMEMADDR + i] = prg.GlobalData[i];
  124. }
  125. }
  126. long staticSize = Math.Min(prg.StaticData.Count, VM_GLOBALMEMSIZE - globalSize) & 0xffFFffFF;
  127. if (staticSize != 0)
  128. {
  129. for (int i = 0; i < staticSize; i++)
  130. // memcpy(Mem+VM_GLOBALMEMADDR+GlobalSize,&Prg->StaticData[0],StaticSize);
  131. {
  132. Mem[VM_GLOBALMEMADDR + (int)globalSize + i] = prg.StaticData[i];
  133. }
  134. }
  135. R[7] = VM_MEMSIZE;
  136. flags = 0;
  137. //UPGRADE_NOTE: There is an untranslated Statement. Please refer to original code. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1153'"
  138. List<VMPreparedCommand> preparedCode = prg.AltCommands.Count != 0
  139. ? prg
  140. .AltCommands
  141. : prg.Commands;
  142. if (!ExecuteCode(preparedCode, prg.CommandCount))
  143. {
  144. preparedCode[0].OpCode = VMCommands.VM_RET;
  145. }
  146. int newBlockPos = GetValue(false, Mem, VM_GLOBALMEMADDR + 0x20) & VM_MEMMASK;
  147. int newBlockSize = GetValue(false, Mem, VM_GLOBALMEMADDR + 0x1c) & VM_MEMMASK;
  148. if ((newBlockPos + newBlockSize) >= VM_MEMSIZE)
  149. {
  150. newBlockPos = 0;
  151. newBlockSize = 0;
  152. }
  153. prg.FilteredDataOffset = newBlockPos;
  154. prg.FilteredDataSize = newBlockSize;
  155. prg.GlobalData.Clear();
  156. int dataSize = Math.Min(GetValue(false, Mem, VM_GLOBALMEMADDR + 0x30), VM_GLOBALMEMSIZE - VM_FIXEDGLOBALSIZE);
  157. if (dataSize != 0)
  158. {
  159. //prg.GlobalData.Clear();
  160. // ->GlobalData.Add(dataSize+VM_FIXEDGLOBALSIZE);
  161. prg.GlobalData.SetSize(dataSize + VM_FIXEDGLOBALSIZE);
  162. for (int i = 0; i < dataSize + VM_FIXEDGLOBALSIZE; i++)
  163. // memcpy(&Prg->GlobalData[0],&Mem[VM_GLOBALMEMADDR],DataSize+VM_FIXEDGLOBALSIZE);
  164. {
  165. prg.GlobalData[i] = Mem[VM_GLOBALMEMADDR + i];
  166. }
  167. }
  168. }
  169. private bool setIP(int ip)
  170. {
  171. if ((ip) >= codeSize)
  172. {
  173. return (true);
  174. }
  175. if (--maxOpCount <= 0)
  176. {
  177. return (false);
  178. }
  179. IP = ip;
  180. return true;
  181. }
  182. private bool ExecuteCode(List<VMPreparedCommand> preparedCode,
  183. int cmdCount)
  184. {
  185. maxOpCount = 25000000;
  186. codeSize = cmdCount;
  187. IP = 0;
  188. while (true)
  189. {
  190. VMPreparedCommand cmd = preparedCode[IP];
  191. int op1 = GetOperand(cmd.Op1);
  192. int op2 = GetOperand(cmd.Op2);
  193. switch (cmd.OpCode)
  194. {
  195. case VMCommands.VM_MOV:
  196. SetValue(cmd.IsByteMode, Mem, op1, GetValue(cmd.IsByteMode, Mem, op2));
  197. // SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2));
  198. break;
  199. case VMCommands.VM_MOVB:
  200. SetValue(true, Mem, op1, GetValue(true, Mem, op2));
  201. break;
  202. case VMCommands.VM_MOVD:
  203. SetValue(false, Mem, op1, GetValue(false, Mem, op2));
  204. break;
  205. case VMCommands.VM_CMP:
  206. {
  207. VMFlags value1 = (VMFlags)GetValue(cmd.IsByteMode, Mem, op1);
  208. VMFlags result = value1 - GetValue(cmd.IsByteMode, Mem, op2);
  209. if (result == 0)
  210. {
  211. flags = VMFlags.VM_FZ;
  212. }
  213. else
  214. {
  215. flags = (VMFlags)((result > value1) ? 1 : 0 | (int)(result & VMFlags.VM_FS));
  216. }
  217. }
  218. break;
  219. case VMCommands.VM_CMPB:
  220. {
  221. VMFlags value1 = (VMFlags)GetValue(true, Mem, op1);
  222. VMFlags result = value1 - GetValue(true, Mem, op2);
  223. if (result == 0)
  224. {
  225. flags = VMFlags.VM_FZ;
  226. }
  227. else
  228. {
  229. flags = (VMFlags)((result > value1) ? 1 : 0 | (int)(result & VMFlags.VM_FS));
  230. }
  231. }
  232. break;
  233. case VMCommands.VM_CMPD:
  234. {
  235. VMFlags value1 = (VMFlags)GetValue(false, Mem, op1);
  236. VMFlags result = value1 - GetValue(false, Mem, op2);
  237. if (result == 0)
  238. {
  239. flags = VMFlags.VM_FZ;
  240. }
  241. else
  242. {
  243. flags = (VMFlags)((result > value1) ? 1 : 0 | (int)(result & VMFlags.VM_FS));
  244. }
  245. }
  246. break;
  247. case VMCommands.VM_ADD:
  248. {
  249. int value1 = GetValue(cmd.IsByteMode, Mem, op1);
  250. int result =
  251. (int)
  252. (((value1 + (long)GetValue(cmd.IsByteMode, Mem, op2))) &
  253. unchecked((int)0xffffffff));
  254. if (cmd.IsByteMode)
  255. {
  256. result &= 0xff;
  257. flags =
  258. (VMFlags)
  259. ((result < value1)
  260. ? 1
  261. : 0 |
  262. (result == 0
  263. ? (int)VMFlags.VM_FZ
  264. : (((result & 0x80) != 0) ? (int)VMFlags.VM_FS : 0)));
  265. // Flags=(Result<Value1)|(Result==0 ? VM_FZ:((Result&0x80) ?
  266. // VM_FS:0));
  267. }
  268. else
  269. {
  270. flags =
  271. (VMFlags)
  272. ((result < value1)
  273. ? 1
  274. : 0 | (result == 0 ? (int)VMFlags.VM_FZ : (result & (int)VMFlags.VM_FS)));
  275. }
  276. SetValue(cmd.IsByteMode, Mem, op1, result);
  277. }
  278. break;
  279. case VMCommands.VM_ADDB:
  280. SetValue(true, Mem, op1,
  281. (int)
  282. (GetValue(true, Mem, op1) & 0xFFffFFff + GetValue(true, Mem, op2) &
  283. unchecked((int)0xFFffFFff)));
  284. break;
  285. case VMCommands.VM_ADDD:
  286. SetValue(false, Mem, op1,
  287. (int)
  288. (GetValue(false, Mem, op1) & 0xFFffFFff + GetValue(false, Mem, op2) &
  289. unchecked((int)0xFFffFFff)));
  290. break;
  291. case VMCommands.VM_SUB:
  292. {
  293. int value1 = GetValue(cmd.IsByteMode, Mem, op1);
  294. int result =
  295. (int)
  296. (value1 & 0xffFFffFF - GetValue(cmd.IsByteMode, Mem, op2) &
  297. unchecked((int)0xFFffFFff));
  298. flags =
  299. (VMFlags)
  300. ((result == 0)
  301. ? (int)VMFlags.VM_FZ
  302. : ((result > value1) ? 1 : 0 | (result & (int)VMFlags.VM_FS)));
  303. SetValue(cmd.IsByteMode, Mem, op1, result); // (Cmd->ByteMode,Op1,Result);
  304. }
  305. break;
  306. case VMCommands.VM_SUBB:
  307. SetValue(true, Mem, op1,
  308. (int)
  309. (GetValue(true, Mem, op1) & 0xFFffFFff - GetValue(true, Mem, op2) &
  310. unchecked((int)0xFFffFFff)));
  311. break;
  312. case VMCommands.VM_SUBD:
  313. SetValue(false, Mem, op1,
  314. (int)
  315. (GetValue(false, Mem, op1) & 0xFFffFFff - GetValue(false, Mem, op2) &
  316. unchecked((int)0xFFffFFff)));
  317. break;
  318. case VMCommands.VM_JZ:
  319. if ((flags & VMFlags.VM_FZ) != 0)
  320. {
  321. setIP(GetValue(false, Mem, op1));
  322. continue;
  323. }
  324. break;
  325. case VMCommands.VM_JNZ:
  326. if ((flags & VMFlags.VM_FZ) == 0)
  327. {
  328. setIP(GetValue(false, Mem, op1));
  329. continue;
  330. }
  331. break;
  332. case VMCommands.VM_INC:
  333. {
  334. int result = (int)(GetValue(cmd.IsByteMode, Mem, op1) & 0xFFffFFffL + 1L);
  335. if (cmd.IsByteMode)
  336. {
  337. result &= 0xff;
  338. }
  339. SetValue(cmd.IsByteMode, Mem, op1, result);
  340. flags = (VMFlags)(result == 0 ? (int)VMFlags.VM_FZ : result & (int)VMFlags.VM_FS);
  341. }
  342. break;
  343. case VMCommands.VM_INCB:
  344. SetValue(true, Mem, op1, (int)(GetValue(true, Mem, op1) & 0xFFffFFffL + 1L));
  345. break;
  346. case VMCommands.VM_INCD:
  347. SetValue(false, Mem, op1, (int)(GetValue(false, Mem, op1) & 0xFFffFFffL + 1L));
  348. break;
  349. case VMCommands.VM_DEC:
  350. {
  351. int result = (int)(GetValue(cmd.IsByteMode, Mem, op1) & 0xFFffFFff - 1);
  352. SetValue(cmd.IsByteMode, Mem, op1, result);
  353. flags = (VMFlags)(result == 0 ? (int)VMFlags.VM_FZ : result & (int)VMFlags.VM_FS);
  354. }
  355. break;
  356. case VMCommands.VM_DECB:
  357. SetValue(true, Mem, op1, (int)(GetValue(true, Mem, op1) & 0xFFffFFff - 1));
  358. break;
  359. case VMCommands.VM_DECD:
  360. SetValue(false, Mem, op1, (int)(GetValue(false, Mem, op1) & 0xFFffFFff - 1));
  361. break;
  362. case VMCommands.VM_JMP:
  363. setIP(GetValue(false, Mem, op1));
  364. continue;
  365. case VMCommands.VM_XOR:
  366. {
  367. int result = GetValue(cmd.IsByteMode, Mem, op1) ^ GetValue(cmd.IsByteMode, Mem, op2);
  368. flags = (VMFlags)(result == 0 ? (int)VMFlags.VM_FZ : result & (int)VMFlags.VM_FS);
  369. SetValue(cmd.IsByteMode, Mem, op1, result);
  370. }
  371. break;
  372. case VMCommands.VM_AND:
  373. {
  374. int result = GetValue(cmd.IsByteMode, Mem, op1) & GetValue(cmd.IsByteMode, Mem, op2);
  375. flags = (VMFlags)(result == 0 ? (int)VMFlags.VM_FZ : result & (int)VMFlags.VM_FS);
  376. SetValue(cmd.IsByteMode, Mem, op1, result);
  377. }
  378. break;
  379. case VMCommands.VM_OR:
  380. {
  381. int result = GetValue(cmd.IsByteMode, Mem, op1) | GetValue(cmd.IsByteMode, Mem, op2);
  382. flags = (VMFlags)(result == 0 ? (int)VMFlags.VM_FZ : result & (int)VMFlags.VM_FS);
  383. SetValue(cmd.IsByteMode, Mem, op1, result);
  384. }
  385. break;
  386. case VMCommands.VM_TEST:
  387. {
  388. int result = GetValue(cmd.IsByteMode, Mem, op1) & GetValue(cmd.IsByteMode, Mem, op2);
  389. flags = (VMFlags)(result == 0 ? (int)VMFlags.VM_FZ : result & (int)VMFlags.VM_FS);
  390. }
  391. break;
  392. case VMCommands.VM_JS:
  393. if ((flags & VMFlags.VM_FS) != 0)
  394. {
  395. setIP(GetValue(false, Mem, op1));
  396. continue;
  397. }
  398. break;
  399. case VMCommands.VM_JNS:
  400. if ((flags & VMFlags.VM_FS) == 0)
  401. {
  402. setIP(GetValue(false, Mem, op1));
  403. continue;
  404. }
  405. break;
  406. case VMCommands.VM_JB:
  407. if ((flags & VMFlags.VM_FC) != 0)
  408. {
  409. setIP(GetValue(false, Mem, op1));
  410. continue;
  411. }
  412. break;
  413. case VMCommands.VM_JBE:
  414. if ((flags & (VMFlags.VM_FC | VMFlags.VM_FZ)) != 0)
  415. {
  416. setIP(GetValue(false, Mem, op1));
  417. continue;
  418. }
  419. break;
  420. case VMCommands.VM_JA:
  421. if ((flags & (VMFlags.VM_FC | VMFlags.VM_FZ)) == 0)
  422. {
  423. setIP(GetValue(false, Mem, op1));
  424. continue;
  425. }
  426. break;
  427. case VMCommands.VM_JAE:
  428. if ((flags & VMFlags.VM_FC) == 0)
  429. {
  430. setIP(GetValue(false, Mem, op1));
  431. continue;
  432. }
  433. break;
  434. case VMCommands.VM_PUSH:
  435. R[7] -= 4;
  436. SetValue(false, Mem, R[7] & VM_MEMMASK, GetValue(false, Mem, op1));
  437. break;
  438. case VMCommands.VM_POP:
  439. SetValue(false, Mem, op1, GetValue(false, Mem, R[7] & VM_MEMMASK));
  440. R[7] += 4;
  441. break;
  442. case VMCommands.VM_CALL:
  443. R[7] -= 4;
  444. SetValue(false, Mem, R[7] & VM_MEMMASK, IP + 1);
  445. setIP(GetValue(false, Mem, op1));
  446. continue;
  447. case VMCommands.VM_NOT:
  448. SetValue(cmd.IsByteMode, Mem, op1, ~GetValue(cmd.IsByteMode, Mem, op1));
  449. break;
  450. case VMCommands.VM_SHL:
  451. {
  452. int value1 = GetValue(cmd.IsByteMode, Mem, op1);
  453. int value2 = GetValue(cmd.IsByteMode, Mem, op2);
  454. int result = value1 << value2;
  455. flags =
  456. (VMFlags)
  457. ((result == 0 ? (int)VMFlags.VM_FZ : (result & (int)VMFlags.VM_FS)) |
  458. (((value1 << (value2 - 1)) & unchecked((int)0x80000000)) != 0
  459. ? (int)VMFlags.VM_FC
  460. : 0));
  461. SetValue(cmd.IsByteMode, Mem, op1, result);
  462. }
  463. break;
  464. case VMCommands.VM_SHR:
  465. {
  466. int value1 = GetValue(cmd.IsByteMode, Mem, op1);
  467. int value2 = GetValue(cmd.IsByteMode, Mem, op2);
  468. int result = Utility.URShift(value1, value2);
  469. flags =
  470. (VMFlags)
  471. ((result == 0 ? (int)VMFlags.VM_FZ : (result & (int)VMFlags.VM_FS)) |
  472. ((Utility.URShift(value1, (value2 - 1))) & (int)VMFlags.VM_FC));
  473. SetValue(cmd.IsByteMode, Mem, op1, result);
  474. }
  475. break;
  476. case VMCommands.VM_SAR:
  477. {
  478. int value1 = GetValue(cmd.IsByteMode, Mem, op1);
  479. int value2 = GetValue(cmd.IsByteMode, Mem, op2);
  480. int result = value1 >> value2;
  481. flags =
  482. (VMFlags)
  483. ((result == 0 ? (int)VMFlags.VM_FZ : (result & (int)VMFlags.VM_FS)) |
  484. ((value1 >> (value2 - 1)) & (int)VMFlags.VM_FC));
  485. SetValue(cmd.IsByteMode, Mem, op1, result);
  486. }
  487. break;
  488. case VMCommands.VM_NEG:
  489. {
  490. int result = -GetValue(cmd.IsByteMode, Mem, op1);
  491. flags =
  492. (VMFlags)
  493. (result == 0
  494. ? (int)VMFlags.VM_FZ
  495. : (int)VMFlags.VM_FC | (result & (int)VMFlags.VM_FS));
  496. SetValue(cmd.IsByteMode, Mem, op1, result);
  497. }
  498. break;
  499. case VMCommands.VM_NEGB:
  500. SetValue(true, Mem, op1, -GetValue(true, Mem, op1));
  501. break;
  502. case VMCommands.VM_NEGD:
  503. SetValue(false, Mem, op1, -GetValue(false, Mem, op1));
  504. break;
  505. case VMCommands.VM_PUSHA:
  506. {
  507. for (int i = 0, SP = R[7] - 4; i < regCount; i++, SP -= 4)
  508. {
  509. SetValue(false, Mem, SP & VM_MEMMASK, R[i]);
  510. }
  511. R[7] -= regCount * 4;
  512. }
  513. break;
  514. case VMCommands.VM_POPA:
  515. {
  516. for (int i = 0, SP = R[7]; i < regCount; i++, SP += 4)
  517. {
  518. R[7 - i] = GetValue(false, Mem, SP & VM_MEMMASK);
  519. }
  520. }
  521. break;
  522. case VMCommands.VM_PUSHF:
  523. R[7] -= 4;
  524. SetValue(false, Mem, R[7] & VM_MEMMASK, (int)flags);
  525. break;
  526. case VMCommands.VM_POPF:
  527. flags = (VMFlags)GetValue(false, Mem, R[7] & VM_MEMMASK);
  528. R[7] += 4;
  529. break;
  530. case VMCommands.VM_MOVZX:
  531. SetValue(false, Mem, op1, GetValue(true, Mem, op2));
  532. break;
  533. case VMCommands.VM_MOVSX:
  534. SetValue(false, Mem, op1, (byte)GetValue(true, Mem, op2));
  535. break;
  536. case VMCommands.VM_XCHG:
  537. {
  538. int value1 = GetValue(cmd.IsByteMode, Mem, op1);
  539. SetValue(cmd.IsByteMode, Mem, op1, GetValue(cmd.IsByteMode, Mem, op2));
  540. SetValue(cmd.IsByteMode, Mem, op2, value1);
  541. }
  542. break;
  543. case VMCommands.VM_MUL:
  544. {
  545. int result =
  546. (int)
  547. ((GetValue(cmd.IsByteMode, Mem, op1) &
  548. 0xFFffFFff * GetValue(cmd.IsByteMode, Mem, op2) & unchecked((int)0xFFffFFff)) &
  549. unchecked((int)0xFFffFFff));
  550. SetValue(cmd.IsByteMode, Mem, op1, result);
  551. }
  552. break;
  553. case VMCommands.VM_DIV:
  554. {
  555. int divider = GetValue(cmd.IsByteMode, Mem, op2);
  556. if (divider != 0)
  557. {
  558. int result = GetValue(cmd.IsByteMode, Mem, op1) / divider;
  559. SetValue(cmd.IsByteMode, Mem, op1, result);
  560. }
  561. }
  562. break;
  563. case VMCommands.VM_ADC:
  564. {
  565. int value1 = GetValue(cmd.IsByteMode, Mem, op1);
  566. int FC = (int)(flags & VMFlags.VM_FC);
  567. int result =
  568. (int)
  569. (value1 & 0xFFffFFff + GetValue(cmd.IsByteMode, Mem, op2) &
  570. 0xFFffFFff + FC & unchecked((int)0xFFffFFff));
  571. if (cmd.IsByteMode)
  572. {
  573. result &= 0xff;
  574. }
  575. flags =
  576. (VMFlags)
  577. ((result < value1 || result == value1 && FC != 0)
  578. ? 1
  579. : 0 | (result == 0 ? (int)VMFlags.VM_FZ : (result & (int)VMFlags.VM_FS)));
  580. SetValue(cmd.IsByteMode, Mem, op1, result);
  581. }
  582. break;
  583. case VMCommands.VM_SBB:
  584. {
  585. int value1 = GetValue(cmd.IsByteMode, Mem, op1);
  586. int FC = (int)(flags & VMFlags.VM_FC);
  587. int result =
  588. (int)
  589. (value1 & 0xFFffFFff - GetValue(cmd.IsByteMode, Mem, op2) &
  590. 0xFFffFFff - FC & unchecked((int)0xFFffFFff));
  591. if (cmd.IsByteMode)
  592. {
  593. result &= 0xff;
  594. }
  595. flags =
  596. (VMFlags)
  597. ((result > value1 || result == value1 && FC != 0)
  598. ? 1
  599. : 0 | (result == 0 ? (int)VMFlags.VM_FZ : (result & (int)VMFlags.VM_FS)));
  600. SetValue(cmd.IsByteMode, Mem, op1, result);
  601. }
  602. break;
  603. case VMCommands.VM_RET:
  604. if (R[7] >= VM_MEMSIZE)
  605. {
  606. return (true);
  607. }
  608. setIP(GetValue(false, Mem, R[7] & VM_MEMMASK));
  609. R[7] += 4;
  610. continue;
  611. case VMCommands.VM_STANDARD:
  612. ExecuteStandardFilter((VMStandardFilters)(cmd.Op1.Data));
  613. break;
  614. case VMCommands.VM_PRINT:
  615. break;
  616. }
  617. IP++;
  618. --maxOpCount;
  619. }
  620. }
  621. public void prepare(byte[] code, int codeSize, VMPreparedProgram prg)
  622. {
  623. InitBitInput();
  624. int cpLength = Math.Min(MAX_SIZE, codeSize);
  625. // memcpy(inBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));
  626. Buffer.BlockCopy(code, 0, InBuf, 0, cpLength);
  627. byte xorSum = 0;
  628. for (int i = 1; i < codeSize; i++)
  629. {
  630. xorSum ^= code[i];
  631. }
  632. AddBits(8);
  633. prg.CommandCount = 0;
  634. if (xorSum == code[0])
  635. {
  636. VMStandardFilters filterType = IsStandardFilter(code, codeSize);
  637. if (filterType != VMStandardFilters.VMSF_NONE)
  638. {
  639. VMPreparedCommand curCmd = new VMPreparedCommand();
  640. curCmd.OpCode = VMCommands.VM_STANDARD;
  641. curCmd.Op1.Data = (int)filterType;
  642. curCmd.Op1.Type = VMOpType.VM_OPNONE;
  643. curCmd.Op2.Type = VMOpType.VM_OPNONE;
  644. codeSize = 0;
  645. prg.Commands.Add(curCmd);
  646. prg.CommandCount = prg.CommandCount + 1;
  647. // TODO
  648. // curCmd->Op1.Data=FilterType;
  649. // >>>>>> CurCmd->Op1.Addr=&CurCmd->Op1.Data; <<<<<<<<<< not set
  650. // do i need to ?
  651. // >>>>>> CurCmd->Op2.Addr=&CurCmd->Op2.Data; <<<<<<<<<< "
  652. // CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;
  653. // CodeSize=0;
  654. }
  655. int dataFlag = GetBits();
  656. AddBits(1);
  657. // Read static data contained in DB operators. This data cannot be
  658. // changed,
  659. // it is a part of VM code, not a filter parameter.
  660. if ((dataFlag & 0x8000) != 0)
  661. {
  662. long dataSize = ReadData(this) & 0xffFFffFFL + 1L;
  663. for (int i = 0; inAddr < codeSize && i < dataSize; i++)
  664. {
  665. prg.StaticData.Add((byte)(GetBits() >> 8));
  666. AddBits(8);
  667. }
  668. }
  669. while (inAddr < codeSize)
  670. {
  671. VMPreparedCommand curCmd = new VMPreparedCommand();
  672. int data = GetBits();
  673. if ((data & 0x8000) == 0)
  674. {
  675. curCmd.OpCode = (VMCommands)((data >> 12));
  676. AddBits(4);
  677. }
  678. else
  679. {
  680. curCmd.OpCode = (VMCommands)((data >> 10) - 24);
  681. AddBits(6);
  682. }
  683. if ((VMCmdFlags.VM_CmdFlags[(int)curCmd.OpCode] & VMCmdFlags.VMCF_BYTEMODE) != 0)
  684. {
  685. curCmd.IsByteMode = (GetBits() >> 15) == 1 ? true : false;
  686. AddBits(1);
  687. }
  688. else
  689. {
  690. curCmd.IsByteMode = false;
  691. }
  692. curCmd.Op1.Type = VMOpType.VM_OPNONE;
  693. curCmd.Op2.Type = VMOpType.VM_OPNONE;
  694. int opNum = (VMCmdFlags.VM_CmdFlags[(int)curCmd.OpCode] & VMCmdFlags.VMCF_OPMASK);
  695. // TODO >>> CurCmd->Op1.Addr=CurCmd->Op2.Addr=NULL; <<<???
  696. if (opNum > 0)
  697. {
  698. decodeArg(curCmd.Op1, curCmd.IsByteMode);
  699. if (opNum == 2)
  700. {
  701. decodeArg(curCmd.Op2, curCmd.IsByteMode);
  702. }
  703. else
  704. {
  705. if (curCmd.Op1.Type == VMOpType.VM_OPINT &&
  706. (VMCmdFlags.VM_CmdFlags[(int)curCmd.OpCode] &
  707. (VMCmdFlags.VMCF_JUMP | VMCmdFlags.VMCF_PROC)) != 0)
  708. {
  709. int distance = curCmd.Op1.Data;
  710. if (distance >= 256)
  711. {
  712. distance -= 256;
  713. }
  714. else
  715. {
  716. if (distance >= 136)
  717. {
  718. distance -= 264;
  719. }
  720. else
  721. {
  722. if (distance >= 16)
  723. {
  724. distance -= 8;
  725. }
  726. else
  727. {
  728. if (distance >= 8)
  729. {
  730. distance -= 16;
  731. }
  732. }
  733. }
  734. distance += prg.CommandCount;
  735. }
  736. curCmd.Op1.Data = distance;
  737. }
  738. }
  739. }
  740. prg.CommandCount = (prg.CommandCount + 1);
  741. prg.Commands.Add(curCmd);
  742. }
  743. }
  744. VMPreparedCommand curCmd2 = new VMPreparedCommand();
  745. curCmd2.OpCode = VMCommands.VM_RET;
  746. // TODO CurCmd->Op1.Addr=&CurCmd->Op1.Data;
  747. // CurCmd->Op2.Addr=&CurCmd->Op2.Data;
  748. curCmd2.Op1.Type = VMOpType.VM_OPNONE;
  749. curCmd2.Op2.Type = VMOpType.VM_OPNONE;
  750. // for (int i=0;i<prg.CmdCount;i++)
  751. // {
  752. // VM_PreparedCommand *Cmd=&Prg->Cmd[I];
  753. // if (Cmd->Op1.Addr==NULL)
  754. // Cmd->Op1.Addr=&Cmd->Op1.Data;
  755. // if (Cmd->Op2.Addr==NULL)
  756. // Cmd->Op2.Addr=&Cmd->Op2.Data;
  757. // }
  758. prg.Commands.Add(curCmd2);
  759. prg.CommandCount = prg.CommandCount + 1;
  760. // #ifdef VM_OPTIMIZE
  761. if (codeSize != 0)
  762. {
  763. optimize(prg);
  764. }
  765. }
  766. private void decodeArg(VMPreparedOperand op, bool byteMode)
  767. {
  768. int data = GetBits();
  769. if ((data & 0x8000) != 0)
  770. {
  771. op.Type = VMOpType.VM_OPREG;
  772. op.Data = (data >> 12) & 7;
  773. op.Offset = op.Data;
  774. AddBits(4);
  775. }
  776. else
  777. {
  778. if ((data & 0xc000) == 0)
  779. {
  780. op.Type = VMOpType.VM_OPINT;
  781. if (byteMode)
  782. {
  783. op.Data = (data >> 6) & 0xff;
  784. AddBits(10);
  785. }
  786. else
  787. {
  788. AddBits(2);
  789. op.Data = ReadData(this);
  790. }
  791. }
  792. else
  793. {
  794. op.Type = VMOpType.VM_OPREGMEM;
  795. if ((data & 0x2000) == 0)
  796. {
  797. op.Data = (data >> 10) & 7;
  798. op.Offset = op.Data;
  799. op.Base = 0;
  800. AddBits(6);
  801. }
  802. else
  803. {
  804. if ((data & 0x1000) == 0)
  805. {
  806. op.Data = (data >> 9) & 7;
  807. op.Offset = op.Data;
  808. AddBits(7);
  809. }
  810. else
  811. {
  812. op.Data = 0;
  813. AddBits(4);
  814. }
  815. op.Base = ReadData(this);
  816. }
  817. }
  818. }
  819. }
  820. private void optimize(VMPreparedProgram prg)
  821. {
  822. //UPGRADE_NOTE: There is an untranslated Statement. Please refer to original code. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1153'"
  823. List<VMPreparedCommand> commands = prg.Commands;
  824. //UPGRADE_ISSUE: The following fragment of code could not be parsed and was not converted. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1156'"
  825. foreach (VMPreparedCommand cmd in commands)
  826. {
  827. switch (cmd.OpCode)
  828. {
  829. case VMCommands.VM_MOV:
  830. cmd.OpCode = cmd.IsByteMode ? VMCommands.VM_MOVB : VMCommands.VM_MOVD;
  831. continue;
  832. case VMCommands.VM_CMP:
  833. cmd.OpCode = cmd.IsByteMode ? VMCommands.VM_CMPB : VMCommands.VM_CMPD;
  834. continue;
  835. }
  836. if ((VMCmdFlags.VM_CmdFlags[(int)cmd.OpCode] & VMCmdFlags.VMCF_CHFLAGS) == 0)
  837. {
  838. continue;
  839. }
  840. bool flagsRequired = false;
  841. for (int i = commands.IndexOf(cmd) + 1; i < commands.Count; i++)
  842. {
  843. int flags = VMCmdFlags.VM_CmdFlags[(int)commands[i].OpCode];
  844. if ((flags & (VMCmdFlags.VMCF_JUMP | VMCmdFlags.VMCF_PROC | VMCmdFlags.VMCF_USEFLAGS)) != 0)
  845. {
  846. flagsRequired = true;
  847. break;
  848. }
  849. if ((flags & VMCmdFlags.VMCF_CHFLAGS) != 0)
  850. {
  851. break;
  852. }
  853. }
  854. if (flagsRequired)
  855. {
  856. continue;
  857. }
  858. switch (cmd.OpCode)
  859. {
  860. case VMCommands.VM_ADD:
  861. cmd.OpCode = cmd.IsByteMode ? VMCommands.VM_ADDB : VMCommands.VM_ADDD;
  862. continue;
  863. case VMCommands.VM_SUB:
  864. cmd.OpCode = cmd.IsByteMode ? VMCommands.VM_SUBB : VMCommands.VM_SUBD;
  865. continue;
  866. case VMCommands.VM_INC:
  867. cmd.OpCode = cmd.IsByteMode ? VMCommands.VM_INCB : VMCommands.VM_INCD;
  868. continue;
  869. case VMCommands.VM_DEC:
  870. cmd.OpCode = cmd.IsByteMode ? VMCommands.VM_DECB : VMCommands.VM_DECD;
  871. continue;
  872. case VMCommands.VM_NEG:
  873. cmd.OpCode = cmd.IsByteMode ? VMCommands.VM_NEGB : VMCommands.VM_NEGD;
  874. continue;
  875. }
  876. }
  877. }
  878. internal static int ReadData(BitInput rarVM)
  879. {
  880. int data = rarVM.GetBits();
  881. switch (data & 0xc000)
  882. {
  883. case 0:
  884. rarVM.AddBits(6);
  885. return ((data >> 10) & 0xf);
  886. case 0x4000:
  887. if ((data & 0x3c00) == 0)
  888. {
  889. data = unchecked((int)0xffffff00) | ((data >> 2) & 0xff);
  890. rarVM.AddBits(14);
  891. }
  892. else
  893. {
  894. data = (data >> 6) & 0xff;
  895. rarVM.AddBits(10);
  896. }
  897. return (data);
  898. case 0x8000:
  899. rarVM.AddBits(2);
  900. data = rarVM.GetBits();
  901. rarVM.AddBits(16);
  902. return (data);
  903. default:
  904. rarVM.AddBits(2);
  905. data = (rarVM.GetBits() << 16);
  906. rarVM.AddBits(16);
  907. data |= rarVM.GetBits();
  908. rarVM.AddBits(16);
  909. return (data);
  910. }
  911. }
  912. private VMStandardFilters IsStandardFilter(byte[] code, int codeSize)
  913. {
  914. VMStandardFilterSignature[] stdList =
  915. {
  916. new VMStandardFilterSignature(53, 0xad576887,
  917. VMStandardFilters.VMSF_E8),
  918. new VMStandardFilterSignature(57, 0x3cd7e57e,
  919. VMStandardFilters.VMSF_E8E9),
  920. new VMStandardFilterSignature(120, 0x3769893f,
  921. VMStandardFilters.VMSF_ITANIUM),
  922. new VMStandardFilterSignature(29, 0x0e06077d,
  923. VMStandardFilters.VMSF_DELTA),
  924. new VMStandardFilterSignature(149, 0x1c2c5dc8,
  925. VMStandardFilters.VMSF_RGB),
  926. new VMStandardFilterSignature(216, 0xbc85e701,
  927. VMStandardFilters.VMSF_AUDIO),
  928. new VMStandardFilterSignature(40, 0x46b9c560,
  929. VMStandardFilters.VMSF_UPCASE)
  930. };
  931. uint CodeCRC = RarCRC.CheckCrc(0xffffffff, code, 0, code.Length) ^ 0xffffffff;
  932. for (int i = 0; i < stdList.Length; i++)
  933. {
  934. if (stdList[i].CRC == CodeCRC && stdList[i].Length == code.Length)
  935. {
  936. return (stdList[i].Type);
  937. }
  938. }
  939. return (VMStandardFilters.VMSF_NONE);
  940. }
  941. private void ExecuteStandardFilter(VMStandardFilters filterType)
  942. {
  943. switch (filterType)
  944. {
  945. case VMStandardFilters.VMSF_E8:
  946. case VMStandardFilters.VMSF_E8E9:
  947. {
  948. int dataSize = R[4];
  949. long fileOffset = R[6] & unchecked((int)0xFFffFFff);
  950. if (dataSize >= VM_GLOBALMEMADDR)
  951. {
  952. break;
  953. }
  954. int fileSize = 0x1000000;
  955. byte cmpByte2 = (byte)((filterType == VMStandardFilters.VMSF_E8E9) ? 0xe9 : 0xe8);
  956. for (int curPos = 0; curPos < dataSize - 4;)
  957. {
  958. byte curByte = Mem[curPos++];
  959. if (curByte == 0xe8 || curByte == cmpByte2)
  960. {
  961. // #ifdef PRESENT_INT32
  962. // sint32 Offset=CurPos+FileOffset;
  963. // sint32 Addr=GET_VALUE(false,Data);
  964. // if (Addr<0)
  965. // {
  966. // if (Addr+Offset>=0)
  967. // SET_VALUE(false,Data,Addr+FileSize);
  968. // }
  969. // else
  970. // if (Addr<FileSize)
  971. // SET_VALUE(false,Data,Addr-Offset);
  972. // #else
  973. long offset = curPos + fileOffset;
  974. long Addr = GetValue(false, Mem, curPos);
  975. if ((Addr & unchecked((int)0x80000000)) != 0)
  976. {
  977. if (((Addr + offset) & unchecked((int)0x80000000)) == 0)
  978. {
  979. SetValue(false, Mem, curPos, (int)Addr + fileSize);
  980. }
  981. }
  982. else
  983. {
  984. if (((Addr - fileSize) & unchecked((int)0x80000000)) != 0)
  985. {
  986. SetValue(false, Mem, curPos, (int)(Addr - offset));
  987. }
  988. }
  989. // #endif
  990. curPos += 4;
  991. }
  992. }
  993. }
  994. break;
  995. case VMStandardFilters.VMSF_ITANIUM:
  996. {
  997. int dataSize = R[4];
  998. long fileOffset = R[6] & unchecked((int)0xFFffFFff);
  999. if (dataSize >= VM_GLOBALMEMADDR)
  1000. {
  1001. break;
  1002. }
  1003. int curPos = 0;
  1004. //UPGRADE_NOTE: Final was removed from the declaration of 'Masks '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
  1005. byte[] Masks = {4, 4, 6, 6, 0, 0, 7, 7, 4, 4, 0, 0, 4, 4, 0, 0};
  1006. fileOffset = Utility.URShift(fileOffset, 4);
  1007. while (curPos < dataSize - 21)
  1008. {
  1009. int Byte = (Mem[curPos] & 0x1f) - 0x10;
  1010. if (Byte >= 0)
  1011. {
  1012. byte cmdMask = Masks[Byte];
  1013. if (cmdMask != 0)
  1014. {
  1015. for (int i = 0; i <= 2; i++)
  1016. {
  1017. if ((cmdMask & (1 << i)) != 0)
  1018. {
  1019. int startPos = i * 41 + 5;
  1020. int opType = filterItanium_GetBits(curPos, startPos + 37, 4);
  1021. if (opType == 5)
  1022. {
  1023. int offset = filterItanium_GetBits(curPos, startPos + 13, 20);
  1024. filterItanium_SetBits(curPos, (int)(offset - fileOffset) & 0xfffff,
  1025. startPos + 13, 20);
  1026. }
  1027. }
  1028. }
  1029. }
  1030. }
  1031. curPos += 16;
  1032. fileOffset++;
  1033. }
  1034. }
  1035. break;
  1036. case VMStandardFilters.VMSF_DELTA:
  1037. {
  1038. int dataSize = R[4] & unchecked((int)0xFFffFFff);
  1039. int channels = R[0] & unchecked((int)0xFFffFFff);
  1040. int srcPos = 0;
  1041. int border = (dataSize * 2) & unchecked((int)0xFFffFFff);
  1042. SetValue(false, Mem, VM_GLOBALMEMADDR + 0x20, dataSize);
  1043. if (dataSize >= VM_GLOBALMEMADDR / 2)
  1044. {
  1045. break;
  1046. }
  1047. // bytes from same channels are grouped to continual data blocks,
  1048. // so we need to place them back to their interleaving positions
  1049. for (int curChannel = 0; curChannel < channels; curChannel++)
  1050. {
  1051. byte PrevByte = 0;
  1052. for (int destPos = dataSize + curChannel; destPos < border; destPos += channels)
  1053. {
  1054. Mem[destPos] = (PrevByte = (byte)(PrevByte - Mem[srcPos++]));
  1055. }
  1056. }
  1057. }
  1058. break;
  1059. case VMStandardFilters.VMSF_RGB:
  1060. {
  1061. // byte *SrcData=Mem,*DestData=SrcData+DataSize;
  1062. int dataSize = R[4], width = R[0] - 3, posR = R[1];
  1063. int channels = 3;
  1064. int srcPos = 0;
  1065. int destDataPos = dataSize;
  1066. SetValue(false, Mem, VM_GLOBALMEMADDR + 0x20, dataSize);
  1067. if (dataSize >= VM_GLOBALMEMADDR / 2 || posR < 0)
  1068. {
  1069. break;
  1070. }
  1071. for (int curChannel = 0; curChannel < channels; curChannel++)
  1072. {
  1073. long prevByte = 0;
  1074. for (int i = curChannel; i < dataSize; i += channels)
  1075. {
  1076. long predicted;
  1077. int upperPos = i - width;
  1078. if (upperPos >= 3)
  1079. {
  1080. int upperDataPos = destDataPos + upperPos;
  1081. int upperByte = Mem[upperDataPos] & 0xff;
  1082. int upperLeftByte = Mem[upperDataPos - 3] & 0xff;
  1083. predicted = prevByte + upperByte - upperLeftByte;
  1084. int pa = Math.Abs((int)(predicted - prevByte));
  1085. int pb = Math.Abs((int)(predicted - upperByte));
  1086. int pc = Math.Abs((int)(predicted - upperLeftByte));
  1087. if (pa <= pb && pa <= pc)
  1088. {
  1089. predicted = prevByte;
  1090. }
  1091. else
  1092. {
  1093. if (pb <= pc)
  1094. {
  1095. predicted = upperByte;
  1096. }
  1097. else
  1098. {
  1099. predicted = upperLeftByte;
  1100. }
  1101. }
  1102. }
  1103. else
  1104. {
  1105. predicted = prevByte;
  1106. }
  1107. prevByte = (predicted - Mem[srcPos++] & 0xff) & 0xff;
  1108. Mem[destDataPos + i] = (byte)(prevByte & 0xff);
  1109. }
  1110. }
  1111. for (int i = posR, border = dataSize - 2; i < border; i += 3)
  1112. {
  1113. byte G = Mem[destDataPos + i + 1];
  1114. Mem[destDataPos + i] = (byte)(Mem[destDataPos + i] + G);
  1115. Mem[destDataPos + i + 2] = (byte)(Mem[destDataPos + i + 2] + G);
  1116. }
  1117. }
  1118. break;
  1119. case VMStandardFilters.VMSF_AUDIO:
  1120. {
  1121. int dataSize = R[4], channels = R[0];
  1122. int srcPos = 0;
  1123. int destDataPos = dataSize;
  1124. //byte *SrcData=Mem,*DestData=SrcData+DataSize;
  1125. SetValue(false, Mem, VM_GLOBALMEMADDR + 0x20, dataSize);
  1126. if (dataSize >= VM_GLOBALMEMADDR / 2)
  1127. {
  1128. break;
  1129. }
  1130. for (int curChannel = 0; curChannel < channels; curChannel++)
  1131. {
  1132. long prevByte = 0;
  1133. long prevDelta = 0;
  1134. long[] Dif = new long[7];
  1135. int D1 = 0, D2 = 0, D3;
  1136. int K1 = 0, K2 = 0, K3 = 0;
  1137. for (int i = curChannel, byteCount = 0; i < dataSize; i += channels, byteCount++)
  1138. {
  1139. D3 = D2;
  1140. D2 = (int)(prevDelta - D1);
  1141. D1 = (int)prevDelta;
  1142. long predicted = 8 * prevByte + K1 * D1 + K2 * D2 + K3 * D3;
  1143. predicted = Utility.URShift(predicted, 3) & 0xff;
  1144. long curByte = Mem[srcPos++];
  1145. predicted -= curByte;
  1146. Mem[destDataPos + i] = (byte)predicted;
  1147. prevDelta = (byte)(predicted - prevByte);
  1148. //fix java byte
  1149. if (prevDelta >= 128)
  1150. {
  1151. prevDelta = 0 - (256 - prevDelta);
  1152. }
  1153. prevByte = predicted;
  1154. //fix java byte
  1155. if (curByte >= 128)
  1156. {
  1157. curByte = 0 - (256 - curByte);
  1158. }
  1159. int D = ((int)curByte) << 3;
  1160. Dif[0] += Math.Abs(D);
  1161. Dif[1] += Math.Abs(D - D1);
  1162. Dif[2] += Math.Abs(D + D1);
  1163. Dif[3] += Math.Abs(D - D2);
  1164. Dif[4] += Math.Abs(D + D2);
  1165. Dif[5] += Math.Abs(D - D3);
  1166. Dif[6] += Math.Abs(D + D3);
  1167. if ((byteCount & 0x1f) == 0)
  1168. {
  1169. long minDif = Dif[0], numMinDif = 0;
  1170. Dif[0] = 0;
  1171. for (int j = 1; j < Dif.Length; j++)
  1172. {
  1173. if (Dif[j] < minDif)
  1174. {
  1175. minDif = Dif[j];
  1176. numMinDif = j;
  1177. }
  1178. Dif[j] = 0;
  1179. }
  1180. switch ((int)numMinDif)
  1181. {
  1182. case 1:
  1183. if (K1 >= -16)
  1184. {
  1185. K1--;
  1186. }
  1187. break;
  1188. case 2:
  1189. if (K1 < 16)
  1190. {
  1191. K1++;
  1192. }
  1193. break;
  1194. case 3:
  1195. if (K2 >= -16)
  1196. {
  1197. K2--;
  1198. }
  1199. break;
  1200. case 4:
  1201. if (K2 < 16)
  1202. {
  1203. K2++;
  1204. }
  1205. break;
  1206. case 5:
  1207. if (K3 >= -16)
  1208. {
  1209. K3--;
  1210. }
  1211. break;
  1212. case 6:
  1213. if (K3 < 16)
  1214. {
  1215. K3++;
  1216. }
  1217. break;
  1218. }
  1219. }
  1220. }
  1221. }
  1222. }
  1223. break;
  1224. case VMStandardFilters.VMSF_UPCASE:
  1225. {
  1226. int dataSize = R[4], srcPos = 0, destPos = dataSize;
  1227. if (dataSize >= VM_GLOBALMEMADDR / 2)
  1228. {
  1229. break;
  1230. }
  1231. while (srcPos < dataSize)
  1232. {
  1233. byte curByte = Mem[srcPos++];
  1234. if (curByte == 2 && (curByte = Mem[srcPos++]) != 2)
  1235. {
  1236. curByte = (byte)(curByte - 32);
  1237. }
  1238. Mem[destPos++] = curByte;
  1239. }
  1240. SetValue(false, Mem, VM_GLOBALMEMADDR + 0x1c, destPos - dataSize);
  1241. SetValue(false, Mem, VM_GLOBALMEMADDR + 0x20, dataSize);
  1242. }
  1243. break;
  1244. }
  1245. }
  1246. private void filterItanium_SetBits(int curPos, int bitField, int bitPos, int bitCount)
  1247. {
  1248. int inAddr = bitPos / 8;
  1249. int inBit = bitPos & 7;
  1250. int andMask = Utility.URShift(unchecked((int)0xffffffff), (32 - bitCount));
  1251. andMask = ~(andMask << inBit);
  1252. bitField <<= inBit;
  1253. for (int i = 0; i < 4; i++)
  1254. {
  1255. Mem[curPos + inAddr + i] &= (byte)(andMask);
  1256. Mem[curPos + inAddr + i] |= (byte)(bitField);
  1257. andMask = (Utility.URShift(andMask, 8)) | unchecked((int)0xff000000);
  1258. bitField = Utility.URShift(bitField, 8);
  1259. }
  1260. }
  1261. private int filterItanium_GetBits(int curPos, int bitPos, int bitCount)
  1262. {
  1263. int inAddr = bitPos / 8;
  1264. int inBit = bitPos & 7;
  1265. int bitField = Mem[curPos + inAddr++] & 0xff;
  1266. bitField |= (Mem[curPos + inAddr++] & 0xff) << 8;
  1267. bitField |= (Mem[curPos + inAddr++] & 0xff) << 16;
  1268. bitField |= (Mem[curPos + inAddr] & 0xff) << 24;
  1269. bitField = Utility.URShift(bitField, inBit);
  1270. return (bitField & (Utility.URShift(unchecked((int)0xffffffff), (32 - bitCount))));
  1271. }
  1272. public virtual void setMemory(int pos, byte[] data, int offset, int dataSize)
  1273. {
  1274. if (pos < VM_MEMSIZE)
  1275. {
  1276. //&& data!=Mem+Pos)
  1277. //memmove(Mem+Pos,Data,Min(DataSize,VM_MEMSIZE-Pos));
  1278. for (int i = 0; i < Math.Min(data.Length - offset, dataSize); i++)
  1279. {
  1280. if ((VM_MEMSIZE - pos) < i)
  1281. {
  1282. break;
  1283. }
  1284. Mem[pos + i] = data[offset + i];
  1285. }
  1286. }
  1287. }
  1288. }
  1289. //
  1290. }