病毒基础系列

上传人:F****n 文档编号:99481751 上传时间:2019-09-19 格式:DOC 页数:7 大小:27KB
返回 下载 相关 举报
病毒基础系列_第1页
第1页 / 共7页
病毒基础系列_第2页
第2页 / 共7页
病毒基础系列_第3页
第3页 / 共7页
病毒基础系列_第4页
第4页 / 共7页
病毒基础系列_第5页
第5页 / 共7页
点击查看更多>>
资源描述

《病毒基础系列》由会员分享,可在线阅读,更多相关《病毒基础系列(7页珍藏版)》请在金锄头文库上搜索。

1、病毒基础系列-API函数地址的获取关键字 API,病毒,函数,地址 前言: 病毒没有什么可怕的,也并不象想像中的复杂,玩汇编的人如果没有看过病毒?简直是白活一遭.病毒就象是双刃剑,恶意使用就会带来恶果,我本人对于此类行为深恶痛绝!我们研究不是为了破坏而是为了知己知彼,另外病毒中确实也有很多高超的技巧值得我们学习,这才是我们的目的所在,我绝没有教唆人犯罪的意图而且就我的水平来讲也远达不到. 在研究病毒之前有几项基础知识要了解: 1)ring0的获取,可参见我翻译的一篇ring0的文章,另外这些资料internet上也很多. 2)Seh的知识,可参见我写的 3)PE结构的知识,ZouDan大侠的论

2、文,IczeLion的PE教学和载 LUEVELSMEYER的PE文件格式,最为重要! 4)文件读写的基本知识,主要是CreateFileA,ReadFile,WriteFile,CreateFileMapping.等文件读写知识,如果你还不了解,最好先学学win32ASM的基础知识. 5)PolyEngine.MetaMorphism等基本概念 6)anti-debug的一些概念 7)有关MBR,FAT等知识,对了解一些老Virus有用. 下面我有的一些tips,可能会对理解病毒有所帮助.另外这些技术在加壳类软件中也很常见. Tip1: API函数地址的获取 这是一个老题目了,如果我们不用任

3、何引入库,能否在程序中调用api函数?当然可以!方法有很多,你可能早就知道了,如果你已经了解了,就此打住,这是为还不了解这一技术而写.另外这也是病毒必用的技巧之一,如果你对病毒技术感兴趣,接着看下去. 这里假设你了解PE的基本结构,如果还不懂,找点资料来看看,到处都是呦. 在几乎每个病毒的开头都用下面的语句: call deltadelta: pop ebp sub ebp,offset delta mov dword ptr ebp+offset appBase,ebp 让我们考虑一下程序的执行情况,如果下面的代码由编译器自动编译连接,那么程序执行的基址一般是h,如果是在Nt下执行,那么基址

4、可能不同,比如从h开始,不用担心,操作系统的Loader会自动为你重定位.但是这里停下来让我们看一下,如果你想要把这段代码附加到其他程序的后面并想让其正确执行的话,就不是那么简单了,因为你的代码可能要从h处开始执行,而在没有得到宿主程序许可的情况下期望操作系统自动为你修正偏移错误是不可能的,既然有非常的目的,就得费点力气,自己搞定重定位.而上面的代码就是首先得到eip指针(保存CPU要执行的下一个指令的地址),也是delta在程序执行时的实际偏移(用 pop ebp ,把它存入ebp中),然后减掉代码头到delta的偏移从而得到你的代码的真正基址,后面对于偏移的操作都应以这个真正的偏移为准.这

5、就是你上面看到的.如果不明白,就仔细想一下,nothing difficult!下面的例子演示了这一点,并没有全部重定位,因为这只是技术演示. 现在回到本文的正式内容,要想获得api的地址,得首先获得诸如kernel32.dll,user32.dll的基址,然后再找到真正的函数地址.如何获得基址和函数地址呢呢?有几种方法 1)搜寻宿主的引入表获得GetModuleHandleA函数和GetProcAddress的地址,然后通过他返回系统dll的基址.因为很多程序都要使用这两个函数,因此在某些情况下是可行的,如果宿主没有使用GetProcAddress,那你就不得不搜寻Export表了. 2)直

6、接获得kernel32.dll的基址,然后再搜寻Export表获得GetProcAddress和LoadLibraryA的地址,然后我们就能得到任何想调用的函数地址. 3)硬编码调用函数,比如在9X下GetModuleHandleA的地址一般是BFF7*. 第一种和第三种方法存在兼容性的问题,假如宿主没有调用GetModuleHandleA,那么你就不能获得基址,别的就更别想了.硬编码问题更大,操作系统不同则不能运行了,比如9X下可能在有些计算机上正常,但肯定不能在Nt/2K下运行. 第二种方法兼容性比较好,因此作以介绍. 一点背景:在PE Loader装入我们的程序启动后堆栈顶的地址是程序的

7、返回地址,肯定在Kernel中(当然是在没有动堆栈的情况下)! 因此我们可以得到这个地址,然后向低地址缩减验证一直到找到模块的起始地址,验证条件为PE头不能大于4096bytes,PE header的ImageBase(文件的优先装载地址)值应该和当前指针相等(不是我们的程序,而是那个kernel32.dll),嘿嘿,简单吧,而且兼容性还不错. 要获得Api的地址首先要获得GetModuleHandle,LoadLibraryA,GetProcAddress的地址,这是通过搜索Export表来实现的,具体原理就是PE Export表的结构,如果了解了PE结构就很简单了.下面我加了点注释,没有优

8、化代码,是为了便于理解. 好,这一部分结束了! 这是一个例子,没有用任何预引入函数,加了一条invoke InitCommonControls是为了在2K下也能正常运行,否则不能在2K下不加载!程序得到MessageBoxA的地址然后显示一个消息框,目的在于演示,重要部分加了注释,很好明白.注意连接时加入/section:.text,RWE选项。.586.model flat, stdcalloption casemap :none ; case sensitiveinclude c:hdhd.hinclude c:hdmac.h ;- GetApiA proto :DWORD,:DWORD

9、;-.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,0sLoadLibrary db LoadLibraryA,0 sMessageB

10、oxA db MessageBoxA,0 aGetModuleHandle dd 0aGetProcAddress dd 0aExitProcess dd 0aLoadLibrary dd 0aMessageBoxA dd 0 u32 db User32.dll,0k32 db Kernel32.dll,0 sztit db By Hume,2002,0szMsg0 db Hey,Hope U enjoy it!,0;- _Start: invokeInitCommonControls call deltadelta: pop ebp ;得到delta地址 sub ebp,offset del

11、ta ;因为在其他程序中基址可能不是默认的所以需要重定位 mov dword ptr ebp+offset appBase,ebp ;呵呵仔细想想 mov ecx,esp ;返回地址 xor edx,edxgetK32Base: dec ecx ;逐字节比较验证 mov dx,word ptr ecx+IMAGE_DOS_HEADER.e_lfanew ;就是ecx+3ch test dx,0f000h ;Dos Header+stub不可能太大,超过4096byte jnz getK32Base ;加速检验 cmp ecx,dword ptr ecx+edx+IMAGE_NT_HEADERS

12、.OptionalHeader.ImageBase jnz getK32Base ;看Image_Base值是否等于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

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 教学/培训

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号