神奇的zip 顺藤摸瓜 Writeup

神奇的zip

首先拿到的apk坏了, 拖到linux下zip -ff testndk4_Signed4.zip修复一下, 第一个知识点完成.

题目是纯的Java加上存的JNI, Java下没有需要分析的逻辑.

首先需要绕过一处一定会退出的检查, 修改so文件里的move r0,0为move r1,1强行返回1. 或者直接动态调在此处下断点改寄存器过去.

        super.onCreate(arg5);
        this.setContentView(2130903065);
        if(this.isExit()) {
            this.startActivity(new Intent(((Context)this), MainActivity.class));
        }
        else {
            Timer v0 = new Timer();
            b v1 = new b(this);
            Toast.makeText(((Context)this), "抱歉,请先获得权限,再进入!!", 0).show();
            v0.schedule(((TimerTask)v1), 5000);
        }

题目有个问题对动态调试没有做任何限制,因此在最终需要比较的密码处下个断点看内存即可发现flag.

int __fastcall Java_com_example_testndk4_MainActivity_encodePassword(int a1)
{
  int v1; // r5@1
  const char *v2; // r7@1
  char *src; // ST04_4@1
  char *v4; // ST04_4@1
  char *v5; // r0@2
  const char *v6; // r1@2
  int result; // r0@4
  char v8; // [sp+8h] [bp-58h]@1
  char v9; // [sp+14h] [bp-4Ch]@1
  char s; // [sp+28h] [bp-38h]@1
  int v11; // [sp+44h] [bp-1Ch]@1

  v1 = a1;
  v11 = _stack_chk_guard;
  v2 = (const char *)Jstring2CStr();
  j_j_memcpy(&v9, "thinkingInAndroid", 0x12u);
  src = (char *)encodePS(&v9);
  j_j_memset(&s, 0, 0x1Au);
  j_j_strcpy(&s, src);
  v4 = (char *)encodePS(&s);
  j_j_memset(&v8, 0, 0xAu);
  if ( j_j_strcmp(v2, v4) )
  {
    v5 = &v8;
    v6 = "Sorry!";
  }
  else
  {
    v5 = &v8;
    v6 = "Sucess!";
  }
  j_j_strcpy(v5, v6);
  result = (*(int (__fastcall **)(int, char *))(*(_DWORD *)v1 + 668))(v1, &v8);
  if ( v11 != _stack_chk_guard )
    j_j___stack_chk_fail(result);
  return result;
}

看源码或者F5都可以发现程序是对thinkingInAndroid字符串做了复杂的运算,但是用户输入没有参与进来,最后将用户输入与复杂预算的结果比较, 直接在那里下断点输出:

