【逆向】IDA使用技巧

IDA编译头文件

打开菜单中Options ->Compiler…
在这里插入图片描述
按 Ctrl+F9 载入头文件(例如jni.h)

IDA拍摄快照

拍摄快照:快捷键Ctrl + Shift + W
管理快照:快捷键Ctrl + Shift + T

IDA创建结构体

参考:https://thinkycx.me/2019-07-15-how-to-create-structs-in-IDA.html

方式1:通过Structures Subview手动创建

(感觉不是很方便,还是编译头文件更好用)
选择Structures选项卡
按Insert新建结构体(对ROG而言是Fn+Delete)
在这里插入图片描述
第一个复选框:决定新结构体在结构体窗口中的显示位置
第二个复选框:是否在窗口中显示新结构体
第三个复选框:是否创建联合体

创建完成后:
在这里插入图片描述

方式2:通过头文件

在这里插入图片描述

IDA还原结构体

参考:https://blog.seeflower.dev/archives/173/

IDA中,32位的指针类型是int*,64位的指针类型是__int64*
__int64如果看着不太顺眼,可以使用int64_t来代替。IDA中没法直接找到int64_t这个类型,但是如果使用了这个写法IDA会自动关联

示例:

struct nameserver {
    int socket;
    int64_t *connection;
    _BYTE address[128];
    socklen_t addrlen;
    int failed_times;
    int timedout;
    _BYTE event[200];
};

IDA修改函数声明

右键函数名 → Set item type

IDA修改函数调用处的函数定义

右键函数名 → Set call type

IDA修改函数参数类型

右键参数 → Set Ivar type
在这里插入图片描述

IDA 处理伪代码JUMPOUT指令

函数被IDA错误合并

IDA分析so时,可能会遇到反编译结果不准确的情况,如下:
在这里插入图片描述
这里的两个JUMPOUT其实解析有问题,如下:
在这里插入图片描述
例如loc_18B27B0被解析成了HEN_WriteBlock函数的一个分支中的代码:
在这里插入图片描述
Tab查看结果如下:
在这里插入图片描述在这里插入图片描述
但是其实loc_18B27B0处是一个独立的函数。

函数重新识别

Undefine HEN_WriteBlock函数(找到HEN_WriteBlock函数的函数名,按U)
在这里插入图片描述
然后再回到HEN_ReadBlock函数,进而找到loc_18B27B0:
在这里插入图片描述
在loc_18B27B0处create function(右键→Create Function,或者按p):
在这里插入图片描述
回到HEN_ReadBlock
在这里插入图片描述
按F5,发现loc_18B27B0处的函数已经被识别出来了:
在这里插入图片描述
同法处理另一个函数loc_18B2868后:
在这里插入图片描述
(如果伪代码更新不过来,就先进入sub_18B2868的伪代码,然后再重新进入HEN_ReadBlock的伪代码,再按F5)

(如果更上层的函数的伪代码更新不过来,也是同法,先进入下层函数伪代码,再回到上层函数伪代码并按F5)

IDA 处理 positive sp value has been detected

TAB看伪代码时出现这种报错:

positive sp value has been detected, the output may be wrong!

这是因为IDA认为函数栈帧不平衡,满堆栈递减情况下SP超出了栈顶

解决办法参考:
https://bbs.kanxue.com/thread-158896.htm
https://blog.csdn.net/xiangshangbashaonian/article/details/81950110
https://d0nuts33.github.io/2023/02/21/%E9%9D%9E%E5%B9%B3%E5%9D%A6%E5%8C%96%E6%B7%B7%E6%B7%86%E6%80%BB%E7%BB%93/index.html
https://blog.csdn.net/weixin_52369224/article/details/121086041

IDA中Options → General → 把Stack pointer勾选上
在这里插入图片描述
这之后汇编代码左侧会出现一列值,(我理解)代表的是 栈顶地址减去当前SP值
如果是负数,就说明运行到该位置时SP越界了
在这里插入图片描述
在某行代码处按ALT+K(或者在代码处右键→“Change stack pointer”),可以看到该行代码对SP的修改情况(新SP 减去 旧SP)
比如这里的ADD SP, SP, #0x50,就会将SP值增加0x50:

加粗样式
显然这里增加0x50之后,SP就越界了。
一种解决思路是将该指令NOP掉,因为它可能是花指令;
另一种思路是强行控制SP的变化情况,比如我们强制让SP的变化量为0x0:

