CCSDS_study project

This commit is contained in:
2026-05-05 21:54:35 +08:00
commit 9be41f9270
585 changed files with 91275 additions and 0 deletions

View File

@@ -0,0 +1,193 @@
// -*- coding: utf-8 -*-
//+---------------------------------------------------------------------------+
//| 01001110 01100101 01110100 01111010 01101111 01100010 |
//| |
//| Netzob : Inferring communication protocols |
//+---------------------------------------------------------------------------+
//| Copyright (C) 2011-2017 Georges Bossert and Frédéric Guihéry |
//| This program is free software: you can redistribute it and/or modify |
//| it under the terms of the GNU General Public License as published by |
//| the Free Software Foundation, either version 3 of the License, or |
//| (at your option) any later version. |
//| |
//| This program is distributed in the hope that it will be useful, |
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
//| GNU General Public License for more details. |
//| |
//| You should have received a copy of the GNU General Public License |
//| along with this program. If not, see <http://www.gnu.org/licenses/>. |
//+---------------------------------------------------------------------------+
//| @url : http://www.netzob.org |
//| @contact : contact@netzob.org |
//| @sponsors : Amossys, http://www.amossys.fr |
//| Supélec, http://www.rennes.supelec.fr/ren/rd/cidre/ |
//+---------------------------------------------------------------------------+
#include <stdio.h>
#include "libRelation.h"
#include "relation.h"
#define DEXC(stmt) if (stmt) PyErr_Print()
PyObject *exception = NULL;
static PyMethodDef relation_methods[] = {
{"find", py_find, METH_VARARGS,
"Iterate over relation algorithms"},
{NULL, NULL, 0, NULL}
};
PyObject* PyInit__libRelation(void) {
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"_libRelation",
NULL,
-1,
relation_methods,
NULL,
NULL,
NULL,
NULL
};
return PyModule_Create(&moduledef);
/* PyObject *d = PyDict_New(); */
/* exception = PyErr_NewException("_libRelation.error", NULL, NULL); */
/* PyDict_SetItemString(d, "error", exception); */
}
/*
* C wrapper for function "find" of _libRelation.
* This functions takes a two-dimension array built like this:
* > [(m0f0, m0f1, ...), (m1f0, m1f1, ...)]
*/
static PyObject*
py_find(__attribute__((unused))PyObject* self, PyObject* args) {
PyObject* pListCells;
PyObject* pCells;
PyObject* pCell;
PyObject* pDm = NULL;
size_t cells_hlen, cells_vlen;
unsigned int i, j;
char ***pppCells = NULL;
struct relation_datamodel* dm = NULL;
/* Parse arguments */
if ((pListCells = PyTuple_GetItem(args, 0)) == NULL) {
fprintf(stderr, "ERROR: Unable to parse args\n");
goto end;
}
/* Check type of arguments */
if (!PySequence_Check(pListCells)) {
fprintf(stderr, "ERROR: Unable to parse arg as list\n");
goto end;
}
cells_hlen = PySequence_Size(pListCells);
if ((pppCells = malloc(cells_hlen * sizeof(*pppCells))) == NULL)
goto end;
/* Allocation is based on the length of the first row */
pCells = PySequence_GetItem(pListCells, 0);
if (!PySequence_Check(pCells)) {
fprintf(stderr, "ERROR: Unable to get list item\n");
goto end;
}
/* Do str dups */
cells_vlen = PySequence_Size(pCells);
for (i = 0; i < cells_hlen; i++) {
/* Get, check and copy messages refs */
pCells = PySequence_GetItem(pListCells, i);
if (!PySequence_Check(pCells))
goto end2;
if ((pppCells[i] = malloc(cells_vlen * sizeof(**pppCells))) == NULL)
goto end2;
for (j = 0; j < cells_vlen; j++) {
/* Get, check and copy cells */
pCell = PySequence_GetItem(pCells, j);
if (!PyBytes_Check(pCell))
goto end2;
if ((pppCells[i][j] = malloc(PyBytes_Size(pCell) * sizeof(**pppCells))) == NULL)
goto end2;
strcpy(pppCells[i][j], PyBytes_AsString(pCell));
}
}
relation_find(&dm, (const char***)pppCells, cells_hlen, cells_vlen);
pDm = create_python_dm(dm);
end2:
for (i = 0; i < cells_hlen; i++) {
if (pppCells[i] != NULL)
for (j = 0; j < cells_vlen; j++)
if (pppCells[i][j] != NULL)
free(pppCells[i][j]);
free(pppCells[i]);
}
end:
if (pppCells != NULL)
free(pppCells);
return pDm;
}
/*
* Convert the native datamodel to a Python structure.
*/
static PyObject*
create_python_dm(struct relation_datamodel* dm)
{
struct relation_datamodel* dm_it = dm;
struct relation_matches* matches;
struct relation_matches* matches_tmp;
PyObject* pDm = NULL;
PyObject* pAlgoName;
PyObject* pRefs;
PyObject* pRefConfig;
PyObject* pRels;
PyObject* pRelConfig;
if (!(pDm = PyDict_New()))
goto error;
while (dm_it) {
pAlgoName = PyBytes_FromString(dm_it->algo_name);
/* Amend/append a algo/match node */
if (!(pRefs = PyDict_GetItem(pDm, pAlgoName)))
if (!(pRefs = PyList_New(0)))
goto error;
matches = dm_it->matches;
while (matches != NULL) {
pRelConfig = Py_BuildValue("(Ikk)",
matches->match.cell_rel_idx,
matches->match.cell_rel_off,
matches->match.cell_rel_size);
pRels = Py_BuildValue("[O]", pRelConfig);
pRefConfig = Py_BuildValue("(IOOO)",
matches->match.cell_ref_idx,
Py_None,
Py_None,
pRels);
PyList_Append(pRefs, pRefConfig);
matches_tmp = matches->next;
free(matches);
matches = matches_tmp;
}
/* Append configuration of reference as tuple */
PyDict_SetItem(pDm, pAlgoName , pRefs);
/* next algo */
dm_it = dm_it->next;
}
return pDm;
error:
Py_RETURN_NONE;
}

View File

@@ -0,0 +1,25 @@
DEBUG=no
SRC=rel_test.c \
rel_equality.c \
rel_size.c
OBJ=$(SRC:.c=.o)
SOBJ=$(OBJ:.o=.so)
CFLAGS=-fPIC -I../../includes
LDFLAGS=-L/usr/lib
ifeq ($(DEBUG),yes)
CFLAGS+= -g -D__DEBUG__
endif
all: $(SOBJ)
%.o: %.c
$(CC) -c -pthread $(CFLAGS) $< -o $@
%.so: %.o
$(CC) -shared -Wl,-soname,$@ $(LDFLAGS) $< -o $@
clean:
$(RM) $(OBJ) $(SOBJ)
re: clean all

View File

@@ -0,0 +1,161 @@
// -*- coding: utf-8 -*-
//+---------------------------------------------------------------------------+
//| 01001110 01100101 01110100 01111010 01101111 01100010 |
//| |
//| Netzob : Inferring communication protocols |
//+---------------------------------------------------------------------------+
//| Copyright (C) 2011-2017 Georges Bossert and Frédéric Guihéry |
//| This program is free software: you can redistribute it and/or modify |
//| it under the terms of the GNU General Public License as published by |
//| the Free Software Foundation, either version 3 of the License, or |
//| (at your option) any later version. |
//| |
//| This program is distributed in the hope that it will be useful, |
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
//| GNU General Public License for more details. |
//| |
//| You should have received a copy of the GNU General Public License |
//| along with this program. If not, see <http://www.gnu.org/licenses/>. |
//+---------------------------------------------------------------------------+
//| @url : http://www.netzob.org |
//| @contact : contact@netzob.org |
//| @sponsors : Amossys, http://www.amossys.fr |
//| Supélec, http://www.rennes.supelec.fr/ren/rd/cidre/ |
//+---------------------------------------------------------------------------+
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "relation.h"
static unsigned int MIN_SIZE = 2;
/*
* wrapper of string comparison used to detect a relation with the
* specified parameters.
*/
static int
get_match(const char* cell_ref, const char* cell_rel,
size_t start, size_t len)
{
int ret;
#if defined(__DEBUG__) && false
char* new_rel;
if ((new_rel = malloc((len + 1) * sizeof(*new_rel)))) {
new_rel[len] = '\0';
DLOG("%s == %s ?", cell_ref, strncpy(new_rel, &cell_rel[start], len));
free(new_rel);
}
#endif
ret = strncmp(cell_ref, &cell_rel[start], len);
#if defined(__DEBUG__) && false
DLOG(" %d\n", ret);
#endif
return ret;
}
/*
* Append a node to the set of matches.
*/
static struct relation_matches*
append_match(struct relation_matches** matches,
const struct relation_match* match)
{
struct relation_matches* new = NULL;
if (!(new = malloc(sizeof(*new))))
return NULL;
new->next = *matches;
memcpy(&new->match, match, sizeof(new->match));
*matches = new;
return new;
}
/*
* Returns the first non-matching message index.
*/
static int
verify_match(const char*** messages, size_t msgs_len, size_t cells_len,
const struct relation_match* match)
{
int i;
int ret = 0;
const char** cells;
const char* ref;
const char* rel;
DLOG("Verifying M%04d", 0);
for (i = 0; i < msgs_len; i++) {
if (i == match->message_idx)
continue;
cells = messages[i];
ref = cells[match->cell_ref_idx];
rel = cells[match->cell_rel_idx];
DLOG2("\b\b\b\b%04d", i);
if (get_match(ref, rel, match->cell_rel_off, match->cell_rel_size)) {
ret = i;
break;
}
}
DLOG2("\n");
return ret;
}
/*
* Main function used to build a set of matches.
*/
static struct relation_matches*
relation_equality_find(const char*** messages, int row, int idx,
size_t vlen, size_t hlen)
{
int i, ret;
size_t off;
int found = 0;
int match_res;
const char** cells;
const char* ref;
size_t ref_len;
const char* rel;
size_t rel_len;
struct relation_matches* matches = NULL;
struct relation_match match;
cells = messages[row];
ref = cells[idx];
ref_len = strlen(ref);
for (i = 0; i < hlen; i++) {
rel = cells[i];
rel_len = strlen(rel);
if (i != idx && rel && ref_len <= rel_len && ref_len >= MIN_SIZE) {
for (off = 0; off <= rel_len - ref_len; off++) {
if (!(match_res = get_match(ref, rel, off, ref_len))) {
match.message_idx = row;
match.cell_ref_idx = idx;
match.cell_rel_idx = i;
match.cell_rel_off = off;
match.cell_rel_size = ref_len;
DLOG("possible match found: M%d F%d[:], F%d[%ld:%ld] (%s)\n",
row, idx, i, off, off+ref_len, ref);
if ((ret = verify_match(messages, vlen, hlen,
(const struct relation_match*)&match)) != 0) {
DLOG("verification failed at M%d\n", ret);
continue;
}
DLOG("MATCH FOUND\n");
DLOG(">> %p\n", matches);
append_match(&matches, (const struct relation_match*)&match);
DLOG(">> %p\n", matches);
}
}
}
}
return matches;
}
struct relation_algorithm_operations operations = {
.name = "equality",
.find = relation_equality_find
};

