tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Bra86.c (1807B)


      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 
     10 SizeT 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 }