-
-
[旧帖] [求助]我的添加新节的程序为什么总“不是win32程序” 0.00雪花
-
发表于: 2011-12-9 14:08 1698
-
我是照这个例子学的,但是修改后的程序,运行是“不是有效win32程序”
http://bbs.pediy.com/showthread.php?p=467116
还有一个问题是教程里要在OrigAddressOfEntry dd ?这里写入原入口地址,但段代码在.code段里,没法写入,是怎么回事
困苦
所有代码在这,请高手过目
.386
.model flat, stdcall
option casemap:none
;; ----------------------------------------
;; header file and lib file
;; ----------------------------------------
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include macro.asm
APPEND_SIZE equ 2000h
;常量
.const
g_szTargetFile db 'FirstWindow.exe',0
g_szNewSectionName db '.wxy',0
g_szErr db 'error',0
.data
g_dwNewSectionSize dd 0
.data?
szBuffer db MAX_PATH dup(?)
;代码段
.code
REMOTE_CODE_START equ this byte
call GetEip
GetEip:
pop ebx
sub ebx,offset GetEip
mov eax,[ebx + offset OrigAddressOfEntry]
jmp eax
OrigAddressOfEntry dd 401195h ;这个位置在.code里面写入不了,我改成一个直接的数
REMOTE_CODE_END equ this byte
REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START
PEAlign proc uses ecx edx, dwTarNum : DWORD, dwAlignTo : DWORD
mov ecx, dwAlignTo
mov eax, dwTarNum
xor edx, edx
div ecx ;eax/ecx
cmp edx, 0 ;edx保存余数
jz AlreadyAligned
inc eax ;如余数不为0,eax+1
AlreadyAligned:
mul ecx ;ecx乘eax
ret
PEAlign endp
_AddSection proc uses ebx ecx edx esi edi, pMem : LPVOID
LOCAL @dwNTHeader : LPVOID
LOCAL @dwFileAlig : DWORD ;文件对齐粒度
LOCAL @dwSecAlig : DWORD ;节对齐粒度
LOCAL @dwLastSecTbl : LPVOID ;原最后一个节区头尾部
LOCAL @kkk:DWORD
mov esi, pMem
;; 这里这个3ch是DOS头中e_lfanew的偏移
add esi, dword ptr [esi+3ch]
mov @dwNTHeader, esi ;保存nt头
assume esi : ptr IMAGE_NT_HEADERS
mov cx, word ptr [esi].FileHeader.NumberOfSections ;节数目保存cx
movzx ecx, cx ;ecx高位清零
inc word ptr [esi].FileHeader.NumberOfSections ;节数目+1
push dword ptr [esi].OptionalHeader.FileAlignment
pop @dwFileAlig ;保存文件对齐粒度
push dword ptr [esi].OptionalHeader.SectionAlignment ;保存节的对齐粒度
pop @dwSecAlig ;保存节的对齐粒度
;; 在NT头结构下面跟着的就是N个节表街头.加上NT头结构的长度就为第一个节表
add esi, sizeof IMAGE_NT_HEADERS
;; 在这里保存最后一个节表的偏移,因为一会在计算新节的RVA和offset要应用。
mov eax, sizeof IMAGE_SECTION_HEADER
mov ebx, ecx ;cx保存的是原节区数
imul ebx ;imul 有符号乘法,但操作数,ebx乘eax也就是:原节区数x节区头长度
add esi, eax ;文件头的位置+刚才算出来的原节区数x节区头长度=节区头尾部
push esi ;节区头尾部压入栈
mov eax,esi
sub eax,pMem
invoke wsprintf,addr szBuffer,CTXT("节区头尾部:%0.8x"),eax
invoke StdOut,offset szBuffer
invoke wsprintf,addr szBuffer,CTXT("节区头尾部:%0.8x"),esi
invoke StdOut,offset szBuffer
;; 这里保存了原最后节表的偏移,为了设置新节的地址做准备
sub esi, sizeof IMAGE_SECTION_HEADER ;原最后一个节区的起始位置
mov @dwLastSecTbl, esi ;原最后一个节区的起始位置保存起来
pop esi ;节区头尾部又压出来
assume esi : ptr IMAGE_SECTION_HEADER
;; 在新建的节表写节表名set section name
push esi ;压入栈保存
lea edi, [esi].Name1 ;节区头尾部地址放入edi
mov esi, offset g_szNewSectionName ;节区名指针放入esi,这里是".wow",0
CopySectionNameLoop:
lodsb ;块装入指令ptr byte [esi]->al
test al, al ;检测是不是零
jz EndCopySectionNameLoop ;是0完事
stosb ;块存储指令al->ptr byte [edi]
jmp CopySectionNameLoop
EndCopySectionNameLoop:
sub edi,4
invoke wsprintf,addr szBuffer,CTXT("写入节区名:%s"),edi
invoke StdOut,offset szBuffer
pop esi ;恢复esi
push 0E00000E0h ;0E00000E0h为设置可读可写可执行三个属性的或运算的值 20000000h | 40000000h | 80000000h
pop dword ptr [esi].Characteristics ;节属性
push g_dwNewSectionSize
pop dword ptr [esi].Misc.VirtualSize ;新节区尺寸
invoke wsprintf,addr szBuffer,CTXT("文件对齐粒度:%0.8x"),@dwFileAlig
invoke StdOut,offset szBuffer
invoke wsprintf,addr szBuffer,CTXT("节区对齐粒度:%0.8x"),@dwSecAlig
invoke StdOut,offset szBuffer
;新节区长度,我对齐粒度直接乘5
mov eax,@dwFileAlig
mov edx,2
imul edx
mov dword ptr [esi].SizeOfRawData, eax ;节在文件中对齐后的尺寸
mov eax, @dwLastSecTbl ;原文件,最后一个节表的起始位置
;设置新节的内存偏移和文件偏移需要上一节的一个信息
assume eax : ptr IMAGE_SECTION_HEADER
mov ecx, dword ptr [eax].VirtualAddress ;rva
add ecx, dword ptr [eax].Misc.VirtualSize ; ecx = new section rva
mov ebx, dword ptr [eax].PointerToRawData ;文件中的偏移
add ebx, dword ptr [eax].SizeOfRawData ; ebx = new section fva
mov dword ptr [esi].VirtualAddress, ecx ;放入新节表
mov dword ptr [esi].PointerToRawData, ebx
;------------------------------------------
;invoke wsprintf,addr szBuffer,CTXT("新节rva:%0.8x"), ecx
;invoke StdOut,offset szBuffer
;invoke wsprintf,addr szBuffer,CTXT("新节文件偏移:%0.8x"),ebx
;invoke StdOut,offset szBuffer
invoke PEAlign, ecx, @dwSecAlig ;为什么修正rva?知道了,以为后面的偏移要对齐
mov dword ptr [esi].VirtualAddress, eax
;; set section pointertorawdata
invoke PEAlign,ebx, @dwFileAlig
mov dword ptr [esi].PointerToRawData, eax
mov edx, @dwNTHeader ;pe头位置
assume edx : ptr IMAGE_NT_HEADERS
mov dword ptr [edx].OptionalHeader.SizeOfImage, eax ;在可选头改变内存中文件映像的尺寸
push dword ptr [esi].PointerToRawData ;新节在文件中的偏移压入栈
pop edi ;放入edi
add edi, pMem ;加上映像视图地址
mov edx, @dwNTHeader
;; clear the new sec
;; 在这里做一下清0工作ZeroMemory ,把新的节区里面清零
mov ecx, g_dwNewSectionSize
xor eax, eax
cld
rep stosb
invoke wsprintf,addr szBuffer,CTXT("新节节表的文件偏移:%0.8x"),esi
invoke StdOut,offset szBuffer
;; 此函数的返回值,新节节表的文件偏移
mov eax, esi
assume esi : nothing
assume eax : nothing
assume edx : nothing
ret
_AddSection endp
_CryptFile proc uses ebx ecx edx esi edi ,szFname : LPSTR
LOCAL @hFile : HANDLE
LOCAL @hMap : HANDLE
LOCAL @pMem : LPVOID
LOCAL @dwOrigFileSize : DWORD ;源文件长度
LOCAL @dwNTHeaderAddr : DWORD ;PE头地址
mov eax, offset REMOTE_CODE_END - offset REMOTE_CODE_START
mov g_dwNewSectionSize, eax
;invoke wsprintf,addr szBuffer,CTXT("新节区尺寸:%0.8x"),g_dwNewSectionSize
;invoke StdOut,offset szBuffer
;; open file
invoke CreateFile, szFname,\
GENERIC_WRITE + GENERIC_READ,\
FILE_SHARE_WRITE + FILE_SHARE_READ,\
NULL,\
OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL,\
0
mov @hFile,eax
.IF eax == INVALID_HANDLE_VALUE
invoke wsprintf,addr szBuffer,CTXT("文件创建失败:%0.8x"),0
invoke StdOut,offset szBuffer
ret
.ENDIF
invoke wsprintf,addr szBuffer,CTXT("文件创建成功:%0.8x "),0
invoke StdOut,offset szBuffer
invoke GetFileSize,@hFile,NULL
mov @dwOrigFileSize, eax
add eax, APPEND_SIZE ;长度加2000h
invoke CreateFileMapping,@hFile,0,PAGE_READWRITE,0,eax,0
mov @hMap,eax
invoke MapViewOfFile, @hMap,
FILE_MAP_WRITE+FILE_MAP_READ+FILE_MAP_COPY,
0, 0, 0
mov @pMem,eax
xchg eax, esi
assume esi : ptr IMAGE_DOS_HEADER
.IF [esi].e_magic != 'ZM' ;dos头mz标志
ret
.endif
add esi, [esi].e_lfanew
assume esi : ptr IMAGE_NT_HEADERS
.IF word ptr [esi].Signature != 4550h ;PE
ret
.endif
lea eax,byte ptr [esi].Signature
invoke wsprintf,addr szBuffer,CTXT("PE文件:%s"),eax
invoke StdOut,offset szBuffer
mov @dwNTHeaderAddr,esi
invoke _AddSection,@pMem
;eax返回新节表偏移
push eax
invoke wsprintf,addr szBuffer,CTXT("新节节表的文件偏移:%0.8x"),eax
invoke StdOut,offset szBuffer
mov esi, @dwNTHeaderAddr
assume esi : ptr IMAGE_NT_HEADERS
;; 下面做的就是设置新节的中的原代码入口点,就是真正的入口地址.
mov ebx, dword ptr [esi].OptionalHeader.AddressOfEntryPoint ;入口点rva
add ebx, dword ptr [esi].OptionalHeader.ImageBase ;入口点加基地址
;; OrigAddressOfEntry这个变量在CryptFile底部的NewSection节中
invoke wsprintf,addr szBuffer,CTXT("入口点加基地址:%0.8x "),ebx
invoke StdOut,offset szBuffer
mov eax, offset OrigAddressOfEntry
invoke wsprintf,addr szBuffer,CTXT("OrigAddressOfEntry:%0.8x "),eax
invoke StdOut,offset szBuffer
; mov eax, offset OrigAddressOfEntry
; mov dword ptr [eax], ebx ;原入口点的RA,放入新节区
;invoke wsprintf,addr szBuffer,CTXT("OrigAddressOfEntry:%0.8x"),dword ptr [eax]
;invoke StdOut,offset szBuffer
pop eax ;还原新节表头到eax
assume eax : ptr IMAGE_SECTION_HEADER
push dword ptr [eax].VirtualAddress ;新节区的rva放入入口地址
pop dword ptr [esi].OptionalHeader.AddressOfEntryPoint
;; 下面的代码利用新节节表将新节的代码写入文件
mov esi, offset REMOTE_CODE_START
mov edi, dword ptr [eax].PointerToRawData
add edi, @pMem
mov ecx, g_dwNewSectionSize
cld
rep movsb ;[esi]---->[edi]
LogicShellExit: ;退出标识
invoke UnmapViewOfFile,@pMem
invoke CloseHandle,@hMap
invoke CloseHandle, @hFile ;CreateFile的收尾
ret
_CryptFile endp
Start:
invoke _CryptFile, offset g_szTargetFile
invoke ExitProcess, 1
end Start
http://bbs.pediy.com/showthread.php?p=467116
还有一个问题是教程里要在OrigAddressOfEntry dd ?这里写入原入口地址,但段代码在.code段里,没法写入,是怎么回事
困苦
所有代码在这,请高手过目
.386
.model flat, stdcall
option casemap:none
;; ----------------------------------------
;; header file and lib file
;; ----------------------------------------
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include macro.asm
APPEND_SIZE equ 2000h
;常量
.const
g_szTargetFile db 'FirstWindow.exe',0
g_szNewSectionName db '.wxy',0
g_szErr db 'error',0
.data
g_dwNewSectionSize dd 0
.data?
szBuffer db MAX_PATH dup(?)
;代码段
.code
REMOTE_CODE_START equ this byte
call GetEip
GetEip:
pop ebx
sub ebx,offset GetEip
mov eax,[ebx + offset OrigAddressOfEntry]
jmp eax
OrigAddressOfEntry dd 401195h ;这个位置在.code里面写入不了,我改成一个直接的数
REMOTE_CODE_END equ this byte
REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START
PEAlign proc uses ecx edx, dwTarNum : DWORD, dwAlignTo : DWORD
mov ecx, dwAlignTo
mov eax, dwTarNum
xor edx, edx
div ecx ;eax/ecx
cmp edx, 0 ;edx保存余数
jz AlreadyAligned
inc eax ;如余数不为0,eax+1
AlreadyAligned:
mul ecx ;ecx乘eax
ret
PEAlign endp
_AddSection proc uses ebx ecx edx esi edi, pMem : LPVOID
LOCAL @dwNTHeader : LPVOID
LOCAL @dwFileAlig : DWORD ;文件对齐粒度
LOCAL @dwSecAlig : DWORD ;节对齐粒度
LOCAL @dwLastSecTbl : LPVOID ;原最后一个节区头尾部
LOCAL @kkk:DWORD
mov esi, pMem
;; 这里这个3ch是DOS头中e_lfanew的偏移
add esi, dword ptr [esi+3ch]
mov @dwNTHeader, esi ;保存nt头
assume esi : ptr IMAGE_NT_HEADERS
mov cx, word ptr [esi].FileHeader.NumberOfSections ;节数目保存cx
movzx ecx, cx ;ecx高位清零
inc word ptr [esi].FileHeader.NumberOfSections ;节数目+1
push dword ptr [esi].OptionalHeader.FileAlignment
pop @dwFileAlig ;保存文件对齐粒度
push dword ptr [esi].OptionalHeader.SectionAlignment ;保存节的对齐粒度
pop @dwSecAlig ;保存节的对齐粒度
;; 在NT头结构下面跟着的就是N个节表街头.加上NT头结构的长度就为第一个节表
add esi, sizeof IMAGE_NT_HEADERS
;; 在这里保存最后一个节表的偏移,因为一会在计算新节的RVA和offset要应用。
mov eax, sizeof IMAGE_SECTION_HEADER
mov ebx, ecx ;cx保存的是原节区数
imul ebx ;imul 有符号乘法,但操作数,ebx乘eax也就是:原节区数x节区头长度
add esi, eax ;文件头的位置+刚才算出来的原节区数x节区头长度=节区头尾部
push esi ;节区头尾部压入栈
mov eax,esi
sub eax,pMem
invoke wsprintf,addr szBuffer,CTXT("节区头尾部:%0.8x"),eax
invoke StdOut,offset szBuffer
invoke wsprintf,addr szBuffer,CTXT("节区头尾部:%0.8x"),esi
invoke StdOut,offset szBuffer
;; 这里保存了原最后节表的偏移,为了设置新节的地址做准备
sub esi, sizeof IMAGE_SECTION_HEADER ;原最后一个节区的起始位置
mov @dwLastSecTbl, esi ;原最后一个节区的起始位置保存起来
pop esi ;节区头尾部又压出来
assume esi : ptr IMAGE_SECTION_HEADER
;; 在新建的节表写节表名set section name
push esi ;压入栈保存
lea edi, [esi].Name1 ;节区头尾部地址放入edi
mov esi, offset g_szNewSectionName ;节区名指针放入esi,这里是".wow",0
CopySectionNameLoop:
lodsb ;块装入指令ptr byte [esi]->al
test al, al ;检测是不是零
jz EndCopySectionNameLoop ;是0完事
stosb ;块存储指令al->ptr byte [edi]
jmp CopySectionNameLoop
EndCopySectionNameLoop:
sub edi,4
invoke wsprintf,addr szBuffer,CTXT("写入节区名:%s"),edi
invoke StdOut,offset szBuffer
pop esi ;恢复esi
push 0E00000E0h ;0E00000E0h为设置可读可写可执行三个属性的或运算的值 20000000h | 40000000h | 80000000h
pop dword ptr [esi].Characteristics ;节属性
push g_dwNewSectionSize
pop dword ptr [esi].Misc.VirtualSize ;新节区尺寸
invoke wsprintf,addr szBuffer,CTXT("文件对齐粒度:%0.8x"),@dwFileAlig
invoke StdOut,offset szBuffer
invoke wsprintf,addr szBuffer,CTXT("节区对齐粒度:%0.8x"),@dwSecAlig
invoke StdOut,offset szBuffer
;新节区长度,我对齐粒度直接乘5
mov eax,@dwFileAlig
mov edx,2
imul edx
mov dword ptr [esi].SizeOfRawData, eax ;节在文件中对齐后的尺寸
mov eax, @dwLastSecTbl ;原文件,最后一个节表的起始位置
;设置新节的内存偏移和文件偏移需要上一节的一个信息
assume eax : ptr IMAGE_SECTION_HEADER
mov ecx, dword ptr [eax].VirtualAddress ;rva
add ecx, dword ptr [eax].Misc.VirtualSize ; ecx = new section rva
mov ebx, dword ptr [eax].PointerToRawData ;文件中的偏移
add ebx, dword ptr [eax].SizeOfRawData ; ebx = new section fva
mov dword ptr [esi].VirtualAddress, ecx ;放入新节表
mov dword ptr [esi].PointerToRawData, ebx
;------------------------------------------
;invoke wsprintf,addr szBuffer,CTXT("新节rva:%0.8x"), ecx
;invoke StdOut,offset szBuffer
;invoke wsprintf,addr szBuffer,CTXT("新节文件偏移:%0.8x"),ebx
;invoke StdOut,offset szBuffer
invoke PEAlign, ecx, @dwSecAlig ;为什么修正rva?知道了,以为后面的偏移要对齐
mov dword ptr [esi].VirtualAddress, eax
;; set section pointertorawdata
invoke PEAlign,ebx, @dwFileAlig
mov dword ptr [esi].PointerToRawData, eax
mov edx, @dwNTHeader ;pe头位置
assume edx : ptr IMAGE_NT_HEADERS
mov dword ptr [edx].OptionalHeader.SizeOfImage, eax ;在可选头改变内存中文件映像的尺寸
push dword ptr [esi].PointerToRawData ;新节在文件中的偏移压入栈
pop edi ;放入edi
add edi, pMem ;加上映像视图地址
mov edx, @dwNTHeader
;; clear the new sec
;; 在这里做一下清0工作ZeroMemory ,把新的节区里面清零
mov ecx, g_dwNewSectionSize
xor eax, eax
cld
rep stosb
invoke wsprintf,addr szBuffer,CTXT("新节节表的文件偏移:%0.8x"),esi
invoke StdOut,offset szBuffer
;; 此函数的返回值,新节节表的文件偏移
mov eax, esi
assume esi : nothing
assume eax : nothing
assume edx : nothing
ret
_AddSection endp
_CryptFile proc uses ebx ecx edx esi edi ,szFname : LPSTR
LOCAL @hFile : HANDLE
LOCAL @hMap : HANDLE
LOCAL @pMem : LPVOID
LOCAL @dwOrigFileSize : DWORD ;源文件长度
LOCAL @dwNTHeaderAddr : DWORD ;PE头地址
mov eax, offset REMOTE_CODE_END - offset REMOTE_CODE_START
mov g_dwNewSectionSize, eax
;invoke wsprintf,addr szBuffer,CTXT("新节区尺寸:%0.8x"),g_dwNewSectionSize
;invoke StdOut,offset szBuffer
;; open file
invoke CreateFile, szFname,\
GENERIC_WRITE + GENERIC_READ,\
FILE_SHARE_WRITE + FILE_SHARE_READ,\
NULL,\
OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL,\
0
mov @hFile,eax
.IF eax == INVALID_HANDLE_VALUE
invoke wsprintf,addr szBuffer,CTXT("文件创建失败:%0.8x"),0
invoke StdOut,offset szBuffer
ret
.ENDIF
invoke wsprintf,addr szBuffer,CTXT("文件创建成功:%0.8x "),0
invoke StdOut,offset szBuffer
invoke GetFileSize,@hFile,NULL
mov @dwOrigFileSize, eax
add eax, APPEND_SIZE ;长度加2000h
invoke CreateFileMapping,@hFile,0,PAGE_READWRITE,0,eax,0
mov @hMap,eax
invoke MapViewOfFile, @hMap,
FILE_MAP_WRITE+FILE_MAP_READ+FILE_MAP_COPY,
0, 0, 0
mov @pMem,eax
xchg eax, esi
assume esi : ptr IMAGE_DOS_HEADER
.IF [esi].e_magic != 'ZM' ;dos头mz标志
ret
.endif
add esi, [esi].e_lfanew
assume esi : ptr IMAGE_NT_HEADERS
.IF word ptr [esi].Signature != 4550h ;PE
ret
.endif
lea eax,byte ptr [esi].Signature
invoke wsprintf,addr szBuffer,CTXT("PE文件:%s"),eax
invoke StdOut,offset szBuffer
mov @dwNTHeaderAddr,esi
invoke _AddSection,@pMem
;eax返回新节表偏移
push eax
invoke wsprintf,addr szBuffer,CTXT("新节节表的文件偏移:%0.8x"),eax
invoke StdOut,offset szBuffer
mov esi, @dwNTHeaderAddr
assume esi : ptr IMAGE_NT_HEADERS
;; 下面做的就是设置新节的中的原代码入口点,就是真正的入口地址.
mov ebx, dword ptr [esi].OptionalHeader.AddressOfEntryPoint ;入口点rva
add ebx, dword ptr [esi].OptionalHeader.ImageBase ;入口点加基地址
;; OrigAddressOfEntry这个变量在CryptFile底部的NewSection节中
invoke wsprintf,addr szBuffer,CTXT("入口点加基地址:%0.8x "),ebx
invoke StdOut,offset szBuffer
mov eax, offset OrigAddressOfEntry
invoke wsprintf,addr szBuffer,CTXT("OrigAddressOfEntry:%0.8x "),eax
invoke StdOut,offset szBuffer
; mov eax, offset OrigAddressOfEntry
; mov dword ptr [eax], ebx ;原入口点的RA,放入新节区
;invoke wsprintf,addr szBuffer,CTXT("OrigAddressOfEntry:%0.8x"),dword ptr [eax]
;invoke StdOut,offset szBuffer
pop eax ;还原新节表头到eax
assume eax : ptr IMAGE_SECTION_HEADER
push dword ptr [eax].VirtualAddress ;新节区的rva放入入口地址
pop dword ptr [esi].OptionalHeader.AddressOfEntryPoint
;; 下面的代码利用新节节表将新节的代码写入文件
mov esi, offset REMOTE_CODE_START
mov edi, dword ptr [eax].PointerToRawData
add edi, @pMem
mov ecx, g_dwNewSectionSize
cld
rep movsb ;[esi]---->[edi]
LogicShellExit: ;退出标识
invoke UnmapViewOfFile,@pMem
invoke CloseHandle,@hMap
invoke CloseHandle, @hFile ;CreateFile的收尾
ret
_CryptFile endp
Start:
invoke _CryptFile, offset g_szTargetFile
invoke ExitProcess, 1
end Start
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: