Skip to content

Commit

Permalink
Add support for FileXOR statements
Browse files Browse the repository at this point in the history
  • Loading branch information
ExcaliburZero committed Nov 5, 2023
1 parent f84eb1e commit 4fa83d8
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/lib
/regression_tests/work_dirs

/tree-sitter-quickbms/test/corpus/crc_scan.bms
/tree-sitter-quickbms/test/corpus/misc_scripts

# Files generate by antlr
.antlr/
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ The following QuickBMS commands are currently supported by the langauge server.
* [x] `ReverseLong VAR [ENDIAN]`
* [x] `ReverseLongLong VAR [ENDIAN]`
* [x] `Endian TYPE [VAR]`
* [ ] `FileXOR SEQ [OFFSET] [FILENUM]`
* [x] `FileXOR SEQ [OFFSET] [FILENUM]`
* [ ] `FileRot SEQ [OFFSET] [FILENUM]`
* [ ] `FileCrypt SEQ [OFFSET] [FILENUM]`
* [ ] `Strlen VAR VAR [SIZE]`
Expand Down
52 changes: 52 additions & 0 deletions src/server/keyword_docs/filexor.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
FileXOR SEQ [OFFSET] [FILENUM]

Any read operation (Get, *Log and so on) on any file will
also perform the XORing of the read data with the numbers
contained in the given string or in the given variable.
The OFFSET field by default is zero which means that if the
data must be xored with more than one byte (a "xor key") the
first byte of the key is the first byte at OFFSET which is 0
by default (beginning of the file).
Recap: the FileXOR command works with ANY file access.

Arguments:
SEQ Sequence of space-separated 8bit numbers, like:
- asequence of bytes separated by space like 0x12
or "0x12 0x34 0x56" or directly a C hex string
like "\x12\x34\x56" (NOT a C notation!)
- a numeric variable like MYXORKEY
- a string not starting with numbers, '\' or '-'
Currently it's not possible to use a key in string
mode and use the Encryption command for doing it,
so if you have a string convert it to a numeric
sequence first or be sure that it doesn't start
with the chars shown above.
Set it to 0 or "" for disabling the xor.
Note that SEQ can be also a 32bit signed number
like filexor 0x11223344 but the size is decided by
value so 0x00000022 is 8 bit and not 32, while
-0x20 is considered 8bit and 0x80112233 a 32bit.
OFFSET Needed only for the xor key offset.
If the archive is xored with a xor key from its
beginning (so first byte of the archive xored with
the first one of the key) this argument is usually
not necessary
Instead if only the file to extract is xored, this
argument must have the same offset of the file (so
just reuse the same OFFSET used in Log)
FILENUM By default FileXOR is applied to ALL the files and
OFFSET (if specified) is referred to file 0.
When FILENUM is specified, it will only be applied
to that specific file.

Examples:
filexor 0xff
filexor -0x20
filexor 0x1122 # 32bit
filexor -0x1122 # 32bit
filexor "0x12 0x34 123 255"
filexor MYXORBYTE
saepos OFFSET
filexor "0x12 0x34 123 255" OFFSET
filexor "\x12\x34\x7b\xff"
Log NAME OFFSET SIZE
4 changes: 4 additions & 0 deletions src/server/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,10 @@ pub fn get_keyword_docs() -> HashMap<String, String> {
"reverselonglong".to_string(),
include_str!("keyword_docs/reverselonglong.txt").to_string(),
),
(
"filexor".to_string(),
include_str!("keyword_docs/filexor.txt").to_string(),
),
]
.iter()
.cloned()
Expand Down
8 changes: 8 additions & 0 deletions tree-sitter-quickbms/grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module.exports = grammar({
$.reverseshort_statement,
$.reverselong_statement,
$.reverselonglong_statement,
$.filexor_statement,
),
set_statement: $ => seq(
$.set,
Expand Down Expand Up @@ -213,6 +214,12 @@ module.exports = grammar({
field("variable", $._expression),
field("endian", optional($._endian_type)),
),
filexor_statement: $ => seq(
$.filexor,
field("sequence", $._expression),
field("offset", optional($._expression)),
// field("file_number", optional($._expression)),
),
comparison: $ => choice(
"<",
">",
Expand Down Expand Up @@ -321,6 +328,7 @@ module.exports = grammar({
reverseshort: $ => /[Rr][Ee][Vv][Ee][Rr][Ss][Ee][Ss][Hh][Oo][Rr][Tt]/,
reverselong: $ => /[Rr][Ee][Vv][Ee][Rr][Ss][Ee][Ll][Oo][Nn][Gg]/,
reverselonglong: $ => /[Rr][Ee][Vv][Ee][Rr][Ss][Ee][Ll][Oo][Nn][Gg][Ll][Oo][Nn][Gg]/,
filexor: $ => /[Ff][Ii][Ll][Ee][Xx][Oo][Rr]/,
question_mark: $ => /\?/,

identifier: $ => /[a-zA-Z_\\]+[a-zA-Z0-9_\-\\]*/,
Expand Down
51 changes: 51 additions & 0 deletions tree-sitter-quickbms/test/corpus/filexor.bms
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
================================================================================
FileXOR statements
================================================================================

filexor 0xff
filexor -0x20
filexor 0x1122 # 32bit
filexor -0x1122 # 32bit
filexor "0x12 0x34 123 255"
filexor MYXORBYTE
# saepos OFFSET # Is this a valid command?
filexor "0x12 0x34 123 255" OFFSET
filexor "\x12\x34\x7b\xff"
Log NAME OFFSET SIZE

--------------------------------------------------------------------------------

(source_file
(filexor_statement
(filexor)
(integer_literal))
(filexor_statement
(filexor)
(integer_literal))
(filexor_statement
(filexor)
(integer_literal))
(comment)
(filexor_statement
(filexor)
(integer_literal))
(comment)
(filexor_statement
(filexor)
(string_literal))
(filexor_statement
(filexor)
(identifier))
(comment)
(filexor_statement
(filexor)
(string_literal)
(identifier))
(filexor_statement
(filexor)
(string_literal))
(log_statement
(log)
(identifier)
(identifier)
(identifier)))

0 comments on commit 4fa83d8

Please sign in to comment.