病毒基础系列文档格式.docx

上传人:b****6 文档编号:18095856 上传时间:2022-12-13 格式:DOCX 页数:8 大小:18.34KB
下载 相关 举报
病毒基础系列文档格式.docx_第1页
第1页 / 共8页
病毒基础系列文档格式.docx_第2页
第2页 / 共8页
病毒基础系列文档格式.docx_第3页
第3页 / 共8页
病毒基础系列文档格式.docx_第4页
第4页 / 共8页
病毒基础系列文档格式.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

病毒基础系列文档格式.docx

《病毒基础系列文档格式.docx》由会员分享,可在线阅读,更多相关《病毒基础系列文档格式.docx(8页珍藏版)》请在冰豆网上搜索。

病毒基础系列文档格式.docx

方法有很多,你可能早就知道了,如果你已经了解了,就此打住,这是为还不了解这一技术而写.另外这也是病毒必用的技巧之一,如果你对病毒技术感兴趣,接着看下去.

这里假设你了解PE的基本结构,如果还不懂,找点资料来看看,到处都是呦.

在几乎每个病毒的开头都用下面的语句:

call 

delta

delta:

pop 

ebp 

sub 

ebp,offsetdelta 

mov 

dwordptr[ebp+offsetappBase],ebp

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

1)搜寻宿主的引入表获得GetModuleHandleA函数和GetProcAddress的地址,然后通过他返回系统dll的基址.因为很多程序都要使用这两个函数,因此在某些情况下是可行的,如果宿主没有使用GetProcAddress,那你就不得不搜寻Export表了.

2)直接获得kernel32.dll的基址,然后再搜寻Export表获得GetProcAddress和LoadLibraryA的地址,然后我们就能得到任何想调用的函数地址.

3)硬编码调用函数,比如在9X下GetModuleHandleA的地址一般是BFF7****.

第一种和第三种方法存在兼容性的问题,假如宿主没有调用GetModuleHandleA,那么你就不能获得基址,别的就更别想了...硬编码问题更大,操作系统不同则不能运行了,比如9X下可能在有些计算机上正常,但肯定不能在Nt/2K下运行...

第二种方法兼容性比较好,因此作以介绍.

一点背景:

在PELoader装入我们的程序启动后堆栈顶的地址是程序的返回地址,肯定在Kernel中(当然是在没有动堆栈的情况下)!

因此我们可以得到这个地址,然后向低地址缩减验证一直到找到模块的起始地址,验证条件为PE头不能大于4096bytes,PEheader的ImageBase(文件的优先装载地址)值应该和当前指针相等(不是我们的程序,而是那个kernel32.dll),嘿嘿,简单吧,而且兼容性还不错.

要获得Api的地址首先要获得GetModuleHandle,LoadLibraryA,GetProcAddress的地址,这是通过搜索Export表来实现的,具体原理就是PEExport表的结构,如果了解了PE结构就很简单了.下面我加了点注释,没有优化代码,是为了便于理解.

好,这一部分结束了!

这是一个例子,没有用任何预引入函数,加了一条invokeInitCommonControls是为了在2K下也能正常运行,否则不能在2K下不加载!

程序得到MessageBoxA的地址然后显示一个消息框,目的在于演示,重要部分加了注释,很好明白.

注意连接时加入/section:

.text,RWE选项。

.586

.modelflat,stdcall

optioncasemap:

none 

;

casesensitive

includec:

\hd\hd.h

\hd\mac.h

;

--------------

GetApiA 

proto 

:

DWORD,:

DWORD

--------------

.CODE

appBase 

dd?

k32Base 

lpApiAddrs 

label 

near

dd 

offsetsGetModuleHandle

offsetsGetProcAddress

offsetsExitProcess

offsetsLoadLibrary

0

sGetModuleHandle 

db"

GetModuleHandleA"

0

sGetProcAddress 

db"

GetProcAddress"

sExitProcess 

ExitProcess"

sLoadLibrary 

LoadLibraryA"

