├── 9008 ├── MPRG8960NECTerrain.bin ├── README.md ├── README_ru.md ├── aboot.img ├── gpt.txt ├── gpt_parser.py ├── hex2bin ├── photo1.jpg ├── photo2.jpg ├── qs9008.tar.gz ├── recovery.img ├── rpm.img ├── sbl1.img ├── sbl2.img ├── sbl3.img ├── stage1.py ├── stage2.py └── tz.img ├── README.md ├── aboutnecterrainphone.md ├── boot-howto.md ├── boot ├── README.md ├── adbb.bat ├── adbb.sh ├── build.prop ├── kas.boot.bin ├── kas.boot.bin-0.8 ├── kas.boot.bin-0.9 └── kas.boot.bin-0.9-ext2 ├── exploit-pre.md ├── exploit-th.md ├── fastroot.md ├── fastroot_ru.md ├── general-th.md ├── recovery-howto.md ├── recovery ├── README.md ├── adbr.bat ├── adbr.sh ├── adbtestgpt.bat ├── adbtestgpt.sh ├── flash_recovery.sh ├── kas.recovery.bin ├── kas.recovery.bin-0.8 ├── kas.recovery.bin-0.8.1 ├── kas.recovery.bin-0.9 ├── kas.recovery.bin-0.9.2 ├── run_root_shell └── sgdisk ├── repart-howto.md ├── system-howto.md ├── system ├── README.md ├── Superuser.apk ├── adbfb.tar.gz ├── adbs.bat ├── adbs.sh ├── apkdissys ├── apken3 ├── apkensys ├── flash_superuser.sh └── su └── ts.md /9008/MPRG8960NECTerrain.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/MPRG8960NECTerrain.bin -------------------------------------------------------------------------------- /9008/README.md: -------------------------------------------------------------------------------- 1 | ### NEC Terrain 9008 guide 2 | 3 | [Здесь](README_ru.md) написано по-русски. 4 | 5 | **GUYS, IT IS IF you have bricked your phone in a soft way, i.e. without dropping from the window of some 10th floor** 6 | 7 | **This is COOL and courageous, but not difficult** 8 | 9 | **This is under LINUX, windows sufferers should find their way** 10 | 11 | **This is NEC Terrain specific** 12 | 13 | #### 9008 explained 14 | 15 | This is the mode in which the external usb port of your phone is enumerated as `05c6:9008` and is recognized as a serial port, i.e. ttySn (COMn in windows). This happens if you so much messed up your phone that it cannot reach boot or recovery partitions. For example, erased aboot ... In this case your phone upon pressing power button shows you _NOTHING_. However, it is very likely still alive. 16 | 17 | Now upon connection to your computer via usb you see _NOTHING_. You must activate the 9008 mode which is indeed your **LAST** chance. But this chance is quite steady and patient. In this mode you can reload the content of your internal flash by means of a simple script under linux. (In windows you must use special drivers `qs9008.tar.gz` and the QPST suite. Ask me in private or google if you need QPST.) Note that your linux kernel must support serial tty (ttyS) through usb. 18 | 19 | Another situation when this mode can be useful is when you messed up your system not heavily but enough to say bye to your phone. For example, it boots but then enters some bootloop and unfortunately you did not install some normal (e.g. mine in case of NEC Terrain) recovery. Then you might need to rewrite the whole system folder or just update recovery without being able to boot. Your savior is the 9008 mode. 20 | 21 | All referred files are in this folder. 22 | 23 | #### 9008 activation 24 | 25 | * Remove the battery and the usb cable from the phone 26 | * Glue off the sticker with your IMEI 27 | * Observe a group of 4 contacts (`photo1.jpg`, encircled by the red contour). The 2 in the middle are named GND and ENG_BOOT from ground and engineering_boot respectively (`photo2.jpg`, shown by red arrows) 28 | * Connect you phone in this state (w/o a battery) to your computer 29 | * Check with `lsusb` that it is _not_ seen, it should be like that 30 | * Shorten for some short time GND and ENG_BOOT contacts, a tweezer from the Swiss army knife is enough. 31 | * Check with `lsusb` that it is **seen** as `05c6:9008`; if not, repeat the previous step more carefully 32 | * Notice that touching neighbour contacts seem to have no effect (including no harm), I tried 33 | * Also you **must not** keep contacts shortened and you **must not** insert the battery. 34 | 35 | My credits about shortening the contacts in question go to VANOLEO from xda. Thanks, dude! 36 | 37 | You just have proven your phone is **ALIVE!** 38 | 39 | Notice 1: if you do not see any connection, then your phone is indeed dead, sorry, my condolences. 40 | 41 | Notice 2: 9008 mode can be activated on a healthy phone as well, just in case. 42 | 43 | #### Stage 1 44 | 45 | Your phone is alive but it is NOT yet submissive. You must have a very special file. It is called a programmer and is named like `MPRG8960.bin`. It can be in `HEX` format, i.e. `MPRG8960.HEX` but we have `hex2bin` converter. `M` in the name is some index letter, `8960` - the QualComm chip model. The crucial obstacle that this file is quite brand dependent. Literally, this took me more than a month to locate one, presumably from Casio 811, which eventually has done the job. I was lucky, I guess! This is why I renamed it as `MPRG8960NECTerrain.bin` to alert that it is a brand-specific thing. 46 | 47 | The technique is as follows. In the 9008 mode your phone is still quite useless. It can accept only special commands and data for use by the primary processor module. You have to switch the phone to another mode (not 9006, apparently, as some sources claim) in which it can write data to its internal flash memory (notice, that for NEC Terrain it is not a 9006 mode, in which the internal flash would be seen as an SD card). To this aim you submit this special `MPRG8960NECTerrain.bin` file by means of the serial protocol and then send a command to execute this file as a program internally in the phone. Upon all of that you can use the serial protocol to write data to the internal flash. 48 | 49 | The command is 50 | ``` 51 | sudo ./stage1.py -v MPRG8960NECTerrain.bin 52 | ``` 53 | It must be under root, `-v` is for the verbosity (you can omit). If no errors, you see `Done` as the last line. You need `python` and `pyserial` installed to have this working. Now you should wait. I could not determine how long, but at least few seconds before going to stage 2. 54 | 55 | **DO NOT touch cable, keep connected, NO battery insertion, RELAX** 56 | 57 | #### Stage 2 58 | 59 | It is a bit more tricky. You are now ready to write to the internal flash. I took the initial script from Droid Ultra unbrick thread by VBlack on xda, so I preserved his strategy. That is rewriting on a by-partition basis. You specify partitions to rewrite and supply their images. 60 | 61 | Thus you must have a file which is the partition table of your phone as position of partitions is vital for the script in question. But you cannot get this file as your phone is dead. So, you must assume one from a working identical phone around, from another person, from here for instance (`gpt.txt`), or from whatever. No more specific help here, sorry. 62 | 63 | What is the **MOST** important, you **MUST** understand what you want to rewrite. In my case I killed `aboot` experimenting with a new kernel and had to rewrite `aboot`. For a friend of mine I have rewritten `recovery` to save the system folder after. As the rule of thumb: 64 | 65 | **You can assume that if you are not me, you have altered your phone only by my instructions (or terroot written after my method) and therefore partitions are either in their original state (of you did not touch your phone) or where they should be after my guides.** 66 | 67 | Therefore, the `gpt.txt` found in this folder is quite nice to locate most vital partitions (for this gpt `recovery` partition is as it is _after_ rooting by my guides or equivalently by terroot). If ever needed, you will rewrite some of `sbl1,2,3`, `aboot`, `tz`, `rpm` or `recovery`, I think. 68 | 69 | If you have your partition table in a form of binary file, you can make a text table by means of `gpt_parser.py` 70 | 71 | In `gpt.txt` the first column is the offset of partitions in bytes, second is names and then sizes 72 | 73 | **!!!YOU DO NOT EVEN THINK TO TOUCH PARTITIONS `modemst1` and `modemst2` BY ANY MEANS!!!** 74 | 75 | Once you understand what exactly you are going to change you edit the script `stage2.py`. You find the definition (line 42) 76 | ``` 77 | BOOT_PARTITIONS = ("recovery",) 78 | ``` 79 | and change `recovery` to the partition name you want to rewrite. Name must appear **EXACTLY** as it is in the partition table file. If you want to rewrite only one partition, you **keep** the comma after, it is correct. If you want to rewrite more than one partition at once, you act like in the commented line in the script file just above (see line 41). For example 80 | ``` 81 | BOOT_PARTITIONS = ("recovery","aboot") 82 | ``` 83 | with no trailing comma. 84 | 85 | For each partition specified in the `BOOT_PARTITION` list you need a separate image file with extension `.img`, e.g. `recovery.img`, `aboot.img`, etc. Names are case sensitive and **MUST** coincide with the names of partitions. 86 | 87 | There is a possibility to rewrite the partition table itself, but this seems to be indeed weird. I have not explored this to details. 88 | 89 | Finally, given you have edited the `BOOT_PARTITION` variable, all `.img` files in place and a file a la `gpt.txt` you are good to go. The command is 90 | ``` 91 | sudo ./stage2.py -v -ptf gpt.txt 92 | ``` 93 | Again, under root, `-v` for the verbosity and can be skipped, `-ptf` - option to specify the partition table file. Be careful, `-pt` is reserved to indicate that partition table itself must be rewritten. As said before, I did not explore this functionality to details. 94 | 95 | If the script exits quickly mentioning errors, it means, you waited to few after the stage 1. It may also say that the phone is in stage 1 yet, so just go back and execute the stage 1 command. However, if there are indeed errors the serial modem will be reset. In this case you have to 96 | * check with `lsusb` that the connection has gone (no `05c6:9008` device) 97 | * shorten again GND and ENG_BOOT 98 | * check that connection has reestablished and go to stage 1 command 99 | * if no connection, remove cable and go anew to stage 1 from the beginning 100 | 101 | Normally writing goes quite slow (serial port). So, `-v` option is useful to see the progress. On success the last line in the output will be be `Done`. 102 | 103 | If you understand that you want to rewrite one more partition, you go to stage 1 again from the beginning as the modem has been reset. 104 | 105 | #### DONE! 106 | 107 | Provided you did what you meant to, you get what you wanted. 108 | 109 | I got 2 phones resurrected from dead. 110 | 111 | **GOOD LUCK!** 112 | -------------------------------------------------------------------------------- /9008/README_ru.md: -------------------------------------------------------------------------------- 1 | ### Руководство по режиму 9008 для NEC Terrain 2 | 3 | **РЕБЯТА, ЭТО ЕСЛИ ВЫ убили свой аппарат программно, а не скинули с 10-го этажа** 4 | 5 | **Это круто, но не сложно** 6 | 7 | **Это под LINUX, windows пользователи должны разбираться сами** 8 | 9 | **Эта инструкция сугубо для NEC Terrain** 10 | 11 | #### Что такое 9008 12 | 13 | Это режим, в котором внешний usb порт телефона нумеруется, как `05c6:9008` и распознается, как серийный порт, то есть ttySn (COMn в windows). Это происходит в случае, когда стратовые разделы испорчены и ни boot ни recovery разделы не получают управления. Например, вы удалили aboot ... В этом случае телефон после старта ни показывает _НИЧЕГО_. Однако, вполне верятно, что он еще живой. 14 | 15 | В этом состоянии при подключении к компьютеру по usb вы не видите _НИЧЕГО_. Вам нужно активировать режим 9008, который, судя по всему, на самом деле **ПОСЛЕДНИЙ** шанс. Но шанс довольно стойкий. В этом режиме можно записать по-новой внутреннюю flash-память с помощью простого срипта в linux. (В windows вам нужны специальные драйверы `qs9008.tar.gz` и программа QPST. QPST нужно искать или спросить меня частным образом.) Важно, что ядро linux должно поддерживать серийные tty через usb (ttyS). 16 | 17 | Другой случай, когда режим 9008 может быть полезен, - когда что-то не так в системе, телефон вроде грузится, но, например, входит в режим постоянной перезагрузки, из которой нет выхода, и, скажем, нет нормального режима восстановления (recovery). В этом случае вы можете хотеть переписать recovery или даже весь системный каталог, не загружая телефон. Режим 9008 - это выход из ситуации. 18 | 19 | Все упоминаемые файлы находятся в этом каталоге. 20 | 21 | #### Активация режима 9008 22 | 23 | * Выньте батарейку и usb провод из телефона 24 | * Отклейте стикер на котором написан номер IMEI 25 | * Откроются разные контакты, найдите группу из 4-х (на `photo1.jpg` они очерчены красным кругом.). 2 в середине называются GND и ENG_BOOT от слов ground (земля) и engineering_boot (инженерная загрузка) (на `photo2.jpg` показаны красными стрелками) 26 | * Подсоедините телефон в этом состоянии (без батареи) к компьютеру 27 | * Проверьте с помощью команды `lsusb`, что телефон _не_ виден, так по идее должно быть 28 | * Замкните на короткое время контакты GND и ENG_BOOT, для этого вполне подойдет пинцет от швейцарского ножа 29 | * Проверьте с помощью команды `lsusb` что теперь телефон **виден** как `05c6:9008`; если нет, закоротите контакты более аккуратно 30 | * Кажется, что касание соседних контактов не имеет никакого эффекта (в том числе никакого опасного), я пробовал 31 | * Также, вы **не должны** держать контакты замкнутыми и **не должны** вставлять батарею 32 | 33 | Мои благодарности за указание на нужные контакы пользавотелю VANOLEO с xda. Спасибо! 34 | 35 | Вы только что доказали, что ваш телефон еще **ЖИВ!** 36 | 37 | Замечание 1: если никакого соединения так и не появляется, ваш телефон видать реально мертв. Мои соболезнования. 38 | 39 | Замечание 2: режим 9008 можно активировать и на здоровом аппарате (так, на всякий случай). 40 | 41 | #### 1-я стадия 42 | 43 | Телефон жив, но еще пока не подчиняется. Нужен специальный файл. Он называется программер и обычно имеет имя наподобие `MPRG8960.bin`. Он может быть в формате `HEX`, например `MPRG8960.HEX`. На этот случай есть конвертор `hex2bin`. `M` в имени - некий индекс, `8960` - код чипа QualComm. Основная трудность, что этот файл зависит как минимум от производителя телефона (то есть файл разный, даже если чип один, у motorola и samsung). У меня заняло более месяца, чтобы найти нужный файл, видать от Casio 811, который в результате подошел. Похоже, что мне повезло! Файл переименован в `MPRG8960NECTerrain.bin`, чтобы подчеркнуть его специфичность для NEC Terrain. 44 | 45 | Технология такова. В режиме 9008 телефон все еще бесполезен. Он может принимать только ограниченный набор комманд и данных для обработки первичным модулем процессора. Необходимо переключить телефон в другой режим (не 9006, однако, как следует из многих итсочников) в котором он сможет писать данные на внутреннюю flash-память (я считаю, что для NEC Terrain это не режим 9006, так как внутренняя flash-память не становится видна, как SDcard). Для достижения этой цели в телефон нужно загрузить тот самый файл `MPRG8960NECTerrain.bin` при помощи протокола серийного порта, а потом передать команду исполнить файл, как программу внутри телефона. Если все пройдет успешно, то потом можно использовать серийный протокол для записи данных на внутреннюю flash-память. 46 | 47 | Для нас команда выглядит 48 | ``` 49 | sudo ./stage1.py -v MPRG8960NECTerrain.bin 50 | ``` 51 | Она должна исполняться из-под пользователя root, `-v` для подробного вывода (в принципе, не критично). Если нет ошибок, последняя строка вывода будет `Done`. Для работы скрипта необходимы установленные `python` и `pyserial`. Теперь надо подождать. Я не смог понять сколько, но хоть несколько секунд, прежде чем переходить ко 2-й стадии. 52 | 53 | **НЕ трогайте кабель, телефон должен оставаться соединенным с компьютером, НЕ вставляйте батарею, РАССЛАБЬТЕСЬ** 54 | 55 | #### 2-я стадия 56 | 57 | Здесь все более запутанно. Для начала: вы готовы писать на внутреннюю flash-память. Я взял скрипты из темы Droid Ultra unbrick, созданной VBlack на xda. В общем, я решил сохранить использованную стратегию. Она заключается в переписывании внутренней flash-памяти по разделам (partitions). Вы должны указать, какие разделы переписывать, и иметь их образы. 58 | 59 | То есть, вам необходим файл с таблицей разделов flash-памяти телефона. Однако, в данный момент вы уже не можете извлечь его из телефона, так как телефон почти мертвый. Единственный выход - это работать с файлом таблицы разделов другого (нормального) телефона. Здесь есть такой файл, называется `gpt.txt`. 60 | 61 | Что **НАИБОЛЕЕ** важно, - вы **ДОЛЖНЫ** понимать, какой раздел вы хотите перезаписать. В моем случае я запортил `aboot`, эксперементируя с новым ядром, то есть нужно было восстановить `aboot`. На телефоне друга я перезаписал старое бесполезное `recovery` на новое, чтобы восстановить системный раздел. Как общее правило, я думаю, что: 62 | 63 | **Если вы - это не я, то вы скорее всего трогали телефон по моим инструкциям (или использовали программу terroot, которая тоже была написана по моему методу). Тем самым, разделы либо как на изначальном фабричном телефоне (то есть вы его не трогали серьезно вообще), либо там, где они должны быть после использования моих описаний.** 64 | 65 | То есть, файл `gpt.txt`, находящийся здесь, вполне подходит для решения большинства задач (он указывает раздел `recovery` в месте, в котором он находится _после_ рутинга по моим описаниям или с использованием terroot). Если что вы и захотите переписать, то это будет что-то из набора `sbl1,2,3`, `aboot`, `tz`, `rpm` или `recovery`, как мне кажется. 66 | 67 | Если у вас есть ваша таблица разделов в виде бинарного файла, вы можете использовать `gpt_parser.py` для переделывания ее в текстовую таблицу. 68 | 69 | В файле `gpt.txt` первая колонка указывает смещение раздела в байтах, вторая - имя раздела, третья - размер раздела 70 | 71 | **!!!ВЫ НЕ ДОЛЖНЫ ДАЖЕ ДУМАТЬ О ПЕРЕЗАПИСЫВАНИИ РАЗДЕЛОВ `modemst1` и `modemst2` для каких угодно целей!!!** 72 | 73 | Как только вы точно понимаете, что конкретно хотите перезаписать на flash-памяти телефона, вы должны отредактировать скрипт `stage2.py`. Вы ищите следующее присваивание (строка 42) 74 | ``` 75 | BOOT_PARTITIONS = ("recovery",) 76 | ``` 77 | и изменяете `recovery` на имя того раздела, который хотите перезаписать. Имя раздела должно быть написано **АБСОЛЮТНО** также, как оно записано в таблице разделов. Если вы хотите перезаписать один раздел, вы **оставляете** запятую после закрывающей кавычки, это верный синтакс. Есди вы хотите перезаписать более одного раздела, то сформируйте строку, как в закомментированном примере в строке 41. Например 78 | ``` 79 | BOOT_PARTITIONS = ("recovery","aboot") 80 | ``` 81 | В этом случае запятая после последнего имени не нужна. 82 | 83 | Для каждого упомянутого в списке `BOOT_PARTITION` раздела должен существовать отдельный файл образа с расширением `.img`, то есть, например, `recovery.img`, `aboot.img`, и так далее. В именах регистр букв различается, и имена **ДОЛЖНЫ** совпалать с названиями разделов в таблице разделов. 84 | 85 | В скрипте заложена возможность перезаписать на внутренней flash-памяти саму таблицу разделов. Я лично не пользовался, хотя выглядит прямолинейно. 86 | 87 | Наконец, вы отредактировали переменную `BOOT_PARTITION`, все `.img` файлы образов на месте, таблица разделов а ля `gpt.txt` пристутствует. Можем выполнять 2-ю стадию. Команда выглядит 88 | ``` 89 | sudo ./stage2.py -v -ptf gpt.txt 90 | ``` 91 | Опять, из-под root, `-v` для подробного вывода на экран, `-ptf` - опция указания файля таблицы разделов. Будьте аккуратны, `-pt` зарезервировано как опция, указывающая на желание перезаписать саму таблицу разделов. 92 | 93 | Если скрипт закончил работу быстро, упомяная ошибки, то корее всего прошло мало времени после 1-й стадии. Возможно, будет сказано, что телефон все еще в 1-й стадии. Тогда нужно вернуться и выполнить команду 1-й стадии. Но нужно иметь ввиду, что если и вправду возникли ошибки, то серийный модем в телефоне будет перегружен. В этом случае необходимо: 94 | * проверить с помощью команды `lsusb`, что подсоединение ушло (нет устройства с номером `05c6:9008`) 95 | * по новой закоротить контакты GND и ENG_BOOT 96 | * проверить, что нужное подсоединение возникло и вернуться к команде 1-й стадии 97 | * если нет соединения, вынуть usb кабель и начать 1-ю стадию с самого начала 98 | 99 | Обычно, запись идет медленно (серийный порт). Поэтому, опция `-v` полезна, чтобы видеть прогресс. В случае успеха последней строкой вывода будет `Done`. 100 | 101 | Если в этот момент вы поняли, что хотите перезаписать еще какие-то разделы, возвращайтесь к началу 1-й стадии, так как модем в телефоне в конце перегружается. 102 | 103 | #### СДЕЛАНО! 104 | 105 | Если вы делали то, что хотели сделать, вы должны получить то, что ожидали. 106 | 107 | Я воскресил 2 аппарата из дэ факто мертвых. 108 | 109 | **УДАЧИ!** 110 | -------------------------------------------------------------------------------- /9008/aboot.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/aboot.img -------------------------------------------------------------------------------- /9008/gpt.txt: -------------------------------------------------------------------------------- 1 | offset : name : size 2 | 0x000000000000: partitions : 5120 3 | 0x000001000000: modem : 134217728 4 | 0x000009000000: flashbackup : 67108864 5 | 0x00000d000000: fatallog : 67108864 6 | 0x000012000000: sbl1 : 262144 7 | 0x000012040000: sbl2 : 262144 8 | 0x000012080000: sbl3 : 2097152 9 | 0x000012280000: aboot : 524288 10 | 0x000012300000: rpm : 524288 11 | 0x000012380000: boot : 10485760 12 | 0x000012d80000: tz : 524288 13 | 0x000011000000: recovery : 16777216 14 | 0x000013800000: system : 1107296256 15 | 0x000056000000: userdata : 5368709120 16 | 0x000196000000: GROW : 134217728 17 | 0x00019e000000: persist : 8388608 18 | 0x00019e800000: cache : 377487360 19 | 0x0001b5000000: tombstones : 73400320 20 | 0x0001b9600000: misc : 1048576 21 | 0x0001b9700000: pad : 1024 22 | 0x0001b9700400: ssd : 8192 23 | 0x0001b9702400: modemst1 : 3145728 24 | 0x0001b9a02400: modemst2 : 3145728 25 | 0x0001b9d02400: fsg : 3145728 26 | 0x0001ba002400: sbl2_bkp : 262144 27 | 0x0001ba042400: sbl3_bkp : 2097152 28 | 0x0001ba242400: aboot_bkp : 524288 29 | 0x0001ba2c2400: rpm_bkp : 524288 30 | 0x0001ba342400: tz_bkp : 524288 31 | 0x0001ba3c2400: recovery_bkp : 10485760 32 | 0x0001badc2400: fota_config : 10485760 33 | 0x0001bb7c2400: MM : 234881024 34 | -------------------------------------------------------------------------------- /9008/gpt_parser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python -tt 2 | # 3 | # Copyright (c) 2013 Intel, Inc. 4 | # 5 | # This program is free software; you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License as published by the Free 7 | # Software Foundation; version 2 of the License 8 | # 9 | # This program is distributed in the hope that it will be useful, but 10 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 | # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | # for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License along 15 | # with this program; if not, write to the Free Software Foundation, Inc., 59 16 | # Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | 18 | """ This module implements a simple GPT partitions parser which can read the 19 | GPT header and the GPT partition table. """ 20 | 21 | import sys 22 | import struct 23 | import uuid 24 | import binascii 25 | 26 | _GPT_HEADER_FORMAT = "<8s4sIIIQQQQ16sQIII" 27 | _GPT_HEADER_SIZE = struct.calcsize(_GPT_HEADER_FORMAT) 28 | _GPT_ENTRY_FORMAT = "<16s16sQQQ72s" 29 | _GPT_ENTRY_SIZE = struct.calcsize(_GPT_ENTRY_FORMAT) 30 | _SUPPORTED_GPT_REVISION = '\x00\x00\x01\x00' 31 | 32 | def _stringify_uuid(binary_uuid): 33 | """ A small helper function to transform a binary UUID into a string 34 | format. """ 35 | 36 | uuid_str = str(uuid.UUID(bytes_le = binary_uuid)) 37 | 38 | return uuid_str.upper() 39 | 40 | def _calc_header_crc(raw_hdr): 41 | """ Calculate GPT header CRC32 checksum. The 'raw_hdr' parameter has to 42 | be a list or a tuple containing all the elements of the GPT header in a 43 | "raw" form, meaning that it should simply contain "unpacked" disk data. 44 | """ 45 | 46 | raw_hdr = list(raw_hdr) 47 | raw_hdr[3] = 0 48 | raw_hdr = struct.pack(_GPT_HEADER_FORMAT, *raw_hdr) 49 | 50 | return binascii.crc32(raw_hdr) & 0xFFFFFFFF 51 | 52 | def _validate_header(raw_hdr): 53 | """ Validate the GPT header. The 'raw_hdr' parameter has to be a list or a 54 | tuple containing all the elements of the GPT header in a "raw" form, 55 | meaning that it should simply contain "unpacked" disk data. """ 56 | 57 | # Validate the signature 58 | if raw_hdr[0] != 'EFI PART': 59 | raise NameError("GPT partition table not found") 60 | 61 | # Validate the revision 62 | if raw_hdr[1] != _SUPPORTED_GPT_REVISION: 63 | raise NameError("Unsupported GPT revision '%s', supported revision " \ 64 | "is '%s'" % \ 65 | (binascii.hexlify(raw_hdr[1]), 66 | binascii.hexlify(_SUPPORTED_GPT_REVISION))) 67 | 68 | # Validate header size 69 | if raw_hdr[2] != _GPT_HEADER_SIZE: 70 | raise NameError("Bad GPT header size: %d bytes, expected %d" % \ 71 | (raw_hdr[2], _GPT_HEADER_SIZE)) 72 | 73 | crc = _calc_header_crc(raw_hdr) 74 | if raw_hdr[3] != crc: 75 | raise NameError("GPT header crc mismatch: %#x, should be %#x" % \ 76 | (crc, raw_hdr[3])) 77 | 78 | class GptParser: 79 | """ GPT partition table parser. Allows reading the GPT header and the 80 | partition table, as well as modifying the partition table records. """ 81 | 82 | def __init__(self, disk_path, sector_size = 512): 83 | """ The class constructor which accepts the following parameters: 84 | * disk_path - full path to the disk image or device node 85 | * sector_size - size of a disk sector in bytes """ 86 | 87 | self.sector_size = sector_size 88 | self.disk_path = disk_path 89 | 90 | try: 91 | self._disk_obj = open(disk_path, 'r+b') 92 | except IOError as err: 93 | raise NameError("Cannot open file '%s' for reading GPT " \ 94 | "partitions: %s" % (disk_path, err)) 95 | 96 | def __del__(self): 97 | """ The class destructor. """ 98 | 99 | self._disk_obj.close() 100 | 101 | def _read_disk(self, offset, size): 102 | """ A helper function which reads 'size' bytes from offset 'offset' of 103 | the disk and checks all the error conditions. """ 104 | 105 | self._disk_obj.seek(offset) 106 | try: 107 | data = self._disk_obj.read(size) 108 | except IOError as err: 109 | raise NameError("cannot read from '%s': %s" % \ 110 | (self.disk_path, err)) 111 | 112 | if len(data) != size: 113 | raise NameError("cannot read %d bytes from offset '%d' of '%s', " \ 114 | "read only %d bytes" % \ 115 | (size, offset, self.disk_path, len(data))) 116 | 117 | return data 118 | 119 | def _write_disk(self, offset, buf): 120 | """ A helper function which writes buffer 'buf' to offset 'offset' of 121 | the disk. This function takes care of unaligned writes and checks all 122 | the error conditions. """ 123 | 124 | # Since we may be dealing with a block device, we only can write in 125 | # 'self.sector_size' chunks. Find the aligned starting and ending 126 | # disk offsets to read. 127 | start = (offset / self.sector_size) * self.sector_size 128 | end = ((start + len(buf)) / self.sector_size + 1) * self.sector_size 129 | 130 | data = self._read_disk(start, end - start) 131 | off = offset - start 132 | data = data[:off] + buf + data[off + len(buf):] 133 | 134 | self._disk_obj.seek(start) 135 | try: 136 | self._disk_obj.write(data) 137 | except IOError as err: 138 | raise NameError("cannot write to '%s': %s" % (self.disk_path, err)) 139 | 140 | def read_header(self, primary = True): 141 | """ Read and verify the GPT header and return a dictionary containing 142 | the following elements: 143 | 144 | 'signature' : header signature 145 | 'revision' : header revision 146 | 'hdr_size' : header size in bytes 147 | 'hdr_crc' : header CRC32 148 | 'hdr_lba' : LBA of this header 149 | 'hdr_offs' : byte disk offset of this header 150 | 'backup_lba' : backup header LBA 151 | 'backup_offs' : byte disk offset of backup header 152 | 'first_lba' : first usable LBA for partitions 153 | 'first_offs' : first usable byte disk offset for partitions 154 | 'last_lba' : last usable LBA for partitions 155 | 'last_offs' : last usable byte disk offset for partitions 156 | 'disk_uuid' : UUID of the disk 157 | 'ptable_lba' : starting LBA of array of partition entries 158 | 'ptable_offs' : disk byte offset of the start of the partition table 159 | 'ptable_size' : partition table size in bytes 160 | 'entries_cnt' : number of available partition table entries 161 | 'entry_size' : size of a single partition entry 162 | 'ptable_crc' : CRC32 of the partition table 163 | 'primary' : a boolean, if 'True', this is the primary GPT header, 164 | if 'False' - the secondary 165 | 'primary_str' : contains string "primary" if this is the primary GPT 166 | header, and "backup" otherwise 167 | 168 | This dictionary corresponds to the GPT header format. Please, see the 169 | UEFI standard for the description of these fields. 170 | 171 | If the 'primary' parameter is 'True', the primary GPT header is read, 172 | otherwise the backup GPT header is read instead. """ 173 | 174 | # Read and validate the primary GPT header 175 | raw_hdr = self._read_disk(self.sector_size, _GPT_HEADER_SIZE) 176 | raw_hdr = struct.unpack(_GPT_HEADER_FORMAT, raw_hdr) 177 | _validate_header(raw_hdr) 178 | primary_str = "primary" 179 | 180 | if not primary: 181 | # Read and validate the backup GPT header 182 | raw_hdr = self._read_disk(raw_hdr[6] * self.sector_size, _GPT_HEADER_SIZE) 183 | raw_hdr = struct.unpack(_GPT_HEADER_FORMAT, raw_hdr) 184 | _validate_header(raw_hdr) 185 | primary_str = "backup" 186 | 187 | return { 'signature' : raw_hdr[0], 188 | 'revision' : raw_hdr[1], 189 | 'hdr_size' : raw_hdr[2], 190 | 'hdr_crc' : raw_hdr[3], 191 | 'hdr_lba' : raw_hdr[5], 192 | 'hdr_offs' : raw_hdr[5] * self.sector_size, 193 | 'backup_lba' : raw_hdr[6], 194 | 'backup_offs' : raw_hdr[6] * self.sector_size, 195 | 'first_lba' : raw_hdr[7], 196 | 'first_offs' : raw_hdr[7] * self.sector_size, 197 | 'last_lba' : raw_hdr[8], 198 | 'last_offs' : raw_hdr[8] * self.sector_size, 199 | 'disk_uuid' :_stringify_uuid(raw_hdr[9]), 200 | 'ptable_lba' : raw_hdr[10], 201 | 'ptable_offs' : raw_hdr[10] * self.sector_size, 202 | 'ptable_size' : raw_hdr[11] * raw_hdr[12], 203 | 'entries_cnt' : raw_hdr[11], 204 | 'entry_size' : raw_hdr[12], 205 | 'ptable_crc' : raw_hdr[13], 206 | 'primary' : primary, 207 | 'primary_str' : primary_str } 208 | 209 | def _read_raw_ptable(self, header): 210 | """ Read and validate primary or backup partition table. The 'header' 211 | argument is the GPT header. If it is the primary GPT header, then the 212 | primary partition table is read and validated, otherwise - the backup 213 | one. The 'header' argument is a dictionary which is returned by the 214 | 'read_header()' method. """ 215 | 216 | raw_ptable = self._read_disk(header['ptable_offs'], 217 | header['ptable_size']) 218 | 219 | crc = binascii.crc32(raw_ptable) & 0xFFFFFFFF 220 | if crc != header['ptable_crc']: 221 | raise NameError("Partition table at LBA %d (%s) is corrupted" % \ 222 | (header['ptable_lba'], header['primary_str'])) 223 | 224 | return raw_ptable 225 | 226 | def get_partitions(self, primary = True): 227 | """ This is a generator which parses the GPT partition table and 228 | generates the following dictionary for each partition: 229 | 230 | 'index' : the index of the partition table endry 231 | 'offs' : byte disk offset of the partition table entry 232 | 'type_uuid' : partition type UUID 233 | 'part_uuid' : partition UUID 234 | 'first_lba' : the first LBA 235 | 'last_lba' : the last LBA 236 | 'flags' : attribute flags 237 | 'name' : partition name 238 | 'primary' : a boolean, if 'True', this is the primary partition 239 | table, if 'False' - the secondary 240 | 'primary_str' : contains string "primary" if this is the primary GPT 241 | header, and "backup" otherwise 242 | 243 | This dictionary corresponds to the GPT header format. Please, see the 244 | UEFI standard for the description of these fields. 245 | 246 | If the 'primary' parameter is 'True', partitions from the primary GPT 247 | partition table are generated, otherwise partitions from the backup GPT 248 | partition table are generated. """ 249 | 250 | if primary: 251 | primary_str = "primary" 252 | else: 253 | primary_str = "backup" 254 | 255 | header = self.read_header(primary) 256 | raw_ptable = self._read_raw_ptable(header) 257 | 258 | for index in xrange(0, header['entries_cnt']): 259 | start = header['entry_size'] * index 260 | end = start + header['entry_size'] 261 | raw_entry = struct.unpack(_GPT_ENTRY_FORMAT, raw_ptable[start:end]) 262 | 263 | if raw_entry[2] == 0 or raw_entry[3] == 0: 264 | continue 265 | 266 | part_name = str(raw_entry[5].decode('UTF-16').split('\0', 1)[0]) 267 | 268 | yield { 'index' : index, 269 | 'offs' : header['ptable_offs'] + start, 270 | 'type_uuid' : _stringify_uuid(raw_entry[0]), 271 | 'part_uuid' : _stringify_uuid(raw_entry[1]), 272 | 'first_lba' : raw_entry[2], 273 | 'last_lba' : raw_entry[3], 274 | 'flags' : raw_entry[4], 275 | 'name' : part_name, 276 | 'primary' : primary, 277 | 'primary_str' : primary_str } 278 | 279 | def _change_partition(self, header, entry): 280 | """ A helper function for 'change_partitions()' which changes a 281 | a paricular instance of the partition table (primary or backup). """ 282 | 283 | if entry['index'] >= header['entries_cnt']: 284 | raise NameError("Partition table at LBA %d has only %d " \ 285 | "records cannot change record number %d" % \ 286 | (header['entries_cnt'], entry['index'])) 287 | # Read raw GPT header 288 | raw_hdr = self._read_disk(header['hdr_offs'], _GPT_HEADER_SIZE) 289 | raw_hdr = list(struct.unpack(_GPT_HEADER_FORMAT, raw_hdr)) 290 | _validate_header(raw_hdr) 291 | 292 | # Prepare the new partition table entry 293 | raw_entry = struct.pack(_GPT_ENTRY_FORMAT, 294 | uuid.UUID(entry['type_uuid']).bytes_le, 295 | uuid.UUID(entry['part_uuid']).bytes_le, 296 | entry['first_lba'], 297 | entry['last_lba'], 298 | entry['flags'], 299 | entry['name'].encode('UTF-16LE')) 300 | 301 | # Write the updated entry to the disk 302 | entry_offs = header['ptable_offs'] + \ 303 | header['entry_size'] * entry['index'] 304 | self._write_disk(entry_offs, raw_entry) 305 | 306 | # Calculate and update partition table CRC32 307 | raw_ptable = self._read_disk(header['ptable_offs'], 308 | header['ptable_size']) 309 | raw_hdr[13] = binascii.crc32(raw_ptable) & 0xFFFFFFFF 310 | 311 | # Calculate and update the GPT header CRC 312 | raw_hdr[3] = _calc_header_crc(raw_hdr) 313 | 314 | # Write the updated header to the disk 315 | raw_hdr = struct.pack(_GPT_HEADER_FORMAT, *raw_hdr) 316 | self._write_disk(header['hdr_offs'], raw_hdr) 317 | 318 | def change_partition(self, entry): 319 | """ Change a GPT partition. The 'entry' argument has the same format as 320 | 'get_partitions()' returns. This function simply changes the partition 321 | table record corresponding to 'entry' in both, the primary and the 322 | backup GPT partition tables. The parition table CRC is re-calculated 323 | and the GPT headers are modified accordingly. """ 324 | 325 | # Change the primary partition table 326 | header = self.read_header(True) 327 | self._change_partition(header, entry) 328 | 329 | # Change the backup partition table 330 | header = self.read_header(False) 331 | self._change_partition(header, entry) 332 | 333 | 334 | def main(): 335 | bs = 512 336 | gpt = GptParser(sys.argv[1], bs) 337 | header = gpt.read_header(); 338 | print "%s: %s: %s"%('offset'.ljust(14), 'name'.ljust(14), 'size') 339 | print "%s: %s: %s"%(("0x%012x"%0).ljust(14), 'partitions'.ljust(14), ("%d"%(header['ptable_offs']+header['ptable_size']))) 340 | for part in gpt.get_partitions(): 341 | print "%s: %s: %s"%(("0x%012x"%(part['first_lba']*bs)).ljust(14), part['name'].ljust(14), ("%d"%((part['last_lba']-part['first_lba']+1)*bs))) 342 | 343 | main() -------------------------------------------------------------------------------- /9008/hex2bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/hex2bin -------------------------------------------------------------------------------- /9008/photo1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/photo1.jpg -------------------------------------------------------------------------------- /9008/photo2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/photo2.jpg -------------------------------------------------------------------------------- /9008/qs9008.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/qs9008.tar.gz -------------------------------------------------------------------------------- /9008/recovery.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/recovery.img -------------------------------------------------------------------------------- /9008/rpm.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/rpm.img -------------------------------------------------------------------------------- /9008/sbl1.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/sbl1.img -------------------------------------------------------------------------------- /9008/sbl2.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/sbl2.img -------------------------------------------------------------------------------- /9008/sbl3.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/sbl3.img -------------------------------------------------------------------------------- /9008/stage1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | V = "1.2" 3 | #History: 4 | #V1.2 06/08/2014 - Add lot of information printing 5 | #V1.1 29/07/2014 - Add windows tty port detection 6 | #V1.0 28/07/2014 - Initial release 7 | #(c) VBlack 8 | 9 | import os, sys, array, time, glob, argparse, platform, struct 10 | 11 | VERSION = 0 12 | FLASH = 0 13 | 14 | #PBL stage packet 15 | PACKET_ACK = array.array('B',[0x02]) 16 | PACKET_EXECUTE = array.array('B',[0x05]) 17 | PACKET_NO_OP = array.array('B',[0x06]) 18 | PACKET_REQUEST_PARAM = array.array('B',[0x07]) 19 | PACKET_RESET_PBL = array.array('B',[0x0a]) 20 | PACKET_VERSION = array.array('B',[0x0c]) 21 | PACKET_WRITE_CHUNK_PBL = array.array('B',[0x0f]) 22 | PACKET_SERIAL_7 = array.array('B',[0x014]) 23 | PACKET_SERIAL_8 = array.array('B',[0x016]) 24 | PACKET_HW_ID = array.array('B',[0x17]) 25 | PACKET_PUBLIC_KEY = array.array('B',[0x18]) 26 | PACKET_REQUEST_DLOAD = array.array('B',[0x3a]) 27 | 28 | #SBL stage packets 29 | PACKET_MAGIC = array.array('B',[0x01,]) + array.array('B',"QCOM fast download protocol host") + array.array('B',[0x07, 0x05, 0x09]) 30 | PACKET_WRITE_CHUNK_SBL = array.array('B',[0x07]) 31 | PACKET_RESET_SBL = array.array('B',[0x0b]) 32 | PACKET_CLOSE_FLUSH = array.array('B',[0x15]) 33 | PACKET_SECURE_MODE = array.array('B',[0x17, 0x01]) 34 | PACKET_OPEN_MULTI = array.array('B',[0x1b, 0x21]) 35 | PACKET_QFUSE_READ = array.array('B',[0x34]) 36 | 37 | PFILE_ADDRESS = 0x2a000000 38 | 39 | CHUNK_SIZE = 1024 40 | 41 | #BOOT_PARTITIONS = ("sbl1", "sbl2", "sbl3", "aboot", "rpm", "tz") 42 | BOOT_PARTITIONS = ("aboot",) 43 | 44 | PT_PARTITION = "partitions" 45 | 46 | VERBOSE = False 47 | 48 | crcTable = ( 49 | 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 50 | 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 51 | 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 52 | 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 53 | 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 54 | 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 55 | 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 56 | 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 57 | 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 58 | 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 59 | 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 60 | 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 61 | 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 62 | 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 63 | 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 64 | 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 65 | 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 66 | 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 67 | 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 68 | 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 69 | 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 70 | 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 71 | 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 72 | 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 73 | 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 74 | 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 75 | 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 76 | 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 77 | 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 78 | 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 79 | 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 80 | 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78) 81 | 82 | flash_sizes = ["Invalid or unrecognized Flash device, or Flash device programming not supported by this implementation", 83 | "4-megabit (512 K byte) Flash", 84 | "8-megabit (1024 K byte) Flash", 85 | "16-megabit (2048 K byte) Flash used as an 8-megabit Flash", 86 | "16-megabit (2048 K byte) Flash", 87 | "32-megabit (4096 K byte) Flash", 88 | "64-megabit (8192 K byte) Flash", 89 | "Reserved"] 90 | 91 | dev_types = ["Intel 28F400BX-TL or Intel 28F400BV-TL", 92 | "AMD Am29F400", 93 | "Intel 28F800BV-T", 94 | "AMD Am29LV400T", 95 | "AMD Am29LV800T", 96 | "Sharp LH28F400SUHT-LC15", 97 | "Hitachi HN29WT800T", 98 | "Texas Instruments TMS28F800SZT", 99 | "AMD Am29DL800T", 100 | "Intel 28F800B3-T", 101 | "Intel 28F160B3-T", 102 | "Sharp LH28F800BG-LT", 103 | "Mitsubishi 29GT161", 104 | "AMD Am29DL162", 105 | "Fujitsu 29DL162", 106 | "Atmel 49BV8192", 107 | "Fujitsu 29DL323", 108 | "Fujitsu 84VD22283", 109 | "AMD Am29DL163", 110 | "AMD Am29DL323", 111 | "Mitsubishi 29GT320", 112 | "Toshiba 50VSF2581", 113 | "NEC 222243A", 114 | "AMD Am29PDS322D", 115 | "Mitsubishi M6MGT641", 116 | "AMD Am29BDS640G", 117 | "Unknown or unrecognized device"] 118 | 119 | nack_res = ["Illegal reason (do not use)", 120 | "Invalid frame FCS", 121 | "Invalid destination address", 122 | "Invalid length", 123 | "Unexpected end of packet", 124 | "Data length too large for buffer", 125 | "Unknown/invalid command", 126 | "Operation failed", 127 | "Wrong Flash intelligent ID", 128 | "Bad programming voltage", 129 | "Write-verify failed", 130 | "Not permitted without unlock", 131 | "Incorrect security code", 132 | "Cannot power down phone", 133 | "Operation not permitted at this time", 134 | "Invalid read address", 135 | "Illegal reason (do not use)"] 136 | 137 | def openTTY(tty_path = ""): 138 | if tty_path == "": 139 | if platform.system() != 'Windows': 140 | product = "" 141 | vendor = "" 142 | dev = "" 143 | devices = map(lambda x: x.split("/")[-1],glob.glob("/sys/bus/usb/devices/*")) 144 | for device in devices: 145 | try: 146 | with open("/sys/bus/usb/devices/%s/idProduct"%device, 'r') as f: 147 | product = f.read() 148 | with open("/sys/bus/usb/devices/%s/idVendor"%device, 'r') as f: 149 | vendor = f.read() 150 | except: 151 | pass 152 | if (vendor.strip() == "05c6") and (product.strip() == "9008"): 153 | dev = device 154 | break 155 | drivers = map(lambda x: x.split("/")[-1],glob.glob("/sys/bus/usb/devices/%s/%s:*"%(dev,dev))) 156 | for driver in drivers: 157 | ttys = map(lambda x: x.split("/")[-1],glob.glob("/sys/bus/usb/devices/%s/%s/tty*"%(dev,driver))) 158 | if len(ttys) >0: 159 | tty_path = "/dev/%s"%ttys[0] 160 | break 161 | else: 162 | dload_port_desc = "Qualcomm HS-USB QDLoader 9008" 163 | 164 | port_list = list(serial.tools.list_ports.comports()) 165 | ''' Loop through the available ports to find the COM port 166 | used for dload enumeration. 167 | Exit if multiple dload enumerations are found ''' 168 | for port in port_list: 169 | if dload_port_desc in port[1]: 170 | tty_path = port[0].lower() 171 | break 172 | 173 | if tty_path != "": 174 | print "Found TTY port: ",tty_path 175 | tty = serial.Serial(port=tty_path, baudrate=115200) 176 | return tty 177 | else: 178 | print "Could not find Qualcomm device in Emergency download mode" 179 | return None 180 | 181 | def closeTTY(tty): 182 | tty.close() 183 | 184 | def serial16(data): 185 | out = array.array('B') 186 | out.append((data >> 8) & 0xFF) 187 | out.append(data & 0xFF) 188 | return out 189 | 190 | def serial16le(data): 191 | out = array.array('B') 192 | out.append(data & 0xFF) 193 | out.append((data >> 8) & 0xFF) 194 | return out 195 | 196 | def serial32(data): 197 | out = array.array('B') 198 | out += serial16((data >> 16) & 0xFFFF) 199 | out += serial16(data & 0xFFFF) 200 | return out 201 | 202 | def serial32le(data): 203 | out = array.array('B') 204 | out += serial16le(data & 0xFFFF) 205 | out += serial16le((data >> 16) & 0xFFFF) 206 | return out 207 | 208 | def crc(initial, packet): 209 | for byte in packet: 210 | initial = ((initial >> 8) & 0xFFFF) ^ crcTable[(initial ^ byte) & 0xFF] 211 | return ~initial & 0xFFFF 212 | 213 | def escape(packet): 214 | out = array.array('B') 215 | for byte in packet: 216 | if byte == 0x7e: 217 | out.append(0x7d) 218 | out.append(0x5e) 219 | elif byte == 0x7d: 220 | out.append(0x7d) 221 | out.append(0x5d) 222 | else: 223 | out.append(byte) 224 | return out 225 | 226 | def unescape(packet): 227 | escape = False 228 | out = array.array('B') 229 | for byte in packet: 230 | if escape: 231 | if byte == 0x5e: 232 | out.append(0x7e) 233 | elif byte == 0x5d: 234 | out.append(0x7d) 235 | else: 236 | print "Fatal error unescaping buffer!" 237 | return None 238 | escape = False 239 | else: 240 | if byte == 0x7d: 241 | escape = True 242 | else: 243 | out.append(byte) 244 | if len(out) == 0: 245 | return None 246 | return out 247 | 248 | def sendPacket(tty, packet): 249 | c = crc( 0xffff, packet ) 250 | out = array.array('B',[0x7e]) + escape(packet + serial16le(c)) + array.array('B',[0x7e]) 251 | if VERBOSE: 252 | print "SENDING: ", " ".join("%02x" % b for b in out) 253 | tty.write(out) 254 | return True 255 | 256 | def readPacket(tty, timeout, expect_packet = -1, expect_no_response = False): 257 | while True: 258 | buf = array.array('B') 259 | end = start = time.clock() 260 | 261 | while (end-start) <= timeout: 262 | if tty.inWaiting() > 0: 263 | curr = ord(tty.read(1)) 264 | if len(buf) == 0: 265 | if curr != 0x7e: 266 | return None 267 | buf.append(curr) 268 | if (curr == 0x7e) and (len(buf) > 1): 269 | break; 270 | end = time.clock() 271 | if len(buf) > 0: 272 | buf = buf [1:-1] 273 | buf = unescape(buf) 274 | 275 | if buf != None: 276 | if (buf[0] == 0x0e) and (expect_packet != buf[0]): 277 | if not expect_no_response: 278 | print "\tLOG: ", buf[1:-2].tostring().strip() 279 | continue 280 | #return None 281 | elif (buf[0] == 0x0d) and (expect_packet != buf[0]): 282 | if not expect_no_response: 283 | print "\tERROR: 0x%08x:"%struct.unpack(" 0): 291 | if (len(buf) < 1) or (buf[0] != expect_packet): 292 | if buf[0] != 3: 293 | print "Invalid Response!!!: ", buf, expect_packet 294 | return False 295 | nack = struct.unpack(">H",buf[1:3])[0] 296 | if nack > len(nack_res)-1: 297 | nack = len(nack_res)-1 298 | print "ERROR: ", nack_res[nack] 299 | return None 300 | 301 | if VERBOSE: 302 | print "RECEIVED: ", " ".join("%02x" % b for b in buf) 303 | break 304 | return buf[:-2] 305 | 306 | ########################### PBL STAGE ################################## 307 | ########################### PBL STAGE ################################## 308 | ########################### PBL STAGE ################################## 309 | ########################### PBL STAGE ################################## 310 | ########################### PBL STAGE ################################## 311 | ########################### PBL STAGE ################################## 312 | ########################### PBL STAGE ################################## 313 | 314 | def writeChunk_PBL(tty, address, chunk): 315 | if not sendPacket( tty, PACKET_WRITE_CHUNK_PBL + serial32(address) + serial16(len(chunk)) + chunk): 316 | print "Failed to send chunk" 317 | return False 318 | 319 | response = readPacket(tty, 2.0, PACKET_ACK[0]) 320 | if None == response: 321 | return False 322 | 323 | return True 324 | 325 | def uploadFile_PBL(tty, address, filename): 326 | data = array.array('B') 327 | print "Uploading file '%s' to addr 0x%x..."%(filename, address) 328 | try: 329 | with open(filename, "rb") as f: 330 | while True: 331 | try: data.fromfile(f, 2000) 332 | except EOFError: break 333 | except: 334 | print "File not found %s"%filename 335 | return False 336 | while len(data) > 0: 337 | chunk = data[:CHUNK_SIZE] 338 | data = data[CHUNK_SIZE:] 339 | 340 | if VERBOSE: 341 | print "Writing %d bytes to 0x%x; %d bytes left."%(len(chunk), address, len(data)) 342 | if not writeChunk_PBL(tty, address, chunk): 343 | print "Upload failed" 344 | return False 345 | address += len(chunk) 346 | return True 347 | 348 | def isStagePBL(tty): 349 | return doNoOp(tty) 350 | 351 | def doGo(tty, address): 352 | print "Executing..." 353 | if not sendPacket( tty, PACKET_EXECUTE + serial32(address)): 354 | print "Failed execute" 355 | return False 356 | 357 | response = readPacket(tty, 5.0, PACKET_ACK[0]) 358 | if None == response: 359 | return False 360 | 361 | time.sleep(2) 362 | return True 363 | 364 | def doNoOp(tty): 365 | if not sendPacket( tty, PACKET_NO_OP): 366 | print "Failed No OP" 367 | return False 368 | 369 | response = readPacket(tty, 2.0, PACKET_ACK[0], expect_no_response = True) 370 | if None == response: 371 | return False 372 | return True 373 | 374 | def doSoftwareVersion(tty): 375 | print "Requesting SoftwareVersion..." 376 | if not sendPacket( tty, PACKET_VERSION): 377 | print "Failed SoftwareVersion" 378 | return False 379 | 380 | response = readPacket(tty, 2.0, PACKET_VERSION[0]+1) 381 | if None == response: 382 | return False 383 | 384 | print "Version: ", response[2:2+response[1]].tostring() 385 | return True 386 | 387 | def doSerialNum(tty): 388 | if VERSION < 7: 389 | return True 390 | print "Requesting SerialNumber..." 391 | if VERSION == 7: 392 | PACKET = PACKET_SERIAL_7 393 | else: 394 | PACKET = PACKET_SERIAL_8 395 | if not sendPacket( tty, PACKET): 396 | print "Failed SerialNumber" 397 | return False 398 | 399 | response = readPacket(tty, 2.0, PACKET[0]) 400 | if None == response: 401 | return False 402 | sn_len = response[1]/8 403 | print "Serial number: ", ",".join("%02x" % b for b in response[2:2+sn_len]) 404 | return True 405 | 406 | def doHWId(tty): 407 | if VERSION < 8: 408 | return True 409 | print "Requesting HW Id..." 410 | if not sendPacket( tty, PACKET_HW_ID): 411 | print "Failed HW Id" 412 | return False 413 | 414 | response = readPacket(tty, 2.0, PACKET_HW_ID[0]) 415 | if None == response: 416 | return False 417 | hwid_len = struct.unpack('>H', response[1:3])[0]/8 418 | print "HW Id: ", ",".join("%02x" % b for b in response[3:3+hwid_len]) 419 | return True 420 | 421 | def doPublicKey(tty): 422 | if VERSION < 8: 423 | return True 424 | print "Requesting PublicKey..." 425 | if not sendPacket( tty, PACKET_PUBLIC_KEY): 426 | print "Failed PublicKey" 427 | return False 428 | 429 | response = readPacket(tty, 2.0, PACKET_PUBLIC_KEY[0]) 430 | if None == response: 431 | return False 432 | pkey_len = struct.unpack('>H', response[1:3])[0]/8 433 | print "PublicKey: ", ",".join("%02x" % b for b in response[3:3+pkey_len]) 434 | return True 435 | 436 | 437 | def doRequestDload(tty): 438 | print "Requesting Dload..." 439 | if not sendPacket( tty, PACKET_REQUEST_DLOAD): 440 | print "Failed requestDload" 441 | return False 442 | 443 | print "requestDload send ok" 444 | 445 | response = readPacket(tty, 2.0, PACKET_REQUEST_DLOAD[0]) 446 | if None == response: 447 | return False 448 | 449 | return True 450 | 451 | def doRequestParam(tty): 452 | print "Requesting Params..." 453 | if not sendPacket( tty, PACKET_REQUEST_PARAM): 454 | print "Failed requestParam" 455 | return False 456 | 457 | response = readPacket(tty, 2.0, PACKET_REQUEST_PARAM[0]+1) 458 | if None == response: 459 | return False 460 | if len(response) != 8: 461 | return False 462 | 463 | print "Params:" 464 | global VERSION 465 | VERSION = response[1] 466 | print "\tVersion: %d"%VERSION 467 | print "\tMin version: %d"%response[2] 468 | ws = struct.unpack('>H', response[3:5])[0] 469 | print "\tMax write size: %d (0x%08x)"%(ws, ws) 470 | print "\tModel: %d"%response[5] 471 | fs = response[6] 472 | if fs > len(flash_sizes)-1: 473 | fs = len(flash_sizes)-1 474 | global FLASH 475 | FLASH = fs 476 | print "\tDevice size: %s"%flash_sizes[fs] 477 | dt = response[7] 478 | if dt > len(dev_types)-1: 479 | dt = len(dev_types)-1 480 | print "\tDevice type: %s"%dev_types[dt] 481 | return True 482 | 483 | def doReset_PBL(tty): 484 | print "Sending PBL Reset..." 485 | if not sendPacket( tty, PACKET_RESET_PBL): 486 | print "Failed Reset\n"; 487 | return False 488 | 489 | response = readPacket(tty, 2.0, PACKET_ACK[0]) 490 | if None == response: 491 | return False 492 | 493 | return True 494 | 495 | def doStage_PBL(tty,pFile): 496 | response = readPacket( tty, 0.1, expect_no_response = True ) 497 | while response != None: 498 | if VERBOSE: 499 | print "Ignoring response: ", response 500 | response = readPacket( tty, 0.1, expect_no_response = True ) 501 | 502 | if doRequestParam(tty): 503 | if doSoftwareVersion(tty): 504 | if doSerialNum(tty): 505 | if doHWId(tty): 506 | if doPublicKey(tty): 507 | if FLASH != 0: 508 | return doRequestDload(tty) 509 | else: 510 | if uploadFile_PBL(tty, PFILE_ADDRESS, pFile): 511 | return doGo( tty, PFILE_ADDRESS ) 512 | return False 513 | 514 | ######################### 515 | ######################### 516 | ######################### 517 | ######################### 518 | ######################### 519 | ######################### 520 | ######################### 521 | 522 | def ParsePTfile(filename, pt_flash): 523 | try: 524 | f = open(filename) 525 | except: 526 | print "File not found %s"%filename 527 | return None 528 | 529 | path = os.path.dirname(os.path.abspath(filename)) 530 | data = map(lambda x: map(lambda y: y.strip(),x.split(":")), f.readlines()[1:]) 531 | file_s = set(map(lambda x: x[1], data)) 532 | data = dict([d[1], [int(d[0],16),int(d[2])]] for d in data) 533 | if pt_flash: 534 | need_s = set(BOOT_PARTITIONS + (PT_PARTITION,)) 535 | else: 536 | need_s = set(BOOT_PARTITIONS) 537 | if not need_s.issubset(file_s): 538 | print "Not all partitions present: ", need_s - (need_s & file_s) 539 | return None 540 | 541 | images = [] 542 | for p in need_s: 543 | try: 544 | fn = path + '/' + p +'.img' 545 | if os.path.getsize(fn) > data[p][1]: 546 | print "File size %s bigger than partition"%fn 547 | return None 548 | except: 549 | print "Could not open file %s"%fn 550 | return None 551 | images.append([data[p][0], fn]) 552 | images.sort() 553 | f.close() 554 | return images 555 | 556 | def main(): 557 | parser = argparse.ArgumentParser(description='Qualcomm DLOAD mode images upload utility.') 558 | parser.add_argument('-tty','--ttyPort', type=str, help='Optional ttyPort', default="") 559 | parser.add_argument('MPRGfile', type=str, help='MPRG file in .bin format') 560 | parser.add_argument("-v", "--verbose", action="store_true") 561 | 562 | args = parser.parse_args() 563 | 564 | tty = None 565 | 566 | print "QDLoad stage 1 utility version %s (c) VBlack 2014, ported by alex-kas"%V 567 | 568 | global VERBOSE 569 | 570 | if args.verbose: 571 | VERBOSE = True 572 | 573 | tty = openTTY(args.ttyPort) 574 | if tty != None: 575 | if VERBOSE: 576 | print tty.getPort() 577 | if isStagePBL(tty): 578 | if doStage_PBL(tty, args.MPRGfile): 579 | print "Done" 580 | return True 581 | else: 582 | doReset_PBL(tty) 583 | else: 584 | print "The device seems ready for stage 2" 585 | return True 586 | 587 | print "Done, with errors!!!" 588 | 589 | if tty != None: 590 | closeTTY(tty) 591 | return False 592 | 593 | if __name__ == "__main__": 594 | #Verify python version is > 2.6 and < 3.0 595 | python_version = sys.version_info 596 | if python_version[0] != 2 or python_version[1] < 6: 597 | print("Python version 2.6 or 2.7 required!") 598 | print("you can download Python 2.6.x or 2.7.x here:") 599 | print("http://www.python.org/download/releases/") 600 | exit() 601 | 602 | # check whether pyserial 2.6 is installed. 603 | try: 604 | import serial 605 | import serial.tools.list_ports 606 | except ImportError: 607 | print("Please install pyserial 2.6 from here") 608 | print("https://pypi.python.org/pypi/pyserial") 609 | exit() 610 | 611 | main() 612 | -------------------------------------------------------------------------------- /9008/stage2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | V = "1.2" 3 | #History: 4 | #V1.2 06/08/2014 - Add lot of information printing 5 | #V1.1 29/07/2014 - Add windows tty port detection 6 | #V1.0 28/07/2014 - Initial release 7 | #(c) VBlack 8 | 9 | import os, sys, array, time, glob, argparse, platform, struct 10 | 11 | VERSION = 0 12 | FLASH = 0 13 | 14 | #PBL stage packet 15 | PACKET_ACK = array.array('B',[0x02]) 16 | PACKET_EXECUTE = array.array('B',[0x05]) 17 | PACKET_NO_OP = array.array('B',[0x06]) 18 | PACKET_REQUEST_PARAM = array.array('B',[0x07]) 19 | PACKET_RESET_PBL = array.array('B',[0x0a]) 20 | PACKET_VERSION = array.array('B',[0x0c]) 21 | PACKET_WRITE_CHUNK_PBL = array.array('B',[0x0f]) 22 | PACKET_SERIAL_7 = array.array('B',[0x014]) 23 | PACKET_SERIAL_8 = array.array('B',[0x016]) 24 | PACKET_HW_ID = array.array('B',[0x17]) 25 | PACKET_PUBLIC_KEY = array.array('B',[0x18]) 26 | PACKET_REQUEST_DLOAD = array.array('B',[0x3a]) 27 | 28 | #SBL stage packets 29 | PACKET_MAGIC = array.array('B',[0x01,]) + array.array('B',"QCOM fast download protocol host") + array.array('B',[0x07, 0x05, 0x09]) 30 | PACKET_WRITE_CHUNK_SBL = array.array('B',[0x07]) 31 | PACKET_RESET_SBL = array.array('B',[0x0b]) 32 | PACKET_CLOSE_FLUSH = array.array('B',[0x15]) 33 | PACKET_SECURE_MODE = array.array('B',[0x17, 0x01]) 34 | PACKET_OPEN_MULTI = array.array('B',[0x1b, 0x21]) 35 | PACKET_QFUSE_READ = array.array('B',[0x34]) 36 | 37 | PFILE_ADDRESS = 0x2a000000 38 | 39 | CHUNK_SIZE = 1024 40 | 41 | #BOOT_PARTITIONS = ("sbl1", "sbl2", "sbl3", "aboot", "rpm", "tz") 42 | BOOT_PARTITIONS = ("recovery",) 43 | 44 | PT_PARTITION = "partitions" 45 | 46 | VERBOSE = False 47 | 48 | crcTable = ( 49 | 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 50 | 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 51 | 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 52 | 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 53 | 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 54 | 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 55 | 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 56 | 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 57 | 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 58 | 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 59 | 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 60 | 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 61 | 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 62 | 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 63 | 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 64 | 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 65 | 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 66 | 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 67 | 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 68 | 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 69 | 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 70 | 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 71 | 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 72 | 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 73 | 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 74 | 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 75 | 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 76 | 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 77 | 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 78 | 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 79 | 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 80 | 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78) 81 | 82 | flash_sizes = ["Invalid or unrecognized Flash device, or Flash device programming not supported by this implementation", 83 | "4-megabit (512 K byte) Flash", 84 | "8-megabit (1024 K byte) Flash", 85 | "16-megabit (2048 K byte) Flash used as an 8-megabit Flash", 86 | "16-megabit (2048 K byte) Flash", 87 | "32-megabit (4096 K byte) Flash", 88 | "64-megabit (8192 K byte) Flash", 89 | "Reserved"] 90 | 91 | dev_types = ["Intel 28F400BX-TL or Intel 28F400BV-TL", 92 | "AMD Am29F400", 93 | "Intel 28F800BV-T", 94 | "AMD Am29LV400T", 95 | "AMD Am29LV800T", 96 | "Sharp LH28F400SUHT-LC15", 97 | "Hitachi HN29WT800T", 98 | "Texas Instruments TMS28F800SZT", 99 | "AMD Am29DL800T", 100 | "Intel 28F800B3-T", 101 | "Intel 28F160B3-T", 102 | "Sharp LH28F800BG-LT", 103 | "Mitsubishi 29GT161", 104 | "AMD Am29DL162", 105 | "Fujitsu 29DL162", 106 | "Atmel 49BV8192", 107 | "Fujitsu 29DL323", 108 | "Fujitsu 84VD22283", 109 | "AMD Am29DL163", 110 | "AMD Am29DL323", 111 | "Mitsubishi 29GT320", 112 | "Toshiba 50VSF2581", 113 | "NEC 222243A", 114 | "AMD Am29PDS322D", 115 | "Mitsubishi M6MGT641", 116 | "AMD Am29BDS640G", 117 | "Unknown or unrecognized device"] 118 | 119 | nack_res = ["Illegal reason (do not use)", 120 | "Invalid frame FCS", 121 | "Invalid destination address", 122 | "Invalid length", 123 | "Unexpected end of packet", 124 | "Data length too large for buffer", 125 | "Unknown/invalid command", 126 | "Operation failed", 127 | "Wrong Flash intelligent ID", 128 | "Bad programming voltage", 129 | "Write-verify failed", 130 | "Not permitted without unlock", 131 | "Incorrect security code", 132 | "Cannot power down phone", 133 | "Operation not permitted at this time", 134 | "Invalid read address", 135 | "Illegal reason (do not use)"] 136 | 137 | def openTTY(tty_path = ""): 138 | if tty_path == "": 139 | if platform.system() != 'Windows': 140 | product = "" 141 | vendor = "" 142 | dev = "" 143 | devices = map(lambda x: x.split("/")[-1],glob.glob("/sys/bus/usb/devices/*")) 144 | for device in devices: 145 | try: 146 | with open("/sys/bus/usb/devices/%s/idProduct"%device, 'r') as f: 147 | product = f.read() 148 | with open("/sys/bus/usb/devices/%s/idVendor"%device, 'r') as f: 149 | vendor = f.read() 150 | except: 151 | pass 152 | if (vendor.strip() == "05c6") and (product.strip() == "9008"): 153 | dev = device 154 | break 155 | drivers = map(lambda x: x.split("/")[-1],glob.glob("/sys/bus/usb/devices/%s/%s:*"%(dev,dev))) 156 | for driver in drivers: 157 | ttys = map(lambda x: x.split("/")[-1],glob.glob("/sys/bus/usb/devices/%s/%s/tty*"%(dev,driver))) 158 | if len(ttys) >0: 159 | tty_path = "/dev/%s"%ttys[0] 160 | break 161 | else: 162 | dload_port_desc = "Qualcomm HS-USB QDLoader 9008" 163 | 164 | port_list = list(serial.tools.list_ports.comports()) 165 | ''' Loop through the available ports to find the COM port 166 | used for dload enumeration. 167 | Exit if multiple dload enumerations are found ''' 168 | for port in port_list: 169 | if dload_port_desc in port[1]: 170 | tty_path = port[0].lower() 171 | break 172 | 173 | if tty_path != "": 174 | print "Found TTY port: ",tty_path 175 | tty = serial.Serial(port=tty_path, baudrate=115200) 176 | return tty 177 | else: 178 | print "Could not find Qualcomm device in Emergency download mode" 179 | return None 180 | 181 | def closeTTY(tty): 182 | tty.close() 183 | 184 | def serial16(data): 185 | out = array.array('B') 186 | out.append((data >> 8) & 0xFF) 187 | out.append(data & 0xFF) 188 | return out 189 | 190 | def serial16le(data): 191 | out = array.array('B') 192 | out.append(data & 0xFF) 193 | out.append((data >> 8) & 0xFF) 194 | return out 195 | 196 | def serial32(data): 197 | out = array.array('B') 198 | out += serial16((data >> 16) & 0xFFFF) 199 | out += serial16(data & 0xFFFF) 200 | return out 201 | 202 | def serial32le(data): 203 | out = array.array('B') 204 | out += serial16le(data & 0xFFFF) 205 | out += serial16le((data >> 16) & 0xFFFF) 206 | return out 207 | 208 | def crc(initial, packet): 209 | for byte in packet: 210 | initial = ((initial >> 8) & 0xFFFF) ^ crcTable[(initial ^ byte) & 0xFF] 211 | return ~initial & 0xFFFF 212 | 213 | def escape(packet): 214 | out = array.array('B') 215 | for byte in packet: 216 | if byte == 0x7e: 217 | out.append(0x7d) 218 | out.append(0x5e) 219 | elif byte == 0x7d: 220 | out.append(0x7d) 221 | out.append(0x5d) 222 | else: 223 | out.append(byte) 224 | return out 225 | 226 | def unescape(packet): 227 | escape = False 228 | out = array.array('B') 229 | for byte in packet: 230 | if escape: 231 | if byte == 0x5e: 232 | out.append(0x7e) 233 | elif byte == 0x5d: 234 | out.append(0x7d) 235 | else: 236 | print "Fatal error unescaping buffer!" 237 | return None 238 | escape = False 239 | else: 240 | if byte == 0x7d: 241 | escape = True 242 | else: 243 | out.append(byte) 244 | if len(out) == 0: 245 | return None 246 | return out 247 | 248 | def sendPacket(tty, packet): 249 | c = crc( 0xffff, packet ) 250 | out = array.array('B',[0x7e]) + escape(packet + serial16le(c)) + array.array('B',[0x7e]) 251 | if VERBOSE: 252 | print "SENDING: ", " ".join("%02x" % b for b in out) 253 | tty.write(out) 254 | return True 255 | 256 | def readPacket(tty, timeout, expect_packet = -1, expect_no_response = False): 257 | while True: 258 | buf = array.array('B') 259 | end = start = time.clock() 260 | 261 | while (end-start) <= timeout: 262 | if tty.inWaiting() > 0: 263 | curr = ord(tty.read(1)) 264 | if len(buf) == 0: 265 | if curr != 0x7e: 266 | return None 267 | buf.append(curr) 268 | if (curr == 0x7e) and (len(buf) > 1): 269 | break; 270 | end = time.clock() 271 | if len(buf) > 0: 272 | buf = buf [1:-1] 273 | buf = unescape(buf) 274 | 275 | if buf != None: 276 | if (buf[0] == 0x0e) and (expect_packet != buf[0]): 277 | if not expect_no_response: 278 | print "\tLOG: ", buf[1:-2].tostring().strip() 279 | continue 280 | #return None 281 | elif (buf[0] == 0x0d) and (expect_packet != buf[0]): 282 | if not expect_no_response: 283 | print "\tERROR: 0x%08x:"%struct.unpack(" 0): 291 | if (len(buf) < 1) or (buf[0] != expect_packet): 292 | if buf[0] != 3: 293 | print "Invalid Response!!!: ", buf, expect_packet 294 | return False 295 | nack = struct.unpack(">H",buf[1:3])[0] 296 | if nack > len(nack_res)-1: 297 | nack = len(nack_res)-1 298 | print "ERROR: ", nack_res[nack] 299 | return None 300 | 301 | if VERBOSE: 302 | print "RECEIVED: ", " ".join("%02x" % b for b in buf) 303 | break 304 | return buf[:-2] 305 | 306 | ########################### PBL STAGE ################################## 307 | ########################### PBL STAGE ################################## 308 | ########################### PBL STAGE ################################## 309 | ########################### PBL STAGE ################################## 310 | ########################### PBL STAGE ################################## 311 | ########################### PBL STAGE ################################## 312 | ########################### PBL STAGE ################################## 313 | 314 | def isStagePBL(tty): 315 | return doNoOp(tty) 316 | 317 | def doNoOp(tty): 318 | if not sendPacket( tty, PACKET_NO_OP): 319 | print "Failed No OP" 320 | return False 321 | 322 | response = readPacket(tty, 2.0, PACKET_ACK[0], expect_no_response = True) 323 | if None == response: 324 | return False 325 | return True 326 | 327 | ########################### SBL STAGE ################################## 328 | ########################### SBL STAGE ################################## 329 | ########################### SBL STAGE ################################## 330 | ########################### SBL STAGE ################################## 331 | ########################### SBL STAGE ################################## 332 | ########################### SBL STAGE ################################## 333 | ########################### SBL STAGE ################################## 334 | ########################### SBL STAGE ################################## 335 | 336 | def writeChunk_SBL(tty, address, chunk, sentPackets): 337 | if not sendPacket( tty, PACKET_WRITE_CHUNK_SBL + serial32le(address) + chunk): 338 | print "Failed to send chunk" 339 | return False 340 | 341 | sentPackets["%08x"%address] = 1 342 | 343 | acktimeout = 10.0 344 | response = readPacket(tty, acktimeout, PACKET_WRITE_CHUNK_SBL[0]+1, True) 345 | while response != None: 346 | if len(response) != 5: 347 | print "Invalid Response: ", response, "\n" 348 | return (False, sentPackets) 349 | ackpacket = "%02x%02x%02x%02x"%(response[4],response[3],response[2],response[1]) 350 | del sentPackets[ackpacket] 351 | if VERBOSE: 352 | print "Response: ACK 0x%s (outstanding: %d)"%(ackpacket, len(sentPackets)) 353 | 354 | if len(sentPackets) == 0: 355 | acktimeout = 0.0001 356 | response = readPacket(tty, acktimeout, PACKET_WRITE_CHUNK_SBL[0]+1, True) 357 | 358 | return (True, sentPackets) 359 | 360 | def uploadFile_SBL(tty, image): 361 | address, filename = image 362 | data = array.array('B') 363 | print "Uploading file2 '%s' to addr 0x%x..."%(filename, address) 364 | try: 365 | with open(filename, "rb") as f: 366 | while True: 367 | try: data.fromfile(f, 2000) 368 | except EOFError: break 369 | except: 370 | print "File not found %s"%filename 371 | return False 372 | sentPackets = {} 373 | while len(data) > 0: 374 | chunk = data[:CHUNK_SIZE] 375 | data = data[CHUNK_SIZE:] 376 | 377 | if VERBOSE: 378 | print "Writing %d bytes to 0x%x; %d bytes left."%(len(chunk), address, len(data)) 379 | (res, sentPackets) = writeChunk_SBL(tty, address, chunk, sentPackets) 380 | if not res: 381 | print "Upload failed" 382 | return False 383 | address += len(chunk) 384 | 385 | while len(sentPackets) > 0: 386 | response = readPacket( tty, 5.0, PACKET_WRITE_CHUNK2[0]+1 ) 387 | if None == response: 388 | print "Failed to receive ACK for %d packets"%len(sentPackets) 389 | for packet in sentPackets.keys(): 390 | print "Outstanding: 0x%s"%packet 391 | return False 392 | if len(response) != 5: 393 | print "Invalid Response: ", response 394 | return False 395 | ackpacket = "%02x%02x%02x%02x"%(response[4],response[3],response[2],response[1]) 396 | del sentPackets[ackpacket] 397 | if VERBOSE: 398 | print "Response: ACK 0x%x (outstanding: %d)"%(ackpacket, len(sentPackets)) 399 | 400 | return True 401 | 402 | def doMagic(tty): 403 | print "Sending MAGIC ..." 404 | if not sendPacket( tty, PACKET_MAGIC): 405 | print "Failed MAGIC"; 406 | return False 407 | 408 | response = readPacket( tty, 2, PACKET_MAGIC[0]+1 ) 409 | if None == response: 410 | return False 411 | 412 | if len(response) > 35: 413 | s = response[1:33].tostring() 414 | if s == "QCOM fast download protocol targ": 415 | print "%s:"%s 416 | print "\tVersion: %d"%response[33] 417 | print "\tCompatible version %d"%response[34] 418 | bs = struct.unpack('= 2) and (response[1] == 0): 446 | return True 447 | 448 | return False 449 | 450 | def doCloseFlush(tty): 451 | print "Sending CloseFlush..." 452 | if not sendPacket( tty, PACKET_CLOSE_FLUSH): 453 | print "Failed CloseFlush" 454 | return False 455 | 456 | response = readPacket(tty, 2.0, PACKET_CLOSE_FLUSH[0]+1) 457 | if None == response: 458 | return False 459 | 460 | return True 461 | 462 | def doSecureMode(tty): 463 | print "Sending secureMode..." 464 | if not sendPacket( tty, PACKET_SECURE_MODE): 465 | print "Failed secureMode" 466 | return False 467 | 468 | response = readPacket(tty, 2.0, PACKET_SECURE_MODE[0]+1) 469 | if None == response: 470 | return False 471 | 472 | return True 473 | 474 | def doReset_SBL(tty): 475 | print "Sending SBL Reset..." 476 | if not sendPacket( tty, PACKET_RESET_SBL): 477 | print "Failed Reset\n"; 478 | return False 479 | 480 | response = readPacket(tty, 2.0, PACKET_RESET_SBL[0]+1) 481 | if None == response: 482 | return False 483 | 484 | return True 485 | 486 | def doReadQfuse(tty): 487 | print "Sending read Qfuse..." 488 | if not sendPacket( tty, PACKET_QFUSE_READ + serial32(0x700438) + serial32(0x1)): 489 | print "Failed read qfuse\n"; 490 | return False 491 | 492 | response = readPacket(tty, 2.0, PACKET_QFUSE_READ[0]+1) 493 | if None == response: 494 | return False 495 | 496 | return False 497 | 498 | def doStage_SBL(tty,images): 499 | if doMagic(tty): 500 | #if doReadQfuse(tty): 501 | if doSecureMode(tty): 502 | if doOpenMulti(tty): 503 | for image in images: 504 | if not uploadFile_SBL( tty, image ): 505 | return False 506 | return doCloseFlush(tty); 507 | return False 508 | 509 | 510 | ######################### 511 | ######################### 512 | ######################### 513 | ######################### 514 | ######################### 515 | ######################### 516 | ######################### 517 | 518 | def ParsePTfile(filename, pt_flash): 519 | try: 520 | f = open(filename) 521 | except: 522 | print "File not found %s"%filename 523 | return None 524 | 525 | path = os.path.dirname(os.path.abspath(filename)) 526 | data = map(lambda x: map(lambda y: y.strip(),x.split(":")), f.readlines()[1:]) 527 | file_s = set(map(lambda x: x[1], data)) 528 | data = dict([d[1], [int(d[0],16),int(d[2])]] for d in data) 529 | if pt_flash: 530 | need_s = set(BOOT_PARTITIONS + (PT_PARTITION,)) 531 | else: 532 | need_s = set(BOOT_PARTITIONS) 533 | if not need_s.issubset(file_s): 534 | print "Not all partitions present: ", need_s - (need_s & file_s) 535 | return None 536 | 537 | images = [] 538 | for p in need_s: 539 | try: 540 | fn = path + '/' + p +'.img' 541 | if os.path.getsize(fn) > data[p][1]: 542 | print "File size %s bigger than partition"%fn 543 | return None 544 | except: 545 | print "Could not open file %s"%fn 546 | return None 547 | images.append([data[p][0], fn]) 548 | images.sort() 549 | f.close() 550 | return images 551 | 552 | def main(): 553 | parser = argparse.ArgumentParser(description='Qualcomm DLOAD mode images upload utility.') 554 | parser.add_argument('-tty','--ttyPort', type=str, help='Optional ttyPort', default="") 555 | parser.add_argument('-ptf', type=str, help='File with partitions addresees', default="") 556 | parser.add_argument('-pt','--need-partition-table-flash', action="store_true", help='If you need to flash partition table first') 557 | parser.add_argument("-v", "--verbose", action="store_true") 558 | 559 | args = parser.parse_args() 560 | 561 | tty = None 562 | images = None 563 | 564 | print "QDLoad stage 2 utility version %s (c) VBlack 2014, ported by alex-kas"%V 565 | 566 | global VERBOSE 567 | 568 | if args.verbose: 569 | VERBOSE = True 570 | if args.ptf != "": 571 | images = ParsePTfile(args.ptf, args.need_partition_table_flash) 572 | if None == images: 573 | return False 574 | 575 | tty = openTTY(args.ttyPort) 576 | if tty != None: 577 | if VERBOSE: 578 | print tty.getPort() 579 | if not isStagePBL(tty): 580 | if None != images: 581 | res = doStage_SBL(tty, images) 582 | doReset_SBL(tty) 583 | closeTTY(tty) 584 | tty = None 585 | print "here" 586 | if res: 587 | print "Done" 588 | return True 589 | else: 590 | print "No images specified, nothing to do" 591 | return True 592 | else: 593 | print "The device seems to be in stage 1 yet" 594 | return True 595 | 596 | print "Done, with errors!!!" 597 | 598 | if tty != None: 599 | closeTTY(tty) 600 | return False 601 | 602 | if __name__ == "__main__": 603 | #Verify python version is > 2.6 and < 3.0 604 | python_version = sys.version_info 605 | if python_version[0] != 2 or python_version[1] < 6: 606 | print("Python version 2.6 or 2.7 required!") 607 | print("you can download Python 2.6.x or 2.7.x here:") 608 | print("http://www.python.org/download/releases/") 609 | exit() 610 | 611 | # check whether pyserial 2.6 is installed. 612 | try: 613 | import serial 614 | import serial.tools.list_ports 615 | except ImportError: 616 | print("Please install pyserial 2.6 from here") 617 | print("https://pypi.python.org/pypi/pyserial") 618 | exit() 619 | 620 | main() 621 | -------------------------------------------------------------------------------- /9008/tz.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/9008/tz.img -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## NEC Terrain 2 | 3 | _As the name of the project suggests all the resources here are devoted to the NEC Terrain mobile phone. As such all 4 | the resources here are specific to this phone (even though theoretically applicable to another one). Moreover, various subjective statements reflect my **personal** opinion._ 5 | 6 | ### For inpatient - *just want it rooted!* 7 | 8 | Read [here](fastroot.md) 9 | 10 | [Здесь](fastroot_ru.md) написано кратко по-русски. 11 | 12 | ### About the phone 13 | 14 | You can read [here](aboutnecterrainphone.md) about the phone, pros and cons including known (serious) bugs 15 | 16 | ### For those who wants freedom 17 | 18 | 1. [General theory](general-th.md) - is a worth reading text which explains what is rooting, nand-lock, bootloader unlocking, and why these are different and sometimes disconnected things. Also many terms are explained there. 19 | 2. [Exploit](exploit-th.md) - explains the theory of how the NEC Terrain is exploited 20 | 3. [Pre-requisits](exploit-pre.md) - lists mandatory pre-requisits to exploit the NEC Terrain 21 | 4. [New Recovery](recovery-howto.md) - desciption of the new recovery image and a step-by-step instruction to install one 22 | 5. [New Boot](boot-howto.md) - description of the new boot image, a step-by-step instruction to install one 23 | 6. [Re-partitioning](repart-howto.md) - a step-by-step instruction to re-partition the internal memory 24 | 7. [System modification](system-howto.md) - several useful howto-s on system modification 25 | 8. [Troubleshooting](ts.md) - issues 26 | 27 | ### Bloatware or not bloatware? 28 | 29 | [Here](system/README.md) are the lists of apps which can be disabled and why, and which *cannot* be disabled and *why*. 30 | -------------------------------------------------------------------------------- /aboutnecterrainphone.md: -------------------------------------------------------------------------------- 1 | ### Specifications and goods 2 | 3 | To be more precise we are talking about the following phone (the info from the `about` menu inside the phone): 4 | * Model number: NE-201A1A 5 | * Android version: 4.0.4 6 | * Baseband version: N126400001 7 | * Kernel version: 3.0.8 ncmc@ncmc #2 SMP PREEMPT Thu Sep 26 17:01:21 IST 2013 8 | * Build number: 126460101 9 | 10 | and the full specifications can be found [here](http://www.gsmarena.com/nec_terrain-5553.php). 11 | 12 | In short, this is a heavily protected phone, all-proof (water, dust, salt, ...) with QWERTY physical keyboard which is also water-proof. You can type under the rain. It is reasonably fast: 1.5GHz dual-core CPU and it even has 1GB of RAM. The stock configuration has Android 4.0.4. Its internal memory is 8GB. Seems like a unique combination in the world of all phones. 13 | 14 | In fact the king property is the physical keyboard. If someone wonders why: the physics of a touch screen is such that its functionality is almost absolutely screwed up in a presence of water-drops. Under the rain or a wet snow, or if your fingers are wet. You are just unable to operate a phone w/o a keyboard in such conditions. 15 | 16 | Leaving the keyboard aside, this phone is comparable to Samsung Galaxy S4 Active or even outperformed by Casio Commando 4G LTE, Samsung Galaxy S5 Active and Samsung Galaxy S6 Active. However, my life-style demands the physical keys to be. 17 | 18 | ### Odds 19 | 20 | This phone has several serious odds: 21 | 22 | * It is discontinued. No updates are expected even though the phone itself is capable for KitKat at least 23 | * Its partition scheme is as awful as that: 24 | * 800MiB for programs installed by you. Practically nothing, just updates to the system apps get it all immediately 25 | * 4.3GiB for your files, like photos, video, but *not* programs 26 | * Tethering cannot be enabled 27 | * A bug (one so far) was found which brings the phone to reboot if a program needs to read big set of data files 28 | 29 | The less severe problem is the big amount of bloatware. 30 | -------------------------------------------------------------------------------- /boot-howto.md: -------------------------------------------------------------------------------- 1 | *You can find [here](recovery-howto.md) how to install the new recovery.* 2 | 3 | --- 4 | 5 | ### Placing new boot image 6 | 7 | * **boot/** - folder: the images are there 8 | 9 | To install a new boot into its proper place, i.e. boot partition, you download from the `boot/` folder here to some place on your pc: 10 | * `adbb.sh (adbb.bat for windows)` 11 | * `build.prop` 12 | * one of the the `.bin` images. **IMPORTANT:** whatever image you download you **must** save it under the name `kas.boot.bin` locally on your pc. 13 | 14 | In linux check that `adbb.sh` has `755` permissions. To be sure simply issue from inside the directory where you have downloaded the files 15 | ``` 16 | chmod 755 adbb.sh 17 | ``` 18 | Your phone must be booted normally. The `adb` daemon must be started on your pc. To be sure in the latter issue, for instance 19 | ``` 20 | sudo adb devices 21 | (adb start-server [for windows]) 22 | ``` 23 | **The microsd-card must be __in__ the phone.** 24 | 25 | 26 | Run on your pc (you should be inside the directory where you downloaded the files) 27 | ``` 28 | ./adbb.sh 29 | (adbr.bat [for windows]) 30 | ``` 31 | To copy files to a proper location on your sdcard (folder named `brnects0.715`). 32 | 33 | **The new recovery must be installed!** 34 | 35 | Now restart your phone into recovery typing on your pc 36 | ``` 37 | adb reboot recovery 38 | ``` 39 | Wait at least the 'NEC' logo. After the 'NEC' logo this recovery shows **NOTHING**. Now go into shell 40 | ``` 41 | adb shell 42 | ``` 43 | and do inside the shell 44 | ``` 45 | cd /rbin 46 | ./flash_boot.sh 47 | ``` 48 | It will copy the current boot image to sdcard as `brnects0.715/boot.current.bin` and flash `kas.boot.bin` into place. On top of this it places `build.prop` file found in `brnects0.715/` on sdcard into `/system`. 49 | Now exit the shell 50 | ``` 51 | exit 52 | ``` 53 | to come back to your pc and reboot the phone 54 | ``` 55 | adb reboot 56 | ``` 57 | **DONE!** 58 | 59 | --- 60 | 61 | *You should proceed [here](repart-howto.md) for the next exercise: repartitioning.* 62 | -------------------------------------------------------------------------------- /boot/README.md: -------------------------------------------------------------------------------- 1 | ### NEC Terrain boot image 2 | 3 | This boot image is made of a kernel extracted from the stock recovery and a modified original ramdisk from the boot image. This kernel does not 4 | enforce a write-protection above linux permissions and privileges. 5 | 6 | * `kas.boot.bin` - the boot image, latest version 7 | * `kas.boot.bin-vvv` - the boot image, version vvv 8 | * `kas.boot.bin-vvv-ext2` - the _experimental_ boot image, version vvv, which mounts **both** `system` and `userdata` partitions as **ext2** They **MUST** be reformatted as such in the recovery! This is a workaround for random reboots. Read http://forum.xda-developers.com/showpost.php?p=62673224&postcount=25 9 | * `build.prop` should be placed in the `/system` 10 | 11 | * `adbb.sh (adbb.bat for windows)` - script to place the boot image and build.prop in a special folder on the sd-card (`brnects0.715`) so that a script in recovery `/rbin/flash_boot.sh` can see them and write in place. 12 | 13 | #### Changelog for the *image*: 14 | 15 | * **version 0.9-ext2** (`kas.boot.bin-0.9-ext2`) 16 | * mounts **both** `system` and `userdata` partitions as **ext2** They **MUST** be reformatted as such in the recovery! This is a workaround for random reboots. Read http://forum.xda-developers.com/showpost.php?p=62673224&postcount=25 17 | 18 | * **version 0.9** (`kas.boot.bin-0.9`) 19 | * service flash_recovery is commented out to prevent a possible FOTA action 20 | * service pmeval is commented out as its binary does not exist 21 | * service ms-monitor is commented out as its binary does not exist 22 | * service immvibed is commented out as its binary does not exist 23 | * insertion of the module adux1001_driver.ko is commented out as it does not exist 24 | * insertion of the module tspdrv.ko is commented out as it does not exist 25 | 26 | * **version 0.8** (`kas.boot.bin-0.8`, the very first!) 27 | * kernel from the stock recovery 28 | * ramdisk/default.prop: ro.secure=0, no obvious use 29 | * ramdisk/init.rc 30 | * All mtd@xxx attempts removed 31 | * e2fsck enforced on `/system` (partition 12) as it can be writable now 32 | * `noauto_da_alloc` removed on mounting /data (partition 13) 33 | * All ext4 partitions are mounted with `noatime,nodiratime,discard` instead of `relatime` 34 | * Service `debuggerd` disabled 35 | * Service `bootanim` (bootanimation) disaled 36 | * ramdisk/init.target.rc: `/tombstones` (partition 17) is now mounted with `noatime,nodiratime,discard` instead of `relatime` 37 | * /system/build.prop 38 | * att.service.entitlement=false for tethering 39 | * service.adb.root=1 added, no obvious use 40 | * **negative**: setting ro.debuggable=1 in ramdisk/default.prop leads to starting 2 additional services from ramdisk/init.rc **discarded** 41 | * **negative**: setting ro.build.type=eng in /system/build.prop leads to flashing red border during the phone operation. **discarded** 42 | 43 | * **version -1** (stock) 44 | -------------------------------------------------------------------------------- /boot/adbb.bat: -------------------------------------------------------------------------------- 1 | adb shell "mkdir /mnt/external_sd/brnects0.715" 2 | adb push kas.boot.bin /mnt/external_sd/brnects0.715 3 | adb push build.prop /mnt/external_sd/brnects0.715 4 | -------------------------------------------------------------------------------- /boot/adbb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | adb shell "mkdir /mnt/external_sd/brnects0.715" 3 | adb push kas.boot.bin /mnt/external_sd/brnects0.715 4 | adb push build.prop /mnt/external_sd/brnects0.715 5 | exit 0 6 | -------------------------------------------------------------------------------- /boot/build.prop: -------------------------------------------------------------------------------- 1 | # begin build properties 2 | # autogenerated by buildinfo.sh 3 | ro.build.id=126460101 4 | ro.build.display.id=126460101 5 | ro.build.version.incremental=eng.20130926.164140 6 | ro.build.version.sdk=15 7 | ro.build.version.codename=REL 8 | ro.build.version.release=4.0.4 9 | ro.build.date=Thu Sep 26 16:43:43 IST 2013 10 | ro.build.date.utc=1380194023 11 | ro.build.type=user 12 | # KAS ro.build.type=eng 13 | ro.build.user=NCmobile 14 | ro.build.host=NCmobile 15 | ro.build.tags=release-keys 16 | ro.product.model=NEC-NE-201A1A 17 | ro.product.brand=NEC 18 | ro.product.name=NEC-NE-201A1A 19 | ro.product.device=NE-201 20 | ro.product.board=NE-201 21 | ro.product.cpu.abi=armeabi-v7a 22 | ro.build.internal.id=12.64.6.01.01_RBY00302_130926_ATT 23 | ro.product.cpu.abi2=armeabi 24 | ro.product.manufacturer=NEC 25 | ro.product.locale.language=en 26 | ro.product.locale.region=US 27 | ro.wifi.channels= 28 | ro.board.platform=msm8960 29 | # ro.build.product is obsolete; use ro.product.device 30 | ro.build.product=NE-201A1A 31 | # Do not try to parse ro.build.description or .fingerprint 32 | ro.build.description=msm8960-user 4.0.4 126460101 eng.20130926.164140 release-keys 33 | ro.build.fingerprint=NEC/NEC-NE-201A1A/NE-201:4.0.4/126460101/eng.20130926.164140:user/release-keys 34 | ro.build.characteristics=default 35 | ro.modemver=N126400001 36 | ro.production.version=0017 37 | # end build properties 38 | sys.auto_connect.attwifi = true 39 | sys.auto_connect.Z736563757265 = true 40 | # KAS att.service.entitlement = true 41 | att.service.entitlement = false 42 | enable.tethering.usb = false 43 | enable.tethering.wifi = false 44 | ro.monkey=0 45 | ro.url.googlelegal=http://www.google.com/intl/%s/mobile/android/basic/phone-legal.html 46 | # 47 | # system.prop for surf 48 | # 49 | 50 | rild.libpath=/system/lib/libril-qc-qmi-1.so 51 | rild.libargs=-d /dev/smd0 52 | persist.rild.nitz_plmn= 53 | persist.rild.nitz_long_ons_0= 54 | persist.rild.nitz_long_ons_1= 55 | persist.rild.nitz_long_ons_2= 56 | persist.rild.nitz_long_ons_3= 57 | persist.rild.nitz_short_ons_0= 58 | persist.rild.nitz_short_ons_1= 59 | persist.rild.nitz_short_ons_2= 60 | persist.rild.nitz_short_ons_3= 61 | ril.subscription.types=NV,RUIM 62 | DEVICE_PROVISIONED=1 63 | debug.sf.hw=1 64 | debug.egl.hw=1 65 | debug.composition.type=dyn 66 | ro.sf.compbypass.enable=1 67 | dalvik.vm.heapsize=36m 68 | dev.pm.dyn_samplingrate=1 69 | debug.enable.wl_log=1 70 | 71 | # 72 | # system props for the cne module 73 | # 74 | persist.cne.UseCne=vendor 75 | persist.cne.UseSwim=false 76 | persist.cne.bat.range.low.med=30 77 | persist.cne.bat.range.med.high=60 78 | persist.cne.loc.policy.op=/system/etc/OperatorPolicy.xml 79 | persist.cne.loc.policy.user=/system/etc/UserPolicy.xml 80 | persist.cne.bwbased.rat.sel=false 81 | persist.cne.snsr.based.rat.mgt=false 82 | persist.cne.bat.based.rat.mgt=false 83 | persist.cne.rat.acq.time.out=30000 84 | persist.cne.rat.acq.retry.tout=0 85 | persist.cne.nsrm.mode=false 86 | 87 | ro.hdmi.enable=true 88 | lpa.decode=true 89 | lpa.use-stagefright=true 90 | 91 | #system propert for wifi 92 | 93 | sys.auto_connect.attwifi = true 94 | sys.auto_connect.Z736563757265 = true 95 | 96 | #system props for the MM modules 97 | 98 | media.stagefright.enable-player=true 99 | media.stagefright.enable-http=true 100 | media.stagefright.enable-aac=true 101 | media.stagefright.enable-qcp=true 102 | media.stagefright.enable-fma2dp=true 103 | media.stagefright.enable-scan=true 104 | # 105 | # system props for the data modules 106 | # 107 | ro.use_data_netmgrd=true 108 | 109 | #system props for time-services 110 | persist.timed.enable=true 111 | 112 | # System props for audio 113 | persist.audio.fluence.mode=endfire 114 | persist.audio.vr.enable=false 115 | persist.audio.handset.mic=digital 116 | 117 | # System prop to select audio resampler quality 118 | af.resampler.quality=255 119 | 120 | # 121 | # system prop for opengles version 122 | # 123 | # 131072 is decimal for 0x20000 to report version 2 124 | ro.opengles.version=131072 125 | 126 | # 127 | # system prop for Bluetooth Dialup Networking 128 | # 129 | ro.qualcomm.bluetooth.dun=false 130 | 131 | # 132 | # system prop for Bluetooth SAP Profile 133 | # 134 | ro.qualcomm.bluetooth.sap=false 135 | 136 | # system prop for Bluetooth FTP profile 137 | ro.qualcomm.bluetooth.ftp=false 138 | # 139 | # system property for Bluetooth Handsfree Profile version 140 | # 141 | ro.bluetooth.hfp.ver=1.6 142 | # 143 | #system prop for Bluetooth hci transport 144 | ro.qualcomm.bt.hci_transport=smd 145 | # 146 | # system prop for requesting Master role in incoming Bluetooth connection. 147 | # 148 | ro.bluetooth.request.master=true 149 | # 150 | # system prop for Bluetooth Auto connect for remote initated connections 151 | # 152 | ro.bluetooth.remote.autoconnect=true 153 | # system property for Bluetooth discoverability time out in seconds 154 | # 0: Always discoverable 155 | #debug.bt.discoverable_time=0 156 | 157 | #system prop for switching gps driver to qmi 158 | persist.gps.qmienabled=true 159 | 160 | # System property for cabl 161 | ro.qualcomm.cabl=1 162 | 163 | # 164 | # System prop for sending transmit power request to RIL during WiFi hotspot on/off 165 | # 166 | ro.ril.transmitpower=true 167 | 168 | # 169 | #Simulate sdcard on /data/media 170 | # 171 | persist.fuse_sdcard=false 172 | ro.hwui.text_cache_width=2048 173 | 174 | # 20120423 NCMC addition of A-PF AD12-1st-PR1-01822 AD12-1st-PR1-01854 start 175 | power.webview.Test=false 176 | # 20120423 NCMC addition of A-PF AD12-1st-PR1-01822 AD12-1st-PR1-01854 end 177 | 178 | #To verify APTN not opening multiple sockets 179 | net.early.sockets=0 180 | 181 | #system prop to not to power down the SIM when Airplane Mode is ON 182 | persist.radio.apm_sim_not_pwdn=1 183 | 184 | # 185 | # ADDITIONAL_BUILD_PROPERTIES 186 | # 187 | ro.setupwizard.mode=REQUIRED 188 | ro.com.google.gmsversion=4.0_r8 189 | keyguard.no_require_sim=true 190 | ro.com.android.dataroaming=false 191 | ro.com.android.dateformat=MM-dd-yyyy 192 | ro.config.ringtone=ATT_Firefly.mp3 193 | ro.config.notification_sound=Antimony.ogg 194 | ro.config.alarm_alert=Alarm_Beep_02.ogg 195 | ro.vendor.extension_library=/system/lib/libqc-opt.so 196 | ro.com.google.clientidbase=android-nec 197 | ro.com.google.clientidbase.yt=android-nec 198 | ro.com.google.clientidbase.gmm=android-nec 199 | ro.com.google.clientidbase.ms=android-att-us 200 | ro.com.google.clientidbase.am=android-att-us 201 | dalvik.vm.heapstartsize=8m 202 | dalvik.vm.heapgrowthlimit=64m 203 | dalvik.vm.heapsize=256m 204 | drm.service.enabled=true 205 | ro.sf.lcd_density=213 206 | net.bt.name=Android 207 | dalvik.vm.stack-trace-file=/data/anr/traces.txt 208 | 209 | # KAS add 210 | service.adb.root=1 211 | -------------------------------------------------------------------------------- /boot/kas.boot.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/boot/kas.boot.bin -------------------------------------------------------------------------------- /boot/kas.boot.bin-0.8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/boot/kas.boot.bin-0.8 -------------------------------------------------------------------------------- /boot/kas.boot.bin-0.9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/boot/kas.boot.bin-0.9 -------------------------------------------------------------------------------- /boot/kas.boot.bin-0.9-ext2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/boot/kas.boot.bin-0.9-ext2 -------------------------------------------------------------------------------- /exploit-pre.md: -------------------------------------------------------------------------------- 1 | *You can read [here](exploit-th.md) a theoretical explanation on how this phone is exploited and used terms.* 2 | 3 | --- 4 | 5 | ### Exploit **mandatory** pre-requisits 6 | 7 | #### Phone 8 | 9 | You need a NEC Terrain phone. 10 | 11 | #### USB Debugging 12 | 13 | The option `USB Debugging` found in *Settings->Developer options* must be enabled. 14 | 15 | #### Desktop/laptop with `adb` and a USB cable 16 | 17 | You must have `adb` installed on your pc and have a USB cable to connect your phone with your pc. 18 | 19 | In linux **NO** driver needed. 20 | 21 | *If unfortunately you use windows you must arrange also drivers. Driver (working in win7pro_x64) and `adb.exe` can be found in `system/` folder in this repository.* 22 | 23 | #### Stock GPT. *THE MOST CRUCIAL PART* 24 | 25 | It is extremely crucial for the scripts to work as expected that your stock GPT table is **EXACTLY** like that 26 | ``` 27 | Number Start (sector) End (sector) Size Code Name 28 | 1 32768 294911 128.0 MiB 0700 modem 29 | 2 294912 425983 64.0 MiB FFFF flashbackup 30 | 3 425984 557055 64.0 MiB FFFF fatallog 31 | 4 589824 590335 256.0 KiB FFFF sbl1 32 | 5 590336 590847 256.0 KiB FFFF sbl2 33 | 6 590848 594943 2.0 MiB FFFF sbl3 34 | 7 594944 595967 512.0 KiB FFFF aboot 35 | 8 595968 596991 512.0 KiB FFFF rpm 36 | 9 596992 617471 10.0 MiB FFFF boot 37 | 10 617472 618495 512.0 KiB FFFF tz 38 | 11 618496 638975 10.0 MiB FFFF recovery 39 | 12 638976 2801663 1.0 GiB 8300 system 40 | 13 2818048 4456447 800.0 MiB 8300 userdata 41 | 14 4456448 13565951 4.3 GiB FFFF GROW 42 | 15 13565952 13582335 8.0 MiB 8300 persist 43 | 16 13582336 14319615 360.0 MiB 8300 cache 44 | 17 14319616 14462975 70.0 MiB 8300 tombstones 45 | 18 14462976 14465023 1024.0 KiB FFFF misc 46 | 19 14465024 14465025 1024 bytes FFFF pad 47 | 20 14465026 14465041 8.0 KiB FFFF ssd 48 | 21 14465042 14471185 3.0 MiB FFFF modemst1 49 | 22 14471186 14477329 3.0 MiB FFFF modemst2 50 | 23 14477330 14483473 3.0 MiB FFFF fsg 51 | 24 14483474 14483985 256.0 KiB FFFF sbl2_bkp 52 | 25 14483986 14488081 2.0 MiB FFFF sbl3_bkp 53 | 26 14488082 14489105 512.0 KiB FFFF aboot_bkp 54 | 27 14489106 14490129 512.0 KiB FFFF rpm_bkp 55 | 28 14490130 14491153 512.0 KiB FFFF tz_bkp 56 | 29 14491154 14511633 10.0 MiB FFFF recovery_bkp 57 | 30 14511634 14532113 10.0 MiB FFFF fota_config 58 | 31 14532114 14990865 224.0 MiB FFFF MM 59 | ``` 60 | The point of **MAIN CONCERN** is the gap between partitions 3 and 4. It must be there and the end of partition 3 and the beginning 61 | of partition 4 must be **EXACTLY** as above. 62 | 63 | "Stock" means the configuration before any possible use of the scripts from here or 64 | before using the **terroot** program or before any other means of altering. 65 | 66 | The script in `recovery/` directory here named [adbtestgpt.sh](recovery/adbtestgpt.sh) ([adbtestgpt.bat](recovery/adbtestgpt.bat) for windows) gets the GPT table from the phone and shows it 67 | for you. 68 | 69 | To use the script download from the `recovery/` folder here into one local directory 70 | * `run_root_shell` 71 | * `sgdisk` 72 | * `adbtestgpt.sh (adbtestgpt.bat for windows)` 73 | 74 | In linux check that `adbtestgpt.sh` has permissions 755. To be sure just issue on your pc inside the directory where all the stuff has been saved 75 | ``` 76 | chmod 755 adbtestgpt.sh 77 | ``` 78 | and run the script 79 | ``` 80 | ./adbtestgpt.sh 81 | (adbtestgpt.bat [for windows]) 82 | ``` 83 | **The script does not take decisions. It is you, who compares and decides what to do!** 84 | 85 | #### micro-SD card 86 | 87 | For the task of flashing new boot image and for the backup during the repartitioning you need a micro-SD card in the phone. It should 88 | have 12MiB free for the boot image, up to 5.2GiB free for the data backup (this is the maximum of partitions 89 | userdata (number 13) and GROW (number 14) together) 90 | and 500MiB free for a possible system 91 | backup. 92 | 93 | The card should be formatted as an mbr with a partition. 94 | 95 | In linux this means that the card is seen as 96 | ``` 97 | /dev/mmcblk0 98 | ``` 99 | and its partition as 100 | ``` 101 | /dev/mmcblk0p1 102 | ``` 103 | In simpler words, if you examine your SD card in `disks` utility on your pc you should see: 104 | ``` 105 | Partitioning: Master Boot Record 106 | Device: /dev/mmcblk0p1 107 | Contents: vfat 108 | ``` 109 | 110 | In windows this means that when you see the inserted sd-card and analyse its properties the corresponding window in the tab `Volumes` says 111 | ``` 112 | Partition style MBR 113 | ``` 114 | and shows one volume. 115 | 116 | The partition (volume) must be formatted as `vfat` 117 | 118 | #### Set? Ready? GO! 119 | 120 | --- 121 | 122 | *You should proceed [here](recovery-howto.md) for the main exercise: new recovery.* 123 | -------------------------------------------------------------------------------- /exploit-th.md: -------------------------------------------------------------------------------- 1 | *You can read [here](general-th.md) somewhat more explanatory text if you feel that this one is a bit too brief for you.* 2 | 3 | --- 4 | 5 | ### Exploiting NEC Terrain mobile 6 | 7 | #### Introduction and terroot 8 | 9 | The pre-story can be found in 10 | 11 | http://forum.xda-developers.com/showthread.php?t=2515602 12 | 13 | Many useful scripts, links and the unlocking app, **terroot**, can be found in 14 | 15 | https://github.com/x29a/nec_terrain_root 16 | 17 | The latter is an easily traceable app which implements the method presented here and outlined first in 18 | 19 | http://forum.xda-developers.com/showpost.php?p=61542922&postcount=186 (also few posts before and all way down) 20 | 21 | The bootable images used in **terroot** are from here as well. 22 | 23 | #### Exploit terminology 24 | 25 | * *boot* - normal boot via the image on the boot partition (number 9). The stock kernel in this image blocks read-write access to the vital system areas, i.e. system, boot, recovery, sbl1,2,3, aboot, rpm, tz partitions. 26 | You cannot write there even if you are root. You moreover cannot remount those partitions rw. The physical area of the internal memory where these partitions are is also write-protected by the kernel. 27 | * *recovery* - recovery boot (via *vol-down+power*) via the recovery partition (number 11). The kernel there turned out to be free of the write-blocks. 28 | * *system* (or *ROM*) - your actual operating system, all inside `/system` directory 29 | 30 | Each bootable image has kernel and the initramdisk to kick-off the system. In our story stock kernels in boot and recovery are different, clearly due to presence/absence of blockages but 31 | the config.gz (the file containing parameters with which the kernel was compiled) for both kernels is identical. 32 | 33 | In order to root the phone *permanently* we need to place the `su` binary inside `/system/bin` (or `/system/xbin`) and the goal is to open the latter directory for write. Since even root cannot do it, the new goal is to modify the boot 34 | image where all mountings happen. But re-flashing of an image is not possible. 35 | 36 | So, the goal is to flash a modified image to a new place and instruct the system about this. 37 | 38 | #### GPT 39 | 40 | * *GPT* - is the table which is located at the beginning of a disk and describes where on the disk each parition lies. A verification copy of the table is at the end of the disk. Those copies **must** match. Also some specific checksums inside these tables **must** be correct. 41 | 42 | Two facts turned out to be true in this phone: 43 | 44 | * Out of the sudden the gpt table itself is **not** protected from writing. 45 | * There are holes between partitions. 46 | * Those holes are **not** write-protected 47 | 48 | Therefore, we can try to modify the table and change the position of a bootable partition to be inside a writable hole. Then write the new image there and try to boot it. However ... 49 | 50 | #### Bootloader 51 | 52 | The bootloader is located in the partition 7 on this phone. It is named *aboot*. The main danger is that sometimes bootloaders refuse to boot wrong images. Wrong means those w/o security keys or with a wrong checksum or both. The images are "wrong" for the original phone system. However they are **perfect** for you. In an extreme case the bootloader can in principle soft-brick your phone. I.e. write internally some data which indicate the attempt to boot a wrong image and refuse any further booting. 53 | 54 | A detailed reverse-engineering of the boot locker showed however that it is just a joke. It exists, it checks certificates, hash, etc, but its logic is like that: 55 | ``` 56 | start booting of an image from boot or recovery 57 | if (some_special_byte is set to 1) boot whatever you have w/o verification 58 | else if (image is wrong) write some_special_byte as 1 AND boot what you have 59 | ``` 60 | Originally that `some_special_byte` is set to 0. So you see, the first time you give a wrong boot image the system checks it, understands that it is wrong, alters `some_special_byte` to 1 and boots your wrong image. Next boots, since `some_special_byte` is already set to 1 the wrong image is just booted even without verification. 61 | 62 | Good for us, less work. As long as you can flash a modified image. It seems that this `some_special_byte` is used for the warranty purposes to reject your phone just in case from the repair. 63 | 64 | #### The idea 65 | 66 | The idea is to make use of the facts that GPT can be altered and has non-write-protected holes. 67 | 68 | 1. The location of the `recovery` partitioin is remapped to such a hole. 69 | 2. A new better recovery image is written to this hole. 70 | 3. After this we should use this new recovery environment to alter the other parts of the system. Write new boot image for the normal boot or write new system programs like `su` in the proper place. 71 | 72 | Naturally these steps require at least a temporary root access and this luckily can be done thanks to `run_root_shell` binary (present in `recovery/` folder here) wich utilizes a hole in the kernel. 73 | 74 | Naturally, new `boot` is better to be equipped with the kernel from original recovery image, as the latter kernel has no security limitation. 75 | 76 | --- 77 | 78 | *You should read [here](exploit-pre.md) what are the strict requirements to implement the exploit.* 79 | -------------------------------------------------------------------------------- /fastroot.md: -------------------------------------------------------------------------------- 1 | ### Fast root guide for NEC Terrain 2 | 3 | For those not common with adb/linux/etc: 4 | * ALL commands are typed on your pc in terminal (`cmd` shell in windows) 5 | * One line - one command 6 | * You type (or copy) a command, press `enter`, wait the result and the new prompt 7 | * after a command execution you see its output, it should be positive or neutral. If you see somewhat like "file not found", "command not found", "cannot ...", etc this most likely inidcates a mistake in your command, absence of vital files, or other oddity 8 | * capital and literal letters are DIFFERENT 9 | * NO unneeded symbols (well in some places I put a second command, for windows; hope it is understandable, what is exactly meant there) 10 | 11 | #### Downloads 12 | 13 | You preferably download everything to one directory on your pc 14 | 15 | From folder `recovery/` in this repository: 16 | * `adbtestgpt.sh (adbtestgpt.bat for windows)` 17 | * `adbr.sh (adbr.bat for windows)` 18 | * `flash_recovery.sh` 19 | * `run_root_shell` 20 | * `sgdisk` 21 | * `kas.recovery.bin` 22 | 23 | From folder `boot/` in this repository: 24 | 25 | * `adbb.sh (adbb.bat for windows)` 26 | * `build.prop` 27 | * `kas.boot.bin` 28 | 29 | From folder `system/` in this repository: 30 | 31 | * `adbs.sh (adbs.bat for windows)` 32 | * `su` 33 | * `Superuser.apk` 34 | 35 | #### Micro-sd card 36 | 37 | You need a micro-sd card to be in the phone. It should have few gigabytes of space and be formatted as an mbr with a partition. 38 | 39 | In linux this means that the card is seen as 40 | ``` 41 | /dev/mmcblk0 42 | ``` 43 | and its partition as 44 | ``` 45 | /dev/mmcblk0p1 46 | ``` 47 | In simpler words, if you examine your SD card in `disks` utility on your pc you should see: 48 | ``` 49 | Partitioning: Master Boot Record 50 | Device: /dev/mmcblk0p1 51 | Contents: vfat 52 | ``` 53 | 54 | In windows this means that when you see the inserted sd-card and analyse its properties the corresponding window in the tab `Volumes` says 55 | ``` 56 | Partition style MBR 57 | ``` 58 | and shows one volume. 59 | 60 | The partition (volume) must be formatted as `vfat` 61 | 62 | #### Pre-test 63 | 64 | In linux check that `adbtestgpt.sh` has permissions 755. To be sure just issue on your pc inside the directory 65 | where all the stuff has been saved 66 | ``` 67 | chmod 755 adbtestgpt.sh 68 | ``` 69 | Now boot your phone normally, into its canonical stock boot configuration. Connect the usb cable. In linux **NO** driver needed. For windows, driver (working in win7pro_x64) and `adb.exe` can be found in `system/` folder in this repository, file `adbfb.tar.gz`. 70 | Also 'USB debugging' must be turned on in the phone. 71 | 72 | Start `adb` daemon for exmaple by 73 | ``` 74 | sudo adb devices 75 | (adb start-server [for windows]) 76 | ``` 77 | and run the script (you should be inside the folder where you have just downloaded the stuff) 78 | ``` 79 | ./adbtestgpt.sh 80 | (adbtestgpt.bat [for windows]) 81 | ``` 82 | You will see the partition table. The corenerstone is the gap between partitions 3 and 4 83 | ``` 84 | Number Start (sector) End (sector) Size Code Name 85 | 3 425984 557055 64.0 MiB FFFF fatallog 86 | 4 589824 590335 256.0 KiB FFFF sbl1 87 | ``` 88 | it should be **ABSOLUTELY EXACTLY** as written above (on a non-altered phone). 89 | 90 | **The script does not take decisions. It is you, who compares and decides what to do!** 91 | 92 | If you are happy, continue! 93 | 94 | #### New recovery 95 | 96 | In linux check that `adbr.sh` script has permissions `755`. To be sure just issue on your pc inside the directory where all the stuff has been saved 97 | ``` 98 | chmod 755 adbr.sh 99 | ``` 100 | Run the script 101 | ``` 102 | ./adbr.sh 103 | (adbr.bat [for windows]) 104 | ``` 105 | The very new recovery is ready to use! 106 | 107 | #### New boot 108 | 109 | **The new recovery MUST be installed!** 110 | 111 | In linux check that `adbb.sh` has `755` permissions. To be sure simply issue from inside the directory where you have downloaded the files 112 | ``` 113 | chmod 755 adbb.sh 114 | ``` 115 | **The microsd-card must be __in__ the phone.** 116 | 117 | Run on your pc 118 | ``` 119 | ./adbb.sh 120 | (adbb.bat [for windows]) 121 | ``` 122 | To copy files to a proper location on your sdcard (folder named `brnects0.715`). 123 | 124 | Now restart your phone into *recovery* typing on your pc 125 | ``` 126 | adb reboot recovery 127 | ``` 128 | Wait at least the 'NEC' logo. After the 'NEC' logo this recovery shows **NOTHING**. Now go into shell (we will continue typing on the pc, of course, but virtually we will be in the phone) 129 | ``` 130 | adb shell 131 | ``` 132 | and do inside the shell 133 | ``` 134 | cd /rbin 135 | ./flash_boot.sh 136 | ``` 137 | Now exit the shell 138 | ``` 139 | exit 140 | ``` 141 | to come back to your pc and reboot the phone 142 | ``` 143 | adb reboot 144 | ``` 145 | The very new boot image is here! 146 | 147 | #### Re-partitioning 148 | 149 | **The new recovery MUST be installed!** 150 | 151 | Sorry, no short instruction yet. 152 | 153 | #### Placing `su` and `Superuser.apk` 154 | 155 | **The new recovery MUST be installed!** 156 | 157 | In linux check that `adbs.sh` has `755` permissions. To be sure simply issue from inside the directory where you have downloaded the files 158 | ``` 159 | chmod 755 adbs.sh 160 | ``` 161 | Now restart your phone into *recovery* typing on your pc 162 | ``` 163 | adb reboot recovery 164 | ``` 165 | From the directory where you have downloaded the suepruser stuff do 166 | ``` 167 | ./adbs.sh 168 | (adbs.bat [for windows]) 169 | ``` 170 | Once done, reboot the phone by 171 | ``` 172 | adb reboot 173 | ``` 174 | After the reboot you will see "Android is upgrading" meaning it installs a new 'system' program Superuser.apk 175 | 176 | **DONE! Your phone is rooted!** 177 | -------------------------------------------------------------------------------- /fastroot_ru.md: -------------------------------------------------------------------------------- 1 | ### Краткая инструкция рутинга NEC Terrain 2 | 3 | Для незнакомых с adb/linux/и так далее: 4 | * ВСЕ команды набираются на компьютере в терминале (`cmd` оболочка в windows) 5 | * Одна строка - одна команда 6 | * каждая команда набирается - нажимается enter и ждется результат: новая строка с приглашением 7 | * после исполнения каждой команды на экране пишется, что она сдлелала, и это должно быть в общем нейтральная или положительная информация. Если вы видите что0то типа "file not found" ("файл не найден"), "command not found" ("команда не найдена"), "cannot ..." ("невозможно ...") и так далее, то вероятнее всего команда набрана с ошибкой или отсутствует необходимый файл, или неправильно что-то еще 8 | * большие и маленькие буквы РАЗЛИЧАЮТСЯ 9 | * случайнух знаков НЕТ (кроме тех мест, где я пишу вторую команду, для windows; надеюсь, там по смыслу понятно) 10 | 11 | #### Что загружать 12 | 13 | Предпочтительно загрузить все в одну директорию на Вашем компьютере 14 | 15 | Из папки `recovery/` здесь на github: 16 | * `adbtestgpt.sh (adbtestgpt.bat для windows)` 17 | * `adbr.sh (adbr.bat для windows)` 18 | * `flash_recovery.sh` 19 | * `run_root_shell` 20 | * `sgdisk` 21 | * `kas.recovery.bin` 22 | 23 | Из папки `boot/` здесь на github: 24 | 25 | * `adbb.sh (adbb.bat для windows)` 26 | * `build.prop` 27 | * `kas.boot.bin` 28 | 29 | Из папки `system/` здесь на github: 30 | 31 | * `adbs.sh (adbs.bat для windows)` 32 | * `su` 33 | * `Superuser.apk` 34 | 35 | #### Карта micro-sd 36 | 37 | Вам понадобится карта micro-sd в телефоне. На ней должно быть нсколько гигабайт свободного места 38 | и она должна быть отформатирована, как mbr с разделом. 39 | 40 | В linux это значит, что карта видна как 41 | ``` 42 | /dev/mmcblk0 43 | ``` 44 | а ее раздел как 45 | ``` 46 | /dev/mmcblk0p1 47 | ``` 48 | Еще проще, просматривая карту в программеy `disks` на своем компьтере Вы должны видеть: 49 | ``` 50 | Partitioning: Master Boot Record 51 | Device: /dev/mmcblk0p1 52 | Contents: vfat 53 | ``` 54 | 55 | В windows это значит, что просматривая свойства карты, в соответствующем окне, в закладке `Volumes` вы должны видеть: 56 | ``` 57 | Partition style MBR 58 | ``` 59 | и должен быть показан один 'volume'. 60 | 61 | Раздел (volume) должен быть отформатирован как `vfat` 62 | 63 | #### Пре-проверка 64 | 65 | В linux проверьте, что `adbtestgpt.sh` имеет код доступа 755. Чтобы быть уверенным в этом, просто выполните команду 66 | (будучи в директории, куда все сохранялось при загрузке) 67 | ``` 68 | chmod 755 adbtestgpt.sh 69 | ``` 70 | Включите телефон нормально, в стандартный режим. Подключите usb кабель. В linux никаких драйверов **НЕ** нужно. 71 | В случае windows, драйвер (работает в win7pro_x64) и `adb.exe` есть в папке `system/` здесь на github, файл `adbfb.tar.gz`. 72 | Также нужно включить в телефоне 'USB debugging'. 73 | 74 | Запустите `adb` демон, например вот так 75 | ``` 76 | sudo adb devices 77 | (adb start-server [для windows]) 78 | ``` 79 | и запустите скрипт (вы должны быть в директории, куда все сохранялось) 80 | ``` 81 | ./adbtestgpt.sh 82 | (adbtestgpt.bat [для windows]) 83 | ``` 84 | Вы увидите таблицу разделов. Основополагающий момент - дырка межда разделами номер 3 и номер 4 85 | ``` 86 | Number Start (sector) End (sector) Size Code Name 87 | 3 425984 557055 64.0 MiB FFFF fatallog 88 | 4 589824 590335 256.0 KiB FFFF sbl1 89 | ``` 90 | Она должна быть **абсолютно точно** как написано выше (на нетронутом телефоне). 91 | 92 | **Скрипт не принимает решений. Это Вы, кто сравнивает и решает, что делать!** 93 | 94 | Если Вас все устраивает - продолжаем! 95 | 96 | #### Новое recovery 97 | 98 | В linux проверьте, что `adbr.sh` имеет код доступа `755`. Чтобы быть уверенным в этом, просто выполните команду 99 | (будучи в директории, куда все сохранялось при загрузке) 100 | ``` 101 | chmod 755 adbr.sh 102 | ``` 103 | Запустите скрипт 104 | ``` 105 | ./adbr.sh 106 | (adbr.bat [для windows]) 107 | ``` 108 | Абсолютно новое recovery установлено! 109 | 110 | #### Новый boot 111 | 112 | **Новый образ recovery ДОЛЖЕН быть установлен!** 113 | 114 | В linux проверьте, что `adbb.sh` имеет код доступа `755`. Чтобы быть уверенным в этом, просто выполните команду 115 | (будучи в директории, куда все сохранялось при загрузке) 116 | ``` 117 | chmod 755 adbb.sh 118 | ``` 119 | **Карточка microsd должна быть __в__ телефоне.** 120 | 121 | Запустите на своем компьютере 122 | ``` 123 | ./adbb.sh 124 | (adbb.bat [for windows]) 125 | ``` 126 | Для копирования файлов в правильное место на карточке (в папку с имменем `brnects0.715`). 127 | 128 | Перезапустите телефон в режиме *recovery*, набрав на своем компьютере 129 | ``` 130 | adb reboot recovery 131 | ``` 132 | Дождитесь как минимум логотипа 'NEC'. После логотипа 'NEC' телефон не будет показывать **НИЧЕГО**. Теперь переходите 133 | внутрь оболочки adb (печатаем все на компьтере и далее, но виртуально мы будем в телефоне) 134 | ``` 135 | adb shell 136 | ``` 137 | и выполняйте команды внутри оболочки 138 | ``` 139 | cd /rbin 140 | ./flash_boot.sh 141 | ``` 142 | Теперь выходите из оболочки 143 | ``` 144 | exit 145 | ``` 146 | для возврата на свой компьютер и перегружайте телефон 147 | ``` 148 | adb reboot 149 | ``` 150 | Новый образ boot установлен! 151 | 152 | #### Переразбиение разделов 153 | 154 | **__ЭТО НЕОБЯЗАТЕЛЬНЫЙ ЭТАП! ОШИБКИ В КОМАНДАХ ЛЕГКО СДЕЛАЮТ ВАШ ТЕЛЕФОН КИРПИЧЁМ!!!__** 155 | 156 | **Новый образ recovery ДОЛЖЕН быть установлен!** 157 | 158 | **Карточка microsd должна быть __в__ телефоне.** 159 | 160 | **Первое: это однозначное переразбиение с результатом 5GB для программ и 128MB для фото/видео внутри телефона. Если Вам нужны другие размеры разделов - нужно использовать программу gdisk в ручном режиме** 161 | 162 | **Второе: перед началом переразбиения сделайте стандартными методами телефона, чтобы в разделе GROW (он же "внутренняя sd карта") было занято не более 120MB!** 163 | 164 | Перезапустите телефон в режиме *recovery*, набрав на своем компьютере 165 | ``` 166 | adb reboot recovery 167 | ``` 168 | Дождитесь как минимум логотипа 'NEC'. После логотипа 'NEC' телефон не будет показывать **НИЧЕГО**. Теперь переходите 169 | внутрь оболочки adb (печатаем все на компьтере и далее, но виртуально мы будем в телефоне) 170 | ``` 171 | adb shell 172 | ``` 173 | и выполняйте команды внутри оболочки 174 | ``` 175 | cd /rbin 176 | ./bu_data.sh 177 | ./redo_data5GROW128.sh 178 | ``` 179 | скрипт `bu_data.sh` копирует все ваши установленные программы, настройки и файлы на sd-карточку (в папку с имменем `brnect08.715`). 180 | скрипт `data5GROW128.sh` задает новые границы разделов 181 | 182 | Теперь выходите из оболочки 183 | ``` 184 | exit 185 | ``` 186 | для возврата на свой компьютер и перегружайте телефон **еще раз** в режиме *recovery* 187 | ``` 188 | adb reboot recovery 189 | ``` 190 | **Перезагрузка необходима для продолжения процедуры!** 191 | 192 | **Еще раз** переходите внутрь оболочки adb 193 | ``` 194 | adb shell 195 | ``` 196 | и выполняйте команды внутри оболочки 197 | ``` 198 | cd /rbin 199 | ./format_dataGROW.sh 200 | ./rr_data.sh 201 | ``` 202 | скрипт `format_dataGROW.sh` форматирует разделы. 203 | скрипт `rr_data.sh` копирует все ваши установленные программы, настройки и файлы обрато с sd-карточки. 204 | 205 | Теперь выходите из оболочки 206 | ``` 207 | exit 208 | ``` 209 | для возврата на свой компьютер и перегружайте телефон 210 | ``` 211 | adb reboot 212 | ``` 213 | Разделы userdata и GROW приобрели новые размеры! 214 | 215 | #### Установка `su` и `Superuser.apk` 216 | 217 | **Новый образ recovery ДОЛЖЕН быть установлен!** 218 | 219 | В linux проверьте, что `adbs.sh` имеет код доступа `755`. Чтобы быть уверенным в этом, просто выполните команду 220 | (будучи в директории, куда все сохранялось при загрузке) 221 | ``` 222 | chmod 755 adbs.sh 223 | ``` 224 | Перезапустите телефон в режиме *recovery*, набрав на своем компьютере 225 | ``` 226 | adb reboot recovery 227 | ``` 228 | Запустите на своем компьютере, находясь в директории, куда все скачено 229 | ``` 230 | ./adbs.sh 231 | (adbs.bat [для windows]) 232 | ``` 233 | По завершении перезагружайте телефон, набирая на компьютере 234 | ``` 235 | adb reboot 236 | ``` 237 | После перезагрузки телефона Вы увидите сообщение "Android is upgrading". Это значит, что телефон устанавливает 238 | новую 'системную' программу Superuser.apk 239 | 240 | **ГОТОВО! Ваш телефон заручен!** 241 | -------------------------------------------------------------------------------- /general-th.md: -------------------------------------------------------------------------------- 1 | ### Exploiting in general 2 | 3 | #### Introduction 4 | 5 | We are sepaking about Android phones (devices in general). These are run using the Android oeprating system and in reality 6 | are slim computers rather than just "phones". Most canonically such devices are locked by the manufacturers 7 | from being tweaked. Not sure I understand the reason. Most likely makers afraid to loose something on the market. 8 | You are therefore initally limited by some predefined functionality and have to leave with many pre-installed programs. 9 | 10 | Just several things which you **cannot** do by default on most (or prehaps all) phones: 11 | * install custom operating system or at least custom system components 12 | * remove bloatware (programs supplied with the phone and which have almost no use, but still eat resourses) 13 | * enable blocked features, often tethering is blocked for commercial reasons. Tethering means your phone uses mobile data 14 | to communicate with internet and serves for you as a wi-fi hotspot. So you can connect your laptop to the internet as well thrugh the same data channel 15 | * upgrade to newer versions of Android if the maker does not provide an update 16 | * fix bugs in the system if the model is discontinued 17 | * fix oddities which are not bugs but make the life difficult (like awful partitioning of the internal memory of NEC Terrain) 18 | * many other aspects as well 19 | 20 | In order to overcome the limits and break free you have to gain the control over the whole system. Some people name it 21 | "rooting" but this is not always the best word. 22 | 23 | #### A bit about the Android 24 | 25 | Android is essentially linux with the user-interface programs written in java. Those programs are run by the java virtual machine. 26 | What most people think about when they say Android is just that 27 | graphical interface made by java programs. 28 | However, if you want to go inside and manipulate the system of your phone you should understand basics of linux. 29 | It is therefore a great plus for you if you are common with linux already. 30 | 31 | The core of linux is its kernel - program code which initiate the system and which communicates between user and hardware devices. 32 | It manages, apart from other devices, disks, file-systems, reading/writing of files. 33 | It of course manages memory and processes in it. What is also essential, it checks permissions. What which user can 34 | and cannot do. 35 | 36 | The main user has identifier 0 (zero) and is traditionally named `root`. Traditionally it has full access to everything. This is why gaining full access is often named "rooting". 37 | 38 | However, this is not obliged to be, and for NEC Terrain in particular it is not! 39 | 40 | #### Usual types of defense which makers use 41 | 42 | As much as possible makers of the phones and tablets, as well as carriers, try to protect devices from being altered. They explain this by their worry that you can damage the device. In reality in some cases they preserve their commercial interests (like no tethering means you have to pay for data on both, say, phone and tablet) but in many instances a paranoic defense is unexplainable. 43 | 44 | ##### No *root* access 45 | 46 | Traditionally, if you are the `root` user you have full access to the system. Kernel permits it. So, in order to avoid this all processes are being run *not* as `root`. As the result you simply cannot execute many system-level commands. To become the `root` you must have a special program, usually named `su` which changes your status to `root` provided a proper configuration file is arranged. Looks simple, just download this program and run it. BUT, the system does not allow you to write it into the directory with programs, like `/system/bin`. Moreover, it does not allow you to run programs from other locations. You are kind of in stuck. Still, usually, `/data/local/tmp` is a place where programs can be written and being run but it is not convenient, as this directory is not in the search path. You have to type all way down `/data/local/tmp/su`. The latter is incompatible with configurations of standard root access programs on the market. 47 | 48 | However, let's comment on what does it mean *traditionally*. Traditionally means that the kernel behaves as follows. Consider mounting of `/system` partition as an example. The pseudo-code maybe like that: 49 | ``` 50 | start mounting function 51 | if (used_id!=0) return ERROR_NOT_PERMITTED 52 | 53 | ``` 54 | Now, imagine another code: 55 | ``` 56 | start mounting function 57 | if (partition=="/system") return ERROR_NOT_PERMITTED 58 | 59 | ``` 60 | You see, in the second case `/system` cannot be mounted whoever you are. Full stop. No way. Even if you are `root` 61 | 62 | So, being `root` does not mean be allowed everything. Traditions may be broken. This is exactly what hapens in NEC Terrain with the stock kernel when you boot normally. Luckily, the recovery boot of this phone has a *different* kernel, free of such security limitations. As you can imagine, one of the further step will be to stuff the normal boot with the kernel from recovery. 63 | 64 | ##### Locked bootloader 65 | 66 | This is another *feature* used by phone makers. The boot process goes in stages. Program code from various partitions of the internal memory is being executed in order. During this the phone initialization is performed. After many really initial stages the so called `aboot` is executed. This guy decides what to boot: *normal* or *recovery* mode depending on has or not the *vol-down* key been pressed. Then it boots using either `boot` or `recovery` partition. 67 | 68 | The trick is that before `aboot` is called it is being checked using certificates written inside and computing the hash sum. If the check does not succeed the boot process halts. 69 | 70 | In the same manner `aboot` checks `boot` or `recovery`. Chances are that `aboot` will just halt the phone if the bootable image does not pass the security checks. 71 | 72 | This is a way more complicated problem to overcome than just become a `root`. The oddity is as follows. Once you have become the `root`, you may have chances to overwrite, say `boot` partition with your new lovely kernel, but this kernel may **not** be booted by `aboot` becuase its hash is wrong. As a result you cannot start your phone completely. 73 | 74 | This is not just a mistake, this with high probability will lead to the complete **brick** out of your phone. You therefore must be absolutely sure **before** altering bootable partitions, that this is in accord with possible lock mechanisms. 75 | 76 | Some people may think that *factory reset* may help but this is wrong! "Factory reset" in most cases assumes that `system`, `boot` and `recovery` (and of course all other system) partitions are given and are immutable. There is just **NO** second image for them inside. Usually "factory reset" only wipes what you, as a normal user, have done on your phone. Your programs, settings, files, etc. Be aware! 77 | 78 | ##### NAND-lock 79 | 80 | This is the most strange concept for a normal pc user like me. Essentially it means *nothing*. The term NAND originates from the technical name of the memory organization type on a chip. *NAND-lock* means some way of preventing writing to the internal memory. However, if you are common with pc you understand that in principle there are only few ways of such a lock. 81 | 82 | 1. Physical lock by some physical switch, like on sd-card. Easy to find and maybe impossible to unlock. Stop. 83 | 2. *Collaborative* lock. For example, some byte, somewhere determines whether write is allowd or not. Say 1 allows and 0 disallows. Kernel appreciates this convention, i.e. it *collaborates* on using this arrangment. It is like a region lock on a dvd. Standard dvd-drive would refuse disks from a wrong region. The disk can be read but the drive simply does not want to read it. You can easily change this by reflashing the dvd-drive firmware on some drives. To remove such type of lock you must trace it down and find out the beast. I.e. understand the convention and make use of it in your favor. 84 | 3. Just modified kernel. For exmaple, on top of standards, kernel may feature some code which prevents writing to, say, partition `system`. Or forbids writing to sectors from A to B. The very latter is exactly the case for the stock kernel of NEC Terrain in the normal boot mode. The area where most vital system partitions (including `boot`, `recovery` and `system`) are forbidden for writing by any user including `root`. 85 | 4. The most tricky - *man-in-between*. Like a resedential program in old ms-dos or like a hypervisor. It means that before you system kernel is loaded some pre-kernel is injected into the memory. It serves as the relay between the full system kernel and the internal memory chip. When the system kernel issues the write request, this request is being captured and checked by the pre-krenel. If, for instance, the request addresses an arrea to be protected, such a request is blocked. Being tricky such a lock means that you must find and change the pre-kernel. 86 | 87 | All these locks can be effectively used to prevent you from altering you phone. 88 | 89 | #### What to do in general? 90 | 91 | As we have seen, several defenses are used. They are complementary. Being `root` does not neccessarily mean you can override bootable partitions, for example. Or, being root does not mean you can safely change bootable partitions without bricking your phone. Thus, to tame the phone completely you must arrange three things: 92 | 93 | 1. Become sure that replacing bootable partitions will not brick your device. Or pave a way to prevent this. 94 | 2. If you cannot override bootable partitions, find a way to remove the write-lock. 95 | 3. When you succeeded in two previous points, arrange such a `root` access that you can really write a program like `su` in a proper place like `/system/bin` 96 | 97 | Now we are ready to go for NEC Terrain. 98 | 99 | --- 100 | 101 | *You should read [here](exploit-th.md) about the theory of exploiting NEC Terrain.* 102 | -------------------------------------------------------------------------------- /recovery-howto.md: -------------------------------------------------------------------------------- 1 | *You can find [here](exploit-pre.md) what are the mandatory pre-requisits for the exploit.* 2 | 3 | --- 4 | 5 | ### New recovery 6 | 7 | #### What is new? 8 | 9 | To understand what is *new* let's say what was *old*. The stock configuration of NEC Terrain comes with the ability to boot into the *recovery* mode. One of the purpose is to perform the *factory reset*. To be more specific let's explain. There are five partitions of the internal memory whihc you 'feel' working with this phone: 10 | * `system` - where all the system pre-insatlled programs are 11 | * `userdata` - where all the user insatlled programs go 12 | * `GROW` - where all user files like photos and video go 13 | * `boot` - image for the normal boot 14 | * `recovery` - image for the recovery boot 15 | 16 | *factory reset* means formatting `userdata` to ext4 and `GROW` to vfat using the stock `recovery` binary inside the recovery partition. All other partitions are considered immutable. It means that if you achieve eventually root access and then mess up, say, `system` which is whatever inside the directory `/system`, you are in stuck. Stock recovery will not repair this. 17 | 18 | Thus the wish is to implement a fully independent and fully functional recovery. Such that it would be capable to restore whatever in the system. This is also essential to repartition your system. You want this as originally you have almost no space for your programs (800MiB in `userdata`) and more than 4GiB just for photos, video, etc (in `GROW`). 19 | 20 | #### Installing new recovery 21 | 22 | * **recovery/** - folder: the proper recovery image is there 23 | 24 | To install new recovery into its proper place, i.e. recovery partition, You download from the `recovery/` folder here into one folder on your pc: 25 | * `adbr.sh (adbr.bat for windows)` 26 | * `flash_recovery.sh` 27 | * `run_root_shell` 28 | * `sgdisk` 29 | * one of the `.bin` images. **IMPORTANT:** whatever image you download you **must** save it under the name `kas.boot.bin` locally on your pc 30 | 31 | In linux check that `adbr.sh` script has permissions `755`. To be sure just issue on your pc inside the directory where all the stuff has been saved 32 | ``` 33 | chmod 755 adbr.sh 34 | ``` 35 | Now boot your phone normally, into its canonical stock boot configuration. Connect usb cable. Start `adb` daemon for exmaple by 36 | ``` 37 | sudo adb devices 38 | (adb start-server [for windows]) 39 | ``` 40 | Then execute on your pc (you should be inside the folder where you have just downloaded the stuff) 41 | ``` 42 | ./adbr.sh 43 | (adbr.bat [for windows]) 44 | ``` 45 | As the result you will have a brand new recovery image to be booted with *vol-down+power* pressed. 46 | 47 | Remember: This recovery environment is immediately root. 48 | 49 | **BE CAREFUL!!! IT IS THE PROPER ROOT!!! NO LIMITS!!!** 50 | 51 | `adb` access is the most serious achievement of this new recovery. 52 | 53 | You have in your disposal `busybox` (with all links), `gdisk`, `sgdik`, `mkfs.ext4` and `mksh` in `/sbin` folder. It is a good linux recovery set of tools. Also you have 54 | some essential scripts in `/rbin`. 55 | `/rbin` is *not* in your path so you will not run scripts from there unintentionally. 56 | 57 | --- 58 | 59 | *You should proceed [here](boot-howto.md) for the next exercise: new boot image.* 60 | -------------------------------------------------------------------------------- /recovery/README.md: -------------------------------------------------------------------------------- 1 | ### NEC Terrain recovery image 2 | 3 | This recovery image is made of the original kernel used in the stock recovery and an amended original ramdisk. This kernel does not 4 | enforce a write-protection above linux permissions and privileges. 5 | 6 | Images: 7 | * `kas.recovery.bin` - the recovery image, latest version 8 | * `kas.recovery.bin-vvv` - the recovery image, version vvv 9 | 10 | Verification script: 11 | * `adbtestgpt.sh (adbtestgpt.bat for windows)` - this script shows to you the GPT table. It is up to **YOU** to decide whether to proceed or not. You should consult [the prerequisits](../exploit-pre.md) page to make the decision. The corenerstone is the gap between partitions 3 and 4 12 | ``` 13 | Number Start (sector) End (sector) Size Code Name 14 | 3 425984 557055 64.0 MiB FFFF fatallog 15 | 4 589824 590335 256.0 KiB FFFF sbl1 16 | ``` 17 | **EXACTLY** as written above (on a non-altered phone). 18 | 19 | Install script: 20 | * `adbr.sh (adbr.bat for windows)` - script to be run on your computer to eventually flash the recovery image on a normally booted phone. 21 | 22 | Required binaries and scripts for the install: 23 | * `run_root_shell` is used to flash this image on a non-rooted NEC Terrain 24 | * `sgdisk` is used to re-map recovery partition to a know standard hole 25 | * `flash_recovery.sh` - the script which is run on the phone to do the re-mapping of the partition and flashing 26 | 27 | #### Changelog for the *image*: 28 | 29 | * **version 0.9.2** (`kas.recovery.bin-0.9`) 30 | * ramdisk/rbin/redo_data5GROW128.sh script re-creates `userdata` to be 5GiB and `GROW` to be 128MiB 31 | * ramdisk/rbin/format_dataGROW.sh script formats `userdata` to ext4 with optimizing options and `GROW` to vfat 32 | 33 | * **version 0.9** (`kas.recovery.bin-0.9`) 34 | * ramdisk/rbin/flash_boot.sh modified such that now it places build.prop automatically 35 | 36 | * **version 0.8.1** (`kas.recovery.bin-0.8.1`) 37 | * ramdisk/init.rc: recovery binary disabled (not deleted though) to prevent a possible FOTA action 38 | 39 | * **version 0.8** (`kas.recovery.bin`, the very first!) 40 | * ramdisk/default.prop 41 | * ro.secure=0, no obvious use 42 | * ro.debuggable=1, no obviouc use 43 | * service.adb.root=1 addded, no obvious use 44 | * ro.build.type=eng, no obvious use 45 | * att.service.entitlement=false, no obvious use in this regime 46 | * ramdisk/init.rc: all stuff governing adb uncommented, not sure it plays role 47 | * ramdisk/adbd replaced with adbd insecure binary hacked for new placing of the shell sh 48 | * New files in ramdisk/sbin 49 | * busybox + all its symlinks 50 | * mksh - shell, slightly hacked for new placing of itself and mkshrc 51 | * mkshrc - rc file for mksh, has aliases 52 | * sh is symlinked to mksh 53 | * gdisk 54 | * sgdisk 55 | * mkfs.ext4 - very big, need smaller 56 | * New directory ramdisk/rbin 57 | * bu_ - scripts for data backup 58 | * rr_ - scripts for data restore 59 | * flash_ - scripts for flashing 60 | * Known bugs: 61 | * adbd stalls from time to time. Can be woken up by another shell request or by cable dis-/connect. Once led 62 | to the need of battery off/in 63 | 64 | * **version -1** (stock) 65 | -------------------------------------------------------------------------------- /recovery/adbr.bat: -------------------------------------------------------------------------------- 1 | adb push run_root_shell /data/local/tmp 2 | adb push sgdisk /data/local/tmp 3 | adb push kas.recovery.bin /data/local/tmp 4 | adb push flash_recovery.sh /data/local/tmp 5 | 6 | adb shell chmod 755 /data/local/tmp/run_root_shell 7 | adb shell chmod 755 /data/local/tmp/sgdisk 8 | adb shell chmod 755 /data/local/tmp/flash_recovery.sh 9 | 10 | adb shell /data/local/tmp/run_root_shell -c '/data/local/tmp/flash_recovery.sh' 11 | -------------------------------------------------------------------------------- /recovery/adbr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | adb push run_root_shell /data/local/tmp 3 | adb push sgdisk /data/local/tmp 4 | adb push kas.recovery.bin /data/local/tmp 5 | adb push flash_recovery.sh /data/local/tmp 6 | 7 | adb shell chmod 755 /data/local/tmp/run_root_shell 8 | adb shell chmod 755 /data/local/tmp/sgdisk 9 | adb shell chmod 755 /data/local/tmp/flash_recovery.sh 10 | 11 | adb shell /data/local/tmp/run_root_shell -c "/data/local/tmp/flash_recovery.sh" 12 | exit 0 13 | -------------------------------------------------------------------------------- /recovery/adbtestgpt.bat: -------------------------------------------------------------------------------- 1 | adb push run_root_shell /data/local/tmp 2 | adb push sgdisk /data/local/tmp 3 | 4 | adb shell chmod 755 /data/local/tmp/run_root_shell 5 | adb shell chmod 755 /data/local/tmp/sgdisk 6 | 7 | adb shell /data/local/tmp/run_root_shell -c '/data/local/tmp/sgdisk -p /dev/block/mmcblk0' 8 | -------------------------------------------------------------------------------- /recovery/adbtestgpt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | adb push run_root_shell /data/local/tmp 3 | adb push sgdisk /data/local/tmp 4 | 5 | adb shell chmod 755 /data/local/tmp/run_root_shell 6 | adb shell chmod 755 /data/local/tmp/sgdisk 7 | 8 | adb shell /data/local/tmp/run_root_shell -c "/data/local/tmp/sgdisk -p /dev/block/mmcblk0" 9 | exit 0 10 | -------------------------------------------------------------------------------- /recovery/flash_recovery.sh: -------------------------------------------------------------------------------- 1 | #!/system/bin/sh 2 | # remapping recovery partition to a standard hole 3 | /data/local/tmp/sgdisk -d 11 /dev/block/mmcblk0 #deleting 4 | /data/local/tmp/sgdisk -n 11:557056:589823 /dev/block/mmcblk0 #re-creating 5 | /data/local/tmp/sgdisk -c 11:recovery /dev/block/mmcblk0 #naming 6 | #/data/local/tmp/sgdisk -t 11:FFFF /dev/block/mmcblk0 -v 7 | # flashing recovery 8 | /system/bin/dd if=/data/local/tmp/kas.recovery.bin of=/dev/block/mmcblk0 bs=512 seek=557056 #flashing 9 | /system/bin/sync #syncing 10 | exit 0 #exiting 11 | 12 | -------------------------------------------------------------------------------- /recovery/kas.recovery.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/recovery/kas.recovery.bin -------------------------------------------------------------------------------- /recovery/kas.recovery.bin-0.8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/recovery/kas.recovery.bin-0.8 -------------------------------------------------------------------------------- /recovery/kas.recovery.bin-0.8.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/recovery/kas.recovery.bin-0.8.1 -------------------------------------------------------------------------------- /recovery/kas.recovery.bin-0.9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/recovery/kas.recovery.bin-0.9 -------------------------------------------------------------------------------- /recovery/kas.recovery.bin-0.9.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/recovery/kas.recovery.bin-0.9.2 -------------------------------------------------------------------------------- /recovery/run_root_shell: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/recovery/run_root_shell -------------------------------------------------------------------------------- /recovery/sgdisk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/recovery/sgdisk -------------------------------------------------------------------------------- /repart-howto.md: -------------------------------------------------------------------------------- 1 | *You can find [here](boot-howto.md) how to install the new boot image.* 2 | 3 | --- 4 | 5 | ### Repartitioning `userdata` and `GROW` 6 | 7 | Re-partitioning is a straightforward but a *must-to-be-done-accurately* procedure. Mistakes may cost you a phone. 8 | 9 | **The micro-sdcard must be IN the phone!** if you **do not** want a la factory reset. 10 | 11 | **The new recovery must be installed!** 12 | 13 | *Also note the following: you most likely start with a large `GROW` partition and want to finish with a small `GROW` partition. Clearly, restoring will fail if initial size of data on `GROW` is bigger than the final partition size. However, as I understand, in order to pretend that nothing happened and continue using the phone (I mean to avoid complains from the system) you must, at least, restore some basic directory structure on `GROW`. Having said this you are advised to clean up the data on the `GROW` partition to the amount less than expected final size of the `GROW` partition __before__ you proceed with backup-restore.* 14 | 15 | Boot into the new recovery with *vol-down+power* pressed. Start the `adb` daemon on your pc, for instance doing 16 | ``` 17 | sudo adb devices 18 | ``` 19 | Go into the shell 20 | ``` 21 | adb shell 22 | ``` 23 | 24 | #### Step 1. Backup. 25 | 26 | Skip it if you do not care neither about your files nor about settings or programs installed by you and (therefore) want an effect of *factory reset* 27 | 28 | If you care about something of the above - do backup. It is as follows (commands inside the adb shell) 29 | ``` 30 | cd /rbin 31 | ./bu_data.sh 32 | ``` 33 | You will see a long output listing each file added to an archive on your sdcard in a very special folder `brnect08.715` 34 | 35 | #### Step 2. Actual re-partitioning 36 | 37 | For this run 38 | ``` 39 | gdisk /dev/block/mmcblk0 40 | ``` 41 | 42 | Unfortunately, I cannot provide you help here as it is solely up to you HOW you want to breakdown partitions. Just for reference, originally the partitions of interest reside as 43 | ``` 44 | 13 2818048 4456447 800.0 MiB 8300 userdata 45 | 14 4456448 13565951 4.3 GiB FFFF GROW 46 | ``` 47 | where start and end are in 512-byte-sectors. I did them like 48 | ``` 49 | 13 2818048 13303807 5.0 GiB 8300 userdata 50 | 14 13303808 13565951 128.0 MiB FFFF GROW 51 | ``` 52 | You achieve this in `gdisk` by deleting a partition and recreating it again with new boundaries. 53 | 54 | Tiny `gdisk` intro: 55 | 56 | All modifications are in **memory**! It is safe, but **do not forget to write**, using command **w** before you quit. 57 | 58 | * **?** - anytime for help 59 | * **d** - delete partition, it asks number: enter number and press `enter` 60 | * **n** - create new partition, it asks number. If say, you deleted partition number 14, you now can enter 14, so you will just redo it, but of another size. Then starting and ending sectors are asked. You can just get from the table above. OR invent YOURS! As you like. Then it asks about a flag, agree to 8300, even for GROW. Standartly FFFF flag is not supported 61 | * **c** - **CRUCIAL**: you **MUST** give it a name as it was before, **EXACTLY**. Before entering the name you will be asked the partition number, of course 62 | * **p** - print, how the table looks now 63 | * **w** - write changes to disk, w/o this you will loose your efforts! 64 | * **q** -- quit 65 | 66 | Once created **and written** by issuing the command `w` INSIDE `gdisk` you **MUST** reboot. It is the only way to instruct the kernel to read new partition table. First, exit the shell 67 | ``` 68 | exit 69 | ``` 70 | Reboot your phone typing on your pc 71 | ``` 72 | adb reboot recovery 73 | ``` 74 | After the reboot your phone is back to the recovery environment. 75 | 76 | #### Step 3. Formatting 77 | 78 | Go into the shell by typing on your pc 79 | ``` 80 | adb shell 81 | ``` 82 | Now you **must** create file-systems on your re-shuffled partitions (command inside the adb shell) 83 | ``` 84 | mkfs.vfat /dev/block/mmcblk0p14 85 | mkfs.ext4 -b 1024 -i 4096 /dev/block/mmcblk0p13 86 | ``` 87 | You are kindly instructed to write the arguments for the ext4 formatiing exactly as they are here. These values of `-b` and `-i` will save you from vasting 25% of the `userdata` space for *nothing*! 88 | 89 | After this you will have a system *exactly* like after a stock *factory reset*. 90 | 91 | ##### Step 4. Restoring your files 92 | 93 | Skip it if already skipped the step 1 or if you have changed your mind and want an a la *factory reset* phone. 94 | 95 | To restore your files issue inside the adb shell 96 | ``` 97 | cd /rbin 98 | ./rr_data.sh 99 | ``` 100 | This will unpack all your files from the backup into the previous place like nothing has happened! 101 | Now exit the shell 102 | ``` 103 | exit 104 | ``` 105 | and then reboot the phone normally by typing on your pc 106 | ``` 107 | adb reboot 108 | ``` 109 | After the reboot you either have your previous phone or will have to re-do all the initialization. This depends on whether you have backed-up files and restored them back or not. 110 | 111 | **DONE!** 112 | 113 | --- 114 | 115 | *You should proceed [here](system-howto.md) for some extra exercises.* 116 | -------------------------------------------------------------------------------- /system-howto.md: -------------------------------------------------------------------------------- 1 | *You can find [here](repart-howto.md) how to repartition NEC Terrain.* 2 | 3 | --- 4 | 5 | ### Placing `su` and `Superuser.apk` 6 | 7 | * **system/** - folder: the relevant files are there 8 | 9 | You download from the `system/` folder here to some place on your pc: 10 | * `adbs.sh (adbs.bat for windows)` 11 | * `su` 12 | * `Superuser.apk` 13 | 14 | Ensure that your `adb` daemon is running bu issuing 15 | ``` 16 | sudo adb devices 17 | ``` 18 | **The new recovery must be installed!** 19 | 20 | In linux check that `adbs.sh` has 755 permissions. To be sure simply issue from inside the directory where you have downloaded the files 21 | ``` 22 | chmod 755 adbs.sh 23 | ``` 24 | Now restart your phone into recovery typing on your pc 25 | ``` 26 | adb reboot recovery 27 | ``` 28 | From the directory where you have downloaded the suepruser stuff do 29 | ``` 30 | ./adbs.sh 31 | (adbs.bat [for windows]) 32 | ``` 33 | Once done, reboot the phone by 34 | ``` 35 | adb reboot 36 | ``` 37 | After the reboot you will see "Android is upgrading" meaning it installs a new 'system' program `Superuser.apk` 38 | 39 | --- 40 | 41 | *You may want to proceed [here](ts.md) for the troubleshooting hints.* 42 | -------------------------------------------------------------------------------- /system/README.md: -------------------------------------------------------------------------------- 1 | ### What can you find in this folder? 2 | 3 | * `adbfb.tar.gz` - `adb.exe` and drivers (show NEC Terrain as some Samsung phone) for windows (proven working in win7pro_x64) 4 | * `superuser.tar.gz` - contains `su` binary and `Superuser.apk` 5 | * `apk*` - contain program lists discussed below 6 | 7 | ### NEC Terrain system and its components 8 | 9 | I did some research and present here lists of apps which should be left in the system, 10 | which I have disabled and which I installed in order to replace stock or add functionality. 11 | 12 | These lists reflect my **personal** opinion which can differ with yours. You should not blame me for this. 13 | Moreover, I'm not affiliated with any programmer/developer. Think for yourself before you disable and 14 | especially remove packages. 15 | 16 | Also note 17 | that the information was taken from my digging inside the phone. Do not get it as 18 | 100% correct, better check. 19 | 20 | As an assurance, any statement below has been verified by me and not just copy-pasted from another internet source. 21 | Currently in my phone all apps from the `disable` list below are indeed disabled and I confirm that: 22 | * the phone boots 23 | * it works normally 24 | * it makes and receives calls 25 | * the same for sms-s 26 | * works with wifi 27 | * data connection 4G works 28 | * both main and front cameras and microphone work 29 | * charging goes as expected 30 | * external sd-card is accessible 31 | * syncing with google account does not produce errors 32 | * all expected programs autostart 33 | * etc 34 | 35 | *`enable` and `disable` lists together have absolutely __all__ packages which are initially in the system* 36 | 37 | #### Apps from the stock rom which I left and why, aka `enable` list (raw list of packages in `apkensys`) 38 | 39 | * android=/system/framework/framework-res.apk 40 | 41 | very system 42 | 43 | * com.android.bluetooth=/system/app/Bluetooth.apk 44 | 45 | very system - bt 46 | 47 | * com.android.certinstaller=/system/app/CertInstaller.apk 48 | 49 | very system - about certificates, seems important 50 | 51 | * com.android.contacts=/system/app/Contacts.apk 52 | 53 | very system! This app is used not only to show, but also to add contacts. If you disable it, you cannot add contacts to your phone storage anymore because 54 | even any replacement app uses the interface of this one. It provides some *service* or *transport* to do this as I understand. Already stored contacts can be viewed, however. 55 | If you still insist to disable/remove this one, you *will* have to install an alternative dialer at least 56 | as the stock dialer will disappear from any graphical view (but will be still enabled though). And again, no contacts cam be added to the phone storage. 57 | Note, that this program *does not start* if you disable/remove `com.android.att.settings.provider` but its part for adding contacts to the phone storage 58 | will still function properly if being called from a third-party program. 59 | 60 | I however wanted to avoid this app (`contacts`, I mean) as much as I can because I'm fed up with the fact that anytime I start it, 61 | it communicates to the internet switching data connection on, at least 62 | for few secs, even if there is wifi and even if before the data connection was off. 63 | 64 | So, since I have failed so far to disable this app I did like that: 65 | * I installed **DW Contacts**, which has a dialer as well 66 | * I disabled `com.android.att.settings.provider` and this automatically closed for me the full stock `contacts` (but not disabled) 67 | * Now I use **DW Contacts** to make calls. The actual call is made again using the stock `Phone` program internals, its graphics 68 | * When I add contacts in **DW Contacts** I see the interface of original `contacts` 69 | * BUT the data-connection has gone! 70 | 71 | The downside: if you try to start `contacts`, you see `unfortunately contacts has stopped` 72 | 73 | * com.android.defcontainer=/system/app/DefaultContainerService.apk 74 | 75 | very system, looks like 76 | 77 | * com.android.keychain=/system/app/KeyChain.apk 78 | 79 | very system, looks like 80 | 81 | * com.android.launcher=/system/app/Launcher2.apk 82 | 83 | very system, looks like 84 | 85 | * com.android.nfc=/system/app/Nfc.apk 86 | 87 | I guess this and next can be disabled if you do not need NFC, which eats your bettery, I left for a moment, do not know why 88 | 89 | * com.android.nfchiddenmenu=/system/app/NfcHiddenMenu.apk 90 | 91 | I guess this and previous can be disabled if you do not need NFC, which eats your bettery, I left for a moment, do not know why 92 | 93 | * com.android.packageinstaller=/system/app/PackageInstaller.apk 94 | 95 | **__EDIT:__** it is required by `pm` in the shell and `pm` does not operate w/o it, so do not remove 96 | 97 | * com.android.phone=/system/app/Phone.apk 98 | 99 | You will not be able to make calls w/o this. It is not just graphics, also some binary internals to communicate with the modem, proprietary in fact. So, no replacement 100 | 101 | * com.android.providers.applications=/system/app/ApplicationsProvider.apk 102 | 103 | Removing this will disintegrate your system. It may start, perhaps, but apps will not communicate one to each other. This is generically bad and causes many to complain or function improperly 104 | 105 | * com.android.providers.contacts=/system/app/ContactsProvider.apk 106 | 107 | This is about the phone contacts storage, if disabled, no contacts to the phone can be stored 108 | 109 | * com.android.providers.downloads=/system/app/DownloadProvider.apk 110 | 111 | Some settings for downloads, not sure it is really critical, but seems that some apps like playstore rely on it and do not bother themselves about where to store what 112 | 113 | * com.android.providers.downloads.ui=/system/app/DownloadProviderUi.apk 114 | 115 | It is to see graphically, what and where has been saved, perhaps can be disabled/removed 116 | 117 | * com.android.providers.drm=/system/app/DrmProvider.apk 118 | 119 | **not sure** what exactly this guy stores, but some databases look like mime-types identification 120 | 121 | * com.android.providers.media=/system/app/MediaProvider.apk 122 | 123 | A centralized databse about where media files are, so that players see them all 124 | 125 | * com.android.providers.settings=/system/app/SettingsProvider.apk 126 | 127 | **not sure** what exactly this guy stores, but looks important 128 | 129 | * com.android.providers.telephony=/system/app/TelephonyProvider.apk 130 | 131 | The database which identifies a numeric gsm network id with the name. Maybe not really critical but chances are some interface elements may complain. They want to write a name, not a number of the 132 | gsm network 133 | 134 | * com.android.providers.userdictionary=/system/app/UserDictionaryProvider.apk 135 | 136 | **__EDIT:__** If you remove this program you will get error `stop` anytime you quit editing of the input method properties. I decided to keep 137 | 138 | * com.android.provision=/system/app/Provision.apk 139 | 140 | People say, it is important and its data look so, but not sure, what is it exactly 141 | 142 | * com.android.settings=/system/app/Settings.apk 143 | 144 | Your setting interface 145 | 146 | * com.android.smspush=/system/app/WAPPushManager.apk 147 | 148 | It is said to be realted to tethering operation, did not check myself inside 149 | 150 | * com.android.stk=/system/app/Stk.apk 151 | 152 | Looks system 153 | 154 | * com.android.systemui=/system/app/SystemUI.apk 155 | 156 | Looks system, the main graphical interface in fact 157 | 158 | * com.android.vending=/data/app/com.android.vending-2.apk 159 | 160 | Looks system and is related to playservices 161 | 162 | * com.android.vpndialogs=/system/app/VpnDialogs.apk 163 | 164 | Used for vpns and perhaps can be disabled/removed, if you are sure that vpn is not for you. Or may be there are better replacements 165 | 166 | * com.google.android.apps.maps=/data/app/com.google.android.apps.maps-1.apk 167 | 168 | Google maps, I like 169 | 170 | * com.google.android.gms=/data/app/com.google.android.gms-1.apk 171 | 172 | Needed for hangouts, which I need, and for other google apps, like maps, if their (google) description is correct 173 | 174 | * com.google.android.gsf=/system/app/GoogleServicesFramework.apk 175 | 176 | google-service-framework, sounds system 177 | 178 | * com.google.android.gsf.login=/system/app/GoogleLoginService.apk 179 | 180 | google-service-framework addition, sounds system 181 | 182 | * com.google.android.location=/system/app/NetworkLocation.apk 183 | 184 | Location service, needed for maps w/o gps, or maybe with gps either 185 | 186 | * com.google.android.onetimeinitializer=/system/app/OneTimeInitializer.apk 187 | 188 | Not used at all but one time when playstore is initialized, so if you will replay your system from zero, it should be in place 189 | 190 | * com.google.android.street=/system/app/Street.apk 191 | 192 | Street view, useful 193 | 194 | * com.google.android.syncadapters.contacts=/system/app/GoogleContactsSyncAdapter.apk 195 | 196 | Sync of your contacts to the google account 197 | 198 | * com.google.android.talk=/data/app/com.google.android.talk-1.apk 199 | 200 | hangouts, I have to use it because of my colleagues 201 | 202 | * com.ipsec.vpnclient=/system/app/VpnClient.apk 203 | 204 | VPN client, I can easily use it, but may be it is crappy and replaceable, I do not know 205 | 206 | * com.kpt_nec.adaptxt=/system/app/NEC_Adaptxt_Base_v1_2.apk 207 | 208 | **__EDIT:__** IT IS VERY SYSTEM, It is what manges properties of your physical keyboard. The story is even more frustrating here: 209 | 210 | A virtual keyboard cannot be installed so you are in stuck in two situations: 211 | * You need some non-only-26-Latin-character input 212 | * You need to use something like terminal and to send, say ctrl-c, or arrow-up codes there 213 | 214 | I have tested dozens of options: no keyboard/input method starts its graphical interface. All silently use the physical keys and only them. `hackers keyboard` and `swiftkeyboard` 215 | are just two examples. If you go brave and **disable** `adaptxt` (of course installing some other input method in parallel and enabling it, and defaulting to it), 216 | then before reboot your keyboard will function but then you will the the so called boot loop. I got and it was tricky to get out. 217 | 218 | In fact it is a problem. How to use a terminal or type, for me for example, Cyrillic letters? 219 | 220 | * com.nec.android.ncmc.ecomode=/system/app/EcoMode.apk 221 | 222 | ECO-mode, nec specific. Seems it can be off here, but I kept, let it save battery, maybe. Not sure, it is useful, though 223 | 224 | * com.quicinc.fmradio=/system/app/FM.apk 225 | 226 | Perhaps crappy and replaceable but for me enough for the moment 227 | 228 | #### App strangely not from the stock rom which **MUST** be there. Do not know why it is absent originally (also listed in `apkensys`) 229 | 230 | * com.koushikdutta.superuser=/system/app/Superuser.apk 231 | 232 | *SUperuser, I need. Of course, it was __not__ in stock, but I put it before in the rom by hands* 233 | 234 | #### Apps from the stock rom which I **disabled** and why, aka `disable` list (raw list of packages in `apkdissys`) 235 | 236 | * borqs.soundrecorder=/system/app/SoundRecorder.apk 237 | 238 | It is the sound recorder, crappy and replaceable 239 | 240 | * com.amazon.kindle=/system/app/KindleForAndroid-0.9.11-STUB.apk 241 | 242 | It is the kindle, why, even if I like reading, the screen is tiny for that 243 | 244 | * com.android.DeviceHelp=/system/app/DeviceHelp.apk 245 | 246 | I do not need this, better use my laptop for help 247 | 248 | * com.android.apps.tag=/system/app/Tag.apk 249 | 250 | **unknown** but removing did not cause troubles 251 | 252 | * com.android.att.settings.provider=/system/app/ATTSettingsProvider.apk 253 | 254 | This **can** be removed but then ATT soft update does not work and stock `contacts` do not start. However, `contacts` **SHOULD NOT BE TOUCHED**, see in the list of still enabled apps why 255 | 256 | * com.android.backupconfirm=/system/app/BackupRestoreConfirmation.apk 257 | 258 | Most likely related to a backup of *data*, not *settings* to your on-line (gmail) account. Not needed for me 259 | 260 | * com.android.browser=/system/app/Browser.apk 261 | 262 | Stock crappy browser, there is firefox 263 | 264 | * com.android.calculator2=/system/app/Calculator.apk 265 | 266 | Stock useless calculator 267 | 268 | * com.android.calendar=/system/app/Calendar.apk 269 | 270 | Stock poor calendar 271 | 272 | * com.android.chrome=/system/app/Chrome.apk 273 | 274 | Chrome, which I disfavor in view of Firefox 275 | 276 | * com.android.contacts.map=/system/app/ContactMap.apk 277 | 278 | This to show a location of your contact given a zip code. Useless for me 279 | 280 | * com.android.deskclock=/system/app/DeskClock.apk 281 | 282 | Crappy stock desktop clock 283 | 284 | * com.android.email=/system/app/Email.apk 285 | 286 | Annoying stock e-mail, there is K-9 287 | 288 | * com.android.facelock=/system/app/FaceLock.apk 289 | 290 | face-lock: I'm not crazy to trust it. Passwords only 291 | 292 | * com.android.gallery3d=/system/app/Gallery2.apk 293 | 294 | It is the stock gallery, there are better and smaller around 295 | 296 | * com.android.htmlviewer=/system/app/HTMLViewer.apk 297 | 298 | Not sure why, but removing it cause no issues 299 | 300 | * com.android.magicsmoke=/system/app/MagicSmokeWallpapers.apk 301 | 302 | Wallpaper to eat you battery 303 | 304 | * com.android.mms=/system/app/Mms.apk 305 | 306 | Stock sms/mms. The only feature it has compared to conquerers - managing sim-card sms. Used to be the fact in around 1995-2005 307 | 308 | * com.android.music=/system/app/Music.apk 309 | 310 | Stock music player. There is VLC 311 | 312 | * com.android.musicfx=/system/app/MusicFX.apk 313 | 314 | Stock music player enhancement. There is VLC 315 | 316 | * com.android.musicvis=/system/app/VisualizationWallpapers.apk 317 | 318 | Wallpaper to eat you battery 319 | 320 | * com.android.noisefield=/system/app/NoiseField.apk 321 | 322 | Wallpaper to eat you battery, if I'm not mistaken, removal is issue-free 323 | 324 | * com.android.phasebeam=/system/app/PhaseBeam.apk 325 | 326 | Wallpaper to eat you battery 327 | 328 | * com.android.protips=/system/app/Protips.apk 329 | 330 | Home screen tips, a la "tap here", I do not need 331 | 332 | * com.android.providers.attxmlprovider=/system/app/ATTXmlProvider.apk 333 | 334 | ATT stuff but even w/o it `contacts` and connection to soft update worked, so why 335 | 336 | * com.android.providers.calendar=/system/app/CalendarProvider.apk 337 | 338 | Stock calendar storage, but I do not want this calendar 339 | 340 | * com.android.providers.partnerbookmarks=/system/app/PartnerBookmarksProvider.apk 341 | 342 | **unknown** but seems to be some advert, removed w/o issues 343 | 344 | * com.android.sharedstoragebackup=/system/app/SharedStorageBackup.apk 345 | 346 | **__EDIT:__** this program can be removed and was misatkenly said as impoartant earlier 347 | 348 | * com.android.videoeditor=/system/app/VideoEditor.apk 349 | 350 | Stock video editor, why 351 | 352 | * com.android.voicedialer=/system/app/VoiceDialer.apk 353 | 354 | Stock voice-dialer, i.e. giving the contact to call by voice, not for me 355 | 356 | * com.android.wallpaper=/system/app/LiveWallpapers.apk 357 | 358 | Wallpaper management to eat you battery 359 | 360 | * com.android.wallpaper.holospiral=/system/app/HoloSpiralWallpaper.apk 361 | 362 | Wallpaper to eat you battery 363 | 364 | * com.android.wallpaper.livepicker=/system/app/LiveWallpapersPicker.apk 365 | 366 | Wallpaper picker to eat you battery 367 | 368 | * com.att.eptt=/system/app/EPTTVPL.apk 369 | 370 | In particular *eptt* pronounced in my native language means kind of "mother f&#ker", and it is. Some functionality to use some att service, I'm in Europe 371 | 372 | * com.att.myWireless=/system/app/myATT_VPL_v5.apk 373 | 374 | I think to connect to att hotspots, I'm in Europe 375 | 376 | * com.borqs.camera=/system/app/BorqsCamera.apk 377 | 378 | Stock camera, crappy 379 | 380 | * com.borqs.dm=/system/app/DeviceManagement.apk 381 | 382 | Some device management, perhaps to use borqs apps with camera and sd card. No camera soft - nothing to manage 383 | 384 | * com.borqs.exif=/system/app/Exif.apk 385 | 386 | Used in gallery to decipher photo metadata. I removed this gallery, so no use 387 | 388 | * com.borqs.facebooksyncadapter=/system/app/FacebookSyncProvider.apk 389 | 390 | Send your photo to facebook, but no camera soft from borqs already 391 | 392 | * com.borqs.filemanager=/system/app/BorqsFileManager.apk 393 | 394 | Perhaps, to list photos in the gallery which I removed, no other use found 395 | 396 | * com.borqs.flickr=/system/app/Flickr.apk 397 | 398 | Send your photo to flickr, but no camera soft from borqs already 399 | 400 | * com.borqs.gif=/system/app/Gif.apk 401 | 402 | Make animated gifs, or play them, I do not care, there are better apps for this 403 | 404 | * com.borqs.hotspot=/system/app/hotspot.apk 405 | 406 | Some collection of us-based hotspot addresses, I'm in Europe 407 | 408 | * com.borqs.movie=/system/app/BorqsVideoPlayer.apk 409 | 410 | To play your clips. There is VLC 411 | 412 | * com.borqs.sdaccess=/system/app/DeviceManagementSDAccess.apk 413 | 414 | sdcard access to manage photos, only for this, other apps do it on their own - disable/remove safely 415 | 416 | * com.borqs.tasks=/system/app/Tasks.apk 417 | 418 | task lists for you, quite poor. This app demands `Exchange` to be. Why? 419 | 420 | * com.borqs.twittersync=/system/app/TwitterSyncProvider.apk 421 | 422 | Send your photo to twitter, but no camera soft from borqs already 423 | 424 | * com.borqs.weatherwidget=/system/app/Weather_Widget.apk 425 | 426 | Widget is fine with me but it gets weather from an us-based system. I'm in Europe with other meteo facilities nearby 427 | 428 | * com.cequint.ecid=/system/app/CityID-release.apk 429 | 430 | Says, in which city you are. Are you so drunk? 431 | 432 | * com.drivemode=/system/app/DriveMode_1_0_2_3.apk 433 | 434 | To stop your phone from calling if you drive. And even if you are not, but just in a train 435 | 436 | * com.google.android.apps.books=/system/app/BooksTablet.apk 437 | 438 | Books, in Terrain case on a screen less then your bankcard 439 | 440 | * com.google.android.apps.plus=/system/app/PlusOne.apk 441 | 442 | G+, not for me 443 | 444 | * com.google.android.apps.uploader=/system/app/MediaUploader.apk 445 | 446 | To upload your media to google drive, not for me 447 | 448 | * com.google.android.backup=/system/app/GoogleBackupTransport.apk 449 | 450 | It is about *data* backup, not *settings* or contacts backup. 451 | 452 | * com.google.android.feedback=/system/app/GoogleFeedback.apk 453 | 454 | It is to say, how crappy is google for you 455 | 456 | * com.google.android.gm=/system/app/Gmail.apk 457 | 458 | gmail, Not for me, there is K-9 459 | 460 | * com.google.android.googlequicksearchbox=/system/app/GoogleQuickSearchBox.apk 461 | 462 | Search widget on your screen, I search in firefox 463 | 464 | * com.google.android.marvin.talkback=/system/app/talkback.apk 465 | 466 | If you are alone and want someone speak to you, phone in this case 467 | 468 | * com.google.android.music=/system/app/Music2.apk 469 | 470 | Play music, there is VLC 471 | 472 | * com.google.android.partnersetup=/system/app/GooglePartnerSetup.apk 473 | 474 | Adverts for google partners 475 | 476 | * com.google.android.syncadapters.bookmarks=/system/app/ChromeBookmarksSyncAdapter.apk 477 | 478 | Synchronize chrome bookmarks, but I do not use chrome 479 | 480 | * com.google.android.syncadapters.calendar=/system/app/GoogleCalendarSyncAdapter.apk 481 | 482 | synchronize your stock calendar with google, but I do not use the stock calendar 483 | 484 | * com.google.android.tts=/system/app/GoogleTTS.apk 485 | 486 | text-to-speech, if you cannot read. But then anyway, Terrain's screen size is not for you 487 | 488 | * com.google.android.videos=/system/app/Videos.apk 489 | 490 | Video player, there is VLC 491 | 492 | * com.google.android.voicesearch=/system/app/VoiceSearch.apk 493 | 494 | Search with voice. I'm not crazy to talk to my phone 495 | 496 | * com.google.android.youtube=/system/app/YouTube.apk 497 | 498 | Youtube, firefox plays youtube, so why 499 | 500 | * com.matchboxmobile.wisp=/system/app/WISPr_58_Android22_postpaid.apk 501 | 502 | Some adverts for us-based service providers, I'm in Europe 503 | 504 | * com.moxier.eas=/system/app/Exchange_mx.apk 505 | 506 | Exchange server interaction. Stock `Tasks` do not start without it 507 | 508 | * com.mtag.att.codescanner=/system/app/ATT_code_scanner_vpl_1.2_aligned.apk 509 | 510 | att code-scanner, maybe it works in us better, but here in Europe not at all 511 | 512 | * com.qo.android.sp.oem=/system/app/Quickoffice_Casio_SP_5.0.114_EC.apk 513 | 514 | Quick office discontinued, there are alternatives, I use andropen 515 | 516 | * com.synchronoss.dcs.att.r2g=/system/app/ATT_Ready2Go.apk 517 | 518 | This is to help you screw up your phone, initial initialization 519 | 520 | * com.telenav.app.android.cingular=/system/app/tn74-android-att-7400094.apk 521 | 522 | Some strange app in view of totally free navit 523 | 524 | * com.wildtangent.android=/system/app/ATT_AndroidGames.apk 525 | 526 | I do not play, but would I, not these games 527 | 528 | * com.yellowpages.android.ypmobile=/system/app/YPmobile-P-V3-8-1_B3539.apk 529 | 530 | yp for us mainly, as I got. Anyway, I can type `yellowpages` in firefox 531 | 532 | * org.simalliance.openmobileapi.service=/system/app/SmartcardService.apk 533 | 534 | Some smartcard service, usage **unknown**. Some sources claim it is a part of security interaction in the phone. 535 | I checked: I could change PIN and use PUK with this app disabled, my android password active and works. So what? 536 | 537 | * search.borqssearch=/system/app/BorqsSearchApp.apk 538 | 539 | **unknown**, but perhaps used by other borqs stuff, removed w/o issues 540 | 541 | One comment: applications having `provider` in the name just contains some settings, or store data. The name suggest, which. If `calendar` it means that calendar 542 | data are there. You should be careful disabling/removing such providers. Some third-party programs which tend to replace stock ones replace *only* the interface, 543 | but continue using these *providers*. Some apps, however initiate their own storages. This is better, I guess 544 | 545 | #### Apps which I **put to replace and to improve and/or to extend** the stock, which and why (raw list of packages in `apken3`) 546 | 547 | * be.irm.kmi.meteo=/data/app/be.irm.kmi.meteo-1.apk 548 | 549 | Weather - Belgian meteo institute 550 | 551 | * com.adobe.reader=/data/app/com.adobe.reader-1.apk 552 | 553 | Adobe reader instead of quick-office pdf 554 | 555 | * com.alensw.PicFolder=/data/app/com.alensw.PicFolder-1.apk 556 | 557 | Better gallery 558 | 559 | * com.andronicus.ledclock=/data/app/com.andronicus.ledclock-1.apk 560 | 561 | Nice clock, can play alarm to the music strem and make it **LOUD** via external speakers 562 | 563 | * com.andropenoffice=/mnt/asec/com.andropenoffice-1/pkg.apk 564 | 565 | openoffice for android instead of quick-office 566 | 567 | * com.andrwq.recorder=/mnt/asec/com.andrwq.recorder-1/pkg.apk 568 | 569 | Nice voice recorder 570 | 571 | * com.dw.contacts.free=/data/app/com.dw.contacts.free-1.apk 572 | 573 | DW contacts to eliminate data-connection with the stock one. And it is MUCH better 574 | 575 | * com.flavionet.android.camera.pro=/data/app/com.flavionet.android.camera.pro-1.apk 576 | 577 | camera, paid, but just for me 578 | 579 | * com.flavionet.android.cinema.pro=/data/app/com.flavionet.android.cinema.pro-1.apk 580 | 581 | video, paid, but just for me 582 | 583 | * com.fsck.k9=/data/app/com.fsck.k9-1.apk 584 | 585 | e-mail, does it ALL 586 | 587 | * com.jb.gosms=/mnt/asec/com.jb.gosms-1/pkg.apk 588 | 589 | ALL what you can imagine about sms/mms 590 | 591 | * com.skype.raider=/mnt/asec/com.skype.raider-1/pkg.apk 592 | 593 | skype 594 | 595 | * com.socialnmobile.dictapps.notepad.color.note=/mnt/asec/com.socialnmobile.dictapps.notepad.color.note-1/pkg.apk 596 | 597 | very nice note-taker 598 | 599 | * com.whatsapp=/data/app/com.whatsapp-1.apk 600 | 601 | watsapp 602 | 603 | * jackpal.androidterm=/mnt/asec/jackpal.androidterm-1/pkg.apk 604 | 605 | terminal emulator - the must for me with android 606 | 607 | * joa.zipper.editor=/data/app/joa.zipper.editor-1.apk 608 | 609 | nice text editor, a la gedit 610 | 611 | * jp.co.johospace.jorte=/data/app/jp.co.johospace.jorte-1.apk 612 | 613 | extremely nice calendar+tasks organizer 614 | 615 | * org.joa.zipperplus7v2=/mnt/asec/org.joa.zipperplus7v2-1/pkg.apk 616 | 617 | extreme file manager, including everything, even archiver, if I'm correct 618 | 619 | * org.mozilla.firefox=/mnt/asec/org.mozilla.firefox-1/pkg.apk 620 | 621 | firefox 622 | 623 | * org.navitproject.navit=/mnt/asec/org.navitproject.navit-1/pkg.apk 624 | 625 | navit - offline navigator with absolutely free and extreme quality weekly updated maps 626 | 627 | * org.videolan.vlc=/mnt/asec/org.videolan.vlc-1/pkg.apk 628 | 629 | vlc - plays everything what can sound or be viewed 630 | 631 | * uk.co.nickfines.RealCalc=/mnt/asec/uk.co.nickfines.RealCalc-1/pkg.apk 632 | 633 | Nice and quite scientific calculator 634 | 635 | #### Apps autostart 636 | 637 | The thing is like that. Say, you use skype. When you start the phone and *before* any interaction with skype and *before* any external call/message you may notice that its presence has gone from accounts to be synced and all skype contacts are gone from the contacts list. 638 | 639 | BUT, skype is alive, you can start chating from outside. 640 | 641 | Once you interact with skype somehow (on the phone or chat/call from outside), all these oddities are gone. 642 | 643 | Eventually I spotted the beast: it is like that if you have moved skype to the sd-card. I decided just to keep it in the phone, not a problem, but good to know. Perhaps this affect other programs of such kind. 644 | 645 | *Most likely this effort is to be continued ...* 646 | -------------------------------------------------------------------------------- /system/Superuser.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/system/Superuser.apk -------------------------------------------------------------------------------- /system/adbfb.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/system/adbfb.tar.gz -------------------------------------------------------------------------------- /system/adbs.bat: -------------------------------------------------------------------------------- 1 | adb push run_root_shell /data/local/tmp 2 | adb push sgdisk /data/local/tmp 3 | adb push kas.recovery.bin /data/local/tmp 4 | adb push flash_recovery.sh /data/local/tmp 5 | 6 | adb shell chmod 755 /data/local/tmp/run_root_shell 7 | adb shell chmod 755 /data/local/tmp/sgdisk 8 | adb shell chmod 755 /data/local/tmp/flash_recovery.sh 9 | 10 | adb shell /data/local/tmp/run_root_shell -c '/data/local/tmp/flash_recovery.sh' 11 | -------------------------------------------------------------------------------- /system/adbs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | adb push su /tmp 3 | adb push Superuser.apk /tmp 4 | adb push flash_superuser.sh /tmp 5 | 6 | adb chmod 755 /tmp/flash_superuser.sh 7 | 8 | adb shell "/tmp/flash_superuser.sh" 9 | exit 0 10 | -------------------------------------------------------------------------------- /system/apkdissys: -------------------------------------------------------------------------------- 1 | borqs.soundrecorder 2 | com.amazon.kindle 3 | com.android.DeviceHelp 4 | com.android.apps.tag 5 | com.android.backupconfirm 6 | com.android.browser 7 | com.android.calculator2 8 | com.android.calendar 9 | com.android.contacts.map 10 | com.android.deskclock 11 | com.android.email 12 | com.android.facelock 13 | com.android.gallery3d 14 | com.android.htmlviewer 15 | com.android.magicsmoke 16 | com.android.music 17 | com.android.musicfx 18 | com.android.musicvis 19 | com.android.noisefield 20 | com.android.phasebeam 21 | com.android.protips 22 | com.android.providers.attxmlprovider 23 | com.android.providers.calendar 24 | com.android.providers.partnerbookmarks 25 | com.android.sharedstoragebackup 26 | com.android.videoeditor 27 | com.android.voicedialer 28 | com.android.wallpaper 29 | com.android.wallpaper.holospiral 30 | com.android.wallpaper.livepicker 31 | com.att.eptt 32 | com.att.myWireless 33 | com.borqs.camera 34 | com.borqs.dm 35 | com.borqs.exif 36 | com.borqs.facebooksyncadapter 37 | com.borqs.filemanager 38 | com.borqs.flickr 39 | com.borqs.gif 40 | com.borqs.hotspot 41 | com.borqs.movie 42 | com.borqs.sdaccess 43 | com.borqs.tasks 44 | com.borqs.twittersync 45 | com.borqs.weatherwidget 46 | com.cequint.ecid 47 | com.drivemode 48 | com.google.android.apps.books 49 | com.google.android.apps.plus 50 | com.google.android.apps.uploader 51 | com.google.android.backup 52 | com.google.android.feedback 53 | com.google.android.gm 54 | com.google.android.googlequicksearchbox 55 | com.google.android.marvin.talkback 56 | com.google.android.music 57 | com.google.android.partnersetup 58 | com.google.android.syncadapters.bookmarks 59 | com.google.android.syncadapters.calendar 60 | com.google.android.tts 61 | com.google.android.videos 62 | com.google.android.voicesearch 63 | com.google.android.youtube 64 | com.matchboxmobile.wisp 65 | com.moxier.eas 66 | com.mtag.att.codescanner 67 | com.qo.android.sp.oem 68 | com.synchronoss.dcs.att.r2g 69 | com.telenav.app.android.cingular 70 | com.wildtangent.android 71 | com.yellowpages.android.ypmobile 72 | org.simalliance.openmobileapi.service 73 | search.borqssearch 74 | -------------------------------------------------------------------------------- /system/apken3: -------------------------------------------------------------------------------- 1 | MyING.be 2 | be.irm.kmi.meteo 3 | be.stib 4 | com.adobe.reader 5 | com.alensw.PicFolder 6 | com.andronicus.ledclock 7 | com.andropenoffice 8 | com.andrwq.recorder 9 | com.dw.contacts.free 10 | com.flavionet.android.camera.pro 11 | com.flavionet.android.cinema.pro 12 | com.fsck.k9 13 | com.jb.gosms 14 | com.skype.raider 15 | com.socialnmobile.dictapps.notepad.color.note 16 | com.whatsapp 17 | jackpal.androidterm 18 | joa.zipper.editor 19 | jp.co.johospace.jorte 20 | org.joa.zipperplus7v2 21 | org.mozilla.firefox 22 | org.navitproject.navit 23 | org.videolan.vlc 24 | uk.co.nickfines.RealCalc 25 | -------------------------------------------------------------------------------- /system/apkensys: -------------------------------------------------------------------------------- 1 | android 2 | com.android.att.settings.provider 3 | com.android.bluetooth 4 | com.android.certinstaller 5 | com.android.chrome 6 | com.android.contacts 7 | com.android.defcontainer 8 | com.android.keychain 9 | com.android.launcher 10 | com.android.mms 11 | com.android.nfc 12 | com.android.nfchiddenmenu 13 | com.android.packageinstaller 14 | com.android.phone 15 | com.android.providers.applications 16 | com.android.providers.contacts 17 | com.android.providers.downloads 18 | com.android.providers.downloads.ui 19 | com.android.providers.drm 20 | com.android.providers.media 21 | com.android.providers.settings 22 | com.android.providers.telephony 23 | com.android.providers.userdictionary 24 | com.android.provision 25 | com.android.settings 26 | com.android.smspush 27 | com.android.stk 28 | com.android.systemui 29 | com.android.vending 30 | com.android.vpndialogs 31 | com.google.android.apps.maps 32 | com.google.android.gms 33 | com.google.android.gsf 34 | com.google.android.gsf.login 35 | com.google.android.location 36 | com.google.android.onetimeinitializer 37 | com.google.android.street 38 | com.google.android.syncadapters.contacts 39 | com.google.android.talk 40 | com.ipsec.vpnclient 41 | com.koushikdutta.superuser 42 | com.kpt_nec.adaptxt 43 | com.nec.android.ncmc.ecomode 44 | com.quicinc.fmradio 45 | -------------------------------------------------------------------------------- /system/flash_superuser.sh: -------------------------------------------------------------------------------- 1 | #!/sbin/sh 2 | 3 | cd /tmp #workdir 4 | mount /dev/block/mmcblk0p12 /system #mounting system 5 | cp su /system/xbin/su #copying su binary 6 | chown 0:0 /system/xbin/su #chown on su 7 | chmod 6755 /system/xbin/su #chmod on su 8 | ln -s /system/xbin/su /system/bin/su #ln to /system/bin 9 | cp Superuser.apk /system/app #placing apk 10 | chmod 644 /system/app/Superuser.apk #chmod on apk 11 | umount /system #unmount system 12 | exit 0 #exiting 13 | 14 | -------------------------------------------------------------------------------- /system/su: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alex-kas/nec_terrain/bb6828db0cb5c2d2edf4e743a636e5895e491828/system/su -------------------------------------------------------------------------------- /ts.md: -------------------------------------------------------------------------------- 1 | *You can find [here](system-howto.md) how to tweak your system.* 2 | 3 | --- 4 | 5 | ### Troubleshooting 6 | 7 | Interaction of your pc with the phone may stall. No clue why exactly but if you believe that some operation cannot last so long you can try to wake up `adb` either by 8 | trying `adb shell` from another terminal on your pc or by unplugging/re-plugging the usb cable. In extreme case you may have to take the battery off, then place it back and then boot your phone 9 | with *vol-down* pressed. (the latter happened to me only once). 10 | 11 | Notice that some operations take indeed long time. Sometimes mounting of a partition takes up to 15 seconds. Again, no clue, why. 12 | --------------------------------------------------------------------------------