On Device Debug!IDA+GDB trace automagic.apk in s1

article/2025/9/18 5:34:48

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

http://forum.xda-developers.com/showthread.php?t=2050393


Well... I have attached a debugger to native code, set breakpoints, analyzed registers, memory, etc. It wasn't that easy though. It took me several days to start debugging and get first key, but I got second one in about 1 hour.


Actually I don't really need that key, I can't even play Angry Birds Rio on my old G1, but it was challenging and I love challenges ;) Plus I have learnt a LOT about gdb, assembler, ARM architecture, etc.

So I want to thank you, Goddchen, for giving me an opportunity to learn & play :)

Ok, let's move on...

First, I have disassembled libangrybirds.so using IDA Pro 5.5 . I was able to examine code and attach IDA to gdbserver on a device, but unfortunately it wasn't working properly. IDA was thinking that libangrybirds.so is a main binary of a process it attached to, but it should look into loaded shared libs instead. Weird, but I didn't find a way to attach it properly. And this is pity, because IDA is a great tool and it would make debugging a pleasure, but I had to use gdb instead.

Second, Android has problems with debugging multi-threaded native code. MT support was added in NDK r5 and because of some bug it's not possible on a system older than Gingerbread.

Third, you could attach gdb manually, but ndk-gdb script does great work for you. You will have to do some tricks to use it with 3rd party app though.

Fourth, it seems libangrybirds.so is a Java code compiled to native or something like that. There are objects like FileInputStream, ByteOutputStream, etc., but there are also some API differencies. We'll see String and Array<uchar> objects, but it's usually easy to find a pointer to simple uchar[].

Steps to start native code debugging:
  1. Upgrade to Gingerbread (Yeah, I had to do that. Hacking requires you to sacrifice yourself a bit ;) ). Or you could use an emulator.
  2. Install NDK >= r5 .
  3. Decode Angry Birds Rio using apktool. You could just unzip it, but decoded app is much more similiar to original sources, so it's more compatible with NDK. For example ndk-gdb reads AndroidManifest.xml to get package name. Of course you could fake simple AndroidManifest.xml and other files if you want.
  4. Rename lib dir to libs.
  5. Fake jni/Android.mk file. I have copied one from hello-jni sample and didn't even bother to modify module name: http://pastebin.com/HMBXt5cm .
  6. Copy libs/armeabi*/libangrybirds.so to obj/local/armeabi*/ . Normally this is done by ndk-build command.
  7. Fake libs/armeabi*/gdb.setup file. It should be something like: http://pastebin.com/BYm13RKz , but second line isn't that important.
  8. Angry Birds Rio apk contains old gdbserver and you need one from NDK r5. Grab ${NDK_ROOT}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/gdbserver and push it to /data/data/com.rovio.angrybirdsrio/lib .
  9. Ufff... you could now try to run: ndk-gdb --verbose --launch=com.rovio.ka3d.App .
  10. After few seconds you should see "(gdb)" prompt and game should be paused on the device.
  11. Run 'info shared' and check if libangrybirds.so is loaded. If not then something is wrong.

