arm架构中干扰ida静态分析的一些方法

破坏堆栈

ida会在分析一个函数的时候会计算堆栈指针的变化,如果不平衡就无法进行F5。

滥用ret

ida在分析函数时,如果碰到ret指令就认为当前函数分析结束。通过内联汇编利用arm64的ret指令可以干扰ida的F5。

__asm__ volatile( 
    "adr x30,0x0 \n\t" 
    "add x30,x30,0xc \n\t" 
    "ret \n\t" 
    );

F5并不会分析此内联汇编后面的代码,目标函数在起始位置使用此内联汇编后F5什么也没分析。

间接跳转

ida使用的递归下降的反汇编引擎,此类反汇编引擎最大的缺点就是无法分析间接跳转。通过在程序中穿插间接跳转的内联汇编可以干扰ida的F5分析

// arm32
__asm__ volatile( 
    "mov r0,pc \n\t" 
    "add r0,0x10 \n\t" 
    "push {r0} \n\t" 
    "pop {r0} \n\t" 
    "bx r0 \n\t"
    "mov r1,r0 \n\t"
    );

// arm64
__asm__ volatile( 
    "adr x30,0x0 \n\t" 
    "add x30,x30,0xc \n\t" 
    "br x30 \n\t" 
    );

目标函数使用间接跳转后,F5会产生JUMPOUT伪代码调转到后续指令,无法直接将整个函数分析出来。

穿插thumb和arm

ida无法同时识别thumb和arm两种指令模式,可以在arm程序中穿插thumb汇编来干扰ida分析。

__asm__ volatile( 
    "mov r0,pc \n\t" 
    "adds r0,0xd \n\t"
    "push {r0} \n\t" 
    "pop {r0} \n\t" 
    "bx r0 \n\t"

    //thumb指令
    ".byte 0x00 \n\t" \
    ".byte 0xBF \n\t" \
    \
    ".byte 0x78 \n\t" \
    ".byte 0x46 \n\t" \
    \
    ".byte 0x02 \n\t" \
    ".byte 0x30 \n\t" \
    \
    ".byte 0x00 \n\t" \
    ".byte 0x47 \n\t" \
    :::"r0" \
    );
    //nop
    //mov r0,pc
    //adds r0,2
    //bx r0

7.5版本的ida无法分析thumb指令以及其后面的指令,7.7版本的ida进行了优化可以分析thumb指令后的指令。二者f5都无法完整的分析此函数。

虚假控制流增加垃圾指令

通过ollvm的虚假控制流,在虚假块中添加垃圾指令,这些垃圾指令是无意义的并且永远不会被运行。ida无法分析这些垃圾指令,从而无法进行F5。例如编写虚假控制流pass时在所有虚假块中增加垃圾指令:__asm__(nop\n\t.byte 0xff\n\t.byte 0xf1)

void insert_unless_instruct(llvm::BasicBlock &BB) {
    LLVMContext& context = BB.getContext();
    BasicBlock::iterator IP = BB.getFirstInsertionPt();
    IRBuilder<> builder(&(*IP));
    builder.SetInsertPoint(&BB, ++builder.GetInsertPoint());
    StringRef asmString = "nop\n\t.byte 0xff\n\t.byte 0xf1\n\t";
    StringRef constraints = "~{dirflag},~{fpsr},~{flags}";
      
    InlineAsm *IA = llvm::InlineAsm::get(
      FunctionType::get(
        Type::getVoidTy(context), false),
        asmString, 
        constraints, 
        true,
        false, 
        InlineAsm::AD_ATT);
    
    ArrayRef<Value *> Args = None;
    llvm::CallInst *Ptr = builder.CreateCall(IA,Args);
    Ptr->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
}

查看pass处理过的IR流程图,所有的虚假块都被加上了垃圾指令。

ida无法分析虚假块中垃圾指令位置的汇编,流程图和F5都无法工作。

参考链接:https://github.com/AppleReer/Anti-Disassembly-On-Arm64
以上谨代表个人观点,仅供参考!

posted @ 2023-03-02 03:15  怎么可以吃突突  阅读(740)  评论(0编辑  收藏  举报