这之后栈帧就平衡了,但仍可能存在其他问题影响反编译

Win IDA 命令行 使用

例如要反汇编JDJRMobile这个macho文件,得到.asm和.i64文件:

ida64 -B JDJRMobile

或者

ida64 -B JDJRMobile | more

在这里插入图片描述

IDA字符串搜素

Alt+T

IDA运行IDC脚本

打开i64文件后,File → Script command
点击Import导入写好的idc文件,点击Run运行
在这里插入图片描述
参考:https://blog.csdn.net/mandiheyanyu/article/details/125997818

IDA复制汇编代码

使用此IDC脚本,输出在当前打开的i64文件目录下,文件名由i64的文件名加"Part" 组成

#include "idc.idc"
 
static ElementExist(arrayid,size,val)
{
  auto i,v;
  for(i=0;i<size;i++)
  {
    v=GetArrayElement(AR_LONG,arrayid,i);
    if(v==val)
      return 1;
  }
  return 0;
}
static GenFuncIns(st,arrayid,size)
{
  auto start,end,i,ins,x,xt,funcend;
  start=st;
  end=FindFuncEnd(start);
  for(i=start;i<end;)
  {
    ins=GetDisasm(i);
    for(x=Rfirst(i);x!=BADADDR;x=Rnext(i,x))
    {
      xt=XrefType();
      if(xt == fl_CN && !ElementExist(arrayid,size,x))
      {
        SetArrayLong(arrayid,size,x);
        size++;
      }
    }
    i=ItemEnd(i);/*FindCode(i,1);*/
    //Message(form("%s\r\n",ins));
  }
  return size;
}
static main()
{
  auto arrayid,size,pos,st,file,funcend,path;
  st=ScreenEA();
  path = GetIdbPath();
  path = substr(path, 0, strlen(path) - 4) + "Part.asm";
  file=fopen(path,"w+");
  if(st==BADADDR)
  {
    Warning("您需要选中一个函数起始地址!");
    return;
  }
  arrayid=CreateArray("gen_func_ins");
  if(arrayid<0)
  {   
    arrayid=GetArrayId("gen_func_ins");
  }
  pos=0;
  SetArrayLong(arrayid,pos,st);
  size=1;
  for(pos=0;pos<size;pos++)
  {
    st=GetArrayElement(AR_LONG,arrayid,pos); 
    Message(form("proc:%8.8x\r\n",st)); 
    funcend=FindFuncEnd(st);
    if (funcend!=BADADDR)
    {
      Message("正在将这个函数代码写入 %s \n",path); 
      GenerateFile(OFILE_ASM,file, st,funcend, 0);
    }
    else
    {
      Message(form("proc:%8.8x Write false\r\n",st));
    }
    size=GenFuncIns(st,arrayid,size);
  }
  DeleteArray(arrayid);
  fclose(file);
Message("All done, exiting...\n");
}

修改基地址

修改IDA显示二进制文件的基地址
Edit–>Segments–>Rebase Program
在这里插入图片描述

左下角的AC

在这里插入图片描述

在这里插入图片描述
据豆包说:
在 IDA Pro 中,左下角的 AC:xxxx 通常指的是 Analysis Coverage(分析覆盖度),xxxx 代表具体的百分比数值 。它表示 IDA Pro 对当前分析文件的代码和数据的分析覆盖程度。比如 AC:90% 意味着 IDA Pro 已经对该文件 90% 的内容完成了分析,还有 10% 的部分未被充分分析或识别,这可能包括一些复杂的代码结构、未识别的数据类型等未被完全解析的内容。通过这个指标,用户可以大致了解 IDA Pro 对文件的分析进展和完整性。

C++ this指针

在 C++ 的底层实现中,当通过指针调用类的成员函数时,隐式的 this 指针会被编译器自动插入为第一个参数。因此,编译后的代码中,参数列表会比源代码中多一个 this 参数,导致在反汇编工具(如 IDA)中看到的参数数量可能比源代码多一个。

比如源代码:

m_registry->callNativeMethod(call.moduleId, call.methodId, std::move(call.arguments), call.callId);

IDA看到的:

sub_100347FE4(*(a1 + 1), *v9, *(v9 + 4), v9 + 8, *(v9 + 56));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值