Files
2026-05-05 21:54:35 +08:00

268 lines
10 KiB
C

// -*- 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/ |
//+---------------------------------------------------------------------------+
//Compilation Windows
//cl -Fe_libInterface.pyd -Ox -Ot -openmp -LD /I"C:\Python26\include" /I"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include" libInterface.c "C:\Python26\libs\python26.lib" "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib\vcomp.lib"
//+---------------------------------------------------------------------------+
//| Import Associated Header
//+---------------------------------------------------------------------------+
#include "Interface.h"
#ifdef _WIN32
#include <stdio.h>
#include <malloc.h>
#endif
#ifdef CCALLFORDEBUG
//+---------------------------------------------------------------------------+
//| callbackStatus : displays the status on terminal when using only C calls
//+---------------------------------------------------------------------------+
int callbackStatus(int stage, double percent, char* message, ...) {
// Variadic member
va_list args;
// local variables
char buffer[4096];
va_start(args, message);
vsnprintf(buffer, sizeof(buffer), message, args);
va_end(args);
buffer[4095] = '\0';
printf("[%d, %f] %s\n", stage, percent, buffer);
return 1;
}
#endif
//+---------------------------------------------------------------------------+
//| deserializeMessages : Deserialization of messages
//+---------------------------------------------------------------------------+
unsigned int deserializeMessages(t_group * group, char *format, unsigned char *serialMessages, unsigned int nbMessages, Bool debugMode) {
unsigned int i_message = 0;
char * p;
unsigned int serial_shift = 0;
unsigned int format_shift = 0;
unsigned int len_size_message=0;
unsigned int size_message=0;
char * size_message_str;
unsigned int nbDeserializedMessages = 0;
for (i_message=0; i_message < nbMessages; i_message++) {
// Retrieve the size of each message
p = strchr(format + format_shift, 'M');
len_size_message = (unsigned int) (p - (format + format_shift));
size_message_str = malloc((len_size_message + 1) * sizeof(char));
memcpy(size_message_str, format + format_shift, len_size_message);
size_message_str[len_size_message] = '\0';
size_message = atoi(size_message_str);
// Register the message
group->messages[i_message].len = size_message;
group->messages[i_message].alignment = serialMessages + serial_shift;
group->messages[i_message].mask = malloc(size_message * sizeof(unsigned char));
memset(group->messages[i_message].mask, '\0', size_message);
t_score score;
group->messages[i_message].score = &score;
nbDeserializedMessages += 1;
format_shift = format_shift + len_size_message + 1;
serial_shift = serial_shift + size_message;
// Cleaning useless allocated memory
free(size_message_str);
}
if (debugMode == TRUE) {
printf("A number of %d messages has been deserialized.\n", nbDeserializedMessages);
for (i_message = 0; i_message<nbDeserializedMessages; i_message++) {
printf("Message %u : \n", i_message);
hexdump(group->messages[i_message].alignment, group->messages[i_message].len);
}
}
return nbDeserializedMessages;
}
unsigned int deserializeGroups(t_groups * groups, char * format, unsigned char * serialGroups, int nbGroups, Bool debugMode) {
int i_group = 0;
int j_group = 0;
int l = 0;
char * p;
char *q;
char *r;
char *s;
unsigned short int format_shift = 0;
unsigned int len_size_group = 0;
unsigned int len_size_message = 0;
unsigned int len_score_group = 0;
unsigned int size_group = 0;
unsigned int size_message = 0;
char * size_group_str;
char * size_message_str;
char * score_group;
unsigned int i_message = 0;
for (i_group = 0; i_group <nbGroups; i_group++) {
//Retrieve the precompiled scores
s = strchr(format + format_shift, 'E');
if (s != NULL){ // Used for compatibility between version
for (j_group = i_group + 1; j_group < nbGroups ; j_group ++){
r = strchr(format + format_shift, 'S');
if (r!=NULL && (int) (s - r) > 0){
len_score_group = (unsigned int) (r - (format + format_shift));
score_group = malloc((len_score_group + 1) * sizeof(unsigned char));
memcpy(score_group, format + format_shift, len_score_group);
score_group[len_score_group]='\0';
groups->groups[i_group].scores[j_group-(i_group+1)] = atof(score_group);
format_shift += len_score_group + 1;
free(score_group);
}
else{
break;
}
}
format_shift += 1; // FOR LETTER 'E'*/
}
// retrieve the number of messages in the current group
p = strchr(format + format_shift, 'G');
len_size_group = (unsigned int) (p - (format + format_shift));
size_group_str = malloc((len_size_group + 1) * sizeof(char));
memcpy(size_group_str, format + format_shift, len_size_group);
size_group_str[len_size_group] = '\0';
size_group = (unsigned int) atoi(size_group_str);
format_shift += len_size_group + 1;
// Allocate pointers to store the messages of current group
groups->groups[i_group].len = size_group;
groups->groups[i_group].messages = malloc(size_group * sizeof(t_message));
for (i_message = 0; i_message < size_group; i_message++) {
// Retrieve the size of each message
q = strchr(format + format_shift, 'M');
len_size_message = (unsigned int) (q - (format + format_shift));
size_message_str = malloc((len_size_message + 1) * sizeof(char));
memcpy(size_message_str, format + format_shift, len_size_message);
size_message_str[len_size_message] = '\0';
size_message = atoi(size_message_str);
format_shift += len_size_message + 1;
// Retrieve the data of each message
groups->groups[i_group].messages[i_message].len = size_message;
groups->groups[i_group].messages[i_message].alignment = serialGroups + l;
groups->groups[i_group].messages[i_message].mask = serialGroups + l + size_message;
l += size_message * 2;
free(size_message_str );
}
free(size_group_str);
}
if (debugMode == TRUE) {
printf("A number of %d group has been deserialized.\n", nbGroups);
}
return i_group;
}
#define OPL 64
void hexdump(unsigned char *buf, int dlen) {
char c[OPL + 1];
int i, ct;
if (dlen < 0) {
printf("WARNING: computed dlen %d\n", dlen);
dlen = 0;
}
for (i = 0; i < dlen; ++i) {
if (i == 0)
printf("DATA: ");
else if ((i % OPL) == 0) {
c[OPL] = '\0';
printf("\t\"%s\"\nDATA: ", c);
}
ct = buf[i] & 0xff;
c[i % OPL] = (ct >= ' ' && ct <= '~') ? ct : '.';
printf("%02x ", ct);
}
c[i % OPL] = '\0';
for (; i % OPL; ++i)
printf(" ");
printf("\t\"%s\"\n", c);
}
void dumpMessage(t_message message) {
unsigned int i;
printf("%d ", message.len);
for(i = 0; i < message.len; i++) {
if(message.mask[i] == 0)
printf("%02x", (unsigned char) message.alignment[i]);
else if(message.mask[i] == 2)
printf("##");
else
printf("--");
}
printf("\n");
}
unsigned int serializeSemanticTags(char ** serializedTags, t_semanticTag ** tags, unsigned int nbSemanticTags) {
unsigned int sizeSerializedTags = 0;
unsigned int iTag = 0;
unsigned int sizeLocalTag = 0;
// serializedTags = "tag1;tag2;tag3;..."
// first we compute the size of the result:
// size(serializedTags) = sum(size(tags->name)+1)+1
for (iTag=0; iTag<nbSemanticTags; iTag++){
if(tags[iTag]->name != NULL) {
sizeSerializedTags += strlen(tags[iTag]->name);
}
sizeSerializedTags +=1;
}
sizeSerializedTags +=1; // for the NULL byte
*serializedTags = calloc(sizeSerializedTags, sizeof(char));
for (iTag=0; iTag<nbSemanticTags; iTag++) {
if (tags[iTag]->name != NULL) {
sizeLocalTag = strlen(tags[iTag]->name);
if(sizeLocalTag>0){
strncat(*serializedTags, tags[iTag]->name, sizeLocalTag);
}
}
strncat(*serializedTags, ";", 1);
}
return sizeSerializedTags;
}
PyObject * serializeMessage(t_message * message) {
char * semanticTags = NULL;
unsigned int lenSemanticTags = serializeSemanticTags(&semanticTags, message->semanticTags, message->len);
return Py_BuildValue("(fffy#y#s#)", message->score->s1, message->score->s2, message->score->s3, message->alignment, message->len, message->mask, message->len, semanticTags, lenSemanticTags);
}