diff options
Diffstat (limited to 'src/hd24hexview.cpp')
-rwxr-xr-x | src/hd24hexview.cpp | 923 |
1 files changed, 923 insertions, 0 deletions
diff --git a/src/hd24hexview.cpp b/src/hd24hexview.cpp new file mode 100755 index 0000000..8ee4751 --- /dev/null +++ b/src/hd24hexview.cpp | |||
@@ -0,0 +1,923 @@ | |||
1 | #include <iostream> | ||
2 | #include <algorithm> | ||
3 | #include <cctype> | ||
4 | #include <string> | ||
5 | #include <sys/types.h> | ||
6 | #include <sys/stat.h> | ||
7 | #include <fcntl.h> | ||
8 | #include <stdio.h> | ||
9 | #include <stdlib.h> | ||
10 | #include "config.h" | ||
11 | #include "hd24fs.h" | ||
12 | #include "convertlib.h" | ||
13 | |||
14 | #define VERSION "1.3 beta" | ||
15 | #define _LARGE_FILES | ||
16 | #define _FILE_OFFSET_BITS 64 | ||
17 | #define FILE_OFFSET_BITS 64 | ||
18 | #define LARGE_FILES | ||
19 | #define LARGEFILE64_SOURCE | ||
20 | #define SECTORSIZE 512 | ||
21 | #define ARGHEADER "--header=" | ||
22 | |||
23 | #ifdef DARWIN | ||
24 | # define open64 open | ||
25 | # define lseek64 lseek | ||
26 | # define pread64 pread | ||
27 | # define creat64 creat | ||
28 | # define pwrite64 pwrite | ||
29 | #endif | ||
30 | |||
31 | #ifndef WINDOWS | ||
32 | # include <unistd.h> | ||
33 | #endif | ||
34 | |||
35 | string device; | ||
36 | string headerfilename; | ||
37 | __uint64 writeoffset; | ||
38 | int force; | ||
39 | int expertmode; | ||
40 | int graphmode; | ||
41 | int enable_graphmode; | ||
42 | int disable_graphmode; | ||
43 | |||
44 | // Check if a file exists | ||
45 | bool fileexists (string* fname) | ||
46 | { | ||
47 | struct stat fi; | ||
48 | |||
49 | if ((stat(fname->c_str(), &fi) != -1) && ((fi.st_mode & S_IFDIR) == 0)) { | ||
50 | return true; | ||
51 | } | ||
52 | |||
53 | return false; | ||
54 | } | ||
55 | |||
56 | // Check if file handle is invalid | ||
57 | bool isinvalidhandle(FSHANDLE handle) | ||
58 | { | ||
59 | #ifdef WINDOWS | ||
60 | if (handle == FSHANDLE_INVALID) { | ||
61 | return true; | ||
62 | } | ||
63 | #else | ||
64 | if (handle == 0 || handle == FSHANDLE_INVALID) { | ||
65 | return true; | ||
66 | } | ||
67 | #endif | ||
68 | return false; | ||
69 | } | ||
70 | |||
71 | // Output a message for expert only features | ||
72 | void expertmodemessage(string feature) | ||
73 | { | ||
74 | cout << feature <<" is only allowed in expert mode." << endl; | ||
75 | } | ||
76 | |||
77 | // Seek to a position in the drive | ||
78 | void hd24seek(FSHANDLE devhd24, __uint64 seekpos) | ||
79 | { | ||
80 | #ifdef WINDOWS | ||
81 | LARGE_INTEGER li; | ||
82 | li.HighPart = seekpos >> 32; | ||
83 | li.LowPart = seekpos % ((__uint64) 1 << 32); | ||
84 | SetFilePointerEx(devhd24, li, NULL, FILE_BEGIN); | ||
85 | #else | ||
86 | lseek64(devhd24, seekpos, 0); | ||
87 | #endif | ||
88 | return; | ||
89 | } | ||
90 | |||
91 | // Calculate a 32-bit checksum for a block | ||
92 | long unsigned int calcblockchecksum(hd24raw* rawdevice, unsigned long firstsector, unsigned long endsector) | ||
93 | { | ||
94 | long unsigned int checksum32 = 0; | ||
95 | unsigned char origblock[5120]; | ||
96 | |||
97 | for (unsigned long k = firstsector; k < endsector; k++) | ||
98 | { | ||
99 | rawdevice->readsectors(k, origblock, 1); | ||
100 | |||
101 | for (unsigned long i = 0; i < SECTORSIZE; i += 4) | ||
102 | { | ||
103 | unsigned long num = Convert::getint32(origblock, i); | ||
104 | int byte1 = num % 256; | ||
105 | int byte2 = (num >> 8) % 256; | ||
106 | int byte3 = (num >> 16) % 256; | ||
107 | int byte4 = (num >> 24) % 256; | ||
108 | num = byte4 + (byte3 << 8) + (byte2 << 16) + (byte1 << 24); | ||
109 | checksum32 += num; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | return checksum32; | ||
114 | } | ||
115 | |||
116 | // Write to a sector | ||
117 | long writesectors(FSHANDLE devhd24, unsigned long sectornum, unsigned char * buffer, int sectors) | ||
118 | { | ||
119 | int WRITESIZE = SECTORSIZE * sectors; // allows searching across sector boundaries | ||
120 | hd24seek(devhd24, (__uint64) sectornum * 512); | ||
121 | |||
122 | #ifdef WINDOWS | ||
123 | DWORD dummy; | ||
124 | long bytes = 0; | ||
125 | |||
126 | if (WriteFile(devhd24, buffer, WRITESIZE, &dummy, NULL)) { | ||
127 | bytes = WRITESIZE; | ||
128 | }; | ||
129 | #else | ||
130 | long bytes = pwrite64(devhd24, buffer, WRITESIZE, (__uint64) sectornum * 512); | ||
131 | #endif | ||
132 | |||
133 | return bytes; | ||
134 | } | ||
135 | |||
136 | void writetofile(hd24raw* rawdevice,string filename, long firstsector,long endsector) | ||
137 | { | ||
138 | int i; | ||
139 | unsigned char bootblock[5120]; | ||
140 | #if defined(LINUX) || defined(DARWIN) | ||
141 | FSHANDLE handle=creat64(filename.c_str(),O_WRONLY); | ||
142 | #endif | ||
143 | #ifdef WINDOWS | ||
144 | FSHANDLE handle=CreateFile(filename.c_str(),GENERIC_WRITE|GENERIC_READ, | ||
145 | FILE_SHARE_READ|FILE_SHARE_WRITE, | ||
146 | NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); | ||
147 | if (isinvalidhandle(handle)) { | ||
148 | handle=CreateFile(filename.c_str(),GENERIC_WRITE|GENERIC_READ, | ||
149 | FILE_SHARE_READ|FILE_SHARE_WRITE, | ||
150 | NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); | ||
151 | } | ||
152 | |||
153 | #endif | ||
154 | if (isinvalidhandle(handle)) { | ||
155 | cout << "Cannot open file "<<filename <<" for writing. Access denied?" << endl; | ||
156 | return; | ||
157 | } | ||
158 | cout << "Write range from offset "<< *Convert::int64tohex((__uint64)firstsector*512)<< " to offset " << *Convert::int64tohex((__uint64)endsector*512-1) << endl; | ||
159 | for (i=firstsector;i<endsector;i++) { | ||
160 | rawdevice->readsectors(i,bootblock,1); | ||
161 | #if defined(LINUX) || defined(DARWIN) | ||
162 | __uint64 targetoff=i; | ||
163 | targetoff-=firstsector; | ||
164 | targetoff+=writeoffset; | ||
165 | targetoff*=512; | ||
166 | ssize_t byteswritten=pwrite64(handle,bootblock,512,targetoff); | ||
167 | #endif | ||
168 | #ifdef WINDOWS | ||
169 | //DWORD dummy; | ||
170 | //long bytes=0; | ||
171 | __uint64 targetoff=i; | ||
172 | targetoff-=firstsector; | ||
173 | targetoff+=writeoffset; | ||
174 | __uint64 byteswritten=writesectors(handle,targetoff,bootblock,1); | ||
175 | #endif | ||
176 | if (byteswritten==0) { | ||
177 | cout << "Wrote 0 bytes to file. Access denied?" << endl; | ||
178 | #if defined(LINUX) || defined(DARWIN) | ||
179 | close (handle); | ||
180 | #endif | ||
181 | #ifdef WNDOWS | ||
182 | CloseHandle(handle); | ||
183 | #endif | ||
184 | return; | ||
185 | } | ||
186 | if ((i%1000)==0) { | ||
187 | string* x=Convert::int64tohex((__uint64)i*0x200); | ||
188 | cout << "Write offset " << *x << "\r"; | ||
189 | if (x!=NULL) { delete x; x=NULL; } | ||
190 | } | ||
191 | } | ||
192 | #if defined(LINUX) || defined(DARWIN) | ||
193 | close (handle); | ||
194 | #endif | ||
195 | #ifdef WINDOWS | ||
196 | CloseHandle(handle); | ||
197 | #endif | ||
198 | return; | ||
199 | } | ||
200 | |||
201 | string getbinstr(string tofind) | ||
202 | { | ||
203 | if (tofind.substr(0,1)=="'") { | ||
204 | // find literal string | ||
205 | tofind=tofind.substr(1,tofind.length()-2); | ||
206 | cout << "Find string " << tofind << endl; | ||
207 | } else { | ||
208 | string binstr=""; | ||
209 | string tmp=""; | ||
210 | tofind+=" "; | ||
211 | unsigned int i; | ||
212 | for (i=0;i<tofind.length();i++) { | ||
213 | string onechar=tofind.substr(i,1); | ||
214 | if (onechar!=" ") { | ||
215 | if (!Convert::isnibble(onechar)) { | ||
216 | cout << "Error: not a valid hex string" << endl; | ||
217 | return ""; | ||
218 | } | ||
219 | tmp+=onechar; | ||
220 | } else { | ||
221 | if (tmp!="") { | ||
222 | binstr+=Convert::hex2byte(tmp); | ||
223 | } | ||
224 | tmp=""; | ||
225 | } | ||
226 | } | ||
227 | tofind=binstr; | ||
228 | cout << "looking for " << binstr << endl; | ||
229 | } | ||
230 | return *(new string(tofind)); | ||
231 | } | ||
232 | |||
233 | long movebytes(unsigned char* bootblock,string editstr) | ||
234 | { | ||
235 | string strfrompos=""; | ||
236 | string strmovelen=""; | ||
237 | string strtopos=""; | ||
238 | while ( | ||
239 | (editstr.substr(0,1)!=" ") | ||
240 | &&(editstr.substr(0,1)!="l") | ||
241 | &&(editstr.substr(0,1)!="L") | ||
242 | &&(editstr!="")) | ||
243 | { | ||
244 | strfrompos+=editstr.substr(0,1); | ||
245 | editstr=editstr.substr(1,editstr.length()-1); | ||
246 | } | ||
247 | if ( | ||
248 | (editstr.substr(0,1)=="l") | ||
249 | ||(editstr.substr(0,1)=="L")) | ||
250 | { | ||
251 | editstr=editstr.substr(1,editstr.length()-1); | ||
252 | |||
253 | while ( | ||
254 | (editstr.substr(0,1)!=" ") | ||
255 | &&(editstr!="")) | ||
256 | { | ||
257 | strmovelen+=editstr.substr(0,1); | ||
258 | editstr=editstr.substr(1,editstr.length()-1); | ||
259 | } | ||
260 | } else { | ||
261 | cout << "Syntax: m<from>L<len> <target>" << endl; | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | if ( | ||
266 | (editstr.substr(0,1)==" ") | ||
267 | ) | ||
268 | { | ||
269 | editstr=editstr.substr(1,editstr.length()-1); | ||
270 | |||
271 | while ( | ||
272 | (editstr.substr(0,1)!=" ") | ||
273 | &&(editstr!="")) | ||
274 | { | ||
275 | strtopos+=editstr.substr(0,1); | ||
276 | editstr=editstr.substr(1,editstr.length()-1); | ||
277 | } | ||
278 | } else { | ||
279 | cout << "Syntax: m<from>L<len> <target>" << endl; | ||
280 | return 0; | ||
281 | } | ||
282 | cout << " strfrompos=" << strfrompos << endl; | ||
283 | cout << " strmovelen=" << strmovelen << endl; | ||
284 | cout << " strtopos=" << strtopos << endl; | ||
285 | |||
286 | long frompos=(Convert::hex2long(strfrompos)%SECTORSIZE); | ||
287 | long movelen=(Convert::hex2long(strmovelen)%SECTORSIZE); | ||
288 | long topos=(Convert::hex2long(strtopos)%SECTORSIZE); | ||
289 | cout << " pos=" << frompos << endl; | ||
290 | cout << " movelen=" << movelen << endl; | ||
291 | cout << " movepos=" << topos << endl; | ||
292 | void* x=malloc(movelen); | ||
293 | memcpy(x,bootblock+frompos,movelen); | ||
294 | memcpy(bootblock+topos,x,movelen); | ||
295 | free (x); | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | long editbytes(unsigned char* bootblock,string editstr) | ||
300 | { | ||
301 | string strpos=""; | ||
302 | while ((editstr.substr(0,1)!=" ") &&(editstr!="")) { | ||
303 | strpos+=editstr.substr(0,1); | ||
304 | editstr=editstr.substr(1,editstr.length()-1); | ||
305 | } | ||
306 | if (editstr!="") { | ||
307 | editstr=editstr.substr(1,editstr.length()-1); | ||
308 | } | ||
309 | string binstr=getbinstr(editstr); | ||
310 | long pos=(Convert::hex2long(strpos)%SECTORSIZE); | ||
311 | cout << "binstr=" << binstr << " " << pos << endl; | ||
312 | memcpy(bootblock+pos,binstr.c_str(),binstr.length()); | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | void compareblock(hd24raw* rawdevice,unsigned long firstsector,unsigned long endsector,long current) | ||
317 | { | ||
318 | unsigned int i; | ||
319 | unsigned int j; | ||
320 | unsigned int k; | ||
321 | unsigned char origblock[5120]; | ||
322 | unsigned char destblock[5120]; | ||
323 | string* startoff=Convert::int64tohex((__uint64)firstsector*512); | ||
324 | string* endoff=Convert::int64tohex((__uint64)endsector*512-1); | ||
325 | cout << "Compare range from offset "<< *startoff << " to offset " << *endoff <<endl; | ||
326 | delete startoff; startoff=NULL; | ||
327 | delete endoff; endoff=NULL; | ||
328 | int anydifs=0; | ||
329 | for (k=firstsector; k<endsector; k++) | ||
330 | { | ||
331 | rawdevice->readsectors(k,origblock,1); | ||
332 | rawdevice->readsectors(k-firstsector+current,destblock,1); | ||
333 | for (i=0;i<SECTORSIZE;i+=16) { | ||
334 | string strline1=""; | ||
335 | string strline2=""; | ||
336 | int havedifs=0; | ||
337 | long offset=k*512; | ||
338 | string* result1=Convert::int32tohex(offset+i); | ||
339 | strline1+= *result1+" "; | ||
340 | offset=current*512; | ||
341 | delete result1; result1=NULL; | ||
342 | string* result2=Convert::int32tohex(offset+i); | ||
343 | strline2+= *result2+" "; | ||
344 | delete result2; result2=NULL; | ||
345 | for (j=0;j<16;j++) | ||
346 | { | ||
347 | if (origblock[i+j]!=destblock[i+j]) | ||
348 | { | ||
349 | string* result=Convert::byte2hex(origblock[i+j]); | ||
350 | strline1+= *result; | ||
351 | delete result; result=NULL; | ||
352 | havedifs=1; | ||
353 | } else { | ||
354 | strline1+=" "; | ||
355 | } | ||
356 | string *result= Convert::byte2hex(destblock[i+j]) ; | ||
357 | strline2+= *result; | ||
358 | delete result; result=NULL; | ||
359 | if (j==7) { | ||
360 | strline1+= "-" ; | ||
361 | strline2+= "-" ; | ||
362 | } else { | ||
363 | strline1+= " " ; | ||
364 | strline2+= " " ; | ||
365 | } | ||
366 | } | ||
367 | strline1+= " "; | ||
368 | strline2+= " "; | ||
369 | for (j=0;j<16;j++) { | ||
370 | strline1+= Convert::safebyte(origblock[i+j]); | ||
371 | if (origblock[i+j]!=destblock[i+j]) { | ||
372 | strline2+= Convert::safebyte(destblock[i+j]); | ||
373 | } else { | ||
374 | strline2+=" "; | ||
375 | } | ||
376 | } | ||
377 | if (havedifs==1) { | ||
378 | anydifs=1; | ||
379 | cout << strline1 << endl; | ||
380 | cout << strline2 << endl; | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | if (anydifs==0) { | ||
385 | cout << "Blocks are equal." << endl; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | long scanforblock(hd24raw* rawdevice,string tofind,unsigned long firstsector,unsigned long endsector,long current) | ||
390 | { | ||
391 | unsigned int i; | ||
392 | unsigned char bootblock[5120]; | ||
393 | tofind=getbinstr(tofind); | ||
394 | if (tofind=="") return current; | ||
395 | |||
396 | /* Now that we know what to look for, let us try to find the string. | ||
397 | * Note that we can search across sector boundaries because we read | ||
398 | * 2 sectors at a time. | ||
399 | */ | ||
400 | string* startoff= Convert::int64tohex((__uint64)firstsector*512); | ||
401 | string* endoff=Convert::int64tohex((__uint64)endsector*512-1); | ||
402 | cout << "Scan range from offset "<< *startoff << " to offset " << *endoff << endl; | ||
403 | delete startoff; startoff=NULL; | ||
404 | delete endoff; endoff=NULL; | ||
405 | for (i=firstsector; i<endsector; i++) { | ||
406 | rawdevice->readsectors(i,bootblock,2); | ||
407 | if ((i%0x1000)==0) { | ||
408 | string* curroff=Convert::int64tohex((__uint64)i*0x200); | ||
409 | cout << "Scan offset " << *curroff << "\r"; | ||
410 | delete curroff; curroff=NULL; | ||
411 | } | ||
412 | /* check if string found. */ | ||
413 | int j=0; | ||
414 | for (j=0;j<512;j++) { | ||
415 | |||
416 | if (memcmp((const void *)&bootblock[j],(const void *)tofind.c_str(),(size_t)tofind.length())==0) { | ||
417 | string* foundoff=Convert::int64tohex((__uint64)i*512+j); | ||
418 | cout << endl << "Found on offset " << *foundoff << endl; | ||
419 | delete foundoff; foundoff=NULL; | ||
420 | return i; | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | cout << endl << "Not found." << endl; | ||
425 | return current; | ||
426 | } | ||
427 | |||
428 | void fstfix(unsigned char * bootblock,int fixsize) | ||
429 | { | ||
430 | for (int i=0;i<fixsize;i+=4) | ||
431 | { | ||
432 | unsigned char a=bootblock[i]; | ||
433 | unsigned char b=bootblock[i+1]; | ||
434 | unsigned char c=bootblock[i+2]; | ||
435 | unsigned char d=bootblock[i+3]; | ||
436 | bootblock[i]=d; | ||
437 | bootblock[i+1]=c; | ||
438 | bootblock[i+2]=b; | ||
439 | bootblock[i+3]=a; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | int parsecommandline(int argc, char ** argv) | ||
444 | { | ||
445 | int invalid=0; | ||
446 | force=0; | ||
447 | expertmode=0; | ||
448 | device=""; | ||
449 | headerfilename=""; | ||
450 | for (int c=1;c<argc;c++) { | ||
451 | string arg=argv[c]; | ||
452 | if (arg.substr(0,2)!="--") { | ||
453 | if (fileexists(&arg)) { | ||
454 | device=arg; | ||
455 | force=1; | ||
456 | continue; | ||
457 | } | ||
458 | } | ||
459 | if (arg.substr(0,strlen("--dev="))=="--dev=") { | ||
460 | device=arg.substr(strlen("--dev=")); | ||
461 | continue; | ||
462 | } | ||
463 | if (arg.substr(0,strlen("--expert"))=="--expert") { | ||
464 | expertmode=1; | ||
465 | continue; | ||
466 | } | ||
467 | if (arg.substr(0,strlen(ARGHEADER))==ARGHEADER) { | ||
468 | headerfilename=arg.substr(strlen(ARGHEADER)); | ||
469 | continue; | ||
470 | } | ||
471 | |||
472 | if (arg.substr(0,strlen("--force"))=="--force") { | ||
473 | force=1; | ||
474 | continue; | ||
475 | } | ||
476 | cout << "Invalid argument: " << arg << endl; | ||
477 | invalid=1; | ||
478 | } | ||
479 | return invalid; | ||
480 | } | ||
481 | |||
482 | int main (int argc,char ** argv) | ||
483 | { | ||
484 | int invalid=parsecommandline(argc,argv); | ||
485 | if (invalid!=0) { | ||
486 | return invalid; | ||
487 | } | ||
488 | |||
489 | hd24fs* fsys = NULL; | ||
490 | if (device=="") { | ||
491 | fsys=new hd24fs((const char*)NULL,hd24fs::MODE_RDWR); | ||
492 | } else { | ||
493 | cout << "Trying to use " << device << " as hd24 device." << endl; | ||
494 | fsys=new hd24fs((const char*)NULL,hd24fs::MODE_RDWR,&device,(force==1)); | ||
495 | } | ||
496 | |||
497 | hd24raw* rawdevice = NULL; | ||
498 | |||
499 | rawdevice=new hd24raw(fsys); //1==1 is true -> no translate | ||
500 | if (!fsys->isOpen()) { | ||
501 | cout << "Cannot open hd24 device." << endl; | ||
502 | delete fsys; fsys=NULL; | ||
503 | if (rawdevice!=NULL) | ||
504 | { | ||
505 | delete rawdevice; | ||
506 | rawdevice=NULL; | ||
507 | } | ||
508 | return 1; | ||
509 | } | ||
510 | if (headerfilename!="") | ||
511 | { | ||
512 | if (!(fsys->useheaderfile(headerfilename))) | ||
513 | { | ||
514 | cout << "Couldn't load header file "<<headerfilename << endl; | ||
515 | delete fsys; fsys=NULL; | ||
516 | return 1; | ||
517 | }; | ||
518 | } | ||
519 | //delete fsys; //not yet, rawdevice is using this | ||
520 | cout << "Using device " << *fsys->getdevicename() << endl; | ||
521 | /* Initialization */ | ||
522 | unsigned char bootblock[5120]; | ||
523 | unsigned long sectornum=0; | ||
524 | int nodump=0; | ||
525 | int noread=0; | ||
526 | int writesec=0; | ||
527 | unsigned long blockstart=0; | ||
528 | unsigned long blockend=0; | ||
529 | writeoffset=0; | ||
530 | unsigned long checksum=0; | ||
531 | string userinput; | ||
532 | string lastsearch=""; | ||
533 | if (expertmode==1) { | ||
534 | cout << "Expert mode enabled. " << endl; | ||
535 | cout << "Warning! Disk writes are enabled." << endl; | ||
536 | cout << "You now have the capability to destroy." << endl; | ||
537 | cout << "Proceed with extreme caution!" << endl; | ||
538 | } | ||
539 | |||
540 | try{ | ||
541 | /* try block is intended to make sure hd24 device is closed on exit*/ | ||
542 | string filename="outfile.dmp"; | ||
543 | |||
544 | do { | ||
545 | int i; | ||
546 | int j; | ||
547 | if (enable_graphmode==1) | ||
548 | { | ||
549 | cout << "Enabling graph mode." << endl; | ||
550 | graphmode=1; | ||
551 | enable_graphmode=0; | ||
552 | } | ||
553 | if (disable_graphmode==1) { | ||
554 | cout << "Disabling graph mode." << endl; | ||
555 | graphmode=0; | ||
556 | disable_graphmode=0; | ||
557 | } | ||
558 | if (writesec==1) { | ||
559 | rawdevice->writesectors(sectornum,bootblock,1); | ||
560 | writesec=0; | ||
561 | } | ||
562 | if (noread==0) { | ||
563 | rawdevice->readsectors(sectornum,bootblock,1); | ||
564 | } | ||
565 | noread=0; | ||
566 | long offset=sectornum*512; | ||
567 | if (nodump==0) { | ||
568 | cout << "Sector " << *Convert::int32tohex((long)sectornum) << endl; | ||
569 | |||
570 | for (i=0;i<SECTORSIZE;i+=16) { | ||
571 | string* dummy=Convert::int32tohex(offset+i); | ||
572 | cout << *dummy << " "; | ||
573 | delete dummy; dummy=NULL; | ||
574 | for (j=0;j<16;j++) { | ||
575 | string* dummy= Convert::byte2hex(bootblock[i+j]); | ||
576 | cout << *dummy; | ||
577 | if (j==7) { | ||
578 | cout << "-" ; | ||
579 | } else { | ||
580 | cout << " " ; | ||
581 | } | ||
582 | delete dummy; dummy=NULL; | ||
583 | } | ||
584 | cout << " "; | ||
585 | for (j=0;j<16;j++) { | ||
586 | cout << Convert::safebyte(bootblock[i+j]); | ||
587 | } | ||
588 | cout << "" << endl; | ||
589 | } | ||
590 | } | ||
591 | nodump=0; | ||
592 | cout << "-"; | ||
593 | char inputbuf[1025]; | ||
594 | cin.getline(inputbuf,1024); | ||
595 | userinput=""; | ||
596 | userinput+=inputbuf; | ||
597 | if (userinput=="") { | ||
598 | continue; | ||
599 | } | ||
600 | while ( | ||
601 | (userinput.substr(userinput.length()-1,1)==" ") | ||
602 | ||(userinput.substr(userinput.length()-1,1)=="\n") | ||
603 | ||(userinput.substr(userinput.length()-1,1)=="\r") | ||
604 | ) | ||
605 | { | ||
606 | userinput=userinput.substr(0,userinput.length()-1); | ||
607 | } | ||
608 | if (userinput=="+") { | ||
609 | sectornum++; | ||
610 | continue; | ||
611 | } | ||
612 | if (userinput=="gon") { | ||
613 | if (graphmode==0) { | ||
614 | enable_graphmode=1; | ||
615 | } | ||
616 | continue; | ||
617 | } | ||
618 | if ((userinput=="goff")||(userinput=="gof")) { | ||
619 | if (graphmode==1) { | ||
620 | disable_graphmode=1; | ||
621 | } | ||
622 | continue; | ||
623 | } | ||
624 | if (userinput=="wo") { | ||
625 | writeoffset=0; | ||
626 | cout << "Writeoffset cleared." << endl; | ||
627 | nodump=1; // inhibit viewing the sector after this command. | ||
628 | continue; | ||
629 | } | ||
630 | if (userinput.substr(0,2)=="wo") { | ||
631 | writeoffset=Convert::hex2long(userinput.substr(2,userinput.length()-2)); | ||
632 | string* convwrite=Convert::int32tohex(writeoffset); | ||
633 | cout << "Writeoffset set to " << *convwrite << " sectors." << endl; | ||
634 | delete convwrite; convwrite=NULL; | ||
635 | nodump=1; // inhibit viewing the sector after this command. | ||
636 | continue; | ||
637 | } | ||
638 | if (userinput.substr(0,1)=="+") { | ||
639 | long sectoadd=Convert::hex2long(userinput.substr(1,userinput.length()-1)); | ||
640 | sectornum+=sectoadd; | ||
641 | continue; | ||
642 | } | ||
643 | if (userinput=="-") { | ||
644 | if (sectornum>0) | ||
645 | { | ||
646 | sectornum--; | ||
647 | } else { | ||
648 | sectornum=0; | ||
649 | } | ||
650 | continue; | ||
651 | } | ||
652 | if (userinput.substr(0,1)=="-") { | ||
653 | long sectoadd=Convert::hex2long(userinput.substr(1,userinput.length()-1)); | ||
654 | if ((__uint32)sectoadd>(__uint32)sectornum) | ||
655 | { | ||
656 | sectornum=0; | ||
657 | } else { | ||
658 | sectornum-=sectoadd; | ||
659 | } | ||
660 | continue; | ||
661 | } | ||
662 | if (userinput==".") { | ||
663 | noread=1; | ||
664 | continue; | ||
665 | } | ||
666 | if ((userinput.substr(0,1)=="?")||(userinput=="help")) { | ||
667 | cout << "Help for hd24hexview " << VERSION << endl; | ||
668 | cout << "==============================" << endl; | ||
669 | cout << "General:" <<endl; | ||
670 | cout << " q quit" << endl; | ||
671 | cout << " ? shows this help" << endl; | ||
672 | cout << endl; | ||
673 | cout << "Navigation:" << endl; | ||
674 | cout << " + dump next sector" << endl; | ||
675 | cout << " +<n> increment n sectors, then dump sector"<<endl; | ||
676 | cout << " - dump prev sector" << endl; | ||
677 | cout << " -<n> decrement n sectors, then dump sector"<<endl; | ||
678 | cout << " . re-display current sector" << endl; | ||
679 | cout << " d<hex> dump sector <hex>" << endl; | ||
680 | cout << " d-<hex> dump sector totalnumberofsectors-<hex>" << endl; | ||
681 | cout << " d re-read current sector from disk" << endl; | ||
682 | cout << " m<from>l<hexlen> <to>" << endl; | ||
683 | cout << " move <hexlen> bytes from offset <from> to <to>" << endl; | ||
684 | cout << " o<hex> dump sector that contains offset <hex>" << endl; | ||
685 | cout << " s x y.. scan marked block for byte sequence x y ..." << endl; | ||
686 | cout << " s'...' scan marked block for exact string" << endl; | ||
687 | cout << " e<p> xx edit byte sequence at pos p to xxxx " << endl; | ||
688 | cout << " e<p> 'x' edit pos p to string 'x'" << endl; | ||
689 | cout << endl; | ||
690 | cout << "Block commands:" << endl; | ||
691 | cout << " bb mark start of sector as block beginning" << endl; | ||
692 | cout << " be mark end of sector as block end" << endl; | ||
693 | cout << " bc block clear" << endl; | ||
694 | cout << " diff compare marked block with current" << endl; | ||
695 | cout << " p paste first sector of marked block to current sector" << endl; | ||
696 | cout << endl; | ||
697 | cout << "File commands:" << endl; | ||
698 | cout << " n<xx> set filename to xx" << endl; | ||
699 | cout << " n clear filename" << endl; | ||
700 | cout << " w write marked block to named file/device" << endl; | ||
701 | cout << " wo clear sector write offset for file/device write" << endl; | ||
702 | cout << " wo<xx> set write offset to xx sectors" << endl; | ||
703 | cout << " ws write back current edited sector to disk" << endl; | ||
704 | cout << "HD24 specific features:" << endl; | ||
705 | cout << " fix reverse byte ordering of 32 bit words" << endl; | ||
706 | cout << " for better human readability" << endl; | ||
707 | cout << " cs Calc checksum of selected block" << endl; | ||
708 | cout << " scs Set zero checksum of selected block" << endl; | ||
709 | |||
710 | nodump=1; // inhibit viewing the sector after this command. | ||
711 | continue; | ||
712 | } | ||
713 | if (userinput.substr(0,2)=="bc") { | ||
714 | blockstart=0; | ||
715 | blockend=0; | ||
716 | cout << "Block selection cleared." << endl; | ||
717 | nodump=1; // inhibit viewing the sector after this command. | ||
718 | continue; | ||
719 | } | ||
720 | if (userinput.substr(0,2)=="bb") { | ||
721 | cout << "Block start set." << endl; | ||
722 | nodump=1; // inhibit viewing the sector after this command. | ||
723 | blockstart=sectornum; | ||
724 | continue; | ||
725 | } | ||
726 | if (userinput.substr(0,2)=="be") { | ||
727 | cout << "Block end set." << endl; | ||
728 | /* dump is startsector..endsector, | ||
729 | * excl. end sector. number of bytes to dump= | ||
730 | * (blockend-blockstart)*512 | ||
731 | */ | ||
732 | nodump=1; // inhibit viewing the sector after this command. | ||
733 | blockend=sectornum+1; | ||
734 | continue; | ||
735 | } | ||
736 | if (userinput.substr(0,2)=="cs") { | ||
737 | checksum=calcblockchecksum(rawdevice,blockstart,blockend); | ||
738 | cout << "Block checksum is " << checksum << endl; | ||
739 | nodump=1; | ||
740 | noread=1; | ||
741 | continue; | ||
742 | } | ||
743 | if (userinput.substr(0,3)=="scs") { | ||
744 | if (blockend-1!=sectornum) { | ||
745 | cout << "Current sector must be block end." << endl; | ||
746 | nodump=1; | ||
747 | noread=1; | ||
748 | continue; | ||
749 | } | ||
750 | unsigned long checksum=calcblockchecksum(rawdevice,blockstart,blockend); | ||
751 | unsigned long oldchecksum=0; | ||
752 | oldchecksum+=((unsigned char)(bootblock[511])); oldchecksum=oldchecksum <<8; | ||
753 | oldchecksum+=((unsigned char)(bootblock[510])); oldchecksum=oldchecksum <<8; | ||
754 | oldchecksum+=((unsigned char)(bootblock[509])); oldchecksum=oldchecksum <<8; | ||
755 | oldchecksum+=((unsigned char)(bootblock[508])); | ||
756 | oldchecksum-=checksum; | ||
757 | bootblock[508]=oldchecksum%256; oldchecksum=oldchecksum >> 8; | ||
758 | bootblock[509]=oldchecksum%256; oldchecksum=oldchecksum >> 8; | ||
759 | bootblock[510]=oldchecksum%256; oldchecksum=oldchecksum >> 8; | ||
760 | bootblock[511]=oldchecksum%256; oldchecksum=oldchecksum >> 8; | ||
761 | |||
762 | noread=1; | ||
763 | continue; | ||
764 | } | ||
765 | if (userinput.substr(0,4)=="diff") { | ||
766 | nodump=1; // inhibit viewing the sector after this command. | ||
767 | if (blockend==blockstart) { | ||
768 | cout << "Please set block start/end first." << endl; | ||
769 | continue; | ||
770 | } | ||
771 | compareblock(rawdevice,blockstart,blockend,sectornum); | ||
772 | continue; | ||
773 | } | ||
774 | if (userinput.substr(0,1)=="s") { | ||
775 | if (userinput=="s") { | ||
776 | userinput+=lastsearch; | ||
777 | } else { | ||
778 | lastsearch=userinput.substr(1,userinput.length()-1); | ||
779 | } | ||
780 | if (blockend==blockstart) { | ||
781 | sectornum=scanforblock(rawdevice,lastsearch,0,0xffffffff,sectornum); | ||
782 | } else { | ||
783 | sectornum=scanforblock(rawdevice,lastsearch,blockstart,blockend,sectornum); | ||
784 | } | ||
785 | continue; | ||
786 | } | ||
787 | if (userinput=="version") { | ||
788 | cout << VERSION << endl; | ||
789 | nodump=1; // inhibit viewing the sector after this command. | ||
790 | noread=1; | ||
791 | continue; | ||
792 | } | ||
793 | if (userinput.substr(0,1)=="p") { | ||
794 | //paste | ||
795 | if (blockend==blockstart) { | ||
796 | nodump=1; | ||
797 | cout << "Mark a block first." << endl; | ||
798 | continue; | ||
799 | } | ||
800 | rawdevice->readsectors(blockstart,bootblock,1); | ||
801 | noread=1; | ||
802 | continue; | ||
803 | } | ||
804 | if (userinput.substr(0,1)=="e") { | ||
805 | string editstr=userinput.substr(1,userinput.length()-1); | ||
806 | editbytes(bootblock,editstr); | ||
807 | noread=1; | ||
808 | continue; | ||
809 | } | ||
810 | if (userinput.substr(0,1)=="m") { | ||
811 | string editstr=userinput.substr(1,userinput.length()-1); | ||
812 | movebytes(bootblock,editstr); | ||
813 | noread=1; | ||
814 | continue; | ||
815 | } | ||
816 | if (userinput=="d") { | ||
817 | continue; | ||
818 | } | ||
819 | |||
820 | if (userinput.substr(0,2)=="d-") { | ||
821 | // if we have 10 sectors (0..9), last one is d-1=sector 9 | ||
822 | // so sector num is total number of secs - negnum | ||
823 | sectornum=rawdevice->getlastsectornum()-Convert::hex2long(userinput.substr(2,userinput.length()-2))+1; | ||
824 | continue; | ||
825 | } | ||
826 | |||
827 | if (userinput.substr(0,1)=="d") { | ||
828 | sectornum=Convert::hex2long(userinput.substr(1,userinput.length()-1)); | ||
829 | continue; | ||
830 | } | ||
831 | if (userinput.substr(0,1)=="o") { | ||
832 | long offset=Convert::hex2long(userinput.substr(1,userinput.length()-1)); | ||
833 | offset-=(offset%512); | ||
834 | sectornum=offset/512; | ||
835 | } | ||
836 | if (userinput=="fix") { | ||
837 | fstfix(bootblock,512); | ||
838 | noread=1; | ||
839 | continue; | ||
840 | } | ||
841 | if (userinput.substr(0,1)=="n") { | ||
842 | int dangerousname=0; | ||
843 | if (userinput.substr(1,4)=="\\\\.\\") { | ||
844 | dangerousname=1; | ||
845 | } | ||
846 | if (userinput.substr(1,5)=="/dev/") { | ||
847 | dangerousname=1; | ||
848 | } | ||
849 | if (userinput.substr(1,4)=="//./") { | ||
850 | dangerousname=1; | ||
851 | } | ||
852 | if (dangerousname==1) { | ||
853 | if (expertmode==0) { | ||
854 | expertmodemessage("Writing to devices"); | ||
855 | } else { | ||
856 | filename=userinput.substr(1,userinput.length()-1); | ||
857 | cout << "OK, setting output file to device " << filename << endl; | ||
858 | cout << "Please take your time to make sure this is really the correct drive."<<endl; | ||
859 | string strlower=filename; | ||
860 | int (*pf)(int)=tolower; | ||
861 | std::transform (strlower.begin(),strlower.end(),strlower.begin(),pf); | ||
862 | if ( | ||
863 | (strlower=="\\\\.\\physicaldrive0") | ||
864 | || (strlower=="/dev/hda")) | ||
865 | { | ||
866 | cout << "CAREFUL!!! " << strlower << " is probably your main system disk!" << endl; | ||
867 | cout << "If you continue you might mess up your computer!!!" << endl; | ||
868 | cout << "I will not stop you from doing this, so " << endl; | ||
869 | cout << "MAKE SURE THIS IS REALLY THE DRIVE YOU WANT TO WRITE TO!" << endl; | ||
870 | cout << "UNLESS ABSOLUTELY SURE, STOP WHAT YOU ARE DOING RIGHT NOW!" << endl; | ||
871 | } | ||
872 | } | ||
873 | } else { | ||
874 | filename=userinput.substr(1,userinput.length()-1); | ||
875 | } | ||
876 | nodump=1; // inhibit viewing the sector after this command. | ||
877 | if (filename=="") { | ||
878 | string filename="outfile.dmp"; | ||
879 | } | ||
880 | cout << "Current output filename is " << filename << endl; | ||
881 | |||
882 | continue; | ||
883 | } | ||
884 | if (userinput=="w") { | ||
885 | cout << "Writing " << blockend-blockstart << " sectors to " << filename << endl; | ||
886 | writetofile(rawdevice,filename,blockstart,blockend); | ||
887 | nodump=1; // inhibit viewing the sector after this command. | ||
888 | cout << "Done." << endl; | ||
889 | continue; | ||
890 | } | ||
891 | if (userinput=="ws") { | ||
892 | if (expertmode==1) { | ||
893 | writesec=1; | ||
894 | } else { | ||
895 | noread=1; | ||
896 | expertmodemessage("Writing sectors"); | ||
897 | nodump=1; | ||
898 | } | ||
899 | } | ||
900 | if (userinput=="freesec") { | ||
901 | nodump=1; | ||
902 | cout << "Sector " << *Convert::int32tohex((long)rawdevice->getnextfreesector(0xFFFFFFFF)) << endl; | ||
903 | cout << rawdevice->getnextfreesector(0xFFFFFFFF) << endl; | ||
904 | } | ||
905 | if (userinput=="commit") { | ||
906 | if (expertmode==1) { | ||
907 | cout << "Commit FS to disk." << endl; | ||
908 | fsys->commit(); | ||
909 | } | ||
910 | } | ||
911 | } while (userinput!="q"); | ||
912 | |||
913 | } catch (string e) { | ||
914 | cout << "Exiting because of an unexpected error." << endl; | ||
915 | delete rawdevice; rawdevice=NULL; | ||
916 | delete fsys; fsys=NULL; | ||
917 | return 1; | ||
918 | } | ||
919 | delete rawdevice; rawdevice=NULL; | ||
920 | delete fsys; fsys=NULL; | ||
921 | return 0; | ||
922 | } | ||
923 | |||