Linux -- 反汇编 (待完善)(转)

Linux下使用objdump+vim+xxd进行反汇编并修改指令

2012-08-27 23:23:46|  分类: Linux相关 |举报 |字号 订阅

前段时间花了一个星期时间马马虎虎算是对汇编入了门吧(好吧,其它我还是什么都不懂),最近又开始对汇编有点兴趣了,于是想试下反汇编的感觉并尝试自己修改下指令

说对一个程序反汇编后再修改的方法是以十六进制的方式打开程序,然后再通过一些工具找到相关的位置再用相关工具计算出偏移量等然后再做修改,不过我从来没
搞过反汇编,对汇编也是一知半解的样子,所以就没那么专业了,至于能不能直接使用汇编的助记符修改我还不知道,估计应该是有这样的工具吧,不过我没搜索
过,所以只尝试下十六进制下以汇编指令的十六进制形式进行修改了,如果有那样的修改方法我希望你能够告诉我,谢谢
在linux下反汇编我们可以使
用gdb这个调试器也可以使用objdump这个工具,当然还有其它工具,不过这里我就不说了,然后用十六进制打开文件我们可以使用xxd,我们通过在
vim内部调用xxd来对文件进行十六进制模式下修改,当然还有其它的十六进制编辑器,这里我也就不说了,因为我也就是玩玩,毕竟最近还在学习Win32
API(我真蛋疼),下面就从一个简单的程序开始吧


大家先看这个程序,很简单,一个主函数,还有一个jmp函数,正常情况下在编译链接后执行是不可能调用到jmp函数的,但我们要做的就是通过反汇编然后修改指令,让该程序在执行完主函数里的printf函数之后跳转到我们jmp函数的首地址以执行jmp函数


没有采用一些特殊的见不得人的手段的话该程序运行后的效果是这样的
然后我们以二进制形式打开可执行程序文件,vim可以使用-b选项来用二进制形式打开文件
vim -b jmp


可以看到是这个样子的,然后我们使用xxd以十六进制模式对该文件进行编译如上图中的那样
:%!xxd
%表示我们当前的文件,!表示我们要执行一个外部命令(程序)
现在我们反汇编下这个程序
objdump -S -M intel jmp


反汇编后的内容比较多,我们就需要看main函数和jmp函数就够了
现在我们可以看出main函数在调用完printf函数返回后(从这样可以看出是调用了puts),下一步的指令是mov eax,0x0,我们还是先看一下反汇编的程序以及相关参数吧
-S这个其实也可以使用-d,这样反汇编出来后会显示地址,十六进制指令,还有就是对应的汇编代码-M intel表示我们以intel语法反汇编,linux下默认的汇编语法格式是AT&T的,这个我不习惯(其实我不会),好了,我们再继续往下说吧
我们刚刚说到在主函数调用完printf函数返回后的下一条指令是给寄存器eax赋0值,具体什么作用就不研究了,我们只说下我们所关心的问题,那就是跳转问题,我们要让程序跳转到jmp函数的地址处,所以我们要修改这条指令
现在我们先停下来说说我们的指令,我们要跳转到jmp,对应的汇编指令应该类似这样的
jmp short jmp

后面的那个jmp不是汇编指令,是一个函数名,当然是个在c语言中是一个合法的标记符,但在汇编语言中我们不要将标号设置成这样,这个指令经过汇编编译器编译后应该是类似这样的
jmp 80483c4
这里的80483c4是0x080483c4也就是jmp函数的地址
所以我们已经知道了我们的指令是什么,但是怎么用十六进制进行表示呢?
我告诉你这条指令应该类似这样写
e9 d2 ff ff ff
e9
是跳转jmp的机器码十六进制表示(这个应该是个段内跳转,而段外跳转应该是ff),后面的d2 ff ff
ff表示偏移量,这个是怎么计算出来的呢?好吧首先我还是先说下我是怎么知道段内跳转的机器码十六进制表示为什么是e9吧,其实很简单........你
丫不会自己先写一个jmp指令然后再反汇编啊(我特别邪恶- -),好了下面说下偏移量的问题
首先从反汇编的结果我们可以看出来我们应该向上跳
转,所以跳转的偏移值是一个负数,而计算机内部表示有符号数的方法是采用补码,最高位表示符号位,1表示负,0表示正,正数的补码是这个数本身,负数和补
码为最高位置1,其它位反转后再加1,那么我们可以从反汇编中的结果中先计算出我们要向上跳转多少



