逆向工程核心原理(九)-“内嵌补丁”练习

前面两节看了感觉不怎么好练习,似懂非懂,就先不写,等到时候用的时候再写。原来的执行流程如左图所示,先进入EP,然后解密OEP代码,然后跳转到OEP执行,如果要加密的代码存在于OEP,如果之久修改比较困难,可以将流程转换成右图所示,解密OEP之后,先跳转至补丁代码,然后再跳转至OEP。

下面来实际操作,先要分析程序流程

首先401000是EP,然后F7步入,进行函数调用,将函数返回地址401006地址入栈,也就是函数调用的下一条地址。

将4010F5存到EAX,然后将其入栈,再进行函数调用,猜测这个入栈应该下面函数调用的参数,再次步入函数,又把返回地址入栈。

循环0x154次,从ebx开始,此时ebx是由eax来的,也是4010F5,应该是一段解密代码,4010F5+154-1=401248,也就是对4010F5—-401248进行(xor  0x44)操作。然后步过这段代码,进入下一个函数调用。

与上面类似,可以看出是对401007—-401085区域进行(xor 0x7)解密操作,然后接下来再对4010F5—–401248区域进行(xor 0x11)操作接下来跳出函数进行下一个函数调用。

(401039—-401083)这个函数的主要作用是对4010F5—-401248进行累加,存在EDX寄存器中,然后与0x31EB8DB0进行比较如果相等就会跳转至40121E(OEP)中。

这基本上就是整个程序的流程。

[ep]:

[B] 4010F5——401248    XOR  0x44

[A] 401007——-401085   XOR 0x7

[B] 4010F5——-401248   XOR   0x11

[A](401039——401083)

将4010F5—–401248进行累加,存在EDX,如果与0x31EB8DB0  相等则跳转至OEP,否则报错。

 

下面的解决思路就是再,在跳转至OEP之前,先跳转的补丁代码,然后从补丁代码跳转至OEP,用PEview打开文件,查看PE头,可以看到:

RVA为1000,装入内存的大小为280,原文件大小为400,可以看到从280-400都是NULL填充。所以可以吧补丁代码加载到这一区域,对原来字符串进行替换。

替换完成之后,跳转到OEP,注意原来跳转到OEP的代码要修改成跳转到401280处,也就是401083-401085处的汇编指令为jmp 0x401280机器码为E9 F8 01,因为这个区域属于B区域需要解密与0x7进行异或操作,所以修改为EE FF 06,这样解密之后就变为 E9 F8 01,修改基本完成保存文件。执行

字符串已经发生了改变!

逆向工程核心原理(八)-PE重定位以及.reloc删除

PE重定位,是在加载是ImageBase已经加载别的内容的情况下,重定位才可以加载成功,重定位的基本原理如下:

在应用程序中查找硬编码的位置,然后减去ImageBase(VA—-RVA),加上实际加载的位置(RVA—-VA)

基址重定位表:

可以看出重定位表的RVA为2F000

可以看出RVA为2F000的文件地址为2AE00

可以看出TypeOffest的基准为RVA 1000,快的总大小为150

TypeOffest 2个字节(16位),四位Type和15位Offest

可以看出第一个偏移位420,所以RVA为1420,可以看到1420处的硬编码的地址值是010010C4,减去ImageBase值为10C4,加上实际加载地址,则可以得到重定位地址。

然后删除.reloc

首先找到.reloc节区头

 

在文件中的C000,大小为1000,然后通过Hxd将c000之后全部删除,所以节区数改变要从5改到4

然后Image大小也发生了改变,也需要进行修改,因为内存大小E40,而SectionAlignment为1000,所以减掉1000

然后保存就可以,最后打不开,但是重启后可以打开,应该是没有重定位之后,无法正确加载的缘故。

 

 

 

逆向工程核心原理(七)-运行时压缩,调试UPX

压缩主要包括有损压缩,无损压缩。

压缩器:PE文件专用压缩器

使用目的:

减少PE文件大小

隐藏PE文件内部代码与资源

保护器防止逆向,主要防止破解

使用UPX压缩之后

注意PE头一样,节区名称变化,第一节区Size变为0,EP位于第二节区,资源节区基本没有变化。

查看 发现节区大小为10000,运行瞬间将代码解压缩到第一节区。

后面的在循环出调试没大明白,不知道怎么调到那,所以只写一下硬件中断,PUSHAD是将8个通用寄存器保存到栈,POPAD是出栈,所以在POP之后就是OEP,设置一个硬件断点

下面就是OEP

这一节 没有什么内容吧 待会继续看书练

(705) 618-3568

最近好像懒惰啦  好久没写啦 前几天电脑坏啦 硬盘坏啦 这几天开始恢复看书

有些东西直接截图吧

首先来看pe文件加载到内存的情形

VA指的是进程虚拟内存的绝对地址,RVA指的是相对于ImageBase的相对地址

