[RE] Babyvm - cew xp0int Posted on Sep 12 2021 调试时dump smc代码,patch源程序方便F5。然后用python模拟下虚拟机指令,得到执行流程。 模拟程序 ``` opcode = [161, 193, 0, 177, 119, 194, 74, 1, 0, 0, 193, 1, 178, 119, 194, 25, 1, 0, 0, 193, 2, 180, 119, 194, 221, 1, 0, 0, 193, 3, 179, 119, 194, 15, 1, 0, 0, 193, 4, 178, 119, 194, 27, 1, 0, 0, 193, 5, 180, 119, 194, 137, 1, 0, 0, 193, 6, 177, 119, 194, 25, 1, 0, 0, 193, 7, 179, 119, 194, 84, 1, 0, 0, 193, 8, 177, 119, 194, 79, 1, 0, 0, 193, 9, 177, 119, 194, 78, 1, 0, 0, 193, 10, 179, 119, 194, 85, 1, 0, 0, 193, 11, 179, 119, 194, 86, 1, 0, 0, 193, 12, 180, 119, 194, 142, 0, 0, 0, 193, 13, 178, 119, 194, 73, 0, 0, 0, 193, 14, 179, 119, 194, 14, 1, 0, 0, 193, 15, 177, 119, 194, 75, 1, 0, 0, 193, 16, 179, 119, 194, 6, 1, 0, 0, 193, 17, 179, 119, 194, 84, 1, 0, 0, 193, 18, 178, 119, 194, 26, 0, 0, 0, 193, 19, 177, 119, 194, 66, 1, 0, 0, 193, 20, 179, 119, 194, 83, 1, 0, 0, 193, 21, 177, 119, 194, 31, 1, 0, 0, 193, 22, 179, 119, 194, 82, 1, 0, 0, 193, 23, 180, 119, 194, 219, 0, 0, 0, 193, 24, 177, 119, 194, 25, 1, 0, 0, 193, 25, 180, 119, 194, 217, 0, 0, 0, 193, 26, 177, 119, 194, 25, 1, 0, 0, 193, 27, 179, 119, 194, 85, 1, 0, 0, 193, 28, 178, 119, 194, 25, 0, 0, 0, 193, 29, 179, 119, 194, 0, 1, 0, 0, 193, 30, 177, 119, 194, 75, 1, 0, 0, 193, 31, 178, 119, 194, 30, 0, 0, 0, 193, 32, 128, 2, 24, 0, 0, 0, 35, 16, 193, 33, 128, 2, 16, 0, 0, 0, 35, 247, 193, 34, 128, 2, 8, 0, 0, 0, 35, 247, 193, 35, 247, 254, 128, 2, 5, 0, 0, 0, 34, 119, 16, 128, 2, 7, 0, 0, 0, 35, 128, 2, 35, 119, 241, 152, 49, 119, 16, 128, 2, 24, 0, 0, 0, 35, 128, 2, 32, 185, 228, 53, 49, 119, 16, 128, 2, 18, 0, 0, 0, 34, 119, 160, 193, 36, 128, 2, 24, 0, 0, 0, 35, 16, 193, 37, 128, 2, 16, 0, 0, 0, 35, 247, 193, 38, 128, 2, 8, 0, 0, 0, 35, 247, 193, 39, 247, 254, 50, 32, 67, 51, 119, 128, 2, 17, 0, 0, 0, 34, 53, 55, 56, 119, 128, 2, 13, 0, 0, 0, 35, 119, 56, 57, 16, 50, 32, 67, 51, 119, 128, 2, 17, 0, 0, 0, 34, 53, 55, 56, 119, 128, 2, 13, 0, 0, 0, 35, 119, 56, 57, 199, 193, 40, 128, 2, 24, 0, 0, 0, 35, 16, 193, 41, 128, 2, 16, 0, 0, 0, 35, 247, 193, 42, 128, 2, 8, 0, 0, 0, 35, 247, 193, 43, 247, 254, 50, 32, 67, 51, 119, 128, 2, 17, 0, 0, 0, 34, 53, 55, 56, 119, 128, 2, 13, 0, 0, 0, 35, 119, 56, 57, 16, 50, 32, 67, 51, 119, 128, 2, 17, 0, 0, 0, 34, 53, 55, 56, 119, 128, 2, 13, 0, 0, 0, 35, 119, 56, 57, 200, 0x99] eip = 0 while eip < len(opcode): op = opcode[eip] if op == 113: int_val = int.from_bytes(bytes(opcode[eip+1:eip+5]), 'little') print(f"push val {int_val}") eip += 5 elif op == 65: print("reg1 += reg2") eip += 1 elif op == 66: print("reg1 -= reg4") eip += 1 elif op == 67: print("reg1 *= reg3") eip += 1 elif op == 55: print("reg1 = reg6") eip += 1 elif op == 56: print("reg1 ^= reg4") eip += 1 elif op == 57: print("reg1 ^= reg6") eip += 1 elif op == 53: print("reg6 = reg1") eip += 1 elif op == 0xf7: print("unknown2 += reg1") eip += 1 elif op == 68: print("reg1 /= reg6") eip += 1 elif op == 0x80: next_val = opcode[eip+1] int_val = int.from_bytes(bytes(opcode[eip+2:eip+6]), 'little') print(f"reg{next_val} = val {int_val}") eip += 6 elif op == 119: print("reg1 ^= unknown2") eip += 1 elif op == 83: print("putchar reg3") eip += 2 elif op == 34: print("reg1 >>= reg2") eip += 1 elif op == 35: print("reg1 <<= reg2") eip += 1 elif op == 0x99: print("emu end") break elif op == 118: print("pop stack store in reg3") eip += 5 elif op == 84: print("reg3 getchar") eip += 2 elif op == 48: print("reg1 |= reg2") eip += 1 elif op == 49: print("reg1 &= reg2") eip += 1 elif op == 50: int_val = opcode[eip+1] print(f"reg3 = val {int_val}") eip += 2 elif op == 9: print("reg1 = 0x6FEBF967") eip += 1 elif op == 16: print("unknown2 = reg1") eip += 1 elif op == 51: print("reg4 = reg1") eip += 1 elif op == 52: int_val = opcode[eip+1] print(f"reg2 = val {int_val}") eip += 2 elif op == 0xfe: print("reg1 = unknown2") eip += 1 elif op == 17: print("printf hex reg1") eip += 1 elif op == 0xa0: print("reg1 must equal 1877735783") eip += 1 elif op == 0xa1: print("read 44 bytes") eip += 1 elif op == 0xb1: print("unknown2 = dword_804B080[0] 0x7b") eip += 1 elif op == 0xb2: print("unknown2 = dword_804B080[1] 0x2f") eip += 1 elif op == 0xa4: int_val = opcode[eip+1] print(f"dword_804B080[{int_val}] = reg1") eip += 4 elif op == 0xb3: print(f"unknown2 = dword_804B080[2] 0x37") eip += 1 elif op == 0xb4: print(f"unknown2 = dword_804B080[3] 0xe8") eip += 1 elif op == 0xc1: int_val = opcode[eip+1] print(f"reg1 = input[{int_val}]") eip += 2 elif op == 0xc7: print(f"reg1 must equal 0x0CF1304DC") eip += 1 elif op == 0xC8: print(f"reg1 must equal 0x283B8E84") eip += 1 elif op == 0xc2: int_val = int.from_bytes(bytes(opcode[eip+1:eip+5]), 'little') print(f"reg1 must equal {int_val} & 0xff = {int_val & 0xff}") eip += 5 ``` 得到 ``` read 44 bytes reg1 = input[0] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 330 & 0xff = 74 reg1 = input[1] unknown2 = dword_804B080[1] 0x2f reg1 ^= unknown2 reg1 must equal 281 & 0xff = 25 reg1 = input[2] unknown2 = dword_804B080[3] 0xe8 reg1 ^= unknown2 reg1 must equal 477 & 0xff = 221 reg1 = input[3] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 271 & 0xff = 15 reg1 = input[4] unknown2 = dword_804B080[1] 0x2f reg1 ^= unknown2 reg1 must equal 283 & 0xff = 27 reg1 = input[5] unknown2 = dword_804B080[3] 0xe8 reg1 ^= unknown2 reg1 must equal 393 & 0xff = 137 reg1 = input[6] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 281 & 0xff = 25 reg1 = input[7] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 340 & 0xff = 84 reg1 = input[8] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 335 & 0xff = 79 reg1 = input[9] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 334 & 0xff = 78 reg1 = input[10] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 341 & 0xff = 85 reg1 = input[11] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 342 & 0xff = 86 reg1 = input[12] unknown2 = dword_804B080[3] 0xe8 reg1 ^= unknown2 reg1 must equal 142 & 0xff = 142 reg1 = input[13] unknown2 = dword_804B080[1] 0x2f reg1 ^= unknown2 reg1 must equal 73 & 0xff = 73 reg1 = input[14] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 270 & 0xff = 14 reg1 = input[15] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 331 & 0xff = 75 reg1 = input[16] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 262 & 0xff = 6 reg1 = input[17] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 340 & 0xff = 84 reg1 = input[18] unknown2 = dword_804B080[1] 0x2f reg1 ^= unknown2 reg1 must equal 26 & 0xff = 26 reg1 = input[19] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 322 & 0xff = 66 reg1 = input[20] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 339 & 0xff = 83 reg1 = input[21] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 287 & 0xff = 31 reg1 = input[22] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 338 & 0xff = 82 reg1 = input[23] unknown2 = dword_804B080[3] 0xe8 reg1 ^= unknown2 reg1 must equal 219 & 0xff = 219 reg1 = input[24] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 281 & 0xff = 25 reg1 = input[25] unknown2 = dword_804B080[3] 0xe8 reg1 ^= unknown2 reg1 must equal 217 & 0xff = 217 reg1 = input[26] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 281 & 0xff = 25 reg1 = input[27] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 341 & 0xff = 85 reg1 = input[28] unknown2 = dword_804B080[1] 0x2f reg1 ^= unknown2 reg1 must equal 25 & 0xff = 25 reg1 = input[29] unknown2 = dword_804B080[2] 0x37 reg1 ^= unknown2 reg1 must equal 256 & 0xff = 0 reg1 = input[30] unknown2 = dword_804B080[0] 0x7b reg1 ^= unknown2 reg1 must equal 331 & 0xff = 75 reg1 = input[31] unknown2 = dword_804B080[1] 0x2f reg1 ^= unknown2 reg1 must equal 30 & 0xff = 30 reg1 = input[32] reg2 = val 24 reg1 <<= reg2 unknown2 = reg1 reg1 = input[33] reg2 = val 16 reg1 <<= reg2 unknown2 += reg1 reg1 = input[34] reg2 = val 8 reg1 <<= reg2 unknown2 += reg1 reg1 = input[35] unknown2 += reg1 reg1 = unknown2 reg2 = val 5 reg1 >>= reg2 reg1 ^= unknown2 unknown2 = reg1 reg2 = val 7 reg1 <<= reg2 reg2 = val 2565961507 reg1 &= reg2 reg1 ^= unknown2 unknown2 = reg1 reg2 = val 24 reg1 <<= reg2 reg2 = val 904182048 reg1 &= reg2 reg1 ^= unknown2 unknown2 = reg1 reg2 = val 18 reg1 >>= reg2 reg1 ^= unknown2 reg1 must equal 1877735783 reg1 = input[36] reg2 = val 24 reg1 <<= reg2 unknown2 = reg1 reg1 = input[37] reg2 = val 16 reg1 <<= reg2 unknown2 += reg1 reg1 = input[38] reg2 = val 8 reg1 <<= reg2 unknown2 += reg1 reg1 = input[39] unknown2 += reg1 reg1 = unknown2 reg3 = val 32 reg1 *= reg3 reg4 = reg1 reg1 ^= unknown2 reg2 = val 17 reg1 >>= reg2 reg6 = reg1 reg1 = reg6 reg1 ^= reg4 reg1 ^= unknown2 reg2 = val 13 reg1 <<= reg2 reg1 ^= unknown2 reg1 ^= reg4 reg1 ^= reg6 unknown2 = reg1 reg3 = val 32 reg1 *= reg3 reg4 = reg1 reg1 ^= unknown2 reg2 = val 17 reg1 >>= reg2 reg6 = reg1 reg1 = reg6 reg1 ^= reg4 reg1 ^= unknown2 reg2 = val 13 reg1 <<= reg2 reg1 ^= unknown2 reg1 ^= reg4 reg1 ^= reg6 reg1 must equal 0x0CF1304DC reg1 = input[40] reg2 = val 24 reg1 <<= reg2 unknown2 = reg1 reg1 = input[41] reg2 = val 16 reg1 <<= reg2 unknown2 += reg1 reg1 = input[42] reg2 = val 8 reg1 <<= reg2 unknown2 += reg1 reg1 = input[43] unknown2 += reg1 reg1 = unknown2 reg3 = val 32 reg1 *= reg3 reg4 = reg1 reg1 ^= unknown2 reg2 = val 17 reg1 >>= reg2 reg6 = reg1 reg1 = reg6 reg1 ^= reg4 reg1 ^= unknown2 reg2 = val 13 reg1 <<= reg2 reg1 ^= unknown2 reg1 ^= reg4 reg1 ^= reg6 unknown2 = reg1 reg3 = val 32 reg1 *= reg3 reg4 = reg1 reg1 ^= unknown2 reg2 = val 17 reg1 >>= reg2 reg6 = reg1 reg1 = reg6 reg1 ^= reg4 reg1 ^= unknown2 reg2 = val 13 reg1 <<= reg2 reg1 ^= unknown2 reg1 ^= reg4 reg1 ^= reg6 reg1 must equal 0x283B8E84 ``` 前32字节输入异或解密即可 后12字节每4位一组进行逻辑运算,无脑爆破。 前32字节 ``` chr(0x7b ^ 74)+ chr(0x2f ^ 25)+ chr(0xe8 ^ 221)+ chr(0x37 ^ 15)+ chr(0x2f ^ 27)+ chr(0xe8 ^ 137)+ chr(0x7b ^ 25)+ chr(0x37 ^ 84)+ chr(0x7b ^ 79)+ chr(0x7b ^ 78)+ chr(0x37 ^ 85)+ chr(0x37 ^ 86)+ chr(0xe8 ^ 142)+ chr(0x2f ^ 73)+ chr(0x37 ^ 14)+ chr(0x7b ^ 75)+ chr(0x37 ^ 6)+ chr(0x37 ^ 84)+ chr(0x2f ^ 26)+ chr(0x7b ^ 66)+ chr(0x37 ^ 83)+ chr(0x7b ^ 31)+ chr(0x37 ^ 82)+ chr(0xe8 ^ 219)+ chr(0x7b ^ 25)+ chr(0xe8 ^ 217)+ chr(0x7b ^ 25)+ chr(0x37 ^ 85)+ chr(0x2f ^ 25)+ chr(0x37 ^ 0)+ chr(0x7b ^ 75)+ chr(0x2f ^ 30) ``` 得到'16584abc45baff901c59dde3b1bb6701' 第33、34、35、36 4字节 ``` #include <cstdio> int main(){ unsigned reg1, reg2, reg3, reg4, reg5, reg6, unknown2, record; for(unsigned int unknown2=0;unknown2<0xffffffff;unknown2++){ record = unknown2; reg1 = unknown2; reg2 = 5; reg1 >>= reg2; reg1 ^= unknown2; unknown2 = reg1; reg2 = 7; reg1 <<= reg2; reg2 = 2565961507; reg1 &= reg2; reg1 ^= unknown2; unknown2 = reg1; reg2 = 24; reg1 <<= reg2; reg2 = 904182048; reg1 &= reg2; reg1 ^= unknown2; unknown2 = reg1; reg2 = 18; reg1 >>= reg2; reg1 ^= unknown2; unknown2 = record; if(reg1 == 1877735783){ printf("%u\n", record); } } } ``` 得到1630680372 -> 'a254' 第37、38、39、40 4字节 ``` #include <cstdio> int main(){ unsigned int record, reg1, reg2, reg3, reg4, reg5, reg6, unknown2; for(unsigned int unknown2=0x20202020;unknown2<0xffffffff;unknown2+=1){ record = unknown2; reg1 = unknown2; reg3 = 32; reg1 *= reg3; reg4 = reg1; reg1 ^= unknown2; reg2 = 17; reg1 >>= reg2; reg6 = reg1; reg1 = reg6; reg1 ^= reg4; reg1 ^= unknown2; reg2 = 13; reg1 <<= reg2; reg1 ^= unknown2; reg1 ^= reg4; reg1 ^= reg6; unknown2 = reg1; reg3 = 32; reg1 *= reg3; reg4 = reg1; reg1 ^= unknown2; reg2 = 17; reg1 >>= reg2; reg6 = reg1; reg1 = reg6; reg1 ^= reg4; reg1 ^= unknown2; reg2 = 13; reg1 <<= reg2; reg1 ^= unknown2; reg1 ^= reg4; reg1 ^= reg6; unknown2 = record; if(reg1 == 0x0CF1304DC){ printf("%u\n", record); break; } } } ``` 得到1647326819 -> 'b06c' 第41、42、43、44 4字节 ``` #include <cstdio> int main(){ unsigned int record, reg1, reg2, reg3, reg4, reg5, reg6, unknown2; for(unsigned int unknown2=0x20202020;unknown2<0xffffffff;unknown2+=1){ record = unknown2; reg1 = unknown2; reg3 = 32; reg1 *= reg3; reg4 = reg1; reg1 ^= unknown2; reg2 = 17; reg1 >>= reg2; reg6 = reg1; reg1 = reg6; reg1 ^= reg4; reg1 ^= unknown2; reg2 = 13; reg1 <<= reg2; reg1 ^= unknown2; reg1 ^= reg4; reg1 ^= reg6; unknown2 = reg1; reg3 = 32; reg1 *= reg3; reg4 = reg1; reg1 ^= unknown2; reg2 = 17; reg1 >>= reg2; reg6 = reg1; reg1 = reg6; reg1 ^= reg4; reg1 ^= unknown2; reg2 = 13; reg1 <<= reg2; reg1 ^= unknown2; reg1 ^= reg4; reg1 ^= reg6; unknown2 = record; if(reg1 == 0x283B8E84){ printf("%u\n", record); break; } } } ``` 得到1684222515 -> 'dc23' 组合一下得到 FLAG:SangFor{16584abc45baff901c59dde3b1bb6701a254b06cdc23} 打赏还是打残,这是个问题 赏 Wechat Pay Alipay [RE] OddCode - cew [PWN] Whats your name - xf1les
没有帐号? 立即注册