ITA中API地址混淆实质——20171209

2021-04-22 20:28

阅读:324

标签:使用   not   一起   崩溃   scroll   结构   nop   混淆代码   vsx   

1. ITA中API地址混淆是做什么?
     ITA中存放着API地址,调用API时,则是取ITA表中的地址,然后再call,如假设EAX为ITA首地址,那么调用其中第一个API方式为call DWORD PTR [EAX]。ITA中API地址混淆则是将原来ITA表中内容去除,将IAT表中的API地址,转到一个新的入口,经过一些算法处理,并添加一些混淆无用指令,但最后总是能获得真正的API地址,然后调用,如源代码中的调用API指令call DWORD PTR [EAX]改成call 00201234,从00201234地址又有很多的call和jmp等跳转指令,最后会得到真正API地址,并实现跳转。不管中间它如何跳,最后总是以push API地址和retn mem结尾。
 
2. ITA中API地址混淆有什么作用?
     ITA中API地址混淆是一种对抗逆向分析员逆向的对抗方法,试想call一个地址,进去后都是混乱的代码,对于不知道是ITA混淆的程序员来说是会崩溃的,自然容易放弃,对于一个有经验的程序员,他会知道遇到call、jmp等指令就跳,到最后push 和retn才能获得真正的API地址,但也大大加强了工作量。ITA中API地址混淆一般在病毒和木马中会用的比较多。
 
3. ITA中API地址混淆原理是什么?
    从一个新的地址进去,然后call、jmp十几回之后,就会到一段含有push 和retn 指令的代码处,这就是混淆的终点。前边的call和jmp都只是实现跳转的,注意这里的call进去后,大多是没有ret的,所以只会push call后边的地址,但并不能真正跳回来,所以在这里下单步步过F8,往往就会跑飞了,因为F8是在call后边的地址下单步断点,但不会断下来,所以在对抗混淆代码中,使用F7会更保险一些。稍微难理解的是最后的push APIAddr和retn Mem指令为什么就能调到API并且返回到原来最初的入口地址处,如以下一段最后出口代码:
10030312   FF7424 58        PUSH DWORD PTR SS:[ESP+58] 
10030316   C2 5C00          RETN 5C
    先回顾一下在正常的一个__stdcall函数中入栈和出栈整个栈结构:
//C代码
int __stdcall test(int m, int n){return 0;}
int main()
{int nRet = test(1, 3);}
    相应的调用test函数汇编代码会是如下:
;调用call时指令
push 3
push 1
call test ;该指令push retAddr
                    jmp test

;test函数中出栈指令
retn 8 ;该指令pop retAddr
                  add esp, 8  
                  jmp retAddr
    再看混淆过的代码:
call AddrConfuse
……
10030312   FF7424 58        PUSH DWORD PTR SS:[ESP+58] 
10030316   C2 5C00          RETN 5C
;最后的RETN 5C pop DWORD PTR SS:[ESP+58]
                  add esp, 5C   ;这一加将混淆中所有的push的东西去掉,到AddrConfuse的参数处
                  jmp DWORD PTR SS:[ESP+58]
;到了API的汇编实现代码处,还会有retn指令,这一指令就正好处理AddrConfuse的参数,并最后跳会原地址处
    所以通过以上代码中注释分析,最后的push和retn指令就必然是最后混淆代码的出口了,并且能够会到原来的地址处。
 
