resurrecting-open-source-projects / dcfldd

Enhanced version of dd for forensics and security
GNU General Public License v2.0
90 stars 19 forks source link

Add 'diffwr' option #12

Closed szolnokit closed 1 year ago

szolnokit commented 1 year ago

'diffwr': write only to output if destination block content is differs [on/off] Default: off (working as original dcfldd)

Good feature, if the destination device is an SSD/flash/thumb drive device, and only some parts of source and destination(s) are different. For example: restore the SSD from an image file. The total speed much more faster, because of read instead full device write. And the smaller quantity of write not wearing SDD/flash device.

Working not only on block device, but working on plain image files as destination.

Tested many times with image files as source and real flash devices as destination, with destination re-checking. I used this feature practically on my forensic job, when I restore an SSD system disk cyclic. After every boot, I needed to restore the SSD disk from original image every time, again and again. Beacuse only small parts of system disk was modified at every boot, the "different write" was much more faster and "gentle" as full disk write. Without this feature, the full disk restore was half hour, with diffwr was only minutes. But the result on the SSD was same bit-by-bit.

diffwr feature only affects full_write function only. Not affects any other dcfldd functions any way. This feature is error proof. If destination read is not possible any way before write, this fall backs to default write operation. This provide, the result on destination will be always complete. In the full_write function, debug is possible (#if 1) to see, what blocks are written in real.

I hope, the forensics community use this feature with happy.

davidpolverari commented 1 year ago

Hi! First of all, thanks for the PR. It is nice to see some enhancement proposals for dcfldd, and that is an interesting one.

That said, I tried to build dcfldd with your changes, and there were lots of errors during the build:

dcfldd.c: In function ‘scanargs’:
dcfldd.c:583:13: error: expected ‘}’ before ‘else’
  583 |           } else if (STREQ(name, "diffwr")) {
      |             ^~~~
dcfldd.c:589:11: error: ‘else’ without a previous ‘if’
  589 |         } else {
      |           ^~~~
dcfldd.c:591:41: error: ‘val’ undeclared (first use in this function)
  591 |             uintmax_t n = parse_integer(val, &invalid);
      |                                         ^~~
dcfldd.c:591:41: note: each undeclared identifier is reported only once for each function it appears in
In file included from system.h:268,
                 from dcfldd.h:41,
                 from dcfldd.c:27:
dcfldd.c:593:23: error: ‘name’ undeclared (first use in this function)
  593 |             if (STREQ(name, "ibs")) {
      |                       ^~~~
sys2.h:280:31: note: in definition of macro ‘STREQ’
  280 | #define STREQ(a, b) (strcmp ((a), (b)) == 0)
      |                               ^
dcfldd.c: At top level:
dcfldd.c:646:5: error: expected identifier or ‘(’ before ‘if’
  646 |     if (input_blocksize == 0 || output_blocksize == 0)
      |     ^~
dcfldd.c:648:5: error: expected identifier or ‘(’ before ‘if’
  648 |     if (input_blocksize == 0)
      |     ^~
dcfldd.c:650:5: error: expected identifier or ‘(’ before ‘if’
  650 |     if (output_blocksize == 0)
      |     ^~
dcfldd.c:652:5: error: expected identifier or ‘(’ before ‘if’
  652 |     if (conversion_blocksize == 0)
      |     ^~
dcfldd.c:655:5: error: expected identifier or ‘(’ before ‘if’
  655 |     if (limit != 0) {
      |     ^~
dcfldd.c:661:5: error: expected identifier or ‘(’ before ‘for’
  661 |     for (i = 0; hashops[i].name != NULL; i++)
      |     ^~~
dcfldd.c:661:25: error: ‘i’ undeclared here (not in a function)
  661 |     for (i = 0; hashops[i].name != NULL; i++)
      |                         ^
dcfldd.c:661:27: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
  661 |     for (i = 0; hashops[i].name != NULL; i++)
      |                           ^
dcfldd.c:661:43: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘++’ token
  661 |     for (i = 0; hashops[i].name != NULL; i++)
      |                                           ^~
dcfldd.c:665:5: error: expected identifier or ‘(’ before ‘if’
  665 |     if (do_hash && hashflags == 0)
      |     ^~
dcfldd.c:668:5: error: expected identifier or ‘(’ before ‘if’
  668 |     if (do_verify) {
      |     ^~
dcfldd.c:671:7: error: expected identifier or ‘(’ before ‘else’
  671 |     } else if (do_hash)
      |       ^~~~
dcfldd.c:675:5: error: expected identifier or ‘(’ before ‘if’
  675 |     if (output_file != NULL && verify_file != NULL)
      |     ^~
dcfldd.c:677:1: error: expected identifier or ‘(’ before ‘}’ token
  677 | }
      | ^

You said that you tested the changes, so I assume you had it building on your machine somehow, but maybe you committed the wrong changes on this PR?

szolnokit commented 1 year ago

That said, I tried to build dcfldd with your changes, and there were lots of errors during the build: You said that you tested the changes, so I assume you had it building on your machine somehow, but maybe you committed the wrong changes on this PR?

Yes It worked, I have used many times. I will check soon... Maybe this is not the latest modification...

davidpolverari commented 1 year ago

Still doesn't build.

szolnokit commented 1 year ago

Sorry... my local version is working. I have problem to using th git... Sorry, I will try again.