2006-11-26

Virus Infecting Portable Executable File (4)

【实践篇】
1. 添加自己的代码
用反汇编工具查看程序的汇编代码,在代码后面加入自己的代码。我所使用的程序就是一个显示对话框的程序,而我添加的代码也是显示一个对话框,而把原对话框的标题和正文交换。

原程序:
00401000   68 40100000      PUSH 1040
00401005   68 00304000      PUSH aaa.00403000             ; ASCII "Hello World"
0040100A   68 14304000      PUSH aaa.00403014
0040100F   6A 00            PUSH 0
00401011   E8 14000000      CALL <JMP.&user32.MessageBoxA>
00401016   6A 00            PUSH 0
00401018   E8 01000000      CALL <JMP.&kernel32.ExitProcess>
0040101D   CC               INT3
0040101E  -FF25 00204000    JMP DWORD PTR DS:[<&kernel32.ExitProcess>; kernel32.ExitProcess
00401024  -FF25 0C204000    JMP DWORD PTR DS:[<&user32.wsprintfA>]   ; user32.wsprintfA
0040102A  -FF25 08204000    JMP DWORD PTR DS:[<&user32.MessageBoxA>] ; user32.MessageBoxA


加入的代码
00401030 > $ 68 40100000    PUSH 1040                     ; /Style = MB_OK|MB_ICONASTERISK|MB_SYSTEMMODAL
00401035   . 68 14304000    PUSH aaa.00403014             ; |Title = "Hello Kitty"
0040103A   . 68 00304000    PUSH aaa.00403000             ; |Text = "Hello World"
0040103F   . 6A 00          PUSH 0                        ; |hOwner = NULL
00401041   . E8 E4FFFFFF    CALL <JMP.&user32.MessageBoxA>; \MessageBoxA


而注意在最后跳转到原程序入口:
00401046   .^EB B8          JMP SHORT aaa.00401000

记录下新的入口地址,即我们新添加代码的首地址;以及所有代码的总长度,以备后用。

2. 更改程序入口
用Stud PE打开程序,用Basic HEADERS tree view in hex editor查看头部信息。找到Optional Header结构里面的AddressOfEntryPoint和BaseOfCode,两个字段均为00 10 00 00,将其改为30 10 00 00,因为我们新加入的代码在地址00401030上。需要注意的是,这里的存储方式是小数端(?记不清了,应该这叫做小数端),所以数字的排列方式和阅读方式是相反的。这样,程序的入口以及代码基地址都已经改成我们新加入的代码的起始地址。

3. 更改代码段长度
用Stud PE打开程序,在Section标签下,找到.text段,这一般就是代码段了。双击.text行,将Virtual Size改为00000048,因为我们加入的代码和原代码总长度有0x48个byte。

4. 总结一下
用UltraEdit打开原程序和改过的程序,使用File->Compare Files比较两者差别,注意选择Binary方式比较。可以看到一共有4片被改动。
  • 入口地址
  • 代码基地址
  • 代码段长度
  • 原代码后一串0改为我们自己的代码

好了,双击我们的程序,就会看到效果了。

5. 下一步打算
写到这里,我们这个教程也差不多了。我们用全手工的方式分析了一个简单的EXE,并在不增长EXE的前提下加入了一段自己的代码,并让它率先执行,随后执行原代码。这也许是病毒感染可执行文件的一种方式。

下一步也许是写一个能够自动分析的程序,全自动地去感染文件。然后也许是尝试将自己复制给被感染的文件,加入潜伏性和破坏性的代码,也许就可以做出一个病毒的雏形了。

笔者才疏学浅,急功近利地做到这个程度,写下这些毫无技术含量的文字,仅仅希望能够帮助对病毒有兴趣的同学入门。如果有业余时间,我也想继续钻研下去,和大家共同进步。

2006-11-25

Virus Infecting Portable Executable File (3)

【原理篇】
病毒要感染EXE文件,也就是把自身插入EXE中,并在执行原先程序指令之前执行自身。这个教程并不能完成一个完整的病毒程序,而只是将自己的一段指令插入在EXE文件中,并优先于原先程序执行。

此篇讲解完成上述目标的原理,所需要的知识是"基础篇"中的一个子集。

由于PE文件会对Section进行对齐,因此一般会在程序段后面留下一些空白空间。这些空间可以用来插入我们自己的代码,也可以是病毒滋生的空间,这样,被"感染"的文件的大小不会改变,大部分结构也没有变化,直接跳转到适当位置覆盖写入即可进行感染。

在空白处插入你的代码并不会执行,更不可能在原程序之前执行。其原因有2:
1. 程序入口仍然是原入口,执行的流程依然是首先执行原程序
2. 每个Section都会有有效长度,超出部分Image Loader会直接忽略掉

因此我们加入的代码和填充的"0"没有什么区别。

为了达到抢先执行我们自己的代码的目的,我们需要:
1. 更改程序入口地址
2. 更改代码段的Section Length字段
3. 为了执行我们自己代码以后还能够回头去执行原程序,我们还需要在代码后面加上跳转指令,跳转到原先的程序入口

基于上述原理,在下篇中我们具体讲解实际的操作过程。

2006-11-24

Virus Infecting Portable Executable File (2)

【工具篇】
工欲善其事,必先利其器。我们先不着急动手,先看看有什么好工具,一方面帮助我们对知识有更好的认识,另一方面为我们动手实践铺平道路。

1.PE文件查看和编辑工具
我使用的是Stud PE,可以在看雪工具下载中找到更多相关工具。Stud PE列出了所有PE文件头字段和各个Section的描述字段,可以直接修改,十分方便。

2.反汇编工具
C32Asm是一个做的挺漂亮的反汇编工具。它的最大特点就是可以查看反汇编代码对应的十六进制数据。
另一个是OllyICE,功能强大,不仅能够查看PE的一些字段、反汇编、改十六进制数据,更可以直接写汇编语句,生成相应的Binary,十分方便修改代码。

3.汇编工具(可选)
用其他的exe太复杂了,自己写一个简单的做研究吧。用masm汇编一段简短的代码是很好的主意。我用masm汇编了一段:

.386
.model flat, stdcall

include \masm32\INCLUDE\windows.inc
include \masm32\INCLUDE\user32.inc
include \masm32\INCLUDE\kernel32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.data
msgtitle db "Hello World",0
msgtext db "Hello Kitty",0

.code
start:
invoke MessageBox, NULL, addr msgtext, addr msgtitle, MB_OK
invoke ExitProcess, 0
invoke MessageBox, NULL, addr msgtext, addr msgtitle, MB_OK
end start

Endless Rain & Endless Work

高强度地写程序;下周开始去Intel上班了;还要准备考试;赶很多门课的作业……

天气预报说,这样的雨还要下10天;我说,这样的生活还要持续至少1周。

暂且在歌声中忘记烦恼吧。Endless Rain,玩vos的时候弹到的曲子,值得一听。

codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715"
align="baseline" border="0" standby="Loading Microsoft Windows Media Player components..."
type="application/x-oleobject">




















type="application/x-mplayer2"
pluginspage="http://www.microsoft.com/isapi/redir.dll?prd=windows&sbp=mediaplayer&ar=media&sba=plugin&"
name="MediaPlayer" showcontrols="1" showpositioncontrols="0"
showaudiocontrols="1" showtracker="1" showdisplay="0"
showstatusbar="1"
autosize="0"
showgotobar="0" showcaptioning="0" autostart="0" autorewind="0"
animationatstart="0" transparentatstart="0" allowscan="1"
enablecontextmenu="1" clicktoplay="0"
defaultframe="datawindow" invokeurls="0">

2006-11-16

The 22th Anniversary of My Birthday

早上很晚才起来,外面已经开始下雨了,天空很阴沉,气温很低,不知道这是不是一个不好的预兆……

起床把公司寄来的一叠协议拿出来,开始签字。当我写到今天的日期的时候,突然间想落笔写下1984年11月16日——11月16日这个日子,似乎永远和1984年捆绑在了一起,每年今日,我都会想到那年:当妈妈看到一个完全陌生的小生命的时候,喜悦中夹杂着痛苦和忏悔,我相信那天她跟我讲述的她的过去都是真实的。而今年今日,那阴沉的天气,似乎是上帝正在忏悔他所犯下的错误——22年前,他无情地将罪孽施加在一个如此纯洁善良的小生命身上。所庆幸的是,他蹒跚地走到了现在。

将所有协议签好,送到邮局寄掉了。回到寝室的路上路过了“思春湖”。雨点洒落在湖面上,形成了一块巨大的毛玻璃,朦胧地映出了远处的景物,虽然有时会隐约显得清晰明朗,但定睛时又开始模糊了。也许这预示着我对于未来的憧憬,或者是我不知所措的爱情吧。

在此时,我做了一个小小的决定,放弃手头的一个兼职机会,安心去实习。我始终相信我是热爱自由的,不会因为生活的压力放弃我的自由。过去种种对自己错误的认识导致牺牲了很多,如今不能再重蹈覆辙了。

最后,需要感谢在这天给我祝福的朋友们,如果没有你们,我会感到多么痛苦和孤独。

2006-11-10

Virus Infecting Portable Executable File (1)

一周时间,从零开始学习病毒感染Windows应用程序的原理。在这里连载我的学习笔记。

【基础篇】
虽然这方面我也只是为了应付计算机病毒的课程论文,但我还是想说,希望看这篇文章的朋友能够踏踏实实的学好基础知识。这篇文章只是一个入门,后面的路还很长很长,只有扎实的基础才能帮助你走得更远,最终写出真正的计算机病毒。

首先,你需要看一下汇编语言,并理解汇编语言和机器语言的联系。我看的教材很肤浅,是饮水思源BBS Crack板精华区,关于汇编语言的一些教程。这些教程写得很粗略,不需要都看,也不要只看这些。看一本汇编语言的书会有很大的帮助。

完成本教程的所有步骤,仅仅需要看懂一些汇编语句即可。写一个汇编程序,用反汇编工具打开汇编输出的执行文件看看,到底生成的是什么语句就可以了。但还是那句话,要踏踏实实地学习才是王道。

另外一方面的基础知识是PE文件的格式。这里的PE不是体育,也不是光盘上的Windows……是Windows可执行文件的格式:Portable Executable。

这方面看这篇文章大概就足够了。我还没有完全看完,也没有完全参透所看的部分,所以不多加评论了。

以上两点就是所需要的基础知识,说简单也很简单,我从零开始学习不到一周,也足够做一些小东西了。但我知道,要深入下去,吃透上面的知识是必要条件。

2006-11-09

在线写诗网站和我的创意

在别人的Blog上看到一个有趣的网站:在线写诗网站(http://www.dopoem.com/),试了一下……晕,不就是printf嘛,太没有技术含量了。

还是偶的创意比较好。还记得前不久Joke板上一度流行的“梨花体”吗?如果能够把一句很普通的句子自动转换成“梨花体”,那就好玩了。

其实实现上也不困难。简单的,分词器分一下,根据词性组合一下,就成了。复杂一点,也许需要用到NLP之类的东西……

不过,再想一下,“梨花体”已经很无聊了,再搞个自动梨花体,真是无聊到极致了。我真是没什么好想的了,就想着这些事情,太无聊了……

2006-11-08

医不自医

今天体会到这句古话是什么意思了。

在为别人解决问题的时候,我能够很冷静地思考,周全地分析,并有条理地表达,帮助别人做出正确的选择。然而,当我遇到类似的问题的时候,我却失去了平时的理性。

在我看来,别人遇到的问题都比我的简单,似乎我在别人同样的位置根本不会犹豫……但我应该考虑到,别人也是有同样的想法的,对于当事人来说,心情是极其复杂的。任何理性的思考,在杂如乱麻的心情的干扰中,都会被扭曲。

也许过去我并没有意识到,我对自己的所谓理性思考都已经被扭曲了,也许我之前所做的判断和决定都是错误的……可是现在,大部分判断都是建立在猜测和假设下,我想,我现在应该放弃“自医”,而只是等待——等待能够帮助我做出正确判断的“医者”出现。

2006-11-05

又是一年光棍节

很难定义自己现在是什么状态……还是不过节了

Intel实习面经和关于找实习的一些思考

Part 0:对Intel的总体印象
---------------------------
Intel总是无视人!这是我很早以来对Intel的看法,自以为在交大旁边,有得天独厚的地理优势,就那样挥霍人才。

我曾经无数次地点击Parttime上Intel招实习生的邮件地址,每封cover letter和resume都认真准备,以突出我符合他们对实习生的要求,结果都石沉大海……

因为最近消费水平提高了,而眼看暑假实习的积蓄也要渐渐耗尽。于是,找同学推荐,得到了一次面试的机会。

Part 1:第一次的三轮面试
--------------------------
面试被安排在周三下午。有三个面试官和三个应聘者,一轮车轮大战,每个应聘者都面了三轮。

每个面试官问的内容都差不多,大致就是看你会不会写程序,思维和反应是不是快,对测试有没有什么基本概念,对工作中需要用到的知识有没有理解。

题目有写程序的,比较简单,基本不需要动脑筋,第一感觉基本就是最优解。只要安心把它实现即可。我的建议是,边写可以边和面试官说说你的思路,边写边思考,说不来更有条理。同时,如果有错误,面试官也会及时发现,避免冷场几分钟后写出来的反而是错误的尴尬。

也有说思路的。Intel和Google的风格不太一样。Google的思维就是,空间是无限大的,但时间需要最少。而Intel也许不要时间上太好,而需要空间上省一些。所以我说的思路大多和面试官期待的有些不同。但题目一般还是比较和蔼,基本上听到题目,稍微想想就会有一个答案,而且时间复杂度要求不高,所以,面试官也不会对答案的深度挖掘。在做这类题目的时候,我的建议是,想到什么说什么,不管对错完整与否。说明你的思
维过程,并根据面试官的反应做适当调整思路。

还有就是问你原理什么的。问你client/server如何通过socket通讯,通讯过程是什么……问问你除了tcp/udp这些协议以外的协议的了解,基本上能说出一些名字,再找一个说说大概原理即可。

最讨厌的就是有些小技巧的程序题和智力题,拼rp吧,想到你就得到了,没想到也不必沮丧。

整个面试过程大约2个小时,要在整个过程中保持清醒的头脑,也不要被前面面试的结果影响到后面几轮的面试,如果你最终走出Intel大门的时候充满自信,那么不要你应该是Intel后悔。

Part 2:第二次面试,面老外Manager
-----------------------------------
不懂为什么Google都是中国人,但其他公司都是老外来做Manager……

第一次面试当天晚上就收到电话,要我周五去见Manager。见老外一向是我最头痛的事情,而且向在Intel有过面试经历的同学打听了一下,问题多不是技术的,问你记忆深刻的一次演讲什么的……这些叫我用中文说都说不清楚。只能怀着忐忑的心情再次到了Intel。

我被带到会议室,这次的待遇好多了。老外和两个先前面我的人都在,心理稍微放心一些。寒暄过后,面试开始。

出乎意料的是,老外并没有问那些bt的套路题,而是针对我的实习,问我关于HAC算法,让我描述一下。我用不熟练的英语,避开Google保密的范围讲了一下这个算法的大概过程。谈技术问题还是令人接受的,我原来的计划也是将非技术问题向技术方向引导。我觉得应聘技术职位且和我一样英语不好的同学,可以专门练习一下谈论技术问题,并且在面试中尽量把话题引导向你所擅长的范围,这也许是一个好方法。

Part 3:我对找实习的看法
--------------------------
什么情况下应该去找实习或者兼职呢?应该找什么样的实习呢?

首先应该确定你要找实习的目的。为了学习技术?为了挣钱?为了体验公司的文化?……这影响到你应该找什么样的公司。

你要学习技术,应该找一些你不是完全了解的领域。如果你对这个领域十分熟悉,那么在实习期间,只是出卖你的劳动力,反复接触你自己已经知道的东西;而如果你对这个领域完全没有概念,那么你的面试也是很难通过的。找学习目的的实习,应该有针对性,选择面不宜太广,差不多就是你希望学习领域中TOP的几个公司,和一个小公司用于保底。也许你不需要特别渴望要去公司学习,其实在课余时间也是可以自学的。

像我一样为了挣钱,那么就选择一些工资尚可且可以保证上班时间的公司。在交大,去紫竹无疑是很好的选择,因为很近,可以每天去,而且上班成本也不高。公司选择面也可以放宽,只要有工资,在自己能力范围内能够通过面试的即可。

为了体验公司文化,也许只能作为附加的收获。如果你完全是为了体验,那么就要咬定你所欣赏的公司猛投……我想也不会有太多人完全为了这个目的吧。

什么时候去找实习比较适宜呢?

我不想说大一、或者大二、大三等,每个人应该根据自己的情况决定。我认为先应该安心学习好必要的知识,做一些小项目来巩固知识,也能在你简历中添上一笔。之后可以开始寻找相关或相近领域的实习,来体验工业界对于这些知识的应用。

但我觉得,最重要的是踏踏实实地学习。有些同学在面试之前抱佛脚,我觉得有些不可取。一方面,短时间的学习完全不能达到公司对你的要求,即使你搪塞过去了,之后你还是需要踏实地再学习;另一方面,去接触一个完全陌生的领域,这样的选择也是很冒险的。应该考虑好你的能力能否学好,你会不会喜欢做这方面的工作之后,再决定是否去投这个职位。这需要时间去考虑,我个人觉得,对大部分准备毕业工作的同学来说,大一和大二的时候应该考虑和准备这些问题了。

我自己找的实习也不多,成功的比例也不大,也许我也经历过慌乱中饥不择食的时候。但现在想起来还是觉得可笑。总结一下经验,后辈可以参考,早做准备。

2006-11-01

关于本地搜索服务的5分钟调查

今天出门,要去一个陌生的地方,于是上网吧去查查地图。

网吧是在华山路,徐家汇路口附近。通过路边一个小楼梯上到二楼,就是网吧。如果不是做过那份兼职还真难找到。

分析:早就对中国网络无语了,看到右下角的W标志,就是我亲手安装的用来监控上网情况的东西,反正我也没有什么见不得人的,随便你看吧……

  • 百度显然是脚本没有做好,没法适应网吧严格权限管理的浏览器环境,而不是网络的问题;
  • 现象1和3表明google.com域名被block,原因可能是这个网吧有人搜索敏感关键字。Google应该尝试从google.cn加载所有资源;
  • sogou的还不错,不仅可用,而且速度很快。

就这样,任务完成,顺便做这个小调查,仅供参考。