4. ITA中API地址混淆如何写及如何反混淆
    本人经过对一些混淆代码的复制分析及对比,同一个API混淆的中途跳转可以是随机的,这点可以通过对API地址多给几套混淆方案,然后随机选择便实现随机,当然也能是固定的,但最后的push的API地址一定是相同的,只是因为中间的处理不同,所以retn mem中立即数mem是不同的额,因为中间push的方式和数量都不同。在所有的跳转段中真正计算API地址的代码指令就三四行,其它的都是做混淆用的,必须要做到的是retn mem中mem的大小一定是中途push 的字节数的总大小,不然最后真正API无法运行。
    反混淆的方法可以是(1)按以上方法手动F7一直运行,直到最后push 和retn 便获得API地址,这时常见的方法,(2)写个反混淆的工具,给OD写插件,使用相应插件时,提示输入call地址,然后写一个函数,将混淆的代码清除,留下算真正API的指令代码。具体的代码实现可以使用反汇编引擎,每3行反汇编代码一获取,判断call、jmp,则跳至对应的地址处,去那边的代码,并反汇编成汇编代码,如此将所有的代码跳转整合到一处,判断最后push 中值是来自哪个寄存器,然后溯源,最初始的会是给寄存器赋一常量值。最后将清理掉混淆代码后的处理API代码,整合一起写到最后的push retn前面,将初始入口的call指令改到新的整合的代码地址处,当然最后retn后的立即数就可以去掉了。
 
5.ITA中同一API地址两种混淆代码
(1)1000AEED  E8 E9EA0100      CALL bmjewm.100299DB  混淆方案1
1)
100299DB  0F88 B6480000    JS bmjewm.1002E297
100299E1  68 8E5124FB      PUSH FB24518E
100299E6  60              PUSHAD
100299E7  90              NOP
100299E8  E9 95CB0000      JMP bmjewm.10036582  ;
 
2)
10036582  60              PUSHAD
10036583  877C24 40        XCHG DWORD PTR SS:[ESP+40],EDI
10036587  8D3C8D 993F81FF  LEA EDI,DWORD PTR DS:[ECX*4+FF813F99]
1003658E  0FCF            BSWAP EDI
10036590  8B7C24 44        MOV EDI,DWORD PTR SS:[ESP+44]
10036594  54              PUSH ESP
10036595  C64424 04 77    MOV BYTE PTR SS:[ESP+4],77
1003659A  E8 6BBBFFFF      CALL bmjewm.1003210A            ;
 
3)
1003210A  E8 98080100      CALL bmjewm.100429A7  ;
 
4)
100429A7  8DBF 01000000    LEA EDI,DWORD PTR DS:[EDI+1]
100429AD  ^E9 2CE9FFFF      JMP bmjewm.100412DE    ;
 
5)
100412DE  C64424 18 44    MOV BYTE PTR SS:[ESP+18],44
100412E3  57              PUSH EDI
100412E4  8D6424 50        LEA ESP,DWORD PTR SS:[ESP+50]
100412E8  ^0F85 A51DFFFF    JNZ bmjewm.10033093          ;
 
610033093  60              PUSHAD
10033094  885C24 0C        MOV BYTE PTR SS:[ESP+C],BL
10033098  FF3424          PUSH DWORD PTR SS:[ESP]
1003309B  60              PUSHAD
1003309C  897C24 48        MOV DWORD PTR SS:[ESP+48],EDI
100330A0  FF7424 04        PUSH DWORD PTR SS:[ESP+4]
100330A4  BF 07610110      MOV EDI,bmjewm.10016107
100330A9  56              PUSH ESI
100330AA  ^E9 3883FFFF      JMP bmjewm.1002B3E7          ;
 
7)
1002B3E7  9C              PUSHFD
1002B3E8  8BBF A8DE0100    MOV EDI,DWORD PTR DS:[EDI+1DEA8]
1002B3EE  E8 FFEFFFFF      CALL bmjewm.1002A3F2          ;
 
8)
1002A3F2  66:C70424 0DAB  MOV WORD PTR SS:[ESP],0AB0D
1002A3F8  E8 547E0000      CALL bmjewm.10032251    ;
 
910032251  C64424 04 18    MOV BYTE PTR SS:[ESP+4],18
10032256  8DBF DBDFD276    LEA EDI,DWORD PTR DS:[EDI+76D2DFDB]
1003225C  ^E9 A5E0FFFF      JMP bmjewm.10030306      ;
 
