PE文件深入(一)
ring0级别,拥有最高权限。但是,驱动程序一般比较复杂,写出一个象样的驱动不仅需要经验,更需要时间以及对操作系统的深入了解。 比较通用的做法就是利用 windows的API去实现我们想要的功能,这样能节省不少时间。但是,杀毒软件一般能实现那种没有加壳、加花的木马病毒,加了之后,有的时候也能杀,要看特征码和杀毒软件的查杀方式。不管怎么样,加壳加花还是必须的,至少会把自己包裹一层,避免被查杀。加壳、加花要对PE有深刻的理解。
PE文件是分节区的,详细的资料请参考<
下面的程序是:打开一个可执行文件,判断是否为PE文件,然后再读出PE文件头,比如文件的建议装入地址。然后再就是遍历所有的节区信息。主要的技术是:程序的异常处理,win32不能像汇编那样去利用SEH处理异常,暂时来个简单的吧。因为,如果打开的文件不是可执行文件,指针操作非法,程序会抛出异常。
主要的代码入下:
#include "info.h"
#include "resource.h"
#pragma comment(lib,"comctl32.lib")
HINSTANCE hInst; TCHAR uu[2000],szFileName[MAX_PATH];
HWND hWim;
CHARRANGE sctr;
INT_PTR CALLBACK PeI(HWND,UINT,WPARAM,LPARAM);
void RRco(HWND,char*);
LONG WINAPI _MyHand(struct _EXCEPTION_POINTERS* ExceptionInfo);
void _safe(void);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
MSG msg;
hInst=GetModuleHandle(NULL);
InitCommonControls();
sctr.cpMax=-1;
sctr.cpMin=0;
SetUnhandledExceptionFilter(_MyHand);
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1),NULL,PeI);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg); }
return (int)msg.wParam;
}
INT_PTR CALLBACK PeI(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
OPENFILENAME stOpen;
switch (message)
{
case WM_INITDIALOG: hWim=hDlg;
SendMessage(GetDlgItem(hDlg,IDC_EDIT1),EM_EXLIMITTEXT,(WPARAM)0,(LPARAM)-1);
SendMessage(GetDlgItem(hDlg,IDC_EDIT1),EM_SETTEXTMODE,(WPARAM)TM_PLAINTEXT,(LPARAM)NULL);
return (INT_PTR)TRUE; break;
case WM_COMMAND: switch(LOWORD(wParam))
{
case IDOK:
ZeroMemory(&stOpen,sizeof(stOpen));
stOpen.lStructSize=sizeof(OPENFILENAME);
stOpen.hwndOwner=hWim;
stOpen.lpstrFile=szFileName;
stOpen.nMaxFile=MAX_PATH;
stOpen.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
stOpen.lpstrFilter="exe Files(*.exe)*.exeAll Files(*.*)*.*";
if(GetOpenFileName(&stOpen)) RRco(hDlg,szFileName);
else MessageBox(hDlg,"请选择文件!","没有选择文件",MB_ICONSTOP);
break;
case IDM_READ:
MessageBox(hDlg,"read record","Button read",MB_OK);
break;
case IDM_SAVE:
MessageBox(hDlg,"save record","Button save",MB_OK);
break;
case IDCANCEL:
EndDialog(hDlg, LOWORD(wParam));
ExitProcess(1);
break;
}
//WM_COMMANDswitch
return (INT_PTR)TRUE; break;
}//switch
return (INT_PTR)FALSE;
}
void RRco(HWND hwc,char *s)
{
HWND hwt; DWORD ccR;
char *ps; IMAGE_DOS_HEADER *pdher;
IMAGE_NT_HEADERS *pntHdr;
IMAGE_SECTION_HEADER *psecHdr;
HANDLE hFile,hFileM; int ic=0;
hwt=GetDlgItem(hwc,IDC_EDIT1);
hFile=CreateFile(s,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
MessageBox(hwc,"打开文件失败,请检查文件!","错误",MB_ICONSTOP);
return;
}
hFileM=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
if(hFileM==NULL)
{
MessageBox(hwc,"创建文件映射失败!","错误",MB_ICONSTOP);
CloseHandle(hFile);
return;
}
ps=(char *)MapViewOfFile(hFileM,FILE_MAP_READ,0,0,0);
pdher=(IMAGE_DOS_HEADER *)ps;
if(pdher->e_magic!=IMAGE_DOS_SIGNATURE)
{
MessageBox(NULL,"不是有效的可执行文件!","错误",MB_ICONSTOP);
goto err;
}
ps+=pdher->e_lfanew;
pntHdr=(IMAGE_NT_HEADERS *)ps;
if(pntHdr->Signature!=IMAGE_NT_SIGNATURE)
{
MessageBox(NULL,"不是有效的PE文件!","PE错误",MB_ICONSTOP);
goto err;
}
ZeroMemory(uu,sizeof(uu));
wsprintf(uu,"File:%s 运行平台:0x%04X 节区数量:%d 文件属性:0x%04X 建议装入地址:0x%04X",s,pntHdr->FileHeader.Machine,
pntHdr->FileHeader.NumberOfSections,pntHdr->FileHeader.Characteristics,pntHdr->OptionalHeader.ImageBase);
ccR=0;
SendMessage(hwt,EM_EXSETSEL,(WPARAM)0,(LPARAM)&sctr);
SendMessage(hwt,EM_REPLACESEL,(WPARAM)FALSE,(LPARAM)"");
SetWindowText(hwt,"");
SetWindowText(hwt,uu);
MessageBox(NULL,uu,"sail",MB_OK);
ps+=sizeof(IMAGE_NT_HEADERS);
for(ic=0;icFileHeader.NumberOfSections;ic++)
{
psecHdr=(IMAGE_SECTION_HEADER*)ps;
ZeroMemory(uu,sizeof(uu));
wsprintf(uu,"节区名称:%s 节区大小:%08X 虚拟地址:%08X Raw_大小:%08X 节区属性:%08X",psecHdr->Name,
psecHdr->Misc.VirtualSize,psecHdr->VirtualAddress,psecHdr->SizeOfRawData,psecHdr->Characteristics);
MessageBox(NULL,uu,"SECTION",MB_OK); ps+=sizeof(IMAGE_SECTION_HEADER);
}
err:
UnmapViewOfFile(s);
CloseHandle(hFileM);
CloseHandle(hFile);
}
LONG WINAPI _MyHand(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
TCHAR ErrMsg[100];
ZeroMemory(ErrMsg,sizeof(ErrMsg));
wsprintf(ErrMsg,"异常发生位置:%d 异常代码:%08X 标志:%d EIP:%d 参数:%d",ExceptionInfo->ExceptionRecord->ExceptionAddress,
ExceptionInfo->ExceptionRecord->ExceptionCode,ExceptionInfo->ExceptionRecord->ExceptionFlags ,ExceptionInfo->ContextRecord->Eip,ExceptionInfo->ExceptionRecord->NumberParameters);
MessageBox(NULL,ErrMsg,"错误信息",MB_OK);
ExceptionInfo->ContextRecord->Eip=(DWORD)_safe;
return EXCEPTION_CONTINUE_EXECUTION;
}
void _safe(void)
{
MessageBox(NULL,"发生错误程序退出!","异常处理",MB_OK);
ExitProcess(1);
}