[大家好,在写输入表这一部分的时候,主要是为了自己能更加深入的理解PE文件格式; 输入表的部分代码参考了北极星2003老兄的一部分,然而发现,在北极星2003写的那个pe文件分析器导入表部分,它用了firstThunk 作为指针来输出Thunk rva 和函数名,由于在内存映射时改变FirstThunk中的数据,所以函数名就怎么都显示不出来了; 由于打算将这个PE文件分析器继续写下去,所以在完成每一部分后,我会将源代码发出;以便大家学习讨论,共同进步,也希望大家能对程序做些改进,而不是简单的复制粘贴代码,由于临近期末,所以时间不多,进度也就慢了点;大家多包涵;
这里给大家两个截图
源代码中Exe文件被剔除,为了减少空间;大家用Visual C++ 6.0 编译下就可以了;
#include<windows.h>
#include <commctrl.h>
#include "resource.h"
#ifndef _IMAGEHLP_H
#include "imagehlp.h"
#pragma comment ( lib, "imagehlp.lib" )
#endif
/*-----------------------------
全局变量定义
-----------------------------*/
HINSTANCE hInst;
HANDLE hFile,hFileMap;
LPVOID lpMemory;
PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
PIMAGE_FILE_HEADER pFileHeader = NULL;
PIMAGE_SECTION_HEADER pSectionHeader = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
/*----------------------------------
对话框函数说明
*---------------------------------*/
BOOL CALLBACK DlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam);
BOOL CALLBACK DataDlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam);
BOOL CALLBACK ImportDlgProc(HWND hDlg, UINT message,WPARAM wParam,LPARAM lparam);
/*----------------------------------
数据显示函数说明
*---------------------------------*/
void ShowSection(HWND hDlg);
void ShowDataDirectoryInDlg ( HWND hwnd );
void ShowSectionTable(HWND hDlg,PIMAGE_FILE_HEADER pFileHeader,PIMAGE_SECTION_HEADER pSectionHeader);
void ShowImportDescInfo(HWND hDlg);
void ShowDllFunction( HWND hDlg, int index );
/*----------------------------------
控件初始化函数说明
*---------------------------------*/
BOOL WINAPI InitListViewColumns(HWND hDlg);
BOOL WINAPI InitImportDescriptor(HWND hDlg);
/*----------------------------------
Pe文件处理函数函数说明
*---------------------------------*/
BOOL IsPeFile(LPVOID ImageBase);
PIMAGE_NT_HEADERS GetNtHeader(LPVOID ImageBase);
PIMAGE_FILE_HEADER WINAPI GetFileHeader(LPVOID Imagebase);
PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase);
PIMAGE_SECTION_HEADER GetFirstSectionHeader(PIMAGE_NT_HEADERS pNtHeader);
PIMAGE_IMPORT_DESCRIPTOR GetFirstImportDesc(LPVOID ImageBase);
/*----------------------------------
主函数入口
*---------------------------------*/
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowcmd)
{
hInst = hInstance;
DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG),NULL,DlgProc);
return 0;
}
/*----------------------------------
主程序对话框函数
*---------------------------------*/
BOOL CALLBACK DlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
{
HMENU hMenu = GetMenu(hDlg);
OPENFILENAME FileName = {0,0,0},
*lpFileName = &FileName;
TCHAR szPe[]="\"PE File(*.exe)\" \0*.exe;*.dll;*.scr;*.fon;*.drv;\0\"*.All File(*.*) \0*.*\0\0";
TCHAR szFileName[256]={""};
TCHAR buf[16];
LVITEM lvItem;
ZeroMemory(&lvItem,sizeof(LVITEM));
switch(message)
{
case WM_INITDIALOG:
EnableMenuItem(hMenu,IDM_DATA_DIRECTORY,MF_GRAYED);
InitListViewColumns(hDlg);
break;
case WM_CLOSE:
UnmapViewOfFile(lpMemory);
CloseHandle(hFileMap);
CloseHandle(hFile);
EndDialog(hDlg,NULL);
EndDialog(hDlg,NULL);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_DATA_DIRECTORY:
DialogBox(hInst,MAKEINTRESOURCE(IDD_DATA_DIRECTORY),hDlg,DataDlgProc);
break;
case IDM_EXIT:
UnmapViewOfFile(lpMemory);
CloseHandle(hFileMap);
CloseHandle(hFile);
EndDialog(hDlg,NULL);
break;
case IDM_OPEN:
FileName.hInstance = (HINSTANCE)hDlg;
FileName.hwndOwner = hDlg;
FileName.lStructSize = sizeof(OPENFILENAME);
FileName.lpstrFilter = szPe;
FileName.lpstrFile = szFileName;
FileName.Flags = OFN_FILEMUSTEXIST||OFN_PATHMUSTEXIST;
FileName.nMaxFile = sizeof(szFileName);
if(!GetOpenFileName(lpFileName))
{
MessageBox(hDlg,"GetOpenFileName 调用失败","ERROR",NULL);
break;
}
SetDlgItemText(hDlg,IDC_FILENAME,szFileName);
hFile = CreateFile(FileName.lpstrFile, // open pe file
GENERIC_READ, // open for reading
FILE_SHARE_READ|| FILE_SHARE_WRITE, // share for reading
NULL, // no security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
MessageBox(hDlg,"Could not open file.","ERROR",MB_ICONERROR);
break;// process error
}
if(GetFileSize(hFile,NULL)!=0)
{
hFileMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
if(hFileMap!=0)
{
lpMemory = MapViewOfFile(hFileMap,FILE_MAP_READ,NULL,NULL,NULL);
}
}
if(IsPeFile(lpMemory))
{
pNtHeader = GetNtHeader(lpMemory);
pFileHeader = GetFileHeader(lpMemory);
pOptionHeader = GetOptionalHeader(lpMemory);
pSectionHeader = GetFirstSectionHeader(pNtHeader);
if(!(pFileHeader&&pOptionHeader))
{
MessageBox(hDlg,"获取文件头指针失败","PEINFO",MB_ICONERROR);
break;
}
else
{
wsprintf(buf,"%04lX",pFileHeader->Machine);
SetDlgItemText(hDlg,IDC_MACHINE,buf);
wsprintf(buf,"%04lX",pFileHeader->NumberOfSections);
SetDlgItemText(hDlg,IDC_NUMSECTION,buf);
wsprintf(buf,"%04lX",pOptionHeader->Magic);
SetDlgItemText(hDlg,IDC_MAGIC,buf);
wsprintf(buf,"%08lX",pOptionHeader->AddressOfEntryPoint);
SetDlgItemText(hDlg,IDC_ENTERPOINT,buf);
ShowSectionTable(hDlg,pFileHeader,pSectionHeader);
}
}
else
{
MessageBox(hDlg,"你选择的不是PE文件","error",MB_ICONERROR);
SendMessage(hDlg,WM_CLOSE,NULL,NULL);
}
EnableMenuItem(hMenu,IDM_DATA_DIRECTORY,MF_ENABLED);
break;
}
}
return FALSE;
}
/*--------------------------------
数据目录对话框的关联函数,
------------------------------*/
BOOL CALLBACK DataDlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
ShowDataDirectoryInDlg ( hDlg );
break;
case WM_CLOSE:
EndDialog(hDlg,NULL);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_IMDLG:
DialogBox((HINSTANCE)GetModuleHandle(0),MAKEINTRESOURCE(IDD_IMPORT_DLG),hDlg,ImportDlgProc);
break;
}
}
return FALSE;
}
BOOL CALLBACK ImportDlgProc(HWND hDlg, UINT message,WPARAM wParam,LPARAM lparam)
{
switch(message)
{
case WM_INITDIALOG:
InitImportDescriptor( hDlg);
ShowImportDescInfo(hDlg);
break;
case WM_CLOSE:
EndDialog(hDlg,NULL);
break;
case WM_NOTIFY:
switch ( LOWORD(wParam) )
{
case IDC_IMPORT_DESCRIPTOR:
switch ( ((LPNMHDR)lparam)->code)
{
case LVN_ITEMCHANGED:
LPNMLISTVIEW temp = ( (LPNMLISTVIEW)lparam ) ;
if( temp->uNewState )
{
ShowDllFunction ( hDlg, ( (LPNMLISTVIEW)lparam )->iItem ) ;
}
break ;
}
return TRUE ;
}
break ;
}
return FALSE;
}
/*------------------------------------
用于显示数据目录表的函数
--------------------------------*/
void ShowDataDirectoryInDlg ( HWND hDlg )
{
typedef struct
{
UINT ID_RVA;
UINT ID_SIZE;
} DataDir_EditID;
DataDir_EditID DataDirEditId[]=
{
{ IDC_EXPORT_RAV, IDC_EXPORT_SIZE },
{ IDC_IMPORT_RVA, IDC_IMPORT_SIZE },
{ IDC_RES_RVA, IDC_RES_SIZE },
{ IDC_EXCEPTION_RVA, IDC_EXCEPTION_SIZE },
{ IDC_SECURITY_RVA, IDC_SECURITY_SIZE },
{ IDC_BASE_RVA, IDC_BASE_SIZE },
{ IDC_DEBUG_RVA, IDC_DEBUG_SIZE },
{ IDC_COPYRIGHT_RVA, IDC_COPYRIGHT_SIZE },
{ IDC_GLOBAL_RVA, IDC_GLOBAL_SIZE },
{ IDC_THREAD_RVA, IDC_THREAD_SIZE },
{ IDC_LOAD_RVA, IDC_LOAD_SIZE },
{ IDC_BOUND_RVA, IDC_BOUND_SIZE },
{ IDC_IAT_RVA, IDC_IAT_SIZE },
{ IDC_DELAY_RVA, IDC_DELAY_SIZE },
{ IDC_COM_RVA, IDC_COM_SIZE }
};
/*----------------------------
循环显示数据目录表
------------------------------*/
TCHAR buff[16];
for (int j=0; j< 15; j++ )
{
wsprintf ( buff, "%08lX", pOptionHeader->DataDirectory[j].VirtualAddress ) ;
SetWindowText ( GetDlgItem ( hDlg, DataDirEditId[j].ID_RVA ), buff ) ;
wsprintf ( buff, "%08lX", pOptionHeader->DataDirectory[j].Size ) ;
SetWindowText ( GetDlgItem ( hDlg, DataDirEditId[j].ID_SIZE ), buff ) ;
}
}
PIMAGE_IMPORT_DESCRIPTOR GetFirstImportDesc(LPVOID ImageBase)
{
DWORD pImportOffset = (pOptionHeader->DataDirectory[1]).VirtualAddress ;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) \
ImageRvaToVa ( pNtHeader, ImageBase, pImportOffset, &pSectionHeader ) ;
if(!pImportDesc)
{
return NULL;
}
return pImportDesc;
}
void ShowImportDescInfo(HWND hDlg)
{
HWND hList = GetDlgItem(hDlg,IDC_IMPORT_DESCRIPTOR);
LVITEM lvi;
TCHAR cBuff[10],
szDllName[256];
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = GetFirstImportDesc(lpMemory);
DWORD dwErrorCode = GetLastError();
for(int i=0;pImportDesc->FirstThunk;i++)
{
ZeroMemory(cBuff,sizeof(cBuff));
ZeroMemory(&lvi,sizeof(LVITEM));
memset(szDllName,0,sizeof(szDllName));
lvi.mask = LVIF_TEXT;
lvi.iItem = i;
lvi.pszText = szDllName;
lvi.iSubItem = 0;
LPVOID pDllName = (PIMAGE_IMPORT_DESCRIPTOR)(ImageRvaToVa(pNtHeader,lpMemory,(DWORD)pImportDesc->Name,&pSectionHeader));
wsprintf ( szDllName, "%s", (char*)pDllName ) ;
ListView_InsertItem(hList,&lvi);
lvi.pszText = cBuff;
lvi.iSubItem =1;
wsprintf(cBuff,"%08lX",pImportDesc->OriginalFirstThunk);
SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ;
lvi.pszText = cBuff;
lvi.iSubItem =2;
wsprintf(cBuff,"%08lX",pImportDesc->TimeDateStamp);
SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ;
lvi.pszText = cBuff;
lvi.iSubItem =3;
wsprintf(cBuff,"%08lX",pImportDesc->ForwarderChain);
SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ;
pImportDesc++ ;
lvi.pszText = cBuff;
lvi.iSubItem =4;
wsprintf(cBuff,"%08lX",pImportDesc->Name);
SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ;
lvi.pszText = cBuff;
lvi.iSubItem =5;
wsprintf(cBuff,"%08lX",pImportDesc->FirstThunk);
SendDlgItemMessage ( hDlg, IDC_IMPORT_DESCRIPTOR, LVM_SETITEM, 0, (LPARAM)&lvi ) ;
}
}
void ShowDllFunction( HWND hDlg, int index )
{
HWND hList = GetDlgItem(hDlg,IDC_THUNK);
ListView_SetExtendedListViewStyle(hList,LVS_EX_FULLROWSELECT);
ListView_DeleteAllItems(hList);
LVITEM lvi;
TCHAR cBuff[10],
szFunName[256];
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = GetFirstImportDesc(lpMemory);
DWORD dwErrorCode = GetLastError();
PIMAGE_IMPORT_DESCRIPTOR pCurrentImportDesc =&pImportDesc[index];
DWORD *INTEntry = (DWORD*)ImageRvaToVa ( pNtHeader, \
lpMemory, (DWORD)pCurrentImportDesc->OriginalFirstThunk, &pSectionHeader ) ;
DWORD *IATEntry = (DWORD*)ImageRvaToVa ( pNtHeader, \
lpMemory, (DWORD)pCurrentImportDesc->FirstThunk, &pSectionHeader ) ;
for(int i=0;((DWORD)(*INTEntry))||((DWORD)(*IATEntry));i++)
{
ZeroMemory(&lvi,sizeof(LVITEM));
ZeroMemory(cBuff,sizeof(cBuff));
ZeroMemory(szFunName,sizeof(szFunName));
lvi.mask = LVIF_TEXT;
lvi.iItem = i;
lvi.pszText = cBuff;
lvi.iSubItem = 0;
wsprintf(cBuff,"%08lX",(DWORD)(*INTEntry));
ListView_InsertItem(hList,&lvi);
lvi.iSubItem = 1;
wsprintf(cBuff,"%08lX",(DWORD)(*IATEntry));
SendDlgItemMessage ( hDlg, IDC_THUNK, LVM_SETITEM, 0, (LPARAM)&lvi);
if(HIWORD(*INTEntry)&0x8000)
{
wsprintf ( szFunName, "ord:%08lX", (DWORD)(LOWORD(*INTEntry)) ) ;
strcpy ( cBuff, "--" ) ;
}
else
{
PIMAGE_IMPORT_BY_NAME pByName = (PIMAGE_IMPORT_BY_NAME)ImageRvaToVa \
(pNtHeader, lpMemory, (DWORD)(*INTEntry), &pSectionHeader ) ;
if ( pByName )
{
wsprintf ( cBuff, "%04lX", pByName->Hint ) ;
wsprintf ( szFunName, "%s", (char*)pByName->Name ) ;
}
}
lvi.pszText = cBuff;
lvi.iSubItem = 2 ;
SendDlgItemMessage (hDlg, IDC_THUNK, LVM_SETITEM, 0, (LPARAM)&lvi ) ;
lvi.pszText = szFunName ;
lvi.iSubItem = 3 ;
SendDlgItemMessage ( hDlg, IDC_THUNK, LVM_SETITEM, 0, (LPARAM)&lvi ) ;
INTEntry++;
IATEntry++;
}
}
/*-----------------------------
初始化输入表列表
*-------------------------------*/
BOOL WINAPI InitImportDescriptor(HWND hDlg)
{
HWND hList = GetDlgItem(hDlg,IDC_IMPORT_DESCRIPTOR);
SendMessage(hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
(LPARAM)LVS_EX_FULLROWSELECT );
HWND hList1 = GetDlgItem(hDlg,IDC_THUNK);
SendMessage(hList1,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
(LPARAM)LVS_EX_FULLROWSELECT );
TCHAR IID[][20] ={"DLL名称","OriginalFirstThunk","时间日期标志","ForwarderChain","Name of RVA","FirstThunk"};
TCHAR THUNK[][10] ={"ThunkRVA","Thunk值","Hint","API名称"};
LVCOLUMN lvc;
ZeroMemory(&lvc,sizeof(LVCOLUMN));
int iCol;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = 80;
for(iCol = 0;iCol<6;iCol++)
{
lvc.iSubItem = iCol;
lvc.pszText = IID[iCol];
if (ListView_InsertColumn(hList, iCol, &lvc) == -1)
return FALSE;
}
for(iCol = 0;iCol<4;iCol++)
{
lvc.iSubItem = iCol;
lvc.pszText =THUNK[iCol];
if (ListView_InsertColumn(hList1, iCol, &lvc) == -1)
return FALSE;
}
return TRUE;
}
/*----------------------------------
区块列表控件初始化
*---------------------------------*/
BOOL WINAPI InitListViewColumns(HWND hDlg)
{
HWND hList = GetDlgItem(hDlg,IDC_SECTION_LIST);
SendMessage(hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
(LPARAM)LVS_EX_FULLROWSELECT ); //设置树形控件的扩展样式
TCHAR section_header[][8]={"Name","VOffset","Vsize","ROffset","RSize","Flags"};
// temporary buffer
LVCOLUMN lvc;
ZeroMemory(&lvc,sizeof(LVCOLUMN));
int iCol;
// Initialize the LVCOLUMN structure.
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = 80;
// Add the columns.
for (iCol = 0; iCol < 6; iCol++)
{
lvc.iSubItem = iCol;
lvc.pszText = section_header[iCol];
if (ListView_InsertColumn(hList, iCol, &lvc) == -1)
return FALSE;
}
return TRUE;
}
/*----------------------------
显示区块信息
*----------------------------*/
void ShowSectionTable(HWND hDlg,PIMAGE_FILE_HEADER pFileHeader,PIMAGE_SECTION_HEADER pSectionHeader)
{
LVITEM lvItem;
ZeroMemory(&lvItem,sizeof(LVITEM));
TCHAR buf[16];
for ( int i = 0; i < pFileHeader->NumberOfSections; i++ )
{
ZeroMemory( &lvItem, sizeof ( lvItem ) ) ;
lvItem.mask = LVIF_TEXT ;
lvItem.iItem = i ;
ZeroMemory(buf,sizeof(buf));
CopyMemory(buf, pSectionHeader->Name, 8 ) ;
lvItem.pszText = buf ;
SendDlgItemMessage ( hDlg, IDC_SECTION_LIST, LVM_INSERTITEM, 0, (LPARAM)&lvItem ) ;
lvItem.pszText = buf;
wsprintf ( buf, "%08lX", pSectionHeader->VirtualAddress);
lvItem.iSubItem = 1;
SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
wsprintf ( buf, "%08lX", pSectionHeader->Misc.VirtualSize);
lvItem.iSubItem = 2;
SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
wsprintf ( buf, "%08lX", pSectionHeader->PointerToRawData);
lvItem.iSubItem = 3;
SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
wsprintf ( buf, "%08lX", pSectionHeader->SizeOfRawData);
lvItem.iSubItem = 4;
SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
wsprintf ( buf, "%08lX", pSectionHeader->Characteristics);
lvItem.iSubItem = 5;
SendDlgItemMessage ( hDlg,IDC_SECTION_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
pSectionHeader++ ;
}
}
//判断是否是PE文件结构
BOOL IsPeFile(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
if(!ImageBase)
return FALSE;
pDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
if(pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
if(pNtHeader->Signature != IMAGE_NT_SIGNATURE )
return FALSE;
return TRUE;
}
//FileHeader 内容的读取
PIMAGE_NT_HEADERS GetNtHeader(LPVOID ImageBase) //获取NT结构指针
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
if(!IsPeFile(ImageBase))
return NULL;
pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
pNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader+pDosHeader->e_lfanew);
return pNtHeader;
}
PIMAGE_FILE_HEADER WINAPI GetFileHeader(LPVOID Imagebase)
{
PIMAGE_FILE_HEADER pFileHeader;
PIMAGE_NT_HEADERS pNtHeader = NULL;
pNtHeader = GetNtHeader(Imagebase);
if(!pNtHeader)
return NULL;
pFileHeader = & pNtHeader->FileHeader;
return pFileHeader;
}
PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID ImageBase)
{
PIMAGE_OPTIONAL_HEADER pOptionHeader = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
pNtHeader = GetNtHeader(ImageBase);
if(!pNtHeader)
return NULL;
pOptionHeader = & pNtHeader->OptionalHeader;
return pOptionHeader;
}
PIMAGE_SECTION_HEADER GetFirstSectionHeader(PIMAGE_NT_HEADERS pNtHeader)
{
PIMAGE_SECTION_HEADER pSectionHeader;
pSectionHeader =IMAGE_FIRST_SECTION(pNtHeader);
return pSectionHeader;
}
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。