自制反汇编逆向分析工具 迭代第六版本 (四)
2016-05-19 17:16
253 查看
本工具从最初版的跳转分布图只为了更直观地分析反汇编代码的分支结构,第三版开始对直观图进行逆向分支代码的输出,第四版对分支输出策略的一些探索,第五版结合之前的探索进行改进。第六版在现在功能的基础上进行增强,利用第六版(一)的基本功能-直译,第六版(二)对条件分支增加条件判断翻译,以及改进在函数调用处附带备选参数参考。
第六版(三)将(一)和(二)组合在一起进行逆向代码输出。
本篇是(四),在(三)的基础上增加对原子操作指令的逆向以及c++函数的逆向。
指令的原子操作如OSAtomic(Add|Xor|Or|And|CompareAndSwap),就是Lock锁总线后的指令操作。
下面说的是c++函数调用的逆向,主要如何套用参数。
c风格的函数和c++函数,在生成的函数符号上有区别。c风格的函数的符号不会有参数的任何信息,顶多就有参数的总大小(size),如msvc对extern "C" void test(int)可能生成 _test@4这样的符号。而c++风格的符号则会带上函数原型的全面信息,如属于哪个类哪个名字空间参数序列几何,这样才能够使c++在相同的函数名可以被重载,符号连接才不会冲突。所以在调试器反汇编出来的代码,往往可以提示出c++函数的原型,而c风格的函数只有名字(不能解析参数序列)。
既然调试器反汇编出了c++函数符号,就应该好好使用。但调试器并没有提示一个类的函数是静态成员函数还是成员函数,因为这两种函数在调用约定时,相差了一个参数位,所以在逆向分析时要进行分析区分。一般来说,构造和析构函数一定是成员函数,static和const修饰不同时使用,带const修饰就可以认为也是成员函数。剩下来的就只能够通过分析判断。
我的方法是将类方法同时分别去应用两种调用约定(不带this的静态成员函数调用和带this的成员函数调用),然后分别对两种情况下寄存器使用的匹配度进行比较,判断出其中的一种。不像hopper那样,将明明是c++的类方法,却当作c风格函数来简单处理。
下面是对CA::Render::key_path_set(void**, __CFString const*)调用的分析判断,判断结果是成员函数参数序列不相符,所以应当是静态成员函数。
再来看
首先是CA::Render::Object::unref() const,可以确定这是一个成员函数,所以使用成员函数调用方式。
接着是CA::Layer::set_animations(CA::Layer::Animation*), 两种方式的假设都没有找出不符,优先使用成员成员函数方式。
第三是CA::Layer::mark_animations(CA::Transaction*, bool),静态成员方式调用匹配有不符,所以可以判定是成员函数。
下面是贴上两个函数的逆向输出:
CA::Layer::update_removed_sublayer
第六版(三)将(一)和(二)组合在一起进行逆向代码输出。
本篇是(四),在(三)的基础上增加对原子操作指令的逆向以及c++函数的逆向。
指令的原子操作如OSAtomic(Add|Xor|Or|And|CompareAndSwap),就是Lock锁总线后的指令操作。
下面说的是c++函数调用的逆向,主要如何套用参数。
c风格的函数和c++函数,在生成的函数符号上有区别。c风格的函数的符号不会有参数的任何信息,顶多就有参数的总大小(size),如msvc对extern "C" void test(int)可能生成 _test@4这样的符号。而c++风格的符号则会带上函数原型的全面信息,如属于哪个类哪个名字空间参数序列几何,这样才能够使c++在相同的函数名可以被重载,符号连接才不会冲突。所以在调试器反汇编出来的代码,往往可以提示出c++函数的原型,而c风格的函数只有名字(不能解析参数序列)。
既然调试器反汇编出了c++函数符号,就应该好好使用。但调试器并没有提示一个类的函数是静态成员函数还是成员函数,因为这两种函数在调用约定时,相差了一个参数位,所以在逆向分析时要进行分析区分。一般来说,构造和析构函数一定是成员函数,static和const修饰不同时使用,带const修饰就可以认为也是成员函数。剩下来的就只能够通过分析判断。
我的方法是将类方法同时分别去应用两种调用约定(不带this的静态成员函数调用和带this的成员函数调用),然后分别对两种情况下寄存器使用的匹配度进行比较,判断出其中的一种。不像hopper那样,将明明是c++的类方法,却当作c风格函数来简单处理。
下面是对CA::Render::key_path_set(void**, __CFString const*)调用的分析判断,判断结果是成员函数参数序列不相符,所以应当是静态成员函数。
// 64 rdi = &_30; // 68 rsi = r12; // 71 call // CA::Render::key_path_set((void**)&_30, (__CFString const*)r12); // ((CA::Render*)&_30)->key_path_set((void**)r12, (__CFString const*)rdx/*wrong*/); CA::Render::key_path_set(void**, __CFString const*); // 76 rdi = r15; // 79 call CA::Transaction::lock(); // 84 r15 = r14->_98; // 91 rbx = r14; // 94 _38 = r15; // 98 testq %r15, %r15 // 101 if (!) { // 98 (0 == r15) // 103 r13 = &_38; // 107 r12d = 0; // 110 r14 = &_30; _b114: // from 174 // 114 rsi = &r15->_10; // 118 edx = 0; // 120 rdi = r14; // 123 call // CA::Render::key_path_equal((void* const*)r14, (void* const*)&r15->_10, (bool)0); // ((CA::Render*)r14)->key_path_equal((void* const*)&r15->_10, (void* const*)rdx/*wrong*/, (bool)cl/*wrong*/); CA::Render::key_path_equal(void* const*, void* const*, bool);
再来看
if (!) { // 738 (0 == r12) // 751 rdi = r12; // 754 call ((CA::Render::Object*)r12)->unref(); _f759: // from 714 } // 759 // 759 rsi = _38; // 763 rdi = r13; // 766 call // CA::Layer::set_animations((CA::Layer::Animation*)r13); // ((CA::Layer*)r13)->set_animations((CA::Layer::Animation*)_38); CA::Layer::set_animations(CA::Layer::Animation*); // 771 edx = 0x1; // 776 rdi = r13; // 779 rsi = r14; // 782 call // CA::Layer::mark_animations((CA::Transaction*)r13, (bool)esi/*wrong*/); // ((CA::Layer*)r13)->mark_animations((CA::Transaction*)r14, (bool)0x1); CA::Layer::mark_animations(CA::Transaction*, bool); // 787 rdi = r14; // 790 call CA::Transaction::unlock();
首先是CA::Render::Object::unref() const,可以确定这是一个成员函数,所以使用成员函数调用方式。
接着是CA::Layer::set_animations(CA::Layer::Animation*), 两种方式的假设都没有找出不符,优先使用成员成员函数方式。
第三是CA::Layer::mark_animations(CA::Transaction*, bool),静态成员方式调用匹配有不符,所以可以判定是成员函数。
下面是贴上两个函数的逆向输出:
CA::Layer::update_removed_sublayer { // 0 pushq %rbp // 1 rbp = rsp; // 4 pushq %r14 // 6 pushq %rbx // 7 r14 = rsi; // 10 rbx = rdi; // 13 rbx->_8 = 0x0; // 21 rbx->_a4 = edx; // 27 edx = 0; // 29 call // CA::Layer::mark_visible((CA::Transaction*)rdi, (bool)esi); // ((CA::Layer*)rdi)->mark_visible((CA::Transaction*)rsi, (bool)0); CA::Layer::mark_visible(CA::Transaction*, bool); // 34 rdi = r14; // 37 rsi = rbx; // 40 call ((CA::Transaction*)r14)->add_root((CA::Layer*)rbx); // 45 lock // 46 OSAtomicAnd32(0xffefffff, (volatile int32_t*)&rbx->_4); // 53 rbx->_84 = rbx->_84 & 0xffffbfff; // 60 eax = rbx->_80; // 66 eax = eax << 0x3; // 69 eax = eax ^ rbx->_4; // 72 testl $0x400000, %eax // 77 if () // 72 (0x400000 & eax) goto _f84; // 79 popq %rbx // 80 popq %r14 // 82 popq %rbp // 83 ret return; _f84: // from 77 // 84 rdi = rbx; // 87 rsi = r14; // 90 popq %rbx // 91 popq %r14 // 93 popq %rbp // 94 ret return; // jmp 0x1041aa814; CA::Layer::toggle_flipped(CA::Transaction*) // 99 nop }
CA::Layer::update_removed_sublayer
相关文章推荐
- A20的板子笔记
- STL源码剖析笔记
- SpringMVC源码剖析(三)- DispatcherServlet的初始化流程
- 基础总结篇之二:Activity的四种launchMode
- 【图像处理】线性、位置不变退化图像的频域复原基础(维纳滤波,最小均方滤波,几何滤波)
- java.sql.Date和java.util.Date的区别
- 很多控件的消息处理
- mysql 定时任务创建开启修改关闭实现
- 图像拼接
- 面试:数组:二维搜索数组
- 安卓黑客工具
- WinForm DataGridView 鼠标点击选中整行
- ReactNative动画(上)
- 经典数据库语句
- vb
- ibatis动态获取执行SQL和参数
- hdu 1044 Collect More Jewels【暴力Bfs+状态压缩】
- 基础总结篇之一:Activity生命周期
- 手机朝向监测
- Principles of training multi-layer neural network using backpropagation