逆向工程核心原理-逆向基础(基于Ollydbg201与Hello World的逆向调试)

文章介绍了逆向工程的核心原理,重点讲解了如何使用调试器OllyDbg进行二进制代码分析,包括代码窗口、寄存器窗口、数据窗口和栈区窗口的功能,以及各种快捷键的用途。此外,还详细阐述了如何查找和修改程序中的字符串,以及通过设置断点和查找API来理解和追踪代码执行流程。文章还提到了文件偏移的概念及其在文件操作中的作用。
摘要由CSDN通过智能技术生成

逆向工程核心原理-逆向基础

调试器与汇编语言

我们编写的源码经过编译转化为exe可执行文件,而exe则是二进制文件,在分析二进制文件时,为了更好地理解它,我们通过调试器进行反汇编处理,将二进制代码转化为汇编语言指令代码

OllyDbg的使用

窗口界面布局

在这里插入图片描述

  • 代码窗口:默认用于显示反汇编代码,还用于显示各种注释,标签,分析代码时显示循环等信息
  • 寄存器窗口:实时显示CPU寄存器的值,还可以用来修改寄存器
  • 数据窗口:用于显示进程的内存地址,也可以用来修改内存地址
  • 栈区窗口:实时显示ESP寄存器指向的进程栈内存,并且允许修改

而代码窗口中的内容又有以下布局:

004011A0E8 6715000CALL 0040270C
进程的虚拟内存地址x86 CPU指令反汇编代码此部分空出为注释区,可自己添加

EP(EntryPoint):指的是可执行代码的入口点

常用的快捷键