个程序是用于计算跳转偏移量的,其中a表示我们要修改的指令的首地址加上指令自身所占的内存,b设为我们要跳转到的地址,这样就可以计算出偏移量了,然后
我们知道我们是向上跳转的,所以要取得补码,这里我们减过后的数是一个正数,最高位是0所以我们直接对该数取反加1,这样最高位为1,其它位反转加1,刚
好得到负数补码形式

通过计算之后我们得到的结果是0xd2ffffff
记住数据在内存中的存储顺序哦,所以我们最终的代码为e9 d2 ff ff ff


是我们使用xxd打开后的十六进制形式,我们打开我们要修改的指令处,怎么找你应该看得出来吧,使用vim自身的查找功能,很简单的,然后我们就可以进行
修改了,将我们的e9 d2 ff ff ff替换掉后面的b8 00 00 00
00(这个还是替换掉好,虽然我这里是先替换然后在后面将先前指令再补上去的,但是这是因为我们的程序后面有大量的nop指令,所以可以覆盖,但是如果没
有的话那么如果我们直接在里面添加的话会导致程序一团乱,这个大家自己可以亲身体会下
修改完成后我们再
:%!xxd -r
其它的命令和前面一样,-r参数表示我们修改完后回到上一层,也就是我们刚用二进制形式打开可执行文件的那种状况,当然现在已经是被我们修改过后的程序了,当然不要忘记保存,不保存也是瞎忙活了
现在我们再次执行一下程序看看效果


哈,你看,我们成功了,我们已经成功在执行完主函数第一个printf函数后将程序的流程跳转到jmp函数处执行了,我们通过黑暗手段让程序改变了原来的执行路线


下面我们再反汇编一下这个已经被我们修改过的文件看下,我们可以看出来我们在主函数中调用printf函数指令后的指令正是一个跳转指令,我们可以看到它后面要跳到的地址,正确无误
好了,到这里就全部结束了,如果你有时间去折磨和研究你可以试试修改为其它的指令来达到不同的目的,甚至于搞一些破坏,破解什么的

转自:http://blog.163.com/lixiangqiu_9202/blog/static/535750372012727102618226/

时间: 2024-12-16 05:42:22

Linux -- 反汇编 (待完善)(转)的相关文章

Linux反汇编 x86 & ARM

一个静态库(.a),或者 可执行文件(动态链接库没试过),可以使用下面的命令查询: 一.有哪些符号: Linux平台(包括armcc和gcc编译的二进制文件):nm file_name 二.反汇编: GCC编译的二进制: objdump -D file_name armcc编译的二进制:fromelf -c file_name (与编译器在同一个包里)

Linux内核调试方法总结之反汇编

Linux反汇编调试方法 Linux内核模块或者应用程序经常因为各种各样的原因而崩溃,一般情况下都会打印函数调用栈信息,那么,这种情况下,我们怎么去定位问题呢?本文档介绍了一种反汇编的方法辅助定位此类问题. 代码示例如下: #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <execinfo.h> #include <fcntl.h> #include <

Linux 常用命令解析及Bash Shell脚本用法示例

 摘要 Linux 命令是基于文本格式输入输出的一种程序,按照Unix哲学中强调的程序功能简单,输入宽松,输出严谨,各种程序组合可以具有更强大的功能,而具有这种灵活性的主要原因是Linux规定程序的输入输出必须坚持文件流格式,即文本格式,而这就是Linux系统的核心之一. 对于Bash,即Shell的一种,为现在主流Linux发行版本默认的命令行解释器,是一种功能强大的工具,可以实现对Linux支持的程序命令的组合,从而实现强大功能.类似于Window系统的bat文件,Bash具有更为强大的

使用delphi 10.2 开发linux 上的webservice

前几天做了linux下apache的开发,今天做一个linux 下的webservice ,以供客户端调用. 闲话少说,直接干. 新建一个工程.选other...,选择如图. 继续输入服务名 然后就生成对应的单元. 增加linux 平台. 完善对应的单元代码 { Invokable implementation File for Txaliontest which implements Ixaliontest } unit xaliontestImpl; interface uses Soap.

Linux多线程

1. Linux多线程概述 1.1. 概述 进程是系统中程序执行和资源分配的基本单位.每个进程有自己的数据段.代码段和堆栈段.这就造成进程在进行切换等操作时都需要有比较负责的上下文切换等动作.为了进一步减少处理器的空转时间支持多处理器和减少上下文切换开销,也就出现了线程. 线程通常叫做轻量级进程.线程是在共享内存空间中并发执行的多道执行路径,是一个更加接近于执行体的概念,拥有独立的执行序列,是进程的基本调度单元,每个进程至少都有一个main线程.它与同进程中的其他线程共享进程空间{堆 代码 数据

linux新手入门前知道的一些概念

前言: 这篇文章是结合自己从小白开始学linux到工作中运用linux系统,以新手怎么理解的角度来说说linux系统,希望能给想学习linux的新手带来一些帮助. 引子:随着互联网技术不断更新,企业对系统服务需求,linux系统渐渐形成IT行业的大趋势.高效率的命令化,不占硬件资源,系统开源等在服务器系统居高不下,也成为IT人员学习新技术的平台对象. 对于有IT行业经验的人来说,习惯了一些语言,linux学习并不难.对于没有任何经验的新手了解linux系统界面(包括安装系统)可能都需要大半天,l

Linux多线程(二)(线程等待,退出)

1. 线程的等待退出 1.1. 等待线程退出 线程从入口点函数自然返回,或者主动调用pthread_exit()函数,都可以让线程正常终止 线程从入口点函数自然返回时,函数返回值可以被其它线程用pthread_join函数获取 pthread_join原型为: #include <pthread.h> int pthread_join(pthread_t th, void **thread_return); 1. 该函数是一个阻塞函数,一直等到参数th指定的线程返回:与多进程中的wait或wa

MSM8909+Android5.1.1键盘驱动------概述

采用SN7326带智能指扫描的键盘扩展芯片,通过I2C接口来读取其状态寄存器的值就可知道是单按键还是多按键按下,可知道具体是哪个按键按下.然后键盘驱动调用input_event()上报linux的扫描码,比如KEY_RIGHT,然后传递给android框架层,流程如下图: 图1 下面介绍要实现键盘驱动所涉及的主要方方面面 1.     Input子系统 Linux输入设备总类繁杂,常见的包括有按键.键盘.触摸屏.鼠标.摇杆等等,他们本身就是字符设备,而linux内核将这些设备的共同性抽象出来,简

MacBook 虚拟机的选择

偶尔有一些测试需要多台电脑,或者不想把电脑的系统弄乱,所以安装一个虚拟机还是很重要的.下面写一下自己用的三个虚拟机软件,以及最终决定. Vmware Fusion: 商业,收费,509元 优点:驱动丰富,linux支持完善.运行稳定. 缺点:官网打不开,购买不方便. VirtualBox 开源,免费 优点:免费 缺点:不稳定,虚拟机运行过程中,macbook不时地风扇狂转,同样地任务,在vmware虚拟机上运行,没有此现象. Parallels 商业,收费,498元 优点: windows支持完