青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 33,  comments - 33,  trackbacks - 0

 編譯過的二進制代碼本身是一種數據結構,在代碼被載入內存執行的時候,由操作系統對這種數據結構進行操作,具體到Win32平臺,就是所謂的PE文件頭。
 對于Windows系統,源代碼是如何轉化為二進制代碼?全局變量存儲在什么地方,如何初始化?共享變量是如何工作?理解PE文件格式能更好地理解上面的問題.舉個例子,我們使用C++編寫源代碼,這些源代碼被編譯器翻譯成obj格式的目標文件,每一個目標文件都包含著全局變量、常量數據、資源、可執行代碼、用于鏈接的符號名以及調試信息。模塊的目標文件通過鏈接器與庫鏈接在一起,而庫自身是一種將目標文件組合在一起的格式。此外,鏈接器將所有已經初始化的全局變量合并到一個段中,將所有未初始化的全局變量合并到另一個段中,再將所有的執行代碼放入到另一個段中等。為什么要將目標文件的不同部分進行分組分段呢?主要是保護資源和優化資源的使用。例如常數和可執行代碼是只讀的,如果操作系統檢測到對這部分內存進行寫操作時,就會發出錯誤。又例如,所有的Win32程序都是用同一個gdi32.dll,這樣就優化了內存的使用,gdi32.dll的可執行代碼段自在內存中存儲一次。
 PE文件格式

PE格式保留了多個目錄,通常可以看到的目錄有導入、綁定導入、延遲導入、到處、重定位、資源和調試信息。將這些段和目錄組合在一起,

加上兩個頭,就成為了PE文件。
 -----------------
|IMAGE_DOS_HEADER | : 兼容DOS程序運行
|-----------------|
|DOS 存根程序     | : 小程序,用于顯示錯誤信息的軟件中斷然后退出,
|-----------------|
|PE Header        | : 真正的PE頭
|-----------------|
|Section Table    |  : 段表
|-----------------|
|Section 1        |
|-----------------|
|Section 2        |
|-----------------|
|Section ...      |
|-----------------|
|Section n        |
 --------------
對于DOS存根程序,由于存根程序長度不定,所以要DOS頭的e_lfanew確定偏移。
段的名稱和作用如下:
節名   作用
.arch  最初的構建信息(Alpha Architecture Information)
.bss   未經初始化的數據
.CRT   C運行期只讀數據
.data   已經初始化的數據
.debug   調試信息
.didata  延遲輸入文件名表
.edata  導出文件名表
.idata  導入文件名表
.pdata      異常信息(Exception Information)
.rdata  只讀的初始化數據
.reloc  重定位表信息
.rsrc  資源
.text   .exe或.dll文件的可執行代碼
.tls  線程的本地存儲器
.xdata  異常處理表

PE文件存儲的地址有些以虛擬地址的形式存儲,不過一旦其相應模塊被加載,它們就可以使用。下面編寫一個簡單的PEFile的C++類,來說明
PE文件的使用。
我們要實現一個小小的鉤子程序,將MessageBoxA改成我們自己設定的程序中去,由于程序比較簡單,不再贅述,詳見程序中的注釋。
PEFile.h

 

#ifndef PE_FILE_H
#define PE_FILE_H

class PEFile
{
public:
    PEFile(HMODULE _hModule);
    
const void* getDirectory(int _id);
    PIMAGE_IMPORT_DESCRIPTOR getImportDescriptor(LPCSTR _pDllName);
    
const unsigned * getFunctionPtr(PIMAGE_IMPORT_DESCRIPTOR _pImport,LPCSTR _pProcName);
    FARPROC setImportAddress(LPCSTR _pDllName,LPCTSTR _pProcName,FARPROC _pNewProc);
    FARPROC setExportAddress(LPCSTR _pProcName,FARPROC _pNewProc);
private:
    
const char* m_pModule;//模塊
    PIMAGE_DOS_HEADER m_pDOSHeader;//DOS頭
    PIMAGE_NT_HEADERS m_pNTHeader;//NT頭
}
;
#endif


PEFile.cpp

#include <Windows.h>
#include 
"PEFile.h"

