栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

安卓简单VMP思路笔记

Java 更新时间:发布时间: 百科书网 趣学号
安卓简单VMP思路笔记 简介

先明白物理机三级流水线概念,分为读取、解析、执行。读取什么?字符串!解析是什么?解释器!执行是什么?CPU!
然后寻找定量,再执行过程中什么想对固定?CPU指令集、原生解释器、原生字符串。
最后提高静态分析原生字符串难度,则会其进行转换。转换过程涉及映射表和解释器,则称为VMP。

简单的编译器

在实际寻找映射表和编译器中,肯定会遇到防护手段。
一位老师傅写好简单的编译器如下,这是一套简易版的编译器,使用JNI接口。实现比较经典,首先定义映射表,就是Compute[] 部分,然后Java_com_vmpprotect_Compute_compute使用JNI接口调用myinterpreter,myinterpreter函数中进行解释器。

#include 
#include 

// Raw code_item.
struct CodeItem {
    uint16_t registers_size_;            // the number of registers used by this code
    //   (locals + parameters)
    uint16_t ins_size_;                  // the number of words of incoming arguments to the method
    //   that this code is for
    uint16_t outs_size_;                 // the number of words of outgoing argument space required
    //   by this code for method invocation
    uint16_t tries_size_;                // the number of try_items for this instance. If non-zero,
    //   then these appear as the tries array just after the
    //   insns in this instance.
    uint32_t debug_info_off_;            // file offset to debug info stream
    uint32_t insns_size_in_code_units_;  // size of the insns array, in 2 byte code units
    uint16_t insns_[1];                  // actual array of bytecode.
};

//90 20
//91 21
//92 22
//93 23
const unsigned char Compute[] = {0x08, 0x00,
                                 0x03, 0x00,
                                 0x00, 0x00,
                                 0x00, 0x00,
                                 0x6e, 0x77, 0x14,0x00,
                                 0x0d, 0x00, 0x00, 0x00,
                                 0x22, 0x00, 0x06, 0x06,
                                 0x22, 0x01,0x06, 0x07,
                                 0x21, 0x02, 0x06, 0x07,
                                 0x23, 0x03, 0x06, 0x07,
                                 0x20,0x04, 0x00, 0x01,
                                 0xb0, 0x24,
                                 0xb0, 0x34,
                                 0x0f, 0x04};

extern "C" JNIEXPORT jstring JNICALL
Java_com_kanxue_vmpprotect_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject ) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

int myinterpreter(JNIEnv *env, jobject obj, jint a, jint b) {


    CodeItem *codeItem = (CodeItem *) Compute;
    int registersize = codeItem->registers_size_;
    int result = 0;
    int *VREG = reinterpret_cast(malloc(sizeof(int) * registersize));
    if (VREG != nullptr) {
        memset(VREG, 0, registersize * sizeof(int));
        int insNum = codeItem->ins_size_;//参数的个数
        int startIndex = registersize - insNum;//总的寄存器数量减去参数个数,剩下的才是解释器能自由使用的寄存器个数
        VREG[startIndex] = 0;
        VREG[++startIndex] = a;
        VREG[++startIndex] = b;
        int pc = 0;
        unsigned long address = (unsigned long) Compute;
        unsigned char *opOffset = reinterpret_cast(address + 16);//指令集的地址
        while (true) {
            unsigned char op = *opOffset;
            switch (op) {
                
                case 0x20: {//90040001 |0008: add-int v4, v0, v1
                    unsigned char des = *(opOffset + 1);
                    unsigned char arg0 = *(opOffset + 2);
                    unsigned char arg1 = *(opOffset + 3);
                    VREG[des] = VREG[arg0] + VREG[arg1];
                    opOffset = opOffset + 4;
                    break;
                }
                case 0x21: {//91020607            |0004: sub-int v2, v6, v7
                    unsigned char des = *(opOffset + 1);
                    unsigned char arg0 = *(opOffset + 2);
                    unsigned char arg1 = *(opOffset + 3);
                    VREG[des] = VREG[arg0] - VREG[arg1];
                    opOffset = opOffset + 4;
                    break;
                }
                case 0x22: {//92010607            |0002: mul-int v1, v6, v7
                    unsigned char des = *(opOffset + 1);
                    unsigned char arg0 = *(opOffset + 2);
                    unsigned char arg1 = *(opOffset + 3);
                    VREG[des] = VREG[arg0] * VREG[arg1];
                    opOffset = opOffset + 4;
                    break;
                }
                case 0x23: {//93030607            |0006: div-int v3, v6, v7
                    unsigned char des = *(opOffset + 1);
                    unsigned char arg0 = *(opOffset + 2);
                    unsigned char arg1 = *(opOffset + 3);
                    VREG[des] = VREG[arg0] / VREG[arg1];
                    opOffset = opOffset + 4;
                    break;
                }
                case 0xb0: {//b024                |000a: add-int/2addr v4, v2
                    unsigned char des = *(opOffset + 1);
                    int arg0 = des & 0x0F;
                    int arg1 = des >> 4;
                    VREG[arg0] = VREG[arg0] + VREG[arg1];
                    opOffset = opOffset + 2;
                    break;
                }
                case 0x0f: {//123cf4: 0f04                |000c: return v4*/
                    unsigned char des = *(opOffset + 1);
                    return VREG[des];
                }

            }

        }
    }
}

extern "C" JNIEXPORT jint JNICALL
Java_com_vmpprotect_Compute_compute(JNIEnv *env, jobject obj, jint a, jint b) {
    int result = myinterpreter(env, obj, a, b);
    return result;
}
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/275040.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号