直接引码:
for (int i = 0; i < 4; i++) { 01222056 mov dword ptr [ebp-4],0 // # var i 0122205D jmp fun_pickup_from_map+28h (01222068h) 0122205F mov eax,dword ptr [ebp-4] // refer i 01222062 add eax,1 // i++ 01222065 mov dword ptr [ebp-4],eax 01222068 cmp dword ptr [ebp-4],4 // # cmp i, 4 0122206C jge fun_pickup_from_map+57h (01222097h) // ... }
以下对应VMP3的虚拟指令:
# i = 0 0087 006A6ED1 vAdd4 0018FEDC <- FFFFFFFC, <ebp>0018FEE0 0088 00688494 vPopReg4 [004] <- 00000203 0089 007416A8 vReadMemSs4 [0018FEDC] -> 00000000 # cmp i, 4 # ~i 0090 0052FDC6 vPushEsp4 0018FE82 0091 0073A93F vReadMemSs4 [0018FE82] -> 00000000 0092 005EEFA2 vNand4 FFFFFFFF <- 00000000, 00000000 0093 006B7196 vPopReg4 [010] <- 00000286 # ~i + 4 0094 0072EEBE vAdd4 00000003 <- FFFFFFFF, 00000004 0095 006C187D vPopReg4 [010] <- 00000217 # ~(~i + 4) => i - 4 0096 00560EEB vPushEsp4 0018FE86 0097 005AC9B3 vReadMemSs4 [0018FE86] -> 00000003 0098 0067C7EB vNor4 FFFFFFFC <- 00000003, 00000003 0099 004FF4B9 vPopReg4 [018] <- 00000286 0100 0071E4FC vPopReg4 [024] <- FFFFFFFC # f1 = eflags of ~i + 4 0101 00519664 vPushReg4 [010] 00000217 0102 006A846B vPushImm4 2E7D332F 0103 0067C969 vPushImm4 004AB24C 0104 0064EFA4 vReadMemSs4 [004AB24C] -> D182D4E6 # NOTE: 0x815 0105 005C6201 vAdd4 00000815 <- D182D4E6, 2E7D332F 0106 00639539 vPopReg4 [01C] <- 00000213 0107 006D4743 vNand4 FFFFFFEA <- 00000815, 00000217 0108 00531E52 vPopReg4 [024] <- 00000282 0109 00645F27 vPushEsp4 0018FE86 0110 005ED537 vReadMemSs4 [0018FE86] -> FFFFFFEA 0111 00510455 vNor4 00000015 <- FFFFFFEA, FFFFFFEA 0112 005919C4 vPopReg4 [008] <- 00000202 # f2 = eflags of ~(~i + 4) 0113 005188E3 vPushReg4 [018] 00000286 0114 00700BC1 vPushImm4 BEC22E73 0115 0073CFF4 vPushImm4 004AB250 0116 004E3333 vReadMemSs4 [004AB250] -> 413DC977 0117 0057E963 vAdd4 FFFFF7EA <- 413DC977, BEC22E73 0118 00551056 vPopReg4 [004] <- 00000282 # NOTE: FFFFF7EA == ~0x815 0119 0052C370 vNand4 FFFFFD7D <- FFFFF7EA, 00000286 0120 006519B6 vPopReg4 [020] <- 00000286 0121 004AE960 vPushEsp4 0018FE82 0122 00675D8B vReadMemSs4 [0018FE82] -> FFFFFD7D 0123 004F6BCA vNor4 00000282 <- FFFFFD7D, FFFFFD7D 0124 00523E4C vPopReg4 [020] <- 00000206 # => eflags = (f1 & 0x815) + (f2 & ~0x815) 0125 0055A32C vAdd4 00000297 <- 00000282, 00000015 0126 00688494 vPopReg4 [030] <- 00000202 0127 006B7196 vPopReg4 [030] <- 00000297 0128 006C187D vPopReg4 [024] <- 00000207 0129 004FBD09 vPushReg4 [030] 00000297 0130 006B2A12 vPushReg4 [030] 00000297 0131 00525C60 vNand4 FFFFFD68 <- 00000297, 00000297 0132 004FF4B9 vPopReg4 [004] <- 00000282 0133 005A067A vPushImm4 57A4C945 0134 005A793D vPushImm4 004AB256 0135 00617E7D vReadMemSs4 [004AB256] -> A85B363A 0136 006FBCFE vAdd4 FFFFFF7F <- A85B363A, 57A4C945 0137 0071E4FC vPopReg4 [010] <- 00000282 # a = eflags & SF 0138 004AEAD6 vNor4 00000080 <- FFFFFF7F, FFFFFD68 0139 00639539 vPopReg4 [024] <- 00000202 0140 00531E52 vPopReg4 [004] <- 00000080 0141 004E4FCE vPushReg4 [030] 00000297 0142 005147F9 vPushImm4 673258CD 0143 0072A795 vPushImm4 004AB25A 0144 006E9C8F vReadMemSs4 [004AB25A] -> 98CDAF33 0145 0076946A vAdd4 00000800 <- 98CDAF33, 673258CD 0146 005919C4 vPopReg4 [01C] <- 00000217 # b = eflags & OF 0147 0052FBE7 vNand4 FFFFFFFF <- 00000800, 00000297 0148 00551056 vPopReg4 [010] <- 00000286 0149 0066B4C7 vPushEsp4 0018FE8A 0150 0053AA78 vReadMemSs4 [0018FE8A] -> FFFFFFFF 0151 004EECA7 vNand4 00000000 <- FFFFFFFF, FFFFFFFF 0152 006519B6 vPopReg4 [01C] <- 00000246 0153 00523E4C vPopReg4 [010] <- 00000000 0154 006FA614 vPushReg4 [024] 00000202 0155 005626A0 vPushReg4 [024] 00000202 0156 0072F738 vNand4 FFFFFDFD <- 00000202, 00000202 0157 00688494 vPopReg4 [008] <- 00000282 0158 005CC9A6 vPushReg4 [01C] 00000246 0159 00595AA8 vPushReg4 [01C] 00000246 0160 0065994B vNor4 FFFFFDB9 <- 00000246, 00000246 0161 006B7196 vPopReg4 [010] <- 00000282 # c = a_eflags & b_eflags 0162 005582AF vNor4 00000202 <- FFFFFDB9, FFFFFDFD 0163 006C187D vPopReg4 [010] <- 00000202 # d = ~a_eflags & ~b_eflags 0164 006FD628 vPushReg4 [024] 00000202 0165 005B5F3B vPushReg4 [01C] 00000246 0166 0050A804 vNor4 FFFFFDB9 <- 00000246, 00000202 0167 004FF4B9 vPopReg4 [004] <- 00000282 # e = nor(c, d) 0168 006B1989 vNor4 00000044 <- FFFFFDB9, 00000202 0169 0071E4FC vPopReg4 [004] <- 00000206 0170 00639539 vPopReg4 [010] <- 00000044 # e = c | d => nxor(c, d) => if(c == d) 0171 00519664 vPushReg4 [010] 00000044 0172 005188E3 vPushReg4 [010] 00000044 0173 00574BF9 vNor4 FFFFFFBB <- 00000044, 00000044 0174 00531E52 vPopReg4 [018] <- 00000286 0175 005919C4 vPopReg4 [004] <- FFFFFFBB # g = e & ZF 0176 004FBD09 vPushReg4 [004] FFFFFFBB 0177 006B2A12 vPushReg4 [004] FFFFFFBB 0178 0063803A vNand4 00000044 <- FFFFFFBB, FFFFFFBB 0179 00551056 vPopReg4 [008] <- 00000206 0180 00700D65 vPushImm4 F291278B 0181 005C99F9 vPushImm4 004AB25E 0182 005267FF vReadMemSs4 [004AB25E] -> 0D6ED834 0183 0071F837 vAdd4 FFFFFFBF <- 0D6ED834, F291278B 0184 006519B6 vPopReg4 [010] <- 00000282 0185 00621576 vNor4 00000000 <- FFFFFFBF, 00000044 0186 00523E4C vPopReg4 [018] <- 00000246 # h = g >> 0x6 // 0 or 1 0187 005E5B67 vShr4 00000000 <- 00000000, 00000006 0188 00688494 vPopReg4 [020] <- 00000246 0189 006A846B vPushImm4 C207B9AF 0190 0067C969 vPushImm4 004AB262 0191 00715986 vReadMemSs4 [004AB262] -> 3DF84650 0192 00698BD3 vAdd4 FFFFFFFF <- 3DF84650, C207B9AF 0193 006B7196 vPopReg4 [020] <- 00000286 # h1 = h - 1 0194 006A8ACA vAdd4 FFFFFFFF <- FFFFFFFF, 00000000 0195 006C187D vPopReg4 [018] <- 00000286 0196 004FF4B9 vPopReg4 [020] <- FFFFFFFF 0197 005C99F9 vPushImm4 94315D17 0198 0073CFF4 vPushImm4 004AB266 0199 005B610F vReadMemSs4 [004AB266] -> 6C423157 0200 006010F8 vAdd4 00738E6E <- 6C423157, 94315D17 0201 0071E4FC vPopReg4 [008] <- 00000203 0202 004E4FCE vPushReg4 [020] FFFFFFFF 0203 006FA614 vPushReg4 [020] FFFFFFFF 0204 0071DD9C vNand4 00000000 <- FFFFFFFF, FFFFFFFF 0205 00639539 vPopReg4 [018] <- 00000246 # h2 = nand(~h1, 00738E6E) 0206 006027AC vNand4 FFFFFFFF <- 00000000, 00738E6E 0207 00531E52 vPopReg4 [024] <- 00000286 # h3 = ~h2 => ~h1 & 00738E6E 0208 006EB142 vPushEsp4 0018FE8C 0209 00573C6C vReadMemSs4 [0018FE8C] -> FFFFFFFF 0210 006CC28D vNand4 00000000 <- FFFFFFFF, FFFFFFFF 0211 005919C4 vPopReg4 [018] <- 00000246 0212 006A846B vPushImm4 A39EE577 0213 005A067A vPushImm4 004AB26A 0214 00612BD5 vReadMemSs4 [004AB26A] -> 5CD4A85E 0215 006A6ED1 vAdd4 00738DD5 <- 5CD4A85E, A39EE577 0216 00551056 vPopReg4 [01C] <- 00000213 # h4 = nand(h1, 00738DD5) 0217 005626A0 vPushReg4 [020] FFFFFFFF 0218 005EEFA2 vNand4 FF8C722A <- FFFFFFFF, 00738DD5 0219 006519B6 vPopReg4 [018] <- 00000282 # h5 = ~h4 => h1 & 00738DD5 0220 004AE312 vPushEsp4 0018FE88 0221 00580DA6 vReadMemSs4 [0018FE88] -> FF8C722A 0222 006D4743 vNand4 00738DD5 <- FF8C722A, FF8C722A 0223 00523E4C vPopReg4 [018] <- 00000202 # h6 = h5 + h3 0224 0072EEBE vAdd4 00738DD5 <- 00738DD5, 00000000 0225 00688494 vPopReg4 [01C] <- 00000202 # h7 = vbase + h6 0226 005CC9A6 vPushReg4 [00C] 00000000 0227 005C6201 vAdd4 00738DD5 <- 00000000, 00738DD5
以上代码过多,请按需要决定阅读,阅读的时候,请参照汇编代码。以下做分析说明
for 循环中的 i<4; 对应 jnl/jge 跳转指令,指令测试条件为 SF==OF,在循环中如果测试条件成立则跳出循环。在虚拟机中执行逻辑过程:
通过以上执行逻辑,我们可以找到一些可以应用:
另:最近在逆向mt4的通讯协议进行学习金融交易系统,新版mt4采用新版vmp进行订制性保护。工作量非常巨大,所以开发了几个工具。而在开发工具的过程中,得到了一些关于vmp方面的思路。其中一个想法是:把vmp中的虚拟指令转编为其他语言表示,如汇编或C/CPP。但由于当前手上工作量庞大,想招募一两个擅长或特别有兴趣于vmp的伙伴组个队完成这个小工具。由汇编到虚拟指令的工具已经完成。
[公告][征集寄语] 看雪20周年年会 | 感恩有你,一路同行
最后于 6小时前 被yiivon编辑 ,原因: