mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-01 00:51:19 +00:00
138 lines
3.9 KiB
C
138 lines
3.9 KiB
C
// https://github.com/quarkslab/binbloom/blob/master/binbloom.c
|
|
|
|
/* Copyright 2020 G. Heilles
|
|
* Copyright 2020 Quarkslab
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include <r_list.h>
|
|
#include <r_util.h>
|
|
#include <r_search.h>
|
|
|
|
#define UDS_SIZE sizeof (UDS)
|
|
#define CANDB_SIZE 512
|
|
|
|
|
|
static unsigned char UDS[] = {
|
|
0x10, 0x11, 0x27, 0x28, 0x3E, 0x83, 0x84, 0x85, 0x86, 0x87, 0x22, 0x23, 0x24, 0x2A, 0x2C, 0x2D, 0x2E, 0x3D, 0x14,
|
|
0x19, 0x2F, 0x31, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x18, 0x3B, 0x20, 0x21, 0x1A
|
|
};
|
|
|
|
#if 0
|
|
static int is_unique_UDS(unsigned int position) {
|
|
unsigned int j, flag;
|
|
flag = 0;
|
|
for (j = 0; j < UDS_SIZE; j++) {
|
|
if (firmware[position] == UDS[j]) {
|
|
flag = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (flag == 1) {
|
|
for (j = position - CANDB_SIZE / 2; j < position + CANDB_SIZE / 2; j++) {
|
|
if ((firmware[j] == firmware[position]) && (j != position)) {
|
|
flag = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return flag;
|
|
}
|
|
#endif
|
|
|
|
R_API RList *r_search_find_uds(RSearch *search, ut64 addr, const ut8 *data, size_t size, bool verbose) {
|
|
RList *list = r_list_newf (free);
|
|
if (size < (CANDB_SIZE * 2)) {
|
|
eprintf ("requires at least 1024 bytes. %d\n", (int)size);
|
|
r_list_free (list);
|
|
return NULL;
|
|
}
|
|
unsigned int i, j, k, max_score, stride;
|
|
unsigned int candb_position = 0;
|
|
|
|
unsigned int *score = (unsigned int *)calloc (size, sizeof (int));
|
|
unsigned int *stride_score = (unsigned int *)calloc (size, sizeof (int));
|
|
|
|
unsigned char UDS_local[UDS_SIZE];
|
|
for (i = 1; i < size - (CANDB_SIZE * 2); i++) {
|
|
for (stride = 6; stride <= 32; stride += 2) {
|
|
// prepare a local copy of the UDS service list, to remove them once each is found. This will ensure each UDS service is matched only once.
|
|
memcpy(UDS_local, UDS, UDS_SIZE);
|
|
max_score = 0;
|
|
for (k = 0; k < CANDB_SIZE; k += stride) {
|
|
bool flag = false;
|
|
for (j = 0; j < UDS_SIZE; j++) {
|
|
// printf("j=%d, k=%d ", j, k);
|
|
if ((data[i + k] == UDS_local[j]) && (UDS_local[j] != 0)) {
|
|
//printf("at %#08x + %#08x, data=%#02x (j=%d, stride=%d)\n", i, k, data[i+k], j, stride);
|
|
max_score++;
|
|
UDS_local[j] = 0;
|
|
flag = true;
|
|
}
|
|
}
|
|
if (!flag) {
|
|
break;
|
|
}
|
|
}
|
|
// if (max_score) printf("Score at %#08x for stride %d: %d\n", i, stride, max_score);
|
|
if (max_score > score[i]) {
|
|
// printf("New high score for %#08x: %d\n", i, max_score);
|
|
score[i] = max_score;
|
|
stride_score[i] = stride;
|
|
}
|
|
}
|
|
}
|
|
|
|
// print 20 best candidates
|
|
for (j = 0; j < 20; j++) {
|
|
max_score = 0;
|
|
unsigned int max_stride = 0;
|
|
for (i = 0; i < size; i++) {
|
|
if (score[i] > max_score) {
|
|
max_score = score[i];
|
|
max_stride = stride_score[i];
|
|
candb_position = i;
|
|
}
|
|
}
|
|
if (max_score == 0) {
|
|
continue;
|
|
}
|
|
RSearchUds *uh = R_NEW0 (RSearchUds);
|
|
if (!uh) {
|
|
break;
|
|
}
|
|
uh->score = max_score;
|
|
uh->stride = max_stride;
|
|
uh->addr = addr + candb_position;
|
|
r_list_append (list, uh);
|
|
if (verbose) {
|
|
eprintf ("UDS DB position: %x with a score of %d and a stride of %d:\n", candb_position, max_score, max_stride);
|
|
unsigned int k;
|
|
for (k = candb_position; k < candb_position + max_score * max_stride; k++) score[k] = 0; // skip all other references to this same candb
|
|
for (i = 0; i < max_score; i++) {
|
|
for (j = 0; j < max_stride; j++) {
|
|
eprintf ("%02x ", data[candb_position + i * max_stride + j]);
|
|
}
|
|
eprintf ("\n");
|
|
}
|
|
eprintf ("\n");
|
|
}
|
|
score[candb_position] = 0;
|
|
}
|
|
free (score);
|
|
free (stride_score);
|
|
return list;
|
|
}
|