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