IDA反编译的几个注意和技巧

2023-11-15

关于一些类型转换以及指针和地址的总结

最可以拿来当教训的应该是 hide cast 功能
在这里插入图片描述
如果隐藏了,就是这样的
在这里插入图片描述
如果SaveAShouldShowStreamIndex是char类型的数组,那会怎么样呢,一次取一个字节和取四个字节就完全不一样了.当然如果你再逆向的时候就已经知道了这个数组的类型那就没问题,但是也应该注意没到必要的时候不要Hide Casts ,虽然你的代码会被很多类型转换搞得头晕,但是关掉真的影响你的逆向准确性.

关于F5汇编代码不能转成c的伪代码的几个问题总结

1.jmpout的问题

jumpot
在这里插入图片描述
如果遇上jumpout的话,一般是只能动态调试去跟踪调试代码.很少能将jumpOut的汇编修改成能反出伪C的形式.

2.positive sp value has been found 的问题

在这里插入图片描述
出现这个问题一般都是能解决的
这个请参考这个帖子:
https://blog.csdn.net/u010334666/article/details/82937413

3.call analysis failed

在这里插入图片描述
这种一般是函数内部的参数没有解析正确,所以如果想正确解析,需要读取去修改函数内部调用函数的参数.
参考帖子:https://www.cnblogs.com/echo579/p/6564433.html

有时候 switch 也可能会导致 出现 jumpout 解决办法是 把jumpout签名的一截汇编 先U 撤销然后再重新反编译 就能正确反编译出来了
或者说函数的没有定位到正确的结尾 也会导致jumpout 这就需要正确定位到函数的末尾 才能将jumpout改成正确的代码
有时候 换一个版本的IDA 去看 也能看出一些问题 比如你用IDA7.0 有时候反编译出来的内容不正确 那就用IDA6.8 去分析 没准比IDA7.0 分析的要准确一点

对于浮点数的逆向思路

在这里插入图片描述
出现COERCE_FLOAT的宏一般是接收的返回值错了,或者是函数的返回值有问题,
还有出现这种LOWWORD的宏一般是参数的问题,有时可能是double的参数,IDA反成了两个Int的类型的参数,因为32位的ARM本身就没有64位的类型,需要自己修改函数的参数和返回值才能得到正确的值,还有一些其他的标志也可以看出是浮点数的运算:比如函数内部大量的位移运算,大量参数未赋值直接参与运算等

对于ARM汇编的一些思路和技巧

局部变量的地址 sp+xx标识
在这里插入图片描述
临时变量,在使用的时候用什么寄存器标识
在这里插入图片描述
暂时先想到这些,以后再补充

对单片机项目的逆向要点

需要掌握一定的单片机开发知识.
很多地方涉及到一些硬件的接口和屏幕显示的接口,都是以地址的形式表示,如:0x20004F64,0x20005014 ,0x64000400 ,0x4001300等的地址
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
看到这种地址上的赋值,就需要去参考手册了
在这里插入图片描述

IDA 反编译一些可变参数的技巧和总结

要IDA 能正确识别出可变参数的函数的参数 首先要清楚定位到可变参数前最后一个确定的参数 这样IDA才能识别出来

C语言中对可变参数的读写依赖于宏va_start、va_arg和va_end

这三个宏的定义如下:

  1. void va_start(va_list ap,
    last);//取第一个可变参数(如上述printf中的i)的指针给ap,last是函数声明中的最后一个固定参数(比如printf函数原型中的*fromat);

  2. type va_arg(va_list ap,
    type);//返回当前ap指向的可变参数的值,然后ap指向下一个可变参数;type表示当前可变参数的类型(支持的类型位int和double);

  3. void va_end(va_list ap);//将ap置为NULL

还有一种方法不用去使用定义的都参数的宏也能去读取参数

这是我在IDA反汇编中看到的 既然IDA把他反汇编成这样 那也肯定可以 然后就写代码测试一下吧

为了测试可变参数 如何在IDA中被识别 写了一个测试程序 如下:

int function(int a,int b,int Num, ...)
{
	int *p;
	p = &Num;//通过一个指针指向可变参数的最后一个确定位置 
	int k = 0;

	p++;//指针向后偏移就可以取到参数的值
	for (int i = 0; i < Num; i++)
	{
		k += *p;
		p++;
	}

	return k;
}




int main(int argc, char* argv[])
{
	printf("hello");
	return function(6, 2, 3, 4, 5, 6);
}

