1 #include "RKImage.h"
2 #include "MD5Checksum.h"
3
4 extern int IsRK3308_Platform();
5 extern int Compatible_rk3308bs_loader();
6
GetVersion()7 DWORD CRKImage::GetVersion()
8 {
9 return m_version;
10 }
GetMergeVersion()11 DWORD CRKImage::GetMergeVersion()
12 {
13 return m_mergeVersion;
14 }
GetReleaseTime()15 STRUCT_RKTIME CRKImage::GetReleaseTime()
16 {
17 return m_releaseTime;
18 }
GetSupportDevice()19 ENUM_RKDEVICE_TYPE CRKImage::GetSupportDevice()
20 {
21 return m_supportDevice;
22 }
GetOsType()23 ENUM_OS_TYPE CRKImage::GetOsType()
24 {
25 UINT *pOsType;
26 pOsType = (UINT *)&m_reserved[4];
27 return (ENUM_OS_TYPE) * pOsType;
28 }
GetBackupSize()29 USHORT CRKImage::GetBackupSize()
30 {
31 USHORT *pBackupSize;
32 pBackupSize = (USHORT *)&m_reserved[12];
33 return *pBackupSize;
34 }
GetBootOffset()35 DWORD CRKImage::GetBootOffset()
36 {
37 return m_bootOffset;
38 }
GetBootSize()39 DWORD CRKImage::GetBootSize()
40 {
41 return m_bootSize;
42 }
GetFWOffset()43 DWORD CRKImage::GetFWOffset()
44 {
45 return m_fwOffset;
46 }
GetFWSize()47 long long CRKImage::GetFWSize()
48 {
49 return m_fwSize;
50 }
51
GetFWFileHandle()52 FILE *CRKImage::GetFWFileHandle()
53 {
54 return m_pFile;
55 }
56
GetFwPath()57 char *CRKImage::GetFwPath()
58 {
59 return m_imgPath;
60 }
61
Md5Check(long long nCheckSize)62 bool CRKImage::Md5Check(long long nCheckSize)
63 {
64 printf("In Md5Check\n");
65 tstring strNewMd5 = _T("");
66 strNewMd5 = CMD5Checksum::GetMD5(m_pFile, nCheckSize);
67 if (strNewMd5.size() == 32)
68 {
69 BYTE newMd5[32];
70 memcpy(newMd5, strNewMd5.c_str(), 32);
71 int i, j;
72 printf("New Md5:\n");
73 for (i = 0; i < 2; i++)
74 {
75 for (j = 0; j < 16; j++)
76 {
77 printf("%02X ", newMd5[i * 16 + j]);
78 }
79 printf("\r\n");
80 }
81 printf("Old Md5:\n");
82 for (i = 0; i < 2; i++)
83 {
84 for (j = 0; j < 16; j++)
85 {
86 printf("%02X ", m_md5[i * 16 + j]);
87 }
88 printf("\r\n");
89 }
90 if (memcmp(newMd5, m_md5, 32) != 0)
91 {
92 return false;
93 }
94 else
95 {
96 return true;
97 }
98 }
99 else
100 {
101 return false;
102 }
103 }
104
SaveBootFile(tstring filename)105 bool CRKImage::SaveBootFile(tstring filename)
106 {
107 FILE *file = NULL;
108 file = fopen(filename.c_str(), _T("wb+"));
109 if (!file)
110 {
111 return false;
112 }
113 BYTE buffer[1024];
114 DWORD dwBufferSize = 1024;
115 DWORD dwBootSize = m_bootSize;
116 DWORD dwReadSize;
117 fseek(m_pFile, m_bootOffset, SEEK_SET);
118 do
119 {
120 dwReadSize = (dwBootSize >= 1024) ? dwBufferSize : dwBootSize;
121 size_t ret = fread(buffer, 1, dwReadSize, m_pFile);
122 if (ret != dwReadSize)
123 {
124 printf("fread error: read:%d, req read:%d", ret, dwReadSize);
125 }
126 fwrite(buffer, 1, dwReadSize, file);
127 dwBootSize -= dwReadSize;
128 } while (dwBootSize > 0);
129 fclose(file);
130 return true;
131 }
132
SaveFWFile(tstring filename)133 bool CRKImage::SaveFWFile(tstring filename)
134 {
135 FILE *file = NULL;
136 file = fopen(filename.c_str(), _T("wb+"));
137 if (!file)
138 {
139 return false;
140 }
141 BYTE buffer[1024];
142 DWORD dwBufferSize = 1024;
143 long long dwFWSize = m_fwSize;
144 DWORD dwReadSize;
145 fseeko(m_pFile, m_fwOffset, SEEK_SET);
146 do
147 {
148 dwReadSize = (dwFWSize >= 1024) ? dwBufferSize : dwFWSize;
149 size_t ret = fread(buffer, 1, dwReadSize, m_pFile);
150 if (ret != dwReadSize)
151 {
152 printf("fread error: read:%d, req read:%d", ret, dwReadSize);
153 }
154
155 fwrite(buffer, 1, dwReadSize, file);
156 dwFWSize -= dwReadSize;
157 } while (dwFWSize > 0);
158 fclose(file);
159 return true;
160 }
161
GetData(long long dwOffset,DWORD dwSize,PBYTE lpBuffer)162 bool CRKImage::GetData(long long dwOffset, DWORD dwSize, PBYTE lpBuffer)
163 {
164 if (dwOffset < 0 || dwSize == 0)
165 {
166 return false;
167 }
168 if (dwOffset + dwSize > m_fileSize)
169 {
170 return false;
171 }
172
173 fseeko64(m_pFile, dwOffset, SEEK_SET);
174 UINT uiActualRead;
175 uiActualRead = fread(lpBuffer, 1, dwSize, m_pFile);
176 if (dwSize != uiActualRead)
177 {
178 return false;
179 }
180 return true;
181 }
GetReservedData(PBYTE & lpData,USHORT & usSize)182 void CRKImage::GetReservedData(PBYTE &lpData, USHORT &usSize)
183 {
184 lpData = m_reserved;
185 usSize = IMAGE_RESERVED_SIZE;
186 }
GetMd5Data(PBYTE & lpMd5,PBYTE & lpSignMd5)187 int CRKImage::GetMd5Data(PBYTE &lpMd5, PBYTE &lpSignMd5)
188 {
189 lpMd5 = m_md5;
190 lpSignMd5 = m_signMd5;
191 return m_signMd5Size;
192 }
193
CRKImage(tstring filename,bool & bCheck)194 CRKImage::CRKImage(tstring filename, bool &bCheck)
195 {
196 Version.setContainer(this);
197 Version.getter(&CRKImage::GetVersion);
198 MergeVersion.setContainer(this);
199 MergeVersion.getter(&CRKImage::GetMergeVersion);
200 ReleaseTime.setContainer(this);
201 ReleaseTime.getter(&CRKImage::GetReleaseTime);
202 SupportDevice.setContainer(this);
203 SupportDevice.getter(&CRKImage::GetSupportDevice);
204 OsType.setContainer(this);
205 OsType.getter(&CRKImage::GetOsType);
206 BackupSize.setContainer(this);
207 BackupSize.getter(&CRKImage::GetBackupSize);
208 BootOffset.setContainer(this);
209 BootOffset.getter(&CRKImage::GetBootOffset);
210 BootSize.setContainer(this);
211 BootSize.getter(&CRKImage::GetBootSize);
212 FWOffset.setContainer(this);
213 FWOffset.getter(&CRKImage::GetFWOffset);
214 FWSize.setContainer(this);
215 FWSize.getter(&CRKImage::GetFWSize);
216 FwPath.setContainer(this);
217 FwPath.getter(&CRKImage::GetFwPath);
218
219 bool bDoMdb5Check = bCheck;
220 struct stat64 statBuf;
221 m_bootObject = NULL;
222 m_pFile = NULL;
223
224 m_signMd5Size = 0;
225 memset(m_md5, 0, 32);
226 memset(m_signMd5, 0, 256);
227
228 tchar szName[256];
229 _tcscpy(szName, filename.c_str());
230 if (stat64(szName, &statBuf) < 0)
231 {
232 bCheck = false;
233 printf("CRKImage : stat <%s> happen error.error_reason = %s\n", szName, strerror(errno));
234 return;
235 }
236 if (S_ISDIR(statBuf.st_mode))
237 {
238 bCheck = false;
239 printf("CRKImage : Error! stat mode is DIR\n");
240 return;
241 }
242 m_fileSize = statBuf.st_size;
243 memcpy(m_imgPath, szName, sizeof(szName));
244
245 bool bOnlyBootFile = false;
246 transform(filename.begin(), filename.end(), filename.begin(), (int(*)(int))tolower);
247 if (filename.find(_T(".bin")) != tstring::npos)
248 {
249 bOnlyBootFile = true;
250 }
251
252 m_pFile = fopen(szName, "rb");
253 if (!m_pFile)
254 {
255 bCheck = false;
256 printf("CRKImage : fopen <%s> fail,will try use fopen64 \n", szName);
257
258 m_pFile = fopen64(szName, "rb");
259 if (!m_pFile)
260 {
261 bCheck = false;
262 printf("CRKImage : fopen64 <%s> fail\n", szName);
263 return;
264 }
265 }
266
267 //code will be error if firmware is signed.md5 is not last 32 byte.
268 // fseeko(m_pFile,-32,SEEK_END);
269 // fread(m_md5,1,32,m_pFile);
270 // fseeko(m_pFile,0,SEEK_SET);
271 // if (!Md5Check())
272 // {
273 // bCheck = false;
274 // return;
275 // }
276
277 int nMd5DataSize;
278 long long ulFwSize;
279 STRUCT_RKIMAGE_HEAD imageHead;
280 if (!bOnlyBootFile)
281 {
282 fseeko64(m_pFile, 0, SEEK_SET);
283 size_t ret = fread((PBYTE)(&imageHead), 1, sizeof(STRUCT_RKIMAGE_HEAD), m_pFile);
284 if (ret != sizeof(STRUCT_RKIMAGE_HEAD))
285 {
286 return;
287 }
288
289 if (imageHead.uiTag != 0x57464B52)
290 {
291 bCheck = false;
292 printf("CRKImage :Error! imageHead.uiTag != 0x57464B52\n");
293 return;
294 }
295 if ((imageHead.reserved[14] == 'H') && (imageHead.reserved[15] == 'I'))
296 {
297 ulFwSize = *((DWORD *)(&imageHead.reserved[16]));
298 ulFwSize <<= 32;
299 ulFwSize += imageHead.dwFWOffset;
300 ulFwSize += imageHead.dwFWSize;
301 }
302 else
303 {
304 ulFwSize = imageHead.dwFWOffset + imageHead.dwFWSize;
305 }
306 nMd5DataSize = GetImageSize() - ulFwSize;
307 if (nMd5DataSize >= 160)
308 {
309 //sign image
310 m_bSignFlag = true;
311 m_signMd5Size = nMd5DataSize - 32;
312 fseeko64(m_pFile, ulFwSize, SEEK_SET);
313 size_t ret = fread(m_md5, 1, 32, m_pFile);
314 if (ret != 32)
315 {
316 printf("%s:read error\n", __func__);
317 }
318 ret = fread(m_signMd5, 1, nMd5DataSize - 32, m_pFile);
319 if (ret != nMd5DataSize - 32)
320 {
321 printf("%s :ret = %d\n", __func__, ret);
322 }
323 }
324 else
325 {
326 fseeko64(m_pFile, -32, SEEK_END);
327 size_t read = fread(m_md5, 1, 32, m_pFile);
328 if (read != 32)
329 {
330 printf("%s: read error\n", __func__);
331 }
332 }
333 if (bDoMdb5Check)
334 {
335 if (!Md5Check(ulFwSize))
336 {
337 printf("Md5Check update.img ulFwSize:%ld", ulFwSize);
338 //bCheck = false;
339 //return;
340 bCheck = true;
341 }
342 }
343
344 m_version = imageHead.dwVersion;
345 m_mergeVersion = imageHead.dwMergeVersion;
346 m_releaseTime.usYear = imageHead.stReleaseTime.usYear;
347 m_releaseTime.ucMonth = imageHead.stReleaseTime.ucMonth;
348 m_releaseTime.ucDay = imageHead.stReleaseTime.ucDay;
349 m_releaseTime.ucHour = imageHead.stReleaseTime.ucHour;
350 m_releaseTime.ucMinute = imageHead.stReleaseTime.ucMinute;
351 m_releaseTime.ucSecond = imageHead.stReleaseTime.ucSecond;
352 m_supportDevice = imageHead.emSupportChip;
353 m_bootOffset = imageHead.dwBootOffset;
354 m_bootSize = imageHead.dwBootSize;
355 m_fwOffset = imageHead.dwFWOffset;
356 m_fwSize = ulFwSize - m_fwOffset;
357
358 memcpy(m_reserved, imageHead.reserved, IMAGE_RESERVED_SIZE);
359 }
360 else
361 {
362 m_bootOffset = 0;
363 m_bootSize = m_fileSize;
364 }
365
366 PBYTE lpBoot;
367 lpBoot = new BYTE[m_bootSize];
368 fseeko64(m_pFile, m_bootOffset, SEEK_SET);
369 size_t ret = fread(lpBoot, 1, m_bootSize, m_pFile);
370 if (ret != m_bootSize)
371 {
372 printf("%s : read error\n", __func__);
373 }
374 bool bRet;
375 m_bootObject = new CRKBoot(lpBoot, m_bootSize, bRet);
376 if (!bRet)
377 {
378 bCheck = false;
379 printf("CRKImage :Error! new CRKBoot fail!\n");
380 return;
381 }
382 if (bOnlyBootFile)
383 {
384 m_supportDevice = m_bootObject->SupportDevice;
385 UINT *pOsType;
386 pOsType = (UINT *)&m_reserved[4];
387 *pOsType = (UINT)RK_OS;
388 fclose(m_pFile);
389 m_pFile = NULL;
390 }
391 bCheck = true;
392 }
~CRKImage()393 CRKImage::~CRKImage()
394 {
395 if (m_pFile)
396 {
397 fclose(m_pFile);
398 m_pFile = NULL;
399 }
400 if (m_bootObject)
401 {
402 delete m_bootObject;
403 m_bootObject = NULL;
404 }
405 }
406
GetImageSize()407 long long CRKImage::GetImageSize()
408 {
409 return m_fileSize;
410 }
411