View File

@@ -0,0 +1,189 @@
// -*- coding: utf-8 -*-
//+---------------------------------------------------------------------------+
//| 01001110 01100101 01110100 01111010 01101111 01100010 |
//| |
//| Netzob : Inferring communication protocols |
//+---------------------------------------------------------------------------+
//| Copyright (C) 2011-2017 Georges Bossert and Frédéric Guihéry |
//| This program is free software: you can redistribute it and/or modify |
//| it under the terms of the GNU General Public License as published by |
//| the Free Software Foundation, either version 3 of the License, or |
//| (at your option) any later version. |
//| |
//| This program is distributed in the hope that it will be useful, |
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
//| GNU General Public License for more details. |
//| |
//| You should have received a copy of the GNU General Public License |
//| along with this program. If not, see <http://www.gnu.org/licenses/>. |
//+---------------------------------------------------------------------------+
//| @url : http://www.netzob.org |
//| @contact : contact@netzob.org |
//| @sponsors : Amossys, http://www.amossys.fr |
//| Supélec, http://www.rennes.supelec.fr/ren/rd/cidre/ |
//+---------------------------------------------------------------------------+
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "relation.h"
static unsigned int MIN_SIZE = 2;
/*
* wrapper of string comparison used to detect a relation with the
* specified parameters.
*/
static int
get_match(const char* cell_ref, const char* cell_rel,
size_t start, size_t len)
{
int ret = -1;
size_t size_ref, size_rel;
char* remaining_str;
unsigned long val_integer;
char* tmp_cell_rel;
DLOG(" ref=%s, rel=%s, start=%d, len=%d\n", cell_ref, cell_rel, start, len);
#if defined(__DEBUG__) && false
char* new_rel;
if ((new_rel = malloc((len + 1) * sizeof(*new_rel)))) {
new_rel[len] = '\0';
DLOG("%s == %s ?", cell_ref, strncpy(new_rel, &cell_rel[start], len));
free(new_rel);
}
#endif
tmp_cell_rel = malloc(len + 1);
strncpy(tmp_cell_rel, &cell_ref[start], len);
tmp_cell_rel[2] = '\0';
val_integer = strtoul(tmp_cell_rel, &remaining_str, 16);
// printf("PANNNN: %s\n", tmp_cell_rel);
// printf("PANNNN: %ud\n\n", val_integer);
free(tmp_cell_rel);
DLOG("strlen(cell_rel)=%d\n", strlen(cell_rel));
if (val_integer != 0 && val_integer == (strlen(cell_rel) / 2)) {
DLOG(" OK!!\n");
ret = 0;
}
else
ret = -1;
// ret = strncmp(cell_ref, &cell_rel[start], len);
#if defined(__DEBUG__) && false
DLOG(" %d\n", ret);
#endif
return ret;
}
/*
* Append a node to the set of matches.
*/
static struct relation_matches*
append_match(struct relation_matches** matches,
const struct relation_match* match)
{
struct relation_matches* new = NULL;
if (!(new = malloc(sizeof(*new))))
return NULL;
new->next = *matches;
memcpy(&new->match, match, sizeof(new->match));
*matches = new;
return new;
}
/*
* Returns the first non-matching message index.
*/
static int
verify_match(const char*** messages, size_t msgs_len, size_t cells_len,
const struct relation_match* match)
{
int i;
int ret = 0;
const char** cells;
const char* ref;
const char* rel;
DLOG("Verifying M%04d", 0);
for (i = 0; i < msgs_len; i++) {
if (i == match->message_idx)
continue;
cells = messages[i];
ref = cells[match->cell_ref_idx];
rel = cells[match->cell_rel_idx];
DLOG2("\b\b\b\b%04d", i);
if (get_match(ref, rel, match->cell_rel_off, match->cell_rel_size)) {
ret = i;
break;
}
}
DLOG2("\n");
return ret;
}
/*
* Main function used to build a set of matches.
*/
static struct relation_matches*
relation_size_find(const char*** messages, int row, int idx,
size_t vlen, size_t hlen)
{
int i, ret;
size_t off;
int found = 0;
int match_res;
const char** cells;
const char* ref;
size_t ref_len;
const char* rel;
size_t rel_len;
struct relation_matches* matches = NULL;
struct relation_match match;
cells = messages[row];
ref = cells[idx];
ref_len = strlen(ref);
for (i = 0; i < hlen; i++) {
if (idx == 5)
DLOG(" i = %d\n", i);
rel = cells[i];
rel_len = strlen(rel);
if (i != idx && rel && ref_len >= MIN_SIZE) {
off = 0;
// for (off = 0; off <= rel_len; off++) {
if (!(match_res = get_match(ref, rel, off, ref_len))) {
match.message_idx = row;
match.cell_ref_idx = idx;
match.cell_rel_idx = i;
match.cell_rel_off = off;
match.cell_rel_size = ref_len;
DLOG("possible match found: M%d F%d[:], F%d[%ld:%ld] (%s)\n",
row, idx, i, off, off+ref_len, ref);
if ((ret = verify_match(messages, vlen, hlen,
(const struct relation_match*)&match)) != 0) {
DLOG("verification failed at M%d\n", ret);
continue;
}
DLOG("MATCH FOUND\n");
DLOG(">> %p\n", matches);
append_match(&matches, (const struct relation_match*)&match);
DLOG(">> %p\n", matches);
}
// }
}
}
return matches;
}
struct relation_algorithm_operations operations = {
.name = "size",
.find = relation_size_find
};

