Essayer d’imprimer des données utiles de la mémoire

void update_memblock(MEMBLOCK *mb) { static unsigned char tempbuf[128 * 1024]; SIZE_T bytes_left; SIZE_T total_read; SIZE_T bytes_to_read; SIZE_T bytes_read; bytes_left = mb->size; total_read = 0; while (bytes_left) { bytes_to_read = (bytes_left > sizeof(tempbuf)) ? sizeof(tempbuf) : bytes_left; ReadProcessMemory(mb->hProc, mb->addr + total_read, tempbuf, bytes_to_read, &bytes_read); if (bytes_read != bytes_to_read) break; memcpy(mb->buffer + total_read, tempbuf, bytes_read); bytes_left -= bytes_read; total_read += bytes_read; } mb->size = total_read; } 

C’est le code actuel que j’ai, je lis d’abord la mémoire d’un autre processus en utilisant ReadProcessMemory . J’ai maintenant les données temporaires stockées dans tempbuf . Je suis capable de sortir les données de tempbuf sous forme hexadécimale. Mais je prévoyais de l’afficher comme indiqué dans l’image, une autre complexité que je rencontre ici est si bytes_left> sizeof (tempbuf) Je lis seulement assez de données équivalentes à la taille de tempbuf. Comment lire plus de données car le tableau que j’ai défini ne prend en charge que le plus de données?

in_this_format

Si je comprends bien, votre question principale concerne la façon d’imiter la sortie des éditeurs hexadécimaux.

Cela peut être divisé en 3 parties:

  1. Imprimer l’adresse
  2. Impression de la valeur hexadécimale de chaque octet
  3. Impression de la valeur ASCII pour chaque octet

Imprimer une adresse en hexadécimal est facile. Nous pouvons utiliser %p pour imprimer l’adresse d’un pointeur comme ceci:

 char* mem = malloc(99); printf("%p\n", (void*)mem); // output: 0xc17080 

Ensuite, vous pouvez imprimer la valeur hexadécimale d’un octet en utilisant %02x sur un caractère (1 octet). Le 02 spécifie une largeur de champ de remplissage nul de 2. Dans ce cas, il suffit de faire en sorte que 0 imprimé pour que les choses soient alignées et jolies.

 printf("%02x", mem[0]); // output: 0A 

Enfin, l’impression en ASCII est la plus simple. Nous pouvons utiliser %c pour imprimer un octet pour certaines valeurs ASCII, mais nous ne voulons pas imprimer des choses comme \n ou \t . Pour résoudre ce problème, nous pouvons limiter l’utilisation de %c à la région caractère / symbole de la table ASCII et imprimer . pour tout le rest.

 char c = mem[0]; if ( ' ' <= c && c <= '~' ) { printf("%c", c); } else { printf("."); } //output: . 

Maintenant, nous avons juste besoin de les combiner tous ensemble. Vous pouvez décider du nombre d'octets que vous souhaitez afficher par ligne et imprimer "[adresse] [n octets hexadécimaux] [n ascii bytes]" et répéter jusqu'à ce que vous ayez parcouru toute la région mémoire. J'ai donné un exemple de fonction ci-dessous et vous pouvez l'exécuter ici même.

 void display_mem(void* mem, int mem_size, int line_len) { /* mem - pointer to beggining of memory region to be printed mem_size - number of bytes mem points to line_len - number of bytyes to display per line */ unsigned char* data = mem; int full_lines = mem_size / line_len; unsigned char* addr = mem; for (int linno = 0; linno < full_lines; linno++) { // Print Address printf("0x%x\t", addr); // Print Hex for (int i = 0; i < line_len; i++) { printf(" %02x", data[linno*line_len + i]); } printf("\t"); // Print Ascii for (int i = 0; i < line_len; i++) { char c = data[linno*line_len + i]; if ( 32 < c && c < 125) { printf(" %c", c); } else { printf(" ."); } } printf("\n"); // Incremement addr by number of bytes printed addr += line_len; } // Print any remaining bytes that couldn't make a full line int remaining = mem_size % line_len; if (remaining > 0) { // Print Address printf("0x%x\t", addr); // Print Hex for (int i = 0; i < remaining; i++) { printf(" %02x", data[line_len*full_lines + i]); } for (int i = 0; i < line_len - remaining; i++) { printf(" "); } printf("\t"); // Print Hex for (int i = 0; i < remaining; i++) { char c = data[line_len*full_lines + i]; if ( 32 < c && c < 125) { printf(" %c", c); } else { printf(" ."); } } printf("\n"); } } 

Sortie de l'échantillon:

 0x1e79010 74 65 73 74 79 2a 6e testy * n 0x1e79017 0c 3e 24 45 5e 33 27 . > $ E ^ 3 ' 0x1e7901e 18 51 09 2d 76 7e 4a . Q . - v . J 0x1e79025 12 53 0f 6e 0b 1a 6d . S . n . . m 0x1e7902c 31 6e 03 2b 01 2f 2c 1 n . + . / , 0x1e79033 72 59 1c 76 18 38 3c r Y . v . 8 < 0x1e7903a 6e 6b 5b 00 36 64 25 nk [ . 6 d % 0x1e79041 2d 5c 6f 38 30 00 27 - \ o 8 0 . ' 0x1e79048 33 12 15 5c 01 18 09 3 . . \ . . . 0x1e7904f 02 40 2d 6c 1a 41 63 . @ - l . A c 0x1e79056 2b 72 18 1a 5e 74 12 + r . . ^ t . 0x1e7905d 0d 51 38 33 26 28 6b . Q 8 3 & ( k 0x1e79064 56 20 0b 0b 32 20 67 V . . . 2 . g 0x1e7906b 34 30 68 2e 70 0f 1c 4 0 h . p . . 0x1e79072 04 50 . P 

En ce qui concerne la deuxième partie de votre question, si vous ne pouvez pas augmenter la taille de tempbuf vous êtes confronté à une telle quantité de mémoire à tout moment.

Cependant, si tout ce que vous voulez faire est d'afficher la mémoire comme décrit ci-dessus, vous pouvez afficher chaque section de mémoire en morceaux. Vous pouvez obtenir un gros morceau de mémoire, l'afficher, puis obtenir un nouveau bloc, afficher le nouveau bloc, répéter.

Quelque chose dans le sens de

 while (bytes_left) { ReadProcessMemory(mb->hProc, mb->addr + total_read, tempbuf, bytes_to_read, &bytes_read); // Get new chunk memcpy(mb->buffer + total_read, tempbuf, bytes_read); // Display chunk display_mem(tempbuf, bytes_read); bytes_left -= bytes_read; } 

Vous devrez faire un peu plus de travail pour vérifier les erreurs et rendre l’apparence agréable, mais nous espérons que cela vous donnera une bonne idée de ce qui pourrait être fait.

Il n’y a aucun moyen de stocker plus de données que l’espace alloué. Si vous avez besoin de stocker plus de données, vous devrez allouer plus d’espace quelque part (plus de RAM, un fichier disque, etc.). La compression vous permettra de stocker un peu plus de données dans l’espace alloué, mais vous n’allez pas en gagner autant. Pour un stockage pratiquement illimité, vous devrez écrire sur le disque.

Alternativement, si vous avez juste besoin d’afficher une fois et puis d’oublier, de lire 16 octets, affichez la ligne, puis lisez les 16 octets suivants dans la même mémoire.