1010030306  877C24 58        XCHG DWORD PTR SS:[ESP+58],EDI              ; kernel32.GetModuleFileNameA
1003030A  887C24 04        MOV BYTE PTR SS:[ESP+4],BH
1003030E  C60424 52        MOV BYTE PTR SS:[ESP],52
10030312  FF7424 58        PUSH DWORD PTR SS:[ESP+58]
10030316  C2 5C00          RETN 5C
(2)1000AEED  E8 E9EA0100      CALL bmjewm.100299DB 混淆方案2
1)
1000AEED  E8 E9EA0100      CALL bmjewm.100299DB
 
2)
100299DB  0F88 B6480000    JS bmjewm.1002E297 //sf = 1
100299E1  68 8E5124FB      PUSH FB24518E
100299E6  60              PUSHAD
100299E7  90              NOP
100299E8  E9 95CB0000      JMP bmjewm.10036582
 
3)
1002E297  60              PUSHAD
1002E298  66:891424        MOV WORD PTR SS:[ESP],DX
1002E29C  90              NOP
1002E29D  881C24          MOV BYTE PTR SS:[ESP],BL
1002E2A0  897C24 1C        MOV DWORD PTR SS:[ESP+1C],EDI
1002E2A4  F7D7            NOT EDI
1002E2A6  60              PUSHAD
1002E2A7  C74424 08 350E28>MOV DWORD PTR SS:[ESP+8],C5280E35
1002E2AF  8B7C24 40        MOV EDI,DWORD PTR SS:[ESP+40]
1002E2B3  E8 FFBDFFFF      CALL bmjewm.1002A0B7
 
4)
1002A0B7  68 E1299C26      PUSH 269C29E1
1002A0BC  C64424 04 82    MOV BYTE PTR SS:[ESP+4],82
1002A0C1  8DBF 01000000    LEA EDI,DWORD PTR DS:[EDI+1]
1002A0C7  9C              PUSHFD
1002A0C8  C60424 06        MOV BYTE PTR SS:[ESP],6
1002A0CC  897C24 4C        MOV DWORD PTR SS:[ESP+4C],EDI
1002A0D0  5F              POP EDI
1002A0D1  66:0FBEFA        MOVSX DI,DL
1002A0D5  E8 19400000      CALL bmjewm.1002E0F3
 
5)
1002E0F3  68 31C040AC      PUSH AC40C031
1002E0F8  BF 07610110      MOV EDI,bmjewm.10016107
1002E0FD  E9 B77B0100      JMP bmjewm.10045CB9
 
6)
10045CB9  ^E9 0FE2FEFF      JMP bmjewm.10033ECD
 
7)
10033ECD  8BBF A8DE0100    MOV EDI,DWORD PTR DS:[EDI+1DEA8]
10033ED3  887C24 04        MOV BYTE PTR SS:[ESP+4],BH
10033ED7  E9 56B80000      JMP bmjewm.1003F732
 
8)
1003F732  E8 0C000000      CALL bmjewm.1003F743
 
9)
1003F743  C60424 3F        MOV BYTE PTR SS:[ESP],3F
1003F747  8DBF DBDFD276    LEA EDI,DWORD PTR DS:[EDI+76D2DFDB]
1003F74D  E8 3037FFFF      CALL bmjewm.10032E82
 
10)
10032E82  E9 B9730100      JMP bmjewm.1004A240
 
11)
1004A240  C60424 8E        MOV BYTE PTR SS:[ESP],8E
1004A244  C64424 04 26    MOV BYTE PTR SS:[ESP+4],26
1004A249  877C24 54        XCHG DWORD PTR SS:[ESP+54],EDI
1004A24D  883C24          MOV BYTE PTR SS:[ESP],BH
1004A250  C60424 50        MOV BYTE PTR SS:[ESP],50
1004A254  FF7424 54        PUSH DWORD PTR SS:[ESP+54]
1004A258  C2 5800          RETN 58

 

ITA中API地址混淆实质——20171209

标签:使用   not   一起   崩溃   scroll   结构   nop   混淆代码   vsx   

原文地址:http://www.cnblogs.com/DennyChen/p/8011320.html


评论


亲,登录后才可以留言!