这应该是应该传递参数的时候是根据栈的循序来的 所以通过指针去指向栈的地址 然后+1 就取到了下一个参数的值
但是这样的话就对反汇编产生了一些困难
所以还是需要手动去解析下 让他变成那种 宏的模式

IDA 识别可变参数

然后我把函数改成了这种宏的形式让IDA去识别

#include "stdafx.h"
#include <stdarg.h>


int function(int a,int b,int Num, ...)
{

	int k = 0;
	va_list ap;
	/*int *p;
	p = &Num;
	

	p++;*/

	va_start(ap,Num);
	for (int i = 0; i < Num; i++)
	{
		k += va_arg(ap,int);
	}
	va_end(ap);
	return k;
}




int main(int argc, char* argv[])
{
	printf("hello");
	return function(6, 2, 3, 4, 5, 6);
}

IDA反汇编的function的代码如下:

int __cdecl sub_411710(int a1, int a2, int a3, char a4)
{
  int v4; // ecx
  int i; // [esp+D0h] [ebp-20h]
  char *v7; // [esp+DCh] [ebp-14h]
  int v8; // [esp+E8h] [ebp-8h]

  v8 = 0;
  sub_41135C(v4);
  v7 = &a4;
  for ( i = 0; i < a3; ++i )
  {
    v7 += 4;
    v8 += *((_DWORD *)v7 - 1);
  }
  return v8;
}

可以看出来 既识别不对参数 也没认出这是可变参数
然后手动修改函数参数
在这里插入图片描述
修改两个地方:
1.找到可变参数前的最后一个确定的参数
2.在最后一个参数后加上三个 …

然后代码变成了如下形式:

int sub_411710(int a1, int a2, int a3, ...)
{
  int i; // [esp+D0h] [ebp-20h]
  va_list v5; // [esp+DCh] [ebp-14h]//变量的类型也识别出来了
  int v6; // [esp+E8h] [ebp-8h]
  va_list a4; // [esp+104h] [ebp+14h]

  va_start(a4, a3);//识别出了宏
  v6 = 0;
  sub_41135C();
  va_copy(v5, a4);
  for ( i = 0; i < a3; ++i )
  {
    v5 += 4;//指向参数的指针
    v6 += *((_DWORD *)v5 - 1);
  }
  return v6;
}

IDA Functions window 函数跟随 Pseudocode IDA-View窗口变化

右键点击functions窗口 Turn on synchronization
在这里插入图片描述

[autohidden] 问题

[autohidden] The current structure is just a copy of a local type.
If you edit it from the struct view, IDA will sync the changes
back to the local type and will consider the type as manually defined
by the user. We recommend you to edit the local type instead
of editing the structure. Do you want to continue? -> No

在从local types导入结构体到structures时提示以上问题,导致我无法直接修改结构体

解决方法: windows->Reset hidden messages
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IDA反编译的几个注意和技巧 的相关文章

