代码逆向(五)——switch-ca识别技巧提高

更新时间:2023-05-09 20:50:26 阅读: 评论:0

我们前面为各位读者分别介绍了转成if-esle与利用跳转表两种优化模式,但是在最后我隐含着提出了一个问题,既如果我们的switch-ca分支两个数之差大于50甚至更多的时候,那么我们此时是否仍需要利用跳转表来解决问题呢?很显然我们不能这样做,假如我们遇到如下这段代码:
int _tmain(int argc, _TCHAR* argv[])
{
    switch (argc)
    {
    ca 0:
        printf("argc=0",argc);
        break;
    ca 1:
        printf("argc=%d",argc);
        break;
    ca 6:
        printf("argc=%d",argc);
        break;
    ca 7:
        printf("argc=%d",argc);
        break;
    ca 199:                      // 注意这里!
        printf("argc=%d",argc);
        break;
    default:
        printf("nNum=%d,error!",argc);
    }
    return 0;
}
    我们通过上面这个稍显极端的例子可以发现,如果此时编译器仍以跳转表的方式来优化的话,那么会出现什么情况?这会使得编译出来的代码具有多达788字节的冗余数据,至少会使其体积变为用Debug模式生成代码体积的2.7倍以上!
    通过与编译器打这么长市间的交道,我们猜也能猜得出编译器肯定不会使用这么笨的方法,由此便引出的“稀疏矩阵”。
    “稀疏矩阵”这名字起的很好,正可谓阅名知意,通过名字我们就可以猜到这应该是一个用来表达稀疏数据的矩阵,正好可以用于我们刚刚所面对的这种情况。
    那么我们的switch-ca分支结构生么时候才会用到稀疏矩阵,而稀疏矩阵又是怎么回事呢?
    下面就由笔者一一为各位解答……
(1、)什么时候应用稀疏矩阵
    由于每个编译器所使用的策略不一样,因此其“体积-效率比”权值的设定也不尽相同,笔者在这里只能告诉大家,如果使用跳转表所生成代码的体积大于使用稀疏矩阵的体积,那么一般情况下编译器就会选择使用稀疏矩阵来优化此段代码。
(2、)什么是稀疏矩阵
    单从数学上讲,假设我们有一个m行乘以n列的二维阵列(既二维数组),那么如果此矩阵中非零值数量N小于等于m*n的话,那么我们就将这个矩阵称之为稀疏矩阵。
    当然稀疏矩阵的具体定义与其它特点还有很多,这里我们不再一一讨论,现在我们着重讲解一下编译器优化时所使用的稀疏矩阵是个什么情况。
    其实当我们深入的接触这种优化方式之后可以发现,编译器所用的优化方案仅仅是思路上借鉴了稀疏矩阵,但是其实际使用中并不符合稀疏矩阵的相关定义,因此笔者认为将其称之为“间接表”更为合适一些,现在就让我们共同看一看switch-ca分支结构的间接表是怎么回事。
    在VC系列编译器中,其针对switch-ca分支结构的间接表都是用一字节表示的,因此其最小索引值与最大索引值之差不得大于256,否则此优化方法便不再适用。
    其次,这个拥有256个byte型元素的数组(间接表)需要与跳转表相呼应最终才能保证程序流程执行到正确的地方上去。下面我就带领各位读者深入的了解一下间接表是怎样被体现出来的。
    鉴于以后知识的复杂性,从现在开始,我们将不再使用OllyDbg,因此也请各位读者跟随本文一起转变到IDA这个最专业的逆向工作平台上去(有关于IDA的使用请参考相关文章)。
    我们下面以一个例子来证明,以前面那个源码为蓝本,看看IDA生成的反汇编代码是不是更已读易懂:
.text:00401000 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00401000 _main proc near                        ; CODE XREF: __tmainCRTStartup+10Ap
.text:00401000
.text:00401000 argc= dword ptr  4
.text:00401000 argv= dword ptr  8
.text:00401000 envp= dword ptr  0Ch
.text:00401000
.text:00401000    mov eax, [esp+argc]
.text:00401004    cmp eax, 0C7h                      ; switch 200 cas
.text:00401009    ja  short loc_40107B                ; default
.text:00401009                                        ; jumptable 00401012 cas 2-5,8-198
.text:0040100B    movzx ecx, ds:byte_4010A8[eax]
.text:00401012    jmp ds:off_401090[ecx*4]            ; switch jump
.text:00401019
.text:00401019 $LN6:                                  ; DATA XREF: _main:off_401090o
.text:00401019    push 0                              ; jumptable 00401012 ca 0
.text:0040101B    push offt Format                  ; "argc=0"
.text:00401020    call ds:__imp__printf
.text:00401026    add esp, 8
.text:00401029    xor eax, eax
.text:0040102B    retn
.text:0040102C ; ---------------------------------------------------------------------------
.text:0040102C
.text:0040102C $LN5:                                  ; CODE XREF: _main+12j
.text:0040102C                                        ; DATA XREF: _main:off_401090o
.text:0040102C    push 1                              ; jumptable 00401012 ca 1
.text:0040102E    push offt aArgcD                  ; "argc=%d"
.text:00401033    call ds:__imp__printf
.text:00401039    add esp, 8
.text:0040103C    xor eax, eax
.text:0040103E    retn
.text:0040103F ; ---------------------------------------------------------------------------
.text:0040103F
.text:0040103F $LN4:                                  ; CODE XREF: _main+12j
.text:0040103F                                        ; DATA XREF: _main:off_401090o
.text:0040103F    push 6                              ; jumptable 00401012 ca 6
.text:00401041    push offt aArgcD                  ; "argc=%d"
.text:00401046    call ds:__imp__printf
.text:0040104C    add esp, 8
.text:0040104F    xor eax, eax
.text:00401051    retn
.text:00401052 ; ---------------------------------------------------------------------------
.text:00401052
.text:00401052 $LN3:                                  ; CODE XREF: _main+12j
.text:00401052                                        ; DATA XREF: _main:off_401090o
.text:00401052    push 7                              ; jumptable 00401012 ca 7
.text:00401054    push offt aArgcD                  ; "argc=%d"
.text:00401059    call ds:__imp__printf

本文发布于:2023-05-09 20:50:26,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/567118.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:矩阵   使用   优化   编译器   跳转   代码   体积
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图