Ejemplo n.º 1
0
/*
 * Process per-sector "fixups" that NTFS uses to detect corruption of
 * multi-sector data structures, like MFT records.
 */
static int
ntfs_fixup(
            char *buf,
            size_t len,
            u_int32_t magic,
            u_int32_t bytesPerSector)
{
	struct fixuphdr *fhp = (struct fixuphdr *) buf;
	int             i;
	u_int16_t       fixup;
	u_int16_t      *fxp;
	u_int16_t      *cfxp;
        u_int32_t	fixup_magic;
        u_int16_t	fixup_count;
        u_int16_t	fixup_offset;
        
        fixup_magic = OSReadLittleInt32(&fhp->fh_magic,0);
	if (fixup_magic != magic) {
		error("ntfs_fixup: magic doesn't match: %08x != %08x\n",
		       fixup_magic, magic);
		return (ERROR);
	}
        fixup_count = OSReadLittleInt16(&fhp->fh_fnum,0);
	if ((fixup_count - 1) * bytesPerSector != len) {
		error("ntfs_fixup: " \
		       "bad fixups number: %d for %ld bytes block\n", 
		       fixup_count, (long)len);	/* XXX printf kludge */
		return (ERROR);
	}
        fixup_offset = OSReadLittleInt16(&fhp->fh_foff,0);
	if (fixup_offset >= len) {
		error("ntfs_fixup: invalid offset: %x", fixup_offset);
		return (ERROR);
	}
	fxp = (u_int16_t *) (buf + fixup_offset);
	cfxp = (u_int16_t *) (buf + bytesPerSector - 2);
	fixup = *fxp++;
	for (i = 1; i < fixup_count; i++, fxp++) {
		if (*cfxp != fixup) {
			error("ntfs_fixup: fixup %d doesn't match\n", i);
			return (ERROR);
		}
		*cfxp = *fxp;
                cfxp = (u_int16_t *)(((caddr_t)cfxp) + bytesPerSector);
	}
	return (0);
}
Ejemplo n.º 2
0
/*
 * Find a resident attribute of a given type.  Returns a pointer to the
 * attribute data, and its size in bytes.
 */
static int
ntfs_find_attr(
                char *buf,
                u_int32_t attrType,
                void **attrData,
                size_t *attrSize)
{
    struct filerec *filerec;
    struct attr *attr;
    u_int16_t offset;
    
    filerec = (struct filerec *) buf;
    offset = OSReadLittleInt16(&filerec->fr_attroff,0);
    attr = (struct attr *) (buf + offset);
    
    /*ее Should we also check offset < buffer size? */
    while (attr->a_hdr.a_type != 0xFFFFFFFF)	/* same for big/little endian */
    {
        if (OSReadLittleInt32(&attr->a_hdr.a_type,0) == attrType)
        {
            if (attr->a_hdr.a_flag != 0)
            {
                //verbose("NTFS: attriubte 0x%X is non-resident\n", attrType);
                return 1;
            }
            
            *attrSize = OSReadLittleInt16(&attr->a_r.a_datalen,0);
            *attrData = buf + offset + OSReadLittleInt16(&attr->a_r.a_dataoff,0);
            return 0;	/* found it! */
        }
        
        /* Skip to the next attribute */
        offset += OSReadLittleInt32(&attr->a_hdr.reclen,0);
        attr = (struct attr *) (buf + offset);
    }
    
    return 1;	/* No matching attrType found */
}
Ejemplo n.º 3
0
static uint64_t ReadMMIO(uint64_t phys, uint8_t length){
    uint64_t value = 0;
    //uint32_t *ioaddr;
    IOMemoryDescriptor* io_desc;
    IOMemoryMap* io_map;
    uint64_t page_offset = phys & PAGE_MASK;

    log_addr((uint64_t) page_offset, 64, "page_offset");

    xlate_pa_va(phys, &io_desc, &io_map);

    if(io_map) {
        log_addr(io_map->getVirtualAddress(), 64, "io_map->getVirtualAddress");

        switch (length) {
            case 1:
                value = *(volatile uint8_t *)((uintptr_t)(io_map->getVirtualAddress()) + page_offset);
                break;
            case 2:
                value = OSReadLittleInt16((void *)io_map->getVirtualAddress(),
                                         page_offset);
                break;
            case 4:
                value = OSReadLittleInt32((void *)io_map->getVirtualAddress(),
                                          page_offset);
                break;
            case 8:
                value = OSReadLittleInt64((void *)io_map->getVirtualAddress(),
                                          page_offset);
            default:
                pmem_error("ReadMMIO Incorrect read length");
                break;
        }

        // DEBUG
        //ioaddr = (uint32_t *) (io_map->getVirtualAddress() + page_offset);
        //log_addr((uint64_t)ioaddr, 64, "ioaddr");
    }

    unxlate_pa_va(&io_desc, &io_map);

    return value;
}
/*
 * Parse/validate a security buffer. Verifies that supplied offset/length don't go
 * past end of avaialble data. Returns ptr to actual data and its length. Returns
 * NTLM_ERR_PARSE_ERR on bogus values.
 */