PEFile::PEFile(HMODULE _hModule)
{
    m_pModule 
= (const char*)_hModule;
    
if (IsBadReadPtr(m_pModule,sizeof(IMAGE_DOS_HEADER)))
    
{
        m_pDOSHeader 
= 0;
        m_pNTHeader 
= 0;
    }

    
else
    
{
        m_pDOSHeader 
= (PIMAGE_DOS_HEADER)m_pModule;
        
if (IsBadReadPtr(m_pModule + m_pDOSHeader->e_lfanew,sizeof(IMAGE_NT_HEADERS)))
        
{
            m_pNTHeader 
= 0;
        }

        
else
        
{
            m_pNTHeader 
= (PIMAGE_NT_HEADERS)(m_pModule + m_pDOSHeader->e_lfanew);
        }

    }

}


const void* PEFile::getDirectory(int _id)
{
    
return m_pModule + (m_pNTHeader->OptionalHeader.DataDirectory[_id].VirtualAddress);
}


//返回引入的模塊
PIMAGE_IMPORT_DESCRIPTOR PEFile::getImportDescriptor(LPCSTR _pDllName)
{
    PIMAGE_IMPORT_DESCRIPTOR pImport 
= (PIMAGE_IMPORT_DESCRIPTOR)getDirectory(IMAGE_DIRECTORY_ENTRY_IMPORT);
    
if (pImport == 0)
    
{
        
return 0;
    }

    
//一個一個查找
    while(pImport->FirstThunk)
    
{
        
if (stricmp(_pDllName,m_pModule + pImport->Name) == 0)
        
{
            
return pImport;
        }

        
++pImport;
    }

    
return 0;
}


//返回引入的函數
const unsigned * PEFile::getFunctionPtr(PIMAGE_IMPORT_DESCRIPTOR _pImport,LPCSTR _pProcName)
{
    PIMAGE_THUNK_DATA pThunk 
= (PIMAGE_THUNK_DATA)(m_pModule + _pImport->OriginalFirstThunk);
    
//一個一個查找
    for (int i = 0; pThunk->u1.Function ; ++i)
    
{
        
bool isMatch = false;
        
if (pThunk->u1.Ordinal & 0x80000000)
        
{
            isMatch 
= (pThunk->u1.Ordinal & 0xFFFF== ((DWORD)_pProcName);
        }

        
else
        
{
            isMatch 
= stricmp(_pProcName,(m_pModule + ((unsigned)pThunk->u1.AddressOfData +2 ))) == 0;
        }


        
if (isMatch)
        
{
            
return ((unsigned *)(m_pModule + _pImport->FirstThunk)) + i;
        }

        
++pThunk;
    }

    
return 0;
}


//設定導入的函數地址
FARPROC PEFile::setImportAddress(LPCSTR _pDllName,LPCTSTR _pProcName,FARPROC _pNewProc)
{
    PIMAGE_IMPORT_DESCRIPTOR pImport 
= getImportDescriptor(_pDllName);
    
if (pImport)
    
{
        
//拿到某模塊的某函數地址
        const unsigned* pfn = getFunctionPtr(pImport,_pProcName);
        
if (IsBadReadPtr(pfn,sizeof(DWORD)))
        
{
            
return 0;
        }

        FARPROC oldproc 
= (FARPROC)*pfn;

        
//寫入自定的函數地址
        DWORD dwWritten;
        WriteProcessMemory(GetCurrentProcess(),(
void*)pfn,&_pNewProc,sizeof(DWORD),&dwWritten);
        
return oldproc;
    }

    
return 0;
}


//導出目錄
FARPROC PEFile::setExportAddress(LPCSTR _pProcName,FARPROC _pNewProc)
{
    PIMAGE_EXPORT_DIRECTORY pExport 
= (PIMAGE_EXPORT_DIRECTORY)getDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT);
    
if (pExport == 0)
    
{
        
return 0;
    }

    unsigned ord 
= 0;
    
if ((unsigned)_pProcName < 0xFFFF)
    
{
        ord 
= (unsigned)_pProcName;
    }

    
else
    
{
        
const DWORD* pNames = (const DWORD*)(m_pModule + pExport->AddressOfNames);
        
const WORD* pOrds = (const WORD*)(m_pModule + pExport->AddressOfNameOrdinals);
        
for (unsigned i = 0; i < pExport->AddressOfNames; ++i)
        
{
            
if (stricmp(_pProcName,m_pModule + pNames[i]) == 0)
            
{
                ord 
= pExport->Base + pOrds[i];
                
break;
            }

        }

    }

    
if ( (ord < pExport->Base) || (ord > pExport->NumberOfFunctions))
    
{
        
return 0;
    }

    DWORD 
*pRVA = ((DWORD*)(m_pModule + pExport->AddressOfFunctions)) + ord - pExport->Base;
    DWORD rslt 
= *pRVA;
    DWORD dwWritten 
= 0;
    DWORD newRVA 
= (DWORD)_pNewProc - (DWORD)m_pModule;
    WriteProcessMemory(::GetCurrentProcess(),pRVA,
&newRVA,sizeof(DWORD),&dwWritten);
    
return (FARPROC)(m_pModule + rslt);
}


測試代碼:

#include <Windows.h>
#include 
"PEFile.h"


int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR pText,LPCSTR pCaption,UINT uType)
{
    
char buf1[128];
    
char buf2[128];
    strcpy(buf1,pCaption);
    strcat(buf1,
"  -  catch!");

    strcpy(buf2,pText);
    strcat(buf2,
"  -  catch!");

    
return MessageBoxExA(hWnd,buf2,buf1,uType,0);
}


int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
    
{
        PEFile pe(hInstance);
        pe.setImportAddress(
"user32.dll","MessageBoxA",(FARPROC)MyMessageBoxA);
        MessageBoxA(
0,"Test","SetImportAddresss",MB_OK);
    }

    HMODULE hUser 
= GetModuleHandle("user32.dll");
    PEFile user32(hUser);
    FARPROC oldproc 
= GetProcAddress(hUser,"MessageBoxA");
    user32.setExportAddress(
"MessageBoxA",(FARPROC)MyMessageBoxA);
    FARPROC newproc 
= GetProcAddress(hUser,"MessageBoxA");
    
char temp[64];
    wsprintf(temp, 
"GetProcAddress(MessageBoxA)\n"
        
"changes from %x to %x", oldproc, newproc);
    MessageBoxA(NULL, temp, 
"SetExportAddress", MB_OK);
    
return 0;
}


運行一下可以發現,MessageBoxA已經變成自定義的函數,并且使用導出目錄的方法導出函數,GetProcAddress將返回新函數的地址,將來DLL載入此進程時也會和新函數鏈接。



 

