仔细看了这道题之后,觉得这道题不应该成为VM,他没有VM的结构和各种handler,但是他反而是有了很多的混淆,那么我们第一步先根据文章修改function size。
文章链接:https://www.dllhook.com/post/217.html
IDAPro F5出现too big function 解决-macOS-优雅人生.pdf
将这个标记位修改完成之后,我们就能正常查看整个函数和进行F5反编译了,但是速度很慢。
耐性等待就好,只反编译一次就够用了。
反编译完成之后我们可以看到,基础的输入输出,判断长度和运算都没变,而且确实没有了VM结构。反而多了一堆异或运算。那么我们先确定这些异或运算会不会影响我们的输入输出。
随便点击几个可以发现他是迭代异或下去的,然而数据在我们对比的数据后门很多,那么就说明这是不影响我们输入输出的东西,就可以当做垃圾代码除掉了。(先将F5得到的代码全选保存成TXT文档)
import structimport osimport ref = open("origin_source.txt", "r")wf = open("de_source.txt", "w")for i in range(25036):tmp = f.readline().strip()if "byte_6941" in tmp:wf.write(tmp + "\n")print tmpf.close()wf.close()

除去之后就只剩这些与运算相关的数据了,但是这里因为他用的全局变量来存储的flag字符串,所以我们没有办法吧byte_xxxxx合并为一个数组,那么我们就用正则去匹配合并好了,同样也是只有简单运算,合并好了之后倒着运算一遍就出来结果了。
import structimport osimport rebyte_overflow = lambda x: x & 0xffcipher_arr = [192, 133, 249, 108, 226, 20, 187, 228, 13, 89, 28, 35, 136, 110, 155, 202, 186, 92, 55, 255, 72, 216, 31,171, 0xa5]op_switch = {'+=': lambda eindex, data: cipher_arr[eindex] - data, '-=': lambda eindex, data: cipher_arr[eindex] + data,'^=': lambda eindex, data: cipher_arr[eindex] ^ data, '++': lambda eindex, data: cipher_arr[eindex] - 1,'--': lambda eindex, data: cipher_arr[eindex] + 1}f = open("de_source.txt", "r")instruction = []for i in range(2415):tmp = f.readline().strip()result = re.findall("byte_6941(.{2})\s(.{2})\s(.+);|(.{2})byte_6941(.{2})", tmp)[0]if len(result) == 5:# print resultinstruction.append(list(result))else:print tmp# print instructioninstruction = instruction[::-1]for i in range(len(instruction)):if instruction[i][0] != '':vm_index = int(instruction[i][0], 16)else:vm_index = int(instruction[i][4], 16)if instruction[i][1] != '':vm_optation = instruction[i][1]else:vm_optation = instruction[i][3]if instruction[i][2] != '':if instruction[i][2].startswith("0x"):vm_data = int(instruction[i][2].strip("u"), 16)else:vm_data = int(instruction[i][2].strip("u"), 10)else:vm_data = Nonecipher_arr[vm_index] = op_switch[vm_optation](vm_index, vm_data)print "".join(map(chr, map(byte_overflow, cipher_arr)))f.close()
