[原创]PEedit
PEedit总结
——千里之行,始于足下
1.引言
1.1编写目的
该工具模仿LoadPE,目的是通过做项目来了解PE结构。
1.2背景
说明:
a.项目名称:PEedit
b.任务提出者:A1pass,编写者:GhostDL
1.3 开发工具
VS2012 Update3、OllDbg
1.4 参考资料
a.LordPE结构说明
b.《黑客免杀攻防》
c.《Windows PE权威指南》
d.网上相关资料
2.实际开发结果
2.1产品结构图

2.2版本
当前版本为Bate1.0版
2.3主要功能
a.查看及编辑PE基本信息
b.查看及编辑目录表结构信息
c.查看区段基本信息
d.查看输入表、输出表、资源表及重定位表信息
e.可用16Edit定位编辑
f.加密伪装壳
2.4性能
性能比较稳定,能够接受压力测试,可以抵御变态的PE文件
2.5进度
进度比较慢,以后慢慢完善。
3.开发
3.1程序文件列表

3.2相关代码
a.工具函数类
/******************************************************************/
/* 函数功能:多字节转宽字节,使用后需要delete */
/* 参数: 多字节 */
/* 返回值:WCHAR* */
/*******************************************************************/
WCHAR* MultiByte2WideChar(CHAR* multiChar)
{
DWORD dwNum = MultiByteToWideChar(CP_ACP,0,multiChar,-1,NULL,0);
WCHAR *wideChar = new WCHAR[dwNum];
MultiByteToWideChar (CP_ACP, 0, multiChar, -1, wideChar, dwNum);
return wideChar;
}
/*******************************************************************/
/* 函数功能:宽字节转多字节,使用后需要delete */
/* 参数: 多字节 */
/* 返回值:CHAR* */
/*******************************************************************/
CHAR* WideChar2MultiByte(WCHAR *wcChar )
{
//宽字节转换多字节
DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,wcChar,-1,NULL,0,NULL,FALSE);
char *psText;
psText = new char[dwNum];
WideCharToMultiByte (CP_OEMCP,NULL,wcChar,-1,psText,dwNum,NULL,FALSE);
return psText;
}
/*******************************************************************/
/* 函数功能:判断是否为PE文件 */
/* 参数:lpImage文件映像基址、文件大小 */
/* 返回值:TURE或FALSE */
/*******************************************************************/
BOOL IsPE_File(PVOID lpImage)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
if ( pDos->e_magic != IMAGE_DOS_SIGNATURE )
return FALSE;
PIMAGE_NT_HEADERS32 pNT32 = (PIMAGE_NT_HEADERS32)((LONG)lpImage+pDos->e_lfanew);
if ( pNT32->Signature != IMAGE_NT_SIGNATURE )
return FALSE;
return TRUE;
}
/*******************************************************************/
/* 函数功能:获取真正内存地址 */
/* 参数:RVA相对虚地址、装入内存基址、PE文件头 */
/* 返回值:真正内存地址 */
/*******************************************************************/
DWORD RVA2Offset( DWORD dwRVA, PVOID lpImage, PIMAGE_NT_HEADERS32 pNT32 )
{
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT32);
for ( DWORD i=0; i<pNT32->FileHeader.NumberOfSections; i++ )
{
if ( dwRVA>=pSection[i].VirtualAddress && dwRVA<pSection[i].VirtualAddress+pSection[i].Misc.VirtualSize )
{
DWORD dwR_Offset = dwRVA - pSection[i].VirtualAddress;
DWORD dwOffset =(DWORD)lpImage+ dwR_Offset+ pSection[i].PointerToRawData;
return dwOffset;
}
}
return 0;
}
/*******************************************************************/
/* 函数功能:判断在哪个区段 */
/* 参数:lpImage文件映像基址 */
/* 返回值:所在区段的RVA */
/*******************************************************************/
DWORD GetRvaInWhitchSection( DWORD dwRVA,PVOID lpImage,PIMAGE_NT_HEADERS32 pNT32)
{
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNT32);
for (DWORD i=0; i<pNT32->FileHeader.NumberOfSections; i++)
{
if (dwRVA>=pSection[i].VirtualAddress && dwRVA<pSection[i].VirtualAddress+pSection[i].Misc.VirtualSize)
{
return (DWORD)&pSection[i];
}
}
return 0;
}
/*******************************************************************/
/* 函数功能:获取PIMAGE_NT_HEADERS32 */
/* 参数:lpImage文件映像基址 */
/* 返回值:PIMAGE_NT_HEADERS32 */
/*******************************************************************/
PIMAGE_NT_HEADERS GetNtHeaders(LPVOID lpImage)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpImage;
PIMAGE_NT_HEADERS32 pNT32 = (PIMAGE_NT_HEADERS32)((LONG)lpImage+pDos->e_lfanew);
return pNT32;
}
/*******************************************************************/
/* 函数功能:获取PIMAGE_FILE_HEADER */
/* 参数:lpImage文件映像基址 */
/* 返回值:PIMAGE_FILE_HEADER */
/*******************************************************************/
PIMAGE_FILE_HEADER GetFileHeader(LPVOID lpImage)
{
if(!IsPE_File(lpImage))
return NULL;
PIMAGE_NT_HEADERS32 pNT32 = GetNtHeaders(lpImage);
PIMAGE_FILE_HEADER pImageHeader = &(pNT32->FileHeader);
return pImageHeader;
}
/*******************************************************************/
/* 函数功能:获取文件扩展头 */
/* 参数:lpImage文件映像基址 */
/* 返回值:PIMAGE_OPTIONAL_HEADER */
/*******************************************************************/
PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPVOID lpImage)
{
if(!IsPE_File(lpImage))
return NULL;
PIMAGE_NT_HEADERS32 pNT32 = GetNtHeaders(lpImage);
PIMAGE_OPTIONAL_HEADER pOH=&pNT32->OptionalHeader;
return pOH;
}
/*******************************************************************/
/* 函数功能:获取数据目录表 */
/* 参数:lpImage文件映像基址 */
/* 返回值:PIMAGE_DATA_DIRECTORY */
/*******************************************************************/
PIMAGE_DATA_DIRECTORY GetDataDirctory(LPVOID lpImage)
{
PIMAGE_NT_HEADERS32 pNT32 = GetNtHeaders(lpImage);
PIMAGE_DATA_DIRECTORY pDir = (PIMAGE_DATA_DIRECTORY)pNT32->OptionalHeader.DataDirectory;
return pDir;
}
/*******************************************************************/
/* 函数功能:获取导入表 */
/* 参数:lpImage文件映像基址 */
/* 返回值:PIMAGE_IMPORT_DESCRIPTOR */
/*******************************************************************/
PIMAGE_IMPORT_DESCRIPTOR GetImportTable(LPVOID lpImage)
{
PIMAGE_NT_HEADERS32 pNT32 = GetNtHeaders(lpImage);
PIMAGE_DATA_DIRECTORY pDir = GetDataDirctory(lpImage);
PIMAGE_DATA_DIRECTORY pImportDir = pDir+IMAGE_DIRECTORY_ENTRY_IMPORT;
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)RVA2Offset(pImportDir->VirtualAddress, lpImage, pNT32);
return pImport;
}
/*******************************************************************/
/* 函数功能:获得第一个节头 */
/* 参数:lpImage文件映像基址 */
/* 返回值:PIMAGE_SECTION_HEADER */
/*******************************************************************/
PIMAGE_SECTION_HEADER GetFirstSectionHeader(LPVOID lpImage)
{
PIMAGE_NT_HEADERS pNtHeader=GetNtHeaders(lpImage);
if (pNtHeader!=NULL)
{
return IMAGE_FIRST_SECTION(pNtHeader); //根据NT头得到首个SECTION的宏
}
return NULL;
}
/*******************************************************************/
/* 函数功能:关闭打开的文件 */
/* 参数:MAP文件结构体 */
/* 返回值:无 */
/*******************************************************************/
void UnLoadFile(PMAP_FILE_STRUCT pstMapFile)
{
if(pstMapFile->ImageBase)
UnmapViewOfFile(pstMapFile->ImageBase);
if(pstMapFile->hMapping)
CloseHandle(pstMapFile->hMapping);
if(pstMapFile->hFile)
CloseHandle(pstMapFile->hFile);
}
/*******************************************************************/
/* 函数功能:加载文件 */
/* 参数:文件绝对地址, MAP文件结构体 */
/* 返回值:无 */
/*******************************************************************/
BOOL LoadFileR(LPTSTR lpFilename,PMAP_FILE_STRUCT pstMapFile)
{
HANDLE hFile;
HANDLE hMapping;
LPVOID ImageBase;
memset(pstMapFile,0,sizeof(MAP_FILE_STRUCT));
hFile=CreateFile(lpFilename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,0);
if (!hFile)
return FALSE;
hMapping=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
if(!hMapping)
{
CloseHandle(hFile);
return FALSE;
}
ImageBase=MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
if(!ImageBase)
{
CloseHandle(hMapping);
CloseHandle(hFile);
return FALSE;
}
pstMapFile->hFile=hFile;
pstMapFile->hMapping=hMapping;
pstMapFile->ImageBase=ImageBase;
return TRUE;
}
b.主界面
LRESULT CALLBACK MainDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_DROPFILES:
{
int FileNum = DragQueryFile((HDROP)wParam,-1,szFilePath,0);//得到拖动文件个数
if(FileNum!=1)
return FALSE;
DragQueryFile((HDROP)wParam, 0, szFilePath, MAX_PATH);
stMapFile.tFilePath = szFilePath;
SendDlgItemMessage(hWnd,IDC_FILEPATH_EDIT,WM_SETTEXT,MAX_PATH,(LPARAM)szFilePath);
UnLoadFile(&stMapFile);
if(!LoadFileR(szFilePath,&stMapFile))
{
MessageBox(hWnd,_T("Load file faild! :("),_T("PEInfo_Example"),MB_OK);
EnableEditCtrl(hWnd,FALSE);
return FALSE;
}
if(!IsPE_File(stMapFile.ImageBase))
{
MessageBox(hWnd,_T("Invalid PE Format file!:("),_T("PEInfo_Example"),MB_OK);
UnLoadFile(&stMapFile);
EnableEditCtrl(hWnd,FALSE);
return FALSE;
}
EnableEditCtrl(hWnd,TRUE);
ShowFileHeaderInfo(hWnd);
ShowOptionHeaderInfo(hWnd);
return TRUE;
}
case WM_INITDIALOG:
hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_SMALL));
SendMessage(hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hIcon);
EnableEditCtrl(hWnd,FALSE);
return TRUE;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
// 打开文件
case IDC_OPEN_BTN:
OpenFileFun(hWnd);
return TRUE;
// 显示位置计算器
case IDC_CLAC:
DialogBox(hInst,MAKEINTRESOURCE(IDD_CALCPOS_DLG), hWnd, (DLGPROC)CalcPosDlgProc);
return TRUE;
// 保存主界面PE修改信息
case IDC_SAVE_BTN:
OnSavePE(hWnd);
return TRUE;
// 显示区段对话框
case IDC_SHOWSHT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_SHT_DLG), hWnd, (DLGPROC)SectionTableDlgProc);
return TRUE;
// 显示数据目录表
case IDC_SHOWDATADIR:
DialogBox(hInst, MAKEINTRESOURCE(IDD_DATADIR_DLG), hWnd, (DLGPROC)DataDirDlgProc);
return TRUE;
//加壳操作
case IDC_PACKER:
Packing(hWnd);
return TRUE;
// 点击退出
case IDC_EXIT:
SendMessage(hWnd, WM_CLOSE,0,0);
return TRUE;
}
break;
case IDC_ABOUTBTN:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, (DLGPROC)About);
return TRUE;
//程序退出
case WM_CLOSE:
UnLoadFile(&stMapFile);
EndDialog(hWnd, 0);
return TRUE;
}
return FALSE;
}c.目录表
/*******************************************************************/
/* 函数功能:显示目录表信息 */
/* 参数:HWND */
/* 返回值:无 */
/*******************************************************************/
void ShowDataDirInfo(HWND hDlg)
{
TCHAR tcBuff[9];
//获取PE扩展头
PIMAGE_OPTIONAL_HEADERpOH=GetOptionalHeader(stMapFile.ImageBase);
if(!pOH) return;
//循环获取目录表信息并显示在对话框中
for(int i=0;i<COUNT_OF_DATADIR;i++)
{
wsprintf(tcBuff,_T("%08lX"),pOH->DataDirectory[i].VirtualAddress);
SetDlgItemText(hDlg,EditID_Array[i].ID_RVA,cBuff);
wsprintf(tcBuff, _T("%08lX"), pOH->DataDirectory[i].Size);
SetDlgItemText(hDlg,EditID_Array[i].ID_SIZE,cBuff);
}
}d.导出表
/*******************************************************************/
/* 函数功能:显示导出表LIST函数控件 */
/* 参数:对话框句柄 */
/* 返回值:无 */
/*******************************************************************/
void ShowExportFunctionsListCtrl(HWND hDlg)
{
//清空列表
HWND hDllList = GetDlgItem(hDlg,IDC_EXPORT_LIST);
LVITEM lvItem;
TCHAR cOrder[10],cRva[10],cOffset[10],*cFuncsName;
int i = 0;
ListView_DeleteAllItems(hDllList);
//获取PE导出表 EAT/ENT/EIT
PIMAGE_NT_HEADERS pNT32=GetNtHeaders(stMapFile.ImageBase);
PIMAGE_DATA_DIRECTORY pDataDir = (PIMAGE_DATA_DIRECTORY)pNT32->OptionalHeader.DataDirectory;
PIMAGE_DATA_DIRECTORY pExportDir = &pDataDir[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)RVA2Offset(pExportDir->VirtualAddress,stMapFile.ImageBase, pNT32);
PDWORD pEAT = (PDWORD)RVA2Offset(pExport->AddressOfFunctions,stMapFile.ImageBase, pNT32);
PDWORD pENT = (PDWORD)RVA2Offset(pExport->AddressOfNames,stMapFile.ImageBase, pNT32);
PWORD pEIT = (PWORD) RVA2Offset(pExport->AddressOfNameOrdinals,stMapFile.ImageBase, pNT32);
//循环获取信息并显示在对话框中
for ( DWORD dwOrdinal=0; dwOrdinal <pExport->NumberOfFunctions; dwOrdinal++ )
{
if ( !pEAT[dwOrdinal] )
continue;
memset(&lvItem, 0, sizeof(lvItem));
lvItem.mask = LVIF_TEXT;
lvItem.iItem = i;
int flag =IsByname(pEIT,dwOrdinal,pExport->NumberOfNames);
wsprintf(cOrder, _T("%04X"), pExport->Base+dwOrdinal);
wsprintf(cRva, _T("%08X"), pEAT[dwOrdinal]);
wsprintf(cOffset,_T("%04X"), pEAT[dwOrdinal]);
if(flag!=-1)
{
PCHAR pszFunName = (PCHAR)RVA2Offset(pENT[flag],stMapFile.ImageBase,pNT32);
cFuncsName = MultiByte2WideChar(pszFunName);
}
else
{
cFuncsName = L"(Null)";
}
lvItem.pszText = cOrder; //序号
SendDlgItemMessage(hDlg,IDC_EXPORT_LIST,LVM_INSERTITEM,0,(LPARAM)&lvItem);
lvItem.pszText = cRva; //RVA
lvItem.iSubItem = 1;
SendDlgItemMessage(hDlg,IDC_EXPORT_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
lvItem.pszText = cOffset; //偏移
lvItem.iSubItem = 2;
SendDlgItemMessage(hDlg,IDC_EXPORT_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
lvItem.pszText = cFuncsName; //函数名
lvItem.iSubItem = 3;
SendDlgItemMessage(hDlg,IDC_EXPORT_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
i++;
}
}
/*******************************************************************/
/* 函数功能:保存导入表信息 */
/* 参数:对话框句柄 */
/* 返回值:无 */
/*******************************************************************/
VOID OnSaveExport(HWND hWnd)
{
WCHAR wcChar[16];
//获取导出表信息
PIMAGE_NT_HEADERS pNT32=GetNtHeaders(stMapFile.ImageBase);
PIMAGE_DATA_DIRECTORY pDataDir = (PIMAGE_DATA_DIRECTORY)pNT32->OptionalHeader.DataDirectory;
PIMAGE_DATA_DIRECTORY pExportDir = &pDataDir[IMAGE_DIRECTORY_ENTRY_EXPORT];
_IMAGE_EXPORT_DIRECTORY Export = *(PIMAGE_EXPORT_DIRECTORY)RVA2Offset(pExportDir->VirtualAddress,stMapFile.ImageBase, pNT32);
int Temp = 0;
//获的文本框修改过的信息
if(IsPE_File(stMapFile.ImageBase) == TRUE) //如果是PE文件
{
GetDlgItemText(hWnd,IDC_EDIT_EXPDIR_CHARACTERISTICS,wcChar,16);
sscanf_s(WideChar2MultiByte(wcChar),"%X",&Temp);//特征值
Export.Characteristics = Temp;
GetDlgItemText(hWnd,IDC_EDIT_EXPDIR_BASE,wcChar,16);
sscanf_s(WideChar2MultiByte(wcChar),"%X",&Temp);//基址
Export.Base = Temp;
GetDlgItemText(hWnd,IDC_EDIT_EXPDIR_NAME,wcChar,16);
sscanf_s(WideChar2MultiByte(wcChar),"%X",&Temp);//名称
Export.Name = Temp;
GetDlgItemText(hWnd,IDC_EDIT_EXPDIR_NUMOFFUNCS,wcChar,16);
sscanf_s(WideChar2MultiByte(wcChar),"%X",&Temp);//函数数量
Export.NumberOfFunctions = Temp;
GetDlgItemText(hWnd,IDC_EDIT_EXPDIR_NUMOFNAMES,wcChar,16);
sscanf_s(WideChar2MultiByte(wcChar),"%X",&Temp);//函数名数量
Export.NumberOfNames = Temp;
GetDlgItemText(hWnd,IDC_EDIT_EXPDIR_ADDROFFUNCS,wcChar,16);
sscanf_s(WideChar2MultiByte(wcChar),"%X",&Temp);//函数地址
Export.AddressOfFunctions = Temp;
GetDlgItemText(hWnd,IDC_EDIT_EXPDIR_ADDROFNAMES,wcChar,16);
sscanf_s(WideChar2MultiByte(wcChar),"%X",&Temp);//函数名称地址
Export.AddressOfNames = Temp;
GetDlgItemText(hWnd,IDC_EDIT_EXPDIR_ADDROFNAMEORD,wcChar,16);
sscanf_s(WideChar2MultiByte(wcChar),"%X",&Temp);//函数名序列号地址
Export.AddressOfNameOrdinals = Temp;
PIMAGE_NT_HEADERS pNT32=GetNtHeaders(stMapFile.ImageBase);
PIMAGE_DATA_DIRECTORY pDataDir = (PIMAGE_DATA_DIRECTORY)pNT32->OptionalHeader.DataDirectory;
PIMAGE_DATA_DIRECTORY pExportDir = &pDataDir[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)RVA2Offset(pExportDir->VirtualAddress,stMapFile.ImageBase, pNT32);
DWORD dwOffset = (DWORD)pExport - (DWORD)stMapFile.ImageBase;
DWORD dwWrite = 0;
Export.MajorVersion = pExport->MajorVersion;
Export.MinorVersion = pExport->MinorVersion;
Export.TimeDateStamp = pExport->TimeDateStamp;
//设置文件指针并写入文件
SetFilePointer(stMapFile.hFile,dwOffset,0,FILE_BEGIN); WriteFile(stMapFile.hFile,&Export,sizeof(IMAGE_FILE_HEADER),&dwWrite,NULL);
}
}
f.导入表
void ShowImportDllListCtrl(HWND hDlg)
{
//清空列表
HWND hDllList = GetDlgItem(hDlg,IDC_IMPORT_LIST);
LVITEM lvItem;
TCHAR cBuff[30];
int i = 0;
ListView_DeleteAllItems(hDllList);
PIMAGE_NT_HEADERS pNT32 = GetNtHeaders(stMapFile.ImageBase);
// 1.2 获取数据目录表
PIMAGE_DATA_DIRECTORY pDir = GetDataDirctory(stMapFile.ImageBase);
// 1.3 获取导入表的数据目录
PIMAGE_DATA_DIRECTORY pDataDir = pDir+IMAGE_DIRECTORY_ENTRY_IMPORT;
// 1.4 获取导入表
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)RVA2Offset(pDataDir->VirtualAddress, stMapFile.ImageBase, pNT32);
// 2. 循环遍历导入表
while ( pImport->Name )
{
// 2.1 获取导入项DLL名称
PCHAR pszDllName = (PCHAR)RVA2Offset(pImport->Name, stMapFile.ImageBase, pNT32);
//PCHAR pszFirstThunk=(PCHAR)RVA2Offset(pImport->FirstThunk, stMapFile.ImageBase, pNT32);
// 2.2 获取INT
PIMAGE_THUNK_DATA32 pINT = (PIMAGE_THUNK_DATA32)RVA2Offset(pImport->FirstThunk, stMapFile.ImageBase, pNT32);
// 2.3 打印导入项头部信息
memset(&lvItem, 0, sizeof(lvItem));
lvItem.mask = LVIF_TEXT;
lvItem.iItem = i;
lvItem.pszText = cBuff; //DLL名称
wsprintf(cBuff, _T("%s"), MultiByte2WideChar(pszDllName));
SendDlgItemMessage(hDlg,IDC_IMPORT_LIST,LVM_INSERTITEM,0,(LPARAM)&lvItem);
lvItem.pszText = cBuff;
wsprintf(cBuff, _T("%08lX"), pImport->OriginalFirstThunk); //OriginalFirstThunk
lvItem.iSubItem = 1;
SendDlgItemMessage(hDlg,IDC_IMPORT_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
lvItem.pszText = cBuff;
wsprintf(cBuff, _T("%08lX"), pImport->TimeDateStamp); //时间日期标志
lvItem.iSubItem = 2;
SendDlgItemMessage(hDlg,IDC_IMPORT_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
lvItem.pszText = cBuff;
wsprintf(cBuff, _T("%08lX"), pImport->ForwarderChain); //ForwarderChain
lvItem.iSubItem = 3;
SendDlgItemMessage(hDlg,IDC_IMPORT_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
lvItem.pszText = cBuff;
wsprintf(cBuff, _T("%08lX"), pImport->Name); //名称
lvItem.iSubItem = 4;
SendDlgItemMessage(hDlg,IDC_IMPORT_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
lvItem.pszText = cBuff;
wsprintf(cBuff, _T("%08lX"), pImport->FirstThunk); //FirstThunk
lvItem.iSubItem = 5;
SendDlgItemMessage(hDlg,IDC_IMPORT_LIST, LVM_SETITEM, 0, (LPARAM)&lvItem);
pImport++;
i++;
}
}f.资源表
if (phdr->hdr.code ==TVN_SELCHANGED) //选择改变
{
TVITEM tvItem;
TCHAR szTemp[40]={0};
HWND hTree=GetDlgItem(hwndDlg,IDC_TREE_RESOURCE);
HTREEITEM hSelItem=TreeView_GetSelection(hTree);
ZeroMemory(&tvItem,sizeof(tvItem));
tvItem.mask =LVIF_PARAM|TVIF_CHILDREN;
tvItem.hItem=hSelItem;
TreeView_GetItem(hTree,&tvItem);
pResData pData=(pResData)tvItem.lParam;
if (tvItem.cChildren==1) //如果存在子节点
{
PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pData->lpResEntry);
PIMAGE_RESOURCE_DIRECTORY pDir=(PIMAGE_RESOURCE_DIRECTORY)(pData->lpRes+pEntry->OffsetToDirectory);
StringCchPrintf(szTemp,sizeof(szTemp),_T("%04X"),pDir->NumberOfNamedEntries);
SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT_SELECTED_NAME),szTemp);
StringCchPrintf(szTemp,sizeof(szTemp),_T("%04X"),pDir->NumberOfIdEntries);
SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT_SELECTED_ID),szTemp);
SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT_REC_RVA),_T(""));
SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT_REC_OFFSET),_T(""));
SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT_REC_SIZE),_T(""));
}else if (tvItem.cChildren==0)
{
PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry=(PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pData->lpResEntry);
PIMAGE_RESOURCE_DIRECTORY pDir=(PIMAGE_RESOURCE_DIRECTORY)(pData->lpRes+pEntry->OffsetToDirectory);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pNextEntry =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pDir+sizeof(IMAGE_RESOURCE_DIRECTORY));
PIMAGE_RESOURCE_DATA_ENTRY pDataEntry=(PIMAGE_RESOURCE_DATA_ENTRY)(pData->lpRes+pNextEntry->OffsetToData);
StringCchPrintf(szTemp,sizeof(szTemp),_T("%08X"),pDataEntry->OffsetToData);
SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT_REC_RVA),szTemp); //RVA
StringCchPrintf(szTemp,sizeof(szTemp),_T("%08X"),RVA2Offset(pDataEntry->OffsetToData,stMapFile.ImageBase,GetNtHeaders(stMapFile.ImageBase))-(DWORD)stMapFile.ImageBase);
SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT_REC_OFFSET),szTemp); //Offset
StringCchPrintf(szTemp,sizeof(szTemp),_T("%08X"),pDataEntry->Size);
SetWindowText(GetDlgItem(hwndDlg,IDC_EDIT_REC_SIZE),szTemp); //Size
}
}g.加壳
/****************************************************************/
/* 函数功能:加壳后文件启动部分,欺骗PEiD */
/* 参数: 多字节 */
/* 返回值:WCHAR* */
/****************************************************************/
void _declspec(naked) StubEntryPoint()
{
_asm
{
push ebp
mov ebp,esp
push -1
push 0x00403550
push 0xE4F6
mov eax,dword ptr fs:[0]
push eax
mov dword ptr fs:[0],esp
sub esp,68
push ebx
}
__asm sub esp,0x50;
start();
__asm add esp,0x50;
__asm retn;
}
/*******************************************************************/
/* 函数功能:获取Kernel32.dll地址 */
/* 参数: 无 */
/* 返回值: */
/*******************************************************************/
DWORD GetKernel32Base()
{
DWORD dwKernel32Addr = 0;
__asm
{
push eax
mov eax,dword ptr fs:[0x30]
mov eax,[eax+0x0C]
mov eax,[eax+0x1C]
mov eax,[eax]
mov eax,[eax+0x08]
mov dwKernel32Addr,eax
pop eax
}
return dwKernel32Addr;
}4.经验与教训
1.当我们学到了知识就要用程序来实现它,有时我们认为自己都懂了,可是自己下手写时就发现不是那回事。所以非必要时应该动手写写。
2.写程序时需低耦合高内聚,做一些工具函数类,方便调用,多做注释,让自己更让别人能够看懂自己程序代码的意思,方便以后的维护代 码要简洁工整。
3.写程序时参考代码时要先多自己动脑筋,和别人交流,参考资料。当自己的程序能跑起来时也要去参考一下别人的代码,看看别人有什么 更好的方法来实现相同的功能吗。
4.多总结,注意细节。在开始写程序时应该大体思考一下流程。不要一开始就闷头做,这样在后期不好维护和扩展功能。
