ida使用入门指北

发布时间 2023-11-06 14:02:08作者: ve1kcon

静态分析

快捷键

操作 作用
空格键 在反汇编窗口中,进行列表视图图形视图之间的切换
TAB 在反汇编窗口中,进行汇编指令伪代码之间的切换
Esc 和 Ctrl+Enter 翻页,返回前一页面
G 定位地址
X 交叉引用
N 重命名变量、函数名
Y 修改函数原型或者变量类型
";" 和 ":" 注释
* 把变量重定义为数组,包括在结构体视窗里也能对变量这么用
Shift + F12 打开字符串窗口,可用于字符串搜索
D 双击进变量之后,可以对变量的数据类型进行切换,db -> dw -> dd 可以设置
R 字符转换,如 '95' -> '_'
H 将字符 在十进制和十六进制之间进行转换
P 创建函数
Shift + s 快速创建结构体/相当于进入到 structures 窗口
... 全局搜索,视图保存,数组创建...

修复代码

结构体还原

分析

使用 ida 进行逆向分析的时候,一些逆向工程量较大的题目,我们是可以通过修复结构体来辅助我们的逆向工作的,什么意思?就是有些结构体 ida 会识别不出来,就会以 *(ptr+8), *(ptr+16) 等形式出现,这时我们可以定义一个结构体,然后指定这个 ptr 指针的某个位置比如 +8 的位置说是结构体的 int size 参数,ida 就会自动识别了

实践

写了个 demo,然后对他进行反编译看伪代码,来进行结构体的还原(demo 的源码放在后面

image-20231031233359690

详细步骤如下:

先进入 Structures 视窗,按下键盘的 insert 键添加结构体

image-20231031233626450

已经能看见详细的操作指引了

00000000 ; Ins/Del : create/delete structure
00000000 ; D/A/*   : create structure member (data/ascii/array)
00000000 ; N       : rename structure or structure member
00000000 ; U       : delete structure member

单击结构体 ends 位置,按 D 增加结构体成员,单击结构体成员,按 D 能切换结构体成员类型,按 N 能对结构体成员重命名

这样我们的结构体就创建好了,回到我们的反汇编代码视窗

image-20231031234052165

!或者直接右键变量,选择 Create new struct type...,使用C语法快速定义结构体,来替代上述步骤!

右键变量,选择设置变量类型

image-20231101204923710

设置成刚刚创建的结构体指针类型

student *student1

然后对变量进行重命名为 student1

btw,像图片中倒数第二个 for 循环里的结构体指针数组可以怎样修复它呢?

*((unsigned int *)*(&students + i) + 13))

其实也是一样的,毕竟变量 students 就是个存指针的数组嘛,也是修改它的类型就好

student *students[]

一般来说如果他不是结构体指针数组,举个例,也可以修改成以下

void **ptr
char **ptr
......

最后修复完呈现出来的效果

image-20231101210106475

demo源码

记得编译成 elf 文件,gcc test_struct.c -o test_struct

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student
{
    char name[50];
    int age;
    int student_id;
};

struct Student *student1;

struct Student *students[4];

int main()
{
    student1 = (struct Student *)malloc(sizeof(struct Student));
    strcpy(student1->name, "A");
    student1->age = 1;
    student1->student_id = 1111;

    printf("Student Name: %s\n", student1->name);
    printf("Student Age: %d\n", student1->age);
    printf("Student ID: %d\n\n", student1->student_id);

    students[0] = student1;

    students[1] = (struct Student *)malloc(sizeof(struct Student));
    strcpy(students[1]->name, "B");
    students[1]->age = 2;
    students[1]->student_id = 2222;

    students[2] = (struct Student *)malloc(sizeof(struct Student));
    strcpy(students[2]->name, "C");
    students[2]->age = 3;
    students[2]->student_id = 3333;

    students[3] = (struct Student *)malloc(sizeof(struct Student));
    strcpy(students[3]->name, "D");
    students[3]->age = 4;
    students[3]->student_id = 4444;

    for (int i = 1; i < 4; i++)
    {
        printf("Student Name: %s\n", students[i]->name);
        printf("Student Age: %d\n", students[i]->age);
        printf("Student ID: %d\n\n", students[i]->student_id);
    }

    // 释放动态分配的内存
    for (int i = 1; i < 4; i++)
    {
        free(students[i]);
    }

    return 0;
}

动态调试

调试exe

找到 IDA 所在文件夹目录下的 dbgsrv 文件夹进去,找到对应版本的win32_remote.exe 或者 win64_remote64.exe,根据程序位数双击运行相应的 remote.exe

IDA 里:Select a debugger --> Local Windows debugger

Debugger --> Process Options,第一项和第二项为目标调试的程序路径,第三项是它所在的目录,注意填 Hostname:127.0.0.1Port:23946,是否设为默认看自己

然后进去之后下好断点,点击顶部绿色的箭头即可开始调试

调试跟踪常用快捷键如下

快捷键 功能
F7 单步步进,跟进函数调用
F8 单步步过,不跟进函数调用
F4 运行到光标所在的行
Ctrl + F7 运行至当前函数的返回
F9 运行程序直至遇到断点
Ctrl+F2 终止当前正在运行的进程
F2 设置断点

调试so文件

咕咕,还没学