反汇编笔记

2023-11-16

1.OD中ctrl+f9:运行到返回,就是运行到当前断点所在的函数末尾"retn xxx"处,若xxx=10,那么
10等于10进制的16,就是说这个函数有4个参数,一个参数默认是占4字节,所以就是retn 10。

2.调试程序时,在OD内部小窗口左上角会显示当前断点所在的函数层,是在系统领空还是某个应用程序领空。

3.call前出现lea edx,dword ptr ss:[ebp-x]的分析方法:
当在call处出现类似于下面,在call内部存在对edx的使用时:
call处:
lea edx,dword ptr ss:[ebp-8]   ;将ebp-8堆栈地址赋给edx,注意是堆栈地址,不是堆栈地址上存储的数据。
call 0045255c
call内部:
mov esi,edx
...
push esi
那么在写call调用的时候,怎么办呢?
只需要查看当程序停在call处时,edx寄存器的数值,然后去找到edx数值代表的堆栈地址处存储的数据是什么。
是1,所以我们就可以通过ce查找出当前为0的值,为0可能就是无关数据,选择一个地址,修改为1,然后将该地址
赋给edx。
就是mov edx, xxxxx
call 0045255c

4.call内部出现mov ebx,dword ptr [esp+8],为什么此句不用分析呢,难道不可能是取call通过堆栈传的参数吗?

5.如果call是堆栈传参,那么在call前面就会有push,那么我们在分析call参数时,就要关注call内部从堆栈取数的操作;
反之,如果call是寄存器传参,那么在call前面就没有push,所以在call内部,我们就不必关注从堆栈取数的操作。
如果是堆栈传参,那么在call内部我们就不用再分析从堆栈取数的操作了,就会更加简单;其实不管是堆栈传参还是寄存器传参,
我们都可以不用管内部类似于mov edx,dword ptr ss:[ebp-8]这样的取堆栈操作,因为假如是堆栈传参,那么这样的操作一定是
取参数的,我们已经知道了在调用call前push了,何必还分析呢;假如是寄存器传参,那么对堆栈的操作也不用分析,因为我们
只关心call的参数,既然参数时寄存器,在call前只需mov xxx,yyy,就可以了。

6.OD中没有$函数头标识以及竖线,可以按ctrl+A进行分析,就可以显示了。

7.使用OD直接打开程序与附加已经运行的程序,会有所不同。
在查找花指令时,若使用附加进程,则找不到花指令,使用od直接
打开就可以找到花指令。

8.OD附加进程出现“调试字串:D3DX系统找不到指定的文件”?
去下载DX9.0c,再去下载个StrongOD插件;安装dx9.0,将StrongOD插件解压放到OD工具
PLUGIN目录下,重启软件就可以了。

9.CALL 的参数其实就是在调用 CALL 的时候所需要的运行环境。

10.找无参数call的方法:
比如找加血减血的call,那么先用CE找出血值地址,然后进入OD,将该地址设置硬件中断(hw 416698),在调用加血减血函数时,在其函数内部就会对血值写入新数值,那么在代码访问到416698地址时,就会发生中断。代码短直接看,代码长使用ctrl+f9执行到返回,这样便很容易找到call。

11.要生成一个Release版本的就可以了,你得先设置一下: 在“工程”中选择“设置”打开Project Settings对话框,
先在“设置”下拉列表中选择Win32 Release,然后在右侧设置为“使用MFC作为静态链接库”。点击确定。 
再打开“组建”下的“批组建”,勾掉Win32 Debug,然后再点击“创建”。这时应该能够生成一个Release版本的应用程序。 这个程序就可以直接拷到别人的电脑上运行,不必安装VC

12.堆栈传参call写法。
经过4次的分析,最终找到了调用call,程序老是崩溃的原因:
在程序中查找call的c代码为:
int add(int a, int b)
{
return (a+b);
}

