• <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>

            星綻紫輝(rawdata)的Blog

            快樂地學(xué)習(xí),快樂地工作!

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              16 Posts :: 0 Stories :: 37 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(5)

            我參與的團(tuán)隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

                    
                   原創(chuàng):星綻紫輝(rawdata)
            http://www.shnenglu.com/rawdata  2009-1-20
                   轉(zhuǎn)載請注明出處

                   關(guān)鍵字: PE   增加  區(qū)段  section 文件格式

                   現(xiàn)在我要給一PE文件增加區(qū)段(section),但是增加區(qū)段后我不希望影響PE文件的正常使用,那么應(yīng)該怎么

            做呢?我寫這個教程的目的,希望能幫學(xué)習(xí)PE格式,當(dāng)然也作為我以后參考的筆記。

                    簡單地說:PE文件和普通文件沒有什么區(qū)別,只是存在格式上的差異。另外,當(dāng)你雙擊某個.exe文件

            時,Windows Shell 程序?qū)L試解析文件并運(yùn)行它的PE代碼。所以第一步,你必須對PE格式比較熟悉。現(xiàn)在

            網(wǎng)上的PE教程我認(rèn)為最好的就是羅云斌主頁上的匯編教程了,我在這里長話短說,只是討論和我們要解決的

            問題相關(guān)的方面。

                     一般來講,PE由以下幾個部分依次排列下來:

                      1.   Dos 頭

                      2.   Dos stub    (通常你不必關(guān)心它的內(nèi)容,重建PE只需完全拷貝即可) 
             
                      3.   NT 頭
                
                      4.    節(jié)表

                      5.    文件對齊間隙

                      6.    第一節(jié)

                      7.    第二節(jié)

                      8.    ...

                      9.    第 n  節(jié) (文件結(jié)尾)


                      對于PE文件,如果沒有文件對齊和內(nèi)存對齊,那將是非常簡單了。(但是,太簡單了就不安全了,不是

            嗎?對于這種格式,當(dāng)初的設(shè)計者還是動了不少腦筋的,呵呵~)。我們可以用非常簡單的讀文件函數(shù),讀取

            各部分結(jié)構(gòu),然后把它重組還原PE。如果你是初次接觸,建議你這樣實(shí)踐一下。

                    
                     然后我們討論一下如何增加區(qū)段,我們將盡量保證維持原來的PE結(jié)構(gòu)的數(shù)據(jù),然后在此基礎(chǔ)上增加我們

            的數(shù)據(jù)。現(xiàn)在我把這個過程步驟化:

                    一、讀取Dos頭

                    二、讀取Dos stub

                    三、讀取NT頭,根據(jù)Dos頭定位到此

                    四、讀取NT頭

                    五、讀取節(jié)表

                    六、遍歷讀取所有節(jié)塊


                  現(xiàn)在,我們把一個PE文件讀到緩沖區(qū)了。然后我們進(jìn)行修改:試驗(yàn)證明,只需要某些特征項(xiàng)即可,而不

            必對所有參數(shù)進(jìn)行修改,這樣PE文件(如.exe)還是能正常運(yùn)行。對于具體的節(jié)塊,我們必須給某些關(guān)鍵的

            參數(shù)賦值,否則將破壞PE結(jié)構(gòu),導(dǎo)致不能運(yùn)行。


                  在開始修改前,有一些非常關(guān)鍵的東西我們必須知道:文件對齊和內(nèi)存對齊。實(shí)際上,所有的section區(qū)

            段都是文件對齊的(你把每一節(jié)當(dāng)成一個塊,具有起始文件位置和塊大小),比如:第一節(jié)的文件偏移為

            1024KB,節(jié)塊大小為1000KB,那么第二節(jié)的文件偏移將是2048KB,而不是2024KB(文件偏移即是節(jié)塊的開始

            位置)。但這其實(shí)不是一成不變的。你可以修改它,只要滿足文件對齊,但是帶來的麻煩是,你必須同時也

            修改它的定位目錄----->節(jié)表里的PointerToRawData文件指針,否則將由于找不到對應(yīng)的節(jié)塊而產(chǎn)生錯誤。

                   我常常思考這樣一個問題,到底要不要把PE裝載到內(nèi)存,然后在內(nèi)存中增加區(qū)段,然后把PE內(nèi)存dump成

            新的PE文件達(dá)到增加區(qū)段的目的。實(shí)際上,這是完全可行的。但是,直接修改PE文件也是可以的,可以不把

            PE裝載到內(nèi)存。因?yàn)槲覀儍H僅是增加區(qū)段,不需要修改引入表之類的東西。在我增加區(qū)段成功后,對比發(fā)

            現(xiàn),節(jié)表里面的Virtual Address 實(shí)際上等于PointerToRawData,節(jié)表里面的Virtual Size 實(shí)際上等于SizeofRawData

            (呵呵,我的網(wǎng)名就是rawdata)。于是,我想,這樣的設(shè)計實(shí)際上是為了簡化PE程序的設(shè)計的復(fù)雜性。內(nèi)存對

            齊轉(zhuǎn)化為文件對齊,一旦設(shè)計好文件對齊,那么內(nèi)存對齊就設(shè)計好了。但是,你千萬不要認(rèn)為兩者一定總是相

            等的,實(shí)際它有很大的靈活性,你可以隨意設(shè)計,只要滿足NT頭里面的指定的內(nèi)存對齊值參數(shù)。

                  還有一個關(guān)鍵的要注意的地方:必須重新修改NT頭里面的pINH->OptionalHeader.SizeOfImage值。即整個PE

            在內(nèi)存的全部的映像的大小。我們可以這樣給它賦予新的值:增加1個新的區(qū)段,就在原來的SizeOfImage值基

            礎(chǔ)上再加上該節(jié)塊大小的文件對齊值,增加了幾個區(qū)段,就累加幾次,你應(yīng)該明白了吧?

                
                  如果你感覺我的語言表達(dá)很糟糕,請你諒解。不過,請你放心,我后面會給出源代碼。其實(shí)主要做的工

            作就是在文件尾加上一些數(shù)據(jù),然后修改文件頭的一些參數(shù),僅此而已,沒有什么神奇的地方,還等什么?

            趕快去寫一個PE加區(qū)工具吧~~~ 

                 代碼清單如下:    (平臺:  console)
                 把其中的PE文件名該為你想加區(qū)的PE文件名就可以了。

                 后記:
                 原來的程序是只使用于raw和rva相等的情況,正確的修改如下:
                 
                 把第295行修改為:
                 //Rva與raw不匹配的情況。。。
               
               ppISH[i]->VirtualAddress = ppISH[i-1]->VirtualAddress +\
               ((ppISH[i-1]->SizeOfRawData/pINH->OptionalHeader.SectionAlignment)+1)*\
               (pINH->OptionalHeader.SectionAlignment);

             

              1/**************************************************************************
              2*    文件名:        Main.cpp
              3*    日  期:        2009年1月13日
              4*    作  者:        rawdata
              5*    描  述:        
              6***************************************************************************/

              7
              8#include <windows.h>
              9#include <windowsx.h>
             10#include <winnt.h>
             11#include <iostream>
             12using namespace std;
             13
             14#pragma warning(disable:4312)
             15#pragma warning(disable:4311)
             16#pragma warning(disable:4244)
             17
             18int main(int argc,char**argv)
             19{
             20    //------------------- 主要緩沖區(qū)定義 ----------------------
             21    
             22    BYTE* pDos = NULL;        //Dos頭和Stub區(qū)
             23    DWORD dwSizeDos = 0;    //Dos頭 大小
             24    DWORD dwSizeStub = 0;    //Dos Stub區(qū)大小
             25
             26    BYTE* pNT = NULL;        //NT頭
             27    DWORD dwSizeNT = 0;        //該區(qū)大小
             28
             29    BYTE* pSecH = NULL;        //節(jié)表
             30    DWORD dwSizeSecH = 0;    //該區(qū)大小
             31    WORD dwSizeAdd = 3;        //增加的節(jié)的個數(shù)
             32
             33    BYTE* pDelta = NULL;    //文件對齊填充數(shù)據(jù)
             34    DWORD dwSizeDelta = 0;    //該區(qū)大小
             35
             36    BYTE* pPrevSec = NULL;    //節(jié)塊
             37    DWORD dwSizePrevSec = 0;//該區(qū)大小
             38
             39    BYTE* pAddSec = NULL;    //新增的節(jié)塊
             40    DWORD dwSizeAddSec = 0;    //該區(qū)大小
             41
             42    //---------------------- 其他臨時定義 --------------------
             43    
             44    const char* pszFilePath = NULL;            //文件路徑
             45    HANDLE hFile = NULL;                    //文件句柄
             46
             47    PIMAGE_DOS_HEADER        pIDH = NULL;    //Dos頭
             48    PIMAGE_NT_HEADERS        pINH = NULL;    //NT 頭
             49    PIMAGE_SECTION_HEADER*    ppISH = NULL;    //節(jié)表
             50
             51    DWORD dwRealRead = 0;                    //實(shí)際每次文件讀取的字節(jié)數(shù)
             52    DWORD dwMiniPointer = 0;                //第一個section的位置
             53    BOOL bNeedModify = FALSE;                //是否有必要需要修改節(jié)塊的文件指針
             54
             55    DWORD dwRawDataSize = 10*1024;                //增加區(qū)段的數(shù)據(jù)大小
             56
             57    DWORD dwTmp=0,dwTmp2=0,dwTmp3 = 0;
             58    
             59    //Dos 頭
             60    //===============================================================================
             61    //打開文件、讀取Dos頭
             62
             63    pszFilePath = argv[0];
             64    pszFilePath = "BeingInjued.exe";//Test
             65
             66    cout<<"PE FileName:"<<pszFilePath<<endl;
             67
             68    if(0 == lstrcmp(pszFilePath,""))
             69    {
             70        cout<<"文件路徑不能為空!"<<endl;
             71        return -1;
             72    }

             73
             74    hFile = CreateFile(pszFilePath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,
             75        FILE_ATTRIBUTE_NORMAL,NULL);
             76
             77    if(INVALID_HANDLE_VALUE == hFile)
             78    {
             79        cout<<"打開文件失敗!"<<endl;
             80        hFile = NULL;
             81        goto Error;
             82    }

             83
             84    dwSizeDos = sizeof(IMAGE_DOS_HEADER);
             85    pDos = new BYTE[dwSizeDos];
             86    memset(pDos,0,dwSizeDos);
             87
             88    if(!ReadFile(hFile,pDos,dwSizeDos,&dwRealRead,NULL))
             89    {
             90        cout<<"讀取Dos頭失敗!"<<endl;
             91        goto Error;
             92    }

             93    cout<<"Dos Header: "<<dwRealRead<<"bytes have read."<<endl;
             94
             95    //獲得IMAGE_DOS_HEADER指針,效驗(yàn)
             96    pIDH = (PIMAGE_DOS_HEADER)pDos;
             97    if(memcmp(&(pIDH->e_magic),"MZ",2)!=0)
             98    {
             99        cout<<"不是有效的PE文件格式!"<<endl;
            100        goto Error;
            101    }

            102
            103    //DOS Stub
            104    //================================================================================
            105    
            106    dwSizeStub = pIDH->e_lfanew - dwSizeDos;
            107    pDos = (BYTE*)realloc(pDos,dwSizeDos + dwSizeStub);
            108    memset(pDos+dwSizeDos,0,dwSizeStub);
            109    
            110    if(!ReadFile(hFile,pDos+dwSizeDos,dwSizeStub,&dwRealRead,NULL))
            111    {
            112        cout<<"讀取DosStub失敗!"<<endl;
            113        goto Error;
            114    }

            115    cout<<"Dos Stub: "<<dwRealRead<<"bytes have read."<<endl;
            116
            117    //NT Header
            118    //================================================================================
            119
            120    dwSizeNT = sizeof(IMAGE_NT_HEADERS);
            121    pNT = new BYTE[dwSizeNT];
            122    memset(pNT,0,dwSizeNT);
            123    
            124    if(!ReadFile(hFile,pNT,dwSizeNT,&dwRealRead,NULL))
            125    {
            126        cout<<"讀取NT Headers失敗!"<<endl;
            127        goto Error;
            128    }

            129    
            130    //獲得NT指針
            131    pINH = (PIMAGE_NT_HEADERS)pNT;
            132    if(memcmp(&(pINH->Signature),"PE",2)!=0)
            133    {
            134        cout<<"錯誤的PE文件格式!"<<endl;
            135        goto Error;
            136    }

            137
            138    //節(jié)表
            139    //================================================================================
            140    
            141    dwSizeSecH = (pINH->FileHeader.NumberOfSections + dwSizeAdd) * sizeof(IMAGE_SECTION_HEADER);
            142    pSecH = new BYTE[dwSizeSecH];
            143    memset(pSecH,0,pINH->FileHeader.NumberOfSections + dwSizeAdd);
            144
            145    ppISH = (PIMAGE_SECTION_HEADER*)new DWORD[pINH->FileHeader.NumberOfSections + dwSizeAdd];
            146    memset(ppISH,0,sizeof(DWORD)*(pINH->FileHeader.NumberOfSections + dwSizeAdd));
            147
            148    for(UINT i=0;i<pINH->FileHeader.NumberOfSections;i++)
            149    {
            150        if(!ReadFile(hFile,pSecH+i*sizeof(IMAGE_SECTION_HEADER),
            151            sizeof(IMAGE_SECTION_HEADER),&dwRealRead,NULL))
            152        {
            153            cout<<"讀取Section Headers失敗!"<<endl;
            154            goto Error;
            155        }

            156        
            157        ppISH[i] = (PIMAGE_SECTION_HEADER)(pSecH+i*sizeof(IMAGE_SECTION_HEADER));
            158        
            159        cout<<"Name: "<<ppISH[i]->Name<<endl;
            160        cout<<"Size: "<<ppISH[i]->SizeOfRawData<<endl;
            161        cout<<"Virtual Adress: "<<ppISH[i]->VirtualAddress<<endl;
            162        cout<<"PointerToRawData: "<<ppISH[i]->PointerToRawData<<endl;
            163    }

            164    cout<<endl;
            165
            166
            167    //節(jié)塊 
            168    //================================================================================
            169
            170    pPrevSec = (BYTE*)malloc(0);
            171    for(i=0;i<pINH->FileHeader.NumberOfSections;i++)
            172    {
            173        dwTmp = ppISH[i]->SizeOfRawData;
            174        pPrevSec = (BYTE*)realloc(pPrevSec,dwTmp2 + dwTmp);
            175        memset(pPrevSec+dwTmp2,0,dwTmp);
            176        
            177        SetFilePointer(hFile,ppISH[i]->PointerToRawData,NULL,FILE_BEGIN);
            178
            179        cout<<i<<":PointerToRawData:"<<ppISH[i]->PointerToRawData<<endl;
            180        cout<<"BlockSize:"<<ppISH[i]->SizeOfRawData<<endl;
            181        cout<<"Virtual Address:"<<ppISH[i]->VirtualAddress<<endl;
            182
            183        if(!ReadFile(hFile,pPrevSec+dwTmp2,dwTmp,&dwRealRead,NULL)){
            184            cout<<"ReadFile Faield!"<<endl;
            185            goto Error;
            186        }

            187
            188        dwTmp2 += dwTmp;
            189    }

            190    dwSizePrevSec = dwTmp2;
            191
            192
            193    //數(shù)據(jù)填補(bǔ)、修改部分
            194    //================================================================================
            195
            196    //第一個節(jié)塊的位置
            197    for(i=0;i<pINH->FileHeader.NumberOfSections;i++)
            198    {
            199        if(ppISH[i])
            200        {
            201            if(0 == dwMiniPointer)
            202                dwMiniPointer = (DWORD)ppISH[i]->PointerToRawData;
            203            
            204            if((ppISH[i]->PointerToRawData)<dwMiniPointer)
            205                dwMiniPointer = (DWORD)ppISH[i]->PointerToRawData;
            206        }

            207    }

            208    cout<<"Prev First Section Pos:"<<dwMiniPointer<<endl;
            209
            210    //空白填充區(qū)大小    ,先計算好
            211    dwTmp = (dwSizeDos+dwSizeStub+dwSizeNT+dwSizeSecH);
            212    if(dwMiniPointer >= dwTmp)
            213        dwSizeDelta = dwMiniPointer - dwTmp;
            214    else
            215    {
            216        dwSizeDelta = dwTmp % (pINH->OptionalHeader.FileAlignment);
            217        
            218        if(dwSizeDelta != 0)
            219            dwSizeDelta = pINH->OptionalHeader.FileAlignment - dwSizeDelta;
            220        else dwSizeDelta = 0;
            221
            222        bNeedModify = TRUE;
            223    }

            224    cout<<"Delta:"<<dwSizeDelta<<endl;
            225    pDelta = new BYTE[dwSizeDelta];
            226    memset(pDelta,0,dwSizeDelta);
            227
            228    dwMiniPointer = dwTmp;
            229    dwMiniPointer += dwSizeDelta;
            230
            231    //修改 NT 頭,必須修改
            232    pINH->FileHeader.NumberOfSections += dwSizeAdd;
            233
            234    
            235    //修改原來節(jié)表頭的文件指針
            236    cout<<endl;
            237    if(bNeedModify)
            238    {
            239        for(i=0;i<(UINT)(pINH->FileHeader.NumberOfSections - dwSizeAdd);i++)
            240        {
            241            if(0 != i)
            242                ppISH[i]->PointerToRawData =
            243                ppISH[i-1]->PointerToRawData +
            244                ppISH[i-1]->SizeOfRawData;
            245            else
            246               ppISH[i]->PointerToRawData = dwMiniPointer;
            247            cout<<"New Entry:"<<i<<""<<ppISH[i]->PointerToRawData<<endl;
            248        }

            249    }

            250
            251    //填充增加的節(jié)表頭
            252    cout<<endl;
            253    char szName[8= ".";
            254    char szNum[7= {0};
            255    szName[5= 0;
            256    dwTmp = ppISH[0]->VirtualAddress;
            257    dwTmp2 = pINH->OptionalHeader.SectionAlignment;
            258    dwTmp3 = pINH->OptionalHeader.FileAlignment;
            259    int nCount = 1;
            260    DWORD dwNewAllocSize = 0;
            261
            262    for(i=(pINH->FileHeader.NumberOfSections - dwSizeAdd);
            263        i<pINH->FileHeader.NumberOfSections;i++)
            264    {                                                   
            265        ppISH[i] = (PIMAGE_SECTION_HEADER)(pSecH+i*sizeof(IMAGE_SECTION_HEADER));
            266        memset(ppISH[i],0,sizeof(IMAGE_SECTION_HEADER));
            267        
            268        ppISH[i]->Characteristics = ppISH[0]->Characteristics;
            269        
            270        sprintf(szNum,"%d",nCount);
            271        memcpy(szName+1,szNum,7);
            272        memcpy(ppISH[i]->Name,szName,8);
            273
            274        dwNewAllocSize = dwRawDataSize % dwTmp3;
            275        if(dwNewAllocSize != 0)
            276           dwNewAllocSize = dwRawDataSize + (dwTmp3 - dwNewAllocSize);
            277        else dwNewAllocSize = dwRawDataSize;
            278        ppISH[i]->SizeOfRawData = dwNewAllocSize;
            279
            280        //增加的文件區(qū)段
            281        dwSizeAddSec += ppISH[i]->SizeOfRawData;
            282        
            283        dwNewAllocSize = dwRawDataSize % dwTmp2;
            284        if(dwNewAllocSize != 0)
            285           dwNewAllocSize = dwRawDataSize + (dwTmp2 - dwNewAllocSize);
            286        else dwNewAllocSize = dwRawDataSize;
            287
            288        ppISH[i]->Misc.VirtualSize = dwNewAllocSize;
            289
            290        //修改NT頭,必須修改
            291        pINH->OptionalHeader.SizeOfImage += dwNewAllocSize;
            292
            293        ppISH[i]->PointerToRawData = (ppISH[i-1]->PointerToRawData+ppISH[i-1]->SizeOfRawData);         
            294
            295        ppISH[i]->VirtualAddress = ppISH[i]->PointerToRawData;
            296        if(ppISH[i]->VirtualAddress>=(0x7FFFFFFF-dwNewAllocSize))
            297        {
            298            cout<<"Error!Virtual address overflow!"<<endl;
            299            goto Error;
            300        }

            301        cout<<"New Entry:"<<i<<""<<ppISH[i]->PointerToRawData<<endl;
            302        nCount++;
            303    }

            304
            305    //修改NT頭,可選,不設(shè)置也能正常運(yùn)行,但是為保證數(shù)據(jù)準(zhǔn)確,還是寫上
            306    pINH->OptionalHeader.SizeOfHeaders = dwMiniPointer;
            307
            308
            309
            310    //新的Sections,必須滿足文件對齊
            311    pAddSec = new BYTE[dwSizeAddSec];
            312    memset(pAddSec,0,dwSizeAddSec);
            313
            314    //重建文件: dumpOK.exe
            315    //================================================================================
            316
            317    CloseHandle(hFile);
            318    hFile = CreateFile("dumpOK.exe",GENERIC_READ|GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,
            319        FILE_ATTRIBUTE_NORMAL,NULL);
            320    
            321    //Dos Data
            322    if(!WriteFile(hFile,pDos,dwSizeDos+dwSizeStub,&dwRealRead,NULL))
            323    {
            324        cout<<"WriteFile Faield!"<<endl;
            325        goto Error;
            326    }

            327    cout<<"Dos Data:"<<dwRealRead<<" bytes write."<<endl;
            328
            329
            330    //NT 頭
            331    if(!WriteFile(hFile,pNT,dwSizeNT,&dwRealRead,NULL))
            332    {
            333        cout<<"WriteFile Faield!"<<endl;
            334        goto Error;
            335    }

            336    cout<<"NT Data:"<<dwRealRead<<" bytes write."<<endl;
            337
            338    //節(jié)表  (包括新加的)
            339    if(!WriteFile(hFile,pSecH,dwSizeSecH,&dwRealRead,NULL))
            340    {
            341        cout<<"WriteFile Faield!"<<endl;
            342        goto Error;
            343    }

            344    cout<<"Section Headers:"<<dwRealRead<<" bytes write."<<endl;
            345
            346    //填充空白數(shù)據(jù)
            347    if(!WriteFile(hFile,pDelta,dwSizeDelta,&dwRealRead,NULL)){
            348        cout<<"WriteFile Faield!"<<endl;
            349        goto Error;
            350    }

            351    cout<<"Delta Data:"<<dwRealRead<<" bytes write."<<endl;
            352
            353
            354    //原來的節(jié)塊
            355    if(!WriteFile(hFile,pPrevSec,dwSizePrevSec,&dwRealRead,NULL)){
            356        cout<<"WriteFile Faield!"<<endl;
            357        goto Error;
            358    }

            359    cout<<"Section Blocks:"<<dwRealRead<<" bytes write."<<endl;
            360
            361    //增加的節(jié)塊
            362    if(!WriteFile(hFile,pAddSec,dwSizeAddSec,&dwRealRead,NULL)){
            363        cout<<"WriteFile Faield!"<<endl;
            364        goto Error;
            365    }

            366    cout<<"Section Blocks:"<<dwRealRead<<" bytes write."<<endl;
            367    cout<<"Requeried Works Success Completed."<<endl;
            368
            369Error:
            370    CloseHandle(hFile);
            371    delete[]ppISH;        
            372    delete[]pDos;
            373    delete[]pNT;
            374    delete[]pSecH;
            375    delete[]pDelta;
            376    delete[]pPrevSec;
            377    delete[]pAddSec;
            378    return 0;
            379}

            380
            381
            382
            383
            384


                  如果代碼有什么謬誤或你有更好的解決方案,請留言或者EmailToMe:xiaolu69soft@yahoo.com.cn
            希望我的文章對你有所幫助。
                  rawdata
            posted on 2009-01-20 10:54 星綻紫輝 閱讀(3396) 評論(13)  編輯 收藏 引用

            Feedback

            # re: 給PE文件增加多個區(qū)段(sections) 2009-01-20 11:14 true
            雖然我主要在linux下工作,但還是挺你一把,文章寫的很認(rèn)真  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-01-20 15:48 星綻紫輝
            呵呵~thx  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-03-16 23:58 passenger
            問個問題。。。
            這段代碼是從文件頭開始讀,還是從DOS頭的尾部開始?
            if(!ReadFile(hFile,pDos+dwSizeDos,dwSizeStub,&dwRealRead,NULL))

            (按照我的理解,這是從DOS頭開始讀地,那讀的就不是DOSSTUB了??)
            可以麻煩樓主幫我解釋一下嗎??  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-03-17 18:02 星綻紫輝
            這段代碼是在先讀取DOS頭后,在進(jìn)行DOSStub的讀取,你可以注意到讀取大小為:dwSizeStub  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-03-17 18:02 星綻紫輝
            讀的就是stub  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-03-17 21:13 passenger
            哦~謝謝博主,大概明白了,原來讀文件指針會移動到那而不會歸原位。
            最近才開始學(xué)用WIN API函數(shù),不是很懂,學(xué)生,呵呵~·  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-06-13 21:42 jiangming
            296if(ppISH[i]->VirtualAddress>=(0x7FFFFFFF-dwNewAllocSize))
            297 {
            298 cout<<"Error!Virtual address overflow!"<<endl;
            299 goto Error;
            300 }
            VirtualAddress是RVA,這里應(yīng)該不能這么寫吧?
            應(yīng)該改為if(ppISH[i]->VirtualAddress+ImageBase>=(0x7FFFFFFF-dwNewAllocSize))
            {
            cout<<"Error!Virtual address overflow!"<<endl;
            goto Error;
            }
            純屬個人看法?
            能否請博主給點(diǎn)意見,本人純屬菜鳥,不當(dāng)之處,請不要見怪
              回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-06-14 02:12 星綻紫輝
            其實(shí)這2種寫法都不盡正確,本意是不希望新分配的進(jìn)程內(nèi)部節(jié)總空間大小不超過4GB,實(shí)際其實(shí)遠(yuǎn)比這還小,因?yàn)檫€有系統(tǒng)空間。這和基址沒多大關(guān)系,不管映像在什么基址,總把它看成是0-4GB的大小空間。我要保證RVA(偏移值:即之前所有的節(jié)的大小)不超過某個值即可。在這里的判斷其實(shí)沒多大意義,新分配的節(jié)RVA離<4GB相當(dāng)遙遠(yuǎn)。當(dāng)然,如果超過了這個值會怎么樣,PE是否還能正常運(yùn)行?系統(tǒng)會報錯嗎?我沒有測試,你有興趣的話可以測測看,或許能找到那個臨界值。

            呵呵,其實(shí)我也是菜鳥,大家互相學(xué)習(xí)了。
              回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-06-15 10:29 jiangming
            博主你好,謝謝你能給我解答,可是我還有點(diǎn)疑問,你使用的OS版本多少吶?
            您的代碼在我機(jī)器(XP SP3)上測試,生成的dump.exe不能運(yùn)行,提示“不是有效的win32應(yīng)用程序”,我有點(diǎn)小不解,當(dāng)然我選擇的程序都是dwFileAlignment = dwSectionAlignment的程序。你能在百忙之中再給我點(diǎn)暗示嗎?謝謝了  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-06-15 19:59 星綻紫輝
            我用的是XP SP2版本,測試通過。到底跟OS版本有沒有關(guān)系,我沒有測試過,你可以在虛擬機(jī)下測試。如果程序不能運(yùn)行,最好的調(diào)試方法是用一些PE分析工具(如:PE Explorer, LoadPE, WinHex) 等查看原來的PE文件和新的修改的PE文件,然后進(jìn)行對比分析。我認(rèn)為不能運(yùn)行的可能的原因有:1.沒有實(shí)現(xiàn)文件對齊與內(nèi)存對齊的一致性2.節(jié)參數(shù)設(shè)置不正確3.新節(jié)首地址計算有誤。  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2009-06-16 01:01 jiangming
            博主,您好,很高興您能為我解答,我用stu_PE查看了,似乎沒有毛病。。。
            我的QQ:386090083,很熱切希望博主您有時間加下,幫我解決下疑難問題。
            拜謝!!!  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2010-01-06 10:33 asmbull
            這是我看到的最負(fù)責(zé)的對PE文件如何去修改的文章,雖然我自己也對PE文件有研究,不過在我明白這些之前,也確實(shí)走了很多的彎路,以至于有的時候反而弄不明白,可能是我比較笨吧。就代碼而言,樓主的code確實(shí)可以可以讓很多人不用去費(fèi)力的想很多的事了。  回復(fù)  更多評論
              

            # re: 給PE文件增加多個區(qū)段(sections) 2012-08-14 23:24 ssss
            破壞了輸入輸出函數(shù)表!所有不是有效的win32程序  回復(fù)  更多評論
              


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            亚洲级αV无码毛片久久精品| 国产精品亚洲综合专区片高清久久久| 久久精品国产影库免费看| 久久综合久久美利坚合众国| 久久久精品日本一区二区三区| 99久久国产免费福利| 国产精品99久久精品爆乳| 国产激情久久久久影院| 狠狠色综合网站久久久久久久| 国产精品美女久久久免费| 久久久久18| 久久伊人五月丁香狠狠色| 久久婷婷成人综合色综合| 久久国产色AV免费看| 亚洲狠狠久久综合一区77777| 精品久久久久久99人妻| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 色综合色天天久久婷婷基地| 久久精品一本到99热免费| 久久精品中文字幕大胸| 亚洲精品白浆高清久久久久久| 久久w5ww成w人免费| 99久久精品免费观看国产| 久久久久国产成人精品亚洲午夜| 欧美久久久久久精选9999| 97精品伊人久久久大香线蕉| 久久久久AV综合网成人| 国产精品99久久久久久猫咪| 中文字幕亚洲综合久久菠萝蜜| 人妻久久久一区二区三区| 国产亚州精品女人久久久久久| 久久久久国产精品嫩草影院| 国产成人久久AV免费| 一本色道久久88综合日韩精品| 久久人人妻人人爽人人爽| 国产精品久久久久久久午夜片| 国产精品久久新婚兰兰| 伊人色综合久久天天| 精品无码久久久久久尤物| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久亚洲国产精品一区二区|