MOVS    R0, R7          ; s1
LDR     R1, [SP,#0x60+src] ; s2
--> set bp here :BL      j_j_strcmp
CMP     R0, #0
BNE     loc_1042

定位到内存,得到flag:lxienietIeAehfyih

顺藤摸瓜

单纯的jni逻辑分析, java代码只涉及一点.

int __fastcall Java_com_example_demo_MainActivity_check(int a1, int a2, int a3)
{
  int v3; // r4@1
  int v4; // r6@1
  int v5; // r7@1
  void *v6; // ST08_4@1
  int v7; // r0@1
  int v8; // r7@1
  signed int v9; // r6@1
  void *v10; // r5@2
  signed int v11; // r0@4
  signed int i; // r3@4
  int result; // r0@7
  void *src; // [sp+8h] [bp-2F0h]@1
  char dest[56]; // [sp+14h] [bp-2E4h]@4
  char v16[200]; // [sp+4Ch] [bp-2ACh]@4
  char v17; // [sp+114h] [bp-1E4h]@4
  char s; // [sp+1DCh] [bp-11Ch]@4
  int v19; // [sp+2DCh] [bp-1Ch]@1

  v3 = a1;
  v4 = a3;
  v19 = _stack_chk_guard;
  v5 = (*(int (**)(void))(*(_DWORD *)a1 + 24))();
  v6 = (void *)(*(int (__fastcall **)(int, const char *))(*(_DWORD *)v3 + 668))(v3, "GB2312");
  v7 = (*(int (__fastcall **)(int, int, const char *, const char *))(*(_DWORD *)v3 + 132))(
         v3,
         v5,
         "getBytes",
         "(Ljava/lang/String;)[B");
  v8 = (*(int (__fastcall **)(int, int, int, void *))(*(_DWORD *)v3 + 136))(v3, v4, v7, v6);
  v9 = (*(int (__fastcall **)(int, int))(*(_DWORD *)v3 + 684))(v3, v8);
  src = (void *)(*(int (__fastcall **)(int, int, _DWORD))(*(_DWORD *)v3 + 736))(v3, v8, 0);
  if ( v9 <= 0 )
  {
    v10 = 0;
  }
  else
  {
    v10 = j_j_malloc(v9 + 1);
    j_j_memcpy(v10, src, v9);
    *((_BYTE *)v10 + v9) = 0;
  }
  (*(void (__fastcall **)(int, int, void *, _DWORD))(*(_DWORD *)v3 + 768))(v3, v8, src, 0);
  j_j_memset(v16, 0, 0xC8u);
  j_j_memset(&v17, 0, 0xC8u);
  j_j_memset(&s, 0, 0x100u);
  j_j_memcpy(dest, &unk_2454, 0x38u);
  v11 = j_j_strlen((const char *)v10);
  for ( i = 0; i < v11; ++i )
    v16[i] = *((_BYTE *)v10 + i) + 97 - dest[4 * i];
  v16[v11 & (~v11 >> 31)] = 0;
  n1(v16, "nbrcdpassword", &v17);
  n2(&v17, &s);
  result = (unsigned int)j_j_strcmp(&s, "7405847394833303439294822334") <= 0;
  if ( v19 != _stack_chk_guard )
    j_j___stack_chk_fail(result);
  return result;
}

先贴一下F5, 其中没有用的逻辑很多, 基本就是如何如何从java拷贝到c申请内存然后到处挪.ida改的变量名没保存.变量里边dest有点用从内存一遍读取了一段加密向量. 然而这些都没有卵用.......

# 我们白白做了这么多工作
#!/bin/env python
#coding:utf-8
import string

iv1 = [0x3F,0x4D,0x6C,0x5B,0x54,0x5B,0x6C,0x5B,0x54,0x46,0x38,0x46,0x3F,0x1C]
iv2 = "nbrcdpassword"
#iv2_alpha = [ord(x) - ord('a') for x in iv2]


final = "7405847394833303439294822334"
#byte1 = [int(final[x:x+2:][::-1]) + 72 - 97 for x in range(0, len(final), 2)]
byte1 = map(int, list(final))
print byte1

#print string.printable
for i in range(14):
    for k in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_":
        k1 = ord(k) - iv1[i] + 0x61 - ord('a')
        k2 = (k1 + ord(iv2[i % len(iv2)]) - ord('a'))%26 + 97 - 72
        if k2 % 10 == byte1[2*i] and (k2/10)%10 == byte1[2*i+1]:
            print k,
    print 
    

因为我们可以从java逻辑中发现jni做不做只影响判断, 对输出没有影响......

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(1);
        this.setContentView(2130903065);
        this.D_text = this.findViewById(2131296319);
        String v0 = this.D_text.getText().toString();
        String v3 = "";
        int v2;
        for(v2 = 0; v2 < v0.length(); ++v2) {
            try {
                v0.charAt(v2);
                v3 = String.valueOf(v3) + (((char)(v0.charAt(v2) - 8)));
            }
            catch(Exception v1) {
                v3 = String.valueOf(v3) + v0.charAt(v2);
            }
        }

        this.D_text.setText(((CharSequence)v3));
    }
}

上面的代码, 当jni执行了或者被绕过之后, 逻辑是对一段R中的烫烫烫进行了移位.
碸夼圸烁B夲皅卟跷:叿 + 8 = 西电的校址会面 = flag

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容