
com.github.katjahahn.tools.anomalies.ClrScanning.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of portex_2.12 Show documentation
Show all versions of portex_2.12 Show documentation
Java library to parse Portable Executable files
The newest version!
/**
* *****************************************************************************
* Copyright 2022 Karsten Philipp Boris Hahn
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ****************************************************************************
*/
package com.github.katjahahn.tools.anomalies
import com.github.katjahahn.parser.IOUtil.NL
import com.github.katjahahn.parser.ScalaIOUtil.filteredString
import com.github.katjahahn.parser.sections.SectionLoader
import com.github.katjahahn.parser.sections.clr.CLRSection
import scala.collection.mutable.ListBuffer
/**
* Scans the .NET related structures for anomalies
*/
trait ClrScanning extends AnomalyScanner {
abstract override def scanReport(): String =
"Applied CLR Anomaly Scanning" + NL + super.scanReport
abstract override def scan(): List[Anomaly] = {
val clr = new SectionLoader(data).maybeLoadCLRSection()
val anomalyList = ListBuffer[Anomaly]()
if (clr.isPresent) {
anomalyList ++= checkStreamHeaders(clr.get)
anomalyList ++= checkStringsHeap(clr.get)
}
super.scan ::: anomalyList.toList
}
/**
* Anomaly scanning the stream headers of the metadata root directory
* @param clr the CLR section object
* @return List of anomalies in stream headers
*/
private def checkStreamHeaders(clr : CLRSection): List[Anomaly] = {
val metadataRoot = clr.metadataRoot
val names = metadataRoot.streamHeaders.map(_.name)
// check stream names for duplicates
val duplicates = names.diff(names.distinct).distinct
val anomalies = for(name <- duplicates) yield
new ClrStreamAnomaly(metadataRoot,
metadataRoot.streamHeaders.find(_.name == name).get,
"There are several streams named '" + name + "', there should only be one",
AnomalySubType.DUPLICATED_STREAMS)
anomalies
}
/**
* Anomalies in the #Strings heap
* @param clr CLR section object
* @return list of anomalies in #Strings heap
*/
private def checkStringsHeap(clr : CLRSection): List[Anomaly] = {
val metadataRoot = clr.metadataRoot
val streamHeader = metadataRoot.streamHeaders.find(_.name == "#Strings")
val stringsHeap = metadataRoot.maybeGetStringsHeap
if(!stringsHeap.isPresent || !streamHeader.isDefined) return Nil
val heap= stringsHeap.get()
val filteredStrings = heap.getArray().filter(filteredString(_).length > 0)
// one less because first string is always empty
val unreadableCount = heap.getArray().length - filteredStrings.length - 1
if(unreadableCount > 0) {
return List(new ClrStreamAnomaly(
metadataRoot, streamHeader.get,
"There is a total of " + unreadableCount + " unreadable strings in #Strings, this is a common obfuscation",
AnomalySubType.UNREADABLE_CHARS_IN_STRINGS_HEAP
))
}
Nil
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy