一、目标

一、目标

我们已经拿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