linux里文件如何进行文件脱壳

linux里文件如何进行文件脱壳,第1张

 linux很少有需要crack的软件,所以最近总是自娱自乐。自己写的软件自己破着玩但是由于都是知道自己的手段,没有什么意思。真的希望有高手们写些crackme for linux 。

最近看了看windows的脱壳大致的理解了脱壳的原理,之前没有怎么接触脱壳,通常只是选择没有壳的软件看看。在linux下的壳没有找到几个。只找到了一个upx的壳,在windows下是个弱壳。实际上在linux下面也是弱壳,完全可以使用"upx -d"的命令解决问题。但我总是喜欢自己手动的。呵呵....纯属于自娱自乐。

ok,开始我们的linux的upx的脱壳之旅.........

我在选择工具的时候花了很多时间,忽然发现GDB在upx面前是那么的苍白无力...也终于知道为什么有人说GDB不适合做逆向了...虽然软件在调试器里可以正常于运行,正常下断。但是根本无法查看反汇编的代码.......。

无奈无奈....使用传说中最好的工具 IDA 为此我特地简单的学习了一下IDC脚本的使用方法...

没有什么资料可以参考,是一件很不愉快的事情,因为不知道能不能成功。不管了,一步一步来吧...

我用“upx -d“ 脱出了原来的文件,发现文件是全的,没有任何部分丢失,所以我相信这些文件会出现在进程空间的某个时间的某个角落,这个很大的坚定了我手动脱壳的信心(但是实际上到这篇文章的结尾我也没有能够在找到完整的程序文件,但我相信理论上内存空间中应该会出现完整的文件的...)。

我的加壳软件是我上次文章中用到做外挂的mines(扫雷游戏)。先找到了upx-3.03-i386_linux 软件 附件中我会给出的免的度这篇文章的人去寻找了。

对我们目标软件加壳,命令如下,的确是个好用的压缩壳软件,直接有54%的压缩律。

代码:

[jun@beijihuCom dumpupx]$Content$nbsp./upx mines

Ultimate Packer for eXecutables

Copyright (C) 1996 - 2008

UPX 3.03Markus Oberhumer, Laszlo Molnar &John Reiser Apr 27th 2008

File size Ratio Format Name

-------------------- ------ ----------- -----------

13960 -> 7556 54.13% linux/elf386 mines

Packed 1 file.

[jun@beijihuCom dumpupx]$Content$nbsp

好了,我们开始调试他了,加了壳以后,一般的调试软件已经对他无能为力了...

实验一下GDB 和 DDD 的效果...以及objdump

readelf还可以正常使用,(仅限于一部分功能.呵呵,不详谈了...)

代码:

[jun@beijihuCom dumpupx]$Content$nbspreadelf -e ./mines

ELF Header:

Magic: 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00

Class: ELF32

Data: 2’s complement, little endian

Version: 1 (current)

OS/ABI:UNIX - Linux

ABI Version: 0

Type: EXEC (Executable file)

Machine: Intel 80386

Version: 0x1

Entry point address: 0xc02598

Start of program headers: 52 (bytes into file)

Start of section headers: 0 (bytes into file)

Flags: 0x0

Size of this header: 52 (bytes)

Size of program headers: 32 (bytes)

Number of program headers: 2

Size of section headers: 40 (bytes)

Number of section headers: 0

Section header string table index: 0

There are no sections in this file.

Program Headers:

Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align

LOAD 0x000000 0x00c01000 0x00c01000 0x01d60 0x01d60 R E 0x1000

LOAD 0x0002fc 0x0804b2fc 0x0804b2fc 0x00000 0x00000 RW 0x1000

上面的输出,我们可以发现他的入口点是0xc02598 这个入口点已经和GCC编译出来的程序大不一样了。实际上重“upx -d“脱出来的效果来看,原来的入口点基本上是不会改变的,也就是说我们的手动脱壳的时候软件的入口点,加载方式都是和未加壳的软件是一样的...这一点又为我们的脱壳成功,增加了砝码..

继续....gdb 调试一下

代码:

(gdb) b *0xc02598

Breakpoint 1 at 0xc02598

(gdb) r

Starting program: /home/jun/Crack/dumpupx/mines

warning: shared library handler failed to enable breakpoint

(no debugging symbols found)

Breakpoint 1, 0x00c02598 in ?? ()

(gdb) disassemble

No function contains program counter for selected frame.

(gdb)

gdb看不反汇编代码,晕了都不知道下一步的 *** 作是什么....看来是没有什么用了

祭起传说中的逆向利器IDA.学西习了一下,简单 *** 作,我开始了调试之旅.

代码:

[jun@beijihuCom dumpupx]$Content$nbspidal ./mines

等到加载完成,会停在入口处,呵呵在光标在call上直接按F4,程序运行,停到了入口出

单步运行...实际上我没有什么办法,不知道有什么下好的方法下断点,可以使这个简单方法调试...

这边我是这么想的,upx是压缩壳,当他把执行权交给原目标程序的时候,必定会有一个大的跳转,好多新手在windows脱壳,都是以这个为oep的标准的。linux应该也不会例外的...

F8单步到0xc025c8 跳到 oxc025d1 在 0xc025d3 又会跳回来。显然是个循环。不在循环里浪费时间了。我们向下找找,下面有个retn返回。光标移到上面F4。实际上没有什么把握。只是蒙的,结果很好,没有飞走.F8单步到了这里

继续单步,retn到一个地方

不详细分析了往下看。翻阿翻,不会这么巧吧.看见了 jmp dword ptr [edi]跳转,这不会是传说中的大跳吧。

不管直接F4到这里...哈哈很成功。

单步一下,跳到了这里。

