@@ -73,34 +73,54 @@ def chromeos_offset(self):
73
73
74
74
return offset
75
75
76
- def _find_file_naive (self , filename ):
76
+ def _find_file_in_chunk (self , bfname , chunk ):
77
+ """
78
+ Checks if the filename is found in the given chunk.
79
+ Then makes some plausibility checks, to see if it is in fact a proper dentry.
80
+
81
+ returns the dentry if found, else False.
82
+ """
83
+
84
+ if bfname in chunk :
85
+ i_index_pos = chunk .index (bfname ) - 8 # the filename is the last element of the dentry, the elements before are 8 bytes total
86
+ file_entry = self .dir_entry (chunk [i_index_pos :i_index_pos + len (bfname ) + 8 ]) # 8 because see above
87
+ if file_entry ['inode' ] < self .sb_dict ['s_inodes_count' ] and file_entry ['name_len' ] == len (bfname ):
88
+ return file_entry
89
+
90
+ log (0 , 'Found filename, but checks did not pass:' )
91
+ log (0 , 'inode number: {inode} < {count}, name_len: {name_len} == {len_fname}' .format (inode = file_entry ['inode' ],
92
+ count = self .sb_dict ['s_inodes_count' ],
93
+ name_len = file_entry ['name_len' ],
94
+ len_fname = len (bfname )))
95
+ return False
96
+
97
+ def _find_file_naive (self , fname ):
77
98
"""
78
99
Finds a file by basically searching for the filename as bytes in the bytestream.
79
100
Searches through the whole image only once, making it fast, but may be unreliable at times.
80
101
81
102
Returns a directory entry.
82
103
"""
83
104
84
- bin_filename = filename .encode ('ascii' )
105
+ fname_alt = fname + '#new' # Sometimes the filename has "#new" at the end
106
+ bfname = fname .encode ('ascii' )
107
+ bfname_alt = fname_alt .encode ('ascii' )
85
108
chunksize = 4 * 1024 ** 2
86
109
chunk1 = self .read_stream (chunksize )
87
110
while True :
88
111
chunk2 = self .read_stream (chunksize )
89
112
if not chunk2 :
90
- raise ChromeOSError ('File {filename } not found in the ChromeOS image' .format (filename = filename ))
113
+ raise ChromeOSError ('File {fname } not found in the ChromeOS image' .format (fname = fname ))
91
114
92
115
chunk = chunk1 + chunk2
93
- if bin_filename in chunk :
94
- i_index_pos = chunk .index (bin_filename ) - 8
95
- file_entry = self .dir_entry (chunk [i_index_pos :i_index_pos + len (filename ) + 8 ])
96
- if file_entry ['inode' ] < self .sb_dict ['s_inodes_count' ] and file_entry ['name_len' ] == len (filename ):
97
- break
98
-
99
- log (0 , 'Found filename, but checks did not pass:' )
100
- log (0 , 'inode number: {inode} < {count}, name_len: {name_len} == {len_filename}' .format (inode = file_entry ['inode' ],
101
- count = self .sb_dict ['s_inodes_count' ],
102
- name_len = file_entry ['name_len' ],
103
- len_filename = len (filename )))
116
+
117
+ file_entry = self ._find_file_in_chunk (bfname , chunk )
118
+ if file_entry :
119
+ break
120
+
121
+ file_entry = self ._find_file_in_chunk (bfname_alt , chunk )
122
+ if file_entry :
123
+ break
104
124
105
125
chunk1 = chunk2
106
126
0 commit comments