文件基础操作:
1:文件有很多种,例如: EXE,TXT,JPG,BMP,GIF,Lnk(快捷方式),RAR,7Z,ZIP,AVI,MP4,RMVB…… 2:在Windows系统中,文件可分为两部分,可执行文件和数据文件,在linux和其他任何系统里面,文件都是这样分的,但是他们都是属于文件,可执行文件会比较特殊,特能够通过操作系统的某个程序进行启动,一般是资源管理器来CreateProcess,其他的文件都是通过可执行文件来打开,体现给使用者的,这是两者之间最大的区别。 3:在系统里面,无论是那种文件,都可以使用CreateFile来打开一个文件,我们可以对不同格式文件的特殊文件头进行识别,判断这是一个什么样的文件,如果仅仅是通过文件的后缀名来判断文件类型,是不标准的,系统可执行文件里面也会有一些标志来进行标明,标明他就是一个可执行文件,这就是PE标明,在EXE和DLL里面,都会有PE的结构,可执行文件里面包含了DOS头和NT头,有这两个头的文件就是一个可执行文件。 4:如果讲一个普通的数据文件前面家长一个DOS头和NT头,操作系统也可以将这个文件执行起来,但是执行的东西谁也不知道是什么,甚至可能导致死机。所谓的后缀名实际上只是给人来看的,机器看的只文件里面的编码。 5:文件本质最重要的是内容,里面内容的不同组合就是不同种类的文件。 6:一个程序有PE结构和数据组成,可以先把PE部分和数据部分分开,下载的时候,先下载数据部分,等下载完之后,在下载PE头,放在前面,就可以一定程度上避免杀软的报毒。当然,现在有行为监控,这样做也是避免不了的。DOS头和NT头的识别:
1:MFC注意点: 在对控件添加变量的时候,不一定是控件类型,还可以是Value类型,党委Value类型的时候,对这个Value进行设置是无效的,它的使用是使用UpdataData来获取空间里面的内容,而不是用于设置。 SetDlgItemText和SetWindowText的区别:SetDlgItemText需要传递ID,是用于设置窗口里面某个控件的Text,而SetWindowText是用于设置已知窗口的Text,需要传递的是窗口的HWND。 在看MFC里面的函数的时候,可能发现在当前类找不到需要的方法,但是很可能在父类里面,另外,命名都是动词开头,这点需要学习。 在查文档的时候,一定要判断清除是MFC里面的函数还是Win32的API,如果查不到,就先找到这个类,再在这个类里面找方法。 2:代码部分: 选择路径的部分:CFileDialog dlg(TRUE);
if (dlg.DoModal() == IDOK)
{
m_EditValue.SetWindowTextW(dlg.GetPathName());
}
判断PE头的部分:
UpdateData();//TRUE会将数据映射过来。
if (m_EditValue.IsEmpty())
{
MessageBox(L"请选择路径!");
return;
}
bool bRet = false;
HANDLE hFile = INVALID_HANDLE_VALUE;
do
{
hFile = CreateFile(m_EditValue, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile == INVALID_HANDLE_VALUE)
break;
IMAGE_DOS_HEADER dosHead;//DOS头用于兼容以前DOS程序而存在的。结构体里面只有两个参数基本还在用。
IMAGE_NT_HEADERS32 ntHead;//NT头
DWORD dwReaded;
::ReadFile(hFile, &dosHead, sizeof(IMAGE_DOS_HEADER), &dwReaded, nullptr);
if (dwReaded != sizeof(IMAGE_DOS_HEADER))
if (dosHead.e_magic != IMAGE_DOS_SIGNATURE)
break;
if (SetFilePointer(hFile, dosHead.e_lfanew, nullptr, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
break;
::ReadFile(hFile, &ntHead, sizeof(IMAGE_NT_HEADERS32), &dwReaded, nullptr);
if (dwReaded != sizeof(IMAGE_NT_HEADERS32))
break;
if (ntHead.Signature != IMAGE_NT_SIGNATURE)
break;
bRet = true;
} while (false);
if (bRet)
MessageBox(L"Is PE");
else
MessageBox(L"Is Not PE");
m_EditPath.SetWindowTextW(L"");
CloseHandle(hFile);
3:检查PE的时候,必须确保m_EditValue里面是有值的,现在了解PE,主要是用于做病毒要使用,逆向用这块都比较少了。 DOS头:
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number//判断是否为一个DOS头,
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header//指向
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
NT头:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
4:一般通过DOS头找NT头,从这两个地方决定它是否为一个真的可执行文件。 只要DOS头里面的e_magic为IMAGE_DOS_SIGNATURE,NT头里面的Signature为IMAGE_NT_SIGNATURE,就说,这个文件是一个可执行文件。