IDA得到的伪代码,有几个点看不懂,请教一下

v102 = v150;
objc_msgSend(v150, "setCanVerify:", v99);
v107 = swift_allocObject(&unk_1022242D0, 24LL, 7LL);
*(_QWORD *)(v107 + 16) = v102;//1. v102是OC对象,是不是可以推断v107swift对象是继承NSObject的?
//2. 这个v107,lldb调试p/po 看不到什么类,有办法看具体是什么类,有哪些属性方法吗?
v144 = sub_1001FAB40;
v145 = (_QWORD *)v107;
aBlock = _NSConcreteStackBlock;
v141 = 1107296256LL;
v142 = sub_10011F630;
v143 = &unk_1022242E8;
v147 = _Block_copy(&aBlock);//3.这个block带的一个参数是哪个?

__int64 __fastcall sub_10011F630(__int64 a1)
{
  __int64 v1; // r13
  v1 = *(_QWORD *)(a1 + 40);
  return (*(__int64 (__cdecl **)(__int64))(a1 + 32))(a1);//这里lldb调试跳转到调用下面的函数sub_1001F9EF0
}

//4. 这个sub_1001F9EF0函数的a2, a3, a4参数是怎么来的,上面只传了一个参数?
__int64 __fastcall sub_1001F9EF0(__int64 a1, __int64 a2, void *a3, __int64 a4)
{/*...*/}

结合汇编看

问题2:lldb的调试需要看语言环境,如果想看oc语法的,使用expr -l objc -- address再看
问题3:如果你可以拿到block的地址,那么可以试试上面的方法得到block对象,里面有invoke地址
有机会试试动态,静态不是万能的 :smiling_face:

动态调试才是逆向最有效的手段,伪代码只是辅助

1 个赞

*(_QWORD *)(v107 + 16) = v102;//1. v102是OC对象,是不是可以推断v107swift对象是继承NSObject的?

应该不可以。据我了解,应该只能看出:只是赋值而已。把v102赋值给*(v107 + 16)

//2. 这个v107,lldb调试p/po 看不到什么类,有办法看具体是什么类,有哪些属性方法吗?

v107(用po都)看不出是什么类,那看来是:调试swift的类方面的技巧了:我暂时没碰到。不清楚。
不过如果有类的定义,按理说可以通过查看内存的值,反推各个属性的值的。

有办法看具体是什么类,有哪些属性方法吗?

有,但都是针对于ObjC的,比如:

  • po someAddr:如果是ObjC类,正常就是打印出,ObjC类名的

查看有哪些属性:

  • po [objcObjectAddress _shortMethodDescription]:就可以查看出对应 有哪些属性和函数方法了
aBlock = _NSConcreteStackBlock;
v141 = 1107296256LL;
v142 = sub_10011F630;
v143 = &unk_1022242E8;
v147 = _Block_copy(&aBlock);//3.这个block带的一个参数是哪个?

-》这个block,没有带额外参数,只带了一个:默认参数==block本身
所以你说的一个参数,估计指的就是:这个block参数本身

注:所有block的被调用的函数=block的invoke函数,被调用时,第一个参数都是:block自身

  return (*(__int64 (__cdecl **)(__int64))(a1 + 32))(a1);//这里lldb调试跳转到调用下面的函数sub_1001F9EF0

//4. 这个sub_1001F9EF0函数的a2, a3, a4参数是怎么来的,上面只传了一个参数?
__int64 __fastcall sub_1001F9EF0(__int64 a1, __int64 a2, void *a3, __int64 a4)

-》*(a1 + 32))(a1) 实际上是就是 sub_1001F9EF0,关于这点,其实是你lldb调试,才看出来的

-》换句话说,直接查看上面IDA伪代码,是看不出来的

-》所以,其实本来就是,很多更深入的,更详细的,更底层的函数调用,参数等逻辑,直接静态分析(查看IDA的伪代码)是看不出来的,只能通过动态调试(lldb调试)等,才能看出来。

而对于sub_1001F9EF0有三个参数:

  • 除了(lldb的)动态调试,可以调试出来
  • 如果熟悉汇编代码,回去看 *(a1 + 32))(a1) 的汇编代码,其按道理,也会有对应的汇编代码,给剩余参数赋值的,比如a2、a3、a4对应着ARM的x1、x2、x3的寄存器,汇编代码中会有x1、x2、x3赋值相关逻辑的。

总结:

  1. 静态分析 只能起辅助作用,无法完全搞懂代码逻辑:是完全正常的
  2. 想要彻底搞懂代码逻辑,往往是,深入的动态调试

而:

  • 上述逆向(静态分析和动态调试)期间涉及到的:block相关知识,函数调用时的函数,等内容,都需要你慢慢掌握,才能更好的去逆向的

部分内容,可以参考我之前的教程:


最后,其实所有内容,我都写了成体系的教程,如果你都看懂了,那上面问题自然就都基本解决了:

成体系的教程的入口就一个:

iOS逆向开发 (crifan.org)

1 个赞