....
finalize(char *hdrs, sendip_data *headers[], int index,
sendip_data *data, sendip_data *pack)
{
........
À des fins de débogage, je veux un vidage hexadécimal des structures data
et pack
, qui sont de type sendip_data
, une structure vraiment complexe. En fait, ils contiennent des informations binaires, donc je ne sais pas si la sortie de mon projet est correcte ou non. Donc, à des fins de débogage, je veux écrire les données dans un fichier afin de pouvoir utiliser hexdump comme suit -
$hexdump -C file.txt
De plus, comme il s'agit d'une génération d'exécution d'un paquet n/w, je ne suis donc pas sûr de la longueur de la structure de data
et pack
qui, je pense, fread / fwrite
nécessitera .. Alors, s'il vous plaît, proposez-moi quelque chose.
Le code suivant vous donnera un vidage hexadécimal de mémoire arbitraire à partir de votre code.
#include <stdio.h>
void hexDump (const char *desc, const void *addr, const int len) {
int i;
unsigned char buff[17];
const unsigned char *pc = (const unsigned char*)addr;
// Output description if given.
if (desc != NULL)
printf ("%s:\n", desc);
if (len == 0) {
printf(" ZERO LENGTH\n");
return;
}
if (len < 0) {
printf(" NEGATIVE LENGTH: %i\n",len);
return;
}
// Process every byte in the data.
for (i = 0; i < len; i++) {
// Multiple of 16 means new line (with line offset).
if ((i % 16) == 0) {
// Just don't print ASCII for the zeroth line.
if (i != 0)
printf (" %s\n", buff);
// Output the offset.
printf (" %04x ", i);
}
// Now the hex code for the specific character.
printf (" %02x", pc[i]);
// And store a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e))
buff[i % 16] = '.';
else
buff[i % 16] = pc[i];
buff[(i % 16) + 1] = '\0';
}
// Pad out last line if not exactly 16 characters.
while ((i % 16) != 0) {
printf (" ");
i++;
}
// And print the final ASCII bit.
printf (" %s\n", buff);
}
int main (int argc, char *argv[]) {
char my_str[] = "a char string greater than 16 chars";
hexDump ("my_str", &my_str, sizeof (my_str));
return 0;
}
Vous passez dans hexDump
une description, une adresse mémoire et une longueur, et il affichera un vidage hexadécimal (y compris les données de caractères) pour examen. Lorsque vous l'exécutez avec le main
inclus, la sortie est:
my_str:
0000 61 20 63 68 61 72 20 73 74 72 69 6e 67 20 67 72 a char string gr
0010 65 61 74 65 72 20 74 68 61 6e 20 31 36 20 63 68 eater than 16 ch
0020 61 72 73 00 ars.
Un vidage hexadécimal pour Android devrait également convenir à d'autres plates-formes.
LOGD()
, comme DLOG()
, joue le rôle de printf()
car printf()
ne fonctionne pas sous Android. Pour les plates-formes autres qu'Android, vous pouvez #define DLOG printf
.
dlog.h:
// Android logging
#include <Android/log.h>
#define LOGD(...) __Android_log_print(Android_LOG_DEBUG , "~~~~~~", __VA_ARGS__)
#define DLOG(...) __Android_log_print(Android_LOG_DEBUG , "~~~~~~", __VA_ARGS__)
#define LOGE(...) __Android_log_print(Android_LOG_ERROR , "~~~~~~", __VA_ARGS__)
#define ELOG(...) __Android_log_print(Android_LOG_ERROR , "~~~~~~", __VA_ARGS__)
#ifdef __cplusplus
extern "C" {
#endif
void log_dump(const void*addr,int len,int linelen);
void log_dumpf(const char*fmt,const void*addr,int len,int linelen);
#ifdef __cplusplus
}
#endif
dump.cpp:
#include <dlog.h>
//#include <alloca.h>
inline char hdigit(int n){return "0123456789abcdef"[n&0xf];};
#define LEN_LIMIT 8
#define SUBSTITUTE_CHAR '`'
static const char* dumpline(char*dest, int linelen, const char*src, const char*srcend)
{
if(src>=srcend) {
return 0;
}
int i;
unsigned long s = (unsigned long)src;
for(i=0; i<8; i++) {
dest[i] = hdigit(s>>(28-i*4));
}
dest[8] = ' ';
dest += 9;
for(i=0; i<linelen/4 ; i++) {
if(src+i<srcend) {
dest[i*3] = hdigit(src[i]>>4);
dest[i*3+1] = hdigit(src[i]);
dest[i*3+2] = ' ';
dest[linelen/4*3+i] = src[i] >= ' ' && src[i] < 0x7f ? src[i] : SUBSTITUTE_CHAR;
}else{
dest[i*3] = dest[i*3+1] = dest[i*3+2] = dest[linelen/4*3+i] = ' ';
}
}
return src+i;
}
void log_dumpf(const char*fmt,const void*addr,int len,int linelen)
{
#if LEN_LIMIT
if(len>linelen*LEN_LIMIT) {
len=linelen*LEN_LIMIT;
}
#endif
linelen *= 4;
static char _buf[4096];
char*buf = _buf;//(char*)alloca(linelen+1); // alloca() causes the initialization to fail!!!!
buf[linelen]=0;
const char*start = (char*)addr;
const char*cur = start;
const char*end = start+len;
while(!!(cur = dumpline(buf,linelen,cur,start+len))){DLOG(fmt,buf);}
}
void log_dump(const void*addr,int len,int linelen)
{
log_dumpf("%s\n",addr,len,linelen);
}
Exemple d'utilisation:
log_dumpf("args: %s\n", &p, 0x20, 0x10);
Production:
args: 61efadc4 00 3c 17 01 6d bc 59 61 02 00 00 00 80 ae ef 61 `<``m`Ya```````a
args: 61efadd4 00 3c 17 01 00 00 00 00 31 a5 59 61 80 ae ef 61 `<``````1`Ya```a
MISE À JOUR: voir dump.cpp et re_dump.h in reDroid (github ) , il inclut un vidage récursif qui vérifie si un pointeur est valide.