171225 逆向-JarvisOJ(DebugMe)(2)

1625-5 王子昂 总结《2017年12月25日》 【连续第451天总结】
A. JarvisOJ-DebugMe(2)
B.
查到WP:http://blog.csdn.net/charlie_heng/article/details/78644424
参照其的说法,v10的算法是

7 * (v3 + 1) - 11*sub_E14(7 * (v3 + 1), 11)

分别对7和0作为起始参数来迭代,发现为0的时候可以输出8个字符

main函数中对input进行了两次变换,都是有条件的

  if ( sub_A30(2u, (int)argv) )
  {
    for ( i = 0; i < j_strlen(name); ++i )
      byte_4008[i] = name[i] ^ i;               // 变换输入
  }
  if ( !j_strstr(v20, &v15) )                   // cmdline中没有sh时执行
  {
    for ( j = 0; j < j_strlen(name); ++j )
      byte_4008[j] = name[j] ^ 1;               // 再次加密
  }

由于关键函数取值都是从byte_4008中取得,因此只有异或1和异或i两种可能,分别尝试也行

前者有sub_A30的返回值决定,sub_A30中fork了一个子进程,然后通过ptrace和prctl进行复杂的交互,没有研究明白
返回值由父进程的waitpid决定,应该是当子进程正常返回信号时会进入

后者则是由进程的命令行参数决定,没观察过所以也不太清楚..

最关键的是v3的迭代方法如何看出

.text:00000D40                 MOVS    R0, #7
.text:00000D42                 ADDS    R3, R7, #1
.text:00000D44                 MULS    R0, R3          ; 7*(r7+1)
.text:00000D46                 MOVS    R1, #0xB        ; 11
.text:00000D48                 BL      sub_EAC
.text:00000D4C                 ADDS    R4, #1
.text:00000D4E                 MOVS    R7, R1

参数很明显,分别是R0=7*(v3+1)和R1=11
返回值很明显通过R1传递,R4是计数器

再进入sub_EAC追踪R1

.text:00000EB0                 PUSH    {R0,R1,LR}
.text:00000EB2                 BL      sub_E14
.text:00000EB6                 POP     {R1-R3}
.text:00000EB8                 MULS    R2, R0          ; r1=r1-(r2*r0)
.text:00000EBA                 SUBS    R1, R1, R2
.text:00000EBC                 BX      R3

发现将R0和R1两个参数push入栈,但函数返回以后将堆栈POP出来到R1-R3中
可以看出R1=R1-(R2*R0)

根据WP的说法反推,可以知道R1=7*(v3+1),R0和R2一个表示11,一个表示函数返回值

但是没明白这三个值是怎么找出来的,R0和R1似乎互换位置了,R2又为啥表示返回值捏
接触ARM的太少
不明所以

另一方面,调用参数为0的原因应该是sub_D90,这个函数通过sigaction绑定到内存访问错误的信号处理上,内部也有正确和错误提示

但是怎么触发的内存访问错误呢?
父子进程的ptrace和prctl之间到底在做什么呢?
171225 逆向-JarvisOJ(DebugMe)(2)_第1张图片

常数对应的值通过/usr/include/linux/ptrace.h和prctl.h查到,感觉子进程似乎又在调试父进程..
很迷糊 理解不能
另一方面这是个安卓程序应该可以确定,但是怎么运行呢(:з」∠)通过gdb?明天试试吧

C. 明日计划
DebugMe继续调试,摸清

你可能感兴趣的:(CTF)