2016-11-28 11:42:58 +01:00
/ * *
* @ author n1474335 [ n1474335 @ gmail . com ]
* @ copyright Crown Copyright 2016
* @ license Apache - 2.0
* /
2018-05-06 13:24:01 +02:00
import Operation from "../Operation" ;
import { fromHex } from "../lib/Hex" ;
/ * *
* From Hexdump operation
* /
class FromHexdump extends Operation {
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
/ * *
2018-05-06 13:24:01 +02:00
* FromHexdump constructor
2016-11-28 11:42:58 +01:00
* /
2018-05-06 13:24:01 +02:00
constructor ( ) {
super ( ) ;
this . name = "From Hexdump" ;
this . module = "Default" ;
this . description = "Attempts to convert a hexdump back into raw data. This operation supports many different hexdump variations, but probably not all. Make sure you verify that the data it gives you is correct before continuing analysis." ;
this . inputType = "string" ;
this . outputType = "byteArray" ;
this . args = [ ] ;
2018-05-20 17:49:42 +02:00
this . patterns = [
{
match : "^(?:(?:[\\dA-F]{4,16}:?)?\\s*((?:[\\dA-F]{2}\\s){1,8}(?:\\s|[\\dA-F]{2}-)(?:[\\dA-F]{2}\\s){1,8}|(?:[\\dA-F]{2}\\s|[\\dA-F]{4}\\s)+)[^\\n]*\\n?)+$" ,
flags : "i" ,
args : [ ]
} ,
] ;
2018-05-06 13:24:01 +02:00
}
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
/ * *
* @ param { string } input
* @ param { Object [ ] } args
2017-01-31 19:24:56 +01:00
* @ returns { byteArray }
2016-11-28 11:42:58 +01:00
* /
2018-05-06 13:24:01 +02:00
run ( input , args ) {
const output = [ ] ,
regex = /^\s*(?:[\dA-F]{4,16}h?:?)?\s*((?:[\dA-F]{2}\s){1,8}(?:\s|[\dA-F]{2}-)(?:[\dA-F]{2}\s){1,8}|(?:[\dA-F]{2}\s|[\dA-F]{4}\s)+)/igm ;
let block , line ;
2017-02-09 16:09:33 +01:00
2016-12-14 17:39:17 +01:00
while ( ( block = regex . exec ( input ) ) ) {
2018-05-06 13:24:01 +02:00
line = fromHex ( block [ 1 ] . replace ( /-/g , " " ) ) ;
2017-04-13 19:08:50 +02:00
for ( let i = 0 ; i < line . length ; i ++ ) {
2016-11-28 11:42:58 +01:00
output . push ( line [ i ] ) ;
}
}
// Is this a CyberChef hexdump or is it from a different tool?
2017-04-13 19:08:50 +02:00
const width = input . indexOf ( "\n" ) ;
const w = ( width - 13 ) / 4 ;
2016-11-28 11:42:58 +01:00
// w should be the specified width of the hexdump and therefore a round number
2016-12-14 17:39:17 +01:00
if ( Math . floor ( w ) !== w || input . indexOf ( "\r" ) !== - 1 || output . indexOf ( 13 ) !== - 1 ) {
2017-09-20 01:37:57 +02:00
if ( ENVIRONMENT _IS _WORKER ( ) ) self . setOption ( "attemptHighlight" , false ) ;
2016-11-28 11:42:58 +01:00
}
return output ;
2018-05-06 13:24:01 +02:00
}
/ * *
* Highlight From Hexdump
*
* @ param { Object [ ] } pos
* @ param { number } pos [ ] . start
* @ param { number } pos [ ] . end
* @ param { Object [ ] } args
* @ returns { Object [ ] } pos
* /
highlight ( pos , args ) {
const w = args [ 0 ] || 16 ;
const width = 14 + ( w * 4 ) ;
let line = Math . floor ( pos [ 0 ] . start / width ) ;
let offset = pos [ 0 ] . start % width ;
if ( offset < 10 ) { // In line number section
pos [ 0 ] . start = line * w ;
} else if ( offset > 10 + ( w * 3 ) ) { // In ASCII section
pos [ 0 ] . start = ( line + 1 ) * w ;
} else { // In byte section
pos [ 0 ] . start = line * w + Math . floor ( ( offset - 10 ) / 3 ) ;
}
line = Math . floor ( pos [ 0 ] . end / width ) ;
offset = pos [ 0 ] . end % width ;
if ( offset < 10 ) { // In line number section
pos [ 0 ] . end = line * w ;
} else if ( offset > 10 + ( w * 3 ) ) { // In ASCII section
pos [ 0 ] . end = ( line + 1 ) * w ;
} else { // In byte section
pos [ 0 ] . end = line * w + Math . ceil ( ( offset - 10 ) / 3 ) ;
}
2017-02-09 16:09:33 +01:00
2018-05-06 13:24:01 +02:00
return pos ;
}
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
/ * *
2018-05-06 13:24:01 +02:00
* Highlight From Hexdump in reverse
2016-11-28 11:42:58 +01:00
*
* @ param { Object [ ] } pos
* @ param { number } pos [ ] . start
* @ param { number } pos [ ] . end
* @ param { Object [ ] } args
* @ returns { Object [ ] } pos
* /
2018-05-06 13:24:01 +02:00
highlightReverse ( pos , args ) {
2016-11-28 11:42:58 +01:00
// Calculate overall selection
2018-05-06 13:24:01 +02:00
const w = args [ 0 ] || 16 ,
width = 14 + ( w * 4 ) ;
let line = Math . floor ( pos [ 0 ] . start / w ) ,
2016-11-28 11:42:58 +01:00
offset = pos [ 0 ] . start % w ,
start = 0 ,
end = 0 ;
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
pos [ 0 ] . start = line * width + 10 + offset * 3 ;
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
line = Math . floor ( pos [ 0 ] . end / w ) ;
offset = pos [ 0 ] . end % w ;
2016-12-14 17:39:17 +01:00
if ( offset === 0 ) {
line -- ;
offset = w ;
}
2016-11-28 11:42:58 +01:00
pos [ 0 ] . end = line * width + 10 + offset * 3 - 1 ;
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
// Set up multiple selections for bytes
2017-04-13 19:08:50 +02:00
let startLineNum = Math . floor ( pos [ 0 ] . start / width ) ;
const endLineNum = Math . floor ( pos [ 0 ] . end / width ) ;
2017-02-09 16:09:33 +01:00
2017-01-31 19:24:56 +01:00
if ( startLineNum === endLineNum ) {
2016-11-28 11:42:58 +01:00
pos . push ( pos [ 0 ] ) ;
} else {
start = pos [ 0 ] . start ;
2017-01-31 19:24:56 +01:00
end = ( startLineNum + 1 ) * width - w - 5 ;
2016-11-28 11:42:58 +01:00
pos . push ( { start : start , end : end } ) ;
while ( end < pos [ 0 ] . end ) {
2017-01-31 19:24:56 +01:00
startLineNum ++ ;
start = startLineNum * width + 10 ;
end = ( startLineNum + 1 ) * width - w - 5 ;
2016-11-28 11:42:58 +01:00
if ( end > pos [ 0 ] . end ) end = pos [ 0 ] . end ;
pos . push ( { start : start , end : end } ) ;
}
}
2017-02-09 16:09:33 +01:00
2016-11-28 11:42:58 +01:00
// Set up multiple selections for ASCII
2018-05-06 13:24:01 +02:00
const len = pos . length ;
let lineNum = 0 ;
2016-11-28 11:42:58 +01:00
start = 0 ;
end = 0 ;
2017-04-13 19:08:50 +02:00
for ( let i = 1 ; i < len ; i ++ ) {
2017-01-31 19:24:56 +01:00
lineNum = Math . floor ( pos [ i ] . start / width ) ;
start = ( ( ( pos [ i ] . start - ( lineNum * width ) ) - 10 ) / 3 ) + ( width - w - 2 ) + ( lineNum * width ) ;
end = ( ( ( pos [ i ] . end + 1 - ( lineNum * width ) ) - 10 ) / 3 ) + ( width - w - 2 ) + ( lineNum * width ) ;
2016-11-28 11:42:58 +01:00
pos . push ( { start : start , end : end } ) ;
}
return pos ;
2018-05-06 13:24:01 +02:00
}
2017-02-09 16:09:33 +01:00
2018-05-06 13:24:01 +02:00
}
2017-03-23 18:52:20 +01:00
2018-05-06 13:24:01 +02:00
export default FromHexdump ;