View File

@@ -0,0 +1,40 @@
// -*- coding: utf-8 -*-
//+---------------------------------------------------------------------------+
//| 01001110 01100101 01110100 01111010 01101111 01100010 |
//| |
//| Netzob : Inferring communication protocols |
//+---------------------------------------------------------------------------+
//| Copyright (C) 2011-2017 Georges Bossert and Frédéric Guihéry |
//| This program is free software: you can redistribute it and/or modify |
//| it under the terms of the GNU General Public License as published by |
//| the Free Software Foundation, either version 3 of the License, or |
//| (at your option) any later version. |
//| |
//| This program is distributed in the hope that it will be useful, |
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
//| GNU General Public License for more details. |
//| |
//| You should have received a copy of the GNU General Public License |
//| along with this program. If not, see <http://www.gnu.org/licenses/>. |
//+---------------------------------------------------------------------------+
//| @url : http://www.netzob.org |
//| @contact : contact@netzob.org |
//| @sponsors : Amossys, http://www.amossys.fr |
//| Supélec, http://www.rennes.supelec.fr/ren/rd/cidre/ |
//+---------------------------------------------------------------------------+
#include "relation.h"
static struct relation_matches*
relation_test_find(const char** messages, int row, int idx,
size_t vlen, size_t hlen)
{
return NULL;
}
struct relation_algorithm_operations operations = {
.name = "test",
.find = relation_test_find
};

