Bra86.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* Bra86.c -- Converter for x86 code (BCJ)
  2. 2008-10-04 : Igor Pavlov : Public domain */
  3. #include "Bra.h"
  4. #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
  5. const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
  6. const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
  7. SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
  8. {
  9. SizeT bufferPos = 0, prevPosT;
  10. UInt32 prevMask = *state & 0x7;
  11. if (size < 5)
  12. return 0;
  13. ip += 5;
  14. prevPosT = (SizeT)0 - 1;
  15. for (;;)
  16. {
  17. Byte *p = data + bufferPos;
  18. Byte *limit = data + size - 4;
  19. for (; p < limit; p++)
  20. if ((*p & 0xFE) == 0xE8)
  21. break;
  22. bufferPos = (SizeT)(p - data);
  23. if (p >= limit)
  24. break;
  25. prevPosT = bufferPos - prevPosT;
  26. if (prevPosT > 3)
  27. prevMask = 0;
  28. else
  29. {
  30. prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
  31. if (prevMask != 0)
  32. {
  33. Byte b = p[4 - kMaskToBitNumber[prevMask]];
  34. if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
  35. {
  36. prevPosT = bufferPos;
  37. prevMask = ((prevMask << 1) & 0x7) | 1;
  38. bufferPos++;
  39. continue;
  40. }
  41. }
  42. }
  43. prevPosT = bufferPos;
  44. if (Test86MSByte(p[4]))
  45. {
  46. UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
  47. UInt32 dest;
  48. for (;;)
  49. {
  50. Byte b;
  51. int index;
  52. if (encoding)
  53. dest = (ip + (UInt32)bufferPos) + src;
  54. else
  55. dest = src - (ip + (UInt32)bufferPos);
  56. if (prevMask == 0)
  57. break;
  58. index = kMaskToBitNumber[prevMask] * 8;
  59. b = (Byte)(dest >> (24 - index));
  60. if (!Test86MSByte(b))
  61. break;
  62. src = dest ^ ((1 << (32 - index)) - 1);
  63. }
  64. p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
  65. p[3] = (Byte)(dest >> 16);
  66. p[2] = (Byte)(dest >> 8);
  67. p[1] = (Byte)dest;
  68. bufferPos += 5;
  69. }
  70. else
  71. {
  72. prevMask = ((prevMask << 1) & 0x7) | 1;
  73. bufferPos++;
  74. }
  75. }
  76. prevPosT = bufferPos - prevPosT;
  77. *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
  78. return bufferPos;
  79. }