吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 13446|回复: 61
上一主题 下一主题
收起左侧

[原创] 手脱花指令及IDA脚本编写

  [复制链接]
跳转到指定楼层
楼主
flatcc 发表于 2021-9-13 16:21 回帖奖励

综合许多篇帖子而成,大多参考以末尾参考文章形式给出,适用于初学者,感谢大家提出意见。可结合末尾源码参考学习。感觉有用的话感谢大佬们点个赞。

简介

作用

  • 欺骗反汇编器,让反汇编器无法正确反汇编出汇编代码,具体来说是破坏了反编译的分析,使得栈指针在反编译引擎中出现异常
  • 从而加大静态分析的难度,使得逆向分析人员难以识别代码的真正意图

原理

由于反编译器的工作原理一般是线性扫描算法或递归下降反汇编算法。

  • 线性扫描反汇编算法从程序的入口点开始反汇编,然后对整个代码进行扫描,反汇编扫描其过程中所遇到的每条指令。那么线性扫描算法的缺点也就显而易见了,由于其不定常的指令格式,在反汇编扫描过程中无法区分数据与代码,从而导致将代码段中嵌入的数据误解释为指令的操作码,以致最后得到错误的反汇编结果。
  • 递归下降算法,递归下降算法通过程序的控制流来确定反汇编的下一条指令,遇到非控制转移指令时顺序进行反汇编,而遇到控制转移指令时则从转移地址处开始进行反汇编。该算法的缺点在于难于准确确定间接转移的目的地址。

PATCH方法

先在IDA中开启字节码的显示,我这里设置显示的字节码是8。

以下图中的花指令为例,我们鼠标光标点到0x004560FF,然后按快捷键D,在下方为指令的地址0x00456100地址处,按快捷键C将其转换为指令。然后将0x004560FF处的0xE8Patch为0x90,也就是打补丁为nop指令。


然后保持副本即可。

实现案例

简单花指令-多层JMP嵌套

如下是单层的JMP形式:

jmp LABEL1
  db junk_code;
LABEL1:

甚至如下的多层嵌套:

//简单花指令-多层JMP嵌套
void example1()
{
    __asm {
        jmp LABEL1;
        _emit 68h;
    LABEL1:
        jmp LABEL2;
        _emit 0CDh;
        _emit 20h;
    LABEL2:
        jmp LABEL3;
        _emit 0E8h;
    LABEL3:
    }
    a = 99;
}

如下图,因为IDA使用的是递归下降算法进行反汇编,所以这种花指令可以被IDA轻松识别。

互补条件代替JMP跳转

类似如下形式,无论如何都会跳转到LABEL1处:

  jz LABEL1
  jnz LABEL1
  db junk_code
LABEL1:

在如下代码中,先对eax进行xor之后,再进行test比较,zf标志位肯定为1,就肯定执行jz LABEL2;,也就是说中间0xC7永远不会执行。要记得:先压栈保存eax的值,最后再把eax的值pop出来。

void example2_1()
{
    __asm {
        push eax;
        xor eax, eax;
        test eax, eax;
        jnz  LABEL1;
        jz LABEL2;
    LABEL1:
        _emit 0xC7;
    LABEL2:
        pop eax;
    }
    a = 21;
}

如下图,我们可以看到,IDA虽然识别栈帧错误,但是正确的程序流还是比较清晰的。


再如下,我们将中间填充代码改为0x21,混淆效果明显了一些,结果如下。

那么我们再来一个加强版,代码如下:

void example2_3()
{
    __asm {
        xor eax, eax;
        test eax, eax;
        je LABEL1;
        jne LABEL2;
    LABEL2 :
        _emit 0x5e;
        and eax, ebx;
        _emit 0x50;
        xor eax, ebx;
        _emit 0x74;
        add eax, edx;
    LABEL1:
    }
    a = 23;
}

call&ret构造花指令

如下案例,代码中的esp存储的就是函数返回地址,对[esp]+8,就是函数的返回地址+8,正好盖过代码中的函数指令和垃圾数据。

void example3()
{

    __asm {
        call LABEL9;
        _emit 0x83;
    LABEL9:
        add dword ptr ss : [esp], 8;
        ret;
        __emit 0xF3;
    }
    a = 3;
}

如下图所示,是上述花指令代码的效果,这里最好自己动态跟以下。

call 指令的直观理解:push 函数返回地址; jmp 立即数
ret 指令的直观理解:pop eip; add esp,4

利用函数返回确定值

有些函数返回值是确定的,比如我们自己写的函数,返回值可以是任意非零整数,就可以自己构造永恒跳转。

还有些API函数也是如此,比如在Win下HMODULE LoadLibraryA(LPCSTR lpLibFileName);函数,如果
我们故意传入一个不存在的模块名称,那么他就会返回一个确定的值NULL,此时就可以通过这个函数来构造永恒跳转。如下例子:

void example4_1()
{

    LoadLibrary(L"./hhhh");//函数返回值存储于eax中
    __asm{
        cmp eax, 0;
        jc LABEL6_1;
        jnc LABEL6_2;
    LABEL6_1:
        _emit 0xE8;
    LABEL6_2:
    }
    a = 41;
}

混淆效果如下:

call和ret的组合

如下代码:

void __declspec(naked)__cdecl example5(int* a)//裸函数,开辟和释放堆栈由我们自己写。
{//55 8b ec 83
    __asm
    {
        push ebp
        mov ebp, esp
        sub esp, 0x40
        push ebx
        push esi
        push edi
        mov eax, 0xCCCCCCCC
        mov ecx, 0x10
        lea edi, dword ptr ds : [ebp - 0x40]
        rep stos dword ptr es : [edi]
    }

    *a = 5;
    __asm
    {
         call LABEL9;
         _emit 0xE8;
         _emit 0x01;
         _emit 0x00;
         _emit 0x00;
         _emit 0x00;

     LABEL9:
         push eax;
         push ebx;
         lea  eax, dword ptr ds : [ebp - 0x0]; //将ebp的地址存放于eax
         add dword ptr ss : [eax - 0x50], 26;  //该地址存放的值正好是函数返回值,
                                              //不过该地址并不固定,根据调试所得。加26正好可以跳到下面的mov指令,该值也是调试计算所得
         pop eax;
         pop ebx;
         pop eax;
         jmp eax;
         __emit 0xE8;
         _emit 0x03;
         _emit 0x00;
         _emit 0x00;
         _emit 0x00;
         mov eax, dword ptr ss : [esp - 8];  //将原本的eax值返回eax寄存器

    }

    __asm
    {
        pop edi
        pop esi
        pop ebx
        mov esp, ebp
        pop ebp
        ret
    }
}

也就是说思路有很多种,按照自己喜欢的方式组合,只要不影响其他正常代码的运行就可以,如下也是比较好的两种思路

call嵌套的其他思路1
    call LABEL1
    db 0E8h
LABEL2:
    jmp LABEL3
    db 0
    db 0
    db 0E8h
    db 0F6h
    db 0FFh
    db OFFh
    db OFFh
LABEL1: 
    :call LABEL2
LABEL3:
    add esp,8
call嵌套的其他思路2
    push eax
    call LABEL1
    db 29h
    db 5Ah
LABEL1:
    POP eax
    imul eax,3
    call LABEL2
    db 29h
    db5Ah
LABEL2:
    add esp,4
    pop eax

花指令原理另类利用

当我们理解了花指令的原理后,我们可以在将花指令中的垃圾数据替换为一些特定的特征码,可以对应的$“定位功能”$,尤其在SMC自解码这个反调试技术中可以运用。例如:

asm
{
  Jz Label
  Jnz Label
  _emit 'h'
  _emit 'E'
  _emit 'l'
  _emit 'L'
  _emit 'e'
  _emit 'w'
  _emit 'o'
  _emit 'R'
  _emit 'l'
  _emit 'D'
Label:
}

