• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 74, 文章 - 0, 評(píng)論 - 26, 引用 - 0
            數(shù)據(jù)加載中……

            直接運(yùn)行內(nèi)存中的程序 轉(zhuǎn)

            Windows的PE加載器在啟動(dòng)程序的時(shí)候,會(huì)將磁盤(pán)上的文件加載到內(nèi)存,然后做很多操作,如函數(shù)導(dǎo)入表重定位,變量預(yù)處理之類(lèi)的。這位仁兄等于是自己寫(xiě)了一個(gè)PE加載器。直接將內(nèi)存中的程序啟動(dòng)。記得以前的“紅色代碼”病毒也有相同的特性。
                直接啟動(dòng)內(nèi)存中的程序相當(dāng)于加了一個(gè)殼,可以把程序加密保存,運(yùn)行時(shí)解密到內(nèi)存,然后啟動(dòng),不過(guò)對(duì)于增加破解難度還要稍微復(fù)雜點(diǎn)。否則人家把內(nèi)存中的進(jìn)程DUMP出來(lái)然后修復(fù)導(dǎo)入表就被拖出來(lái)了。
            #include "stdafx.h"  
              
              
            typedef IMAGE_SECTION_HEADER (
            *PIMAGE_SECTION_HEADERS)[1];   
              
            // 計(jì)算對(duì)齊后的大小   
            unsigned long GetAlignedSize(unsigned long Origin, unsigned long Alignment)   
            {   
                
            return (Origin + Alignment - 1/ Alignment * Alignment;   
            }
               
              
            // 計(jì)算加載pe并對(duì)齊需要占用多少內(nèi)存   
            //
             未直接使用OptionalHeader.SizeOfImage作為結(jié)果是因?yàn)閾?jù)說(shuō)有的編譯器生成的exe這個(gè)值會(huì)填0   
            unsigned long CalcTotalImageSize(PIMAGE_DOS_HEADER MzH   
                                             , unsigned 
            long FileLen   
                                             , PIMAGE_NT_HEADERS peH   
                                             , PIMAGE_SECTION_HEADERS peSecH)   
            {   
                unsigned 
            long res;   
                
            // 計(jì)算pe頭的大小   
                res = GetAlignedSize( peH->OptionalHeader.SizeOfHeaders   
                    , peH
            ->OptionalHeader.SectionAlignment   
                    );   
              
                
            // 計(jì)算所有節(jié)的大小   
                forint i = 0; i < peH->FileHeader.NumberOfSections; ++i)   
                
            {   
                    
            // 超出文件范圍   
                    if(peSecH[i]->PointerToRawData + peSecH[i]->SizeOfRawData > FileLen)   
                        
            return 0;   
                    
            else if(peSecH[i]->VirtualAddress)//計(jì)算對(duì)齊后某節(jié)的大小   
                    {   
                        
            if(peSecH[i]->Misc.VirtualSize)   
                        
            {   
                            res 
            = GetAlignedSize( peSecH[i]->VirtualAddress + peSecH[i]->Misc.VirtualSize   
                                , peH
            ->OptionalHeader.SectionAlignment   
                                );   
                        }
               
                        
            else  
                        
            {   
                            res 
            = GetAlignedSize( peSecH[i]->VirtualAddress + peSecH[i]->SizeOfRawData   
                                , peH
            ->OptionalHeader.SectionAlignment   
                                );   
                        }
               
                    }
               
                    
            else if( peSecH[i]->Misc.VirtualSize < peSecH[i]->SizeOfRawData )   
                    
            {   
                        res 
            += GetAlignedSize( peSecH[i]->SizeOfRawData   
                            , peH
            ->OptionalHeader.SectionAlignment   
                            );   
                    }
               
                    
            else  
                    
            {   
                        res 
            += GetAlignedSize( peSecH[i]->Misc.VirtualSize   
                            , peH
            ->OptionalHeader.SectionAlignment   
                            );   
                    }
            // if_else   
                }
            // for   
                   
                
            return res;   
            }
               
              
              
              
              
            // 加載pe到內(nèi)存并對(duì)齊所有節(jié)   
            BOOL AlignPEToMem( void *Buf   
                              , 
            long Len   
                              , PIMAGE_NT_HEADERS 
            &peH   
                              , PIMAGE_SECTION_HEADERS 
            &peSecH   
                              , 
            void *&Mem   
                              , unsigned 
            long &ImageSize)   
            {   
                PIMAGE_DOS_HEADER SrcMz;
            // DOS頭   
                PIMAGE_NT_HEADERS SrcPeH;// PE頭   
                PIMAGE_SECTION_HEADERS SrcPeSecH;// 節(jié)表   
                   
                SrcMz 
            = (PIMAGE_DOS_HEADER)Buf;   
              
                
            if( Len < sizeof(IMAGE_DOS_HEADER) )    
                    
            return FALSE;   
                   
                
            if( SrcMz->e_magic != IMAGE_DOS_SIGNATURE )   
                    
            return FALSE;   
                   
                
            if( Len < SrcMz->e_lfanew + (long)sizeof(IMAGE_NT_HEADERS) )   
                    
            return FALSE;   
              
                SrcPeH 
            = (PIMAGE_NT_HEADERS)((int)SrcMz + SrcMz->e_lfanew);   
                
            if( SrcPeH->Signature != IMAGE_NT_SIGNATURE )   
                    
            return FALSE;   
              
                
            if( (SrcPeH->FileHeader.Characteristics & IMAGE_FILE_DLL) ||   
                    (SrcPeH
            ->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE == 0||   
                    (SrcPeH
            ->FileHeader.SizeOfOptionalHeader != sizeof(IMAGE_OPTIONAL_HEADER)) )   
                
            {   
                    
            return FALSE;   
                }
               
              
              
                SrcPeSecH 
            = (PIMAGE_SECTION_HEADERS)((int)SrcPeH + sizeof(IMAGE_NT_HEADERS));   
                ImageSize 
            = CalcTotalImageSize( SrcMz, Len, SrcPeH, SrcPeSecH);   
              
                
            if( ImageSize == 0 )   
                    
            return FALSE;   
                   
                Mem 
            = VirtualAlloc( NULL, ImageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); // 分配內(nèi)存   
                if( Mem != NULL )   
                
            {   
                    
            // 計(jì)算需要復(fù)制的PE頭字節(jié)數(shù)   
                    unsigned long l = SrcPeH->OptionalHeader.SizeOfHeaders;   
                    
            forint i = 0; i < SrcPeH->FileHeader.NumberOfSections; ++i)   
                    
            {   
                        
            if( (SrcPeSecH[i]->PointerToRawData) &&   
                            (SrcPeSecH[i]
            ->PointerToRawData < l) )   
                        
            {   
                            l 
            = SrcPeSecH[i]->PointerToRawData;   
                        }
               
                    }
               
                    memmove( Mem, SrcMz, l);   
                    peH 
            = (PIMAGE_NT_HEADERS)((int)Mem + ((PIMAGE_DOS_HEADER)Mem)->e_lfanew);   
                    peSecH 
            = (PIMAGE_SECTION_HEADERS)((int)peH + sizeof(IMAGE_NT_HEADERS));   
              
                    
            void *Pt = (void *)((unsigned long)Mem    
                        
            + GetAlignedSize( peH->OptionalHeader.SizeOfHeaders   
                        , peH
            ->OptionalHeader.SectionAlignment)   
                        );   
              
                    
            for( i = 0; i < peH->FileHeader.NumberOfSections; ++i)   
                    
            {   
                        
            // 定位該節(jié)在內(nèi)存中的位置   
                        if(peSecH[i]->VirtualAddress)   
                            Pt 
            = (void *)((unsigned long)Mem + peSecH[i]->VirtualAddress);   
              
                        
            if(peSecH[i]->SizeOfRawData)   
                        
            {   
                            
            // 復(fù)制數(shù)據(jù)到內(nèi)存   
                            memmove(Pt, (const void *)((unsigned long)(SrcMz) + peSecH[i]->PointerToRawData), peSecH[i]->SizeOfRawData);   
                            
            if(peSecH[i]->Misc.VirtualSize < peSecH[i]->SizeOfRawData)   
                                Pt 
            = (void *)((unsigned long)Pt + GetAlignedSize(peSecH[i]->SizeOfRawData, peH->OptionalHeader.SectionAlignment));   
                            
            else // pt 定位到下一節(jié)開(kāi)始位置   
                                Pt = (void *)((unsigned long)Pt + GetAlignedSize(peSecH[i]->Misc.VirtualSize, peH->OptionalHeader.SectionAlignment));   
                        }
               
                        
            else  
                        
            {   
                            Pt 
            = (void *)((unsigned long)Pt + GetAlignedSize(peSecH[i]->Misc.VirtualSize, peH->OptionalHeader.SectionAlignment));   
                        }
               
                    }
               
                }
               
                
            return TRUE;   
            }
               
              
              
              
            typedef 
            void *(__stdcall *pfVirtualAllocEx)(unsigned longvoid *, unsigned long, unsigned long, unsigned long);   
            pfVirtualAllocEx MyVirtualAllocEx 
            = NULL;   
              
            BOOL IsNT()   
            {   
                
            return MyVirtualAllocEx!=NULL;   
            }
               
              
            // 生成外殼程序命令行   
            char *PrepareShellExe(char *CmdParam, unsigned long BaseAddr, unsigned long ImageSize)   
            {   
                
            if(IsNT())   
                
            {   
                    
            char *Buf = new char[256];   
                    memset(Buf, 
            0256);   
                    GetModuleFileName(
            0, Buf, 256);   
                    strcat(Buf, CmdParam);   
                    
            return Buf; // 請(qǐng)記得釋放內(nèi)存;-)   
                }
               
                
            else  
                
            {   
                    
            // Win98下的處理請(qǐng)參考原文;-)   
                    // http://community.csdn.net/Expert/topic/4416/4416252.xml?temp=8.709133E-03   
                    return NULL;   
                }
               
            }
               
              
            // 是否包含可重定向列表   
            BOOL HasRelocationTable(PIMAGE_NT_HEADERS peH)   
            {   
                
            return (peH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)   
                    
            && (peH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size);   
            }
               
              
              
              
              
            #pragma pack(push, 
            1)   
            typedef struct
            {   
                unsigned 
            long VirtualAddress;   
                unsigned 
            long SizeOfBlock;   
            }
             *PImageBaseRelocation;   
            #pragma pack(pop)   
              
            // 重定向PE用到的地址   
            void DoRelocation(PIMAGE_NT_HEADERS peH, void *OldBase, void *NewBase)   
            {   
                unsigned 
            long Delta = (unsigned long)NewBase - peH->OptionalHeader.ImageBase;   
                PImageBaseRelocation p 
            = (PImageBaseRelocation)((unsigned long)OldBase    
                    
            + peH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);   
                
            while(p->VirtualAddress + p->SizeOfBlock)   
                
            {   
                    unsigned 
            short *pw = (unsigned short *)((int)p + sizeof(*p));   
                    
            for(unsigned int i=1; i <= (p->SizeOfBlock - sizeof(*p)) / 2++i)   
                    
            {   
                        
            if((*pw) & 0xF000 == 0x3000){   
                            unsigned 
            long *= (unsigned long *)((unsigned long)(OldBase) + p->VirtualAddress + ((*pw) & 0x0FFF));   
                            
            *+= Delta;   
                        }
               
                        
            ++pw;   
                    }
               
                    p 
            = (PImageBaseRelocation)pw;   
                }
               
            }
               
              
            // 卸載原外殼占用內(nèi)存   
            BOOL UnloadShell(HANDLE ProcHnd, unsigned long BaseAddr)   
            {   
                typedef unsigned 
            long (__stdcall *pfZwUnmapViewOfSection)(unsigned long, unsigned long);   
                pfZwUnmapViewOfSection ZwUnmapViewOfSection 
            = NULL;   
                BOOL res 
            = FALSE;   
                HMODULE m 
            = LoadLibrary("ntdll.dll");   
                
            if(m){   
                    ZwUnmapViewOfSection 
            = (pfZwUnmapViewOfSection)GetProcAddress(m, "ZwUnmapViewOfSection");   
                    
            if(ZwUnmapViewOfSection)   
                        res 
            = (ZwUnmapViewOfSection((unsigned long)ProcHnd, BaseAddr) == 0);   
                    FreeLibrary(m);   
                }
               
                
            return res;   
            }
               
              
            // 創(chuàng)建外殼進(jìn)程并獲取其基址、大小和當(dāng)前運(yùn)行狀態(tài)   
            BOOL CreateChild(char *Cmd, CONTEXT &Ctx, HANDLE &ProcHnd, HANDLE &ThrdHnd,    
                             unsigned 
            long &ProcId, unsigned long &BaseAddr, unsigned long &ImageSize)   
            {   
                STARTUPINFOA si;   
                PROCESS_INFORMATION pi;   
                unsigned 
            long old;   
                MEMORY_BASIC_INFORMATION MemInfo;   
                memset(
            &si, 0, sizeof(si));   
                memset(
            &pi, 0, sizeof(pi));   
                si.cb 
            = sizeof(si);   
                   
                BOOL res 
            = CreateProcess(NULL, Cmd, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi); // 以?huà)炱鸱绞竭\(yùn)行進(jìn)程;   
                if(res){   
                    ProcHnd 
            = pi.hProcess;   
                    ThrdHnd 
            = pi.hThread;   
                    ProcId 
            = pi.dwProcessId;   
                    
            // 獲取外殼進(jìn)程運(yùn)行狀態(tài),[ctx.Ebx+8]內(nèi)存處存的是外殼進(jìn)程的加載基址,ctx.Eax存放有外殼進(jìn)程的入口地址   
                    Ctx.ContextFlags = CONTEXT_FULL;   
                    GetThreadContext(ThrdHnd, 
            &Ctx);   
                    ReadProcessMemory(ProcHnd, (
            void *)(Ctx.Ebx+8), &BaseAddr, sizeof(unsigned long), &old); // 讀取加載基址   
                    void *= (void *)BaseAddr;   
                    
            // 計(jì)算外殼進(jìn)程占有的內(nèi)存   
                    while(VirtualQueryEx(ProcHnd, p, &MemInfo, sizeof(MemInfo)))   
                    
            {   
                        
            if(MemInfo.State = MEM_FREE) break;   
                        p 
            = (void *)((unsigned long)p + MemInfo.RegionSize);   
                    }
               
                    ImageSize 
            = (unsigned long)p - (unsigned long)BaseAddr;   
                }
               
                
            return res;   
            }
               
              
            // 創(chuàng)建外殼進(jìn)程并用目標(biāo)進(jìn)程替換它然后執(zhí)行   
            HANDLE AttachPE(char *CmdParam, PIMAGE_NT_HEADERS peH, PIMAGE_SECTION_HEADERS peSecH,    
                            
            void *Ptr, unsigned long ImageSize, unsigned long &ProcId)   
            {   
                HANDLE res 
            = INVALID_HANDLE_VALUE;   
                CONTEXT Ctx;   
                HANDLE Thrd;   
                unsigned 
            long Addr, Size;   
                
            char *= PrepareShellExe(CmdParam, peH->OptionalHeader.ImageBase, ImageSize);   
                
            if(s==NULL) return res;   
                
            if(CreateChild(s, Ctx, res, Thrd, ProcId, Addr, Size)){   
                    
            void *= NULL;   
                    unsigned 
            long old;   
                    
            if((peH->OptionalHeader.ImageBase == Addr) && (Size >= ImageSize)){// 外殼進(jìn)程可以容納目標(biāo)進(jìn)程并且加載地址一致   
                        p = (void *)Addr;   
                        VirtualProtectEx(res, p, Size, PAGE_EXECUTE_READWRITE, 
            &old);   
                    }
               
                    
            else if(IsNT()){   
                        
            if(UnloadShell(res, Addr)){// 卸載外殼進(jìn)程占有內(nèi)存   
                            p = MyVirtualAllocEx((unsigned long)res, (void *)peH->OptionalHeader.ImageBase, ImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);   
                        }
               
                        
            if((p == NULL) && HasRelocationTable(peH)){// 分配內(nèi)存失敗并且目標(biāo)進(jìn)程支持重定向   
                            p = MyVirtualAllocEx((unsigned long)res, NULL, ImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);   
                            
            if(p) DoRelocation(peH, Ptr, p); // 重定向   
                        }
               
                    }
               
                    
            if(p){   
                        WriteProcessMemory(res, (
            void *)(Ctx.Ebx+8), &p, sizeof(DWORD), &old); // 重置目標(biāo)進(jìn)程運(yùn)行環(huán)境中的基址   
                        peH->OptionalHeader.ImageBase = (unsigned long)p;   
                        
            if(WriteProcessMemory(res, p, Ptr, ImageSize, &old)){// 復(fù)制PE數(shù)據(jù)到目標(biāo)進(jìn)程   
                            Ctx.ContextFlags = CONTEXT_FULL;   
                            
            if((unsigned long)p == Addr)   
                                Ctx.Eax 
            = peH->OptionalHeader.ImageBase + peH->OptionalHeader.AddressOfEntryPoint; // 重置運(yùn)行環(huán)境中的入口地址   
                            else  
                                Ctx.Eax 
            = (unsigned long)p + peH->OptionalHeader.AddressOfEntryPoint;   
                            SetThreadContext(Thrd, 
            &Ctx);// 更新運(yùn)行環(huán)境   
                            ResumeThread(Thrd);// 執(zhí)行   
                            CloseHandle(Thrd);   
                        }
               
                        
            else{// 加載失敗,殺掉外殼進(jìn)程   
                            TerminateProcess(res, 0);   
                            CloseHandle(Thrd);   
                            CloseHandle(res);   
                            res 
            = INVALID_HANDLE_VALUE;   
                        }
               
                    }
               
                    
            else{// 加載失敗,殺掉外殼進(jìn)程   
                        TerminateProcess(res, 0);   
                        CloseHandle(Thrd);   
                        CloseHandle(res);   
                        res 
            = INVALID_HANDLE_VALUE;   
                    }
               
                }
               
                
            delete[] s;   
                
            return res;   
            }
               
              
              
              
              
             
            /**//*******************************************************  
            { ******************************************************* }  
            { *                 從內(nèi)存中加載并運(yùn)行exe               * }  
            { ******************************************************* }  
            { * 參數(shù):                                                }  
            { * Buffer: 內(nèi)存中的exe地址                               }  
            { * Len: 內(nèi)存中exe占用長(zhǎng)度                                }  
            { * CmdParam: 命令行參數(shù)(不包含exe文件名的剩余命令行參數(shù))}  
            { * ProcessId: 返回的進(jìn)程Id                               }  
            { * 返回值: 如果成功則返回進(jìn)程的Handle(ProcessHandle),   }  
            {            如果失敗則返回INVALID_HANDLE_VALUE           }  
            { ******************************************************* }  
             ******************************************************
            */
              
            HANDLE MemExecute(
            void *ABuffer, long Len, char *CmdParam, unsigned long *ProcessId)   
            {   
                HANDLE res 
            = INVALID_HANDLE_VALUE;   
                PIMAGE_NT_HEADERS peH;   
                PIMAGE_SECTION_HEADERS peSecH;   
                
            void *Ptr;   
                unsigned 
            long peSz;   
                
            if(AlignPEToMem(ABuffer, Len, peH, peSecH, Ptr, peSz))   
                
            {   
                    res 
            = AttachPE(CmdParam, peH, peSecH, Ptr, peSz, *ProcessId);   
                    VirtualFree(Ptr, peSz, MEM_DECOMMIT);   
                }
               
                
            return res;   
            }
               
              
            // 初始化   
            class CInit   
            {   
            public:   
                CInit()   
                
            {   
                    MyVirtualAllocEx 
            = (pfVirtualAllocEx)GetProcAddress(GetModuleHandle("Kernel32.dll"), "VirtualAllocEx");   
                }
               
            }
            Init;   
              
              
              
              
            int APIENTRY WinMain(HINSTANCE hInstance,   
                                 HINSTANCE hPrevInstance,   
                                 LPSTR     lpCmdLine,   
                                 
            int       nCmdShow)   
            {   
                HANDLE hFile 
            = NULL;   
                hFile 
            = ::CreateFile( "f:\SourceFromCsdn2.exe"  
                    , FILE_ALL_ACCESS   
                    , 
            0   
                    , NULL   
                    , OPEN_EXISTING   
                    , FILE_ATTRIBUTE_NORMAL   
                    , NULL   
                    );   
                
            if( hFile == INVALID_HANDLE_VALUE )   
                    
            return -1;   
              
                ::SetFilePointer( hFile, 
            0, NULL, FILE_BEGIN);   
                DWORD dwFileSize 
            = ::GetFileSize( hFile, NULL);   
              
                LPBYTE pBuf 
            = new BYTE[dwFileSize];   
                memset( pBuf, 
            0, dwFileSize);   
              
                DWORD dwNumberOfBytesRead 
            = 0;   
                ::ReadFile( hFile   
                    , pBuf   
                    , dwFileSize   
                    , 
            &dwNumberOfBytesRead   
                    , NULL   
                    );   
              
                ::CloseHandle(hFile);   
                   
                unsigned 
            long ulProcessId = 0;   
                MemExecute( pBuf, dwFileSize, 
            ""&ulProcessId);   
                
            delete[] pBuf;   
              
                   
                
            return 0;   
            }
              

            posted on 2008-10-31 15:18 井泉 閱讀(494) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi):

            久久噜噜电影你懂的| 久久久精品人妻一区二区三区蜜桃 | 久久婷婷五月综合97色一本一本| 久久精品国产亚洲av水果派| 99精品久久久久久久婷婷| 99久久香蕉国产线看观香| 999久久久免费精品国产| 久久高清一级毛片| 人妻无码中文久久久久专区| 精品久久久久久国产免费了| 无码久久精品国产亚洲Av影片| 一本大道加勒比久久综合| 久久精品国产欧美日韩99热| 69久久夜色精品国产69| 亚洲欧美国产精品专区久久| 99久久精品国产免看国产一区| 中文字幕精品久久| 亚洲国产二区三区久久| 亚洲日本va中文字幕久久| 久久国产免费直播| 97久久精品国产精品青草| 精品国产日韩久久亚洲| 99久久无码一区人妻| 少妇高潮惨叫久久久久久| 一本色道久久88综合日韩精品| 97久久久久人妻精品专区| 国产亚洲精品久久久久秋霞| 国内精品伊人久久久久影院对白 | 久久五月精品中文字幕| 久久A级毛片免费观看| 久久亚洲精品国产亚洲老地址| 91性高湖久久久久| 国产精品99久久99久久久| 精品一二三区久久aaa片| 久久久久一级精品亚洲国产成人综合AV区| 国产精品女同久久久久电影院| 久久久精品人妻一区二区三区蜜桃 | 久久久艹| 国产99久久久国产精免费| 2021久久精品国产99国产精品| 亚洲国产精品无码久久98|