A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about user-mode development.
 #17872  by myid
 Sat Jan 26, 2013 11:38 am
I want to get the absolute offset of "c:\\test.exe", how can I do this?
Note: I don't want to get the file absolute offset of "\\\\.\\C:\\", but the absolute offset of "\\\\.\\PhysicalDrive0".
 #17874  by myid
 Sat Jan 26, 2013 2:06 pm
EP_X0FF wrote:For example, read list of clusters used to store file.
FSCTL_GET_RETRIEVAL_POINTERS
I know this IOCTL, but how to get the file offset of "\\\\.\\PhysicalDrive0"?
I use code below and I get the file offset of "\\\\.\\c:"
Code: Select all
#include <Windows.h>
#include <stdio.h>

SIZE_T *GetFileClusters(
                    PCHAR lpFileName,
                    ULONG ClusterSize,
                    ULONG *ClCount,
                    ULONG *FileSize
                    )
{
    HANDLE  hFile;
    ULONG   OutSize;
    ULONG   Bytes, Cls, CnCount, r;
    SIZE_T *Clusters = NULL;
    BOOLEAN Result = FALSE;
    LARGE_INTEGER PrevVCN, Lcn;
    STARTING_VCN_INPUT_BUFFER  InBuf;
    PRETRIEVAL_POINTERS_BUFFER OutBuf;
    hFile = CreateFile(lpFileName, GENERIC_READ,	// FILE_READ_ATTRIBUTES
                       FILE_SHARE_READ,	// | FILE_SHARE_WRITE | FILE_SHARE_DELETE
                       NULL, OPEN_EXISTING, 0, 0);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        *FileSize = GetFileSize(hFile, NULL);
        OutSize = sizeof(RETRIEVAL_POINTERS_BUFFER) + (*FileSize / ClusterSize) * sizeof(OutBuf->Extents);
        OutBuf = (PRETRIEVAL_POINTERS_BUFFER)malloc(OutSize);
        InBuf.StartingVcn.QuadPart = 0;
        if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,
                            sizeof(InBuf), OutBuf, OutSize, &Bytes, NULL))
        {
            *ClCount = (*FileSize + ClusterSize - 1) / ClusterSize;
            Clusters = (SIZE_T *)malloc(*ClCount * sizeof(SIZE_T));
            PrevVCN = OutBuf->StartingVcn;
            for (r = 0, Cls = 0; r < OutBuf->ExtentCount; r++)
            {
                Lcn = OutBuf->Extents[r].Lcn;
                for (CnCount = OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart;
                     CnCount; 
					 CnCount--, Cls++, Lcn.QuadPart++) 
					 Clusters[Cls] = Lcn.QuadPart;
                PrevVCN = OutBuf->Extents[r].NextVcn;
            }
        }
        free(OutBuf);
        CloseHandle(hFile);
    }
    return Clusters;
}

void GetNtfsFilePos(char *FilePath)
{
	ULONG64 d1=0,d2=0;
	char DriveName[3]={0};
	ULONG SecPerCl, BtPerSec, ClusterSize, ClCount, FileSize, i;
	memcpy(DriveName,FilePath,2);
    GetDiskFreeSpaceA(DriveName, &SecPerCl, &BtPerSec, NULL, NULL);
    ClusterSize = SecPerCl * BtPerSec;
	PSIZE_T x=GetFileClusters(FilePath,ClusterSize,&ClCount,&FileSize);
	if(x!=NULL)
	{
		for(i=0;i<ClCount;i++)
		{	
			d1=8*x[i];
			d2=512*8*x[i];
			printf("Cluster[%ld]: %ld\tSector: %lLd\tOffset: 0x%llx\n",i,x[i],d1,d2);
		}
		free(x);
	}
	else
	{
		printf("Cannot get file position!\n");
	}
}

int main()
{
	GetNtfsFilePos("c:\\test.exe");
	getchar();
}
 #17876  by EP_X0FF
 Sat Jan 26, 2013 2:29 pm
Get partition info (IOCTL_DISK_GET_PARTITION_INFO_EX), get file clusters map from fs
partitionoffset/volumeoffset + 1 clusternumber (VCN) * clustersize
IoBuildDeviceIoControlRequest/ZwFsControlFile,see MSDN.
Something like this, try it. See also IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
 #17878  by myid
 Sat Jan 26, 2013 3:45 pm
EP_X0FF wrote:Get partition info (IOCTL_DISK_GET_PARTITION_INFO_EX), get file clusters map from fs
partitionoffset/volumeoffset + 1 clusternumber (VCN) * clustersize
IoBuildDeviceIoControlRequest/ZwFsControlFile,see MSDN.
Something like this, try it. See also IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Thanks, I will try it.