|
|
|
|
移动端

旅行青蛙Unity游戏逆向修改--iOS篇

之前写了一篇分析Android C#脚本的文章,主要也是为了给这篇文章做铺垫吧,因为在iOS现在都是IL2CPP模式,C#脚本已经被转成了c代码。所以要单独分析iOS的话难度会大很多,如果从Android的C#脚本入手的话,因为iOS和Android脚本都是一样的话,可以从Android分析的函数名来对应iOS的c函数然后进行hook修改。

作者:佚名来源:酷爱丸子头|2018-02-06 10:46

人工智能+区块链的发展趋势及应用调研报告


之前写了一篇分析Android C#脚本的文章,主要也是为了给这篇文章做铺垫吧,因为在iOS现在都是IL2CPP模式,C#脚本已经被转成了c代码。所以要单独分析iOS的话难度会大很多,如果从Android的C#脚本入手的话,因为iOS和Android脚本都是一样的话,可以从Android分析的函数名来对应iOS的c函数然后进行hook修改。

提取ipa

首先从越狱设备上面提取旅行青蛙的ipa包,使用 frida-ios-dump 一键提取即可。由于是日文名字,先通过 ./dump.py -l 把名字列出来,然后复制名字或者通过bundle id去dump就可以了。

IL2CPP符号还原

由于使用IL2CPP选项编译unity游戏,会生成cpp的代码,直接使用IDA看是看不到函数和函数名的,而且游戏中使用的字符串都被保存在global-metadata.dat的资源文件里。首先要通过提取global-metadata.dat文件里面的字符串对对应的c函数进行符号还原。具体也有现成的文章: 还原使用IL2CPP编译的unity游戏的symbol ,github上面也有线程的项目也做这件事情 Il2CppDumper 。下载release的工具,运行Il2CppDumper.exe并依次选择il2cpp的可执行文件和global-metadata.dat文件,然后选择Auto(Plus)模式,将生成dump.cs文件和script.py脚本。使用IDA打开可执行文件然后使用script.py脚本即可还原符号。

10344541-21e6a3aeaa283ff9.jpg

Makingmethodname...MakemethodnamedoneSettingString...SetstringdoneMakingfunction...Makefunctiondone, please waitforIDAtocomplete the analysisScriptfinish !

根据函数hook代码

还原之后就可以根据之前分析到的函数名来hook对应的代码了,首先是三叶草的数目通过 SuperGameMaster.CloverPointStock() 获取的,在IDA搜索 CloverPointStock如下:

10344541-0f036b6ab3b6d5fe.jpg

接着就可以直接hook这个函数了,由于要inline hook目前是在越狱机器上面,后面会讲到非越狱机器hook的方案。使用 MonkeyDev 新建一个 Logos Tweak 项目,清空.xm 的内容并写入如下内容:

  1. #import#import#importint(*old_clover_point_stock)(void);intnew_clover_point_stock(void){return9999;}%ctor{ @autoreleasepool {unsignedlongclover_point_stock = _dyld_get_image_vmaddr_slide(0) +0x100093A2C; MSHookFunction((void*)clover_point_stock, (void*)&new_clover_point_stock, (void**)&old_clover_point_stock); }} 

然后在build settings里面设置端口和设备密码然后command + b安装就能看到效果了,其它函数的hook也是一样的:

  1. #import#import#importint(*old_clover_point_stock)(void);intnew_clover_point_stock(void){return9999;}int(*old_ticket_stock)(void);intnew_ticket_stock(void){return9999;}void(*old_lotterycheck)(unsignedlongobj);voidnew_lotterycheck(unsignedlongobj){    *(int*)(obj +80) = rand() %4+1;}id(*old_new_clover_object)(intindex,idcloverData,idcloversObj,boolfourLeafFlag);idnew_new_clover_object(intindex,idcloverData,idcloversObj,boolfourLeafFlag){    fourLeafFlag =true;returnold_new_clover_object(index,cloverData,cloversObj,fourLeafFlag);}%ctor{@autoreleasepool{unsignedlongclover_point_stock = _dyld_get_image_vmaddr_slide(0) +0x100093A2C;        MSHookFunction((void*)clover_point_stock, (void*)&new_clover_point_stock, (void**)&old_clover_point_stock);unsignedlongticket_stock = _dyld_get_image_vmaddr_slide(0) +0x100093AA4;        MSHookFunction((void*)ticket_stock, (void*)&new_ticket_stock, (void**)&old_ticket_stock);unsignedlonglotterycheck = _dyld_get_image_vmaddr_slide(0) +0x100086CF4;        MSHookFunction((void*)lotterycheck, (void*)&new_lotterycheck, (void**)&old_lotterycheck);unsignedlongnew_clover_object = _dyld_get_image_vmaddr_slide(0) +0x100037100;        MSHookFunction((void*)new_clover_object, (void*)&new_new_clover_object, (void**)&old_new_clover_object);    }} 

