-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
208 lines (208 loc) · 94.1 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://isKoi.github.io</id>
<title>Koi的学习之路</title>
<subtitle></subtitle>
<icon>https://iskoi.github.io/images/favicon.ico</icon>
<link href="https://isKoi.github.io" />
<author>
<name>Koi</name>
</author>
<updated>2023-03-23T14:30:00.000Z</updated>
<entry>
<id>https://iskoi.github.io/reverseEngineering/pyinstaller/</id>
<title>逆向实战-反编译Pyinstall打包的exe并进行功能分析</title>
<link rel="alternate" href="https://iskoi.github.io/reverseEngineering/pyinstaller/"/>
<content type="html"><h1 id="前言"><a class="anchor" href="#前言">#</a> 前言</h1>
<p>最近接触到一个程序,大概功能就是用激活码安装游戏,有点好奇想看看什么原理</p>
<h1 id="一-查壳脱壳"><a class="anchor" href="#一-查壳脱壳">#</a> 一、查壳脱壳</h1>
<p>使用 <span class="label danger">Detect It Easy</span> 进行查壳<br />
<img data-src="https://s2.loli.net/2023/04/12/j97eUApKZiTLNkq.png" alt="" /><br />
原来是用 <span class="label danger">PyInstaller</span> 打包的,这不简单?都不用反汇编了,直接反编译</p>
<h1 id="二-反编译"><a class="anchor" href="#二-反编译">#</a> 二、反编译</h1>
<p>先使用<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2V4dHJlbWVjb2RlcnMtcmUvcHlpbnN0eHRyYWN0b3I="> PyInstaller Extractor</span> 工具解包</p>
<figure class="highlight powershell"><figcaption data-lang="PowerShell"><span>命令提示符</span></figcaption><table><tr><td data-num="1"></td><td data-command="D:\Koi>"></td><td><pre>python <span class="token punctuation">.</span>\pyinstxtractor<span class="token punctuation">.</span>py <span class="token punctuation">.</span>\xxx<span class="token punctuation">.</span>exe</pre></td></tr><tr><td data-num="2"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Processing <span class="token punctuation">.</span>\xxx<span class="token punctuation">.</span>exe</pre></td></tr><tr><td data-num="3"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Pyinstaller version: 2<span class="token punctuation">.</span>1+</pre></td></tr><tr><td data-num="4"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Python version: 3<span class="token punctuation">.</span>10</pre></td></tr><tr><td data-num="5"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Length of package: 29268660 bytes</pre></td></tr><tr><td data-num="6"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Found 138 files in CArchive</pre></td></tr><tr><td data-num="7"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Beginning extraction<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>please standby</pre></td></tr><tr><td data-num="8"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Possible entry point: pyiboot01_bootstrap<span class="token punctuation">.</span>pyc</pre></td></tr><tr><td data-num="9"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Possible entry point: pyi_rth_inspect<span class="token punctuation">.</span>pyc</pre></td></tr><tr><td data-num="10"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Possible entry point: pyi_rth_pyqt5<span class="token punctuation">.</span>pyc</pre></td></tr><tr><td data-num="11"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Possible entry point: pyi_rth_pkgutil<span class="token punctuation">.</span>pyc</pre></td></tr><tr><td data-num="12"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Possible entry point: pyi_rth_multiprocessing<span class="token punctuation">.</span>pyc</pre></td></tr><tr><td data-num="13"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Possible entry point: main<span class="token punctuation">.</span>pyc</pre></td></tr><tr><td data-num="14"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Found 279 files in PYZ archive</pre></td></tr><tr><td data-num="15"></td><td data-command=""></td><td><pre><span class="token punctuation">[</span><span class="token operator">+</span><span class="token punctuation">]</span> Successfully extracted pyinstaller archive: <span class="token punctuation">.</span>\xxx<span class="token punctuation">.</span>exe</pre></td></tr><tr><td data-num="16"></td><td data-command=""></td><td><pre></pre></td></tr><tr><td data-num="17"></td><td data-command=""></td><td><pre>You can now use a python decompiler on the pyc files within the extracted directory</pre></td></tr></table></figure><p>新版 <span class="label danger">PyInstaller Extractor</span> 会自动对 pyc 文件添加 magic head,所以这里我们不用手动修改,也可以检查一下以防万一<br />
然后安装 <span class="label danger">uncompyle6</span> 反编译 pyc 文件</p>
<figure class="highlight powershell"><figcaption data-lang="PowerShell"><span>命令提示符</span></figcaption><table><tr><td data-num="1"></td><td data-command="D:\Koi>"></td><td><pre>pip install uncompyle6</pre></td></tr><tr><td data-num="2"></td><td data-command="D:\Koi>"></td><td><pre>cd <span class="token punctuation">.</span>\xxx<span class="token punctuation">.</span>exe_extracted\</pre></td></tr><tr><td data-num="3"></td><td data-command="D:\Koi\xxx.exe_extracted>"></td><td><pre>uncompyle6 <span class="token operator">-</span>o main<span class="token punctuation">.</span>py main<span class="token punctuation">.</span>pyc</pre></td></tr><tr><td data-num="4"></td><td data-command=""></td><td><pre>Unsupported Python version<span class="token punctuation">,</span> 3<span class="token punctuation">.</span>10<span class="token punctuation">.</span>0<span class="token punctuation">,</span> <span class="token keyword">for</span> decompilation</pre></td></tr><tr><td data-num="5"></td><td data-command=""></td><td><pre><span class="token comment"># Unsupported bytecode in file main.pyc</span></pre></td></tr><tr><td data-num="6"></td><td data-command=""></td><td><pre><span class="token comment"># Unsupported Python version, 3.10.0, for decompilation</span></pre></td></tr><tr><td data-num="7"></td><td data-command=""></td><td><pre>main<span class="token punctuation">.</span>pyc <span class="token operator">--</span> decompiled 0 files: 0 okay<span class="token punctuation">,</span> 0 failed</pre></td></tr></table></figure><p><span class="label danger">uncompyle6</span> 不支持 Python310,那试试 <span class="label danger">pycdc</span> 反编译工具</p>
<figure class="highlight powershell"><figcaption data-lang="PowerShell"><span>命令提示符</span></figcaption><table><tr><td data-num="1"></td><td data-command="D:\Koi\xxx.exe_extracted>"></td><td><pre>pycdc main<span class="token punctuation">.</span>pyc >main<span class="token punctuation">.</span>py</pre></td></tr><tr><td data-num="2"></td><td data-command=""></td><td><pre><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span></pre></td></tr><tr><td data-num="3"></td><td data-command=""></td><td><pre><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span></pre></td></tr><tr><td data-num="4"></td><td data-command=""></td><td><pre>Unsupported opcode: JUMP_IF_NOT_EXC_MATCH</pre></td></tr></table></figure><p><span class="label danger">JUMP_IF_NOT_EXC_MATCH</span> 是最近刚添加的字节码, <span class="label danger">pycdc</span> 尚未进行适配,因此生成的源码是不完整的,可以用<span class="label danger"> pycdas</span> 反汇编,结合 main.py 来进行分析<br />
但是呢, <span class="label danger">JUMP_IF_NOT_EXC_MATCH</span> 字节码与 <span class="label danger">try...except</span> 异常处理相关,我的目标是功能分析,所以要看的是正常无报错的代码,所以我们可以忽略这个错误<br />
不过因为 <span class="label danger">pycdc</span> 报错后会中断跳过当前函数,所以要对 <span class="label danger">pycdc</span> 进行修改<br />
打开<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3pyYXgvcHljZGM="> pycdc Github 仓库</span>利用 Github 的搜索功能,搜索 Unsupported opcode,搜索到关键代码在 ASTree.cpp 当中</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">case</span> Pyc<span class="token double-colon punctuation">::</span>YIELD_VALUE<span class="token operator">:</span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="3"></td><td><pre> PycRef<span class="token operator">&lt;</span>ASTNode<span class="token operator">></span> value <span class="token operator">=</span> stack<span class="token punctuation">.</span><span class="token function">top</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> stack<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="5"></td><td><pre> curblock<span class="token operator">-></span><span class="token function">append</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token function">ASTReturn</span><span class="token punctuation">(</span>value<span class="token punctuation">,</span> ASTReturn<span class="token double-colon punctuation">::</span>YIELD<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token keyword">break</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token keyword">case</span> Pyc<span class="token double-colon punctuation">::</span>SETUP_ANNOTATIONS<span class="token operator">:</span></pre></td></tr><tr><td data-num="9"></td><td><pre> variable_annotations <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token keyword">break</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token keyword">case</span> Pyc<span class="token double-colon punctuation">::</span>PRECALL_A<span class="token operator">:</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token keyword">case</span> Pyc<span class="token double-colon punctuation">::</span>RESUME_A<span class="token operator">:</span></pre></td></tr><tr><td data-num="13"></td><td><pre> <span class="token comment">/* We just entirely ignore this / no-op */</span></pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token keyword">break</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="15"></td><td><pre> <span class="token keyword">case</span> Pyc<span class="token double-colon punctuation">::</span>CACHE<span class="token operator">:</span></pre></td></tr><tr><td data-num="16"></td><td><pre> <span class="token comment">/* These "fake" opcodes are used as placeholders for optimizing</pre></td></tr><tr><td data-num="17"></td><td><pre> certain opcodes in Python 3.11+. Since we have no need for</pre></td></tr><tr><td data-num="18"></td><td><pre> that during disassembly/decompilation, we can just treat these</pre></td></tr><tr><td data-num="19"></td><td><pre> as no-ops. */</span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token keyword">break</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="21"></td><td><pre> <span class="token keyword">case</span> Pyc<span class="token double-colon punctuation">::</span>PUSH_NULL<span class="token operator">:</span></pre></td></tr><tr><td data-num="22"></td><td><pre> stack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="23"></td><td><pre> <span class="token keyword">break</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="24"></td><td><pre> <span class="token keyword">default</span><span class="token operator">:</span></pre></td></tr><tr><td data-num="25"></td><td><pre> <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"Unsupported opcode: %s\n"</span><span class="token punctuation">,</span> <span class="token class-name">Pyc</span><span class="token double-colon punctuation">::</span><span class="token function">OpcodeName</span><span class="token punctuation">(</span>opcode <span class="token operator">&amp;</span> <span class="token number">0xFF</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="26"></td><td><pre> cleanBuild <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="27"></td><td><pre> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token function">ASTNodeList</span><span class="token punctuation">(</span>defblock<span class="token operator">-></span><span class="token function">nodes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>虽然说我不会 <span class="label danger">C++</span> ,但是基本的是可以看得懂,因为用的方法都一样,这里是用了 <span class="label danger">swtich...case...default</span> 方法,当 switch 的值与所有的 case 的值不相等时,就会运行 default 语句,所以这里我们要修改 default 之后的代码,fprintf 除外全部注释掉,然后让<span class="label danger"> opcode</span> 出栈,从上下文分析可以发现 opcode 是存在 stack 里的,在 fprintf 的下一行写入 stack.pop ();<br />
重新编译得到 pycdc.exe,重命名为 pycdc1.exe 和原版 <span class="label danger">pycdc</span> 区分开,方便以后调用<br />
使用 pycdc1 对 main.pyc 反编译,并找到关键函数</p>
<figure class="highlight python"><figcaption data-lang="python"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">def</span> <span class="token function">on_click_act</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'button clicked.'</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="3"></td><td><pre> </pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token keyword">try</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="5"></td><td><pre> code <span class="token operator">=</span> self<span class="token punctuation">.</span>lineEdit<span class="token punctuation">.</span>text<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token keyword">if</span> code <span class="token operator">==</span> <span class="token string">''</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="7"></td><td><pre> msg_box <span class="token operator">=</span> QMessageBox<span class="token punctuation">(</span>QMessageBox<span class="token punctuation">.</span>Critical<span class="token punctuation">,</span> <span class="token string">'\xe9\x94\x99\xe8\xaf\xaf'</span><span class="token punctuation">,</span> <span class="token string">'\xe8\xaf\xb7\xe8\xbe\x93\xe5\x85\xa5\xe6\xbf\x80\xe6\xb4\xbb\xe7\xa0\x81'</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="8"></td><td><pre> msg_box<span class="token punctuation">.</span>exec_<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token keyword">finally</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token keyword">return</span> <span class="token boolean">None</span></pre></td></tr><tr><td data-num="11"></td><td><pre> self<span class="token punctuation">.</span>lineEdit<span class="token punctuation">.</span>setEnabled<span class="token punctuation">(</span><span class="token boolean">False</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="12"></td><td><pre> self<span class="token punctuation">.</span>pushButton<span class="token punctuation">.</span>setText<span class="token punctuation">(</span><span class="token string">'\xe6\xbf\x80\xe6\xb4\xbb\xe4\xb8\xad'</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="13"></td><td><pre> self<span class="token punctuation">.</span>pushButton_2<span class="token punctuation">.</span>setText<span class="token punctuation">(</span><span class="token string">'\xe4\xbf\xae\xe5\xa4\x8d\xe9\x94\x99\xe8\xaf\xaf'</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="14"></td><td><pre> self<span class="token punctuation">.</span>pushButton<span class="token punctuation">.</span>setEnabled<span class="token punctuation">(</span><span class="token boolean">False</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="15"></td><td><pre> self<span class="token punctuation">.</span>pushButton_2<span class="token punctuation">.</span>setEnabled<span class="token punctuation">(</span><span class="token boolean">False</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="16"></td><td><pre> self<span class="token punctuation">.</span>work_thread <span class="token operator">=</span> WorkThread<span class="token punctuation">(</span>code<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="17"></td><td><pre> self<span class="token punctuation">.</span>work_thread<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>connect<span class="token punctuation">(</span>after_process<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="18"></td><td><pre> self<span class="token punctuation">.</span>work_thread<span class="token punctuation">.</span>start<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="19"></td><td><pre> <span class="token keyword">return</span> <span class="token boolean">None</span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token keyword">except</span> setText <span class="token keyword">as</span> e<span class="token punctuation">:</span></pre></td></tr><tr><td data-num="21"></td><td><pre> <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'Error'</span><span class="token punctuation">,</span>e<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="22"></td><td><pre> <span class="token keyword">break</span></pre></td></tr></table></figure><p>找到 <span class="label danger">on_click_act</span> 函数,从函数名和代码可以明显看出,这是按下按钮后执行的函数,首先判断 code 是否为空,是则弹出窗口提示 &quot;请输入激活码&quot;,所以 code 就是激活码,接下来就是更新按钮和输入框的状态,然后调用 <span class="label danger">WorkThread</span> 函数<br />
从 PYZ-00.pyz_extracted 文件夹找到 work_thread.pyc,用 pycdc1 反编译,仍然有 Unsupported opcode: JUMP_IF_NOT_EXC_MATCH 报错,不管它,直接看代码</p>
<figure class="highlight python"><figcaption data-lang="python"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">def</span> <span class="token function">WorkThread</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token triple-quoted-string string">'''WorkThread'''</span></pre></td></tr><tr><td data-num="3"></td><td><pre> trigger <span class="token operator">=</span> QtCore<span class="token punctuation">.</span>pyqtSignal<span class="token punctuation">(</span><span class="token builtin">str</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="4"></td><td><pre> </pre></td></tr><tr><td data-num="5"></td><td><pre> <span class="token keyword">def</span> <span class="token function">__init__</span><span class="token punctuation">(</span>self <span class="token operator">=</span> <span class="token boolean">None</span><span class="token punctuation">,</span> code <span class="token operator">=</span> <span class="token boolean">None</span><span class="token punctuation">,</span> parent <span class="token operator">=</span> <span class="token boolean">None</span><span class="token punctuation">)</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token builtin">super</span><span class="token punctuation">(</span>WorkThread<span class="token punctuation">,</span> self<span class="token punctuation">)</span><span class="token punctuation">.</span>__init__<span class="token punctuation">(</span>parent<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="7"></td><td><pre> self<span class="token punctuation">.</span>code <span class="token operator">=</span> code</pre></td></tr><tr><td data-num="8"></td><td><pre></pre></td></tr><tr><td data-num="9"></td><td><pre> </pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token keyword">def</span> <span class="token function">run</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="11"></td><td><pre> temp <span class="token operator">=</span> main_process<span class="token punctuation">(</span>self<span class="token punctuation">.</span>code<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="12"></td><td><pre> self<span class="token punctuation">.</span>trigger<span class="token punctuation">.</span>emit<span class="token punctuation">(</span>temp<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="13"></td><td><pre></pre></td></tr><tr><td data-num="14"></td><td><pre> __classcell__ <span class="token operator">=</span> <span class="token boolean">None</span></pre></td></tr><tr><td data-num="15"></td><td><pre></pre></td></tr><tr><td data-num="16"></td><td><pre>WorkThread <span class="token operator">=</span> <span class="token operator">&lt;</span>NODE<span class="token punctuation">:</span><span class="token number">27</span><span class="token operator">></span><span class="token punctuation">(</span>WorkThread<span class="token punctuation">,</span> <span class="token string">'WorkThread'</span><span class="token punctuation">,</span> QtCore<span class="token punctuation">.</span>QThread<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="17"></td><td><pre></pre></td></tr><tr><td data-num="18"></td><td><pre><span class="token keyword">def</span> <span class="token function">main_process</span><span class="token punctuation">(</span>code<span class="token punctuation">)</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="19"></td><td><pre> result <span class="token operator">=</span> xxxcore<span class="token punctuation">.</span>query_game<span class="token punctuation">(</span>code<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token keyword">if</span> result <span class="token keyword">is</span> <span class="token keyword">not</span> <span class="token boolean">False</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="21"></td><td><pre> depot_id_list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span></pre></td></tr><tr><td data-num="22"></td><td><pre> xxxcore<span class="token punctuation">.</span>close_xxx<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="23"></td><td><pre> <span class="token keyword">if</span> result<span class="token punctuation">[</span><span class="token string">'manifest'</span><span class="token punctuation">]</span> <span class="token keyword">is</span> <span class="token keyword">not</span> <span class="token boolean">None</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="24"></td><td><pre> depot_id_list <span class="token operator">=</span> xxxcore<span class="token punctuation">.</span>generate_manifest_vdf<span class="token punctuation">(</span>result<span class="token punctuation">[</span><span class="token string">'appid'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> result<span class="token punctuation">[</span><span class="token string">'manifest'</span><span class="token punctuation">]</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="25"></td><td><pre> xxxcore<span class="token punctuation">.</span>generate_applist<span class="token punctuation">(</span>result<span class="token punctuation">[</span><span class="token string">'appid'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> result<span class="token punctuation">[</span><span class="token string">'dlcid'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> depot_id_list<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="26"></td><td><pre> xxxcore<span class="token punctuation">.</span>get_user32<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="27"></td><td><pre> xxxcore<span class="token punctuation">.</span>code_add_1<span class="token punctuation">(</span>code<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="28"></td><td><pre> <span class="token keyword">if</span> result<span class="token punctuation">[</span><span class="token string">'exe_name'</span><span class="token punctuation">]</span> <span class="token keyword">is</span> <span class="token boolean">None</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="29"></td><td><pre> xxxcore<span class="token punctuation">.</span>code_add_1<span class="token punctuation">(</span>code<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="30"></td><td><pre> <span class="token keyword">if</span> result<span class="token punctuation">[</span><span class="token string">'family_sharing_code'</span><span class="token punctuation">]</span> <span class="token operator">!=</span> code<span class="token punctuation">:</span></pre></td></tr><tr><td data-num="31"></td><td><pre> xxxcore<span class="token punctuation">.</span>delete_code<span class="token punctuation">(</span>code<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="32"></td><td><pre> xxxcore<span class="token punctuation">.</span>start_xxx<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="33"></td><td><pre> xxxcore<span class="token punctuation">.</span>generate_shortcut<span class="token punctuation">(</span>result<span class="token punctuation">[</span><span class="token string">'appid'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> result<span class="token punctuation">[</span><span class="token string">'name_cn'</span><span class="token punctuation">]</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="34"></td><td><pre> <span class="token keyword">return</span> <span class="token string">'a'</span></pre></td></tr></table></figure><p>在主函数里,调用 <span class="label danger">main_process</span> 函数并传递了 code,在 <span class="label danger">main_process</span> 函数声明 result 变量的值为 xxxcore.query_game (code),看来 <span class="label danger">xxxcore</span> 就是我们要找的<br />
反编译,报错,管它呢...</p>
<figure class="highlight python"><figcaption data-lang="python"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">def</span> <span class="token function">query_game</span><span class="token punctuation">(</span>code<span class="token punctuation">)</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="2"></td><td><pre> db <span class="token operator">=</span> get_connection<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="3"></td><td><pre> cursor <span class="token operator">=</span> db<span class="token punctuation">.</span>cursor<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="4"></td><td><pre> sql <span class="token operator">=</span> <span class="token string">"SELECT game_info.appid,dlcid,name_cn,url,exe_name,family_sharing_code,manifest FROM activation_code INNER JOIN game_info ON activation_code.appid = game_info.appid WHERE code = '%s'"</span> <span class="token operator">%</span> code</pre></td></tr><tr><td data-num="5"></td><td><pre> </pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token keyword">try</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="7"></td><td><pre> cursor<span class="token punctuation">.</span>execute<span class="token punctuation">(</span>sql<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="8"></td><td><pre> results <span class="token operator">=</span> cursor<span class="token punctuation">.</span>fetchall<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token keyword">if</span> results <span class="token operator">!=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="10"></td><td><pre> result <span class="token operator">=</span> <span class="token builtin">dict</span><span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token keyword">for</span> row <span class="token keyword">in</span> results<span class="token punctuation">:</span></pre></td></tr><tr><td data-num="12"></td><td><pre> result<span class="token punctuation">[</span><span class="token string">'appid'</span><span class="token punctuation">]</span> <span class="token operator">=</span> row<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span></pre></td></tr><tr><td data-num="13"></td><td><pre> result<span class="token punctuation">[</span><span class="token string">'dlcid'</span><span class="token punctuation">]</span> <span class="token operator">=</span> row<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span></pre></td></tr><tr><td data-num="14"></td><td><pre> result<span class="token punctuation">[</span><span class="token string">'name_cn'</span><span class="token punctuation">]</span> <span class="token operator">=</span> row<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span></pre></td></tr><tr><td data-num="15"></td><td><pre> result<span class="token punctuation">[</span><span class="token string">'url'</span><span class="token punctuation">]</span> <span class="token operator">=</span> row<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span></pre></td></tr><tr><td data-num="16"></td><td><pre> result<span class="token punctuation">[</span><span class="token string">'exe_name'</span><span class="token punctuation">]</span> <span class="token operator">=</span> row<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span></pre></td></tr><tr><td data-num="17"></td><td><pre> result<span class="token punctuation">[</span><span class="token string">'family_sharing_code'</span><span class="token punctuation">]</span> <span class="token operator">=</span> row<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span></pre></td></tr><tr><td data-num="18"></td><td><pre> result<span class="token punctuation">[</span><span class="token string">'manifest'</span><span class="token punctuation">]</span> <span class="token operator">=</span> row<span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">]</span></pre></td></tr><tr><td data-num="19"></td><td><pre> <span class="token keyword">else</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token keyword">return</span> result</pre></td></tr><tr><td data-num="21"></td><td><pre> <span class="token keyword">return</span> <span class="token boolean">None</span></pre></td></tr><tr><td data-num="22"></td><td><pre> <span class="token keyword">return</span> <span class="token boolean">False</span></pre></td></tr><tr><td data-num="23"></td><td><pre> e <span class="token operator">=</span> <span class="token boolean">None</span></pre></td></tr><tr><td data-num="24"></td><td><pre> </pre></td></tr><tr><td data-num="25"></td><td><pre> <span class="token keyword">try</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="26"></td><td><pre> <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'\xe7\xbd\x91\xe7\xbb\x9c\xe9\x94\x99\xe8\xaf\xaf'</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="27"></td><td><pre> <span class="token keyword">finally</span><span class="token punctuation">:</span></pre></td></tr><tr><td data-num="28"></td><td><pre> e <span class="token operator">=</span> <span class="token boolean">None</span></pre></td></tr><tr><td data-num="29"></td><td><pre> <span class="token keyword">del</span> e </pre></td></tr><tr><td data-num="30"></td><td><pre> <span class="token keyword">return</span> <span class="token boolean">None</span></pre></td></tr><tr><td data-num="31"></td><td><pre> e <span class="token operator">=</span> <span class="token boolean">None</span></pre></td></tr><tr><td data-num="32"></td><td><pre> <span class="token keyword">del</span> e</pre></td></tr></table></figure><p>因为报错,后面的代码变得诡异,没关系,这不是关键代码<br />
可以看到这个函数就是从 <span class="label danger">mysql</span> 取出与游戏有关的信息,解读 sql 命令,查找 dlcid,appid 等数据,并且要满足 game_info.appid 和 activation_code.appid 相等,以及 activation_code.code 等于输入的 code 的条件<br />
这里就省略看代码的过程,直接概括</p>
<ul>
<li>在 /config/config.vdf 的 depot 元素添加用于解密 manifest 的 key</li>
<li>获取作者在腾讯云存储的 manifest 文件,添加到 /depotcache/ 下</li>
<li>获取 User32.dll (同上),存放在程序根目录</li>
<li>修改 /xxx.cfg 添加 BootStrapperInhibitAll=enable,查了一下,这个参数用来阻止自动更新</li>
<li>如果存在 /hid.dll,就删除</li>
<li>删除 /appcache/ 下的所有文件,清除 app 缓存,可能是为了刷新仓库界面</li>
<li>在 / Applist / 下 (如果没有就创建) 添加 txt 文件,文件名是有序的数字,如 &quot;0.txt&quot;,&quot;1.txt&quot;,&quot;3.txt&quot;,文件内容为 appid、dlcid、manifest,一个文件只写一个 id<br />
由于本期的主题是逆向 <span class="label danger">pyinstaller</span> 打包的程序,所以关于 User32.dll 的逆向放到下期</li>
</ul>
</content>
<category term="软件逆向工程" scheme="https://iskoi.github.io/categories/reverseEngineering/" />
<category term="逆向" scheme="https://iskoi.github.io/tags/%E9%80%86%E5%90%91/" />
<category term="pyinstaller" scheme="https://iskoi.github.io/tags/pyinstaller/" />
<category term="python" scheme="https://iskoi.github.io/tags/python/" />
<updated>2023-03-23T14:30:00.000Z</updated>
</entry>
<entry>
<id>https://iskoi.github.io/Programming/cmake/</id>
<title>Cmake安装与使用</title>
<link rel="alternate" href="https://iskoi.github.io/Programming/cmake/"/>
<content type="html"><h1 id="安装"><a class="anchor" href="#安装">#</a> 安装</h1>
<p><span class="exturl" data-url="aHR0cHM6Ly9jbWFrZS5vcmcvZG93bmxvYWQv">官方下载地址</span><br />
根据自己系统和架构下载对应的包<br />
<img data-src="https://s2.loli.net/2023/03/23/sLT26zeAobv5jIf.png" alt="" /><br />
选择<span class="pink"> Add CMake to the system PATH for the current user</span>,意思是只添加到用户环境变量,另一个就是添加到系统环境变量<br />
<img data-src="https://s2.loli.net/2023/03/23/LixeqmIfcJzYkNX.png" alt="" /><br />
安装完成后,打开 cmd 或者 Powershell, 输入命令<span class="blue"> cmake --version</span></p>
<figure class="highlight powershell"><figcaption data-lang="PowerShell"><span>命令提示符</span></figcaption><table><tr><td data-num="1"></td><td data-command="C:\Users\Koi>"></td><td><pre>cmake <span class="token operator">--</span>version</pre></td></tr><tr><td data-num="2"></td><td data-command=""></td><td><pre>cmake version 3<span class="token punctuation">.</span>26<span class="token punctuation">.</span>0</pre></td></tr><tr><td data-num="3"></td><td data-command=""></td><td><pre>CMake suite maintained and supported by Kitware <span class="token punctuation">(</span>kitware<span class="token punctuation">.</span>com/cmake<span class="token punctuation">)</span><span class="token punctuation">.</span></pre></td></tr></table></figure><p>如上,没有报错即安装成功</p>
<h1 id="使用"><a class="anchor" href="#使用">#</a> 使用</h1>
<p>这里用 <span class="label danger">Pycdc</span> 作为示例</p>
<figure class="highlight powershell"><figcaption data-lang="PowerShell"><span>命令提示符</span></figcaption><table><tr><td data-num="1"></td><td data-command="D:\Koi>"></td><td><pre>git clone https:<span class="token operator">/</span><span class="token operator">/</span>github<span class="token punctuation">.</span>com/zrax/pycdc<span class="token punctuation">.</span>git</pre></td></tr><tr><td data-num="2"></td><td data-command="D:\Koi>"></td><td><pre>cd pycdc</pre></td></tr><tr><td data-num="3"></td><td data-command="D:\Koi\pycdc>"></td><td><pre>cmake <span class="token punctuation">.</span></pre></td></tr><tr><td data-num="4"></td><td data-command="D:\Koi\pycdc>"></td><td><pre>MSBuild pycdc<span class="token punctuation">.</span>sln</pre></td></tr></table></figure><p>这里遇到几个坑,首先是输入<span class="blue"> cmake .</span> 后显示</p>
<figure class="highlight powershell"><figcaption data-lang="PowerShell"><span>命令提示符</span></figcaption><table><tr><td data-num="1"></td><td><pre>CMake Warning <span class="token punctuation">(</span>dev<span class="token punctuation">)</span> at CMakeLists<span class="token punctuation">.</span>txt:1 <span class="token punctuation">(</span>project<span class="token punctuation">)</span>:</pre></td></tr><tr><td data-num="2"></td><td><pre> cmake_minimum_required<span class="token punctuation">(</span><span class="token punctuation">)</span> should be called prior to this top-level project<span class="token punctuation">(</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="3"></td><td><pre> call<span class="token punctuation">.</span> Please see the cmake-commands<span class="token punctuation">(</span>7<span class="token punctuation">)</span> manual <span class="token keyword">for</span> usage documentation of</pre></td></tr><tr><td data-num="4"></td><td><pre> both commands<span class="token punctuation">.</span></pre></td></tr><tr><td data-num="5"></td><td><pre>This warning is <span class="token keyword">for</span> project developers<span class="token punctuation">.</span> Use <span class="token operator">-</span>Wno-dev to suppress it<span class="token punctuation">.</span></pre></td></tr></table></figure><p>意思是 <span class="label danger">cmake_minimum_required</span> 函数不能在 <span class="label danger">Project</span> 函数之后,编辑 CMakeLists.txt 将 <span class="label danger">cmake_minimum_required</span> 改到第一行即可<br />
第二个是找不到 <span class="label danger">Visual Studio</span></p>
<figure class="highlight powershell"><figcaption data-lang="PowerShell"><span>命令提示符</span></figcaption><table><tr><td data-num="1"></td><td><pre>CMake Error at CMakeLists<span class="token punctuation">.</span>txt:3 <span class="token punctuation">(</span>project<span class="token punctuation">)</span>:</pre></td></tr><tr><td data-num="2"></td><td><pre> Generator</pre></td></tr><tr><td data-num="3"></td><td><pre> Visual Studio 17 2022</pre></td></tr><tr><td data-num="4"></td><td><pre> could not find any instance of Visual Studio<span class="token punctuation">.</span></pre></td></tr><tr><td data-num="5"></td><td><pre>Configuring incomplete<span class="token punctuation">,</span> errors occurred!</pre></td></tr></table></figure><p>打开 <span class="label danger">Visual Studio Installer</span> ,点击右边的修改按钮<br />
<img data-src="https://s2.loli.net/2023/03/23/bAaHIQ4iLP2J9v3.png" alt="" /><br />
<span class="label danger">使用 C++ 的桌面开发</span> 和 <span class="label danger">Visual Studio 扩展开发</span> 和 <span class="label danger">单个组件</span> 中有关 <span class="label danger">Cmake</span> 的都要选中<br />
<img data-src="https://s2.loli.net/2023/03/23/fXbhAncQ1DxwGlm.png" alt="" /><br />
也有人说要有 <span class="label danger">VS17COMNTOOLS VisualStudio 安装路径 \2022\Community\Common7\Tools</span> 环境变量,但是这里我没有这个环境变量也可以正常编译,看个人情况吧<br />
重新执行<span class="blue"> cmake .</span></p>
<figure class="highlight powershell"><figcaption data-lang="PowerShell"><span>命令提示符</span></figcaption><table><tr><td data-num="1"></td><td data-command="D:\Koi>"></td><td><pre>cmake <span class="token punctuation">.</span></pre></td></tr><tr><td data-num="2"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Building <span class="token keyword">for</span>: Visual Studio 17 2022</pre></td></tr><tr><td data-num="3"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Selecting Windows SDK version 10<span class="token punctuation">.</span>0<span class="token punctuation">.</span>22000<span class="token punctuation">.</span>0 to target Windows 10<span class="token punctuation">.</span>0<span class="token punctuation">.</span>19045<span class="token punctuation">.</span></pre></td></tr><tr><td data-num="4"></td><td data-command=""></td><td><pre><span class="token operator">--</span> The C compiler identification is MSVC 19<span class="token punctuation">.</span>35<span class="token punctuation">.</span>32216<span class="token punctuation">.</span>1</pre></td></tr><tr><td data-num="5"></td><td data-command=""></td><td><pre><span class="token operator">--</span> The CXX compiler identification is MSVC 19<span class="token punctuation">.</span>35<span class="token punctuation">.</span>32216<span class="token punctuation">.</span>1</pre></td></tr><tr><td data-num="6"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Detecting C compiler ABI info</pre></td></tr><tr><td data-num="7"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Detecting C compiler ABI info <span class="token operator">-</span> done</pre></td></tr><tr><td data-num="8"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Check <span class="token keyword">for</span> working C compiler: D:<span class="token operator">/</span>Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14<span class="token punctuation">.</span>35<span class="token punctuation">.</span>32215/bin/Hostx64/x64/cl<span class="token punctuation">.</span>exe <span class="token operator">-</span> skipped</pre></td></tr><tr><td data-num="9"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Detecting C compile features</pre></td></tr><tr><td data-num="10"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Detecting C compile features <span class="token operator">-</span> done</pre></td></tr><tr><td data-num="11"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Detecting CXX compiler ABI info</pre></td></tr><tr><td data-num="12"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Detecting CXX compiler ABI info <span class="token operator">-</span> done</pre></td></tr><tr><td data-num="13"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Check <span class="token keyword">for</span> working CXX compiler: D:<span class="token operator">/</span>Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14<span class="token punctuation">.</span>35<span class="token punctuation">.</span>32215/bin/Hostx64/x64/cl<span class="token punctuation">.</span>exe <span class="token operator">-</span> skipped</pre></td></tr><tr><td data-num="14"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Detecting CXX compile features</pre></td></tr><tr><td data-num="15"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Detecting CXX compile features <span class="token operator">-</span> done</pre></td></tr><tr><td data-num="16"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Found PythonInterp: C:<span class="token operator">/</span>Users/Koi/AppData/Local/Programs/Python/Python310/python<span class="token punctuation">.</span>exe <span class="token punctuation">(</span>found version <span class="token string">"3.10.7"</span><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="17"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Configuring done <span class="token punctuation">(</span>3<span class="token punctuation">.</span>6s<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="18"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Generating done <span class="token punctuation">(</span>0<span class="token punctuation">.</span>1s<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="19"></td><td data-command=""></td><td><pre><span class="token operator">--</span> Build files have been written to: D:<span class="token operator">/</span>Koi/pycdc</pre></td></tr><tr><td data-num="20"></td><td data-command="D:\Koi>"></td><td><pre>MSBuild pycdc<span class="token punctuation">.</span>sln</pre></td></tr><tr><td data-num="21"></td><td data-command=""></td><td><pre>MSBuild version 17<span class="token punctuation">.</span>5<span class="token punctuation">.</span>1+f6fdcf537 <span class="token keyword">for</span> <span class="token punctuation">.</span>NET Framework</pre></td></tr><tr><td data-num="22"></td><td data-command=""></td><td><pre>在此解决方案中一次生成一个项目。若要启用并行生成,请添加“<span class="token operator">-</span>m”开关。</pre></td></tr><tr><td data-num="23"></td><td data-command=""></td><td><pre></pre></td></tr><tr><td data-num="24"></td><td data-command=""></td><td><pre>略</pre></td></tr><tr><td data-num="25"></td><td data-command=""></td><td><pre></pre></td></tr><tr><td data-num="26"></td><td data-command=""></td><td><pre>已完成生成项目“D:\Koi\pycdc\ALL_BUILD<span class="token punctuation">.</span>vcxproj”<span class="token punctuation">(</span>默认目标<span class="token punctuation">)</span>的操作。</pre></td></tr><tr><td data-num="27"></td><td data-command=""></td><td><pre></pre></td></tr><tr><td data-num="28"></td><td data-command=""></td><td><pre>已完成生成项目“D:\Koi\pycdc\ALL_BUILD<span class="token punctuation">.</span>vcxproj<span class="token punctuation">.</span>metaproj”<span class="token punctuation">(</span>默认目标<span class="token punctuation">)</span>的操作。</pre></td></tr><tr><td data-num="29"></td><td data-command=""></td><td><pre></pre></td></tr><tr><td data-num="30"></td><td data-command=""></td><td><pre>已完成生成项目“D:\Koi\pycdc\pycdc<span class="token punctuation">.</span>sln”<span class="token punctuation">(</span>默认目标<span class="token punctuation">)</span>的操作。</pre></td></tr><tr><td data-num="31"></td><td data-command=""></td><td><pre></pre></td></tr><tr><td data-num="32"></td><td data-command=""></td><td><pre></pre></td></tr><tr><td data-num="33"></td><td data-command=""></td><td><pre>已成功生成。</pre></td></tr><tr><td data-num="34"></td><td data-command=""></td><td><pre> 0 个警告</pre></td></tr><tr><td data-num="35"></td><td data-command=""></td><td><pre> 0 个错误</pre></td></tr><tr><td data-num="36"></td><td data-command=""></td><td><pre></pre></td></tr><tr><td data-num="37"></td><td data-command=""></td><td><pre>已用时间 00:00:09<span class="token punctuation">.</span>86</pre></td></tr></table></figure><p>编译成功无报错</p>
</content>
<category term="计算机程序设计" scheme="https://iskoi.github.io/categories/Programming/" />
<category term="编译" scheme="https://iskoi.github.io/tags/%E7%BC%96%E8%AF%91/" />
<category term="工具" scheme="https://iskoi.github.io/tags/%E5%B7%A5%E5%85%B7/" />
<updated>2023-03-10T12:00:00.000Z</updated>
</entry>
<entry>
<id>https://iskoi.github.io/Programming/datastructureAlgorithms/datastructure3/</id>
<title>数据结构【逻辑结构篇】</title>
<link rel="alternate" href="https://iskoi.github.io/Programming/datastructureAlgorithms/datastructure3/"/>
<content type="html"><h1 id="栈"><a class="anchor" href="#栈">#</a> 栈</h1>
<p>栈是线性数据结构,元素在其中只能先进后出,就像一端封闭一端开放的圆筒形容器<br />
最早进入的元素叫做栈底 <code>bottom</code> ,最后的元素叫做栈顶 <code>top</code> <br />
只有栈顶才能入栈 <code>push</code> 、出栈 <code>pop</code></p>
<h2 id="总结"><a class="anchor" href="#总结">#</a> 总结</h2>
<p>栈的输出顺序与输入顺序相反,适合用于回溯,例如递归操作返回上一级递归、面包屑导航<br />
<img data-src="breadcrumb.png" alt="breadcrumb" title="面包屑导航" /></p>
<h1 id="队列"><a class="anchor" href="#队列">#</a> 队列</h1>
<p>队列也是线性数据结构,元素在其中只能先入先出,就像现实中的隧道<br />
队列的出口端叫做队头 <code>front</code> ,入口端叫队尾 <code>rear</code> ,队尾指针指向的位置必须空出一位<br />
元素只能在队尾入队 <code>enqueue</code> 、队头出队 <code>dequeue</code> 时间复杂度 O (1)</p>
<h2 id="循环队列"><a class="anchor" href="#循环队列">#</a> 循环队列</h2>
<p>当队列使用数组实现时,不断进行入、出队操作,就会面临空间不足的情况,循环队列可以解决这个问题,并且不用扩容数组<br />
只需将队尾放到数组的首位,重新利用先前出队的空间<br />
当<span class="pink"> (队尾下标 + 1) % 数组长度 = 队头下标</span>时,说明队列已满<br />
<img data-src="circularqueue.gif" alt="circularqueue" title="循环队列" /></p>
<h2 id="双端队列"><a class="anchor" href="#双端队列">#</a> 双端队列</h2>
<h2 id="优先队列"><a class="anchor" href="#优先队列">#</a> 优先队列</h2>
<h2 id="总结-2"><a class="anchor" href="#总结-2">#</a> 总结</h2>
<p>队列的输出顺序和输入顺序相同,经常用于现实中的排队系统</p>
<h1 id="散列表哈希表"><a class="anchor" href="#散列表哈希表">#</a> 散列表 (哈希表)</h1>
<p>散列表是 hash 结构,由 <code>Key</code> 和 <code>Valve</code> 组成,通过对 <code>Key</code> 进行 hash 计算出 <code>Value</code> 在数组中的下标位置<br />
<span class="pink"> index = HashCode (Key) % Array.length</span></p>
<h2 id="哈希冲突"><a class="anchor" href="#哈希冲突">#</a> 哈希冲突</h2>
<p>由于数组的长度是有限的,就会有 hash 冲突的情况,主要有两种方法解决这种问题</p>
<ul>
<li>开放寻址法:当写入的位置已经有元素时,往后寻找空位写入</li>
<li>链表法:每一个元素都是一个链表的头节点,只需要用 next 指针指向要被写入的冲突的元素即可(HashMap 应用了此方法)</li>
</ul>
<h2 id="扩容"><a class="anchor" href="#扩容">#</a> 扩容</h2>
<p>既然使用数组实现,那么就会涉及到扩容问题,虽然链表法可以一直往下延伸,但这会大大影响效率,在 HashMap 中判断需要扩容的条件是<span class="pink"> HashMap.Size &gt;= Capacity*LoadFactor</span>, <code>Capacity</code> 指 HashMap 当前长度, <code>LoadFactor</code> 指 HashMap 的负载因子,默认为 0.75f<br />
和数组扩容一样,先创建原数组两倍的新数组,不过要重新进行 hash 计算,因为数组长度发生了变化,先前计算得出的下标已经不再适用于新数组</p>
<h1 id="树"><a class="anchor" href="#树">#</a> 树</h1>
<p>树 <code>tree</code> 是 n (n&gt;=0) 个节点的有限集。当 n=0 时,称为空树<br />
非空树有以下特点:</p>
<ul>
<li>有且仅有一个称为根的节点 <code>root</code></li>
<li>当 n&gt;1 时,其余节点可分为 m (m&gt;0) 个互不相交的有限集,每一个集合本身又是一个树,并称为根的子树</li>
</ul>
<p>没有孩子的节点是树的末端,称做叶子节点 <code>leaf</code> <br />
一个节点的上一级节点,是这个节点的父节点 <code>parent</code> ,从这个节点衍生出来的节点,是这个节点的孩子节点 <code>child</code> ,和这个节点同级,同一个父节点衍生出来的节点是这个节点的兄弟节点 <code>sibling</code> <br />
树的最大层级数,称为树的高度和深度</p>
<h2 id="二叉树"><a class="anchor" href="#二叉树">#</a> 二叉树</h2>
<p>二叉树中的每一个节点最多能有两个孩子节点,也可以只有一个,或者没有。一个叫做左孩子 <code>leftChild</code> ,一个叫做右孩子 <code>rightChild</code> ,它们的顺序是固定和,如同名字一样</p>
<ul>
<li>满二叉树:一个二叉树的每一个非叶子节点都有两个孩子节点,并且所有叶子节点都在同一层级</li>
<li>完全二叉树:完全二叉树的所有节点和同样高度的满二叉树的节点位置相同,仅要求最后一个节点之前的节点满分支即可</li>
</ul>
</content>
<category term="计算机程序设计" scheme="https://iskoi.github.io/categories/Programming/" />
<category term="数据结构与算法" scheme="https://iskoi.github.io/categories/Programming/datastructureAlgorithms/" />
<category term="数据结构" scheme="https://iskoi.github.io/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/" />
<updated>2023-02-19T13:37:00.000Z</updated>
</entry>
<entry>
<id>https://iskoi.github.io/Programming/datastructureAlgorithms/datastructure2/</id>
<title>数据结构【物理结构篇】</title>
<link rel="alternate" href="https://iskoi.github.io/Programming/datastructureAlgorithms/datastructure2/"/>
<content type="html"><h1 id="数组"><a class="anchor" href="#数组">#</a> 数组</h1>
<p>数组在内存中是按顺序存储的,数组内每个元素都有一个单独的下标,在查找元素时只需要给出对应的下标即可,下标就是一个数字,从第一个元素为 0 逐次增加,这叫随机读取,读取的时间复杂度只有 O (1)<br />
数组的长度在创建数组的时候就固定了,所以当长度不够时就只能再创建一个更长的数组再将元素一个个复制过去(Java 是这样的,在 JavaScript 中是动态的可随意增减)扩容的时间复杂度是 O (n)<br />
由于每个元素是固定下标,所以在数组中作中间插入的操作是繁琐的,需要把要插入的位置的元素包括在这之后的元素一个个往后移,中间删除操作往前移,时间复杂度都是 O (n)<br />
如果没有顺序要求,中间删除操作可以将最后一个元素复制到要删除元素的位置,然后删除最后一个元素,这样时间复杂度只有 O (2)</p>
<h2 id="总结"><a class="anchor" href="#总结">#</a> 总结</h2>
<p>数组的随机读取能力强但插入、删除能力会导致大量元素移动,因此数组适合在读操作多,写操作少的情况使用</p>
<h1 id="链表"><a class="anchor" href="#链表">#</a> 链表</h1>
<h2 id="单向链表"><a class="anchor" href="#单向链表">#</a> 单向链表</h2>
<p>每一个节点由 <code>data</code> 、 <code>next</code> 组成, <code>data</code> 为存储的数据, <code>next</code> 指向下一个节点,头节点为 <code>head</code> ,尾部节点为 <code>last</code> 且 <code>next</code> 指向 null,因此只能做向下读取的操作<br />
链表是随机存储的 (所以需要指针),在做查找的操作时只能一个一个节点往下找,时间复杂度为 O (n),但它的长度是动态的<br />
头部插入:将新节点的 <code>next</code> 指向第一个节点,然后更新 head 为新节点<br />
中间插入:将新节点的 <code>next</code> 指向下一个节点,将上一个节点的 <code>next</code> 指向新节点<br />
头部删除:将 <code>head</code> 更新为第二个节点(Java 特性会删除未被使用的数据)<br />
中间删除:将上一个节点的 <code>next</code> 指向下一个节点<br />
尾部删除:将倒数第二个节点的 <code>next</code> 指向 null</p>
<h2 id="双向链表"><a class="anchor" href="#双向链表">#</a> 双向链表</h2>
<p>和单向链表唯有一点不同,一个节点多包含了 prev,用于指向上一个节点</p>
<h2 id="总结-2"><a class="anchor" href="#总结-2">#</a> 总结</h2>
<p>如果忽略查找的过程,链表在插入、删除方面上更为灵活,链表适合用于在尾部频繁插入、删除的情况下</p>
</content>
<category term="计算机程序设计" scheme="https://iskoi.github.io/categories/Programming/" />
<category term="数据结构与算法" scheme="https://iskoi.github.io/categories/Programming/datastructureAlgorithms/" />
<category term="数据结构" scheme="https://iskoi.github.io/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/" />
<updated>2023-02-18T13:45:00.000Z</updated>
</entry>
<entry>
<id>https://iskoi.github.io/Programming/datastructureAlgorithms/datastructure1/</id>
<title>数据结构【介绍篇】</title>
<link rel="alternate" href="https://iskoi.github.io/Programming/datastructureAlgorithms/datastructure1/"/>
<content type="html"><h1 id="物理结构"><a class="anchor" href="#物理结构">#</a> 物理结构</h1>
<p>存储在内存中的就是物理结构</p>
<h2 id="顺序存储结构"><a class="anchor" href="#顺序存储结构">#</a> 顺序存储结构</h2>
<p>顺序结构是将连续的数据依次存储在连续的内存中</p>
<h2 id="链式存储结构"><a class="anchor" href="#链式存储结构">#</a> 链式存储结构</h2>
<p>链式结构是将数据存储在任意的内存中,可以是连续的,也可以是不连续的,每个元素都有指针域和数据域</p>
<h2 id="索引存储结构"><a class="anchor" href="#索引存储结构">#</a> 索引存储结构</h2>
<p>与链式结构不同的是索引结构没有指针,但创建了索引表存储数据在内存中的地址,对内存消耗大,但查找速度快</p>
<h3 id="索引顺序结构"><a class="anchor" href="#索引顺序结构">#</a> 索引顺序结构</h3>
<p>每个数据在内存中是连续的</p>
<h2 id="散列结构hash结构"><a class="anchor" href="#散列结构hash结构">#</a> 散列结构(hash 结构)</h2>
<p>通过计算决定数据在内存中的位置</p>
<h1 id="逻辑结构"><a class="anchor" href="#逻辑结构">#</a> 逻辑结构</h1>
<p>逻辑结构就是数据之间的关系,一个逻辑结构可以用两种以上的物理结构实现</p>
<h2 id="线性结构"><a class="anchor" href="#线性结构">#</a> 线性结构</h2>
<p>有唯一的首、尾元素,除了首、尾元素,其他元素都是首尾相接的,是一对一的关系,容易遍历,比如栈、队列、双队列、循环队列、一维数组等</p>
<h2 id="非线性结构"><a class="anchor" href="#非线性结构">#</a> 非线性结构</h2>
<p>非线性结构是一对多或者多对一的关系,需要多次运行才能完全遍历,比如二维数组、多维数组、广义表、树、二叉树等</p>
<h2 id="集合"><a class="anchor" href="#集合">#</a> 集合</h2>
<p>各个数据之间没有任何关系</p>
<h1 id="总结"><a class="anchor" href="#总结">#</a> 总结</h1>
<p>逻辑结构是面向问题的,物理结构是面向计算机的,其目的是将数据及其逻辑关系存储在内存中</p>
</content>
<category term="计算机程序设计" scheme="https://iskoi.github.io/categories/Programming/" />
<category term="数据结构与算法" scheme="https://iskoi.github.io/categories/Programming/datastructureAlgorithms/" />
<category term="数据结构" scheme="https://iskoi.github.io/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/" />
<updated>2023-02-18T12:35:00.000Z</updated>
</entry>
</feed>