反汇编代码为:
004014E5   .  E8 44020000   CALL <JMP.&MFC42.#6334>
004014EA   .  8B46 64       MOV EAX,DWORD PTR DS:[ESI+0x64]
004014ED   .  8B4E 68       MOV ECX,DWORD PTR DS:[ESI+0x68]
004014F0   .  50            PUSH EAX
004014F1   .  51            PUSH ECX
004014F2   .  E8 D9FFFFFF   CALL test.004014D0
004014F7   .  83C4 08       ADD ESP,0x8
004014FA   .  8BCE          MOV ECX,ESI
004014FC   .  8946 60       MOV DWORD PTR DS:[ESI+0x60],EAX
004014FF   .  6A 00         PUSH 0x0
00401501   .  E8 28020000   CALL <JMP.&MFC42.#6334>
其中下面是add的call
004014F0   .  50            PUSH EAX
004014F1   .  51            PUSH ECX
004014F2   .  E8 D9FFFFFF   CALL test.004014D0
004014F7   .  83C4 08       ADD ESP,0x8
call内部为:
004014D0  /$  8B4424 08     MOV EAX,DWORD PTR SS:[ESP+0x8]
004014D4  |.  8B4C24 04     MOV ECX,DWORD PTR SS:[ESP+0x4]
004014D8  |.  03C1          ADD EAX,ECX
004014DA  \.  C3            RETN

第一次调用call时,在注射器中输入
push 1
push 2
call 004014f2
add esp,0x8
程序老是要崩溃,然后就自己单步查看堆栈情况,因为这个call是通过堆栈传递的2个参数。
当程序单步到004014D0时,堆栈情况:
0532ffa8 004014f7   ;CALL test.004014D0返回地址
0532ffac 04720009   ;注入的线程调用函数返回地址
0532ffb0 00000002   ;push 2
0532ffb4 00000001   ;push 1
0532ffb8 7c80b729   ;为压栈前esp的值,在调用call之后,esp应该回到这个位置。

而在call内部,分别取ESP+0x8,ESP+0x4,这2个参数,此时esp=0532ffa8,那么
[ESP+0x8]=2,[ESP+0x4]=04720009,可以看到参数已经取错了。再次当call执行完毕后,将0532ffa8处的
函数返回地址弹出,函数继续执行下一条指令ADD ESP,0x8,此时esp=0532ffac+8=0532ffb4,可以看到
esp的值并没有回到调用call之前的值,所以造成堆栈不平衡,程序就崩溃了。
解决方法:
类似于这种堆栈传参的call调用,不能调用call所在的地址,因为这样会多在堆栈中压入一个返回地址,
从而造成堆栈不平衡。只能直接调用call内部的第一条指令,就可以了。
           PUSH EAX
           PUSH ECX
004014F2   CALL test.004014D0
           ADD ESP,0x8

不能call 004014F2,只能call 004014D0。

正确的写法是:
push 1
push 2
call 4014D0
add esp,0x8

不管是有参还是无参call,最好都调用call内部的第一条指令地址,这样一定没有错。

13.OD命令:
hw 00416698,在00416698处添加硬件断点
dd 2AE6C68,显示2AE6C68处的内存地址
dd [03109164]+i*4+00000404   // 在od中数值方式显示数组[i]
dc [03109164]+i*4+00000404   // 在od中ASC字符方式显示数组[i]
ctrl+'-':查看上一个过程
ctrl+'+': 查看下一个过程

14.OD跟踪的使用:
右键->HIT跟踪和RUN跟踪,HIT可以查看代码的执行过程,HIT为“击中”的意思,被执行的代码会变色,而RUN可以设置条件,及从上面某一行代码开始执行(ctrl+f11跟踪步入,strl+f12跟踪步过),执行到下面某行代码满足条件,就会断下来,例如可以查找某寄存器的值在哪条代码被修改。
    在已经使用跟踪的情况下,按"-"键可以一条一条查看执行过的代码和数据情况,同时在寄存器,堆栈窗口的数据也会随着代码的返回而更新。

15.mov eax,dword ptr ds:[esp+20]与mov eax,dword ptr ss:[esp+20]的区别:

ds表示从内存地址esp+20处取一个双字数据存入eax,ss表示从堆栈地址esp+20处取一个双字数据存入eax。

 

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

