|
|
@ -7,48 +7,48 @@ namespace vm
|
|
|
|
std::pair< std::uint64_t, std::uint64_t > decrypt_operand( transform::map_t &transforms, std::uint64_t operand,
|
|
|
|
std::pair< std::uint64_t, std::uint64_t > decrypt_operand( transform::map_t &transforms, std::uint64_t operand,
|
|
|
|
std::uint64_t rolling_key )
|
|
|
|
std::uint64_t rolling_key )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const auto generic_decrypt_0 = &transforms[ transform::type::generic0 ];
|
|
|
|
const auto& generic_decrypt_0 = transforms[ transform::type::generic0 ];
|
|
|
|
const auto key_decrypt = &transforms[ transform::type::rolling_key ];
|
|
|
|
const auto& key_decrypt = transforms[ transform::type::rolling_key ];
|
|
|
|
const auto generic_decrypt_1 = &transforms[ transform::type::generic1 ];
|
|
|
|
const auto& generic_decrypt_1 = transforms[ transform::type::generic1 ];
|
|
|
|
const auto generic_decrypt_2 = &transforms[ transform::type::generic2 ];
|
|
|
|
const auto& generic_decrypt_2 = transforms[ transform::type::generic2 ];
|
|
|
|
const auto generic_decrypt_3 = &transforms[ transform::type::generic3 ];
|
|
|
|
const auto& generic_decrypt_3 = transforms[ transform::type::generic3 ];
|
|
|
|
const auto update_key = &transforms[ transform::type::update_key ];
|
|
|
|
const auto& update_key = transforms[ transform::type::update_key ];
|
|
|
|
|
|
|
|
|
|
|
|
if ( generic_decrypt_0->mnemonic != ZYDIS_MNEMONIC_INVALID )
|
|
|
|
if ( generic_decrypt_0.mnemonic != ZYDIS_MNEMONIC_INVALID )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
operand = transform::apply(
|
|
|
|
operand = transform::apply(
|
|
|
|
generic_decrypt_0->operands[ 0 ].size, generic_decrypt_0->mnemonic, operand,
|
|
|
|
generic_decrypt_0.operands[ 0 ].size, generic_decrypt_0.mnemonic, operand,
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
transform::has_imm( generic_decrypt_0 ) ? generic_decrypt_0->operands[ 1 ].imm.value.u : 0 );
|
|
|
|
transform::has_imm( &generic_decrypt_0 ) ? generic_decrypt_0.operands[ 1 ].imm.value.u : 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// apply transformation with rolling decrypt key...
|
|
|
|
// apply transformation with rolling decrypt key...
|
|
|
|
operand = transform::apply( key_decrypt->operands[ 0 ].size, key_decrypt->mnemonic, operand, rolling_key );
|
|
|
|
operand = transform::apply( key_decrypt.operands[ 0 ].size, key_decrypt.mnemonic, operand, rolling_key );
|
|
|
|
|
|
|
|
|
|
|
|
// apply three generic transformations...
|
|
|
|
// apply three generic transformations...
|
|
|
|
{
|
|
|
|
{
|
|
|
|
operand = transform::apply(
|
|
|
|
operand = transform::apply(
|
|
|
|
generic_decrypt_1->operands[ 0 ].size, generic_decrypt_1->mnemonic, operand,
|
|
|
|
generic_decrypt_1.operands[ 0 ].size, generic_decrypt_1.mnemonic, operand,
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
transform::has_imm( generic_decrypt_1 ) ? generic_decrypt_1->operands[ 1 ].imm.value.u : 0 );
|
|
|
|
transform::has_imm( &generic_decrypt_1 ) ? generic_decrypt_1.operands[ 1 ].imm.value.u : 0 );
|
|
|
|
|
|
|
|
|
|
|
|
operand = transform::apply(
|
|
|
|
operand = transform::apply(
|
|
|
|
generic_decrypt_2->operands[ 0 ].size, generic_decrypt_2->mnemonic, operand,
|
|
|
|
generic_decrypt_2.operands[ 0 ].size, generic_decrypt_2.mnemonic, operand,
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
transform::has_imm( generic_decrypt_2 ) ? generic_decrypt_2->operands[ 1 ].imm.value.u : 0 );
|
|
|
|
transform::has_imm( &generic_decrypt_2 ) ? generic_decrypt_2.operands[ 1 ].imm.value.u : 0 );
|
|
|
|
|
|
|
|
|
|
|
|
operand = transform::apply(
|
|
|
|
operand = transform::apply(
|
|
|
|
generic_decrypt_3->operands[ 0 ].size, generic_decrypt_3->mnemonic, operand,
|
|
|
|
generic_decrypt_3.operands[ 0 ].size, generic_decrypt_3.mnemonic, operand,
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
transform::has_imm( generic_decrypt_3 ) ? generic_decrypt_3->operands[ 1 ].imm.value.u : 0 );
|
|
|
|
transform::has_imm( &generic_decrypt_3 ) ? generic_decrypt_3.operands[ 1 ].imm.value.u : 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// update rolling key...
|
|
|
|
// update rolling key...
|
|
|
|
auto result =
|
|
|
|
auto result =
|
|
|
|
transform::apply( update_key->operands[ 0 ].size, update_key->mnemonic, rolling_key, operand );
|
|
|
|
transform::apply( update_key.operands[ 0 ].size, update_key.mnemonic, rolling_key, operand );
|
|
|
|
|
|
|
|
|
|
|
|
// update decryption key correctly...
|
|
|
|
// update decryption key correctly...
|
|
|
|
switch ( update_key->operands[ 0 ].size )
|
|
|
|
switch ( update_key.operands[ 0 ].size )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case 8:
|
|
|
|
case 8:
|
|
|
|
rolling_key = ( rolling_key & ~0xFFull ) + result;
|
|
|
|
rolling_key = ( rolling_key & ~0xFFull ) + result;
|
|
|
@ -70,18 +70,18 @@ namespace vm
|
|
|
|
transform::map_t inverse;
|
|
|
|
transform::map_t inverse;
|
|
|
|
inverse_transforms( transforms, inverse );
|
|
|
|
inverse_transforms( transforms, inverse );
|
|
|
|
|
|
|
|
|
|
|
|
const auto generic_decrypt_0 = &inverse[ transform::type::generic0 ];
|
|
|
|
const auto& generic_decrypt_0 = inverse[ transform::type::generic0 ];
|
|
|
|
const auto key_decrypt = &inverse[ transform::type::rolling_key ];
|
|
|
|
const auto& key_decrypt = inverse[ transform::type::rolling_key ];
|
|
|
|
const auto generic_decrypt_1 = &inverse[ transform::type::generic1 ];
|
|
|
|
const auto& generic_decrypt_1 = inverse[ transform::type::generic1 ];
|
|
|
|
const auto generic_decrypt_2 = &inverse[ transform::type::generic2 ];
|
|
|
|
const auto& generic_decrypt_2 = inverse[ transform::type::generic2 ];
|
|
|
|
const auto generic_decrypt_3 = &inverse[ transform::type::generic3 ];
|
|
|
|
const auto& generic_decrypt_3 = inverse[ transform::type::generic3 ];
|
|
|
|
const auto update_key = &inverse[ transform::type::update_key ];
|
|
|
|
const auto& update_key = inverse[ transform::type::update_key ];
|
|
|
|
|
|
|
|
|
|
|
|
auto result =
|
|
|
|
auto result =
|
|
|
|
transform::apply( update_key->operands[ 0 ].size, update_key->mnemonic, rolling_key, operand );
|
|
|
|
transform::apply( update_key.operands[ 0 ].size, update_key.mnemonic, rolling_key, operand );
|
|
|
|
|
|
|
|
|
|
|
|
// make sure we update the rolling decryption key correctly...
|
|
|
|
// make sure we update the rolling decryption key correctly...
|
|
|
|
switch ( update_key->operands[ 0 ].size )
|
|
|
|
switch ( update_key.operands[ 0 ].size )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case 8:
|
|
|
|
case 8:
|
|
|
|
rolling_key = ( rolling_key & ~0xFFull ) + result;
|
|
|
|
rolling_key = ( rolling_key & ~0xFFull ) + result;
|
|
|
@ -96,29 +96,29 @@ namespace vm
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
operand = transform::apply(
|
|
|
|
operand = transform::apply(
|
|
|
|
generic_decrypt_3->operands[ 0 ].size, generic_decrypt_3->mnemonic, operand,
|
|
|
|
generic_decrypt_3.operands[ 0 ].size, generic_decrypt_3.mnemonic, operand,
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
transform::has_imm( generic_decrypt_3 ) ? generic_decrypt_3->operands[ 1 ].imm.value.u : 0 );
|
|
|
|
transform::has_imm( &generic_decrypt_3 ) ? generic_decrypt_3.operands[ 1 ].imm.value.u : 0 );
|
|
|
|
|
|
|
|
|
|
|
|
operand = transform::apply(
|
|
|
|
operand = transform::apply(
|
|
|
|
generic_decrypt_2->operands[ 0 ].size, generic_decrypt_2->mnemonic, operand,
|
|
|
|
generic_decrypt_2.operands[ 0 ].size, generic_decrypt_2.mnemonic, operand,
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
transform::has_imm( generic_decrypt_2 ) ? generic_decrypt_2->operands[ 1 ].imm.value.u : 0 );
|
|
|
|
transform::has_imm( &generic_decrypt_2 ) ? generic_decrypt_2.operands[ 1 ].imm.value.u : 0 );
|
|
|
|
|
|
|
|
|
|
|
|
operand = transform::apply(
|
|
|
|
operand = transform::apply(
|
|
|
|
generic_decrypt_1->operands[ 0 ].size, generic_decrypt_1->mnemonic, operand,
|
|
|
|
generic_decrypt_1.operands[ 0 ].size, generic_decrypt_1.mnemonic, operand,
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
transform::has_imm( generic_decrypt_1 ) ? generic_decrypt_1->operands[ 1 ].imm.value.u : 0 );
|
|
|
|
transform::has_imm( &generic_decrypt_1 ) ? generic_decrypt_1.operands[ 1 ].imm.value.u : 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
operand = transform::apply( key_decrypt->operands[ 0 ].size, key_decrypt->mnemonic, operand, rolling_key );
|
|
|
|
operand = transform::apply( key_decrypt.operands[ 0 ].size, key_decrypt.mnemonic, operand, rolling_key );
|
|
|
|
|
|
|
|
|
|
|
|
if ( generic_decrypt_0->mnemonic != ZYDIS_MNEMONIC_INVALID )
|
|
|
|
if ( generic_decrypt_0.mnemonic != ZYDIS_MNEMONIC_INVALID )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
operand = transform::apply(
|
|
|
|
operand = transform::apply(
|
|
|
|
generic_decrypt_0->operands[ 0 ].size, generic_decrypt_0->mnemonic, operand,
|
|
|
|
generic_decrypt_0.operands[ 0 ].size, generic_decrypt_0.mnemonic, operand,
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
// check to see if this instruction has an IMM...
|
|
|
|
transform::has_imm( generic_decrypt_0 ) ? generic_decrypt_0->operands[ 1 ].imm.value.u : 0 );
|
|
|
|
transform::has_imm( &generic_decrypt_0 ) ? generic_decrypt_0.operands[ 1 ].imm.value.u : 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return { operand, rolling_key };
|
|
|
|
return { operand, rolling_key };
|
|
|
|