Ok, let's find a key for levels lua files:
  1. Set a breakpoint for GameLua::loadLevel() - find this method in IDA Pro and copy its EXPORT name:
    Code:
    (gdb) br _ZN7GameLua9loadLevelEN4lang6StringE
    Breakpoint 1 at 0x80468e4c
  2. Resume game and open some level. You should hit a breakpoint:
    Code:
    (gdb) c
    Continuing.
    [New Thread 5857]
    [Switching to Thread 5857]Breakpoint 1, 0x80468e4c in GameLua::loadLevel () from /home/brutall/t-angrybirds/com.rovio.angrybirdsrio-1/obj/local/armeabi/libangrybirds.so
  3. Look into IDA and note there are 2 lang::String objects passed as first arguments to method, so pointers are in R1 and R2 registers. We need to examine these objects and find pointers to raw char[]. Fortunately lang::String is very simple wrapper around char[], so pointer is first (and only one, I think) member of String:
    Code:
    (gdb) x/4x $r1
    0x4395e66c:	0x00a405f0	0x00153b28	0x804ec778	0x00000000
    (gdb) x/s 0x00a405f0
    0xa405f0:	 "levels/warehouse/Level190"
    Yey, finally we see something :)
  4. Let's move to lang::AESUtil::decrypt() method. It's named _ZN4lang7AESUtil7decryptERKNS_5ArrayIhEES4_RS2_, so:
    Code:
    (gdb) advance _ZN4lang7AESUtil7decryptERKNS_5ArrayIhEES4_RS2_
    0x80539894 in lang::AESUtil::decrypt () from /home/brutall/t-angrybirds/com.rovio.angrybirdsrio-1/obj/local/armeabi/libangrybirds.so
  5. As you can see decrypt() gets 3 Array<uchar> objects and 2 of them are const. It's quite easy to guess they're: key, encrypted data and container for decrypted data. Let's check this:
    Code:
    (gdb) x/4x $r1
    0x1592b0:	0x00159528	0x00000020	0x00000020	0x7b206e65
    0x00000020 = 32 - yes, length of AES key :) First 4 bytes of an Array object is a pointer to raw char[] and second 4 bytes contain length of an array. Now we could read contents of an Array:
    Code:
    (gdb) x/s 0x00159528
    0x159528:	 "USCaPQpA4TSNVxMI1v9SK9UC0yZuAnb2a"
    :) As you can see there are 33 chars instead of 32. This is because Array stores its length, so char[] isn't null-terminated. Ignore last "a" char.
  6. We could also look into second const Array to be sure that encoded string is exactly the same as contents of lua file:
    Code:
    (gdb) x/4x $r2
    0x4395d6f4:	0x009ca248	0x000004a0	0x000004a0	0x00000378
    (gdb) x/4x 0x009ca248
    0x9ca248:	0x3347b5dc	0x26048446	0x1a0c1231	0x35d3f99c
    First 16 bytes are the same, length of data is also ok.

As you can see there is AES::BlockMode passed to AES: ecrypt(). It would be quite hard to interpret it without headers, so I was trying various block modes and I found that CBC with empty initial vector decodes to string starting with '7z'. For me that meant: mission successfull :)

Ok, highscores.lua and settings.lua files now. Technique is very similar, but there are some differences:
  • Different keys.
  • They aren't loaded using GameLua::loadLevel(), but GameLua::loadPersistentFile(). You could find this very easily, searching for "highscores.lua" in IDA.
  • If you examine GameLua::loadPersistentFile() method you will see it doesn't load files using FileInputStream, but io::AppDataInputStream, so we have to be sure, what exactly is being decrypted.
  • Annoying thing is that gdb can't catch highscores/settings loading, because they're loaded too soon - before gdb attach itself.

Maybe there is a better solution to last problem, but I've decided to add some Thread.sleep() call just after System.loadLibrary(), so gdb will attach before highscores.lua loading.
  1. Open smali/com/rovio/ka3d/App.smali, and add 2 lines of code just after loadLibrary() call in onCreate() method:
    Code:
    invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)Vconst-wide/16 v0, 5000invoke-static {v0, v1}, Ljava/lang/Thread;->sleep(J)V
  2. Run ndk-gdb --verbose --launch=com.rovio.ka3d.App .
  3. Set a breakpoint for GameLua::loadPersistentFile() method and check which file is being loaded:
    Code:
    (gdb) br _ZN7GameLua18loadPersistentFileERKN4lang6StringE
    Breakpoint 1 at 0x80457030
    (gdb) c
    Continuing.
    [New Thread 6735]
    [Switching to Thread 6735]Breakpoint 1, 0x80457030 in GameLua::loadPersistentFile () from /home/brutall/t-angrybirds/com.rovio.angrybirdsrio-1/obj/local/armeabi/libangrybirds.so
    (gdb) x/s $r2
    0x4395e3b8:	 "highscores.lua"
    I'm not sure why it's R2, not R1 and why there is no lang::String, but char[] directly. I think this isn't a pointer to String, but String itself, passed to method in registers, so its char[] is in R2.
  4. Now advance to lang::AESUtil::decrypt() method and read key as usual:
    Code:
    (gdb) advance _ZN4lang7AESUtil7decryptERKNS_5ArrayIhEES4_RS2_
    0x80539894 in lang::AESUtil::decrypt () from /home/brutall/t-angrybirds/com.rovio.angrybirdsrio-1/obj/local/armeabi/libangrybirds.so
    (gdb) x/4x $r1
    0x159294:	0x00159620	0x00000020	0x00000020	0x00159518
    (gdb) x/s 0x00159620
    0x159620:	 "44iUY5aTrlaYoet9lapRlaK1Ehlec5i0"
  5. Because of that AppDataInputStream object, we need to check if encrypted data is the same as file contents. Pull highscores.lua file from a device and run:
    Code:
    (gdb) x/4x $r2
    0x4395ddc4:	0x0015bc00	0x00000040	0x00000040	0x00000001
    (gdb) x/16x 0x0015bc00
    0x15bc00:	0x2271b777	0xe6f19f4c	0x2489a316	0xfae1aee2
    0x15bc10:	0x82e0ef38	0xe84fc25d	0xb196adac	0xbf030439
    0x15bc20:	0xb6b9bade	0x3046af12	0xe8eeeb0d	0x20e8037c
    0x15bc30:	0x1a405edf	0xc218f7f6	0xc29209e2	0x9ad03e8c
    Yeah, this is my highscores.lua file.
  6. Same for settings.lua file to check if it's encrypted with the same key. It is.
  7. After decrypting these files we'll see some weird chars at the end of decoded data. Few seconds on the Wikipedia and we'll know this is just PKCS7 padding scheme.

