系統實際上如何處理重新分析點
這是文件系統驅動程序中完成的。結果取決於在呼叫CreateFile
(或NT呼叫中的)中使用的FILE_FLAG_OPEN_REPARSE_POINT
選項。
指定FILE_FLAG_OPEN_REPARSE_POINT
時 - 文件系統繞過文件的正常重新分析點處理,並嘗試按原樣直接打開重新分析點文件。
如果沒有指定FILE_OPEN_REPARSE_POINT
標誌 - 文件系統試圖打開到重分析點文件是點(在fs瞭解解析點的格式 - 初級只有微軟重解析點)
保存在數據格式重新分析點是REPARSE_DATA_BUFFER
(Microsoft重新分析點格式)或REPARSE_GUID_DATA_BUFFER
- 開始時需要查找ReparseTag
。
以確定重新分析點標記是否對應於Microsoft擁有的標記,我們使用IsReparseTagMicrosoft
宏。測試/打印重分析點數據
代碼:
volatile UCHAR guz;
ULONG TestReparsePoint(PCWSTR FileName)
{
HANDLE hFile = CreateFile(FileName, 0, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
union {
PVOID pv;
PULONG ReparseTag;
PREPARSE_DATA_BUFFER prdb;
PREPARSE_GUID_DATA_BUFFER prgdb;
};
PVOID stack = alloca(guz);
ULONG cb = 0, rcb = sizeof(REPARSE_DATA_BUFFER) + 0x100, BytesReturned;
ULONG dwError;
do
{
if (cb < rcb) cb = RtlPointerToOffset(pv = alloca(rcb - cb), stack);
if (DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, 0, 0, pv, cb, &BytesReturned, 0))
{
dwError = NOERROR;
if (IsReparseTagMicrosoft(*ReparseTag))
{
char cc[16];
LPCSTR name;
switch (*ReparseTag)
{
case IO_REPARSE_TAG_SYMLINK:
name = " SYMLINK";
stack = prdb->SymbolicLinkReparseBuffer.PathBuffer;
break;
case IO_REPARSE_TAG_MOUNT_POINT:
name = " MOUNT_POINT";
stack = prdb->MountPointReparseBuffer.PathBuffer;
break;
default:
sprintf(cc, " %08x", prdb->ReparseTag);
name = cc;
}
DbgPrint(" %s->%.*S <%.*S>\n", name,
prdb->MountPointReparseBuffer.SubstituteNameLength >> 1,
RtlOffsetToPointer(stack, prdb->MountPointReparseBuffer.SubstituteNameOffset),
prdb->MountPointReparseBuffer.PrintNameLength >> 1,
RtlOffsetToPointer(stack, prdb->MountPointReparseBuffer.PrintNameOffset)
);
}
else
{
PGUID g = &prgdb->ReparseGuid;
DbgPrint(" tag=%x {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x} size=%x\n", *ReparseTag,
g->Data1, g->Data2, g->Data3,
g->Data4[0],g->Data4[1],g->Data4[2],g->Data4[3],g->Data4[4],g->Data4[5],g->Data4[6],g->Data4[7],
prgdb->ReparseDataLength);
}
break;
}
rcb = IsReparseTagMicrosoft(*ReparseTag)
? REPARSE_DATA_BUFFER_HEADER_SIZE + prdb->ReparseDataLength
: REPARSE_GUID_DATA_BUFFER_HEADER_SIZE + prgdb->ReparseDataLength;
} while((dwError = GetLastError()) == ERROR_MORE_DATA);
CloseHandle(hFile);
return dwError;
}
一些逆向工程後,真的似乎CMD.EXE不會調用* DeviceIoControl的*和分析數據,但只有一個符號或一個結。 – IllidanS4
您需要使用「FILE_FLAG_OPEN_REPARSE_POINT」選項打開文件。只有在這種情況下,您才能發送'FSCTL_GET_REPARSE_POINT'。否則將是'ERROR_NOT_A_REPARSE_POINT' – RbMm
@RbMm是的,我知道。忘了提及。 – IllidanS4