反汇编笔记 的相关文章

  • 出栈的合法性检测

    对于一个给定的入栈顺序 可能的出栈顺序会有很多 但是肯定都要遵循栈 后进先出 的特点 那么怎么进行合法性检测呢 算法思想如下 定义变量InIndex标记入栈序列的当前位置 定义OutIndex标记出栈序列的当前位置 对InIndex和Out
  • ARM常用汇编指令

    目录 一 汇编基本语法 1 汇编指令的最典型书写模式 二 常用汇编指令 1 push压栈指令 2 pop出栈指令 3 sub指令 4 add指令 5 movs数据传输指令 6 str指令 7 ldr指令 8 bl指令 9 MOVW指令 10
  • 通过栈实现算术表达式的计算

    最近在看数据结构的栈 其中有一节为栈应用到算术表达式的计算 接下来我讲举例说明如何用栈去计算 如有不对的地方 请各位大神指教 1 定义操作符的优先级 作为栈顶操作符时优先级仅高于 作为栈顶操作符时优先级是最高的 和 优先级一样 但是一个作为
  • libtool的作用及应用

    gcc library makefile archive command object 注意 本文为转载 原文也是转载 但是为了尊重他人得劳动成果 我将将转载网址贴出来 libtool常见于autoconf automake 单独用的例子很
  • 【数据结构与算法】栈的实现(附源码)

    目录 一 栈的概念和结构 二 接口实现 A 初始化 Stackinit 销毁 Stackdestroy 1 Stackinit 2 Stackdestroy B 插入 Stackpush 删除 Stackpop 1 Stackpush 2
  • 反汇编笔记

    1 OD中ctrl f9 运行到返回 就是运行到当前断点所在的函数末尾 retn xxx 处 若xxx 10 那么 10等于10进制的16 就是说这个函数有4个参数 一个参数默认是占4字节 所以就是retn 10 2 调试程序时 在OD内部
  • 一文弄懂c/c++编译过程(预处理,编译,汇编,链接)

    目录 1 为什么要编译 2 编译过程 3 实验验证 1 为什么要编译 c语言是一门高级语言 需要编译器将其转换成计算机能理解的机器语言 才能在计算机上执行 编译的过程就是将c语言代码转换成汇编代码文件的过程 2 编译过程 程序从代码编译成可
  • 我看Java虚拟机(2)---Java虚拟机内存区域详解

    虚拟机内存区域的组成 直接上图 程序计数器 对于Java方法 用来选取下一条要执行的字节码 对于本地方法 值为空 线程独有 虚拟机栈 执行Java方法 每一层都是一个栈帧 栈帧包括局部变量表 操作数栈 动态链接和方法出口等信息 线程独有 本
  • Linux下C编译系统

    Linux下C编译系统 编译过程概述 了解一些编译知识的读者都知道 所谓编译 就是在编译程序读取源程序 字符流 对之进行词法和语法的分析 将高级语言指令转换为功能等效的汇编代码 再由汇编程序转换为机器语言 并且按照操作系统对可执行文件感谢格
  • 汇编语言(王爽第三版) 实验5编写、调试具体多个段的程序

    参考 http blog sina com cn s blog 171daf8e00102xclx html 汇编语言实验答案 王爽 https wenku baidu com view a1cd7c6c1fb91a37f111f18583
  • 【数据结构】栈的知识点总结--关于栈的定义和基本操作;C语言实现栈;顺序栈;链栈;共享栈;栈的易错点的总结

    欢迎各位看官 目录 1 栈的定义 2 栈的基本操作 2 1创建 2 2销毁 2 3插入Push 2 4删除Pop 2 5获得栈顶元素GetTop 2 6判空 2 7清空栈 3 C语言实现栈 4 顺序栈 4 1数组实现顺序栈 4 2链表实现顺
  • Android内存管理

    Android内存泄露 全解析和处理办法 http www jianshu com p bf159a9c391a
  • [培训-DSP快速入门-8]:C54x DSP汇编语言之寻址方式

    作者主页 文火冰糖的硅基工坊 https blog csdn net HiWangWenBing 本文网址 https blog csdn net HiWangWenBing article details 119023151 目录 第1章
  • JVM内存模型图解(包含堆栈方法区例子和图解)

    下图是完整的虚拟机模型 我们主要是了解三个 1 堆区 heap 存储的全部是对象 每个对象都包含一个与之对应的class的信息 jvm只有一个堆区 heap 被所有线程共享 堆中不存放基本类型和对象引用 只存放对象本身 2 栈区 stack
  • 数据结构----链式栈

    目录 前言 链式栈 操作方式 1 存储结构 2 初始化 3 创建节点 4 判断是否满栈 5 判断是否空栈 6 入栈 7 出栈 8 获取栈顶元素 9 遍历栈 10 清空栈 完整代码 前言 前面我们学习过了数组栈的相关方法 链接 线性表 栈 栈
  • C++实现栈的顺序存储与链式存储

    栈是一种特殊的数据结构 栈中数据先进后出 且栈中数据只能从头部出栈 能直接访问的数据也仅为栈的头部数据 要想访问下面的数据则需要将前面的数据逐个出栈后才可访问 下面通过一个word撤销的案例来解释 我们用word写paper时 首先需要创建
  • 用栈来判断括号匹配问题

    用栈实现 输入一行符号 以 结束 判断其中的括号是否匹配 括号包括 lt gt 如果匹配 输出 right 如果不匹配 给出错误提示 包括 1 对称符号都匹配 输出 right 2 处理到某个符号时不匹配了 输出 The character
  • 栈的讲解及实现(图解+代码/C语言)

    今天为大家分享的是栈的模拟实现 本文主要讲解如何以数组的形式模拟实现 同时给出链表模拟实现栈的代码 目录 图解栈的结构 数组模拟栈的分步实现 创建并初始化 入栈 检测栈是否为空 出栈 获取栈顶元素 获取栈内有效元素个数 销毁栈 链表模拟实现
  • C++用两个栈实现队列

    1 基础 队列 先进先出 即插入数据在队尾进行 删除数据在队头进行 栈 后进先出 即插入与删除数据均在栈顶进行 2 思路 两个栈实现一个队列的思想 用pushStack栈作为push数据的栈 用popStack栈作为pop数据的栈 只要是对
  • 堆栈01--用两个栈实现队列

    堆栈01 用两个栈实现队列 jz05 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 用两个栈来实现一个队列 完成队列的Push和Pop操作 队列中的元素为int类型 测试用例 队列先进先出 输入 1 2 输出 1 2 解析