OSStatus ntlmParseSecBuffer(
	const unsigned char *cp,			/* start of security buffer */
	const unsigned char *bufStart,		/* start of whole msg buffer */
	unsigned bufLen,					/* # of valid bytes starting at bufStart */
	const unsigned char **data,			/* RETURNED, start of actual data */
	uint16_t *dataLen)					/* RETURNED, length of actual data */
{
	assert(cp >= bufStart);

	uint16_t secBufLen = OSReadLittleInt16(cp, 0);
	/* skip length we just parsed plus alloc size, which we don't use */
	cp += 4;
	uint32_t offset = OSReadLittleInt32(cp, 0);
	if((offset + secBufLen) > bufLen) {
		dprintf("ntlmParseSecBuffer: buf overflow\n");
		return NTLM_ERR_PARSE_ERR;
	}
	*data = bufStart + offset;
	*dataLen = secBufLen;
	return errSecSuccess;
}
Ejemplo n.º 5
0
/*
 * Examine a volume to see if we recognize it as a mountable.
 */
void
NTFSGetDescription(CICell ih, char *str, long strMaxLen)
{
    struct bootfile *boot;
    unsigned bytesPerSector;
    unsigned sectorsPerCluster;
    int mftRecordSize;
    u_int64_t totalClusters;
    u_int64_t cluster, mftCluster;
    size_t mftOffset;
    void *nameAttr;
    size_t nameSize;
    char *buf;

    buf = (char *)malloc(MAX_CLUSTER_SIZE);
    if (buf == 0) {
        goto error;
    }

    /*
     * Read the boot sector, check signatures, and do some minimal
     * sanity checking.  NOTE: the size of the read below is intended
     * to be a multiple of all supported block sizes, so we don't
     * have to determine or change the device's block size.
     */
    Seek(ih, 0);
    Read(ih, (long)buf, MAX_BLOCK_SIZE);

    boot = (struct bootfile *) buf;
    
    /*
     * The first three bytes are an Intel x86 jump instruction.  I assume it
     * can be the same forms as DOS FAT:
     *    0xE9 0x?? 0x??
     *    0xEC 0x?? 0x90
     * where 0x?? means any byte value is OK.
     */
    if (boot->reserved1[0] != 0xE9
        && (boot->reserved1[0] != 0xEB || boot->reserved1[2] != 0x90))
    {
        goto error;
    }

    /*
     * Check the "NTFS    " signature.
     */
    if (memcmp((const char *)boot->bf_sysid, "NTFS    ", 8) != 0)
    {
        goto error;
    }

    /*
     * Make sure the bytes per sector and sectors per cluster are
     * powers of two, and within reasonable ranges.
     */
    bytesPerSector = OSReadLittleInt16(&boot->bf_bps,0);
    if ((bytesPerSector & (bytesPerSector-1)) || bytesPerSector < 512 || bytesPerSector > 32768)
    {
        //verbose("NTFS: invalid bytes per sector (%d)\n", bytesPerSector);
        goto error;
    }

    sectorsPerCluster = boot->bf_spc;	/* Just one byte; no swapping needed */
    if ((sectorsPerCluster & (sectorsPerCluster-1)) || sectorsPerCluster > 128)
    {
        //verbose("NTFS: invalid sectors per cluster (%d)\n", bytesPerSector);
        goto error;
    }
    
    /*
     * Calculate the number of clusters from the number of sectors.
     * Then bounds check the $MFT and $MFTMirr clusters.
     */
    totalClusters = OSReadLittleInt64(&boot->bf_spv,0) / sectorsPerCluster;
    mftCluster = OSReadLittleInt64(&boot->bf_mftcn,0);
    if (mftCluster > totalClusters)
    {
        ////verbose("NTFS: invalid $MFT cluster (%lld)\n", mftCluster);
        goto error;
    }
    cluster = OSReadLittleInt64(&boot->bf_mftmirrcn,0);
    if (cluster > totalClusters)
    {
        //verbose("NTFS: invalid $MFTMirr cluster (%lld)\n", cluster);
        goto error;
    }
    
    /*
     * Determine the size of an MFT record.
     */
    mftRecordSize = (int8_t) boot->bf_mftrecsz;
    if (mftRecordSize < 0)
        mftRecordSize = 1 << -mftRecordSize;
    else
        mftRecordSize *= bytesPerSector * sectorsPerCluster;
    //verbose("NTFS: MFT record size = %d\n", mftRecordSize);

    /*
     * Read the MFT record for $Volume.  This assumes the first four
     * file records in the MFT are contiguous; if they aren't, we
     * would have to map the $MFT itself.
     *
     * This will fail if the device sector size is larger than the
     * MFT record size, since the $Volume record won't be aligned
     * on a sector boundary.
     */
    mftOffset = mftCluster * sectorsPerCluster * bytesPerSector;
    mftOffset += mftRecordSize * NTFS_VOLUMEINO;

    Seek(ih, mftOffset);
    Read(ih, (long)buf, mftRecordSize);
#if UNUSED
    if (lseek(fd, mftOffset, SEEK_SET) == -1)
    {
        //verbose("NTFS: lseek to $Volume failed: %s\n", strerror(errno));
        goto error;
    }
    if (read(fd, buf, mftRecordSize) != mftRecordSize)
    {
        //verbose("NTFS: error reading MFT $Volume record: %s\n",
                strerror(errno));
        goto error;
    }
