ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:19.20KB ,
资源ID:5364180      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5364180.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(WindowsAPI函数地址的获取.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

WindowsAPI函数地址的获取.docx

1、WindowsAPI函数地址的获取 API函数地址的获取 by Hume/前言: 病毒没有什么恐怖的,也并非象想像中的复杂,病毒就象是双刃剑,歹意利用就会带来恶果,我本人关于此类行为深恶痛绝!咱们研究不是为了破坏而是为了知己知彼,另外病毒中确实也有很多精湛的技术值得咱们学习,这才是咱们的目的所在,我绝没有指令人犯法的用意。 一点理论:这是一个老题目了,若是咱们不用任何引入库,可否在程序中挪用api函数?固然能够!方式有很多,你可能早就明白了,若是你已经了解了,就此打住,这是为还不了解这一技术而写.另外这也是病毒必用的技术之一,若是你对病毒技术感爱好,接着看下去. 那个地址假设你了解PE的大体结

2、构,若是还不懂,找点资料来看看,处处都是呦. 在几乎每一个病毒的开头都用下面的语句: call deltadelta: pop ebp sub ebp,offset delta mov dword ptr ebp+offset appBase,ebp 让咱们考虑一下程序的执行情形,若是下面的代码由编译器自动编译连接,那么程序执行的基址一般是400000h,若是是在Nt下执行,那么基址可能不同,比如从100000h开始,不用担忧,操作系统的Loader会自动为你重定位.可是那个地址停下来让咱们看一下,若是你想要把这段代码附加到其他程序的后面并想让其正确执行的话,就不是那么简单了,因为你的代码可能

3、要从555588h处开始执行,而在没有取得宿主程序许可的情形下期望操作系统自动为你修正偏移错误是不可能的,既然有超级的目的,就得费点力气,自己弄定重定位.而上面的代码确实是第一取得eip指针,也是delta在程序执行时的实际偏移,然后减掉代码头到delta的偏移从而取得你的代码的真正基址,后面关于偏移的操作都应以那个真正的偏移为准.这确实是你上面看到的.若是不明白,就认真想一下,nothing difficult!下面的例子演示了这一点,并没有全数重定位,因为这只是技术演示. 此刻回到本文的正式内容,要想取得api的地址,得第一取得诸如,的基址,然后再找到真正的函数地址.如何取得基址和函数地址

4、呢呢?有几种方式 1)搜寻宿主的引入表取得GetModuleHandleA函数和GetProcAddress的地址,然后通过他返回系统dll的基址.因为很多程序都要利用这两个函数,因此在某些情形下是可行的,若是宿主没有利用GetProcAddress,那你就不能不搜寻Export表了. 2)直接取得的基址,然后再搜寻Export表取得GetProcAddress和LoadLibraryA的地址,然后咱们就能够取得任何想挪用的函数地址. 3)硬编码挪用函数,比如在9X下GetModuleHandleA的地址一样是BFF7*. 第一种和第三种方式存在兼容性的问题,假设宿主没有挪用GetModule

5、HandleA,那么你就不能取得基址,别的就更别想了.硬编码问题更大,操作系统不同那么不能运行了,比如9X下可能在有些运算机上正常,但确信不能在Nt/2K下运行. 第二种方式兼容性比较好,因此作以介绍. 一点背景:在PE Loader装入咱们的程序启动后堆栈顶的地址是是程序的返回地址,确信在Kernel中! 因此咱们能够取得那个地址,然后向低地址缩减验证一直到找到模块的起始地址,验证条件为PE头不能大于4096bytes,PE header的ImageBase值应该和当前指针相等,嘿嘿,简单吧,而且兼容性还不错. 要取得Api的地址第一要取得GetModuleHandle,LoadLibrar

