c - Forsøger at udskrive nyttige data fra hukommelsen

Indlæg af Hanne Mølgaard Plasc

Problem



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;
}


Dette er den nuværende kode, jeg har, jeg læser i første omgang en anden proces 'hukommelse ved hjælp af ReadProcessMemory. Nu har jeg de midlertidige data gemt i tempbuf. Jeg kan sende dataene fra tempbuf i hexadecimal form.Men jeg planlagde at vise den som vist på billedet, også en anden kompleksitet, jeg står her er, hvis bytes\_left> sizeof (tempbuf) Jeg læser kun nok data svarende til størrelsen af ​​tempbuf. Hvordan gør jeg læs flere data, da arrayet jeg definerede kun kan understøtte så mange data?


in\_this\_format [22]

Bedste reference


Hvis jeg forstår rigtigt, handler dit hovedspørgsmål om, hvordan man efterligner output fra hex redaktører.


Dette kan opdeles i 3 dele:



  1. Udskriv adressen

  2. Udskriv hex-værdien af ​​hver byte

  3. Udskrivning af ASCII-værdien for hver byte



Det er nemt at udskrive en adresse i hex. Vi kan bruge \%p til at udskrive adressen på en peger som denne:


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


Derefter kan du udskrive hex-værdien af ​​en byte ved hjælp af \%02x på en char (1 byte). 02 angiver en nul polstret feltbredde på 2. I dette tilfælde er det bare at lave 0 som 00 for at gøre tingene lineært og se smukke ud.


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


Endelig er udskrivning ASCII det nemmeste af alle ... næsten. Vi kan bruge \%c til at udskrive en byte for nogle ASCII-værdier, men vi vil ikke udskrive ting som eller . For at løse dette kan vi begrænse brugen af ​​ 19]] til tegnet/symbolregionen i ASCII-tabellen og udskrive . for alt andet. [23]


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


Nu skal vi bare kombinere disse sammen. Du kan bestemme, hvor mange byte du vil vise pr. Linje og udskrive '[[adresse]] [[n hex bytes]] [[n ascii bytes]]' og gentag indtil du har gået gennem hele hukommelsesområdet. Jeg har givet en prøvefunktion nedenfor og du kan køre det selv her. [24]


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	", addr);

        // Print Hex
        for (int i = 0; i < line\_len; i++) {
            printf(" \%02x", data[linno*line\_len + i]);
        }
        printf("	");

        // 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("
");

        // 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	", 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("	");

        // 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("
");
     }
 }


Prøveudgang:


0x1e79010        74 65 73 74 79 2a 6e    t e s t y * 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    n k [ . 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





Hvad angår den anden del af dit spørgsmål, hvis du ikke kan øge størrelsen på tempbuf, så sidder du fast i den mængde hukommelse til enhver tid.


Men hvis alt du vil gøre er at vise hukommelsen som beskrevet ovenfor, kan du vise hvert afsnit af hukommelsen i stykker. Du kan få en klump af hukommelse, vise den, så få en ny klump, vis den nye klump, gentag.


Noget i retning af


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;
}


Du bliver nødt til at gøre lidt mere arbejde for at kontrollere fejl og få alt til at se godt ud, men forhåbentlig giver det dig en god ide om hvad der kunne gøres.

Andre referencer 1


Der er ingen mulighed for at gemme flere data, end du har plads til. Hvis du skal gemme flere data, skal du allokere mere plads et sted (mere RAM, en diskfil osv.). Komprimering giver dig mulighed for at gemme lidt flere data i den tildelte plads, men du vil ikke få alt så meget. Til næsten ubegrænset lagring skal du skrive til disken.


Alternativt, hvis du bare skal vise en gang og derefter glemme, læs i 16 byte, vis linjen, og læs derefter de næste 16 byte i samme hukommelse.