Now we have got everything we want :)

Ahh, not exactly everything... I would be really happy to know, how to properly attach IDA for debugging - it would be much easier, even if gdb interface is also very good.

转载于:https://my.oschina.net/zhuzihasablog/blog/141016


http://chatgpt.dhexx.cn/article/Va0JeR4h.shtml

相关文章

【Jetson Nano 入门】环境配置汇总

文章目录 前言一、镜像烧写二、PWM风扇自动调速三、使用MicroUSB在电脑打开终端四、VNC实现局域网及网线直连通信五、SSH文件传输六、状态监控软件Jtop七、检查CUDA、OpenCV及cuDNN八、USB摄像头测试软件Camorama九、CSI摄像头测试十、实现Yolov4-tiny的USB摄像头实时检测 前言…

WEB UI自动化测试之AutoMagic自动化测试平台开源

作者介绍&#xff1a; 网名: Ray 介绍&#xff1a;笑起来像个孩子&#xff0c;冷起来是个迷。 博客&#xff1a;http://www.cnblogs.com/tsbc/ 2018年3月29日&#xff0c;Ray说准备把AutoMagic自动化测试管理平台开源了&#xff01;&#xff01;&#xff01; 这是个好消息&…

三星s20 android auto,Automagic一个更简单的方式来自动化您的Android手机 | MOS86

你有没有想过你的智能手机会在你回家的时候开始播放音乐&#xff1f;当你关闭社交网络的时候怎么样&#xff1f;Automagic是一种替代方案&#xff0c;通过使用易于理解的流程图执行许多相同的任务&#xff0c;向用户提供了一种更简单的自动化Android手机的方法。 Automagic如何…

AutoMagic自动化测试平台简介

PS:给想做自动化平台同学一点思路。 AutoMagic 是一个基于WebUI的自动化管理平台。为什么叫AutoMagic呢&#xff1f;因为自动化&#xff08;Automation&#xff09;在执行起来的时候是一个很神奇的事情&#xff0c;它可以无人值守的模拟人的操作&#xff0c;就像魔术&#xff0…

AutoMagic设计思路简介及新增自定义关键字实例

目录 简介 AutoMagic介绍 SeleniumKey介绍 自定义关键字 简介 AutoMagic 是一个基于WebUI的自动化管理平台。为什么叫AutoMagic呢&#xff1f;因为自动化在执行起来的时候是一个很神奇的事情&#xff0c;它可以无人值守的模拟人的操作&#xff0c;就像魔术&#xff08;Magic&am…

AutoMagic-开源自动化平台的容器化构建

github上看到AutoMagic自动化平台开源了&#xff0c;一时手痒&#xff0c;就试着搭了一套环境&#xff0c;现在把思路和大家说一说。 AutoMagic从其工作分工分两部分&#xff1a; 1&#xff1a;Web端管理平台 管理平台基于Python Django框架Mysql开发&#xff0c;主要用来管理自…

Automagic Premium 安卓上的自动化神器

每当我使用手机时&#xff0c;就对各种App的签到领奖非常反感&#xff0c;如果不签好像吃了亏&#xff0c;签一次花的时间自己也觉得不值。这时候我就在想&#xff0c;如果有一个App&#xff0c;能够自动帮我完成这种每天重复执行的任务就好了。之前找到一个叫uiautomator2的py…

[重磅消息]AutoMagic自动化测试平台开源

作者介绍&#xff1a; 网名: Ray 介绍&#xff1a;笑起来像个孩子&#xff0c;冷起来是个迷。 博客&#xff1a;http://www.cnblogs.com/tsbc/ 2018年3月29日&#xff0c;Ray跟我说准备把AutoMagic自动化测试管理平台开源了&#xff01;&#xff01;&#xff01; 这是个好消息&…

AutoMagic使用说明

简介 自动化测试管理平台&#xff0c;可以进行用户、产品、项目、模块、测试用例、测试元素、测试关键字、测试报告的管理等。 Github地址&#xff1a;https://github.com/radiateboy/automagic/ 用户和产品管理 本平台是自动化管理平台&#xff0c;整个平台结构是 用户>产品…

AutoMagic使用说明以及图文操作步骤

一、简介 自动化测试管理平台&#xff0c;可以进行用户、产品、项目、模块、测试用例、测试元素、测试关键字、测试报告的管理等。 二、平台结构设计 三、用例关系 四、用户和产品管理 本平台是自动化管理平台&#xff0c;整个平台结构是 用户>产品>项目>模块>…

automagic 使用_使用Automagic在Android设备上自动化任务

automagic 使用 Automation is always a good thing, and we’ve looked at various ways in which you can automate tasks on your Android. AutoMagic takes a different approach to things, making it possible to create flow charts that are used to trigger actions b…

AutoMagic-开源自动化平台构建思路

最近在github上看到AutoMagic自动化平台开源了&#xff0c;一时手痒&#xff0c;就试着搭了一套环境&#xff0c;现在把思路和大家说一说。 AutoMagic从其工作分工分两部分&#xff1a; 1&#xff1a;Web端管理平台 管理平台基于Python Django框架Mysql开发&#xff0c;主要用来…

VMware中卸载Ubuntu

1、右键>>管理>>从磁盘中删除 2、点击“是”&#xff0c;磁盘路径安装Ubuntu的文件一并删除

Ubuntu系统的卸载与安装

Ubuntu系统的卸载与安装 卸载 如果要重装Ubuntu系统&#xff0c;在重装之前需要先把原来系统进行删除&#xff0c;并且删除引导向 具体步骤参考&#xff1a;https://blog.csdn.net/Spacegene/article/details/86659349 用管理员权限打开记事本&#xff1a;https://zhidao.bai…

Ubuntu 22.04 双系统安装和卸载

前言&#xff1a; 一,为什么选择Ubuntu系统&#xff1f; 1.免费且提供长期系统维护支持&#xff1b;2.是主流的Linux服务器发行版&#xff1b; 3.强大的Shell&#xff1b;4.简洁好看的图形化UI界面&#xff1b;5.丰富的软件支持&#xff1b; 二&#xff0c;如何联系我&…

3种方法来卸载Ubuntu软件

1 使用Synaptic软件包管理器进行卸载 1 打开软件包管理器。Ubuntu自带了一个GUI&#xff08;Graphical User Interface&#xff0c;图形化用户界面&#xff09;软件包管理器&#xff0c;它可以让你在一个可视化窗口中卸载程序。如果你不习惯使用命令行&#xff0c;这一工具将非…

在Win10和Ubuntu双系统下卸载Ubuntu系统的方法

一、清除Ubuntu系统 删除Ubuntu系统使用的几个分区(包括EFI分区)&#xff0c;注意不要删除Windows的EFI分区&#xff1b;如果不确定Ubuntu相关分区&#xff0c;可以通过[WindowsX]选择磁盘管理&#xff0c;通过分区大小进行对比判断。 二、删除开启引导启动项 删除了Ubuntu系…

电脑双系统完美卸载Ubuntu

【由于自己经常在Ubuntu下跑各种包&#xff0c;经常遇到依赖项不兼容问题&#xff0c;所以有时需要卸载重装Ubnutu系统&#xff0c;故写下此文以备查阅&#xff1b;本文是在多次卸载经验后摸索出来的方法&#xff0c;可以在不影响Windows系统下成功的完成Ubuntu系统的卸载】 1…

Windows+Ubuntu双系统下卸载Ubuntu

记录一下自己卸载Ubuntu的步骤&#xff0c;防止以后再卸载重新找教程。 1.删除Ubuntu的分区 步骤1&#xff1a;打开 “ 我的电脑 ”&#xff0c;选择 “ 管理 ”&#xff0c;点击 “ 磁盘管理 ”。 步骤2&#xff1a;确定Ubuntu系统所在的磁盘分区&#xff08;我的是磁盘1的磁…

卸载ubuntu系统简单实用

删除EFI分区部分主要参考博客https://blog.csdn.net/mtllyb/article/details/78635757 因为我最近需要更新ubuntu系统,参考了好多教程,感觉还是很麻烦的,我就是直接删除了ubuntu的系统分区,因为我对ubuntu系统的具体结构也不是很了解,不知道会不会有什么隐患.不过我更新ubuntu…