不懂代码的具体含义,但是明显不是程序的入口...为什么?单步....继续

看到这里我忽然顿悟,这里是在做ld连接,不能让他运行了,很可能是为了我们目标程序的运行进行共享库的连接..会修改我们内存中的映像文件。这样我们dump出来的就不是原来的干净程序,因为我们没有修复工具,比起windows里面的PE修复要麻烦多了.....所以赶紧dump出来...

用来dump映像的idc脚本

代码:

#include <idc.idc>

#define PT_LOAD 1

#define PT_DYNAMIC 2

static main(void)

{

auto ImageBase,StartImg,EndImg//基址 08048000

auto e_phoff

auto e_phnum,p_offset//paddr 0xc 地址,pmemsz ox14大小,p_offset 0x4

auto i,dumpfile

ImageBase=0x08048000

StartImg=0x08048000

EndImg=0x0

Message("%8x\n",Dword(ImageBase))

if (Dword(ImageBase)==0x7f454c46 || Dword(ImageBase)==0x464c457f )

{

if(dumpfile=fopen("./dumpfile","w+"))

{

e_phoff=ImageBase+Word(ImageBase+0x1c)

e_phnum=Word(ImageBase+0x2c)

for(i=0i<e_phnumi++)

{

if (Dword(e_phoff)==PT_LOAD || Dword(e_phoff)==PT_DYNAMIC)

{ p_offset=Dword(e_phoff+0x4)

StartImg=Dword(e_phoff+0xc)

EndImg=Dword(e_phoff+0xc)+Dword(e_phoff+0x14)

dump(dumpfile,StartImg,EndImg,p_offset)

Message("dump LOAD%d ok.\n",i)

}

e_phoff=e_phoff+0x20

}

fseek(dumpfile,0x30,0)

fputc(0x00,dumpfile)

fputc(0x00,dumpfile)

fputc(0x00,dumpfile)

fputc(0x00,dumpfile)

fclose(dumpfile)

}else Message("dump err.")

}

}

static dump(dumpfile,startimg,endimg,offset)

{ auto i

auto size

size=endimg-startimg

fseek(dumpfile,offset,0)

for ( i=0i <sizei=i+1 )

{

fputc(Byte(startimg+i),dumpfile)

}

}

改变文件的属性,让他可以运行。

代码:

[jun@beijihuCom dumpupx]$Content$nbspsu

口令:

[root@beijihuCom dumpupx]# chmod 755 ./dumpfile

[root@beijihuCom dumpupx]# ./dumpfile

程序运行的很好..

总结:第一次在linux下手动脱壳,看上去文章中写的很轻松,实际上在之前做了很多工作。包括ELF的加载等等。还有我发现如果程序的节表头程序也能很好的运行,什么的..

另外,我之调试的时候,实际经过很多挫折...没有足够的经验嘛...不过些文章,截图的时候都很顺利..呵呵.共勉........

Binder主要能提供以下一些功能:

用驱动程序来推进进程间的通信。

通过共享内存来提高性能。

为进程请求分配每个进程的线程池。

针对系统中的对象引入了引用计数和跨进程的对象引用映射。

进程间同步调用。

Android Binder设计与实现 – 设计篇:

目前linux支持的IPC包括传统的管道、System V IPC、即消息队列/共享内存/信号量,以及socket中只有socket支持Client-Server的通信方式。

当然也可以在这些底层机制上架设一套协议来实现Client-Server通信,但这样增加了系统的复杂性,在手机这种条件复杂,资源稀缺的环境下可靠性也难以保证。

另一方面是传输性能:

socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。

消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,

至少有两次拷贝过程。共享内存虽然无需拷贝,但控制复杂,难以使用。

还有一点是出于安全性考虑:

Android作为一个开放式,拥有众多开发者的平台,应用程序的来源广泛,确保智能终端的安全是非常重要的。

终端用户不希望从网上下载的程序在不知情的情况下偷窥隐私数据,连接无线网络,长期 *** 作底层设备导致电池很快耗尽等等。传统IPC没有任何

安全措施,完全依赖上层协议来确保。首先传统IPC的接收方无法获得对方进程可靠的UID/PID(用户ID/进程ID),从而无法鉴别对方身份。

Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。使用传统IPC只能由用户在数据包里填入UID/PID,

但这样不可靠,容易被恶意程序利用。可靠的身份标记只有由IPC机制本身在内核中添加。其次传统IPC访问接入点是开放的,无法建立私有通道。

比如命名管道的名称、system V的键值、socket的ip地址或文件名都是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法

阻止恶意程序通过猜测接收方地址获得连接。

基于以上原因,Android需要建立一套新的IPC机制来满足系统对通信方式,传输性能和安全性的要求,这就是Binder。

Binder基于 Client-Server通信模式,传输过程只需一次拷贝,为发送发添加UID/PID身份,既支持实名Binder也支持匿名Binder,安全性高。

面向对象的 Binder IPC:

面向对象思想的引入将进程间通信转化为通过对某个Binder对象的引用调用该对象的方法,而其独特之处在于Binder对象是一个

可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍布于系统的各个进程之中。最诱人的是,这个引用和java里引用

一样既可以是强类型,也可以是弱类型,而且可以从一个进程传给其它进程,让大家都能访问同一Server,就像将一个对象或引用赋

值给另一个引用一样。Binder模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于同一个面向对象的程序之中。

面向对象只是针对应用程序而言,对于Binder驱动和内核其它模块一样使用C语言实现,没有类和对象的概念。

Binder驱动为面向对象的进程间通信提供底层支持。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7165428.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-02
下一篇 2023-04-02

发表评论

登录后才能评论

评论列表(0条)

保存