有  RVA+ImageBase=VA  PE内部大多数以RVA形式存在 因为可能会发生重定位,这时使用VA就无法正确加载。

首先来看DOS头,有两个比较重要的e_magic,e_lfanew,前者是固定的值 4d5a-》MZ,后者是NT头的偏移。下面用peview打开notepad.exe来看看

首先看e_magic的值为MZ,后面的e_lfanew的值先记住待会再看,值为0x000000E0

然后下面应该再看DOS存根,好像不是很重要,没太关注。

再来看NT头

可以看出开始地址为0x000000E0,第一个是签名结构体,总是为0x00004550,第二个成员是文件头,第三个成员是可选头。

下面再来看NT头的文件头:

Machine是机器码,NumberofSections是节区的数量,SizeOfOptionalHeader可选头的大小,Characteristics是文件的标识信息。下面查看一下

下面再学习NT头的可选头

Magic IMAGE_OPTIONAL_HEADER32时为10B,IMAGE_OPTIONAL_HEADER34时为20B,AddressOfEntryPoint时EP的RVA值,ImageBase文件优先装入地址,SectionAlignment节区在内存中的最小单位,FileAligment是文件在磁盘中的最小单位,SizeOfImage是PE Image在虚拟内存中所占空间的大小,SizeOfHeader指出整个PE头的大小,Subsystem用来区分驱动文件与普通的可执行文件,NumberOfRvaAndSizes用来指定DataDirectory数组的个数。DataDirectory。下面看一看

可以看见入口点RVA是0x739d,同ollydbg打开看看

可以看到入口点的VA是ImageBase+RVA=0x01000000+0x0000739d,也就是0x0100739d。数据目录个数是10。

下面是DataDirectory的结构

16个数组分别是VA和Size

下面再是节区头 .

以下是.text头的结构

 

RVA与RAW的转化

RAW=RVA-VirtualAddress+PointerToRawData

下面在学习IAT,一边练习一边学习。找到PE头的数据目录

7604—->6A04

查看IAT的值7990—->6D90

查看数组第一个值7A7A—–>6E7A,000F是Ordinal,是库中函数固有编号,后面是函数名

FirstThunk的RAW:6C4

用ollydbg查看

跟随76344906就是函数(为什么成了大端)

下面是EAT 在dll中边学边练,

首先看

名称数组地址3538——>2938

查看索引为2的004b3b,这是名称的地址

4bb3—–>3fb3再看

441c—–>381c

 

再看 000326d9+7c800000=7c8326d9就是函数地址,到此为止

基本学完,这一章比较杂,以后练习过程中慢慢加深吧

870-430-5472

本题是一个破解序列号的问题

如果输错就会报错

下面进行加载调试,然后找字符串,应该会将用户输入与序列号进行比较,如果不相等就会报错,否则通过,所以应该会有一个条件跳转指令,检测两个值是否相等。

可以看出有一个测试相等的函数调用,前面两个应该就是他的参数,在dump窗口查看

可以看出压入栈的两个地址是12f468和12f458,转到dump窗口可以看见(12f458+0x8)是注册码,而(12f468+0x8)是用户的输入,这两个就是比较函数的参数。然后直接就得到D2C5D1C9 然后进行尝试

这就得到了验证码,但是这个序列号是怎么计算的了,下面要进一步破解加密算法。上面验证应该属于某个函数,这个函数是对check做出处理的。

预测代码

首先读取name字符串,然后循环对字符串进行加密

在402f98函数调用之后,ebp-0x88处的值为name

然后再就是循环加密啦

首先获取第一个字符,然后转换为ascii(n变为6E),

后面不懂  以后提高点再战

 

(972) 320-3791

这一篇主要介绍栈帧的调试,下面是源程序:

然后关闭vs编译优化,得到可执行程序。运行调试,找到main函数

401020是main函数的入口,push ebp,mov ebp,esp;是帧栈的典型结构。sub esp,0x8  是因为需要流出8个字节给局部变量啊a,b后面,此时ebp为12ff40,ebp-8为12ff38(对应local.2),ebp-4为12ff3c(对应local.1),分别赋值1,2.然后把local.1入栈,local.2入栈,然后调用401000的函数,这两个入栈应该是调用函数的参数,下面看401000出的函数(也就是add函数)

注意:在进入一个函数之前会把调用函数的下一个地址压入栈中,也就是函数的返回地址。

然后执行x+y,然后将结果存在eax寄存器中,然后返回,此时将esp+8,删除掉add函数的参数,将eax也就是add返回结果压入栈,然后参数“%d\n”,这应该是printf的参数

调用完之后,已经打印了结果,然后将printf的参数出栈。

注意xor eax,eax设置返回值0

然后结束。

对着运行一遍收获很大吧!继续加油

 

7803177854

首先来看一下这个程序,打开只有一个确定可以点击,猜测有MessageBox 有提示框,然后点击确定之后发生另一个,所以应该有一个跳转。

