zoukankan      html  css  js  c++  java
  • 脱壳2

     

    脱壳­0.upx.exe

    ① 找OEP

    ESP定律

    跟脱aspack.exe方法差不多。

    脱壳­0.exe(FSG 2.0)

    ① 找oep

    单步跟踪

    跳转到OEP代码:

    观察寄存器,看是否有在获取导入表的代码附近代表快到OEP了。

    就能找到 JMP DWORD PTR DS:[EBX+0xC]

     

     

     

    ② dump内存

    。。

    ③ 修复IAT

    FSG 2.0对内存中的IAT 进行了一些空隙填充,需要将其改为0 ,

    否则会修复不完全。

    进到oep里面,机器码为FF15或者FF25就是跟导入表有关,

     

     

    右键数据窗口跟随

     

     

    脱壳­2.exe(15PB pack)

    ① 找OEP

    单步跟踪

    跟到有个jmp到

     

    GetVersion函数特征

     

    FF15或者FF25后面跟着一般都是导入表

     

     

    对着004094AC这行右键-数据窗口跟随

    然后下硬件写入断点,当程序在往里写数据的时候就会断下,就能找到加密的地方。

     

    ② IAT加密,解密IAT

    解密IAT需要先找到加密IAT的地方,然后将其删除或是能还原。

    找加密IAT代码的方式

     

     

    ① 对IAT设置硬件写入断点

    对GetVersion所在的iat设置硬件写入断点,最终可以找到填充IAT的地方

    004385EE      8907            MOV DWORD PTR DS:[EDI],EAX                ; 填充IAT 函数地址

    修改附近代码

     

    修改前

     

    修改后

     

    dump的时候,入口应该用9486.

     

     

    修复导入表的时候大小可以弄大点。然后再把无效的剪切掉。

     

    ② 对IAT相关的API设置断点

    LoadLibraryA

    GetProcAddress

    GetModuleHandleA

    VirtualProtect

    脱壳中的一些问题

    1. 拿到程序怎么办?

    以脱壳为目的,尽可能完成脱壳

    1. 技巧的使用?

    ① API下断注意的问题

    API下断之后,第一应该观察的是堆栈,确定返回地址是我们要分析的模块

     

     

    ②注意当前分析的模块是不是主模块

     

    脱壳­4.exe(未知壳)

    ① 找OEP

    ESP定律

    ② IAT加密

    这个壳使用一些加密技术:

     

    1. IAT函数地址是不规则的

    2. 填充IAT时有混淆代码

    3. 自己实现了一个GetProcAddress

    4. 字符串使用Hash值来存储

    5. 壳代码填充IAT的代码是在申请的内存中执行

    混淆规则

    1. jmp 地址

    等价于 call 地址

    LEA ESP,DWORD PTR SS:[ESP+0x4]

    哈希算法

    edx=0, 保存计算之后的结果

    LODS BYTE PTR DS:[ESI] TEST AL,AL

    JE SHORT 002F1CCB ROL EDX,0x3

    XOR DL,AL

    手动修改填充IAT代码解密IAT

    1. 修改代码

    ① 保存API函数地址到EBX

     

    001D14DC mov dword ptr ds:[ecx+eax-0x4],edx
    改为
    001D14DC mov ecx,edx

    这里的修改为了能将函数地址保存到ecx中,经过测试ecx中的值没有什么用

    001D0EE2 mov eax,dword ptr ss:[ebp-0x58]
    改为
    001D0EE2 mov eax,ecx

    这里的修改为了将函数地址保存到eax中,因为最后填充IAT的代码使用的是eax

     

     

     

    由于上面代码是在申请出来的地址, 所以有可能是从原程序中拷贝的, 经过搜索,可以在原代码修改

    特征:FF 75 D8 E9 AD 00 00 00 C2 04 00 E9 F3 F1 FF FF 8D 64 24 04

     

    ② 将原CALL指令改为jmp,增加代码空间

     

     

    在原代码中修改

     

    ③ 在原混淆指令上,添加填充IAT代码

     

     

    在原代码中修改

     

     

     

    寻址OEP解密IAT脚本

    // 1. 定义一些必要的变量 VAR  vOldOEP
    VAR  vAllocAddr
    VAR  vWriteIATAddr
    VAR  vGetAPIAddr
    VAR  vTmp
    ​
    MOV vOldOEP,0047148B  
    MOV vAllocAddr, 0047A37F 
    MOV vGetAPIAddr,  14E0 
    MOV vWriteIATAddr,0897// 2. 对申请空间的地方下断,取出基址
    // 3. 设置其他的断点,让程序跑起来,对每一个断点进行处理
    BPHWC  // 清除硬件断点
    BC    //清除所有断点 
    BPHWS vOldOEP, "x" //当执行到此地址时产生中断. 
    BPHWS vAllocAddr, "x" //当执行到此地址时产生中断.
    ​
    LOOP1:
    ​
    RUN 
    ​
    CMP vAllocAddr,eip
    JNZ CASE1
    ADD vGetAPIAddr,  eax
    ADD vWriteIATAddr,eax 
    BPHWS vGetAPIAddr, "x" //当执行到此地址时产生中断. 
    BPHWS vWriteIATAddr, "x" //当执行到此地址时产生中断.
    ​
    JMP LOOP1
    CASE1:
    CMP vGetAPIAddr,eip JNZ CASE2
    MOV vTmp,edx
    JMP LOOP1
    ​
    CASE2:
    CMP vWriteIATAddr,eip JNZ CASE3
    MOV [edx],vTmp
    JMP LOOP1
    ​
    CASE3:
    MSG "到达OEP!"

    寻找OEP脚本

    // 1. 定义变量
    VAR dwWriteIATAddr    //  填充IAT地址的下一行地址
    VAR dwGetAPIAddr      //  获取到了API地址
    VAR dwOEP             //  原始OEP   
    VAR dwGetBaseAddr     //  申请的内存             
    VAR dwTmp             //  临时变量
    // 2. 初始化变了
    MOV dwOEP, 0047148B 
    MOV dwGetBaseAddr,0047A37F
    // 0047A37F     0BC>OR EAX,EAX                            ; eax=申请 的基地址
    MOV dwWriteIATAddr,0897 
     // 001D0895     890>MOV DWORD PTR DS:[EDX],EAX            ; 填充IAT             
     // 001D0897     E8 >CALL 001D08D5
     //00300895     890>MOV DWORD PTR DS:[EDX],EAX //00300897     E8 >CALL 003008D5
     MOV dwGetAPIAddr, 0828    
     //00300828   ^E9 >JMP 00300474    ; eax=函数地址   
     // 3. 清除所有断点    
     BPHWC 
     BPMC    
     BC
     // 4. 设置断点
     BPHWS dwGetBaseAddr, "x"     BPHWS dwOEP, "x"   
     // 5. 循环判断   
     LOOP0:
     RUN  
     CMP eip,dwGetBaseAddr 
     JNZ NEXT1 
     ADD dwWriteIATAddr,eax 
     ADD dwGetAPIAddr,eax           
     BPHWS dwWriteIATAddr, "x"   
     BPHWS dwGetAPIAddr, "x"   
     JMP LOOP0
    NEXT1:  
     CMP eip,dwGetAPIAddr             JNZ NEXT2
     MOV dwTmp,eax
     JMP LOOP0
    NEXT2:
     CMP eip,dwWriteIATAddr             JNZ NEXT3
     MOV [edx],dwTmp  JMP LOOP0
    NEXT3:
      CMP eip,dwOEP   JNZ LOOP0  
      MSG "到达OEP!"

    脚本3


    // 1. 定义变量
    MOV dwGetAPIAddr, 14DC
    MOV dwWriteIATAddr, 0895
    MOV dwOEP, 0047148B
    MOV dwGetBase,0047A37F 
    ​
    ​
    // 2. 初始化环境
    BC     // 清除软件断点
    BPHWC  // 清除硬件断点
    BPMC   // 清除内存断点
    ​
    ​
    BPHWS dwGetBase, "x" 
    BPHWS dwOEP, "x" 
    ​
    ​
    // 3. 构建循环判断
    LOOP0:
      RUN   //  相当于在OllyDbg中按 F9  
      
      CMP dwGetBase, eip
      JNZ case0   
      ADD dwGetAPIAddr, eax
      ADD dwWriteIATAddr, eax    
      BPHWS dwGetAPIAddr, "x" 
      BPHWS dwWriteIATAddr, "x" 
      JMP LOOP0
        
    case0:
      CMP dwGetAPIAddr, eip  
      JNZ case1  
      // 修改指令  
      fill dwGetAPIAddr,4,90   
      asm dwGetAPIAddr, "mov ebx, edx"
      JMP LOOP0
    ​
    case1:
      CMP dwWriteIATAddr, eip  
      JNZ  LOOP0  
      asm dwWriteIATAddr, "mov dword ptr [edx], ebx"   
      // 清除环境  
      BPHWC dwGetAPIAddr
      BPHWC dwWriteIATAddr     
      RUN

     

  • 相关阅读:
    推荐:VisualStudio 2005/2008的“Consolas”字体包
    [转]Calendar 動態產生子控制項的 Event Handler, 模拟__doPostBack() 回发
    Ajax ToolKit ModelPopupExtender应用经验二则
    [转]Calendar 控件日期复选
    ASP.NET偷懒大法六(可空类型的动态赋值)
    弹出层(Div)屏蔽父窗口并且让父窗口变暗
    CSS巧用expression来区分只读文本框
    formValidator用户注册表单自动验证
    基于Session原理的验证码方案
    jQuery解决IE6下PNG图片背景透明问题
  • 原文地址:https://www.cnblogs.com/ltyandy/p/11273679.html
Copyright © 2011-2022 走看看