一、目标

一、目标

我们已经拿AndroidNativeEmu模拟执行出了sign的值,但是这个值对不对,除了直接往服务器发送之后,最好是能和真机算出来的对比验算下,这样才好放心它有没有做别的小动作。

二、分析

算法还原的助手(一) 先让时间停下来 的文章里面我们已经把联手机签名的结果固定下来了,所以在AndroidNativeEmu里面我们也需要Hook gettimeofday和lrand48。

gettimeofday
1:gettimeofday

从IDA的分析中可以看到,调用gettimeofday函数的时候 tv 的指针在R5寄存器中,所以我们只需要在函数返回之后的 0x129C0 地址上断下来,然后把R5地址所指向的内存值改成我们需要的定值就行了。

rand48
1:rand48

lrand48就比较简单了,函数的返回值一般都是存在R0寄存器里,我们只需要在函数返回的时候,在 0x00012A720x00012A8C 把R0写成我们需要的定值就行了。

def hook_code(mu, address, size, user_data):
        global lib_moduleBase

        try:
                emu = user_data
                if (not emu.memory.check_addr(address, UC_PROT_EXEC)):
                        logger.error("addr 0x%08X out of range"%(address,))
                        sys.exit(-1)

                # 修改gettimeofday返回值
                if (lib_moduleBase + 0x129C0) == address:
                        # 读取R5寄存器的值
                        r5 = mu.reg_read(UC_ARM_REG_R5)
                        logger.info(">>> addr 0x%08X,r5=0x%08X" %(address,r5))

                        # 读取R5指向的内存地址的值,就是tv的值
                        b = mu.mem_read(r5, 8).hex().upper()
                        logger.info(b)

                        # 给 tv写入一个定值
                        mu.mem_write(r5,b"\x91\x50\xc4\x5f\x15\x97\x09\x00")

                        # 看一眼,是不是写对了
                        b = mu.mem_read(r5, 8).hex().upper()
                        logger.info(b)

                # 修改 lrand48的返回值
                if (lib_moduleBase + 0x00012A72) == address  or (lib_moduleBase + 0x00012A8C) == address :
                        r0 = mu.reg_read(UC_ARM_REG_R0)
                        logger.info(">>> addr 0x%08X,r0=0x%08X" %(address,r0))
                        mu.reg_write(UC_ARM_REG_R0,1)

                except Exception as e:
                        logger.exception("exception in hook_code")
                        sys.exit(-1)

好了,跑一下,算出来的结果和联手机签名的结果一致,收工

rcok
1:rcok
rcokold
1:rcold

三、总结

验算是个好习惯

100

关注微信公众号,最新技术干货实时推送

100