View File

@@ -0,0 +1,163 @@
// -*- coding: utf-8 -*-
//+---------------------------------------------------------------------------+
//| 01001110 01100101 01110100 01111010 01101111 01100010 |
//| |
//| Netzob : Inferring communication protocols |
//+---------------------------------------------------------------------------+
//| Copyright (C) 2011-2017 Georges Bossert and Frédéric Guihéry |
//| This program is free software: you can redistribute it and/or modify |
//| it under the terms of the GNU General Public License as published by |
//| the Free Software Foundation, either version 3 of the License, or |
//| (at your option) any later version. |
//| |
//| This program is distributed in the hope that it will be useful, |
//| but WITHOUT ANY WARRANTY; without even the implied warranty of |
//| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
//| GNU General Public License for more details. |
//| |
//| You should have received a copy of the GNU General Public License |
//| along with this program. If not, see <http://www.gnu.org/licenses/>. |
//+---------------------------------------------------------------------------+
//| @url : http://www.netzob.org |
//| @contact : contact@netzob.org |
//| @sponsors : Amossys, http://www.amossys.fr |
//| Supélec, http://www.rennes.supelec.fr/ren/rd/cidre/ |
//+---------------------------------------------------------------------------+
#define _GNU_SOURCE
#include <dirent.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "relation.h"
static const char* algorithm_path = "lib/libRelation/algorithms";
/*
* Build a native datamodel containing results.
*/
void
relation_find(struct relation_datamodel** dm,
const char*** data,
size_t vlen, size_t hlen)
{
unsigned int i, j;
struct relation_matches* matches;
struct relation_algorithm_operations_list* algo_opers;
algo_opers = search_algorithms();
while (algo_opers) {
DLOG("ALGO %s\n", algo_opers->data.name);
for (i = 0; i < vlen; i++) {
for (j = 0; j < hlen; j++) {
DLOG("-- idx = %d\n", j);
matches = algo_opers->data.find(data, i, j, vlen, hlen);
if (matches != NULL)
append_algo_matches(dm, algo_opers, matches);
}
/* only search over the first row, others are useless */
break;
}
algo_opers = algo_opers->next;
}
clean_algo(algo_opers);
}
/*
* Append a result to the datamodel structure.
*/
struct relation_datamodel*
append_algo_matches(struct relation_datamodel** dm,
struct relation_algorithm_operations_list* opers,
struct relation_matches* matches)
{
struct relation_datamodel* new;
if (!(new = malloc(sizeof(*new))))
return NULL;
new->next = *dm;
new->matches = matches;
new->algo_name = opers->data.name;
*dm = new;
return new;
}
/*
* Build a list of libRelation algorithm.
* This structure contains a handle returned by dlopen() of libraries.
*/
struct relation_algorithm_operations_list*
search_algorithms(void)
{
DIR* pDir;
struct dirent* entry;
void* pLib;
char* libPath;
int libPathLen;
struct relation_algorithm_operations* algo_oper;
struct relation_algorithm_operations_list* algo_opers = NULL;
struct relation_algorithm_operations_list* algo_opers_prev = NULL;
DLOG("Searching in %s\n", algorithm_path);
if ((pDir = opendir(algorithm_path)) == NULL)
goto end;
while ((entry = readdir(pDir)) != NULL) {
if (strstr(entry->d_name, ".so") != NULL) {
libPathLen = strlen(algorithm_path) + 1 + strlen(entry->d_name);
if (!(libPath = malloc(sizeof(*libPath) * (libPathLen + 1)))) {
perror("search_algorithms()");
goto end;
}
if (snprintf(libPath, libPathLen + 1, "%s/%s", algorithm_path, entry->d_name) != libPathLen) {
fprintf(stderr, "snprintf() failed at %s:%d\n", __FILE__, __LINE__);
fprintf(stderr, " %s\n", libPath);
goto end;
}
if (!(pLib = dlopen(libPath, RTLD_NOW|RTLD_GLOBAL))) {
DLOG("Skipping '%s'\n", libPath);
goto next;
}
dlerror(); // clear last error
algo_oper = dlsym(pLib, "operations");
/* Check current error flag */
if (dlerror() != NULL)
goto next;
DLOG("[%s] Operations loaded\n", libPath);
if (!(algo_opers = malloc(sizeof(*algo_opers))))
goto next;
algo_opers->next = algo_opers_prev;
algo_opers->pHandle = pLib;
memcpy(&algo_opers->data, algo_oper, sizeof(*algo_oper));
algo_opers_prev = algo_opers;
DLOG("[%s] Algo added\n", algo_opers->data.name);
next:
free(libPath);
continue;
}
}
closedir(pDir);
end:
return algo_opers;
}
/*
* Correctly free a relation_algorithm_operations_list recursively.
*/
void
clean_algo(struct relation_algorithm_operations_list* algo)
{
struct relation_algorithm_operations_list* cur = algo;
struct relation_algorithm_operations_list* next;
while (cur) {
if (cur->pHandle)
dlclose(cur->pHandle);
next = cur->next;
free(cur);
cur = next;
}
}