能力值:
( LV3,RANK:20 )
|
-
-
2 楼
下面放上现在我称之为暴利搜索的代码。。求保养。求看有多挫。
int ParseDataRun(BYTE * pData, int * nOffset, DWORD * dwLength)
{
int offsetBits, lengthBits;
if(pData[0] == 0)
{
*nOffset = 0;
*dwLength = 0;
return 0;
}
offsetBits = (pData[0] >> 4) * 8;
lengthBits = (pData[0] & 0x0f) * 8;
if(offsetBits > 32 || lengthBits > 32)
{
dprintf("can't handle DataRun size");
*dwLength = 0;
*nOffset = 0;
return -1;
}
//计算length
*dwLength = *(PULONG)(pData + 1) & ~(LENMASK << offsetBits);
//计算offset因为有正负所以稍复杂在不足DWORD的时候要用远数字 减去 那个100000..原数字位个0取得符号
//判断最高位即标志位是否为1
*nOffset = (*(PULONG)(pData + 1 + lengthBits / 8) & 0x1 << (offsetBits - 1)) ?
//为1则为负数转换成32位的此负数表示
(*(PULONG)(pData + 1 + lengthBits / 8) & ~(LENMASK << offsetBits)) - (OFFSETMASK << lengthBits) :
//否则为正数无需转换
(*(PULONG)(pData + 1 + lengthBits / 8) & ~(LENMASK << offsetBits));
return (offsetBits + lengthBits) / 8 + 1;
}
DWORD FindSplice(ULONG Sector, wchar_t * splice, DWORD IndexRootRecordSector)
//sector开始扇区
//splice需要查找的名称字符串
//IndexRootRecordSector是第一个DataRun指向的VCN
{
PCHAR pBuffer;
NTSTATUS status;
DWORD dwFindRec, IndexAllocOffset;
ULONG i, dwLen, EntrySize;
PINDEX_ENTRY pIndexEntry;
PINDEX_BLOCK pIndexBlock;
wchar_t szFileName[260];
pIndexBlock = ExAllocatePoolWithTag(NonPagedPool, sizeof(INDEX_BLOCK), 'Bu4n');
RtlZeroMemory(pIndexBlock , sizeof(INDEX_BLOCK));
status = ScsiReadWriteDisk(g_pDr0DevObj, TRUE, (ULONG)(Sector), (PCHAR)pIndexBlock, sizeof(INDEX_BLOCK));
if(!NT_SUCCESS(status))
{
ExFreePool(pIndexBlock);
return 0;
}
if(*(PULONG)pIndexBlock != magic_INDX)
{
ExFreePool(pIndexBlock);
return 0;
}
/*
Standard Index Header
Offset Size Description
0x00 4 Magic number 'INDX'
0x04 2 Offset to the Update Sequence
0x06 2 Size in words of the Update Sequence Number & Array (S)
0x08 8 $LogFile sequence number
0x10 8 VCN of this INDX buffer in the Index Allocation
0x18 4 Offset to the Index Entries (a)
0x1C 4 Size of Index Entries (a)
0x20 4 Allocated size of the Index Entries (a)
0x24 1 1 if not leaf node (b)
0x25 3 Padding (always zero)
0x28 2 Update sequence
0x2A 2S-2 Update sequence array
(a) These values are relative to 0x18
(b) Has children
*/
//_asm int 3;
EntrySize = pIndexBlock->TotalEntrySize;
pBuffer = ExAllocatePoolWithTag(NonPagedPool, 0x18 + pIndexBlock->EntryOffset + EntrySize, 'Bu4n');
if (pBuffer == NULL)
{
ExFreePool(pIndexBlock);
return 0;
}
//一次失败的调用。。。造成第二次不返回的调用。。。
status = ScsiReadWriteDisk(g_pDr0DevObj, TRUE, (ULONG)(Sector), pBuffer, 0x18 + pIndexBlock->EntryOffset + EntrySize);
ExFreePool(pIndexBlock);
pIndexBlock = NULL;
if(!NT_SUCCESS(status))
{
ExFreePool(pBuffer);
return 0;
}
pIndexBlock = (PINDEX_BLOCK)pBuffer;
pIndexEntry = (PINDEX_ENTRY)(pBuffer + 0x18 + pIndexBlock->EntryOffset);
while((ULONG)pIndexEntry < (ULONG)pBuffer + EntrySize + pIndexBlock->EntryOffset)
{
if(pIndexEntry->Flags & 2) //END标志
{
if(pIndexEntry->Flags & 1) //SUBNOD标志
{
/*IndexAllocOffset = *(PULONG)(pIndexEntry->Size - 8 + (ULONG)pIndexEntry);
dwFindRec = FindSplice(IndexRootRecordSector + IndexAllocOffset * 8, splice, IndexRootRecordSector);
if(dwFindRec != 0)
{
return dwFindRec;
}*/
}
dprintf("Index Allocate END_NOD\r\n");
break;
}
else
{
RtlZeroMemory(szFileName, 260 * sizeof(wchar_t));
RtlCopyMemory(szFileName, (PCHAR)((ULONG)pIndexEntry + 0x52), *(BYTE *)((ULONG)pIndexEntry + 0x50) * sizeof(wchar_t));
if(wcscmp(_wcsupr(szFileName), splice) == 0)
{
//Sector
dprintf("Find %S MftRec:%d\r\n", szFileName, *(PULONG)pIndexEntry);
return *(PULONG)pIndexEntry;
}
dprintf("%S\r\n", szFileName);
}
(ULONG)pIndexEntry += pIndexEntry->Size;
}
ExFreePool(pBuffer);
return 0;
}
DWORD ParsePath(wchar_t *splice, DWORD Sector, PPARTITION_INFO pPartition)
//splice需要查找的文件名称
//sector父文件夹的MFT中的记录所在的扇区
//文件pPartition所在逻辑卷分区的信息
{
NTSTATUS status;
PMFT_RECORD pMftRecord;
PATTRIBUTE pAttr;
PINDEX_ROOT pIndexRoot;
PINDEX_HEAD pIndexHead;
PINDEX_ENTRY pIndexEntry;
PNONRESIDENT_ATTRIBUTE pIndexAlloc;
ULONG IndexRecordSector, IndexRootRecordSector, dwLength, IndexAllocOffset = 0;
PCHAR pData;
DWORD i, dwFindRet, dwDataRunSizeRemain;
int DataRunOffset = 0, nOffset;
wchar_t szFileName[260];
status = STATUS_UNSUCCESSFUL;
pMftRecord = ExAllocatePoolWithTag(NonPagedPool, 0x400, 'Bu4n');
if(pMftRecord == NULL)
{
status = STATUS_UNSUCCESSFUL;
goto END;
}
status = ScsiReadWriteDisk(g_pDr0DevObj, TRUE, Sector, (PUCHAR)pMftRecord, 0x200 * 2);
if(!NT_SUCCESS(status))
{
goto END;
}
//解析IndexRoot属性
pAttr = FindAttribute(pMftRecord, AttributeIndexRoot);
if(pAttr == NULL)
{
goto END;
}
pIndexHead = (PINDEX_HEAD)((ULONG)pAttr + sizeof(INDEX_ROOT) + GetAttributeHeadSize(pAttr));
pIndexEntry = (PINDEX_ENTRY)((ULONG)pIndexHead + pIndexHead->EntryOffset);
//遍历IndexRoot中的IndexEntry
while((ULONG)pIndexEntry < pIndexHead->TotalEntrySize + (ULONG)pIndexHead)
{
if(pIndexEntry->Flags & 0x2)
{
if(pIndexEntry->Flags & 0x1)
{
IndexAllocOffset = *(PULONG)(pIndexEntry->Size - 8 + (ULONG)pIndexEntry);
}
dprintf("IndexRoot END_ENTRY IndexOffset:%d\r\n", IndexAllocOffset);
break;
}
else
{
RtlZeroMemory(szFileName, 260 * sizeof(wchar_t));
RtlCopyMemory(szFileName, (PCHAR)((ULONG)pIndexEntry + 0x52), *(BYTE *)(pIndexEntry + 0x50) * sizeof(wchar_t));
dprintf("%S\r\n", szFileName);
if(wcscmp(_wcsupr(szFileName), splice) == 0)
{
dprintf("Find %S MftRec:%d\r\n", szFileName, *(PULONG)pIndexEntry);
dwFindRet = *(PULONG)pIndexEntry;
return pPartition->MFT + dwFindRet * 2;
}
(ULONG)pIndexEntry += pIndexEntry->Size;
}
}
if(!(pIndexEntry->Flags & 0x1))
{
goto END;
}
//计算IndexAllocate指向的IndexRecord所在的扇区
//FindAttribute根据Type从MFT中找到属性头的位置返回指向其的指针
pIndexAlloc = (PNONRESIDENT_ATTRIBUTE)FindAttribute(pMftRecord, AttributeIndexAllocation);
if(pIndexAlloc == NULL)
{
goto END;
}
//DataRun数据的指针
pData = (PCHAR)(ULONG)pIndexAlloc + pIndexAlloc->RunArrayOffset;
//DataRun数据的占用字节
dwDataRunSizeRemain = pIndexAlloc->DataSize;
//dwSize = pIndexAlloc->AllocatedSize;
//解析DataRun获得Size LCN或VCN。。DataRunOffet是下一个DataRun的偏移
DataRunOffset = ParseDataRun(pData, &nOffset, &dwLength);
if(DataRunOffset == -1 || DataRunOffset == 0)
{
goto END;
}
//第一个DataRun指向的 IndexBlock数据的开始扇区
IndexRootRecordSector = pPartition->StartLBA + nOffset * 8;
for(IndexRecordSector = pPartition->StartLBA + nOffset * 8; nOffset != 0; IndexRecordSector += nOffset * 8)
{
//逐个簇遍历IndexBlock中的IndexEntry
for(i = 0; i < dwLength; i++)
{
//FindSplice从一个IndexBlock中查找指定的文件名
dwFindRet = FindSplice(IndexRecordSector + i * 8, splice, IndexRootRecordSector);
if(dwFindRet != 0)
{
return pPartition->MFT + dwFindRet * 2;
}
}
pData += DataRunOffset;
//解析下一个DataRun
DataRunOffset = ParseDataRun(pData, &nOffset, &dwLength);
if(DataRunOffset == -1)
{
goto END;
}
}
//IndexRecordSector = (*(PLONG)(&pData[1]) >> 4) * 8 + pPartition->StartLBA;
//ParseDir(IndexRecordSector);
//if()
//NextAllocateGrabFromIndexRoot
//if(IndexAllocOffset != 0)
//{
// //IndexRecordSector += IndexAllocOffset * 8;
// dwFindRet = FindSplice(IndexRootRecordSector + IndexAllocOffset * 8, splice, IndexRootRecordSector);
// if(dwFindRet != 0)
// {
// return pPartition->MFT + dwFindRet * 2;
// }
//}
status = 0;
END:
if(pMftRecord != NULL)
{
ExFreePool(pMftRecord);
}
return status;
}
void FormatPath(wchar_t * lpPath, DWORD length)
{
if(wcsstr(lpPath, L"\\SYSTEMROOT\\") != NULL)
{
RtlCopyMemory(lpPath, L"C:\\WINDOWS", 10 * sizeof(wchar_t));
//RtlMoveMemory(lpPath, lpPath + 3, length - 12 * sizeof(wchar_t));
}
return;
}
wchar_t * SplitPath(wchar_t * RemainPath, wchar_t * splice)
{
wchar_t * EndPath;
DWORD dwLen;
RemainPath++;
EndPath = wcschr(RemainPath, L'\\');
if(EndPath == NULL)
{
wcscpy(splice, RemainPath);
return 0;
}
else
{
dwLen = (ULONG)EndPath - (ULONG)RemainPath;
RtlZeroMemory(splice, dwLen + 2);
RtlCopyMemory(splice, RemainPath, dwLen);
return EndPath;
}
}
//////////////////////////////////////////////////////////////////////////
//
// 这个是我想要完成的删除功能的函数。现在还没写删除的代码。。先能找到就不错
//
////////////////////////////////////////////////////////////////////////
NTSTATUS MyIoDeleteFile(PUNICODE_STRING pFilePath)
{
wchar_t *lpPathBuffer, *RemainPath, szSplice[260];
DWORD PartitionNumber;
DWORD sector;
//__asm int 3;
lpPathBuffer = ExAllocatePoolWithTag(NonPagedPool, pFilePath->Length + 2, 'Bu4n');
RtlZeroMemory(lpPathBuffer, pFilePath->Length + 2);
RtlCopyMemory(lpPathBuffer, pFilePath->Buffer, pFilePath->Length);
_wcsupr(lpPathBuffer);
FormatPath(lpPathBuffer, pFilePath->Length);
PartitionNumber = *lpPathBuffer - L'C';
RemainPath = lpPathBuffer + 2;
sector = g_PartitionInfo[PartitionNumber].MFT + 5 * 2;
//ParseRootDir(g_PartitionInfo + PartitionNumber);
__asm int 3;
while(RemainPath != NULL)
{
//从RemaindPath截取一个/ / 之间的部分。。放到splice中
RemainPath = SplitPath(RemainPath, szSplice);
sector = ParsePath(szSplice, sector, g_PartitionInfo + PartitionNumber);
if(sector == 0)
{
return STATUS_UNSUCCESSFUL;
}
}
return STATUS_SUCCESS;
}
|