• <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, 評論 - 26, 引用 - 0
            數據加載中……

            直接運行內存中的程序 轉

            Windows的PE加載器在啟動程序的時候,會將磁盤上的文件加載到內存,然后做很多操作,如函數導入表重定位,變量預處理之類的。這位仁兄等于是自己寫了一個PE加載器。直接將內存中的程序啟動。記得以前的“紅色代碼”病毒也有相同的特性。
                直接啟動內存中的程序相當于加了一個殼,可以把程序加密保存,運行時解密到內存,然后啟動,不過對于增加破解難度還要稍微復雜點。否則人家把內存中的進程DUMP出來然后修復導入表就被拖出來了。
            #include "stdafx.h"  
              
              
            typedef IMAGE_SECTION_HEADER (
            *PIMAGE_SECTION_HEADERS)[1];   
              
            // 計算對齊后的大小   
            unsigned long GetAlignedSize(unsigned long Origin, unsigned long Alignment)   
            {   
                
            return (Origin + Alignment - 1/ Alignment * Alignment;   
            }
               
              
            // 計算加載pe并對齊需要占用多少內存   
            //
             未直接使用OptionalHeader.SizeOfImage作為結果是因為據說有的編譯器生成的exe這個值會填0   
            unsigned long CalcTotalImageSize(PIMAGE_DOS_HEADER MzH   
                                             , unsigned 
            long FileLen   
                                             , PIMAGE_NT_HEADERS peH   
                                             , PIMAGE_SECTION_HEADERS peSecH)   
            {   
                unsigned 
            long res;   
                
            // 計算pe頭的大小   
                res = GetAlignedSize( peH->OptionalHeader.SizeOfHeaders   
                    , peH
            ->OptionalHeader.SectionAlignment   
                    );   
              
                
            // 計算所有節的大小   
                forint i = 0; i < peH->FileHeader.NumberOfSections; ++i)   
                
            {   
                    
            // 超出文件范圍   
                    if(peSecH[i]->PointerToRawData + peSecH[i]->SizeOfRawData > FileLen)   
                        
            return 0;   
                    
            else if(peSecH[i]->VirtualAddress)//計算對齊后某節的大小   
                    {   
                        
            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到內存并對齊所有節   
            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;// 節表   
                   
                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); // 分配內存   
                if( Mem != NULL )   
                
            {   
                    
            // 計算需要復制的PE頭字節數   
                    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)   
                    
            {   
                        
            // 定位該節在內存中的位置   
                        if(peSecH[i]->VirtualAddress)   
                            Pt 
            = (void *)((unsigned long)Mem + peSecH[i]->VirtualAddress);   
              
                        
            if(peSecH[i]->SizeOfRawData)   
                        
            {   
                            
            // 復制數據到內存   
                            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 定位到下一節開始位置   
                                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; // 請記得釋放內存;-)   
                }
               
                
            else  
                
            {   
                    
            // Win98下的處理請參考原文;-)   
                    // 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;   
                }
               
            }
               
              
            // 卸載原外殼占用內存   
            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;   
            }
               
              
            // 創建外殼進程并獲取其基址、大小和當前運行狀態   
            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); // 以掛起方式運行進程;   
                if(res){   
                    ProcHnd 
            = pi.hProcess;   
                    ThrdHnd 
            = pi.hThread;   
                    ProcId 
            = pi.dwProcessId;   
                    
            // 獲取外殼進程運行狀態,[ctx.Ebx+8]內存處存的是外殼進程的加載基址,ctx.Eax存放有外殼進程的入口地址   
                    Ctx.ContextFlags = CONTEXT_FULL;   
                    GetThreadContext(ThrdHnd, 
            &Ctx);   
                    ReadProcessMemory(ProcHnd, (
            void *)(Ctx.Ebx+8), &BaseAddr, sizeof(unsigned long), &old); // 讀取加載基址   
                    void *= (void *)BaseAddr;   
                    
            // 計算外殼進程占有的內存   
                    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;   
            }
               
              
            // 創建外殼進程并用目標進程替換它然后執行   
            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)){// 外殼進程可以容納目標進程并且加載地址一致   
                        p = (void *)Addr;   
                        VirtualProtectEx(res, p, Size, PAGE_EXECUTE_READWRITE, 
            &old);   
                    }
               
                    
            else if(IsNT()){   
                        
            if(UnloadShell(res, Addr)){// 卸載外殼進程占有內存   
                            p = MyVirtualAllocEx((unsigned long)res, (void *)peH->OptionalHeader.ImageBase, ImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);   
                        }
               
                        
            if((p == NULL) && HasRelocationTable(peH)){// 分配內存失敗并且目標進程支持重定向   
                            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); // 重置目標進程運行環境中的基址   
                        peH->OptionalHeader.ImageBase = (unsigned long)p;   
                        
            if(WriteProcessMemory(res, p, Ptr, ImageSize, &old)){// 復制PE數據到目標進程   
                            Ctx.ContextFlags = CONTEXT_FULL;   
                            
            if((unsigned long)p == Addr)   
                                Ctx.Eax 
            = peH->OptionalHeader.ImageBase + peH->OptionalHeader.AddressOfEntryPoint; // 重置運行環境中的入口地址   
                            else  
                                Ctx.Eax 
            = (unsigned long)p + peH->OptionalHeader.AddressOfEntryPoint;   
                            SetThreadContext(Thrd, 
            &Ctx);// 更新運行環境   
                            ResumeThread(Thrd);// 執行   
                            CloseHandle(Thrd);   
                        }
               
                        
            else{// 加載失敗,殺掉外殼進程   
                            TerminateProcess(res, 0);   
                            CloseHandle(Thrd);   
                            CloseHandle(res);   
                            res 
            = INVALID_HANDLE_VALUE;   
                        }
               
                    }
               
                    
            else{// 加載失敗,殺掉外殼進程   
                        TerminateProcess(res, 0);   
                        CloseHandle(Thrd);   
                        CloseHandle(res);   
                        res 
            = INVALID_HANDLE_VALUE;   
                    }
               
                }
               
                
            delete[] s;   
                
            return res;   
            }
               
              
              
              
              
             
            /**//*******************************************************  
            { ******************************************************* }  
            { *                 從內存中加載并運行exe               * }  
            { ******************************************************* }  
            { * 參數:                                                }  
            { * Buffer: 內存中的exe地址                               }  
            { * Len: 內存中exe占用長度                                }  
            { * CmdParam: 命令行參數(不包含exe文件名的剩余命令行參數)}  
            { * ProcessId: 返回的進程Id                               }  
            { * 返回值: 如果成功則返回進程的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) 評論(0)  編輯 收藏 引用 所屬分類:

            93精91精品国产综合久久香蕉| 欧美激情精品久久久久久久| 亚洲狠狠综合久久| 久久影院综合精品| 亚洲午夜无码久久久久小说| 久久久噜噜噜久久熟女AA片| 久久精品国产亚洲AV不卡| 久久久久久a亚洲欧洲aⅴ | 久久亚洲国产成人精品无码区| 国内精品伊人久久久久| 99久久久精品免费观看国产| 日产精品久久久一区二区| 色欲av伊人久久大香线蕉影院 | 久久久中文字幕日本| 久久久久久久综合日本| 久久这里只有精品视频99| 天堂无码久久综合东京热| 国产三级观看久久| 久久综合久久综合九色| 久久电影网一区| 久久夜色精品国产噜噜麻豆| 久久精品国产乱子伦| 久久精品a亚洲国产v高清不卡| 亚洲美日韩Av中文字幕无码久久久妻妇| 怡红院日本一道日本久久 | 色天使久久综合网天天| 伊人色综合久久天天网| 久久综合88熟人妻| 中文字幕一区二区三区久久网站| 国产69精品久久久久99尤物 | 亚洲精品高清一二区久久| 亚洲中文字幕无码久久综合网| 久久精品中文字幕无码绿巨人| 99久久国产综合精品网成人影院| 久久伊人精品青青草原日本| 国产精品一久久香蕉国产线看观看| 久久电影网一区| 7777精品久久久大香线蕉 | 精品久久久久久国产| 思思久久99热只有频精品66| 99久久人妻无码精品系列蜜桃|