将这串特征码hElLowoRlD嵌入到代码中,那我们只需要在当前进程中搜索hElLowoRlD字符串,就可以定位到当前代码位置,然后对下面的代码进行SMC自解密。

小结

构造永恒跳转,添加垃圾数据

综合题目案例

IDC脚本去花

我们以题目[MSLRH].exe为例子,分析一段花指令,使用IDA中的快捷键DC来手动过花指令。手动分析清楚其流程后,我们可以写一个脚本,来批量匹配花指令的模式NOP掉影响静态分析的代码。

写好的IDC脚本如下:

//文件名:test.idc
#include <idc.idc>
static main() 
{
    auto x,FBin,ProcRange;
    FBin = "E8 0A 00 00 00 E8 EB 0C 00 00 E8 F6 FF FF FF";
    //目标 = "E8 0A tel:00 00 00 90 EB 0C tel:90 90 90 90 90 90 90";
    //花指令1的特征码
    for (x = FindBinary(MinEA(),0x03,FBin);x != BADADDR;x = FindBinary(x,0x03,FBin))
    {
            x=x+5; //返回的x是第一个E8的地址,
                  //加上5是第二个E8的地址
            PatchByte (x,0x90);//nop掉
            x = x + 3; //00
            PatchByte (x,0x90);
            x++;  //00 E8
            PatchWord (x,0x9090);
            x =x + 2 ; //F6 FF FF FF
            PatchDword(x,0x90909090);
    }
}

使用IDAPython去花

import idautils
import idc

def my_nop(addr, endaddr):
    while addr < endaddr:
        patch_byte(addr, 0x90)
        addr += 1

pattern = "E8 0A 00 00 00 E8 EB 0C 00 00 E8 F6 FF FF FF"
cur_addr = 0x456000
end_addr = 0x467894

while cur_addr<end_addr:
    cur_addr = idc.find_binary(cur_addr,SEARCH_DOWN,pattern)
    print("patch address: " + str(cur_addr)) # 打印提示信息
    if cur_addr == idc.BADADDR:
        break
    else:
        my_nop(cur_addr+5,cur_addr+6)
        my_nop(cur_addr+8,cur_addr+14)
    cur_addr = idc.next_head(cur_addr)

附带源码:
JunkCode.7z (5.11 KB, 下载次数: 93)

参考

免费评分

参与人数 33吾爱币 +34 热心值 +31 收起 理由
Y1rannn + 1 谢谢@Thanks!
m1n9yu3 + 1 + 1 用心讨论,共获提升!
WangFuGui + 1 谢谢@Thanks!
feng198686cs + 1 + 1 学习了
crazycannon + 1 + 1 谢谢@Thanks!
victos + 1 + 1 谢谢@Thanks!
DancingLight + 1 + 1 热心回复!
rQOkhE + 1 谢谢@Thanks!
zhenkaixin852 + 1 + 1 谢谢@Thanks!
cvil666 + 1 + 1 我很赞同!
azcolf + 1 + 1 热心回复!
叶灬凌风 + 1 + 1 热心回复!
chenjingyes + 1 + 1 谢谢@Thanks!
光之优雅 + 1 + 1 我很赞同!
Lugia + 1 + 1 谢谢@Thanks!
gaosld + 1 + 1 用心讨论,共获提升!
Stoneone + 1 + 1 谢谢@Thanks!
fengbolee + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xmmyzht + 1 + 1 谢谢@Thanks!
努力加载中 + 1 + 1 热心回复!
longestusername + 2 + 1 谢谢@Thanks!
nevinhappy + 1 + 1 用心讨论,共获提升!
timeni + 1 + 1 我很赞同!
dsanke + 1 + 1 用心讨论,共获提升!
笙若 + 1 + 1 谢谢@Thanks!
杨辣子 + 1 + 1 谢谢@Thanks!
WHOAMI2 + 1 + 1 用心讨论,共获提升!
wws天池 + 1 + 1 热心回复!
wdraemv + 1 + 1 谢谢@Thanks!
Ravey + 1 + 1 谢谢@Thanks!
鹤舞九月天 + 1 + 1 用心讨论,共获提升!
mqlv + 1 + 1 用心讨论,共获提升!
xouou + 1 + 1 666

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
heartingrass 发表于 2022-9-19 13:53
本帖最后由 heartingrass 于 2022-9-19 15:24 编辑
flatcc 发表于 2022-9-16 17:49
我想想啊,有遇到实例嘛,可以探讨下
楼主可以试一试,感觉这个长跳转就无法进行模式匹配了,需要消除长跳转,然后拼接代码,可能要利用到一些功能模块,另外完全借助IDA分析,也存在指令识别错误或未识别的情况。


