Access to ctypes **argv from binary file through Python
Question: 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.


Answer: 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
    