然后用Ollydbg打开调试,打开后代码如下

可以看出首先把0x402000内存中的入栈,然后再把0x402012内存中入栈。

此时栈内情况如图:

然后弹出对话框如图一,等待按确认,先前栈内应该是MessageBox的参数。

然后按确定,然后继续运行,又入栈了一个根目录。然后继续调用一个函数,这个函数最后的返回结果应该会对之后产生影响。之后执行比较eax,esi的值相等则跳到对的去执行,否则返回到错误的执行。然后调用00401050退出。

所以只要在比较完之后直接跳到对的去执行即可。

如图所示

第二种思路,既然原因是由eax,esi不相等导致的,那么可以将其中增减指令替换为nop,使得eax与esi相等即可绕过。

替换为两个nop,结果也可以完成。另存也可以完成。

本节到此为止。

 

 

 

逆向工程核心原理(二)-大小端、基本寄存器,栈

刚刚在外边吃完饭回来,继续写,涨这肚子写!这两节内容不是太多吧!

计算机中,字节序主要分为小端序和大端序。

BYTE   b=0x12;

WORD w=0x1234;

DWORD  dw=0x12345678;

char str[]=”abcde”;

TYPE                              大端序                            小端序

BYTE                                 [12]                                [12]

WORD                               [12][34]                          [34][12]

DWORD                            [12][34][56][78]               [78][56][34][12]

char[]                                 [61][62][63][64][65]         [61][62][63][64][65]

 

数据类型为BYTE时,其长度为一个字节,保存这样的数据,无论采用大端还是小端字节序都一样。

字符数组在内存中是连续的,此时向字符数组存放数据,无论采用大端序还是小端序,存储顺序都相同。

再就是基本寄存器:

ESP :ss段中栈内数据指针,扩展基址指针寄存器。

ESI: 源变址寄存器

EDI:目的变址寄存器

ESP:栈指针寄存器

EFLAGS:

ZF:零标志   OF:溢出标志    CF:进位标志

 

EIP:指令指针寄存器

栈没啥可讲的,先进后出

这两节基本内容就这些吧!慢点加油看吧!

 

9512163407

最近开始看《逆向工程核心原理》这本书吧,韩国人写的,前面就不说啦!直接从有内容的地方开始吧!

首先快速查找指定代码的四种方法:

1、代码执行法,就是一点点执行

2、字符串检索

3、API检索  在调用代码中设置断点

4、API 检索 在API代码找那个设置断点

打补丁修改字符串

原本是这样 弹出一个对话框

然后通过字符串定位,知道hello world的地址,然后修改

可以看见已经被修改成了Hello hangzhou!然后继续运行

可以保存为可执行文件,然后就直接运行啦!

 

可以看见已经被更改,这就是打补丁的方法,这是通过直接修改字符缓冲区完成的,然后我们还可以通过在其他内存区域创建一个新的字符串传递给函数达到目的!但是要选那个区域了,这个书上说先随便选个区域!

然后 F9可以看到

已经完成了变成了我想说的话。。。.

 

 

 

rectitic

       现在开始准备每天看一个DEFCON,或者BlackHat的相关方面的视频吧,这样既能学到专业方面东西,又可以练听力,这是极好的。哈哈,好啦,开始今天的“演讲”
          今天看的是一个攻击无人机的。
       无人机的一个基本通信结构,Remote Control与Telemetry Box是分离的,一般有两种通信链路,一个是Remote Control直接与UAV进行通信(2.4Ghz远程控制链路)这个链控制范围比较短,只有100m左右。另一个链路就是Telemetry Box通过Wifi链路与平板或者手机上的软件进行通信,然后通过XBee与UAV进行通信,这个链路较长,距离达到2000m左右。该研究中,Wifi是通过WEP进行加密的,很容易遭到破解。
       第一个攻击面,通过破解Wifi可以使攻击者直接与Telemetry Box进行通信。
  
       第二个攻击面,XBee,芯片有地址,暴力破解比较费时,通过查看文档发现有三个特性。
    
         第一个API Mode可以修改包的目的地址,第二个通过广播,然后会收到UAV和Telemetry Box的回应,然后就知道他们的地址的,这不骗人家的啊!!!第三个就是远程命令,这个就比较邪恶了,通过远程改掉UAV还有Telemetry Box的目的地址,然后又你们现在发送的消息就都到我这来了。明明你们两个好好的,我非要来个第三者插足。
    
          这就是传说中的中间人攻击啦!
          那么现在我们可以在XBee中发消息,写消息啦。但是这些数据流是什么意思啦?那么就要逆向APP,然后搞懂每个指令的意思啦。然后就可以调戏无人机啦!
          所以通信要加密,而且Wifi不要用弱弱的WEP啦!不过加密位置不对也不行。还有的会带来延迟啊!
           一戳去YouTube看视频
          (224) 828-7603