0

sMessageBoxA 

MessageBoxA"

aGetModuleHandle 

dd0

aGetProcAddress 

dd0

aExitProcess 

aLoadLibrary 

aMessageBoxA 

dd0

u32 

User32.dll"

k32 

Kernel32.dll"

sztit 

ByHume,2002"

szMsg0 

Hey,HopeUenjoyit!

"

-----------------------------------------

__Start:

invokeInitCommonControls

得到delta地址

因为在其他程序中基址可能不是默认的所以需要重定位

dwordptr[ebp+offsetappBase],ebp 

呵呵仔细想想

mov 

ecx,[esp] 

返回地址

xor 

edx,edx

getK32Base:

dec 

ecx 

逐字节比较验证

dx,word 

ptr[ecx+IMAGE_DOS_HEADER.e_lfanew] 

就是ecx+3ch

test 

dx,0f000h 

DosHeader+stub不可能太大,超过4096byte

jnz 

getK32Base 

加速检验

cmp 

看Image_Base值是否等于ecx即模块起始值,

[ebp+offsetk32Base],ecx 

如果是,就认为找到kernel32的Base值

lea 

edi,[ebp+offsetaGetModuleHandle]

esi,[ebp+offsetlpApiAddrs]

lop_get:

lodsd

eax,0

jz 

End_Get

push 

eax

dwordptr[ebp+offsetk32Base]

callGetApiA 

获取API地址 

stosd

jmp 

lop_get

End_Get:

offsetu32

dwordptr[ebp+offsetaLoadLibrary] 

在程序空间加载User32.dll

EDX,[EBP+OFFSETsMessageBoxA]

edx

eax,dwordptr[ebp+aGetProcAddress] 

用GetProcAddress获得MessageBoxA的地址

eax 

调用GetProcAddress

40h+1000h 

style

offsetsztit 

title

offset 

消息内容

一个消息框产生了...嘿嘿

有理由为此高兴吧,因为我们没有预先引入

@@:

这些函数

[ebp+aExitProcess]

-----------------------------------------

K32_api_retrieve 

proc 

Base:

DWORD,sApi:

edx 

保存edx 

eax,eax 

此时esi=sApi

Next_Api:

edi=AddressOfNames

esi,sApi

edx

Match_Api_name:

bl,byte 

ptr[esi]

inc 

esi

bl,0

foundit

edx

eax,[edi+eax*4] 

AddressOfNames的指针,递增

add 

eax,Base 

注意是RVA,一定要加Base值

ptr[eax+edx] 

逐字符比较 

eax

Match_Api_name 

继续搜寻

eax 

不匹配,下一个api

loop 

Next_Api

no_exist 

若全部搜完,即未存在

foundit:

edx 

edx=AddressOfNameOrdinals

shl 

eax,1 

*2得到AddressOfNameOrdinals的指针

movzx 

eax,word 

ptr[edx+eax];

eax返回指向AddressOfFunctions的指针

ret

no_exist:

eax,eax

endp

proc 

DWORD,sApi:

DWORD

local 

ADDRofFun:

pushad

edi,Base

edi,IMAGE_DOS_HEADER.e_lfanew

edi,[edi] 

现在edi=offPE_HEADER

edi,Base 

得到IMAGE_NT_HEADERS的偏移 

ebx,edi

得到edi=IMAGE_EXPORT_DIRECTORY入口

eax,[edi+1ch] 

AddressOfFunctions的地址

eax,Base

ADDRofFun,eax

ecx=NumberOfNames

ecx,[edi+18h] 

edx,[edi+24h] 

edx,Base 

edx=AddressOfNameOrdinals

edi,[edi+20h]

invokeK32_api_retrieve,Base,sApi

ebx,ADDRofFun

eax,2 

要*4才得到偏移

eax,ebx

eax,[eax]

加上Base!

[esp+7*4],eax 

eax返回api地址

popad

endp

END__Start

------------------------------------------Endall

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 艺术

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

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