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之间到底在做什么呢?
常数对应的值通过/usr/include/linux/ptrace.h和prctl.h查到,感觉子进程似乎又在调试父进程..
很迷糊 理解不能
另一方面这是个安卓程序应该可以确定,但是怎么运行呢(:з」∠)通过gdb?明天试试吧
C. 明日计划
DebugMe继续调试,摸清