forked from Mirror/GodMode9
Scripting: add fget & fset commands
This commit is contained in:
parent
b656f0d90b
commit
4f8dfc1eaf
@ -95,6 +95,8 @@ typedef enum {
|
||||
CMD_ID_UMOUNT,
|
||||
CMD_ID_FIND,
|
||||
CMD_ID_FINDNOT,
|
||||
CMD_ID_FGET,
|
||||
CMD_ID_FSET,
|
||||
CMD_ID_SHA,
|
||||
CMD_ID_SHAGET,
|
||||
CMD_ID_FIXCMAC,
|
||||
@ -157,6 +159,8 @@ Gm9ScriptCmd cmd_list[] = {
|
||||
{ CMD_ID_UMOUNT , "imgumount",0, 0 },
|
||||
{ CMD_ID_FIND , "find" , 2, _FLG('f') },
|
||||
{ CMD_ID_FINDNOT , "findnot" , 2, 0 },
|
||||
{ CMD_ID_FGET , "fget" , 2, _FLG('e') },
|
||||
{ CMD_ID_FSET , "fset" , 2, _FLG('e') },
|
||||
{ CMD_ID_SHA , "sha" , 2, 0 },
|
||||
{ CMD_ID_SHAGET , "shaget" , 2, 0 },
|
||||
{ CMD_ID_FIXCMAC , "fixcmac" , 1, 0 },
|
||||
@ -202,23 +206,30 @@ static inline bool isntrboot(void) {
|
||||
return (bootMediaStatus[3] == 2) && !bootMediaStatus[1] && !bootPartitionsStatus[0] && !bootPartitionsStatus[1];
|
||||
}
|
||||
|
||||
static inline bool strntohex(const char* str, u8* hex, u32 len) {
|
||||
static inline u32 strntohex(const char* str, u8* hex, u32 len) {
|
||||
if (!len) {
|
||||
len = strlen(str);
|
||||
if (len%1) return false;
|
||||
if (len%1) return 0;
|
||||
else len >>= 1;
|
||||
} else if (len*2 != strnlen(str, (len*2)+1)) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
for (u32 i = 0; i < len; i++) {
|
||||
char bytestr[2+1] = { 0 };
|
||||
u32 bytehex;
|
||||
memcpy(bytestr, str + (i*2), 2);
|
||||
if (sscanf(bytestr, "%02lx", &bytehex) != 1)
|
||||
return false;
|
||||
return 0;
|
||||
hex[i] = (u8) bytehex;
|
||||
}
|
||||
return true;
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline u32 hexntostr(const u8* hex, char* str, u32 len) {
|
||||
if (!len) return 0;
|
||||
for (u32 i = 0; i < len; i++)
|
||||
snprintf(str + (i<<1), 2 + 1, "%02lx", (u32) hex[i]);
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline u32 line_len(const char* text, u32 len, u32 ww, const char* line) {
|
||||
@ -507,6 +518,7 @@ u32 get_flag(char* str, u32 len, char* err_str) {
|
||||
else if (strncmp(str, "--all", len) == 0) flag_char = 'a';
|
||||
else if (strncmp(str, "--before", len) == 0) flag_char = 'b';
|
||||
else if (strncmp(str, "--include_dirs", len) == 0) flag_char = 'd';
|
||||
else if (strncmp(str, "--flip_endian", len) == 0) flag_char = 'e';
|
||||
else if (strncmp(str, "--first", len) == 0) flag_char = 'f';
|
||||
else if (strncmp(str, "--hash", len) == 0) flag_char = 'h';
|
||||
else if (strncmp(str, "--skip", len) == 0) flag_char = 'k';
|
||||
@ -775,7 +787,7 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
|
||||
// process arg0 @string
|
||||
u64 at_org = 0;
|
||||
u64 sz_org = 0;
|
||||
if ((id == CMD_ID_SHA) || (id == CMD_ID_SHAGET) || (id == CMD_ID_INJECT) || (id == CMD_ID_FILL)) {
|
||||
if ((id == CMD_ID_FGET) || (id == CMD_ID_FSET) || (id == CMD_ID_SHA) || (id == CMD_ID_SHAGET) || (id == CMD_ID_INJECT) || (id == CMD_ID_FILL)) {
|
||||
char* atstr_org = strrchr(argv[0], '@');
|
||||
if (atstr_org) {
|
||||
*(atstr_org++) = '\0';
|
||||
@ -1131,6 +1143,57 @@ bool run_cmd(cmd_id id, u32 flags, char** argv, char* err_str) {
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail");
|
||||
}
|
||||
}
|
||||
else if (id == CMD_ID_FGET) {
|
||||
u8 data[(_VAR_CNT_LEN-1)/2];
|
||||
if (sz_org == 0) {
|
||||
ret = false;
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "no size given");
|
||||
} else if (sz_org > (_VAR_CNT_LEN-1)/2) {
|
||||
ret = false;
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "size too big");
|
||||
} else if (FileGetData(argv[0], data, sz_org, at_org) != sz_org) {
|
||||
ret = false;
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "read fail");
|
||||
} else {
|
||||
char* var = set_var(argv[1], "");
|
||||
if (!var) {
|
||||
ret = false;
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "var fail");
|
||||
} else {
|
||||
if (flags & _FLG('e')) { // flip data
|
||||
for (u32 i = 0; i < (sz_org >> 1); i++) {
|
||||
u8 tmp = data[i];
|
||||
data[i] = data[sz_org - 1 - i];
|
||||
data[sz_org - 1 - i] = tmp;
|
||||
}
|
||||
}
|
||||
ret = hexntostr(data, var, sz_org);
|
||||
if (!ret && err_str) snprintf(err_str, _ERR_STR_LEN, "conversion fail");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (id == CMD_ID_FSET) {
|
||||
u8 data[(_ARG_MAX_LEN-1)/2];
|
||||
u32 len = strntohex(argv[1], data, 0);
|
||||
if (!sz_org) sz_org = len;
|
||||
if ((sz_org <= len) && (flags & _FLG('e'))) { // flip data
|
||||
for (u32 i = 0; i < (sz_org >> 1); i++) {
|
||||
u8 tmp = data[i];
|
||||
data[i] = data[sz_org - 1 - i];
|
||||
data[sz_org - 1 - i] = tmp;
|
||||
}
|
||||
}
|
||||
if (!len) {
|
||||
ret = false;
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "invalid data");
|
||||
} else if (sz_org > len) {
|
||||
ret = false;
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "size too big");
|
||||
} else if (!FileSetData(argv[0], data, sz_org, at_org, false)) {
|
||||
ret = false;
|
||||
if (err_str) snprintf(err_str, _ERR_STR_LEN, "write fail");
|
||||
}
|
||||
}
|
||||
else if (id == CMD_ID_SHA) {
|
||||
u8 sha256_fil[0x20];
|
||||
u8 sha256_cmp[0x20];
|
||||
|
@ -221,6 +221,24 @@ fdummy $[DUMMY] 400
|
||||
fill $[DUMMY]@100:100 FF
|
||||
fill $[DUMMY]@300 80
|
||||
|
||||
# 'fset' COMMAND
|
||||
# This command sets a portition of a file with the specified data in hex
|
||||
# The syntax is: fset destination@x hexdata
|
||||
# x: destination offset (in hex)
|
||||
# If x is not given, data is inserted at the beginning of the file
|
||||
# -e / --flip_endian flips the order of the bytes
|
||||
fset $[DUMMY]@100 48454c4c4f # 'HELLO'
|
||||
|
||||
# 'fget' COMMAND
|
||||
# This command reads data from a file and stores it in a var
|
||||
# The syntax is: fset origin@x:y var
|
||||
# x: origin offset (in hex)
|
||||
# y: origin size, starting at x (in hex)
|
||||
# Both x and y have to be set(!)
|
||||
# -e / --flip_endian flips the order of the bytes
|
||||
fget -e $[DUMMY]@100:5 OLLEH
|
||||
echo "This is 'HELLO', in hex and reverse:\n$[OLLEH]"
|
||||
|
||||
# 'fixcmac' COMMAND
|
||||
# Use this to fix the CMACs for a file or a whole folder (recursively)
|
||||
# This will count as success if a file does not contain a CMAC
|
||||
|
Loading…
x
Reference in New Issue
Block a user