posted on 2011-09-02 20:18 bennycen 閱讀(2379) 評論(2)  編輯 收藏 引用 所屬分類: Windows Programming
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            91久久在线播放| 亚洲特色特黄| 亚洲欧美另类在线观看| 亚洲精品一二区| 99热精品在线观看| 在线亚洲免费视频| 亚洲一区二区精品在线观看| 亚洲欧美日本伦理| 久久久久久久久岛国免费| 久久一区欧美| 亚洲精选中文字幕| 欧美一区二区在线| 女仆av观看一区| 欧美午夜精品久久久久久人妖| 国产精品美女999| 在线看无码的免费网站| 99精品免费视频| 久久成人资源| 亚洲国产精品ⅴa在线观看| 亚洲日本激情| 欧美在线播放一区二区| 欧美精品亚洲精品| 国产欧美韩日| 亚洲精选视频在线| 久久精品一区蜜桃臀影院| 欧美激情一区二区三区| 亚洲视频专区在线| 久久夜色精品一区| 国产精品久久福利| 亚洲日本中文字幕| 欧美主播一区二区三区| 91久久夜色精品国产网站| 欧美影片第一页| 欧美日韩成人在线视频| 精品二区久久| 久久不见久久见免费视频1| 亚洲国产二区| 久久久久九九九| 国产精品一区二区在线| 欧美日本一区二区三区| 黄色亚洲精品| 久久国产一区| 亚洲女同同性videoxma| 欧美精品在线观看播放| 国产一区二区三区观看| 午夜精品区一区二区三| 一本色道久久99精品综合 | 国产欧美日韩精品丝袜高跟鞋| 亚洲欧美国产日韩天堂区| 久久免费国产精品| 国产欧美日韩免费| 亚洲男女毛片无遮挡| 99精品国产福利在线观看免费| 蜜桃精品久久久久久久免费影院| 狠狠爱www人成狠狠爱综合网| 久久国产精品一区二区三区四区| 洋洋av久久久久久久一区| 欧美精品久久99| 亚洲精品中文字幕在线观看| 欧美阿v一级看视频| 久久久久久9999| 黄色成人av网| 欧美国产日韩一区| 女同性一区二区三区人了人一 | 欧美伊人久久久久久久久影院| 国产精品看片你懂得| 亚洲视频一区在线观看| 夜夜精品视频| 国产精品夜色7777狼人| 午夜精品偷拍| 销魂美女一区二区三区视频在线| 国产欧美一区二区精品忘忧草 | 久久在线免费| 亚洲人屁股眼子交8| 亚洲人人精品| 欧美日韩国产bt| 亚洲制服少妇| 欧美一二三区精品| 在线观看亚洲精品视频| 欧美成人一区二区| 你懂的国产精品永久在线| 亚洲精品国产品国语在线app| 亚洲人成久久| 国产精品天美传媒入口| 久久躁狠狠躁夜夜爽| 欧美乱大交xxxxx| 性欧美大战久久久久久久免费观看| 欧美一区二区在线| 99亚洲一区二区| 午夜久久久久久| 亚洲欧洲日韩女同| 一区二区av在线| 红杏aⅴ成人免费视频| 亚洲黄色性网站| 国产热re99久久6国产精品| 欧美顶级少妇做爰| 国产精品夜夜嗨| 亚洲激情视频| 国产一区亚洲一区| 亚洲伦理中文字幕| 激情亚洲成人| 一区二区av在线| 在线精品国产欧美| 亚洲一级二级在线| 亚洲人成7777| 久久精品人人做人人爽| 欧美日韩中文在线观看| 亚洲电影专区| 欧美日韩国产不卡| 久久久久.com| 国产精品国产福利国产秒拍| 农村妇女精品| 99国产一区| 久久精品在线视频| 亚洲国产第一页| 亚洲欧美视频| 在线观看日韩av| 欧美日韩精品三区| 亚洲女性裸体视频| 欧美成人午夜剧场免费观看| 日韩亚洲综合在线| 国产精品亚洲综合久久| 久久婷婷激情| 亚洲日本一区二区| 午夜亚洲性色福利视频| 黄色免费成人| 欧美日韩美女在线观看| 亚洲欧美在线另类| 欧美大片91| 性欧美大战久久久久久久免费观看| 国产一区二区三区高清播放| 欧美电影免费观看大全| 亚洲天堂av高清| 欧美国产大片| 亚洲欧美变态国产另类| 精品成人一区二区| 欧美日韩精品一区二区天天拍小说| 午夜免费日韩视频| 亚洲人成免费| 开心色5月久久精品| 亚洲欧美日韩精品| 伊人久久成人| 国产精品免费网站在线观看| 六十路精品视频| 午夜精品三级视频福利| 亚洲精品国产视频| 蜜桃久久精品乱码一区二区| 亚洲欧美大片| 一本一本久久| 亚洲二区视频在线| 国产日韩一区二区三区在线| 欧美日韩色婷婷| 老牛影视一区二区三区| 午夜久久久久久| 一区二区日韩欧美| 亚洲电影在线免费观看| 久久综合狠狠综合久久激情| 亚洲午夜三级在线| 亚洲日本在线观看| 在线观看日韩av先锋影音电影院| 国产精品黄色| 欧美日韩国产小视频在线观看| 久久久国产精品一区二区中文| 亚洲线精品一区二区三区八戒| 亚洲国产小视频在线观看| 另类成人小视频在线| 久久成人免费网| 欧美一级专区免费大片| 在线午夜精品自拍| 亚洲区一区二| 亚洲国产欧美日韩精品| 亚洲第一精品夜夜躁人人爽| 国产一本一道久久香蕉| 国产精品视频大全| 欧美午夜不卡视频| 欧美日韩中字| 国产精品久久久久毛片软件| 欧美午夜在线观看| 欧美午夜精品久久久久免费视| 在线视频亚洲一区| 亚洲伦理在线| 一区二区久久久久久| 一区二区欧美视频| 在线中文字幕不卡| 一本色道精品久久一区二区三区| 日韩一级黄色av| 一本色道久久| 亚洲一区二区在线视频| 亚洲专区免费| 性色av一区二区三区红粉影视| 欧美亚洲一区二区在线观看| 欧美在线网址| 美女精品在线观看| 欧美国产先锋| 欧美午夜欧美| 国产视频一区二区三区在线观看| 国产亚洲精品一区二区| 欲香欲色天天天综合和网| 亚洲国产成人不卡| 一本色道久久综合精品竹菊|