RG5
RG5

Reputation: 519

Access to ctypes **argv from binary file through Python

I have the following struct output in a binary file from hashcat restore file:

typedef struct
{
  uint32_t  version_bin;
  char      cwd[256];
  uint32_t  argc;
  char      **argv;
  uint32_t  pid;

  uint32_t  devices_cnt;

  uint32_t  dictpos;
  uint32_t  maskpos;

  uint64_t *pw_off;
  uint64_t *pw_num;
  uint64_t  pw_cur;

  uint32_t  digests_cnt;
  uint32_t  digests_done;
  uint     *digests_shown;

  uint32_t  salts_cnt;
  uint32_t  salts_done;
  uint     *salts_shown;

  float     ms_running;

} restore_data_t;

I'm trying to import the raw data and parse it with a Python script using the ctypes data structure as follows:

class RestoreStruct(Structure):

    _fields_ = [
        ("version_bin", c_uint32),
        ("cwd", c_char*256),
        ("argc", c_uint32),
        ("argv", POINTER(POINTER(c_char))), 
        ("pid", c_uint32),
        ("devices_cnt", c_uint32),
        ("dictpos", c_uint32),
        ("maskpos", c_uint32),
        ("pw_off", POINTER(c_uint64)),  
        ("pw_NUM", POINTER(c_uint64)),  
        ("pw_CUR", c_uint64),
        ("digests_cnt", c_uint32),
        ("digests_done", c_uint32),
        ("digests_shown", POINTER(c_uint32)),   
        ("salts_cnt", c_uint32),
        ("salts_done", c_uint32),
        ("salts_shown", POINTER(c_uint*30)),    
        ("ms_running", c_float)

        ]

with open("cudaHashcat.restore", "rb") as restore_file:

    status = []
    struct = RestoreStruct()
    while restore_file.readinto(struct) == sizeof(struct):
        status.append((struct.version_bin, struct.cwd, struct.argc, struct.argv, \
                    struct.pid, struct.devices_cnt, struct.dictpos, struct.maskpos, struct.pw_off, \
                    struct.pw_NUM, struct.pw_CUR, struct.digests_cnt, struct.digests_done, struct.digests_shown, \
                    struct.salts_cnt, struct.salts_done, struct.salts_shown, struct.ms_running))



    print struct._fields_[0][0], status[0][0]
    print struct._fields_[1][0], status[0][1]
    print struct._fields_[2][0], status[0][2]
    print struct._fields_[3][0], status[0][3]
    print struct._fields_[4][0], status[0][4]
    print struct._fields_[5][0], status[0][5]
    print struct._fields_[6][0], status[0][6]
    print struct._fields_[7][0], status[0][7]
    print struct._fields_[8][0], status[0][8]
    print struct._fields_[9][0], status[0][9]
    print struct._fields_[10][0], status[0][10]
    print struct._fields_[11][0], status[0][11]
    print struct._fields_[12][0], status[0][12]
    print struct._fields_[13][0], status[0][13]
    print struct._fields_[14][0], status[0][14]
    print struct._fields_[15][0], status[0][15]
    print struct._fields_[16][0], status[0][16]
    print struct._fields_[17][0], status[0][17]

This issue I'm having is how to access the data in the pointer ctypes (argv,pw_off, etc)? I've tried the "contents", but I get "NULL pointer access" error. argv should be an array of char arrays, and the others should be a simple pointer to an int.

How would I access the actual data that the pointers are addressing? Am I completely off on how I'm going about this?

Here is a base64 encoded version of the restore file:

ZQAAAEU6XG9jbEhhc2hjYXQtMS4wMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAAAACBdvAHwiAAABAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAABACgBAAAAAA8AAAAFAAAAAAAAAAEAAAAAAAAAAAAAAEDPnkYAAAAAY3VkYUhh c2hjYXQzMgotbQoxMDAwCi1hCjAKLXIKcnVsZXNccmljaF9wd19ydWxlcy5ydWxlCi4uXHBsYWlu X3RleHRfaGFzaC50eHQKLi5cMTZfV2Fsa19taW4udHh0Cv//JwEAAAAAAAAIAAAAAAAAAAAAAQAA AAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

As pointed out in the comments it looks like the argv values are stored in the file as plain text. My issue is still how to read this information into a struct properly. All of the other values in the restore struct are read in and stored correctly in the python object, but the code above. Any pointer structure though doesn't read in as easy.

Upvotes: 2

Views: 737

Answers (1)

RG5
RG5

Reputation: 519

Taking eryksun's advice here what I did to get the argv values.

class RestoreStruct(Structure):

    _fields_ = [
        ("version_bin", c_uint32),
        ("cwd", c_char*256),
        ("argc", c_uint32),
        ("argv", POINTER(POINTER(c_char))), 
        ("pid", c_uint32),
        ("devices_cnt", c_uint32),
        ("dictpos", c_uint32),
        ("maskpos", c_uint32),
        ("pw_off", POINTER(c_uint64)),  
        ("pw_NUM", POINTER(c_uint64)),  
        ("pw_CUR", c_uint64),
        ("digests_cnt", c_uint32),
        ("digests_done", c_uint32),
        ("digests_shown", POINTER(c_uint32)),   
        ("salts_cnt", c_uint32),
        ("salts_done", c_uint32),
        ("salts_shown", POINTER(c_uint*30)),    
        ("ms_running", c_float)

        ]

with open("cudaHashcat.restore", "rb") as restore_file:

    status = []
    struct = RestoreStruct()
    restore_file.readinto(struct)
    rest = restore_file.read()

    print struct.version_bin
    # Print rest of variables that are not pointers

    print rest.splitlines()[0:struct.argc]    # Prints a list structure of argv values

Upvotes: 1

Related Questions