1 /* zenutils - Utilities for working with creative firmwares.
2 * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 const char* zen::find_firmware_key(const byte
* buffer
, size_t len
)
27 char szkey1
[] = "34d1";
28 size_t cchkey1
= strlen(szkey1
);
29 char szkey2
[] = "TbnCboEbn";
30 size_t cchkey2
= strlen(szkey2
);
31 for (int i
= 0; i
< static_cast<int>(len
); i
++)
35 if (!strncmp((char*)&buffer
[i
], szkey1
, cchkey1
))
37 return (const char*)&buffer
[i
];
42 if (!strncmp((char*)&buffer
[i
], szkey2
, cchkey2
))
44 return (const char*)&buffer
[i
];
51 dword
zen::find_firmware_offset(byte
* buffer
, size_t len
)
53 for (dword i
= 0; i
< static_cast<dword
>(len
); i
+= 4)
55 dword size
= *(dword
*)&buffer
[i
];
58 && buffer
[i
+ 4 + 1] != 0
59 && buffer
[i
+ 4 + 2] != 0
60 && buffer
[i
+ 4 + 3] != 0)
64 if(i
> 0xFF) /* Arbitrary guess */
70 bool zen::find_firmware_archive(const std::string
& filename
, dword
& va
, dword
& pa
)
73 if (!pef
.read(filename
))
77 shared::section_info data_section
;
78 if (!pef
.find_section(".data", data_section
))
83 if (!shared::read_file(filename
, buffer
, data_section
.raw_address
,
84 data_section
.raw_size
))
88 dword offset
= find_firmware_offset(&buffer
[0], buffer
.size());
93 va
= data_section
.virtual_address
+ offset
;
94 pa
= data_section
.raw_address
+ offset
;
100 bool zen::crypt_firmware(const char* key
, byte
* buffer
, size_t len
)
105 unsigned int tmp
= 0;
106 int key_length
= strlen(key
);
108 for(i
=0; i
< strlen(key
); i
++)
109 key_cpy
[i
] = key
[i
] - 1;
111 for(i
=0; i
< len
; i
++)
113 buffer
[i
] ^= key_cpy
[tmp
] | 0x80;
114 tmp
= (tmp
+ 1) % key_length
;
119 /* Determine if the key length is dword aligned. */
120 int keylen
= strlen(key
);
121 int keylen_rem
= keylen
% sizeof(dword
);
123 /* Determine how many times the key must be repeated to be dword aligned. */
124 int keycycle
= keylen_rem
? (sizeof(dword
) / keylen_rem
) : 1;
125 int keyscount
= (keylen
* keycycle
) / sizeof(dword
);
127 /* Allocate a buffer to hold the key as an array of dwords. */
128 dword
* keys
= new dword
[keyscount
];
130 /* Copy the key into the key array, whilst mutating it. */
131 for (int i
= 0; i
< keyscount
; i
++)
134 int keyoffset
= (i
* sizeof(dword
)) % keylen
;
135 if ((keyoffset
+sizeof(dword
)) < keylen
)
137 val
= *(dword
*)&key
[keyoffset
];
142 | (key
[(keyoffset
+ 1) % keylen
] << 8)
143 | (key
[(keyoffset
+ 2) % keylen
] << 16)
144 | (key
[(keyoffset
+ 3) % keylen
] << 24);
146 keys
[i
] = (val
- 0x01010101) | 0x80808080;
149 /* Determine the number of dwords in the buffer. */
150 int len_div
= len
/ sizeof(dword
);
152 /* Decrypt all dwords of the buffer. */
153 for (int i
= 0; i
< len_div
; i
++)
155 ((dword
*)buffer
)[i
] ^= keys
[i
% keyscount
];
158 /* Determine the remaining number of bytes in the buffer. */
159 int len_rem
= len
% sizeof(dword
);
161 /* Decrypt the remaining number of bytes in the buffer. */
162 for (int i
= len_div
* sizeof(dword
); i
< len
; i
++)
164 buffer
[i
] ^= ((key
[i
% keylen
] - 0x01) | 0x80);