diff options
Diffstat (limited to 'utils/zenutils/source/shared/updater.cpp')
-rw-r--r--[-rwxr-xr-x] | utils/zenutils/source/shared/updater.cpp | 302 |
1 files changed, 151 insertions, 151 deletions
diff --git a/utils/zenutils/source/shared/updater.cpp b/utils/zenutils/source/shared/updater.cpp index 77d3f2876c..25d8452992 100755..100644 --- a/utils/zenutils/source/shared/updater.cpp +++ b/utils/zenutils/source/shared/updater.cpp | |||
@@ -1,151 +1,151 @@ | |||
1 | /* zenutils - Utilities for working with creative firmwares. | 1 | /* zenutils - Utilities for working with creative firmwares. |
2 | * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com> | 2 | * Copyright 2007 (c) Rasmus Ry <rasmus.ry{at}gmail.com> |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 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 | 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 | 6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. | 7 | * (at your option) any later version. |
8 | * | 8 | * |
9 | * This program is distributed in the hope that it will be useful, | 9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | * | 13 | * |
14 | * You should have received a copy of the GNU General Public License | 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 | 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 | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "updater.h" | 19 | #include "updater.h" |
20 | #include <file.h> | 20 | #include <file.h> |
21 | #include <pe.h> | 21 | #include <pe.h> |
22 | #include <utils.h> | 22 | #include <utils.h> |
23 | 23 | ||
24 | 24 | ||
25 | const char* zen::find_firmware_key(const byte* buffer, size_t len) | 25 | const char* zen::find_firmware_key(const byte* buffer, size_t len) |
26 | { | 26 | { |
27 | char szkey1[] = "34d1"; | 27 | char szkey1[] = "34d1"; |
28 | size_t cchkey1 = strlen(szkey1); | 28 | size_t cchkey1 = strlen(szkey1); |
29 | char szkey2[] = "TbnCboEbn"; | 29 | char szkey2[] = "TbnCboEbn"; |
30 | size_t cchkey2 = strlen(szkey2); | 30 | size_t cchkey2 = strlen(szkey2); |
31 | for (int i = 0; i < static_cast<int>(len); i++) | 31 | for (int i = 0; i < static_cast<int>(len); i++) |
32 | { | 32 | { |
33 | if (len >= cchkey1) | 33 | if (len >= cchkey1) |
34 | { | 34 | { |
35 | if (!strncmp((char*)&buffer[i], szkey1, cchkey1)) | 35 | if (!strncmp((char*)&buffer[i], szkey1, cchkey1)) |
36 | { | 36 | { |
37 | return (const char*)&buffer[i]; | 37 | return (const char*)&buffer[i]; |
38 | } | 38 | } |
39 | } | 39 | } |
40 | if (len >= cchkey2) | 40 | if (len >= cchkey2) |
41 | { | 41 | { |
42 | if (!strncmp((char*)&buffer[i], szkey2, cchkey2)) | 42 | if (!strncmp((char*)&buffer[i], szkey2, cchkey2)) |
43 | { | 43 | { |
44 | return (const char*)&buffer[i]; | 44 | return (const char*)&buffer[i]; |
45 | } | 45 | } |
46 | } | 46 | } |
47 | } | 47 | } |
48 | return NULL; | 48 | return NULL; |
49 | } | 49 | } |
50 | 50 | ||
51 | dword zen::find_firmware_offset(byte* buffer, size_t len) | 51 | dword zen::find_firmware_offset(byte* buffer, size_t len) |
52 | { | 52 | { |
53 | for (dword i = 0; i < static_cast<dword>(len); i += 0x10) | 53 | for (dword i = 0; i < static_cast<dword>(len); i += 0x10) |
54 | { | 54 | { |
55 | dword size = *(dword*)&buffer[i]; | 55 | dword size = *(dword*)&buffer[i]; |
56 | if (size < (i + len) && size > (len >> 1)) | 56 | if (size < (i + len) && size > (len >> 1)) |
57 | { | 57 | { |
58 | if (buffer[i + sizeof(dword)] != 0 | 58 | if (buffer[i + sizeof(dword)] != 0 |
59 | && buffer[i + sizeof(dword) + 1] != 0 | 59 | && buffer[i + sizeof(dword) + 1] != 0 |
60 | && buffer[i + sizeof(dword) + 2] != 0 | 60 | && buffer[i + sizeof(dword) + 2] != 0 |
61 | && buffer[i + sizeof(dword) + 3] != 0) | 61 | && buffer[i + sizeof(dword) + 3] != 0) |
62 | { | 62 | { |
63 | return i; | 63 | return i; |
64 | } | 64 | } |
65 | } | 65 | } |
66 | } | 66 | } |
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | bool zen::find_firmware_archive(const std::string& filename, dword& va, dword& pa) | 70 | bool zen::find_firmware_archive(const std::string& filename, dword& va, dword& pa) |
71 | { | 71 | { |
72 | shared::pe_file pef; | 72 | shared::pe_file pef; |
73 | if (!pef.read(filename)) | 73 | if (!pef.read(filename)) |
74 | { | 74 | { |
75 | return false; | 75 | return false; |
76 | } | 76 | } |
77 | shared::section_info data_section; | 77 | shared::section_info data_section; |
78 | if (!pef.find_section(".data", data_section)) | 78 | if (!pef.find_section(".data", data_section)) |
79 | { | 79 | { |
80 | return false; | 80 | return false; |
81 | } | 81 | } |
82 | shared::bytes buffer; | 82 | shared::bytes buffer; |
83 | if (!shared::read_file(filename, buffer, data_section.raw_address, | 83 | if (!shared::read_file(filename, buffer, data_section.raw_address, |
84 | data_section.raw_size)) | 84 | data_section.raw_size)) |
85 | { | 85 | { |
86 | return false; | 86 | return false; |
87 | } | 87 | } |
88 | dword offset = find_firmware_offset(&buffer[0], buffer.size()); | 88 | dword offset = find_firmware_offset(&buffer[0], buffer.size()); |
89 | if (!offset) | 89 | if (!offset) |
90 | { | 90 | { |
91 | return false; | 91 | return false; |
92 | } | 92 | } |
93 | va = data_section.virtual_address + offset; | 93 | va = data_section.virtual_address + offset; |
94 | pa = data_section.raw_address + offset; | 94 | pa = data_section.raw_address + offset; |
95 | 95 | ||
96 | return true; | 96 | return true; |
97 | } | 97 | } |
98 | 98 | ||
99 | 99 | ||
100 | bool zen::crypt_firmware(const char* key, byte* buffer, size_t len) | 100 | bool zen::crypt_firmware(const char* key, byte* buffer, size_t len) |
101 | { | 101 | { |
102 | // Determine if the key length is dword aligned. | 102 | // Determine if the key length is dword aligned. |
103 | int keylen = strlen(key); | 103 | int keylen = strlen(key); |
104 | int keylen_rem = keylen % sizeof(dword); | 104 | int keylen_rem = keylen % sizeof(dword); |
105 | 105 | ||
106 | // Determine how many times the key must be repeated to be dword aligned. | 106 | // Determine how many times the key must be repeated to be dword aligned. |
107 | int keycycle = keylen_rem ? (sizeof(dword) / keylen_rem) : 1; | 107 | int keycycle = keylen_rem ? (sizeof(dword) / keylen_rem) : 1; |
108 | int keyscount = (keylen * keycycle) / sizeof(dword); | 108 | int keyscount = (keylen * keycycle) / sizeof(dword); |
109 | 109 | ||
110 | // Allocate a buffer to hold the key as an array of dwords. | 110 | // Allocate a buffer to hold the key as an array of dwords. |
111 | dword* keys = new dword[keyscount]; | 111 | dword* keys = new dword[keyscount]; |
112 | 112 | ||
113 | // Copy the key into the key array, whilst mutating it. | 113 | // Copy the key into the key array, whilst mutating it. |
114 | for (int i = 0; i < keyscount; i++) | 114 | for (int i = 0; i < keyscount; i++) |
115 | { | 115 | { |
116 | dword val; | 116 | dword val; |
117 | int keyoffset = (i * sizeof(dword)) % keylen; | 117 | int keyoffset = (i * sizeof(dword)) % keylen; |
118 | if ((keyoffset+sizeof(dword)) < keylen) | 118 | if ((keyoffset+sizeof(dword)) < keylen) |
119 | { | 119 | { |
120 | val = *(dword*)&key[keyoffset]; | 120 | val = *(dword*)&key[keyoffset]; |
121 | } | 121 | } |
122 | else | 122 | else |
123 | { | 123 | { |
124 | val = key[keyoffset] | 124 | val = key[keyoffset] |
125 | | (key[(keyoffset + 1) % keylen] << 8) | 125 | | (key[(keyoffset + 1) % keylen] << 8) |
126 | | (key[(keyoffset + 2) % keylen] << 16) | 126 | | (key[(keyoffset + 2) % keylen] << 16) |
127 | | (key[(keyoffset + 3) % keylen] << 24); | 127 | | (key[(keyoffset + 3) % keylen] << 24); |
128 | } | 128 | } |
129 | keys[i] = (val - 0x01010101) | 0x80808080; | 129 | keys[i] = (val - 0x01010101) | 0x80808080; |
130 | } | 130 | } |
131 | 131 | ||
132 | // Determine the number of dwords in the buffer. | 132 | // Determine the number of dwords in the buffer. |
133 | int len_div = len / sizeof(dword); | 133 | int len_div = len / sizeof(dword); |
134 | 134 | ||
135 | // Decrypt all dwords of the buffer. | 135 | // Decrypt all dwords of the buffer. |
136 | for (int i = 0; i < len_div; i++) | 136 | for (int i = 0; i < len_div; i++) |
137 | { | 137 | { |
138 | ((dword*)buffer)[i] ^= keys[i % keyscount]; | 138 | ((dword*)buffer)[i] ^= keys[i % keyscount]; |
139 | } | 139 | } |
140 | 140 | ||
141 | // Determine the remaining number of bytes in the buffer. | 141 | // Determine the remaining number of bytes in the buffer. |
142 | int len_rem = len % sizeof(dword); | 142 | int len_rem = len % sizeof(dword); |
143 | 143 | ||
144 | // Decrypt the remaining number of bytes in the buffer. | 144 | // Decrypt the remaining number of bytes in the buffer. |
145 | for (int i = len_div * sizeof(dword); i < len; i++) | 145 | for (int i = len_div * sizeof(dword); i < len; i++) |
146 | { | 146 | { |
147 | buffer[i] ^= ((key[i % keylen] - 0x01) | 0x80); | 147 | buffer[i] ^= ((key[i % keylen] - 0x01) | 0x80); |
148 | } | 148 | } |
149 | 149 | ||
150 | return true; | 150 | return true; |
151 | } | 151 | } |