首页
社区
课程
招聘
[旧帖] [求助]我的添加新节的程序为什么总“不是win32程序” 0.00雪花
发表于: 2011-12-9 14:08 1698

[旧帖] [求助]我的添加新节的程序为什么总“不是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

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
怎么没人看啊
2011-12-12 10:37
0
游客
登录 | 注册 方可回帖
返回
//