dump2.exe:第二段代码是32bit,里面有大量花指令,需要进行清除之后,才方便进行程序逻辑分析。花指令的特征主要有如下几处:
一、连续的指令
1、ebp、esp还原【是后面的特例】
[Plain Text] 纯文本查看 复制代码
seg000:000CC824 014 55                         push    ebp
seg000:000CC825 018 89 E5                       mov     ebp, esp
seg000:000CC827 018 8D 64 24 FC                    lea     esp, [esp-4]
seg000:000CC82B 01C 89 EC                       mov     esp, ebp
seg000:000CC82D 01C 5D                         pop     ebp


2、esp还原【是后面的特例】
[Plain Text] 纯文本查看 复制代码
seg000:000C5FBA 01C 52                            push    edx
seg000:000C5FBB 020 8D 64 24 04                   lea     esp, [esp+4]

3、无用指令【待核实,只有一处】
[Plain Text] 纯文本查看 复制代码
seg000:0021C40D 84 56 C7                                test    [esi-39h], dl
seg000:0021C410 08 00                                   or      [eax], al

二、存有大量跳转指令
1、ebp、esp还原【中间嵌入长跳转】
[Plain Text] 纯文本查看 复制代码
seg000:000CC824 014 55                            push    ebp
seg000:000CC825 018 89 E5                         mov     ebp, esp
seg000:000CC827 018 8D 64 24 FC                   lea     esp, [esp-4]
seg000:000CC82B 01C 89 EC                         mov     esp, ebp
seg000:000CC82D 01C 5D                            pop     ebp


2、esp还原【中间嵌入长跳转】
[Plain Text] 纯文本查看 复制代码
seg000:000C5FBA 01C 52                            push    edx
seg000:000C5FBB 020 8D 64 24 04                   lea     esp, [esp+4]


3、pushf、popf还原【中间嵌入长跳转
[Plain Text] 纯文本查看 复制代码
seg000:002A0496                               loc_2A0496:                             ; CODE XREF: seg000:00000001↑j
seg000:002A0496 9C                                            pushf
seg000:002A0497 51                                            push    ecx
seg000:002A0498 50                                            push    eax
seg000:002A0499 31 C0                                         xor     eax, eax
seg000:002A049B
seg000:002A049B                               loc_2A049B:                             ; CODE XREF: seg000:002A04B3↓j
seg000:002A049B 83 F8 03                                      cmp     eax, 3
seg000:002A049E 74 15                                         jz      short loc_2A04B5
seg000:002A04A0 40                                            inc     eax
seg000:002A04A1 81 E9 2E CD 9B A2                             sub     ecx, 0A29BCD2Eh
seg000:002A04A7 81 C9 07 48 0C 20                             or      ecx, 200C4807h
seg000:002A04AD 81 D9 2B 22 BB B1                             sbb     ecx, 0B1BB222Bh
seg000:002A04B3 72 E6                                         jb      short loc_2A049B
seg000:002A04B5
seg000:002A04B5                               loc_2A04B5:                             ; CODE XREF: seg000:002A049E↑j
seg000:002A04B5 58                                            pop     eax
seg000:002A04B6 59                                            pop     ecx
seg000:002A04B7 9D                                            popf