Ejemplo n.º 6
0
bool EX2Probe (const void *buf)
{
	return (OSReadLittleInt16(buf+0x438,0)==0xEF53);
}
Ejemplo n.º 7
0
Archivo: raw.c Proyecto: B1NG0/cifs
NTSTATUS
SMBRawTransaction(
    SMBHANDLE   inConnection,
    const void *lpInBuffer,
    size_t		nInBufferSize,
    void		*lpOutBuffer,
    size_t		nOutBufferSize,
    size_t		*lpBytesRead)
{
    NTSTATUS            status;
    int                 err;

    void *              hContext;

    struct smb_header   header;
    mbuf_t				words = NULL;
    mbuf_t				bytes = NULL;
    mbuf_t				response = NULL;
	size_t				len;

    const void * ptr;

	bzero(&header, sizeof(header));
    status = SMBServerContext(inConnection, &hContext);
	if (!NT_SUCCESS(status)) {
        return status;
    }

    if ((size_t)nInBufferSize < sizeof(struct smb_header) ||
        (size_t)nOutBufferSize < sizeof(struct smb_header)) {
 		err = STATUS_BUFFER_TOO_SMALL;
        goto errout;
    }

    /* Split the request buffer into the header, the parameter words and the
     * data bytes.
     */
    ptr = lpInBuffer;

    ADVANCE(ptr, sizeof(uint32_t));
    header.command = *(uint8_t *)ptr;

    if ((size_t)nInBufferSize < (sizeof(struct smb_header) + sizeof(uint8_t))) {
 		err = STATUS_BUFFER_TOO_SMALL;
        goto errout;
    }

    ptr = lpInBuffer;
    ADVANCE(ptr, sizeof(struct smb_header));

	len = (*(uint8_t *)ptr) * sizeof(uint16_t);
	ADVANCE(ptr, sizeof(uint8_t));  /* skip word_count field */
	if (mbuf_attachcluster(MBUF_WAITOK, MBUF_TYPE_DATA, &words, (void *)ptr, NULL, len, NULL)) {
		err = STATUS_NO_MEMORY;
        goto errout;
	}
	mbuf_setlen(words, len);
	ADVANCE(ptr, len);      /* skip parameter words */

    if ((uintptr_t)ptr > ((uintptr_t)lpInBuffer + nInBufferSize) ||
        (uintptr_t)ptr < (uintptr_t)mbuf_data(words)) {
		err = STATUS_MARSHALL_OVERFLOW;
        goto errout;
    }

    len = OSReadLittleInt16(ptr, 0);
    ADVANCE(ptr, sizeof(uint16_t)); /* skip byte_count field */
	if (mbuf_attachcluster(MBUF_WAITOK, MBUF_TYPE_DATA, &bytes, (void *)ptr, NULL, len, NULL)) {
		err = STATUS_NO_MEMORY;
        goto errout;
	}
	mbuf_setlen(bytes, len);
    ADVANCE(ptr, len);

    if ((uintptr_t)ptr > ((uintptr_t)lpInBuffer + nInBufferSize) ||
        (uintptr_t)ptr < (uintptr_t)mbuf_data(bytes)) {
		err = STATUS_MARSHALL_OVERFLOW;
        goto errout;
    }

    /* Set up the response buffer so that we leave room to place the
     * SMB header at the front.
     */
    len = (size_t)(nOutBufferSize - sizeof(struct smb_header));
 	if (mbuf_attachcluster(MBUF_WAITOK, MBUF_TYPE_DATA, &response, ((uint8_t *)lpOutBuffer + sizeof(struct smb_header)), NULL, len, NULL)) {
		err = STATUS_NO_MEMORY;
        goto errout;
    }
	
	err = smb_ioc_request(hContext, &header, words, bytes, response);
    if (err) {
		err = STATUS_IO_DEVICE_ERROR;
        goto errout;
    }

    /* Stash the new SMB header at the front of the output buffer so the
     * caller gets the server status code, etc.
     */
    memcpy(lpOutBuffer, lpInBuffer, sizeof(header));
    OSWriteLittleInt32(lpOutBuffer, 0, *(const uint32_t *)(void *)SMB_SIGNATURE);
    OSWriteLittleInt32(lpOutBuffer, offsetof(struct smb_header, status),
                    header.status);
    OSWriteLittleInt16(lpOutBuffer, offsetof(struct smb_header, flags),
					   header.flags);
    OSWriteLittleInt32(lpOutBuffer, offsetof(struct smb_header, flags2),
                    header.flags2);

    *lpBytesRead = mbuf_len(response) + sizeof(struct smb_header);

    /* We return success, even though the server may have failed the call. The
     * caller is responsible for parsing the reply packet and looking at the
     * status field in the header.
     */
    err = STATUS_SUCCESS;
	
errout:
    if (words)
		mbuf_freem(words);
    if (bytes)
		mbuf_freem(bytes);
    if (response)
		mbuf_freem(response);
	return err;
}