6、yA,GetProcAddress的地址,这是通点注释,没有优化代码,是为了便于明白得. 好,这一部份终止了! 代码举例: 这是一个例子,没有效任何预引入函数,加了一条invoke InitCommonControls是为了在2K下也能正常运行,不然不能在2K下不加载! 程序取得MessageBoxA的地址然后显示一个消息框,目的在于演示,重要部份加了注释,专门好明白.注意连接时加入/section:.text,RWE选项。.586.model flat, stdcalloption casemap :none ; case sensitiveinclude c:hdinclude c:hd

7、;- GetApiA proto :DWORD,:DWORD ;-.CODEappBase dd ?k32Base dd ? lpApiAddrs label near dd offset sGetModuleHandle dd offset sGetProcAddress dd offset sExitProcess dd offset sLoadLibrary dd 0 sGetModuleHandle db GetModuleHandleA,0sGetProcAddress db GetProcAddress,0sExitProcess db ExitProcess,0sLoadLibr

8、ary db LoadLibraryA,0 sMessageBoxA db MessageBoxA,0 aGetModuleHandle dd 0aGetProcAddress dd 0aExitProcess dd 0aLoadLibrary dd 0aMessageBoxA dd 0 u32 db ,0k32 db ,0 sztit db By Hume,2002,0szMsg0 db Hey,Hope U enjoy it!,0;- _Start: invokeInitCommonControls call deltadelta: pop ebp ;取得delta地址 sub ebp,o

9、ffset delta ;因为在其他程序中基址可能不是默许的因此需要重定位 mov dword ptr ebp+offset appBase,ebp ;呵呵认真想一想 mov ecx,esp ;返回地址 xor edx,edxgetK32Base: dec ecx ;逐字节比较验证 mov dx,word ptr ecx+ ;确实是ecx+3ch test dx,0f000h ;Dos Header+stub不可能太大,超过4096byte jnz getK32Base ;加速查验 cmp ecx,dword ptr ecx+edx+ jnz getK32Base ;看Image_Base值是

10、不是等于ecx即模块起始值, mov ebp+offset k32Base,ecx ;若是是,就以为找到kernel32的Base值 lea edi,ebp+offset aGetModuleHandle lea esi,ebp+offset lpApiAddrslop_get: lodsd cmp eax,0 jz End_Get push eax push dword ptr ebp+offset k32Base callGetApiA ;获取API地址 stosd jmp lop_getEnd_Get: push offset u32 call dword ptr ebp+offset

11、aLoadLibrary ;在程序空间加载 lea EDX,EBP+OFFSET sMessageBoxA push edx push eax mov eax,dword ptr ebp+aGetProcAddress ;用GetProcAddress取得MessageBoxA的地址 call eax ;挪用GetProcAddress push 40h+1000h ;style push offset sztit ;title push offset szMsg0 ;消息内容 push 0 call eax ;一个消息框产生了.嘿嘿 ;有理由为此快乐吧,因为咱们没有预先引入: ;这些函数 p

12、ush 0 call ebp+aExitProcess;-K32_api_retrieve proc Base:DWORD ,sApi:DWORD push edx ;保留edx xor eax,eax ;现在esi=sApiNext_Api: ;edi=AddressOfNames mov esi,sApi xor edx,edx dec edxMatch_Api_name: mov bl,byte ptr esi inc esi cmp bl,0 jz foundit inc edx push eax mov eax,edi+eax*4 ;AddressOfNames的指针,递增 add

13、eax,Base ;注意是RVA,必然要加Base值 cmp bl,byte ptr eax+edx ;逐字符比较 pop eax jz Match_Api_name ;继续搜寻 inc eax ;不匹配,下一个api loop Next_Api jmp no_exist ;假设全数搜完,即未存在foundit: pop edx ;edx=AddressOfNameOrdinals shl eax,1 ;*2取得AddressOfNameOrdinals的指针 movzx eax,word ptr edx+eax ;eax返回指向AddressOfFunctions的指针 retno_exis

