OhGodAPet icon

Structure Dumper Generator

OhGodAPet | PRO | 09/22/22 01:47:52 PM UTC | 0 ⭐ | 1023 👁️ | Never ⏰ | []
C |

4.83 KB

|

None

|

0 👍

/

0 👎

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
 
// Ref struct
/*
typedef struct
{
    uint32_t VersionID;
    uint8_t KeyID[16];
    uint8_t CertifyingKeyID[16];
    uint32_t KeyUsageFlag;
    uint8_t PlatformBindingInfo;
    uint8_t Reserved[15];
    uint32_t PublicExponentSize;
    uint32_t ModulusSize;
    PSPRSAKey RSAKeyData;
} PSPRSAKeyHdr;
* */
 
const char Structure[] =
"typedef struct\n"
"{\n"
"   uint32_t VersionID;\n"
"   uint8_t KeyID[16];\n"
"   uint8_t CertifyingKeyID[16];\n"
"   uint32_t KeyUsageFlag;\n"
"   uint8_t PlatformBindingInfo;\n"
"   uint8_t Reserved[15];\n"
"   uint32_t PublicExponentSize;\n"
"   uint32_t ModulusSize;\n"
"   PSPRSAKey RSAKeyData;\n"
"} PSPRSAKeyHdr;\n";
 
typedef struct StructMember_s
{
    char *TypeStr;
    char *NameStr;
    uint32_t TypeSize;
    uint32_t ArraySize;
    struct StructMember_s *next;
} StructMember;
 
char *CarveStr(const char *Src, size_t StartOffset, size_t Len)
{
    //char *TmpBuf = (char *)malloc(sizeof(char) * (Len + 1));
    char TmpBuf[256];
    char *Output;
    
    memcpy(TmpBuf, Src + StartOffset, Len);
    TmpBuf[Len] = 0x00;
    Output = strdup(TmpBuf);
    //free(TmpBuf);
    
    return(Output);
}
 
int main(int argc, char **argv)
{
    //char *inputstruct = Structure;
    StructMember *MemberList = NULL;
    
    if(argc != 2)
    {
        printf("Usage: %s <structure definition>\n", argv[0]);
        return(-1);
    }
    
    char *inputstruct = (char *)malloc(strlen(argv[1]) + 1);
    strcpy(inputstruct, argv[1]);
    
    for(char *line = strtok(inputstruct, "\n"); line; line = strtok(NULL, "\n"))
    {
        StructMember *memb = MemberList;
        
        // If the line does not have a semicolon, it can be
        // safely ignored.
        if(!strchr(line, ';'))
            continue;
            
        // First, is this really a type?
        uint32_t SizeOfType;
        char *NamePos, *NameEnd, *TypePos, *TypeEnd, *ArrStart, *ArrEnd;
        
        TypePos = strstr(line, "uint");
        
        if(TypePos)
        {
            // Is it uint8_t? If so, stash the info in variables
            if(TypePos[4] == '8' && TypePos[5] == '_' && TypePos[6] == 't')
            {
                NamePos = TypePos + strlen("uint8_t");
                SizeOfType = 1;
            }
            // Is it uint16_t? Same deal.
            else if(TypePos[4] == '1' && TypePos[5] == '6' && TypePos[6] == '_' && TypePos[7] == 't')
            {
                NamePos = TypePos + strlen("uint16_t");
                SizeOfType = 2;
            }
            // Same for uint32_t...
            else if(TypePos[4] == '3' && TypePos[5] == '2' && TypePos[6] == '_' && TypePos[7] == 't')
            {
                NamePos = TypePos + strlen("uint32_t");
                SizeOfType = 4;
            }
            // Ditto for uint64_t.
            else if(TypePos[4] == '6' && TypePos[5] == '4' && TypePos[6] == '_' && TypePos[7] == 't')
            {
                NamePos = TypePos + strlen("uint64_t");
                SizeOfType = 8;
            }
            
            if(!memb) MemberList = memb = (StructMember *)malloc(sizeof(StructMember));
            else
            {
                //  Skip all previous members
                for(memb = MemberList; memb->next; memb = memb->next);
                
                memb = memb->next = (StructMember *)malloc(sizeof(StructMember));
            }
            
            memset(memb, 0x00, sizeof(StructMember));
            TypeEnd = TypePos;
            
            while(!isspace(*TypeEnd)) TypeEnd++;
            
            //printf("TypeEnd = %s\nTypePos = %s\n", TypeEnd, TypePos);
            NamePos = TypeEnd + 1;
            NameEnd = strchr(NamePos, ';') - 1;
            
            if(!NameEnd)
            {
                printf("Error: Malformed line %s\n", line);
                exit(1);
            }
            
            memb->TypeStr = CarveStr(TypePos, 0x00, (SizeOfType == 1) ? 7 : 8);
            memb->NameStr = CarveStr(NamePos, 0x00, NameEnd - NamePos + 1);
            memb->TypeSize = SizeOfType;
            
            // Is it an array?
            ArrStart = strchr(memb->NameStr, '[');
            
            // If so, get the size.
            if(ArrStart)
            {
                ArrEnd = strchr(memb->NameStr, ']');
                memb->ArraySize = strtoul(ArrStart + 1, NULL, 0);
                // Cut the array notation off the name.
                ArrStart[0] = 0x00;
            }
            
            memb->next = NULL;
        }
        else
        {
            printf("Warning: Line not recognized: '%s'\n", line);
        }
    }
    
    // Info harvested; time to generate code.
    for(StructMember *CurMemb = MemberList; CurMemb; CurMemb = CurMemb->next)
    {
        char *TypeSpecifier = NULL;
        
        //printf("TypeStr = %s\nNameStr = %s\nArraySize = %d\n", CurMemb->TypeStr, CurMemb->NameStr, CurMemb->ArraySize);
        
        if(CurMemb->TypeSize == 1) TypeSpecifier = "0x%02X";
        else if(CurMemb->TypeSize == 2) TypeSpecifier = "0x%04X";
        else if(CurMemb->TypeSize == 4) TypeSpecifier = "0x%08X";
        else if(CurMemb->TypeSize == 8) TypeSpecifier = "0x%016llX";
        else printf("How did you even get here?");
        
        printf("printf(\"%s: ", CurMemb->NameStr);
        
        if(CurMemb->ArraySize)
        {
            printf("\");\n");
            printf("\nfor(int i = 0; i < %d; ++i)\n", CurMemb->ArraySize);
            printf("\tprintf(\"%s, \", dmp->%s[i]);\n\n", TypeSpecifier, CurMemb->NameStr);
            printf("putchar('\\n');\n");
        }
        else
        {
            printf("%s\\n\", dmp->%s);\n", TypeSpecifier, CurMemb->NameStr);
        }
    }
    
    
    
    return(0);
}
 

Comments