随机推荐

  • Char和VarChar的区别(无废话版)

    区别1 定长与变长 char表示定长 长度固定 varchar表示变长 即长度可变 char如果插入的长度小于自定义长度时候 中间用空格填充 varChar小于定义长度时 还是按照实际长度存储 插入多长就存多长 因为长度是固定的 char的
  • 浙江农林大学蓝桥杯程序设计竞赛校选拔赛 E-谁是天选之人

    众所周知下棋是一个运气游戏 不过好像也是有规律可循的 Graceful smiling cookies给它的n个棋子标序号 他决定以这些序号决定谁是天选 最开始每个棋子标号都是0 它要进行m次标序号 第i次标序号 它会将第 i X a b
  • python decimal 转换为float_在Python中将float转换为decimal类型

    我只是在玩数字游戏 我发现Numpy提供了一个名为np vectorize的函数 允许您获取一个函数并将其应用于Numpy数组 在 23 中 import numpy as np import decimal D decimal Decim
  • manjaro笔记本显卡驱动_从入门到高端!AMD Radeon RX 500系列移动显卡全解析

    前言 在处理器领域 卧薪尝胆十年之久的AMD终究还是给所有玩家带来了惊喜 2017年2月推出了ZEN构架的处理器之后 相信后面的事情大家都知道了 手忙脚乱的Intel公司在不到2年的时间内连续发布了三代酷睿产品以应对Ryzen处理器的威胁
  • mysql5.7以上的启动、停止、赋权命令

    文章目录 1 启动mysql server 2 查看初始密码 3 本地登陆mysql 4 修改本地root用户密码 5 防火墙设置 6 开启mysql的远程登录 1 启动mysql server systemctl start mysqld
  • 查看数据库字符集

    问题描述 最近发现在不同的数据库中 有时中文占用2个字节 有时占用3个字节 经过分析发现 对于varchar类型的字段 如果数据库字符集使用utf 8 则3个字节表示一个中文 如果数据库字符集使用gbk 则2个字节表示一个中文 数据库字符集
  • QMainWindow、QDialog与QWidget的区别

    一 定义 QWidget 是所有用户界面对象的基类 窗口部件是用户界面的一个原子 它从窗口系统接收鼠标 键盘和其它事件 并且在屏幕上绘制自己的表现 每一个窗口部件都是矩形 并且它们按Z轴顺序排列的 一个窗口部件可以被它的父窗口部件或者它前面
  • 关于mysql导入中文乱码问题的理解

    一般来说 mysql导入方式有三种 一种是通过mysql命令导入 一种是通过source方式导入 最后一种是直接复制sql语句导入 前两种方式一般都能导入成功 但如果这个备份文件有问题 例如本身这个文件里面在默认编码下就乱码了 那么第三种方
  • 全连接层详解

    一 什么是全连接层 转载自 https blog csdn net qq 39521554 article details 81385159 全连接层 fully connected layers FC 在整个卷积神经网络中起到 分类器 的
  • Hyperledger Fabric 应用实战(2)--网络节点设置

    1 网络节点设置 网络名称 rentnet 联盟组织 orderer排序组织 三个成员组织supervisor rentalcrop agency 通道 rentsign 账本数据库 couchdb 物理节点 组织 容器节点 supervi
  • 普通代码块,静态代码块,构造代码块,构造方法

    1 使用示例 2 静态代码块介绍 在类中通过static修饰然后大括号里面的内容就是静态代码块 见13 1实例 static 静态代码块在类被加载的时候执行 并且他只会执行一次 优先于其他所有代码块以及构造方法执行 如果有多个静态代码块则按
  • 怎么用电脑兼职赚钱,普通人可做的6个副业项目

    现在的生活中 我们总是感觉所过的日子都很紧张 虽然我们尽可能地工作和努力 但是生活成本和社会压力仍然那么大 为了弥补自己的生活经验和财务困难 很多人开始寻找一种额外的收入来源 其实这种额外的收入来源就被称之为 兼职或副业 在如今的经济环境中
  • 浅析数组名与&数组名的区别

    一 一维数组 我们借助sizeof帮助我们理解 运行结果如下 二 二维数组 同样借助sizeof来理解 运行结果如下 三 字符型数组 1 借助sizeof来理解 类似的 注意 a b数组有一些差别 造成这种差别的原因是b数组是字符串赋值 此
  • Liveness、Readiness 和 Startup Probes

    liveness apiVersion v1 kind Pod metadata labels test liveness name liveness exec spec containers name liveness image k8s
  • tomcat点击startup.bat一闪而退的解决方法

    1 点击startup bat会闪退 编辑startup bat 在最后一行加入pause 然后保存 再次运行 就可以看到闪退的原因 2 出现这个的原因是没有配置启动的环境JAVA HOME 下面配置一下JAVA HOME 右键电脑 点击属
  • mysql数据库优化--分区

    前言 公司业务数据量很大 因为是面向全国的数据统计分析 所以一天大约是大几十万数据 因为最开始设计架构没有参与 当系统出现问题 去查看的时候发现数据库两个表一个三亿多 另一个十一亿 1 优化思路 因为单表破亿执行sql现在都是问题了 del
  • sudo apt-get update 报错(Ubuntu20.04)

    1 错误 今天运行 sudo apt get update 时报错 appstreamcli 10947 GLib ERROR 09 43 36 719 g variant new parsed 11 13 invalid GVariant
  • 分巧克力 蓝桥杯 99

    题目描述 儿童节那天有 K 位小朋友到小明家做客 小明拿出了珍藏的巧克力招待小朋友们 小明一共有 N 块巧克力 其中第 i 块是 Hi Wi 的方格组成的长方形 为了公平起见 小明需要从这N 块巧克力中切出 K 块巧克力分给小朋友们 切出的
  • OpenCV代码提取:dilate函数的实现

    Morphological Operations A set of operations that process images based on shapes Morphological operations apply a struct
  • 反汇编笔记

    1 OD中ctrl f9 运行到返回 就是运行到当前断点所在的函数末尾 retn xxx 处 若xxx 10 那么 10等于10进制的16 就是说这个函数有4个参数 一个参数默认是占4字节 所以就是retn 10 2 调试程序时 在OD内部