4、pushf、popf还原【中间嵌入长跳转、还嵌套自身
[Plain Text] 纯文本查看 复制代码
seg000:002AE278 9C                                            pushf
seg000:002AE279 E9 5E 37 FB FF                                jmp     loc_2619DC
seg000:002619DC                               loc_2619DC:                             ; CODE XREF: seg000:002AE279↓j
seg000:002619DC 52                                            push    edx
seg000:002619DD 51                                            push    ecx
seg000:002619DE 9C                                            pushf 【此处 嵌套了自身】
seg000:002619DF 50                                            push    eax
seg000:002619E0 52                                            push    edx
seg000:002619E1 31 D2                                         xor     edx, edx
seg000:002619E3
seg000:002619E3                               loc_2619E3:                             ; CODE XREF: seg000:002619F8↓j
seg000:002619E3 83 FA 0A                                      cmp     edx, 0Ah
seg000:002619E6 74 12                                         jz      short loc_2619FA
seg000:002619E8 42                                            inc     edx
seg000:002619E9 05 3F 86 3A 6F                                add     eax, 6F3A863Fh
seg000:002619EE 0D 99 24 DF 25                                or      eax, 25DF2499h
seg000:002619F3 05 D0 BA 30 4B                                add     eax, 4B30BAD0h
seg000:002619F8 7E E9                                         jle     short loc_2619E3
seg000:002619FA
seg000:002619FA                               loc_2619FA:                             ; CODE XREF: seg000:002619E6↑j
seg000:002619FA 5A                                            pop     edx
seg000:002619FB 58                                            pop     eax
seg000:002619FC 9D                                            popf
seg000:002619FD E9 B6 62 EC FF                                jmp     loc_127CB8
seg000:00127CB8                               loc_127CB8:                             ; CODE XREF: seg000:002619FD↓j
seg000:00127CB8 31 C9                                         xor     ecx, ecx
seg000:00127CBA
seg000:00127CBA                               loc_127CBA:                             ; CODE XREF: seg000:000FAD33↑j
seg000:00127CBA 83 F9 06                                      cmp     ecx, 6
seg000:00127CBD 55                                            push    ebp
seg000:00127CBE 89 E5                                         mov     ebp, esp
seg000:00127CC0 8D 64 24 FC                                   lea     esp, [esp-4]
seg000:00127CC4 89 EC                                         mov     esp, ebp
seg000:00127CC6 5D                                            pop     ebp
seg000:00127CC7 E9 E0 48 F4 FF                                jmp     loc_6C5AC
seg000:0006C5AC                               loc_6C5AC:                              ; CODE XREF: seg000:00127CC7↓j
seg000:0006C5AC 0F 84 15 0A FF FF                             jz      loc_5CFC7
seg000:0006C5B2 41                                            inc     ecx
seg000:0006C5B3 E9 78 7B 1B 00                                jmp     loc_224130
seg000:00224130                               loc_224130:                             ; CODE XREF: seg000:0006C5B3↑j
seg000:00224130 81 FA 6B 15 C8 6D                             cmp     edx, 6DC8156Bh
seg000:00224136 81 E2 38 42 C7 AF                             and     edx, 0AFC74238h
seg000:0022413C E9 EC 6B ED FF                                jmp     loc_FAD2D
seg000:000FAD2D                               loc_FAD2D:                              ; CODE XREF: seg000:0022413C↓j
seg000:000FAD2D 81 DA FA A1 7F 86                             sbb     edx, 867FA1FAh
seg000:000FAD33 0F 80 81 CF 02 00                             jo      loc_127CBA
seg000:000FAD39 E9 89 22 F6 FF                                jmp     loc_5CFC7
seg000:0005CFC7                               loc_5CFC7:                              ; CODE XREF: seg000:loc_6C5AC↓j
seg000:0005CFC7                                                                       ; seg000:000FAD39↓j
seg000:0005CFC7 59                                            pop     ecx
seg000:0005CFC8 5A                                            pop     edx
seg000:0005CFC9 E9 54 CF 1E 00                                jmp     loc_249F22
seg000:00249F22                               loc_249F22:                             ; CODE XREF: seg000:0005CFC9↑j
seg000:00249F22 9D                                            popf
seg000:00249F23 8D 64 24 04                                   lea     esp, [esp+4]
seg000:00249F27 E9 4B AA E9 FF                                jmp     loc_E4977
seg000:000E4977                               loc_E4977:                              ; CODE XREF: seg000:00249F27↓j
seg000:000E4977 E9 C5 2E 1A 00                                jmp     loc_287841
seg000:00287841                               loc_287841:                             ; CODE XREF: seg000:loc_E4977↑j
seg000:00287841 9D                                            popf

