summaryrefslogtreecommitdiff
path: root/cheat/internal_rewrite/hde32.cpp
diff options
context:
space:
mode:
authorboris <wzn@moneybot.cc>2018-11-28 16:00:02 +1300
committerboris <wzn@moneybot.cc>2018-11-28 16:00:02 +1300
commit3d412a4b30a9f7c7f51ea6562e694315948bd3da (patch)
tree26d67dfd1f3e5fd12903ad13e85d0cb8bcf8f21c /cheat/internal_rewrite/hde32.cpp
parente4729e4393d90271a3814c7a79950a660c48325a (diff)
cleaned up
in short, the cheat and loader are now separate solutions. unused stuff was moved into the legacy solution in case anyone wants to compile it or whatever. i can change this back if you want to. also, i configured the loader to compile in x64, and have separate build types for linux and win64
Diffstat (limited to 'cheat/internal_rewrite/hde32.cpp')
-rw-r--r--cheat/internal_rewrite/hde32.cpp377
1 files changed, 377 insertions, 0 deletions
diff --git a/cheat/internal_rewrite/hde32.cpp b/cheat/internal_rewrite/hde32.cpp
new file mode 100644
index 0000000..8569287
--- /dev/null
+++ b/cheat/internal_rewrite/hde32.cpp
@@ -0,0 +1,377 @@
+/*
+* Hacker Disassembler Engine 32 C
+* Copyright (c) 2008-2009, Vyacheslav Patkov.
+* All rights reserved.
+*
+*/
+
+#include <cstring>
+#include "hde32.h"
+#include "table32.h"
+
+unsigned int hde32_disasm( const void *code, hde32s *hs )
+{
+ uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
+ uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0;
+
+ memset( (uint8_t*)hs, 0, sizeof( hde32s ) );
+
+ for ( x = 16; x; x-- )
+ switch ( c = *p++ )
+ {
+ case 0xf3:
+ hs->p_rep = c;
+ pref |= PRE_F3;
+ break;
+ case 0xf2:
+ hs->p_rep = c;
+ pref |= PRE_F2;
+ break;
+ case 0xf0:
+ hs->p_lock = c;
+ pref |= PRE_LOCK;
+ break;
+ case 0x26: case 0x2e: case 0x36:
+ case 0x3e: case 0x64: case 0x65:
+ hs->p_seg = c;
+ pref |= PRE_SEG;
+ break;
+ case 0x66:
+ hs->p_66 = c;
+ pref |= PRE_66;
+ break;
+ case 0x67:
+ hs->p_67 = c;
+ pref |= PRE_67;
+ break;
+ default:
+ goto pref_done;
+ }
+pref_done:
+
+ hs->flags = (uint32_t)pref << 23;
+
+ if ( !pref )
+ pref |= PRE_NONE;
+
+ if ( ( hs->opcode = c ) == 0x0f )
+ {
+ hs->opcode2 = c = *p++;
+ ht += DELTA_OPCODES;
+ }
+ else if ( c >= 0xa0 && c <= 0xa3 )
+ {
+ if ( pref & PRE_67 )
+ pref |= PRE_66;
+ else
+ pref &= ~PRE_66;
+ }
+
+ opcode = c;
+ cflags = ht[ht[opcode / 4] + ( opcode % 4 )];
+
+ if ( cflags == C_ERROR )
+ {
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+ cflags = 0;
+ if ( ( opcode & -3 ) == 0x24 )
+ cflags++;
+ }
+
+ x = 0;
+ if ( cflags & C_GROUP )
+ {
+ uint16_t t;
+ t = *(uint16_t *)( ht + ( cflags & 0x7f ) );
+ cflags = (uint8_t)t;
+ x = (uint8_t)( t >> 8 );
+ }
+
+ if ( hs->opcode2 )
+ {
+ ht = hde32_table + DELTA_PREFIXES;
+ if ( ht[ht[opcode / 4] + ( opcode % 4 )] & pref )
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+ }
+
+ if ( cflags & C_MODRM )
+ {
+ hs->flags |= F_MODRM;
+ hs->modrm = c = *p++;
+ hs->modrm_mod = m_mod = c >> 6;
+ hs->modrm_rm = m_rm = c & 7;
+ hs->modrm_reg = m_reg = ( c & 0x3f ) >> 3;
+
+ if ( x && ( ( x << m_reg ) & 0x80 ) )
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+
+ if ( !hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf )
+ {
+ uint8_t t = opcode - 0xd9;
+ if ( m_mod == 3 )
+ {
+ ht = hde32_table + DELTA_FPU_MODRM + t * 8;
+ t = ht[m_reg] << m_rm;
+ }
+ else
+ {
+ ht = hde32_table + DELTA_FPU_REG;
+ t = ht[t] << m_reg;
+ }
+ if ( t & 0x80 )
+ hs->flags |= F_ERROR | F_ERROR_OPCODE;
+ }
+
+ if ( pref & PRE_LOCK )
+ {
+ if ( m_mod == 3 )
+ {
+ hs->flags |= F_ERROR | F_ERROR_LOCK;
+ }
+ else
+ {
+ uint8_t *table_end, op = opcode;
+ if ( hs->opcode2 )
+ {
+ ht = hde32_table + DELTA_OP2_LOCK_OK;
+ table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
+ }
+ else
+ {
+ ht = hde32_table + DELTA_OP_LOCK_OK;
+ table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
+ op &= -2;
+ }
+ for ( ; ht != table_end; ht++ )
+ if ( *ht++ == op )
+ {
+ if ( !( ( *ht << m_reg ) & 0x80 ) )
+ goto no_lock_error;
+ else
+ break;
+ }
+ hs->flags |= F_ERROR | F_ERROR_LOCK;
+ no_lock_error:
+ ;
+ }
+ }
+
+ if ( hs->opcode2 )
+ {
+ switch ( opcode )
+ {
+ case 0x20: case 0x22:
+ m_mod = 3;
+ if ( m_reg > 4 || m_reg == 1 )
+ goto error_operand;
+ else
+ goto no_error_operand;
+ case 0x21: case 0x23:
+ m_mod = 3;
+ if ( m_reg == 4 || m_reg == 5 )
+ goto error_operand;
+ else
+ goto no_error_operand;
+ }
+ }
+ else
+ {
+ switch ( opcode )
+ {
+ case 0x8c:
+ if ( m_reg > 5 )
+ goto error_operand;
+ else
+ goto no_error_operand;
+ case 0x8e:
+ if ( m_reg == 1 || m_reg > 5 )
+ goto error_operand;
+ else
+ goto no_error_operand;
+ }
+ }
+
+ if ( m_mod == 3 )
+ {
+ uint8_t *table_end;
+ if ( hs->opcode2 )
+ {
+ ht = hde32_table + DELTA_OP2_ONLY_MEM;
+ table_end = ht + sizeof( hde32_table ) - DELTA_OP2_ONLY_MEM;
+ }
+ else
+ {
+ ht = hde32_table + DELTA_OP_ONLY_MEM;
+ table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
+ }
+ for ( ; ht != table_end; ht += 2 )
+ if ( *ht++ == opcode )
+ {
+ if ( *ht++ & pref && !( ( *ht << m_reg ) & 0x80 ) )
+ goto error_operand;
+ else
+ break;
+ }
+ goto no_error_operand;
+ }
+ else if ( hs->opcode2 )
+ {
+ switch ( opcode )
+ {
+ case 0x50: case 0xd7: case 0xf7:
+ if ( pref & ( PRE_NONE | PRE_66 ) )
+ goto error_operand;
+ break;
+ case 0xd6:
+ if ( pref & ( PRE_F2 | PRE_F3 ) )
+ goto error_operand;
+ break;
+ case 0xc5:
+ goto error_operand;
+ }
+ goto no_error_operand;
+ }
+ else
+ goto no_error_operand;
+
+ error_operand:
+ hs->flags |= F_ERROR | F_ERROR_OPERAND;
+ no_error_operand:
+
+ c = *p++;
+ if ( m_reg <= 1 )
+ {
+ if ( opcode == 0xf6 )
+ cflags |= C_IMM8;
+ else if ( opcode == 0xf7 )
+ cflags |= C_IMM_P66;
+ }
+
+ switch ( m_mod )
+ {
+ case 0:
+ if ( pref & PRE_67 )
+ {
+ if ( m_rm == 6 )
+ disp_size = 2;
+ }
+ else
+ if ( m_rm == 5 )
+ disp_size = 4;
+ break;
+ case 1:
+ disp_size = 1;
+ break;
+ case 2:
+ disp_size = 2;
+ if ( !( pref & PRE_67 ) )
+ disp_size <<= 1;
+ }
+
+ if ( m_mod != 3 && m_rm == 4 && !( pref & PRE_67 ) )
+ {
+ hs->flags |= F_SIB;
+ p++;
+ hs->sib = c;
+ hs->sib_scale = c >> 6;
+ hs->sib_index = ( c & 0x3f ) >> 3;
+ if ( ( hs->sib_base = c & 7 ) == 5 && !( m_mod & 1 ) )
+ disp_size = 4;
+ }
+
+ p--;
+ switch ( disp_size )
+ {
+ case 1:
+ hs->flags |= F_DISP8;
+ hs->disp.disp8 = *p;
+ break;
+ case 2:
+ hs->flags |= F_DISP16;
+ hs->disp.disp16 = *(uint16_t *)p;
+ break;
+ case 4:
+ hs->flags |= F_DISP32;
+ hs->disp.disp32 = *(uint32_t *)p;
+ }
+ p += disp_size;
+ }
+ else if ( pref & PRE_LOCK )
+ hs->flags |= F_ERROR | F_ERROR_LOCK;
+
+ if ( cflags & C_IMM_P66 )
+ {
+ if ( cflags & C_REL32 )
+ {
+ if ( pref & PRE_66 )
+ {
+ hs->flags |= F_IMM16 | F_RELATIVE;
+ hs->imm.imm16 = *(uint16_t *)p;
+ p += 2;
+ goto disasm_done;
+ }
+ goto rel32_ok;
+ }
+ if ( pref & PRE_66 )
+ {
+ hs->flags |= F_IMM16;
+ hs->imm.imm16 = *(uint16_t *)p;
+ p += 2;
+ }
+ else
+ {
+ hs->flags |= F_IMM32;
+ hs->imm.imm32 = *(uint32_t *)p;
+ p += 4;
+ }
+ }
+
+ if ( cflags & C_IMM16 )
+ {
+ if ( hs->flags & F_IMM32 )
+ {
+ hs->flags |= F_IMM16;
+ hs->disp.disp16 = *(uint16_t *)p;
+ }
+ else if ( hs->flags & F_IMM16 )
+ {
+ hs->flags |= F_2IMM16;
+ hs->disp.disp16 = *(uint16_t *)p;
+ }
+ else
+ {
+ hs->flags |= F_IMM16;
+ hs->imm.imm16 = *(uint16_t *)p;
+ }
+ p += 2;
+ }
+ if ( cflags & C_IMM8 )
+ {
+ hs->flags |= F_IMM8;
+ hs->imm.imm8 = *p++;
+ }
+
+ if ( cflags & C_REL32 )
+ {
+ rel32_ok:
+ hs->flags |= F_IMM32 | F_RELATIVE;
+ hs->imm.imm32 = *(uint32_t *)p;
+ p += 4;
+ }
+ else if ( cflags & C_REL8 )
+ {
+ hs->flags |= F_IMM8 | F_RELATIVE;
+ hs->imm.imm8 = *p++;
+ }
+
+disasm_done:
+
+ if ( ( hs->len = (uint8_t)( p - (uint8_t *)code ) ) > 15 )
+ {
+ hs->flags |= F_ERROR | F_ERROR_LENGTH;
+ hs->len = 15;
+ }
+
+ return (unsigned int)hs->len;
+}
+