14、t: pop edx xor eax,eax retK32_api_retrieve endp;- GetApiA proc Base:DWORD,sApi:DWORD local ADDRofFun:DWORD pushad mov edi,Base add edi, mov edi,edi ;此刻edi=off PE_HEADER add edi,Base ;取得IMAGE_NT_HEADERS的偏移 mov ebx,edi mov edi,edi+ add edi,Base ;取得edi=IMAGE_EXPORT_DIRECTORY入口 mov eax,edi+1ch ;AddressO

15、fFunctions的地址 add eax,Base mov ADDRofFun,eax ;ecx=NumberOfNames mov ecx,edi+18h mov edx,edi+24h add edx,Base ;edx=AddressOfNameOrdinals mov edi,edi+20h add edi,Base ;edi=AddressOfNames invokeK32_api_retrieve,Base,sApi mov ebx,ADDRofFun shl eax,2 ;要*4才取得偏移 add eax,ebx mov eax,eax add eax,Base ;加上Base

16、! mov esp+7*4,eax ;eax返回api地址 popad retGetApiA endp ;- END_Start;-End all API函数地址的获取(2) by Hume/一点理论API地址的获取方式很多,在API函数地址的获取(1)中介绍的方式事实上是有专门大缺点的,要求病毒定位的代码必需在Windows PE Loader加载程序后程序未改变esp的值之前执行,也确实是说若是程序进行了堆栈操作那么咱们无法保证esp中的地址还位于Kernel32中了,因此若是为了知足多态,EPO等对Vir代码入口的不同要求,必需寻觅其他良方。事实上,若是你了解Windows的SEH机制,

17、就会专门快找到一种简单的方式。那确实是遍历SEH链,在链中查找prev成员等于0xFFFFFFFF 的EXCEPTION_REGISTER结构(具体参见杂志的SEH介绍),该结构中handler值是所谓的系统异样处置例程,他老是位于中!依照这一特性,就能够够查找在内存中的基地址了。利用遍历SEH链表取得API的步骤如下:a)遍历SEH链,找到prev等于0xFFFFFFFF 的EXCEPTION_REGISTER结构,获取handler值;b)用类似方式1的方式查找的基地址;c)搜索的IAT,获取GetProcAddress的地址;d)以GetProceAddress获取其他任何Win32 A

18、PI函数地址。so easy。代码实例以下是该思路的实现的例子,敬请欣赏:;walking through the seh frame to get kernel32 addr;search to get GetProcAddress addr;then use base of kernel32 and GetProcAddress to;get all needed APIsinclude %fasinc%/include %fasinc%/.databuf rb 256fmt db Kernel32 base is: %X,0zTit db By Hume 2K2+,0hModulek32

19、 dd 0.codewapi_List:api_ends:StArT: xor esi,esi lods dword fs:esi : inc eax je F dec eax xchg esi,eax LODSD ;next seh_frame jmp near B : LODSD ;kernel32 func. ;compare if PE_hdr xchg esi,eax find_pe_header: dec esi xor si,si ;kernel32 is 64kb align mov eax,esi add ax,-MZ ;anti heuristic jne find_pe_

20、header mov edi,esi+ ;.e_lfanew mov eax,esi+edi add eax,-PE ;anti heuristic jne find_pe_header ; mov hModulek32,esi push esi ;esi=VA ;edi=RVA mov ebp,esi mov edi,ebp+edi+ push edi esi mov eax,ebp+edi+ mov edx,ebp+edi+ call F db GetProcAddress,0 : pop edi mov ecx,15 sub eax,4 next_: add eax,4 add edi,

21、ecx sub edi,15 mov esi,ebp+eax add esi,ebp mov ecx,15 repz cmpsb jnz next_ pop esi edi sub eax,ebp+edi+ shr eax,1 add edx,ebp movzx eax,word edx+eax add esi,ebp+edi+ add ebp,esi+eax*4 ;ebp= ;use GetProcAddress and hModule to get other func pop esi ;esi=kernel32 Base ;int 3 invoke ExitProcess,0 .end StArT

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1