快捷键描述
CTRL+F2终止当前进程,重新开始调试
F7执行一句操作码,遇到call将会跳转进入函数
F8执行一句操作码,遇到call执行函数,但是不会进入函数
CTRL+F9一直在函数内部运行,直到retn指令跳出(和F8的区别在于,此指令是执行发起指令时所在函数的return,F8就是一个简单的跳过功能
CTRL+G移动到指定地址,用来查看代码或内存(运行状态下不可用)
F4执行到光标位置,直接跳转到要调试的地址
为当前位置填写注释
为当前位置填写标签
F2设置或者取消断点
F9一直运行,存在断点则停止在断点处
*显示当前EIP指针的位置
-显示上一个光标的位置
Enter若存在call或者jmp则跟踪并显示相关地址
ALT+B显示存在的断点列表

标记/进入特定地址的方法

  • 使用CTRL+G后在 enter expression to follow对话框中输入对应的地址即可
  • 在调试时,在需要标记的地址处设置断点,然后F9执行到断点处即可,在断点列表中双击也可以跳转到相应位置
  • 设置注释在指定语句中,寻找注释可以在右键菜单search for中找到all user comment中看到添加的所有注释,双击可以到达注释位置
  • 在指定位置添加标签,后在右键菜单search for中找到中user defined labls(目前的201版本貌似找不到这个功能了)看到添加的所有注释

快速查找指定代码

  • 代码执行法

我们已知目标可执行文件调用了MassageBox的API,则我们只需要执行到目标API中的函数即可,我们通常的思路是,按F7或者F8执行程序,遇到call或者jmp指令就使用F7执行进入函数(遇到非目标函数ctrl+F9)或者enter查看函数内容,非目标函数则使用-回到原来的的位置,按F8继续调试(留意可能的API调用或程序内容)

  • 字符串检索法

在ollydbg的右键菜单中使用search for中的all referenced strings其中内容是其在调试之初对程序使用的字符串和API都将被摘录出来成为列表

  • API检索法

在程序运行后,我们可以根据运行效果,猜测运行时调用了哪些API,可以直接使用ALL intermodular calls查看调用的所有API,不过在文件受到压缩或保护后,ollydbug就无法列出API列表了,此时我们要进行调试我们需要为加载进内存中的DLL代码库设置断点

压缩器(运行时压缩器):它可以将可执行文件的代码,数据,资源压缩,但是其压缩完成后仍是一个可执行文件

保护器:保护器具有压缩功能,并且还添加了反调试,反模拟,反转储,可有效保护进程

API的实现:API实际上是系统提供的一系列函数,他们位于系统提供的DLL库中,我们的程序进行的一系列操作必须通过系统的API向系统提出请求,系统才会将对应DLL文件加载到应用程序的进程内存

我们可以在ollydbg的view菜单(也可以ALT+M)中找到memory map打开内存映射窗口,看到程序请求的DLL库列表等,为了找到调用的API,我们使用search for中的name选项在其中寻找对应API,双击即可定位到该位置,注意是本可执行程序的name列表,有时候选定了一个地址name列表可能会是对应的DLL库中的name列表

修改程序中字符串

修改程序中的字符串有两种方式:

  • 修改字符串的缓冲区

我们在定位字符串后,找到字符串所在内存地址,然后在数据窗口查找该地址,然后选中要修改的字符串部分,使用ctrl+e进行快速编辑该字符串即可修改,需要注意,如果修改后字符串长度大于原有字符串,可能会导致程序后面的数据被覆盖,此时就有可能发生内存错误(不建议比原有字符串长),并且在修改时一定要注意unicode字符串的结尾是NULL占据两个字节。

如果要保存文件,我们则应该在数据窗口选中修改后的字符串,右键找到edit中的Copy to executable或Copy all modifications to executable,进入新的界面中选中save file,然后根据提示保存即可,在文件命名处要加上exe的可执行文件扩展名

注意:可执行文件在保存时一般会给字符串留出更多空间,所以有时候以更长的字符串覆盖也不会出问题

  • 在其他内存区域建立字符串,并传递给API

这种方法实际上是利用了一个特性,应用程序被加载到内存有一个最小内存分配大小,即使程序大小未达到分配内存大小,其他的内存也会被分配,并且以NULL填充

我们可以利用填充为NULL的内存,在其中添加需要的字符串,最后在传递字符串到API处,将PUSH的地址修改成我们修改处的地址起始点即可(选中对应指令后按空格键即可通过Assemble窗口修改)

逆向尝试

首先我们自己写一个和作者一摸一样的程序,尝试逆向它:

#include "windows.h"
#include "tchar.h"


int _tmain(int argc, TCHAR* argv[]) {

	MessageBox(NULL, L"Hello World",
		L"This is a test file",
		MB_OK);

	return 0;

}

修改字符缓冲区

首先我们通过all referenced strings找到我们的对应字符串(可以看到我这里字符串地址是B22100和B22128),然后打上断点过后按F9执行到断点处,然后在数据窗口找到字符串内存:

在这里插入图片描述

进行修改(注意keep size选项,保证修改不会超过范围),第一处改为测试通过,第二处改为大写字母:

在这里插入图片描述

在这里插入图片描述

调试后修改成功:

在这里插入图片描述

保存文件:

在这里插入图片描述

在这里插入图片描述

在其他区域建立字符串

我们重新调试文件,然后找到字符串,在填充为NULL的内存区域加入字符串内容(如下我们在283020处建立新字符串):

在这里插入图片描述

改变字符串载入地址:

在这里插入图片描述

进行调试,修改成功:

在这里插入图片描述

注意:此修改方法保存的可执行文件无法正常运行,当可执行文件加载进入内存时,通常来讲进程的内存仍然存在,但是对应的文件偏移并不存在,所以无法正常运行

文件偏移

文件偏移是指在计算机中对文件进行访问时,当前位置与文件开头之间的距离。每个文件都可以看作是一系列字节的集合,文件偏移表示从文件开头到当前位置所经过的字节数。

文件偏移常用于读取和写入文件的特定位置。通过设置文件偏移,可以确定下一个要读取或写入的位置,以便在文件中执行精确的操作。

在大多数编程语言和操作系统中,文件偏移以字节为单位进行计量。初始文件偏移通常为0,表示从文件的开头开始。随着读取或写入操作的进行,文件偏移会自动增加,指向下一个要操作的位置。

文件偏移对于处理文件的不同部分非常有用。通过更改文件偏移,可以在文件中前后移动,查找和更新特定位置的数据,或者追加新数据到文件末尾。

需要注意的是,在某些情况下,文件偏移可能以其他单位(如块或记录)进行计量,这取决于使用的文件系统或应用程序的要求。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值