随机推荐

  • 运用顺序表实现多项式相加

    本题要求输入两个一元多项式 然后输出它们的和 相加后得到的一元多项式 输入格式 输入一个整数n 表示输入组数 然后依次输入每一组数据 输入一个整数A 表示多项式的项数 小于100 然后输入A对整数 每一对整数表示对应项的指数和系数 输出格式
  • 通配符

    1 通配符 用来匹配文件名或目录 匹配文件内容用正则表达式 匹配任意一个字符 匹配0个或任意多个字符 也就是可以匹配任何内容 匹配括号中的任意一个字符 eg abc 匹配一个字符 或a 或b 或c 匹配括号中任意一个字符 代表一个范围 eg
  • 词向量的运算与Emoji生成器

    本文参考参考 没有对框架内容进行学习 旨在学习思路和方法 1 词向量运算 之前学习RNN和LSTM的时候 输入的语句都是一个向量 比如恐龙的名字那个例子就是将一个单词中的字母按顺序依次输入 这对于一个单词的预测是可行的 但是对于想让机器学习
  • Qt - MVC模型/视图编程

    MVC模型 视图编程 Qt中的模型 视图架构用来实现大量的数据存储 处理及显示 MVC Model View Controller 包括了3个组件 模型 Model 是应用对象 用来表示数据 视图 View 是模型的用户界面 用来显示数据
  • mac安装eclipse报错:Failed to create the Java Virtual Machine

    目录 1 报错场景 2 解决办法 1 查看本机安装的JAVA环境 2 修改info plsit文件 1 报错场景 macosx安装Eclipse的时候报错 Failed to create the Java Virtual Machine
  • @InitBinder解析和@ModelAttribute参数注入分析

    当我们请求 hello时 传参数u username如何注入到user中的username 样例 Controller public class HelloController RequestMapping hello public Str
  • Activiti7与SpringBoot整合开发

    SpringBoot 整合 Activti7 的具体步骤大概包括以下4步 1 添加 SpringBoot 整合 Activti7 的相关jar包 2 添加 SpringSecurity 安全框架的整合配置信息 3 使用 Activti7 新
  • 用递归解决八皇后问题

    单纯用递归解决该问题 就是利用一个一维数组表示出每种解 例如arry n i 其中n表示第n行的棋子 而 i 表示该 行的棋子所在列的位置 该问题可以用贪心算法进行优化 这是针对初学者练习递归时的一种解决办法 该代码并不是为了优化解决问题
  • flutter 开发踩坑集

    一 TextField设置高度后 文字无法居中 解决方案 TextField style TextStyle decoration InputDecoration prefixIcon ImageUtils getImage search
  • 区块链技术发展现状与展望 论文阅读摘要(袁勇、王飞跃)

    阅读摘要
  • 前端代码审查和测试

    检查代码的概念和过程 来自百度回答 https zhidao baidu com question 499002410583455364 html 1 代码检查法 1 桌面检查 这是一种传统的检查方法 由程序员检查自己编写的程序 程序员在程
  • GPT带我学-设计模式-命令模式

    1 你知道设计模式的命令模式吗 是的 我知道设计模式中的命令模式 命令模式是一种行为型设计模式 它将请求封装成一个对象 从而允许使用不同的请求 队列或日志来参数化其他对象 命令模式还支持撤销操作 并且可以提供事务的实现 在命令模式中 有四个
  • 机器学习——RBF神经网络

    RBF神经网络 本文部分资料与案例来源 MATLAB神经网络43个案例分析 RBF神经网络简述 再介绍RBF神经网络之前我们先来看一下径向基函数 RBF 在百度百科上 RBF定义如下 径向基函数是一个取值仅仅依赖于离原点距离的实值函数 也就
  • 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0"[已解决]

    前两天升级系统架构 升级后打开网页报错了 详细信息如下 未能加载文件或程序集 Newtonsoft Json Version 4 5 0 0 Culture neutral PublicKeyToken 30ad4fe6b2a6aeed 或
  • PHP架构师成长路线,PHP架构师要求

    在软件开发圈 架构师 是一个受万人追捧的头衔 架构师给人的感觉是站在软件系统后面指点江山的诸葛亮 一个系统的如何运作 运作得如何 架构师都能提前设想出来 然而 梦想是美好的 现实却是残酷的 很多人在实际工作后就会发现 梦想是成为大牛 但做的
  • 当对比学习遇上prompt,擦出了怎样的火花……

    细数最近NLP领域的热门关键词 transformer 多模态 预训练 还有不得不提的prompt 本质上说 prompt是一种激发语言模型中知识的手段 随着prompting技术的大火 有越来越多的研究者在思考 Prompt 除了让这个方
  • vue3 antd pro 框架动态路由

    此框架中路由权限使用了两种方法 主要介绍第二种方法 从路由表构建路由 前端对比后端权限字段过滤静态路由表 即 前端配置好全部的路由表 然后根据权限来与后端获取到的进行对比 最终展示对比后的数据 从后端获取路由表结构体 并构建前端路由 从后端
  • ubuntu的使用--系统目录篇(文末附Desktop目录位置)

    Ubuntu的Desktop 桌面 的目录是什么 ubuntu下的系统目录是什么样子的 1 cd命令技巧 直接进入用户的home目录 cd 进入上一个目录 cd 进入当前目录的上一层目录 cd 进入当前目录的上两层目录 cd 2 每次初始打
  • navicat 传输和同步

    同步 如果表存在 数据相同的则留 不同的则删除 然后插入目的表不存在的数据 同步相当于两个数据库表的数据拿出来比对是否有差异 传输 直接删表 插入源表数据 传输是一个数据表的数据进行插入 优缺点 这样比较的话 同步占内存但是快 适合数据量少
  • IDA反编译的几个注意和技巧

    IDA逆向程序的经验总结 关于一些类型转换以及指针和地址的总结 关于F5汇编代码不能转成c的伪代码的几个问题总结 1 jmpout的问题 2 positive sp value has been found 的问题 3 call analy