In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)05/31 Report--
This article shows you how to analyze the reverse and protection of iOS mobile games, the content is concise and easy to understand, it can definitely brighten your eyes. I hope you can get something through the detailed introduction of this article.
Background introduction
With the development of mobile games, the reverse cracking technology of mobile games is becoming more and more mature, especially in Andorid, all kinds of cracking articles can be found everywhere. Relatively speaking, there are relatively few reverse analysis articles on mobile games in iOS. Lu Xinyi, an expert on mobile security at NetEase Shield, will analyze the general game cracking and protection ideas by analyzing a unity game and a cocos-lua game.
Identify Unity games
The ipa package of iOS platform can be decompressed by compression software. Generally speaking, Unity games have the following file directory features:
Crack the train of thought
Unity games will produce the resource file global-metadata.dat under\ Data\ Managed\ Metadata. The strings used in the game are saved in a global-metadata.dat resource file, and these strings are read into memory only when running dynamically. This makes it more difficult to use IDA for static analysis of games. So in order to solve this problem, there are artificial wheels, that is, Il2CppDumper. This reads the information in the global-metadata.dat file and combines it with the executable file.
When github: https://github.com/Perfare/Il2CppDumper opens Il2CppDumper, a window pops up. The first one selects macho to execute the program, the second one selects global-metadata.dat, and then selects the corresponding mode. Generally, auto is selected, and then the following dump.cs is generated. This is the interface of c # used in the game.
With the interface, we can search for general game modified keywords such as battle,player,maxhp,fight, and then we locate if the class FightRoleData shown is the source of our character data when we fight, there is also a class called battlemanager, which is a combat manager, including starting combat, suspending combat, and ending combat.
Public class FightRoleData: ICloneable / / TypeDefIndex: 2414 {/ / Fields public long Sid; / / 0x10 public long OwnerId; / / 0x18 public long Uid; / / 0x20 public int Power; / / 0x28 public int Level; / / 0x2C public int Sex; / / 0x30 public int FlagType; / / 0x34 public int RoleUnit; / / 0x38 public int Sit; / / 0x3C public int AttackType; / / 0x40 public int Race; / / 0x44 public int Professional; / / 0x48 public int Star / / 0x4C public int Quality; / / 0x50 public int Impression; / / 0x54 public int Awaken; / / 0x58 public int IsNpc; / / 0x5C public int Soul; / / 0x60 public int Formation; / / 0x64 public int SkinID; / / 0x68 public int AwakenLv; / / 0x6C public int [] [] Skills; / / 0x70 public int [] Runes; / / 0x78 public double Hp; / / 0x80 public double MaxHp; / / 0x88 public double Rage; / / 0x90 public double MaxRage / / 0x98 public double Aggro; / / 0xA0 public double MoveSpeed; / / 0xA8 public double Attack; / / 0xB0 public double PhysisDefense; / / 0xB8 public double MagicDefense; / / 0xC0. / / Properties public ERolePosType PostitionType {get;} public ERoleGender Gender {get;} public bool IsAwaken {get;} / / Methods public virtual void Init (ErlArray erlData) / / RVA: 0x100EDDB68 Offset: 0xEDDB68 private static double _ getProperty (ErlArray attrData, int index, bool [] checker, ERoleProperty property); / / RVA: 0x100EDE8A0 Offset: 0xEDE8A0 public ERolePosType get_PostitionType (); / / RVA: 0x100EDE93C Offset: 0xEDE93C public ERoleGender get_Gender (); / / RVA: 0x100EDE964 Offset: 0xEDE964 public bool get_IsAwaken (); / / RVA: 0x100EDE97C Offset: 0xEDE97C public object Clone (); / / RVA: 0x100EDE98C Offset: 0xEDE98C public void .ctor () / / RVA: 0x100EDE994 Offset: 0xEDE994} / / Namespace: public class BattleManager: MonoBehaviour / / TypeDefIndex: 3127 {/ / Fields... / / Properties public Camera GameCamera {get; set;} public GameObject CameraBase {get;} public bool Loading {get; set;} public BattleView battleView {get; set;} public string BattleMusic {get;} public Dictionary`2 RoleModelConfigDic {get;} public int TargetFrame {get } public static BattleManager Instance {get;} public DragonBallBattle Battle {get;} public bool Pause {get; set;} public List`1 BattleRoleControllers {get;} public bool IsSkipSuperSkill {get;} private bool _ startAnimPlaying {get;} / / Methods... Public void StartBattle (); / / RVA: 0x101BBB1EC Offset: 0x1BBB1EC public void SkipBattle (); / / RVA: 0x101BE18B0 Offset: 0x1BE18B0.}
At this point, we can easily implement two functions to skip the battle and modify our character's attack force. the first function can use the hook StartBattle () method and then get the this pointer, that is, the BattleManager object, and then we can call the SkipBattle () method according to the BattleManager object. in the second way, we can modify the FightRoleData data to achieve it, so let's first look at where FightRoleData is used. Through the search, you can find this class:
/ / Namespace: BattleSystempublic static class BattleAPI / / TypeDefIndex: 2490 {/ / Methods private static T _ GetConfig (long id); / / RVA: 0x1000E98B4 Offset: 0xE98B4 public static DragonBallBattle Create (BattleScene scene, string hexData); / / RVA: 0x100B06CFC Offset: 0xB06CFC public static DragonBallBattle Create (BattleScene scene, byte [] dataBytes); / / RVA: 0x100B0950C Offset: 0xB0950C public static DragonBallBattle Create (BattleScene scene, BattleData data, optional CallBack`1 beforeInit) / / RVA: 0x100B06E04 Offset: 0xB06E04 public static BattleRole CreateBattleRole (BattleRoleConfig roleConfig, FightRoleData roleData, BattleScene scene, DragonBallBattle battle, optional double initialCD, optional double autoCD); / / RVA: 0x100B0B3A0 Offset: 0xB0B3A0 private static int [] _ getUniqueAttackSequence (int [] seq, long sid, Dictionary`2 cache, YKRandom random); / / RVA: 0x100B0CC28 Offset: 0xB0CC28 private static BattleRole _ createBattleRolePartner (BattlePartnerConfig partnerConfig, BattleScene scene, int [] level, DragonBallBattle battle); / / RVA: 0x100B0A4B4 Offset: 0xB0A4B4 public static void ApplyProperty (BattleRoleData roleData, FightRoleData netData) / / RVA: 0x100B0CDB0 Offset: 0xB0CDB0 private static BattleRole [] _ getFormatBattleRoles (BattleScene scene, List`1 data, BattleFormation formatiom, int battleIndex, DragonBallBattle battle, Dictionary`2 seqCache, double [] initialCDModifier, double [] autoCD); / / RVA: 0x100B09C1C Offset: 0xB09C1C public static int ServerIndexToConfigIndex (int index, ERolePosType posType); / / RVA: 0x100B0E2A8 Offset: 0xB0E2A8 public static void ImportConfig (IConfigImporter importer); / / RVA: 0x100B0E390 Offset: 0xB0E390}
The CreateBattleRole function uses FightRoleData data, so we can modify the attack force through the hook CreateBattleRole function and modify the value in the roledata offset corresponding to the third parameter (the first parameter is the this pointer), such as the attack value in the 0xB0 offset position.
Protection
Although Unity games convert il to cpp form in iOS, this increases the reverse difficulty to a certain extent, because it is not easy to analyze functions from the code level when converted to assembly form. But because of the redundancy of il2cpp itself, too much string and symbol information is retained. It is easy for analysts to find a breakthrough through this information, so here are a few suggestions:
Encrypted global-metadata.dat
Function symbol confusion at the c # level (as function symbol confusion is easy to make mistakes, it is recommended to confuse several core classes)
String encryption, code confusion
The server should not trust the client and increase the verification of the data. For example, if I modified the attack force above, the server needs to sign the issued roledata when sending roledata. If my client modifies the data, the server will not trust the data signature when verifying.
After talking a little bit about Unity games, now let's talk about a cocos-lua game.
Identify Lua games
Generally speaking, whether it is a lua script game from these two aspects, first decompress ipa, and then enter the resource directory: generally speaking, it is src or res, which has a similar lua,luac suffix. To be safe, let's drag the binary into ida to take a look:
Search the lua luajit keyword to get the information shown in the figure.
It's decided to be a lua script game. Let's drag the lua script into the game and take a look. Generally speaking, it must be encrypted or compiled into luac/luajit form, otherwise it will be too easy to crack.
According to the above results, it is not plaintext storage that is encrypted, and it seems likely that the first few bytes are encrypted by xxtea (this method is officially provided by cocos and has obvious characteristics. After encryption, sign is appended to the file header as an identity. The encrypted key is written directly in the code)
Crack the train of thought
Generally speaking, there are two ways to think about Lua games:
Get the lua script and replace the lua script
Because of the dynamic nature of lua scripts, we only need to load our lua scripts through the lua engine to hijack data.
We can get the script through dump, and we can get the decrypted script through hook luaL_loadbuffer, but iOS is still a little different from Android, because Android lua is loaded through so, so there must be an export function luaL_loadbuffer. But iOS lua has been integrated into the binary, so the symbol is naturally dropped by strip. At this time, we can locate it by combining the string with the lua source code. For example, the string I selected here is "error loading module'% s' from file", and then it is easy to find this function by tracing up.
Compare the f5 content with the luaL_loadbuffer prototype
Int luaL_loadbuffer (lua_State * L, const char * buff, size_t sz, const char * name)
Now let's start to write code to dump script, here I use frida to implement, because frida for these one-time requirements are so easy to use, do not need to compile, do not need to restart the device, use it out of the box.
Script = session.create_script ("" var baseAddr = Module.findBaseAddress ('QuickMud-mobile'); var luaL_loadbuffer = baseAddr.add (0x2DF644); Interceptor.attach (luaL_loadbuffer, {onEnter: function (args) {var name = Memory.readUtf8String (args [3]); var obj = {} obj.size = args [2] .toInt32 () obj.name = name; obj.content = Memory.readCString (args [1], obj.size) Send (obj);}}) "") def write (path, content): print ('write:', path) folder = os.path.dirname (path) if not os.path.exists (folder): os.makedirs (folder) open (path,' w') .write (content) def on_message (message Data): if message ['payload'] [' name']: name = message ['payload'] [' name'] name = "/ Add/Your/Dump/Path/" + name content = message ['payload'] [' content'] .encode ('utf-8') dirName = os.path.dirname (name) if not os.path.exists (dirName): os.makedirs (os) .path.dirname (name) if name.endswith ('.lua'): write (name Content) script.on ('message', on_message) script.load () sys.stdin.read ()
With the decrypted script, we can cheat by modifying the script, because with the source code we can even write an offline hang out, which is very harmful to the game.
Protection
You can see that lua scripts do great harm if they are only encrypted, so if lua games need to ensure the security of lua scripts, you can start with the following points:
Compile lua to luac or luajit, then modify opcode to lua engine on this basis, and then modify bytecode of luajit to increase the difficulty of reversing
Although iOS strip symbols, but because lua is open source and easy to locate to luaL_loadbuff, it is necessary to add string encryption and code logic confusion to protect the security of the game.
The above content is how to analyze the reverse and protection of iOS mobile games. Have you learned the knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.