83 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			83 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/* Bra86.c -- Converter for x86 code (BCJ)
							 | 
						||
| 
								 | 
							
								2017-04-03 : Igor Pavlov : Public domain */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "Precomp.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "Bra.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  SizeT pos = 0;
							 | 
						||
| 
								 | 
							
								  UInt32 mask = *state & 7;
							 | 
						||
| 
								 | 
							
								  if (size < 5)
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								  size -= 4;
							 | 
						||
| 
								 | 
							
								  ip += 5;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  for (;;)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    Byte *p = data + pos;
							 | 
						||
| 
								 | 
							
								    const Byte *limit = data + size;
							 | 
						||
| 
								 | 
							
								    for (; p < limit; p++)
							 | 
						||
| 
								 | 
							
								      if ((*p & 0xFE) == 0xE8)
							 | 
						||
| 
								 | 
							
								        break;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      SizeT d = (SizeT)(p - data - pos);
							 | 
						||
| 
								 | 
							
								      pos = (SizeT)(p - data);
							 | 
						||
| 
								 | 
							
								      if (p >= limit)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        *state = (d > 2 ? 0 : mask >> (unsigned)d);
							 | 
						||
| 
								 | 
							
								        return pos;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      if (d > 2)
							 | 
						||
| 
								 | 
							
								        mask = 0;
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        mask >>= (unsigned)d;
							 | 
						||
| 
								 | 
							
								        if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          mask = (mask >> 1) | 4;
							 | 
						||
| 
								 | 
							
								          pos++;
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (Test86MSByte(p[4]))
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
							 | 
						||
| 
								 | 
							
								      UInt32 cur = ip + (UInt32)pos;
							 | 
						||
| 
								 | 
							
								      pos += 5;
							 | 
						||
| 
								 | 
							
								      if (encoding)
							 | 
						||
| 
								 | 
							
								        v += cur;
							 | 
						||
| 
								 | 
							
								      else
							 | 
						||
| 
								 | 
							
								        v -= cur;
							 | 
						||
| 
								 | 
							
								      if (mask != 0)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        unsigned sh = (mask & 6) << 2;
							 | 
						||
| 
								 | 
							
								        if (Test86MSByte((Byte)(v >> sh)))
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								          v ^= (((UInt32)0x100 << sh) - 1);
							 | 
						||
| 
								 | 
							
								          if (encoding)
							 | 
						||
| 
								 | 
							
								            v += cur;
							 | 
						||
| 
								 | 
							
								          else
							 | 
						||
| 
								 | 
							
								            v -= cur;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        mask = 0;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      p[1] = (Byte)v;
							 | 
						||
| 
								 | 
							
								      p[2] = (Byte)(v >> 8);
							 | 
						||
| 
								 | 
							
								      p[3] = (Byte)(v >> 16);
							 | 
						||
| 
								 | 
							
								      p[4] = (Byte)(0 - ((v >> 24) & 1));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      mask = (mask >> 1) | 4;
							 | 
						||
| 
								 | 
							
								      pos++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 |