首页
社区
课程
招聘
[原创]vm虚拟机的初探
发表于: 2天前 1482

[原创]vm虚拟机的初探

2天前
1482

本文仅限于技术讨论,不得用于非法途径,后果自负。

这是萌新第一次逆向vmp,主要是分享分析过程,这里借鉴了金罡大佬的文章https://bbs.kanxue.com/thread-282300.htm,vmp的内存布局和context 在我选用的这个版本差别并不大。选用的TT 中libEncryptor.so 中被vm 的jnionload。

用ida打开so 定位到AF8 ,看一下cfg
图片描述
下面这一排就是handle的实现了
图片描述
不过handle太多了 我只会还原被执行的指令集。

从下面两张图可以看出vm指令集4字节对齐和arm一致 ,在后面的逆向中发现开发者并没有实现指令集或者说指令集就是arm64
图片描述
图片描述
还原指令的第一步就是解析出指令中携带的信息,一般来说,有这几个信息
1.指令类型
2.寄存器信息
3.立即数
可以看到在虚拟机循环的开头就是虚拟机取出指令各个信息的过程
图片描述

可以看到 指令类型 sourceREG destREG opcode 这几个关键的信息

可以理解为虚拟机使用的寄存器 堆栈 等信息
这里可以参考金罡大佬的文章https://bbs.kanxue.com/thread-282300.htm 这个版本没什么变化,唯一注意的是我并不是通过汇编而是f5代码来确定coutext的结构的,而开发者为了对抗,这个context结构体是负指针寻址的 所以需要自己patch代码
比如 STP X3, X20, [X19,#-0x100]=>STP X3, X20, [X19,#0x100]
这个方法中只需要patch 所有有关x19的指针操作即可
效果图
图片描述
图片描述

这个可能是最头疼的一点,明明开发者写的就是一个while switch 可是被编译器优化后代码复用,各种跳转比如
图片描述
可能你找handle的时间都比逆向handle的时间长
这里,我使用了一个实验性质的方法
利用trace在剔除控制流指令后重新patch
效果图
图片描述
可以看到 所有handle都被打印出来了
指令缩短 变成单次打印单个handle
图片描述
这样我觉得是提高了我的分析效率

这个是我觉得最繁琐的地方,我看了我还原出来的指令和金罡大佬的还原,还是细节不够
图片描述
图片描述
对比可以看到mov少了个z,这就是细节不够,另外还有对arm指令集不够熟悉一些偏门指令如果不知道那就完犊子了

这是我还原最后一个handle看出来的 原先我以为是cmp 但是不对劲,简而言之就是每一次call 后会检查返回值 如果返回值对 vm_pc+2 结合br指令集 lr = pc+2 刚好四字节对齐,如果不对 哦吼 pc +2 指令集对齐直接挂 随机崩溃
图片描述
图片描述
br handle
图片描述

// unsigned int code
// Bit_28_State = code & 0x10000000;
// Bit_29_State = code & 0x20000000;
// Bit_30_State = code & 0x40000000;
// v17 = (code >> 11) & 2 | (code >> 31) | (code >> 11) & 4 | (code >> 11) & 8 | (code >> 11) & 0x10;// 提取第31位 提取第12,13,14,15位 组合
//                                           // [15,14,13,12,31]
// sourceREG = (code >> 21) & 0x1F;          // 取第22 =>26的值
//                                           // [26,25,24,23,22]
// destREG = HIWORD(code) & 0x1F;            // 17 > 21
//                                           // [21,20,19,18,17]
// Bit_31_State = code & 0x80000000;
// Bit_30_State_1 = code & 0x4000000;
// Bit_31_State_1 = code & 0x8000000;
var type = code.and(0x3f)
var code = this.vm_handles
var sourceREG = code.shr(21).and(0x1F)
var destREG = code.shr(16).and(0x1F)
 
var Bit_28_State = code.and(0x10000000)
var Bit_29_State = code.and(0x20000000)
var Bit_30_State = code.and(0x40000000)
var Bit_31_State = code.and(0x80000000)
var Bit_30_State_1 = code.and(0x4000000)
var Bit_31_State_1 = code.and(0x8000000)
var intv17 = code.toUInt32()
var v17 = (intv17 >>> 11) & 2 | (intv17 >>> 31) | (intv17 >>> 11) & 4 | (intv17 >>> 11) & 8 | (intv17 >>> 11) & 0x10
let opcode = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
// unsigned int code
// Bit_28_State = code & 0x10000000;
// Bit_29_State = code & 0x20000000;
// Bit_30_State = code & 0x40000000;
// v17 = (code >> 11) & 2 | (code >> 31) | (code >> 11) & 4 | (code >> 11) & 8 | (code >> 11) & 0x10;// 提取第31位 提取第12,13,14,15位 组合
//                                           // [15,14,13,12,31]
// sourceREG = (code >> 21) & 0x1F;          // 取第22 =>26的值
//                                           // [26,25,24,23,22]
// destREG = HIWORD(code) & 0x1F;            // 17 > 21
//                                           // [21,20,19,18,17]
// Bit_31_State = code & 0x80000000;
// Bit_30_State_1 = code & 0x4000000;
// Bit_31_State_1 = code & 0x8000000;
var type = code.and(0x3f)
var code = this.vm_handles
var sourceREG = code.shr(21).and(0x1F)
var destREG = code.shr(16).and(0x1F)
 
var Bit_28_State = code.and(0x10000000)
var Bit_29_State = code.and(0x20000000)
var Bit_30_State = code.and(0x40000000)
var Bit_31_State = code.and(0x80000000)
var Bit_30_State_1 = code.and(0x4000000)
var Bit_31_State_1 = code.and(0x8000000)
var intv17 = code.toUInt32()
var v17 = (intv17 >>> 11) & 2 | (intv17 >>> 31) | (intv17 >>> 11) & 4 | (intv17 >>> 11) & 8 | (intv17 >>> 11) & 0x10
let opcode = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
decode(): string {
       //ArrayBuffer to ptr
       var type = this.vm_handles.and(0x3F)
       // unsigned int code
       // Bit_28_State = code & 0x10000000;
       // Bit_29_State = code & 0x20000000;
       // Bit_30_State = code & 0x40000000;
       // v17 = (code >> 11) & 2 | (code >> 31) | (code >> 11) & 4 | (code >> 11) & 8 | (code >> 11) & 0x10;// 提取第31位 提取第12,13,14,15位 组合
       //                                           // [15,14,13,12,31]
       // sourceREG = (code >> 21) & 0x1F;          // 取第22 =>26的值
       //                                           // [26,25,24,23,22]
       // destREG = HIWORD(code) & 0x1F;            // 17 > 21
       //                                           // [21,20,19,18,17]
       // Bit_31_State = code & 0x80000000;
       // Bit_30_State_1 = code & 0x4000000;
       // Bit_31_State_1 = code & 0x8000000;
       var code = this.vm_handles
       var sourceREG = code.shr(21).and(0x1F)
       var destREG = code.shr(16).and(0x1F)
 
       var Bit_28_State = code.and(0x10000000)
       var Bit_29_State = code.and(0x20000000)
       var Bit_30_State = code.and(0x40000000)
       var Bit_31_State = code.and(0x80000000)
       var Bit_30_State_1 = code.and(0x4000000)
       var Bit_31_State_1 = code.and(0x8000000)
       var intv17 = code.toUInt32()
       var v17 = (intv17 >>> 11) & 2 | (intv17 >>> 31) | (intv17 >>> 11) & 4 | (intv17 >>> 11) & 8 | (intv17 >>> 11) & 0x10
       let opcode = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
                
       switch (type.toUInt32()) {
           case 3:
           case 5:
           case 0xF:
           case 0x1A:
           case 0x2C:
           case 0x2D:
           case 0x3A:
           case 0x3F:
               switch (type.toUInt32()) {
                   case 5:
                   case 0xF:
                   case 0x2C:
                   case 0x3A:
                       return "cmp " + this.reg(sourceREG) + "," + this.reg(destREG)
               }
                
           case 0x2:
               // vm_regs[(HIWORD(vm_code_1) & 0x1F) + 1] = *(_QWORD *)(vm_regs[((vm_code_1 >> 21) & 0x1F) + 1]
               // + (__int16)(vm_code_1 & 0xF000 | ((vm_code_1 & 0x4000000) >> 20) | (vm_code_1 >> 6) & 0x3F | ((vm_code_1 & 0x8000000) >> 20) | ((vm_code_1 & 0x10000000) >> 20) | ((vm_code_1 & 0x20000000) >> 20) | ((vm_code_1 & 0x40000000) >> 20) | ((vm_code_1 & 0x80000000) >> 20)));
               let opcode1 = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
               return "ldr " + this.reg(destREG) + ",[" + this.reg(sourceREG) + ",#" + opcode1 + "]"
           case 0xA:
           case 0xB:
           case 0xE:
           case 0x14:
           case 0x16:
           case 0x24:
           case 0x36:
           case 0x3b:
               // (__int16)(code & 0xF000 | (Bit_30_State_1 >> 20) | (code >> 6) & 0x3F | (Bit_31_State_1 >> 20) | (Bit_28_State >> 20) | (Bit_29_State >> 20) | (Bit_30_State >> 20) | (Bit_31_State >> 20));
               let opcode = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
               return "stp " + this.reg(destREG) + " ,[" + this.reg(sourceREG) + "," + opcode + "]"
           case 4:
           case 0x20:
           case 0x38:
           case 0x3e:
               // v39 = vm_code_1 & 0x3F;
               // if (v39 > 0x37) {
               //     if (v39 == 56) {
               // * (& v5 -> REGS + (unsigned int)v19) = * (& v5 -> REGS + (unsigned int)v18) ^ (vm_code_1 & 0xF000 | (v21 >> 20) | (vm_code_1 >> 6) & 0x3F | (v22 >> 20) | (v14 >> 20) | (v15 >> 20) | (v16 >> 20) | (v20 >> 20));
               //     }
               //     else if (v39 == 62) {
               // * (& v5 -> REGS + (unsigned int)v19) = * (& v5 -> REGS + (unsigned int)v18) | vm_code_1 & 0xF000 | (v21 >> 20) | (vm_code_1 >> 6) & 0x3F | (v22 >> 20) | (v14 >> 20) | (v15 >> 20) | (v16 >> 20) | (v20 >> 20);
               //     }
               // }
               // else {
               //     if (v39 == 4) {
               //         LODWORD(v18) = (vm_code_1 & 0xF000 | (v21 >> 20) | (vm_code_1 >> 6) & 0x3F | (v22 >> 20) | (v14 >> 20) | (v15 >> 20) | (v16 >> 20) | (v20 >> 20)) << 16;
               // v18 = (int)v18;
               // v25 = &vm_regs[(unsigned int)v19];
               // v25[1] = v18;
               //     }
               //     if (v39 == 32)
               // * (& v5 -> REGS + (unsigned int)v19) = * (& v5 -> REGS + (unsigned int)v18) & (vm_code_1 & 0xF000 | (v21 >> 20) | (vm_code_1 >> 6) & 0x3F | (v22 >> 20) | (v14 >> 20) | (v15 >> 20) | (v16 >> 20) | (v20 >> 20));
               // }
               var v39 = code.and(0x3F)
               let opcode2 = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
               if(v39.toUInt32() > 0x37){
                   if(v39.toUInt32() == 56){
                       return "eor " + this.reg(destREG) + "," + this.reg(sourceREG) + "," + opcode2
                   }else if(v39.toUInt32() == 62){
                       return "orr " + this.reg(destREG) + "," + this.reg(sourceREG) + "," + opcode2
                   }
               }else{
                   if(v39.toUInt32() == 4){
                       return "mov " + this.reg(destREG) + "," + opcode2
                   }else if(v39.toUInt32() == 32){
                       return "and " + this.reg(destREG) + "," + this.reg(sourceREG) + "," + opcode2
                   }
               }
           case 0:
           case 2:
           case 8:
           case 0x12:
           case 0x1F:
           case 0x21:
           case 0x22:
           case 0x27:
           case 0x2B:
           case 0x30:
           case 0x31:
           case 0x33:
           case 0x37:
               return "mov " + this.reg(destREG) + " , " + this.reg(sourceREG)
           case 0xD:
           case 0x15:
           case 0x1B:
           case 0x28:
               // v40 = vm_code_1 & 0x3F;
               // v41 = vm_code_1 & 0xF000 | (v21 >> 20) | (vm_code_1 >> 6) & 0x3F | (v22 >> 20) | (v14 >> 20) | (v15 >> 20) | (v16 >> 20) | (v20 >> 20);
               // if ( v40 == 13 || v40 == 40 )
               // {
               //   *(&v5->REGS + (unsigned int)v19) = *(&v5->REGS + (unsigned int)v18) + (__int16)v41;
               // }
               // else if ( v40 == 21 )
               //     {
               //       *(&v5->REGS + (unsigned int)v19) = *((int *)&v5->REGS + 2 * v18) + (__int64)(__int16)v41;
               //     }
               let v40 = code.and(0x3F)
               let v41 = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
               if (v40.toUInt32() == 13 || v40.toUInt32() == 40) {
                   return "add " + this.reg(destREG) + "," + this.reg(sourceREG) + "," + v41
               }
               else if (v40.toUInt32() == 21) {
                   return "add " + this.reg(destREG) + "," + this.reg(sourceREG.shl(1)) + "," + v41
               }
           case 0x2f:
               // v71 = vm_code_1 & 0xFFF;
               // HIDWORD(v72) = v71 - 111;
               // LODWORD(v72) = HIDWORD(v72);
               // switch ( (unsigned int)(v72 >> 6) )
               var v71 = code.and(0xFFF)
               var v72 = v71.sub(111)
               switch (v72.shr(6).toUInt32()) {
                   case 0x30:
                       if (v71.toInt32() == 0xC6F)
                           // p_REGS = &v5->REGS;
                           // v96 = *((_DWORD *)&v5->REGS + 2 * v19) << (((vm_code_1 & 0x10000000) >> 26) & 0xFC | (vm_code_1 >> 26) & 3 | ((vm_code_1 & 0x20000000) >> 26) | ((vm_code_1 & 0x40000000) >> 26));
                       
                           return "ldr " + this.reg(destREG) + ",[" + this.reg(sourceREG.shl(1)) + ",#" + code.shr(26).and(0xFC).or(Bit_28_State.shr(26).and(3)).or(Bit_29_State.shr(26)).or(Bit_30_State.shr(26)).or(Bit_31_State.shr(26)) + "]"
                       return "ret"
                   case 0x15:
                       if(v71.toInt32() == 0x5af)
                           return "br " + this.reg(sourceREG)
                   case 0x19:
                       return "ret"
                   case 6:
                   case 0xD:
                   case 0x1A:
                   case 0x20:
                   case 0x24:
                   case 0x26:
                   case 0x28:
                   case 0x33:
                       //   v73 = vm_code_1 & 0xFFF;
                       //   if ( v73 > 0x86E )
                       //   {
                       //     if ( (vm_code_1 & 0xFFF) <= 0x9EE )
                       //       goto LABEL_154;
                       //     goto LABEL_64;
                       //   }
                       //   if ( (vm_code_1 & 0xFFF) > 0x3AE )
                       //     goto LABEL_254;
                       //   if ( v73 != 495 )
                       //     goto LABEL_218;
                       //   goto LABEL_252;
                       var v73 = v71.toUInt32()
                       if (v73 > 0x86E) {
                           if (v71.toUInt32() <= 0x9EE) {
                               return "ret"
                           } else {
                               if ( v73 == 2543 )
                                   // *(&v5->REGS + v17) = *(&v5->REGS + (unsigned int)v19) + *(&v5->REGS + (unsigned int)v18);
                                   return "add " + this.reg(ptr(v17)) + "," + this.reg(destREG) + "," + this.reg(sourceREG)
                           }
                       }
                       if (v73 > 0x3AE) {
                           return "ret"
                       }
                       if (v73 != 495) {
                           return "ret"
                       } else {
                           return "ret"
                       }
                   case 0xC:
                   case 0x17:
                   case 0x1F:
                   case 0x3C:
                       //             v108 = vm_code_1 & 0xFFF;
                       //   if ( v108 > 0x82E )
                       //   {
                       //     if ( v108 == 2095 )
                       //     {
                       //       *(&v5->REGS + v17) = ~(*(&v5->REGS + (unsigned int)v19) | *(&v5->REGS + (unsigned int)v18));
                       //     }
                       //     else if ( v108 == 3951 )
                       //     {
                       //       *(&v5->REGS + v17) = *(&v5->REGS + (unsigned int)v19) & *(&v5->REGS + (unsigned int)v18);
                       //     }
                       //   }
                       //   else if ( v108 == 879 )
                       //   {
                       //     *(&v5->REGS + v17) = *(&v5->REGS + (unsigned int)v19) ^ *(&v5->REGS + (unsigned int)v18);
                       //   }
                       //   else if ( v108 == 1583 )
                       //   {
                       //     *(&v5->REGS + v17) = *(&v5->REGS + (unsigned int)v19) | *(&v5->REGS + (unsigned int)v18);
                       //   }
                       var v108 = v71.toUInt32()
                       if (v108 > 0x82E) {
                           if (v108 == 2095) {
                               return "not " + this.reg(ptr(v17)) + "," + this.reg(destREG) + "," + this.reg(sourceREG)
                           } else if (v108 == 3951) {
                               return "and " + this.reg(ptr(v17)) + "," + this.reg(destREG) + "," + this.reg(sourceREG)
                           }
 
                       } else if (v108 == 879) {
                           return "eor " + this.reg(ptr(v17)) + "," + this.reg(destREG) + "," + this.reg(sourceREG)
                       } else if (v108 == 1583) {
                           return "orr " + this.reg(ptr(v17)) + "," + this.reg(destREG) + "," + this.reg(sourceREG)
                       }
               }
       }
 
       return ""
   }
   reg(index: NativePointer): string {
       var index1 = index.toUInt32()
       if (index1 == 31) {
           return "lr"
       }
       if (index1 == 29) {
           return "sp"
       }
       if (index1 == 30) {
           return "fp"
       }
       return "x" + index1
   }
decode(): string {
       //ArrayBuffer to ptr
       var type = this.vm_handles.and(0x3F)
       // unsigned int code
       // Bit_28_State = code & 0x10000000;
       // Bit_29_State = code & 0x20000000;
       // Bit_30_State = code & 0x40000000;
       // v17 = (code >> 11) & 2 | (code >> 31) | (code >> 11) & 4 | (code >> 11) & 8 | (code >> 11) & 0x10;// 提取第31位 提取第12,13,14,15位 组合
       //                                           // [15,14,13,12,31]
       // sourceREG = (code >> 21) & 0x1F;          // 取第22 =>26的值
       //                                           // [26,25,24,23,22]
       // destREG = HIWORD(code) & 0x1F;            // 17 > 21
       //                                           // [21,20,19,18,17]
       // Bit_31_State = code & 0x80000000;
       // Bit_30_State_1 = code & 0x4000000;
       // Bit_31_State_1 = code & 0x8000000;
       var code = this.vm_handles
       var sourceREG = code.shr(21).and(0x1F)
       var destREG = code.shr(16).and(0x1F)
 
       var Bit_28_State = code.and(0x10000000)
       var Bit_29_State = code.and(0x20000000)
       var Bit_30_State = code.and(0x40000000)
       var Bit_31_State = code.and(0x80000000)
       var Bit_30_State_1 = code.and(0x4000000)
       var Bit_31_State_1 = code.and(0x8000000)
       var intv17 = code.toUInt32()
       var v17 = (intv17 >>> 11) & 2 | (intv17 >>> 31) | (intv17 >>> 11) & 4 | (intv17 >>> 11) & 8 | (intv17 >>> 11) & 0x10
       let opcode = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
                
       switch (type.toUInt32()) {
           case 3:
           case 5:
           case 0xF:
           case 0x1A:
           case 0x2C:
           case 0x2D:
           case 0x3A:
           case 0x3F:
               switch (type.toUInt32()) {
                   case 5:
                   case 0xF:
                   case 0x2C:
                   case 0x3A:
                       return "cmp " + this.reg(sourceREG) + "," + this.reg(destREG)
               }
                
           case 0x2:
               // vm_regs[(HIWORD(vm_code_1) & 0x1F) + 1] = *(_QWORD *)(vm_regs[((vm_code_1 >> 21) & 0x1F) + 1]
               // + (__int16)(vm_code_1 & 0xF000 | ((vm_code_1 & 0x4000000) >> 20) | (vm_code_1 >> 6) & 0x3F | ((vm_code_1 & 0x8000000) >> 20) | ((vm_code_1 & 0x10000000) >> 20) | ((vm_code_1 & 0x20000000) >> 20) | ((vm_code_1 & 0x40000000) >> 20) | ((vm_code_1 & 0x80000000) >> 20)));
               let opcode1 = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
               return "ldr " + this.reg(destREG) + ",[" + this.reg(sourceREG) + ",#" + opcode1 + "]"
           case 0xA:
           case 0xB:
           case 0xE:
           case 0x14:
           case 0x16:
           case 0x24:
           case 0x36:
           case 0x3b:
               // (__int16)(code & 0xF000 | (Bit_30_State_1 >> 20) | (code >> 6) & 0x3F | (Bit_31_State_1 >> 20) | (Bit_28_State >> 20) | (Bit_29_State >> 20) | (Bit_30_State >> 20) | (Bit_31_State >> 20));
               let opcode = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
               return "stp " + this.reg(destREG) + " ,[" + this.reg(sourceREG) + "," + opcode + "]"
           case 4:
           case 0x20:
           case 0x38:
           case 0x3e:
               // v39 = vm_code_1 & 0x3F;
               // if (v39 > 0x37) {
               //     if (v39 == 56) {
               // * (& v5 -> REGS + (unsigned int)v19) = * (& v5 -> REGS + (unsigned int)v18) ^ (vm_code_1 & 0xF000 | (v21 >> 20) | (vm_code_1 >> 6) & 0x3F | (v22 >> 20) | (v14 >> 20) | (v15 >> 20) | (v16 >> 20) | (v20 >> 20));
               //     }
               //     else if (v39 == 62) {
               // * (& v5 -> REGS + (unsigned int)v19) = * (& v5 -> REGS + (unsigned int)v18) | vm_code_1 & 0xF000 | (v21 >> 20) | (vm_code_1 >> 6) & 0x3F | (v22 >> 20) | (v14 >> 20) | (v15 >> 20) | (v16 >> 20) | (v20 >> 20);
               //     }
               // }
               // else {
               //     if (v39 == 4) {
               //         LODWORD(v18) = (vm_code_1 & 0xF000 | (v21 >> 20) | (vm_code_1 >> 6) & 0x3F | (v22 >> 20) | (v14 >> 20) | (v15 >> 20) | (v16 >> 20) | (v20 >> 20)) << 16;
               // v18 = (int)v18;
               // v25 = &vm_regs[(unsigned int)v19];
               // v25[1] = v18;
               //     }
               //     if (v39 == 32)
               // * (& v5 -> REGS + (unsigned int)v19) = * (& v5 -> REGS + (unsigned int)v18) & (vm_code_1 & 0xF000 | (v21 >> 20) | (vm_code_1 >> 6) & 0x3F | (v22 >> 20) | (v14 >> 20) | (v15 >> 20) | (v16 >> 20) | (v20 >> 20));
               // }
               var v39 = code.and(0x3F)
               let opcode2 = code.and(0xF000).or(Bit_30_State_1.shr(20)).or(code.shr(6).and(0x3F)).or(Bit_31_State_1.shr(20)).or(Bit_28_State.shr(20)).or(Bit_29_State.shr(20)).or(Bit_30_State.shr(20)).or(Bit_31_State.shr(20))
               if(v39.toUInt32() > 0x37){
                   if(v39.toUInt32() == 56){
                       return "eor " + this.reg(destREG) + "," + this.reg(sourceREG) + "," + opcode2
                   }else if(v39.toUInt32() == 62){
                       return "orr " + this.reg(destREG) + "," + this.reg(sourceREG) + "," + opcode2
                   }
               }else{
                   if(v39.toUInt32() == 4){
                       return "mov " + this.reg(destREG) + "," + opcode2
                   }else if(v39.toUInt32() == 32){
                       return "and " + this.reg(destREG) + "," + this.reg(sourceREG) + "," + opcode2
                   }
               }
           case 0:
           case 2:
           case 8:
           case 0x12:
           case 0x1F:
           case 0x21:
           case 0x22:
           case 0x27:

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 48
支持
分享
最新回复 (19)
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
好东西,感谢分享
2天前
0
雪    币: 185
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
2天前
0
雪    币: 223
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
你的帖子非常有用,感谢分享!
2天前
0
雪    币: 1360
活跃值: (2816)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
666
2天前
0
雪    币: 376
活跃值: (2135)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
2天前
0
雪    币: 24
活跃值: (810)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
来看看
2天前
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
1
2天前
0
雪    币: 489
活跃值: (1027)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
学习
2天前
0
雪    币: 1913
活跃值: (7604)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
Been looking for this
2天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
1
2天前
0
雪    币: 439
活跃值: (1243)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
学习一下
1天前
0
雪    币: 2314
活跃值: (3067)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
感谢分享
1天前
0
雪    币: 9049
活跃值: (4449)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
感谢分享
1天前
0
雪    币: 74
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
1天前
0
雪    币: 13
活跃值: (1888)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
感谢分享
21小时前
0
雪    币: 94
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
学习一下
14小时前
0
雪    币: 18
活跃值: (696)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
太好了,好好学习一下
3小时前
0
雪    币: 221
活跃值: (2391)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
学习一下 
2小时前
0
雪    币: 374
活跃值: (685)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
好东西,感谢分享
53分钟前
0
游客
登录 | 注册 方可回帖
返回
//