这里有一个函数 RaffelPanel$$LotteryCheck 要修改里面的result的值,就要根据汇编或者伪代码来看result的赋值是在什么位置了,该函数通过F5获得的伪代码如下:

  1. __int64 __fastcall RaffelPanel__LotteryCheck(__int64 a1){ 
  2.   __int64 v1; // x19 
  3.   __int64 v2; // x0 
  4.   __int64 v3; // x0 
  5.   int v4; // w20 
  6.   int v5; // w23 
  7.   signed int v6; // w24 
  8.   __int64 v7; // x0 
  9.   __int64 result; // x0 
  10.   v1 = a1; 
  11.   if ( !(byte_10137EDBB & 1) ) 
  12.   { 
  13.     sub_100DEAD34(6810LL); 
  14.     byte_10137EDBB = 1; 
  15.   }v2 = qword_101439198;if( *(_BYTE *)(qword_101439198 +266) &1&& !*(_DWORD *)(qword_101439198 +188) ){ 
  16.     sub_100DFF71C(); 
  17.     v2 = qword_101439198; 
  18.   }if( !*(_QWORD *)(*(_QWORD *)(v2 +160) +192LL) )LABEL_17:    sub_100DE28B4();  v3 = sub_1000FB954();  v4 = Random__Range_71094(0LL,0LL, v3,0LL);  v5 =0;  *(_DWORD *)(v1 +80) =0;  this.result = Rank.White;//默认都是白色的球v6 = -1;while(1){ 
  19.     v7 = qword_101439198; 
  20.     if ( *(_BYTE *)(qword_101439198 + 266) & 1 ) 
  21.     { 
  22.       if ( !*(_DWORD *)(qword_101439198 + 188) ) 
  23.       { 
  24.         sub_100DFF71C(); 
  25.         v7 = qword_101439198; 
  26.       }}if( !*(_QWORD *)(*(_QWORD *)(v7 +160) +192LL) )gotoLABEL_17;    result = sub_1000FB954();    v5 += result;if( v4 < v5 )//if (num < num2)break;if( ++v6 >=4)      return result;  }  *(_DWORD *)(v1 +80) = v6 +1;//this.result = (Rank)i;return result;} 

这里的 *(_DWORD *)(v1 + 80) 的位置其实就是 this.result 所以直接修改 80 偏移位置的值就可以了。

总结

总结来说的话,要分析iOS里面转换后的脚本C代码还是不容易的,如果能够根据Android C#脚本分析的结果然后对iOS的符号进行恢复一下的话,就可以直接根据Android分析到的函数直接来Hook iOS对应的函数来修改参数或者值了。不过这里还是在越狱设备上面进行的hook,然后会讲到非越狱设备同样也可以进行静态的hook操作。

【编辑推荐】

  1. iOS 11.3 要来了,这是 iOS 11 目前为止最大的一次更新
  2. iOS 11缩小界面导航栏与标签栏异常的问题
  3. iOS 11.3支持导入病历 这将引领医疗革命
  4. 推荐提升iOS开发效率的一些keys
  5. iOS架构师的必经之路
【责任编辑:未丽燕 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

解密SEO:搜索引擎优化与网站成功战略

本书是作者根据十年网站营销经验,特别是搜索引擎优化(SEO)实现营销方面的技术和实践总结。本书帮助读者建立搜索营销的概念,分析搜索营...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