简体   繁体   English

从C中的磁盘末尾读取数据

[英]Reading data from the end of disk in C

I try to use crypto key for decrypting disk in Ubuntu 16 and I want read it from the end of disk just as raw data without creating any file for security reason, ie like dd does in way我尝试使用加密密钥在 Ubuntu 16 中解密磁盘,并且出于安全原因,我想从磁盘末尾读取它作为原始数据而不创建任何文件,即像 dd 那样

sudo dd if=some_disk bs=1 skip=end_of_disk - keysize count=keysize

So, I wrote a test program所以,我写了一个测试程序

#include <fcntl.h>
#include <linux/fs.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

unsigned long long disksize(char *drivename)
{
  int fd;
  unsigned long long numblocks=0;

  fd = open(drivename, O_RDONLY);
  ioctl(fd, BLKGETSIZE64, &numblocks);
  close(fd);
  return numblocks;
}

int main(int argc, char **argv)
{
  int fd;
  FILE *device;
  int keySize = 2048;
  int count;
  unsigned char *block;
  unsigned long long endOfDisk=disksize(argv[1]);
  unsigned long long startFrom = endOfDisk - keySize;
  block = calloc(keySize, sizeof(char));
//  fd=open(argv[1], O_RDWR | O_DIRECT);
  device = fopen(argv[1], "r");
  long res = fseek(device, startFrom, SEEK_SET);
  perror("\nSeeking error:");
  fread(block, 1, keySize, device);
  fclose(device);
  printf("\nDevice Size: %lld\n", endOfDisk);
  printf("\nReading data starting from: %lld\n", startFrom);
  for(count = 0; count < keySize; count++){
      printf("%c", block[count]); 
  }
  free(block);
}

It works good on small disks, say, on boot partition or USB stick with capacity of 1Gb, but when I try to get key from, say, 4Gb USB stick, I can't: program prints something beyond key area on disk and perror shows "Invalid argument" as result of fseek .它在小型磁盘上运行良好,例如,在容量为 1Gb 的引导分区或 USB 记忆棒上,但是当我尝试从 4Gb USB 记忆棒获取密钥时,我不能:程序在磁盘上打印超出密钥区域的内容并出现错误显示“无效参数”作为fseek的结果。 It looks like fseek can't set pointer right and I don't understand why:看起来fseek无法正确设置指针,我不明白为什么:

fdisk -l some_disk

shows exactly the same disk size as endOfDisk from given program.显示与给定程序的endOfDisk完全相同的磁盘大小。

PS As someone can see from a couple of rudiments, I tried lseek too with exactly the same result printing exactly the same info instead of stored on disk key. PS 正如有人从一些基本知识中看到的那样,我也尝试了 lseek ,结果完全相同,打印完全相同的信息,而不是存储在磁盘密钥上。

ioctl(fd, BLKGETSIZE64, &numblocks) return size in 512-byte blocks, fseek() expect offset in bytes. ioctl(fd, BLKGETSIZE64, &numblocks)以 512 字节块为单位返回大小, fseek()期望以字节为单位的偏移量。 BTW, you can set pointer relative to the end of disk without knowing it's size:顺便说一句,您可以在不知道磁盘大小的情况下设置相对于磁盘末尾的指针:

fseek(device, -keySize, SEEK_END);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM