Last active
July 2, 2020 14:18
-
-
Save ChronoMonochrome/d298a1ad5747f2566dc927cc8db99b4a to your computer and use it in GitHub Desktop.
Qualcomm QMI kickstart (qcks)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This file has been generated by the Hex-Rays decompiler. | |
Copyright (c) 2007-2014 Hex-Rays <[email protected]> | |
Detected compiler: GNU C++ | |
*/ | |
#include <defs.h> | |
//------------------------------------------------------------------------- | |
// Function declarations | |
// int __fastcall prctl(_DWORD, _DWORD, _DWORD, _DWORD); weak | |
// int __fastcall setuid(_DWORD); weak | |
// int __fastcall capset(_DWORD, _DWORD); weak | |
// int __fastcall stat(_DWORD, _DWORD); weak | |
// FILE *fopen(const char *, const char *); | |
// int _android_log_print(_DWORD, _DWORD, const char *, ...); weak | |
// int fclose(FILE *); | |
// int __fastcall strlcpy(_DWORD, _DWORD, _DWORD); weak | |
// int __fastcall strlcat(_DWORD, _DWORD, _DWORD); weak | |
// int snprintf(char *, size_t, const char *, ...); | |
// int system(const char *); | |
// int __fastcall _stack_chk_fail(_DWORD); weak | |
// int printf(const char *, ...); | |
// int puts(const char *); | |
// int __fastcall ioctl(_DWORD, _DWORD); weak | |
// int __fastcall usleep(_DWORD); weak | |
// size_t strlen(const char *); | |
// void *memcpy(void *, const void *, size_t); | |
// int __fastcall getopt_long(_DWORD, _DWORD, _DWORD, _DWORD); weak | |
// int __fastcall _strlen_chk(_DWORD, _DWORD); weak | |
// int __fastcall open(_DWORD, _DWORD); weak | |
// int __fastcall property_get(_DWORD, _DWORD, _DWORD); weak | |
// int strncmp(const char *, const char *, size_t); | |
// int __fastcall close(_DWORD); weak | |
// int __fastcall fork(_DWORD); weak | |
// int __fastcall execve(_DWORD, _DWORD, _DWORD); weak | |
// void exit(int); | |
// int __fastcall kill(_DWORD, _DWORD); weak | |
// int __fastcall wait(_DWORD); weak | |
int set_capabilities(); | |
signed int __fastcall checkFileAvailable(const char *firmwareImage, int readOnly); // idb | |
signed int load_efs_images(); | |
int usage(); | |
signed int __fastcall wake_device(int dev_fd); // idb | |
signed int __fastcall check_port_exists(const char *devName, int read_mode); // idb | |
signed int __fastcall load_sahara_images(char *flag, char *firmwareImage, char *dataCP_log, int tombstonesQcks); // idb | |
signed int __fastcall memory_dump(char *firmwareImage, char *dataCP_log); // idb | |
signed int __fastcall load_dload(char *firmwareImage); // idb | |
signed int __fastcall build_path(char *fullPath, const char *execPath, const char *progName, int commandLength); // idb | |
signed int __fastcall main(int argc, const char **argv); | |
int j_j_puts(const char *); | |
int j_puts(const char *); | |
//------------------------------------------------------------------------- | |
// Data declarations | |
_UNKNOWN unk_2518; // weak | |
char *off_4000 = "dloadport"; // weak | |
void *off_4090 = &gEFSKSFile; // weak | |
char *off_4094[4] = { "-p", "/dev/ttyUSB0", "-w", "/dev/block/modem/dump_path/" }; // weak | |
char *off_4098[3] = { "/dev/ttyUSB0", "-w", "/dev/block/modem/dump_path/" }; // weak | |
char *off_409C[2] = { "-w", "/dev/block/modem/dump_path/" }; // weak | |
char *off_40A0 = "/dev/block/modem/dump_path/"; // weak | |
char algn_40A4[4] = { '\0', '\0', '\0', '\0' }; // weak | |
char aDataCp_log[14] = "/data/cp_log/"; // weak | |
char aAcdb_mbn[9] = "acdb.mbn"; // weak | |
char aDevTtyusb0[13] = "/dev/ttyUSB0"; // weak | |
char aTombstonesQcks[18] = "/tombstones/qcks/"; // weak | |
char aDevBlockMode_1[25] = "/dev/block/modem/m9kefs3"; // weak | |
char aFirmwareImageM[29] = "/firmware/image/mdm_acdb.img"; // weak | |
char aDevTtyusb0_0[13] = "/dev/ttyUSB0"; // weak | |
char aEfs2_mbn[9] = "efs2.mbn"; // weak | |
char aEfs3_mbn[9] = "efs3.mbn"; // weak | |
char aDevBlockModemM[25] = "/dev/block/modem/m9kefs1"; // weak | |
char aDevBlockMode_0[25] = "/dev/block/modem/m9kefs2"; // weak | |
char aEfs1_mbn[9] = "efs1.mbn"; // weak | |
char aFirmwareImage[17] = "/firmware/image/"; // weak | |
char gEFSKSFile[1024]; // idb | |
int bootProtocolDload; // weak | |
char gCommand[1024]; // idb | |
int gChildPid; // weak | |
char gKSFile[1024]; // idb | |
// extern _UNKNOWN _stack_chk_guard; weak | |
// extern _UNKNOWN optarg; weak | |
//----- (00000A68) -------------------------------------------------------- | |
int set_capabilities() | |
{ | |
__user_cap_header_struct *v1; // [sp+Ch] [bp-1Ch]@1 | |
int v2; // [sp+10h] [bp-18h]@1 | |
__user_cap_data_struct *v3; // [sp+14h] [bp-14h]@1 | |
int v4; // [sp+18h] [bp-10h]@1 | |
int v5; // [sp+1Ch] [bp-Ch]@1 | |
prctl(8, 1, 0, 0); | |
setuid(1000); | |
v5 = 1; | |
v4 = 0x203002; | |
v3 = 0x203002; | |
v1 = 0x19980330; | |
v2 = 0; | |
return capset(&v1, &v3); | |
} | |
// 858: using guessed type int __fastcall prctl(_DWORD, _DWORD, _DWORD, _DWORD); | |
// 864: using guessed type int __fastcall setuid(_DWORD); | |
// 870: using guessed type int __fastcall capset(_DWORD, _DWORD); | |
//----- (00000AA8) -------------------------------------------------------- | |
signed int __fastcall checkFileAvailable(const char *firmwareImage, int readOnly) | |
{ | |
int v4; // r1@2 | |
const char *v5; // r2@2 | |
FILE *v6; // r5@4 | |
int v8; // [sp+0h] [bp-78h]@1 | |
if ( stat(firmwareImage, &v8) < 0 ) | |
{ | |
v4 = "kickstart-qcks"; | |
v5 = "File '%s' was not found"; | |
err_out: | |
_android_log_print(6, v4, v5, firmwareImage); | |
return 1; | |
} | |
if ( readOnly ) | |
{ | |
v6 = fopen(firmwareImage, "rb"); | |
if ( v6 ) | |
{ | |
_android_log_print(4, "kickstart-qcks", "File:'%s' is available for reading", firmwareImage); | |
fclose(v6); | |
return 0; | |
} | |
v4 = "kickstart-qcks"; | |
v5 = "File: %s could not be opened for reading"; | |
goto err_out; | |
} | |
return 0; | |
} | |
// 87C: using guessed type int __fastcall stat(_DWORD, _DWORD); | |
// 894: using guessed type int _android_log_print(_DWORD, _DWORD, const char *, ...); | |
//----- (00000B28) -------------------------------------------------------- | |
signed int load_efs_images() | |
{ | |
int v0; // r1@3 | |
const char *v1; // r2@3 | |
signed int result; // r0@26 | |
char v3; // [sp+14h] [bp-202Ch]@2 | |
char v4; // [sp+814h] [bp-182Ch]@4 | |
int v5; // [sp+1014h] [bp-102Ch]@5 | |
int v6; // [sp+1814h] [bp-82Ch]@6 | |
int v7; // [sp+2014h] [bp-2Ch]@1 | |
v7 = _stack_chk_guard; | |
_android_log_print(4, "kickstart-qcks", "EFS Prepend"); | |
if ( !aFirmwareImage[0] ) | |
{ | |
if ( strlcpy(&v3, aEfs1_mbn, 2048) <= 0x7FF | |
&& strlcpy(&v4, aEfs2_mbn, 2048) <= 0x7FF | |
&& strlcpy(&v5, aEfs3_mbn, 2048) <= 0x7FF | |
&& strlcpy(&v6, aAcdb_mbn, 2048) <= 0x7FF ) | |
{ | |
goto LABEL_17; | |
} | |
LABEL_3: | |
v0 = "kickstart-qcks"; | |
v1 = "String was truncated while copying"; | |
LABEL_26: | |
_android_log_print(6, v0, v1); | |
result = 1; | |
goto LABEL_35; | |
} | |
if ( strlcpy(&v3, aFirmwareImage, 2048) > 0x7FF | |
|| strlcpy(&v4, aFirmwareImage, 2048) > 0x7FF | |
|| strlcpy(&v5, aFirmwareImage, 2048) > 0x7FF | |
|| strlcpy(&v6, aFirmwareImage, 2048) > 0x7FF ) | |
{ | |
goto LABEL_3; | |
} | |
if ( strlcat(&v3, aEfs1_mbn, 2048) > 0x7FF | |
|| strlcat(&v4, aEfs2_mbn, 2048) > 0x7FF | |
|| strlcat(&v5, aEfs3_mbn, 2048) > 0x7FF | |
|| strlcat(&v6, aAcdb_mbn, 2048) > 0x7FF ) | |
{ | |
v0 = "kickstart-qcks"; | |
v1 = "String was truncated while concatenating"; | |
goto LABEL_26; | |
} | |
LABEL_17: | |
if ( checkFileAvailable(&v3, 1) == 1 | |
|| checkFileAvailable(&v4, 1) == 1 | |
|| checkFileAvailable(aDevBlockModemM, 1) == 1 | |
|| checkFileAvailable(aDevBlockMode_0, 1) == 1 | |
|| checkFileAvailable(&v6, 1) == 1 | |
|| checkFileAvailable(aFirmwareImageM, 1) == 1 ) | |
{ | |
v0 = "kickstart-qcks"; | |
v1 = "Prepend failed."; | |
goto LABEL_26; | |
} | |
_android_log_print(4, "kickstart-qcks", "Reading RAW EFS1 partition"); | |
if ( snprintf(gCommand, 0x400u, "dd if=%s of=%stemp.dump bs=1024 count=3072", aDevBlockModemM, aTombstonesQcks) > 0x3FF | |
|| (_android_log_print(4, "kickstart-qcks", "Running %s", gCommand), | |
system(gCommand), | |
snprintf(gCommand, 0x400u, "chmod 666 %stemp.dump", aTombstonesQcks) > 0x3FF) | |
|| (system(gCommand), | |
_android_log_print(4, "kickstart-qcks", "Combining Header1 with RAW EFS1 partition"), | |
snprintf( | |
gCommand, | |
0x400u, | |
"cat %s%s %stemp.dump > %sefs1.bin", | |
aFirmwareImage, | |
aEfs1_mbn, | |
aTombstonesQcks, | |
aTombstonesQcks) > 0x3FF) | |
|| (_android_log_print(4, "kickstart-qcks", "Running %s", gCommand), | |
system(gCommand), | |
_android_log_print(4, "kickstart-qcks", "Reading RAW EFS2 partition"), | |
snprintf(gCommand, 0x400u, "dd if=%s of=%stemp.dump bs=1024 count=3072", aDevBlockMode_0, aTombstonesQcks) > 0x3FF) | |
|| (_android_log_print(4, "kickstart-qcks", "Running %s", gCommand), | |
system(gCommand), | |
_android_log_print(4, "kickstart-qcks", "Combining Header2 with RAW EFS2 partition"), | |
snprintf( | |
gCommand, | |
0x400u, | |
"cat %s%s %stemp.dump > %sefs2.bin", | |
aFirmwareImage, | |
aEfs2_mbn, | |
aTombstonesQcks, | |
aTombstonesQcks) > 0x3FF) | |
|| (_android_log_print(4, "kickstart-qcks", "Running %s", gCommand), | |
system(gCommand), | |
_android_log_print(4, "kickstart-qcks", "Reading RAW EFS3 partition"), | |
snprintf(gCommand, 0x400u, "dd if=%s of=%stemp.dump bs=1024 count=3072", aDevBlockMode_1, aTombstonesQcks) > 0x3FF) | |
|| (_android_log_print(4, "kickstart-qcks", "Running %s", gCommand), | |
system(gCommand), | |
_android_log_print(4, "kickstart-qcks", "Combining Header3 with RAW EFS3 partition"), | |
snprintf( | |
gCommand, | |
0x400u, | |
"cat %s%s %stemp.dump > %sefs3.bin", | |
aFirmwareImage, | |
aEfs3_mbn, | |
aTombstonesQcks, | |
aTombstonesQcks) > 0x3FF) | |
|| (_android_log_print(4, "kickstart-qcks", "Running %s", gCommand), | |
system(gCommand), | |
_android_log_print(4, "kickstart-qcks", "Combining ACDB Header with ACDB binary"), | |
snprintf( | |
gCommand, | |
0x400u, | |
"cat %s%s %s > %sacdb.bin", | |
aFirmwareImage, | |
aAcdb_mbn, | |
aFirmwareImageM, | |
aTombstonesQcks) > 0x3FF) ) | |
{ | |
v0 = "kickstart-qcks"; | |
v1 = "String was truncated in snprintf"; | |
goto LABEL_26; | |
} | |
_android_log_print(4, "kickstart-qcks", "Running %s", gCommand); | |
system(gCommand); | |
result = 0; | |
LABEL_35: | |
if ( v7 != _stack_chk_guard ) | |
_stack_chk_fail(result); | |
return result; | |
} | |
// 894: using guessed type int _android_log_print(_DWORD, _DWORD, const char *, ...); | |
// 8AC: using guessed type int __fastcall strlcpy(_DWORD, _DWORD, _DWORD); | |
// 8B8: using guessed type int __fastcall strlcat(_DWORD, _DWORD, _DWORD); | |
// 8DC: using guessed type int __fastcall _stack_chk_fail(_DWORD); | |
// 3FB8: using guessed type void *_stack_chk_fail_ptr; | |
//----- (00000FC0) -------------------------------------------------------- | |
int usage() | |
{ | |
printf("\nBuilt on '%s' at '%s'\n", "May 8 2014", "00:04:00"); | |
return j_j_puts("\n\nExample usage:\n\tsudo qcks m\t\t<-- Memory dump\n\tsudo qcks p\t\t<-- Prepend, creates efs1.bin and efs2.bin\n\tsudo qcks l\t\t<-- Prepend + Load ALL Images\n\tsudo qcks d\t\t<-- Load DLOAD images\n\tsudo qcks s\t\t<-- Load SAHARA Images (does not do Prepend)\n"); | |
} | |
//----- (00000FF0) -------------------------------------------------------- | |
signed int __fastcall wake_device(int dev_fd) | |
{ | |
signed int result; // r0@2 | |
_android_log_print(4, "kickstart-qcks", "Trying to bring MDM9K out of reset"); | |
if ( ioctl(dev_fd, 0xCC01) >= 0 ) | |
{ | |
result = 0; | |
} | |
else | |
{ | |
_android_log_print(6, "kickstart-qcks", "Could not issue ioctl WAKE_CHARM"); | |
result = 1; | |
} | |
return result; | |
} | |
// 894: using guessed type int _android_log_print(_DWORD, _DWORD, const char *, ...); | |
// 900: using guessed type int __fastcall ioctl(_DWORD, _DWORD); | |
//----- (00001034) -------------------------------------------------------- | |
signed int __fastcall check_port_exists(const char *devName, int read_mode) | |
{ | |
int retries; // r5@1 | |
int retries2; // r5@5 | |
FILE *v6; // r0@7 | |
char *LOG_TAG; // r1@9 | |
const char *LOG_MESSAGE; // r2@9 | |
struct stat v10; // [sp+8h] [bp-80h]@3 | |
_android_log_print(4, "kickstart-qcks", "Testing if port \"%s\" exists", devName); | |
retries = 0; | |
while ( stat(devName, &v10) < 0 ) | |
{ | |
_android_log_print(6, "kickstart-qcks", "Couldn't find \"%s\", %i of %i", devName, ++retries, 10); | |
usleep(500000); | |
if ( retries == 10 ) | |
{ | |
LOG_TAG = "kickstart-qcks"; | |
LOG_MESSAGE = "'%s' was not found"; | |
err_log_and_out: | |
_android_log_print(6, LOG_TAG, LOG_MESSAGE, devName); | |
return 1; | |
} | |
} | |
if ( read_mode ) | |
{ | |
_android_log_print(4, "kickstart-qcks", "Attempting to open port \"%s\" for reading", devName); | |
retries2 = 0; | |
do | |
{ | |
v6 = fopen(devName, "r"); | |
if ( v6 ) | |
{ | |
fclose(v6); | |
return 0; | |
} | |
_android_log_print(6, "kickstart-qcks", "Couldn't read \"%s\", %i of %i", devName, ++retries2, 10); | |
usleep(500000); | |
} | |
while ( retries2 != 10 ); | |
LOG_TAG = "kickstart-qcks"; | |
LOG_MESSAGE = "'%s' could not be opened for reading"; | |
goto err_log_and_out; | |
} | |
return 0; | |
} | |
// 87C: using guessed type int __fastcall stat(_DWORD, _DWORD); | |
// 894: using guessed type int _android_log_print(_DWORD, _DWORD, const char *, ...); | |
// 90C: using guessed type int __fastcall usleep(_DWORD); | |
//----- (00001134) -------------------------------------------------------- | |
signed int __fastcall load_sahara_images(char *flag, char *firmwareImage, char *dataCP_log, int tombstonesQcks) | |
{ | |
int v8; // r1@2 | |
const char *v9; // r2@2 | |
int commandLength; // r0@3 | |
int retCode; // r5@4 | |
signed int result; // r0@10 | |
_android_log_print(4, "kickstart-qcks", "Loading Sahara images"); | |
if ( check_port_exists(aDevTtyusb0_0, 0) == 1 ) | |
{ | |
v8 = "kickstart-qcks"; | |
v9 = "LoadSahara failed"; | |
LABEL_9: | |
_android_log_print(6, v8, v9); | |
return 1; | |
} | |
commandLength = snprintf( | |
gCommand, | |
0x400u, | |
"%s -v %s -w %s -p %s -f %d -r %d -s 2:%samss.mbn -s 6:%sapps.mbn -s 8:%sdsp1.mbn -s 11:%sosbl.mbn -s" | |
" 12:%sdsp2.mbn -s 21:%ssbl1.mbn -s 22:%ssbl2.mbn -s 23:%srpm.mbn -s 28:%sdsp3.mbn -s 16:%sefs1.bin -" | |
"s 17:%sefs2.bin -s 20:%sefs3.bin -s 29:%sacdb.bin", | |
gKSFile, | |
flag, | |
dataCP_log, | |
aDevTtyusb0_0, | |
bootProtocolDload, | |
21, | |
firmwareImage, | |
firmwareImage, | |
firmwareImage, | |
firmwareImage, | |
firmwareImage, | |
firmwareImage, | |
firmwareImage, | |
firmwareImage, | |
firmwareImage, | |
tombstonesQcks, | |
tombstonesQcks, | |
tombstonesQcks, | |
tombstonesQcks); | |
v8 = "kickstart-qcks"; | |
if ( commandLength >= 0x400 ) | |
{ | |
v9 = "String was truncated in snprintf"; | |
goto LABEL_9; | |
} | |
_android_log_print(6, "kickstart-qcks", "RUNNING:\t%s", gCommand); | |
retCode = system(gCommand); | |
_android_log_print(4, "kickstart-qcks", "RetCode = %u", retCode); | |
v8 = "kickstart-qcks"; | |
if ( retCode ) | |
{ | |
if ( retCode == 0x500 ) | |
{ | |
v9 = "ERROR: RAM dumps were forced unexpectedly"; | |
goto LABEL_9; | |
} | |
if ( retCode != 0x400 ) | |
{ | |
_android_log_print(6, "kickstart-qcks", "ERROR: ks return code was %d, something failed", retCode); | |
return 1; | |
} | |
_android_log_print(6, "kickstart-qcks", "ERROR: RAM dumps were closed by silent reset"); | |
result = 2; | |
} | |
else | |
{ | |
_android_log_print(6, "kickstart-qcks", "Sahara transfer completed successfully"); | |
result = 0; | |
} | |
return result; | |
} | |
// 894: using guessed type int _android_log_print(_DWORD, _DWORD, const char *, ...); | |
// 78AC: using guessed type int bootProtocolDload; | |
//----- (0000126C) -------------------------------------------------------- | |
signed int __fastcall memory_dump(char *firmwareImage, char *dataCP_log) | |
{ | |
_android_log_print(4, "kickstart-qcks", "Memory Dump"); | |
return load_sahara_images("-m ", firmwareImage, dataCP_log, aTombstonesQcks); | |
} | |
// 894: using guessed type int _android_log_print(_DWORD, _DWORD, const char *, ...); | |
//----- (000012A4) -------------------------------------------------------- | |
signed int __fastcall load_dload(char *firmwareImage) | |
{ | |
signed int res; // r5@1 | |
char *v3; // r1@2 | |
const char *v4; // r2@2 | |
int tmpRes; // r0@4 | |
_android_log_print(4, "kickstart-qcks", "Loading Dload"); | |
res = check_port_exists(aDevTtyusb0, 0); | |
if ( res != 1 ) | |
{ | |
if ( snprintf(gCommand, 0x400u, "%s -v -p %s -d 21:%ssbl1.mbn", gKSFile, aDevTtyusb0, firmwareImage) >= 0x400 ) | |
{ | |
_android_log_print(6, "kickstart-qcks", "String was truncated in snprintf"); | |
} | |
else | |
{ | |
_android_log_print(6, "kickstart-qcks", "RUNNING:\t%s", gCommand); | |
tmpRes = system(gCommand); | |
v3 = "kickstart-qcks"; | |
res = tmpRes; | |
if ( !tmpRes ) | |
{ | |
v4 = "Dload completed successfully"; | |
goto log_and_out; | |
} | |
_android_log_print(6, "kickstart-qcks", "ERROR: Dload return code was %d, something failed", tmpRes); | |
usleep(10000); | |
} | |
return 1; | |
} | |
v3 = "kickstart-qcks"; | |
v4 = "DLoad failed"; | |
log_and_out: | |
_android_log_print(6, v3, v4); | |
return res; | |
} | |
// 894: using guessed type int _android_log_print(_DWORD, _DWORD, const char *, ...); | |
// 90C: using guessed type int __fastcall usleep(_DWORD); | |
//----- (0000136C) -------------------------------------------------------- | |
signed int __fastcall build_path(char *fullPath, const char *execPath, const char *progName, int commandLength) | |
{ | |
int pathLen; // r4@1 | |
size_t progNameLen; // r9@1 | |
int totalCommandLength; // r6@7 | |
signed int result; // r0@8 | |
pathLen = strlen(execPath) - 1; | |
progNameLen = strlen(progName); | |
while ( 1 ) | |
{ | |
if ( pathLen < 0 ) | |
goto verify_command_length; | |
if ( execPath[pathLen] == '/' ) | |
break; | |
--pathLen; | |
} | |
if ( pathLen >= commandLength ) | |
return 1; | |
strlcpy(fullPath, execPath, pathLen + 2); | |
verify_command_length: | |
totalCommandLength = pathLen + 1 + progNameLen; | |
if ( totalCommandLength > commandLength ) | |
return 1; | |
strlcpy(&fullPath[pathLen + 1], progName, progNameLen + 1); | |
result = 0; | |
fullPath[totalCommandLength] = 0; | |
return result; | |
} | |
// 8AC: using guessed type int __fastcall strlcpy(_DWORD, _DWORD, _DWORD); | |
//----- (000013C8) -------------------------------------------------------- | |
signed int __fastcall main(int argc, const char **argv) | |
{ | |
int option; // r0@2 | |
int v5; // r3@2 | |
char *LOG_TAG; // r1@20 | |
const char *LOG_MESSAGE; // r2@20 | |
_DWORD *optarg_ref; // r3@8 | |
char *devName; // r0@8 | |
int dev_fd; // r4@37 | |
signed int res; // r2@39 MAPDST | |
signed int enableDebug; // r6@41 | |
signed int unkSaharaLoadFLag; // r8@43 | |
int v14; // r1@46 | |
const char *v15; // r2@46 | |
char *bootProtocol; // r3@48 | |
signed int result; // r0@51 | |
signed int retries; // r7@54 | |
char *saharaLoadFlag; // r0@57 | |
char *firmwareImage; // r1@57 | |
char *dataCP_log; // r2@57 | |
int tombstonesQcks; // r3@57 | |
int v23; // r0@70 | |
int childPid; // r0@70 | |
signed int v25; // r7@80 | |
signed int v26; // r0@82 | |
int bootRetries; // [sp+28h] [bp-138h]@1 | |
char *const envp; // [sp+2Ch] [bp-134h]@73 | |
char *efsksArgv[5]; // [sp+30h] [bp-130h]@73 | |
int v31; // [sp+44h] [bp-11Ch]@73 | |
const char optstring[144]; // [sp+48h] [bp-118h]@1 | |
char isMdmDebugEnabled; // [sp+D8h] [bp-88h]@39 | |
int v34; // [sp+134h] [bp-2Ch]@1 | |
res = -1; | |
bootRetries = 0; | |
v34 = _stack_chk_guard; | |
memcpy(optstring, &off_4000, 144u); | |
if ( argc <= 1 ) | |
{ | |
show_usage: | |
usage(); | |
goto err_out; | |
} | |
while ( 1 ) | |
{ | |
option = getopt_long(argc, argv, "d:s:i:r:1:2:3:e:", optstring); | |
if ( option == 'd' ) | |
{ | |
devName = aDevTtyusb0; | |
optarg_ref = &optarg; | |
goto set_dev_name; | |
} | |
if ( option <= 'd' ) | |
break; | |
if ( option == 'i' ) | |
{ | |
if ( strlcpy(aFirmwareImage, optarg, 1024) >= 0x400 ) | |
goto string_was_truncated; | |
if ( aFirmwareImage[_strlen_chk(aFirmwareImage, 1024) - 1] != '/' ) | |
{ | |
LOG_TAG = "kickstart-qcks"; | |
LOG_MESSAGE = "PATHTOIMAGES is not formed well, must *end* with a '/'"; | |
goto err_log_and_out; | |
} | |
} | |
else if ( option > 'i' ) | |
{ | |
if ( option == 'r' ) | |
{ | |
if ( strlcpy(aDataCp_log, optarg, 1024) >= 0x400 ) | |
goto string_was_truncated; | |
if ( aDataCp_log[_strlen_chk(aDataCp_log, 1024) - 1] != '/' ) | |
{ | |
LOG_TAG = "kickstart-qcks"; | |
LOG_MESSAGE = "PATHFORRAMDUMP is not formed well, must *end* with a '/'"; | |
goto err_log_and_out; | |
} | |
} | |
else | |
{ | |
if ( option != 's' ) | |
{ | |
unrecogized_argv: | |
_android_log_print(6, "kickstart-qcks", "Unrecognized option", v5, 0); | |
goto show_usage; | |
} | |
optarg_ref = &optarg; | |
devName = aDevTtyusb0_0; | |
set_dev_name: | |
if ( strlcpy(devName, *optarg_ref, 1024) >= 0x400 ) | |
goto string_was_truncated; | |
} | |
} | |
else | |
{ | |
if ( option != 'e' ) | |
goto unrecogized_argv; | |
if ( strlcpy(aTombstonesQcks, optarg, 1024) >= 0x400 ) | |
{ | |
string_was_truncated: | |
LOG_TAG = "kickstart-qcks"; | |
LOG_MESSAGE = "String was truncated while copying"; | |
goto err_log_and_out; | |
} | |
if ( aTombstonesQcks[_strlen_chk(aTombstonesQcks, 1024) - 1] != '/' ) | |
{ | |
LOG_TAG = "kickstart-qcks"; | |
LOG_MESSAGE = "PATHFOREFS is not formed well, must *end* with a '/'"; | |
goto err_log_and_out; | |
} | |
} | |
} | |
if ( option == '2' ) | |
{ | |
optarg_ref = &optarg; | |
devName = aDevBlockMode_0; | |
goto set_dev_name; | |
} | |
if ( option > '2' ) | |
{ | |
if ( option != '3' ) | |
goto unrecogized_argv; | |
optarg_ref = &optarg; | |
devName = aDevBlockMode_1; | |
goto set_dev_name; | |
} | |
v5 = option + 1; | |
if ( option != -1 ) | |
{ | |
if ( option != '1' ) | |
goto unrecogized_argv; | |
optarg_ref = &optarg; | |
devName = aDevBlockModemM; | |
goto set_dev_name; | |
} | |
set_capabilities(); | |
_android_log_print(4, "kickstart-qcks", "PARAMETER VALUES"); | |
_android_log_print(4, "kickstart-qcks", "COMPORT_DLOAD=%s", aDevTtyusb0, 0); | |
_android_log_print(4, "kickstart-qcks", "COMPORT_SAHARA=%s", aDevTtyusb0_0); | |
_android_log_print(4, "kickstart-qcks", "PATHTOIMAGES=%s", aFirmwareImage); | |
_android_log_print(4, "kickstart-qcks", "PATHFORRAMDUMP=%s", aDataCp_log); | |
_android_log_print(4, "kickstart-qcks", "EFSRAW1=%s", aDevBlockModemM); | |
_android_log_print(4, "kickstart-qcks", "EFSRAW2=%s", aDevBlockMode_0); | |
_android_log_print(4, "kickstart-qcks", "EFSRAW3=%s", aDevBlockMode_1); | |
_android_log_print(4, "kickstart-qcks", "Header1=%s", aEfs1_mbn); | |
_android_log_print(4, "kickstart-qcks", "Header2=%s", aEfs2_mbn); | |
_android_log_print(4, "kickstart-qcks", "Header3=%s", aEfs3_mbn); | |
build_path(gKSFile, *argv, "ks", 1024); | |
if ( checkFileAvailable(gKSFile, 0) == 1 ) | |
goto err_out; | |
build_path(gEFSKSFile, *argv, "efsks", 1024); | |
if ( checkFileAvailable(gEFSKSFile, 0) == 1 ) | |
goto err_out; | |
if ( check_port_exists("/dev/mdm", 0) != 1 ) | |
{ | |
dev_fd = open("/dev/mdm", 2048); | |
if ( dev_fd < 0 ) | |
{ | |
_android_log_print(6, "kickstart-qcks", "Could not open device %s", "/dev/mdm"); | |
goto err_out; | |
} | |
res = property_get("mdm.debug", &isMdmDebugEnabled, "false"); | |
if ( res > 0 && !strncmp(&isMdmDebugEnabled, "true", res) ) | |
{ | |
enableDebug = 1; | |
_android_log_print(6, "kickstart-qcks", "Property mdm.debug=true. Running in MDM debug mode"); | |
} | |
else | |
{ | |
enableDebug = 0; | |
} | |
unkSaharaLoadFLag = 1; | |
retry: | |
while ( wake_device(dev_fd) == 1 ) | |
; | |
if ( check_port_exists(aDevTtyusb0, 0) == 1 ) | |
{ | |
v14 = "kickstart-qcks"; | |
v15 = "1st enumeration failed"; | |
goto log_and_retry; | |
} | |
bootProtocolDload = ioctl(dev_fd, 0x4004CC0A); | |
if ( bootProtocolDload ) | |
bootProtocol = "DLOAD"; | |
else | |
bootProtocol = "SAHARA"; | |
_android_log_print(6, "kickstart-qcks", "MDM9x15 Boot protocol is %s\n", bootProtocol); | |
if ( enableDebug ) | |
{ | |
_android_log_print(6, "kickstart-qcks", "Will not continue with image transfer"); | |
close(dev_fd); | |
result = 0; | |
goto LABEL_99; | |
} | |
if ( !bootRetries ) | |
{ | |
res = load_efs_images(); | |
if ( res == 1 ) | |
goto issue_normal_boot; | |
retries = 10; | |
while ( 1 ) | |
{ | |
if ( !bootProtocolDload || (res = load_dload(aFirmwareImage), res != 1) || wake_device(dev_fd) != 1 ) | |
{ | |
if ( unkSaharaLoadFLag ) | |
{ | |
saharaLoadFlag = &unk_2518; | |
firmwareImage = aFirmwareImage; | |
dataCP_log = aDataCp_log; | |
tombstonesQcks = aTombstonesQcks; | |
} | |
else | |
{ | |
saharaLoadFlag = "-i "; | |
firmwareImage = aFirmwareImage; | |
dataCP_log = aDataCp_log; | |
tombstonesQcks = aTombstonesQcks; | |
} | |
res = load_sahara_images(saharaLoadFlag, firmwareImage, dataCP_log, tombstonesQcks); | |
if ( !res ) | |
{ | |
unset_unk_sahara_flag: | |
unkSaharaLoadFLag = 0; | |
issue_normal_boot: | |
if ( ioctl(dev_fd, 0x4004CC05) < 0 ) | |
{ | |
v14 = "kickstart-qcks"; | |
v15 = "Could not issue ioctl NORMAL_BOOT_DONE"; | |
goto log_and_retry; | |
} | |
if ( !res ) | |
{ | |
v23 = _android_log_print(6, "kickstart-qcks", "Spawning efsks"); | |
childPid = fork(v23); | |
gChildPid = childPid; | |
if ( childPid < 0 ) | |
{ | |
v14 = "kickstart-qcks"; | |
v15 = "Forking new process for efsks failed"; | |
goto log_and_retry; | |
} | |
if ( !childPid ) | |
{ | |
envp = 0; | |
efsksArgv[0] = off_4090; | |
efsksArgv[1] = off_4094[0]; | |
efsksArgv[2] = off_4098[0]; | |
efsksArgv[3] = off_409C[0]; | |
efsksArgv[4] = off_40A0; | |
v31 = *algn_40A4; | |
if ( execve(gEFSKSFile, efsksArgv, &envp) == -1 ) | |
{ | |
_android_log_print(6, "kickstart-qcks", "Spawning efsks using execve failed"); | |
exit(127); | |
} | |
} | |
} | |
if ( ioctl(dev_fd, 0x4004CC0C) < 0 ) | |
_android_log_print(6, "kickstart-qcks", "Could not issue ioctl WAIT_FOR_ERROR"); | |
issue_wait_for_restart: | |
if ( ioctl(dev_fd, 0x8004CC07) < 0 ) | |
{ | |
v14 = "kickstart-qcks"; | |
v15 = "Could not issue ioctl WAIT_FOR_RESTART"; | |
goto log_and_retry; | |
} | |
if ( gChildPid > 0 ) | |
{ | |
_android_log_print(6, "kickstart-qcks", "Issuing kill(%i) for EFSKS\n"); | |
kill(gChildPid, 15); | |
wait(&res); | |
_android_log_print(6, "kickstart-qcks", "EFSKS should be dead"); | |
gChildPid = 0; | |
} | |
goto retry; | |
} | |
wake_device(dev_fd); | |
} | |
if ( !--retries ) | |
goto unset_unk_sahara_flag; | |
} | |
} | |
if ( bootRetries != 1 ) | |
goto issue_wait_for_restart; | |
res = load_efs_images(); | |
if ( res == 1 ) | |
goto issue_ram_dump; | |
v25 = 10; | |
while ( 1 ) | |
{ | |
if ( !bootProtocolDload || (res = load_dload(aFirmwareImage), res != 1) || wake_device(dev_fd) != 1 ) | |
{ | |
v26 = memory_dump(aFirmwareImage, aDataCp_log); | |
res = v26; | |
if ( !v26 ) | |
goto issue_ram_dump; | |
if ( v26 == 2 ) | |
{ | |
_android_log_print(6, "kickstart-qcks", "issue ioctl Silent reset control"); | |
ioctl(dev_fd, 0x8004CC08); | |
issue_ram_dump: | |
if ( ioctl(dev_fd, 0x4004CC06) >= 0 ) | |
goto issue_wait_for_restart; | |
v14 = "kickstart-qcks"; | |
v15 = "Could not issue ioctl RAM_DUMP_DONE"; | |
log_and_retry: | |
_android_log_print(6, v14, v15); | |
goto retry; | |
} | |
wake_device(dev_fd); | |
} | |
if ( !--v25 ) | |
goto issue_ram_dump; | |
} | |
} | |
LOG_TAG = "kickstart-qcks"; | |
LOG_MESSAGE = "ERROR: Can't bring MDM9K out of reset"; | |
err_log_and_out: | |
_android_log_print(6, LOG_TAG, LOG_MESSAGE); | |
err_out: | |
result = 1; | |
LABEL_99: | |
if ( v34 != _stack_chk_guard ) | |
_stack_chk_fail(result); | |
return result; | |
} | |
// 894: using guessed type int _android_log_print(_DWORD, _DWORD, const char *, ...); | |
// 8AC: using guessed type int __fastcall strlcpy(_DWORD, _DWORD, _DWORD); | |
// 8DC: using guessed type int __fastcall _stack_chk_fail(_DWORD); | |
// 900: using guessed type int __fastcall ioctl(_DWORD, _DWORD); | |
// 930: using guessed type int __fastcall getopt_long(_DWORD, _DWORD, _DWORD, _DWORD); | |
// 93C: using guessed type int __fastcall _strlen_chk(_DWORD, _DWORD); | |
// 948: using guessed type int __fastcall open(_DWORD, _DWORD); | |
// 954: using guessed type int __fastcall property_get(_DWORD, _DWORD, _DWORD); | |
// 96C: using guessed type int __fastcall close(_DWORD); | |
// 978: using guessed type int __fastcall fork(_DWORD); | |
// 984: using guessed type int __fastcall execve(_DWORD, _DWORD, _DWORD); | |
// 99C: using guessed type int __fastcall kill(_DWORD, _DWORD); | |
// 9A8: using guessed type int __fastcall wait(_DWORD); | |
// 4000: using guessed type char *off_4000; | |
// 4090: using guessed type void *off_4090; | |
// 4094: using guessed type char *off_4094[4]; | |
// 4098: using guessed type char *off_4098[3]; | |
// 409C: using guessed type char *off_409C[2]; | |
// 40A0: using guessed type char *off_40A0; | |
// 78AC: using guessed type int bootProtocolDload; | |
// 7CB0: using guessed type int gChildPid; | |
//----- (00001B54) -------------------------------------------------------- | |
int j_j_puts(const char *a1) | |
{ | |
return j_puts(a1); | |
} | |
//----- (00001B58) -------------------------------------------------------- | |
int j_puts(const char *a1) | |
{ | |
return puts(a1); | |
} | |
// ALL OK, 13 function(s) have been successfully decompiled |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment