【Hashcat】statsprocessor(马尔可夫过程)部分源码分析
文件sp.c
函数E sp_get_sum
目的:算出掩码展开后的总空间。
输入:start(密码的开头位置), stop(密码的结尾位置), root_css_buf(每一位对应的展开后字库的集合)
输出:sum(空间大小)
内容:
1. 循环:从start到stop
1.1 sum *= root_css_buf.cs_len(sum初始值为1)
main函数(只包含sp处理部分)
sp部分1 生成root_css_buf和markov_css_buf
功能:由统计数据hcstats生成root_css_buf和markov_css_buf
输入:hcstats File
(统计数据文件,root方面是各密码位置某字符的出现次数,
markov则是各密码位置某字符出现后,其后续其他字符出现次数)
输出:root_css_buf、markov_css_buf(另有例子解析其结构)
内容:
1. Initialize hcstats
2. Load hcstats File
3. Markov modifier of hcstat_table on user request(不太重要)
4. Add all stats to first position & copy them to all pw_positions
5. Initialize tables
6. Convert hcstat to tables
7. Sort them
8. Convert tables to css
补充说明:
1)Add all stats to first position & copy them to all pw_positions
以root中12位pw,其中的a字符在各pw位的出现次数为例,markov同理:
就是说,12个位置中的a字符出现次数加到一起,然后把这个和赋给12个pw位。
2)由hcstats ---> tables ---> css的意义:
(具体还是要看代码,这里简略说明一下)
皆以root为例,pw12位,字符256。
hcstats:每个pw位中,256字符分别的统计而来的出现次数;
tables:转换了一下数据结构,每个pw位中,256字符的字符值key+出现次数val,
这里table的数据结构,主要为了之后利用val来对key进行排序;
css:根据每个pw位的唯一存在表uniq,去除每个pw位256字符中不存在的,
并把存在的存入每个pw位新的数据结构cs_t(buf和len为主)中,
由于之前table中排过序,这里也是有序的;
markov:和root不同的是,pw位的key是pw+1位的,为什么呢?
请百度马尔可夫过程,看看知乎上那个高亮的答就行。
sp部分1.1 Convert hcstat to tables
功能:由统计数据stats_buf生成table_buf
输入:root_stats_buf、markov_stats_buf
输出:root_table_buf、markov_table_buf
内容:
1. 生成二维数组root_table(意义上,代码中没有),
一维表示形式root_table_buf
一维表示形式root_table_buf_by_key,用于排序
markov_table同理,一维和三维;
(Initialize tables那段,很长但其实有点类似new)
2. for(PW位数上限 * 字符种类上限)
源码中(root_cnt = PW_MAX * CHARIZ)
2.1 字符key = i % CHARIZ,例如(11*256 + 255) % 256 = 255;
2.2 转换成key,val形式,为之后的排序作准备,
root_table_buf[i].key = key;
root_table_buf[i].val = root_stats_buf[i];
3.for(PW位数上限 * 字符种类上限 * 字符种类上限)
源码中(markov_cnt = PW_MAX * CHARIZ * CHARIZ)
3.1 字符key = i % CHARIZ,例如(11*25*256 + 255) % 256 = 255;
3.2 转换成key,val形式,为之后的排序作准备,
markov_table_buf[i].key = key;
markov_table_buf[i].val = markov_stats_buf[i];
4.释放stats_buf的空间。
sp部分1.2 Convert tables to css
功能:由表格tables_buf生成css_buf
输入:root_tables_buf、markov_tables_buf
输出:root_css_buf、markov_css_buf
内容:
1.初始化root_css_buf和markov_css_buf,
root为例,由于现在是字符组织成cs_t的形式(例如256类型字库,就是cs_buf,cs_len=256),
所以变为一维数组, cs_t *root_css_buf = (cs_t *) calloc (PW_MAX, sizeof (cs_t))。
markov同理;
2. for (PW位数上限 * 字符种类上限)
2.1 当前pw位pw_pos = i / 字符种类上限;
2.2 从root_css_buf中,取得当前pw位pw_pos的cs(字库)空间;
2.3 从root_table_buf中,获取当前pw位的字符key,之前已经转化成table形式;
2.4 从mask_css中,取得当前的pw位的字库唯一存在表mask_css[pw_pos].cs_uniq
2.4.1 if (当前位置的存在表中,没有字符key) continue;
2.5 将key写入当前位置字库的cs_buf中,然后cs_len递增;
3. for (PW位数上限 * 字符种类上限 * 字符种类上限)
3.1 当前pw位中的第n个字符,例如第1位中的第5个字符,c = i / 字符种类上限;
3.2 从markov_css_buf中,取得当前c位的cs(字库)空间;
3.3 从markov_table_buf中,获取当前c位的字符key,之前已经转化成table形式;
3.4 当前pw位pw_pos = c / 字符种类上限;
3.4 从mask_css中,取得当前的pw位的字库唯一存在表mask_css[pw_pos].cs_uniq
3.4.1 if (当前pw位还没到末尾) if(当前位置的下一位置的存在表中,没有字符key)continue;
为什么是下一位置,参考这个马尔可夫转移矩阵的第二天状态:
3.5 将key写入当前位置字库的cs_buf中,然后cs_len递增;