এখানে "পুনরুদ্ধার" ইমেজগুলি রয়েছে, লেবারবার্গের আরও গবেষণার জন্য ধন্যবাদ:
প্রত্যাশিত হিসাবে, প্রতি 0x4020 বাইটে 5-বাইট ব্লক চিহ্নিতকারী রয়েছে । ফর্ম্যাটটি নিম্নলিখিত বলে মনে হচ্ছে:
struct marker {
uint8_t tag; /* 1 if this is the last marker in the file, 0 otherwise */
uint16_t len; /* size of the following block (little-endian) */
uint16_t notlen; /* 0xffff - len */
};
একবার মার্কারটি পড়ার পরে, পরবর্তী marker.len
বাইটগুলি একটি ব্লক তৈরি করে যা ফাইলটির অংশ। marker.notlen
একটি নিয়ন্ত্রণ পরিবর্তনশীল যে যেমন marker.len + marker.notlen == 0xffff
। সর্বশেষ ব্লকটি এমন marker.tag == 1
।
কাঠামো সম্ভবত নিম্নলিখিত হিসাবে রয়েছে। এখনও অজানা মান আছে।
struct file {
uint8_t name_len; /* number of bytes in the filename */
/* (not sure whether it's uint8_t or uint16_t) */
char name[name_len]; /* filename */
uint32_t file_len; /* size of the file (little endian) */
/* eg. "40 25 01 00" is 0x12540 bytes */
uint16_t unknown; /* maybe a checksum? */
marker marker1; /* first block marker (tag == 0) */
uint8_t data1[marker1.len]; /* data of the first block */
marker marker2; /* second block marker (tag == 0) */
uint8_t data2[marker2.len]; /* data of the second block */
/* ... */
marker lastmarker; /* last block marker (tag == 1) */
uint8_t lastdata[lastmarker.len]; /* data of the last block */
uint32_t unknown2; /* end data? another checksum? */
};
শেষে কী আছে তা আমি বুঝতে পারি নি, তবে পিএনজিরা যেহেতু প্যাডিং গ্রহণ করে, এটি খুব বেশি নাটকীয় নয়। যাইহোক, এনকোডযুক্ত ফাইলের আকারটি পরিষ্কারভাবে নির্দেশ করে যে শেষ 4 বাইট উপেক্ষা করা উচিত ...
যেহেতু ফাইল শুরুর ঠিক আগে আমার কাছে সমস্ত ব্লক চিহ্নিতকারীগুলিতে অ্যাক্সেস ছিল না, তাই আমি এই ডিকোডারটি লিখেছিলাম যা শেষে শুরু হয় এবং ব্লক চিহ্নিতকারীগুলিকে সন্ধান করার চেষ্টা করে। এটি মোটেও শক্তিশালী নয়, এটি আপনার পরীক্ষার চিত্রগুলির জন্য কাজ করেছে:
#include <stdio.h>
#include <string.h>
#define MAX_SIZE (1024 * 1024)
unsigned char buf[MAX_SIZE];
/* Usage: program infile.png outfile.png */
int main(int argc, char *argv[])
{
size_t i, len, lastcheck;
FILE *f = fopen(argv[1], "rb");
len = fread(buf, 1, MAX_SIZE, f);
fclose(f);
/* Start from the end and check validity */
lastcheck = len;
for (i = len - 5; i-- > 0; )
{
size_t off = buf[i + 2] * 256 + buf[i + 1];
size_t notoff = buf[i + 4] * 256 + buf[i + 3];
if (buf[i] >= 2 || off + notoff != 0xffff)
continue;
else if (buf[i] == 1 && lastcheck != len)
continue;
else if (buf[i] == 0 && i + off + 5 != lastcheck)
continue;
lastcheck = i;
memmove(buf + i, buf + i + 5, len - i - 5);
len -= 5;
i -= 5;
}
f = fopen(argv[2], "wb+");
fwrite(buf, 1, len, f);
fclose(f);
return 0;
}
পুরানো গবেষণা
0x4022
দ্বিতীয় চিত্র থেকে বাইট অপসারণ করার পরে, বাইট অপসারণ করার মাধ্যমে আপনি এটি পান 0x8092
:
এটি চিত্রগুলি সত্যই "মেরামত" করে না; আমি এটি পরীক্ষা এবং ত্রুটি করে করেছি। তবে এটি যা বলে তা প্রতি 16384 বাইটে অপ্রত্যাশিত ডেটা রয়েছে। আমার অনুমান যে চিত্রগুলি কিছু প্রকারের ফাইল সিস্টেম কাঠামোভুক্ত এবং অপ্রত্যাশিত ডেটা কেবলমাত্র চিহ্নিতকারীগুলিকে ব্লক করে যা ডেটা পড়ার সময় আপনাকে অপসারণ করা উচিত।
আমি জানি না ঠিক যেখানে ব্লক চিহ্নিতকারী এবং তার আকার, কিন্তু ব্লকের আকারটি অবশ্যই 2 ^ 14 বাইট।
আপনি যদি চিত্রের ঠিক আগে এবং ঠিক পরে প্রদর্শিত হয় তার একটি হেক্সস ডাম্প (কয়েক ডজন বাইট) সরবরাহ করতে পারেন তবে এটি সহায়তা করবে। এটি ব্লকের শুরুতে বা শেষে কী ধরণের তথ্য সংরক্ষণ করা হয় সে সম্পর্কে ইঙ্গিত দেয়।
অবশ্যই আপনার নিষ্কাশন কোডে একটি ত্রুটি রয়েছে এমন সম্ভাবনাও রয়েছে। আপনি যদি নিজের ফাইল অপারেশনের জন্য 16384 বাইটের একটি বাফার ব্যবহার করছেন তবে আমি প্রথমে সেখানে চেক করব।