CTF 安卓逆向

MagicImageViewer——png结构+算法

很少做安卓逆向的题目,在此记录一下

先用模拟器看一下



嗯,没啥提示。

jeb打开

关键部分

if(s.length() == 16) //输入的字符串长度为16

String s1 = MainActivity.this.getKey(s); //该方法获得s1,getKey()在native层

Bitmap bitmap0 = MagicImageUtils.readMagicImage(MainActivity.this, "png/encrypt_png.dat", s1);
// MagicImageUtils.readMagicImage是Java层的方法

先看getKey()

关键部分

strcpy(v5, "Welcome_to_sdnisc_2018_By.Zero");

v13[i] = *(v7 + 2 * i) ^ v5[i - 30 * (v9 / 30)];

2*i比较怪,是什么呢?我们查一下JNI的GetStringChars方法,由参考链接1可知它返回的是Unicode格式的char*,所以2字节算一个字符**

v5[i - 30 * (v9 / 30)这个就是v5[i]

就是对输入的字符串进行异或(前16位)

接着看MagicImageUtils.readMagicImage



关键部分

int v1 = inputStream0.read();//读取路径文件
arrayList0.add(Byte.valueOf(((byte)MagicImageUtils.decrypt(v1, ((char)s1.charAt(v % 16))))));
//decrypt() 在native层



也是个异或

接着往下看可以发现,后面生成了图片,也就是对于加密后的图片数据,解密为图片

输入s,s与v5异或得到s1,s1,路径文件异或生成内容转化,图片。

但是png图片的前16位是固定的,所以很容易解出来。

goal = b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52' //png图片的前16 位
key_s = 'Welcome_to_sdnisc_2018_By.Zero'
ans = '' with open('encrypt_png.dat', 'rb') as f:
dat = f.read(16)
for i in range(16):
v = (dat[i] - 1) ^ 0x61 ^ goal[i] ^ ord(key_s[i])
ans += chr(v)
print(ans)

输出 XaE3*2#@!qV^v+_.

验证:

得到flag。

此时可以更为有趣的写出png(刚开始没想到)

此时

没看懂getKey也能过这题。

作者贴心地提供了一个正常图片的处理函数MagicImageUtils.readImage。

此时会出现dat=0的情况,所以加了验证

goal = b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52'

def b(v):
return v if v >= 0 else 0xff with open('encrypt_png.dat', 'rb') as f:
dat = f.read()
_key = b''
for i in range(16):
_key += (b(dat[i] - 1) ^ 0x61 ^ goal[i]).to_bytes(length=1, byteorder='big', signed=False)
with open('flag.png', 'wb') as f:
for i in range(len(dat)):
f.write((b(dat[i] - 1) ^ 0x61 ^ _key[i & 0xf]).to_bytes(length=1, byteorder='big', signed=False))

flag{y0ur'r3_g00d_aT_4ndr01d}

参考链接:

https://www.cnblogs.com/lijunamneg/archive/2012/12/22/2828891.html

https://www.52pojie.cn//thread-1665541-1-1.html

随机推荐

  1. java数组使用、Arrays类使用 、排序方法

    数组使用 数组的基本使用: package charpter4; public class ArrayDemo2 { public static void main(String[] args) { ...

  2. PHP微信三方平台-代公众号发起微信支付(jsAPI)

    一.前期准备工作 1.微信公众号需要开通微信支付认证将获取的秘钥给三方平台 2.添加支付回调域名地址:填写三方平台域名地址即可(最多5个) 二.代码demo 1.完成支付类 <?php /** ...

  3. js模拟下拉菜单

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Linux磁盘LVM根目录扩容

    LVM 的基本概念 物理卷 Physical Volume (PV):可以在上面建立卷组的媒介,可以是硬盘分区,也可以是硬盘本身或者回环文件(loopback file).物理卷包括一个特殊的 hea ...

  5. 新手小白需要了解的 Go 基础细节杂谈

    今日记录一下 学习 golang 这门语言遇到的一些比较特殊的细节,供大家参考. 所以,在我们输出内容的时候,可以包含很多的非 ASCII 码字符.实际上,Go 是天生支持 UTF-8 的,任何字符都 ...

  6. Java设计模式 —— 享元模式

    14 享元模式 14.1 享元模式概述 Flyweight Pattern: 运用共享技术有效地支持大量细粒度对象的复用. 当系统中存在大量相同或相似的对象时,它通过共享技术实现相同或相似的细粒度对象 ...

  7. classmethod和staticmethod装饰器

    """ 两个装饰器 @classmethod 把一个对象绑定的方法,修改成为一个类方法 1.在方法中仍然可以引用类中的静态变量 2.可以不用实例化对象,就直接使用类名在外 ...

  8. Semantic Kernel 入门系列:🥑Memory内存

    了解的运作原理之后,就可以开始使用Semantic Kernel来制作应用了. Semantic Kernel将embedding的功能封装到了Memory中,用来存储上下文信息,就好像电脑的内存一样 ...

  9. [备份]Open-CMSIS-Pack Flash Programing

    Flash Programming Flash Programming Algorithms are a piece of software to erase or download applicat ...

  10. Dokcer应用部署(搭建Wordpress网站)

    实现多个容器之间的协同,搭建Wordpress网站,要用到3个容器,Wordpress.MariaDB和Nginx 拉取镜像 使用docker pull拉取3个镜像: $ sudo docker pu ...