这两个花指令的简略特征是:
[Plain Text] 纯文本查看 复制代码
9C                            pushf
52                            push    edx
51                            push    ecx
31 C9                         xor     ecx, ecx
83 F9 08                      cmp     ecx, 8            【JZ 后续代码 的最后一个有条件跳转会 跳转到此处】
0F 84 A2 17 E4 FF             jz      loc_E9020
59                            pop     ecx
5A                            pop     edx
9D                            popf

【JZ】后续代码特征1:
[Plain Text] 纯文本查看 复制代码
47                            inc     edi
81 EA 4A 0A 6A C8             sub     edx, 0C86A0A4Ah
81 F2 F7 12 2D EE             xor     edx, 0EE2D12F7h
81 EA C6 07 02 1C             sub     edx, 1C0207C6h
0F 89 FB E3 13 00             jns     loc_1D2296

特征2:
[Plain Text] 纯文本查看 复制代码
43                            inc     ebx
1D F3 63 58 CC                sbb     eax, 0CC5863F3h
25 DC C9 C5 7F                and     eax, 7FC5C9DCh
05 C8 9D D9 2E                add     eax, 2ED99DC8h
0F 8D FB 01 FA FF             jge     loc_1A7C7E



特征3:
[Plain Text] 纯文本查看 复制代码
41                            inc     ecx
3D 7C AA 0E E6                cmp     eax, 0E60EAA7Ch
35 93 5A FA 84                xor     eax, 84FA5A93h
1D 64 15 D9 23                sbb     eax, 23D91564h
0F 88 B0 7F EA FF             js      loc_158A72

特征4:
[Plain Text] 纯文本查看 复制代码
41                            inc     ecx
81 D2 B7 D6 07 45             adc     edx, 4507D6B7h
81 CA 5A 03 73 78             or      edx, 7873035Ah
81 C2 10 EA 7D 71             add     edx, 717DEA10h
0F 88 E1 61 03 00             js      loc_1CC00A

特征5:
[Plain Text] 纯文本查看 复制代码
41                            inc     ecx
15 CB 30 92 03                adc     eax, 39230CBh
25 86 2C C9 70                and     eax, 70C92C86h
15 17 1C 96 C5                adc     eax, 0C5961C17h
0F 86 FE 34 11 00             jbe     loc_2077A4

附件是:x32程序片段,不可执行,里面是一大堆的花指令。

dump2.rar

1.92 MB, 下载次数: 4, 下载积分: 吾爱币 -1 CB

程序片段

沙发
njzyjyyd 发表于 2021-9-13 18:31
3#
guangzisam 发表于 2021-9-13 19:43
4#
白云点缀的蓝 发表于 2021-9-14 12:32
vmp的代码能还原不
5#
mic2zac 发表于 2021-9-14 17:36
知识盲区了
6#
submariner 发表于 2021-9-14 18:23
好复杂,看着头晕
7#
fyh505099 发表于 2021-9-14 23:10
学习学习,谢谢分享
8#
残风逝雪夜阑天 发表于 2021-9-14 23:28
感谢分享
9#
zhhispig 发表于 2021-9-14 23:44
除了案例都看懂了 感谢分享
10#
gba626 发表于 2021-9-15 04:32
学习了 感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-14 10:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表