Created
January 30, 2018 15:32
-
-
Save Bloody-Badboy/bd29d7529f3bb15cb66c66dd4e5caf52 to your computer and use it in GitHub Desktop.
A utility class to search for certain byte pattern in any file or in bytes array
This file contains 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
/* | |
* Copyright (C) 2015 BloodyBadboyCreation, Inc. (Arpan Bloody Badboy) | |
* | |
* 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 package <package-name>; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
@SuppressWarnings({"WeakerAccess", "LoopStatementThatDoesntLoop"}) | |
class BytesSearchUtils { | |
private final byte[] mSourceBytes; | |
private BytesSearchUtils(byte[] source) { | |
mSourceBytes = source; | |
} | |
public static BytesSearchUtils newInstance(byte[] source) { | |
if (source == null) { | |
throw new NullPointerException("Source bytes can't be null."); | |
} else if (source.length <= 0) { | |
throw new RuntimeException("Source bytes length must not be < 0"); | |
} | |
return new BytesSearchUtils(source); | |
} | |
static String toHexString(byte[] bytes) { | |
StringBuilder stringBuilder = new StringBuilder(); | |
for (byte b : bytes) { | |
stringBuilder.append(String.format("%02X ", b)); | |
} | |
return stringBuilder.toString(); | |
} | |
private byte[] generateSearchBytes(String pattern) { | |
if (pattern == null) { | |
throw new InvalidPatternException("Search pattern can't be null."); | |
} | |
String mPattern = pattern; | |
int count = 0; | |
for (Matcher m = Pattern.compile("(\\*)").matcher(mPattern); m.find(); ) { | |
count++; | |
} | |
if (count % 2 != 0) { | |
throw new InvalidPatternException("Invalid search search pattern: " + mPattern); | |
} | |
mPattern = mPattern.replaceAll("(\\*){2}", "2A"); | |
mPattern = mPattern.replaceAll("(\\s+)", ""); | |
int length = mPattern.length() / 2; | |
byte[] bytes = new byte[length]; | |
for (int i = 0; i < length; i++) { | |
bytes[i] = (byte) (((Character.digit(mPattern.charAt(i * 2), 16)) << 4) + Character.digit(mPattern.charAt(i * 2 + 1), 16)); | |
} | |
return bytes; | |
} | |
/** | |
* @param searchPattern search hex pattern | |
* @return the index of the first occurrence of hex pattern in the initialized bytes array, or -1 if the hex pattern does not occur. | |
* @throws InvalidPatternException if the search patten is null or contains invalid characters | |
*/ | |
public int indexOf(String searchPattern) throws InvalidPatternException { | |
int[] indexes = getAllIndex(searchPattern); | |
for (int i : indexes) { | |
return i; | |
} | |
return -1; | |
} | |
/** | |
* @param searchPattern search hex pattern | |
* @param start search start range | |
* @param end search end range | |
* @return the index of the first occurrence of hex pattern in the initialized bytes array, or -1 if the hex pattern does not occur. | |
* @throws InvalidPatternException if the search patten is null or contains invalid characters | |
*/ | |
public int indexOf(String searchPattern, int start, int end) throws InvalidPatternException { | |
int[] indexes = getAllIndex(searchPattern, start, end); | |
for (int i : indexes) { | |
return i; | |
} | |
return -1; | |
} | |
/** | |
* @param searchPattern search hex pattern | |
* @return all indexes index of hex pattern in the initialized bytes array, or an empty array if the hex pattern does not occur. | |
* @throws InvalidPatternException if the search patten is null or contains invalid characters. | |
*/ | |
public int[] getAllIndex(String searchPattern) throws InvalidPatternException { | |
return getAllIndex(searchPattern, 0, mSourceBytes.length); | |
} | |
/** | |
* @param searchPattern search hex pattern | |
* @param start search start range | |
* @param end search end range | |
* @return all indexes index of hex pattern in the initialized bytes array, or an empty array if the hex pattern does not occur. | |
* @throws InvalidPatternException if the search patten is null or contains invalid characters. | |
*/ | |
public int[] getAllIndex(String searchPattern, int start, int end) throws InvalidPatternException { | |
if (searchPattern == null) { | |
throw new InvalidPatternException("Search pattern most not be null"); | |
} | |
if (searchPattern.length() < 2) { | |
throw new InvalidPatternException("Search pattern length must be > 0"); | |
} | |
if (start < 0) { | |
throw new InvalidPatternException("Start range must be positive"); | |
} | |
if (end < 0) { | |
throw new InvalidPatternException("End range must be positive"); | |
} | |
if (start >= end) { | |
throw new InvalidPatternException("Start range must be < end range"); | |
} | |
byte[] search = generateSearchBytes(searchPattern); | |
List<Integer> positionList = new ArrayList<>(); | |
int searchLength = search.length; | |
for (int index = start; index < end; index++) { | |
if (index + search.length <= mSourceBytes.length) { | |
boolean find = true; | |
for (int count = 0; count < searchLength; count++) { | |
if (search[count] != 42) { | |
if (mSourceBytes[index + count] != search[count]) { | |
find = false; | |
break; | |
} | |
} | |
} | |
if (find) { | |
positionList.add(index); | |
index += (search.length - 1); | |
} | |
} | |
} | |
int[] positions = new int[positionList.size()]; | |
for (int i = 0; i < positionList.size(); i++) { | |
positions[i] = positionList.get(i); | |
} | |
return positions; | |
} | |
private static class InvalidPatternException extends RuntimeException { | |
InvalidPatternException(String message) { | |
super(message); | |
} | |
} | |
} |
This file contains 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
package <package-name>; | |
@SuppressWarnings("SpellCheckingInspection") | |
public class Main { | |
public static void main(String[] args) { | |
String normalText = "Lorem ipsum dolor sit amet, consectetur adipisicing elit." + | |
" Ratione nam vitae officia explicabo est voluptatum, dignissimos adipisci" + | |
" possimus porro aliquam. Consequatur praesentium recusandae laudantium " + | |
"nihil aliquid molestiae optio atque, repellat, maiores, deleniti dolores" + | |
" asperiores! Ipsa quidem voluptatem corrupti vero quibusdam, corporis aliquam." + | |
" Iusto earum ipsum nesciunt reiciendis quisquam mollitia, debitis nobis maxime " + | |
"numquam asperiores ea in ex, soluta molestiae corporis culpa recusandae commodi."; | |
byte[] anyBytes = normalText.getBytes(); | |
System.out.println(toHexString(normalText.getBytes())); | |
// Get the instance of BytesSearchUtils | |
BytesSearchUtils bytesSearchUtils = BytesSearchUtils.newInstance(anyBytes); | |
// Find and return the first indexof hex pattern in the bytes array | |
System.out.println(bytesSearchUtils.indexOf("61 6D 65 74 2C 20 63")); | |
System.out.println(bytesSearchUtils.indexOf("61 ** 65 ** 2C 20 63")); | |
// Find and return an array of indexes | |
int[] indexs = bytesSearchUtils.getAllIndex("61 6D 65 74"); | |
// Find hex pattern between to ranges and return an array of indexes | |
int[] indexs1 = bytesSearchUtils.getAllIndex("61 6D 65 74", 100, 250); | |
} | |
static String toHexString(byte[] bytes) { | |
StringBuilder stringBuilder = new StringBuilder(); | |
for (byte b : bytes) { | |
stringBuilder.append(String.format("%02X ", b)); | |
} | |
return stringBuilder.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello not work!!!
not all bytes are found