 So, let's start today's topic. My name is Wan, and today's topic is One Step Before Game Hackers in Too Many Android Emulators. So, first let me give a brief self-introduction. I am Chinese, but now I live and work in Japan. I work as a security engineer in a company called DNA Corporation, which is basically a mobile game company. Personally, in private, I love playing games as well as hacking games. So, this is today's agenda. Before we start, may I know how many of you have ever played or liked to play games? Any kind of games? I am so motivated. So, first let me introduce the background, the game cheating threat model. So, we have defined three roles in the game cheating threat model. The users, the cheaters, and the vendors, aka the game developers. So, for PC games, all these three roles have the full control over their PCs. They have the permission to install or run privileged code, but on mobile devices, things get a bit different. The users usually don't have a privileged access over their devices unless they're rooted or jail-broke their devices. And this is the same for game developers. On the other hand, the cheaters usually own a rooted or jail-broken device. You may think, okay, then the cheaters must be the most powerful. Nothing can stop them from cheating, but this does not mean the cheaters are making profits. Actually, yes, it's true that the cheaters can hack on their own devices, but if they want to sell their cheat tools to the users, they will have to persuade their users to root or jail-break their device firstly, which is not an easy task. So, for cheaters, they think of an easy way to distribute their cheating tools. That is the emulators. Here, I mean emulators like the commercial emulators like Bluestacks, Nox, and so you may have heard of these emulators, and I don't mean the AVD from Android Studio. So, AVD from Android Studio are basically for x86 emulation, which does not support APK that is built for only ARM, or you can build a full ARM emulation in AVD, but it's super slow. So, these commercial emulators like Bluestacks and Nox, they use a different technology called Houdini, which is developed by Intel, and I will introduce this further later. So, for these commercial emulators, they have highly unified environment, so you don't need to tune your software, tune your cheat tools for different firmware or for different API levels, et cetera, and what is better is that these emulators are usually very easy to root, and some of them are even shipped with a rooted environment in advance, so this is a good news for the cheaters. So, according to my investigation, the most popular cheating approach on emulators is Touch Simulation. So, Touch Simulation requires root privilege, it does require root privilege, but it does not involve modification or analysis of games binary. That also means Touch Simulation is a great zone because you can say it is cheating, but you can hardly say it is a crime, it is illegal, because it does not modify the game data directly. So, and the interesting thing is that some Touch Simulation engine even have some advanced function like OCR or image recognition. On the other hand, you can see Cheat by Huking is not showing up on emulators. This is because game codes are usually native, and on commercial emulators they use Houdini, as I said, to translate ARM codes to x86 at runtime. So, this makes it difficult to hook on emulators than on a physical, pure ARM device. So, here comes my research purpose. My purpose is to enable hooking on commercial Android emulators, so you can distribute your Cheat Tours more easily. And this is the emulator targets I have investigated. They are Bluestacks, Nox, and Ladyn. You can tear from this table the Android version, and these emulators are very much alike. They use similar Android versions and also similar Houdini versions. So, maybe it is just a coincidence, but maybe not. This is not our concern, so let's move on to our next page. If you try to run a quant-line binary on emulators, you will find it will be executed properly. This is because the emulators use a feature in Linux called Bing for Maths, MISC. With this feature, you can readjust a certain binary signature or magic number with a certain loader. So, in our case, when the ARM binary comes to emulator, you want to execute it on the emulator. As the slide shows, the Houdini binary, the Houdini executable will be used to load this ARM binary, execute this ARM binary. In this case, it is easy to inject your library to the target executable with RD preload feature, and thus to perform a hooking from your injected library. However, there are other methods very popular used to do hook, like P-Chase, but if you try to use x86 version P-Chase, you won't make it work directly because you can't load your ARM-line binary with x86 DR open. If you compile ARM version P-Chase, because ARM version P-Chase also will run on the emulators, but you will find you will still fail here because, in fact, the P-Chase is very much dependent on the registers, on architectures. So, Houdini seems to fail to translate ARM's P-Chase correctly to x86 version's P-Chase. So, this also doesn't work. But anyway, at least we have the RD preload feature work. So, can we also use RD preload feature to inject your library to a Java application, not a command line application? So, the answer is no, and I will show why the answer is no in the following slides. So, this is a normal Java application startup process. We are known that there is a process called Zygote in Android, and every Java application is forked from it. The basic process is that Zygote runs a loop, and when a startup request comes from activity manager, the Zygote will fork itself and initialize Houdini. You can see Zygote process is initialized where before launching the application. So, setting RD preload environment variable before launching such application will cause no change. Anyway, Android, in fact, it provides a workaround to enable RD preload feature when you start a Java application. So, it's called a rep system property. So, you can set a rep system property to RD preload equal the library you want to inject. And when you set this rep property, the start process is a little bit different. So, this time the Zygote is still listening at a socket, and they're ready to fork itself whenever a startup request comes. But when forked itself in the child process, instead of initialize the application, it executes the APP process binary with share. So, of course, when you are executing a command with share, the share will first fork itself. So, the relation among these processes will finally look like this picture. So, the direct parent of the application process is actually share instead of Zygote. And this is the detail of the core stack. You will see after Zygote forked itself a function called exec application will be called. In this function, it concatenates some command line strings and executes with share. You can see that the APP process binary is executed by share with hyphen application parameters here. So, it looks fine that if you work, if you start your APP with rep property, you can take advantage of RD preload. But actually, if you look carefully to this command line, this command is the final share command when you start application by setting the rep property. So, look carefully. The system being share, this binary is x86 version. And the library you intended to inject is ARM version. So, this actually won't do the trick. It won't load your ARM version's binary to your target process. So, in order to inject an ARM library, I'm afraid we have to investigate more about how Houdini work on emulators. So, again, this is the how Zygote starts. This is the common for both 105 and 104, which are used on this code. So, this is the commercial emulators version, the AOS version. I won't go into detail of this core stack, but note that Houdini still haven't interacted with this part yet. And after the application start up, the application start up request from activity manager is received the Zygote fork itself, and it's here that the Houdini is initialized. From here, the Android 5 and Android 4 behave different. For Android 5, here is the Android 5 picture. Houdini is initialized by the function called, it's marked red. It's called initialized native bridge. In fact, there is another stage called pre-analyzed face, but let's just ignore it for simplicity. So, what's initialized bridge, what this function do is very simple. It just register some corebacks to a structure called native bridge corebacks. So, note there are two functions, very important. It's called load library and get trample line. You can consider it, you can consider them as the ARM versions, DR open and DR same. So, each time the Java layer want to load a library, an ARM library, we call this functions and without handle the different of architecture. So, if you look at liphoudini.sofire, you will find a structure called native bridge interface is exported and some function pointers are there. So, these function pointers will eventually be registered to this native bridge coreback structure. On the other hand, the 400, 400, 400, 400 version with DVM. So, at that time, the Android developers still didn't, they didn't consider, they haven't considered cross-platform implementations. They didn't expect the Android will run on the x86 version device. So, in this case, you have to modify the DVM code yourself. How you modify it is quite simple. So, there is a DVM load native code there and you can insert a function called hook DR open, houdini hook DR open. And what this function do is quite straightforward. It will first, first you call the x86 version DR open to open the library. And if this DR open failed, it will init houdini and use houdini's DR open. And houdini's DR open is, this is marked as red, is called actually its name is dvm2hdd open. And there is also a function similar to DR same, is called dvm2hdd DR same. And these are, these functions are registered in houdini init hook init. So, this is basically how houdini is initialized in emitters. And during my investigations I found some interesting facts. So, there are, as far as I know, intair does not, so houdini is developed by intair. And intair actually does not provide commercial license for houdini library publicly. So, as you can see, there is another emulator, very famous emulator called GeniMotion, which is also super famous but not included in my research. Because it is not bundled with the houdini when released in order to avoid the violence of the intair's license. Instead, it will hint you to download the houdini binary yourself somewhere after you download their software emulations. So, this is not a fashion for users, so GeniMotion is not a main cheating platform. But on the other hand, you can see BlueStacks, it is using houdini while released. And deliberately or not, it seems that it's trying to hide the houdini by the wrist. So, if you look at the reverse, the, by, livedvm.so file in BlueStacks, you can find a code like, it's trying to DR open a library called lib3btrans.so. And if this DR open failed, it will tell you, lib houdini libraries load is failed. It does not consist, consistent. So, actually this lib3btrans.so is libhoudini.so, so they somehow want to hide it. And for NOx, they packed the libdvm.so file. But if you unpack it, it's basically doing the same thing as BlueStacks. So, next let's go to the, let's go to the hooking, hooking stuff. So, there are very many famous hooking frameworks existed, like exposed Frida and substrates, some typical ones. So, exposed, usually is only used for Java applications. For hooking, but I will talk this later to use exposed to utilize, to enable native hooking. So, and the second one, the exposed works by substituting the APP process and it will load its own JAR files in this modified APP process. And once I got it, it makes sure that all of the applications worked from Zygote will load the JAR file in advance. So, and another one is Frida. And Frida is the, is my, personally is my favorite hooking framework, it's instrumentation framework. So, it's, it almost can do everything. You can use it to instrument on your desktop, on iOS, on Android, and you can use it to instrument the Java layer, and you can use it to instrument the native layer. So, but the bad thing for cheaters, they don't want to use Frida, the cheaters don't want to use Frida because Frida acts, Frida acts as a client side and a server side. So, you have to, basically you have to connect your PCs with USB to your device and use your PCs to control the behavior of your device. So, you can't develop cheaters by Frida and distribute it to your users easily. You will require your, it will require your user to plug your USB properly and have a rooted form and have a PC. So, it's not preferable for cheaters. And what's more, the Frida said, the author said they won't support emulators instrumentation in foreseeable future. It's not their priority, and this is on their Github's issues. And substrate is kind of, it's also a good one, works on Android. It works by fake the liblog.sofire. So, every Java application will load this fake liblog.sofire to achieve the injection. So, but it's kind of outdated. It only works up to Android 4.4 if I recall correctly, and if you want to make it work with emulators, you have to do some modification yourselves. So, here comes my propose. So, this is the normal approach for how do you do hooking. So, besides the LD preload trick, you can also do hooking using P-Chase, right? So, the basic idea is to use P-Chase to attach to your target process and call the DI open inside the target process to load your injection library. And in the injection library, you would modify the function entry point. So, that's the hooking part. So, on emulator, it's only one step further to do hooking. So, it's the same first you use P-Chase to attach, the x86 version P-Chase to attach to your target process. And you call the DI open to load x86 versions, your x86 versions injection library. And inside your x86 versions library, you can find, you can load the libhoudini.so and to find the libhoudini.so's DI open inside it. And use this DI open to open your arm versions injection library. And inside this real arm injection library, you can do your hooking work. So, my implementation is based on this A method. But after I implemented it, I found there is an under process. There is other way to achieve this goal. So, you can utilize X-Post. So, X-Post basically it works for x86 Android versions. So, the key point to hook on emulator is to inject your, the most difficult thing is to inject your arm library to the target process. So, as, and being aware that X-Post has already enabled you to inject java code to the target process, you can do it. So, you can do it. You can do it. You can do it. You can do it. You can do it. You can do it. You can do it. You can do it. You can do it. You can do it. You can do it. So, the creative part is to inject your arm library to target process. But you can take advantage of this feature to core system library inside the target process with the help of X-Post. So, note that the system.load library function will take care of the works to load the ARM or X66 version's library, so you can just call it using exposed. So after you load your native library, it's successfully injected to your target process, and then you can do hooking works inside your native library. So this is my Github, my tools to hook on the emulators, and it's based on the method A. I didn't make one based on method B, and the usage is as simple as you can pass the library and the target address to this hook by address function or hook by name function and you can hook it. And I'm going to show you a demo, but you don't expect this demo to be so fantastic because it's on a demo game, and the demo game is basically made by our company for training purpose, and definitely I can't do a demo on a real game product, it's illegal, I've got caught, so I can only perform this on a demo game, so this is the typical cute kawaii characters in Japan. So first you are fighting the boss and the boss SP is very, very sub-checked, and of course you lose, you lose, and this is on the emulator, the NOx emulator, so when you use ADB Shear, you use ADB Shear to connect to the emulator and play this stage again, since you are still losing, but you can find the results, it's actually a win, so finally this is the conclusion for today, so mobile game is getting more and more popular as well as cheating developing, and the cheating patterns change as a technical developer, so I am expecting the cheating patterns will become more popular on Android, and there are more people using hooking skills on emulators instead of only merely touch simulation, the primitive method, but of course, so in order to prepare ourselves as a game company, prepare ourselves for this kind of cheating, we should do some further work like emulator detections or some doing some other efforts in the future, and finally game security is found, and I'm so happy to meet so many guys that like play games or maybe also like hacking games, so thank you. Any questions?