电子设计大赛总结

比赛对于我来说很早就已经结束了,前后累加将近3,4个月的训练,我确实收获了不少,相关的体会我已经在阶段性的报告中进行了陈述,这里仅对比赛前后的点点滴滴进行一下小结,算是对我难得的一次经历的历史性回顾吧。

9月2日,正式的比赛拉开了帷幕。清晨我们学校的各个队伍就集结在了会议室,才7:20而已,平日这个时间还在梦乡中徘徊呢。相关的领导进进出出,直到巡视员的姗姗到来,我们正式进入了比赛场地。题目已经发布在网站上了,电源,宽带运放,无线通信…这些我们训练提及过的内容似乎都如约而至,只不过题目乍看起来还有一些欺骗性,”它们都是伪装成几何问题的函数问题”(《嫌疑犯X献身》)。比赛前我们小组一直在研究的数字滤波内容,目标自然就锁定在与之相关的‘数字均衡’题目上了。

整个系统的结构确定还是不难的,题目上也给出了相当的约束条件。我的初期任务主要是研究后级的功率放大模块,也就是从FPGA输出的信号将之功率放大。题目上要求效率较高,这首先使我们想到的就是采用D类功放,比赛开始前,我们就已经投入了经历在其中,因此选择它更是理所当然(想当然的结果就是Surprise!)。由于IR2105类驱动芯片一直尝试不通,而我本人也一直怀疑这个芯片使用的必要性(主要是对D类功放两个MOS管的控制原理理解不透)。好在时间看起来还是比较充分的。运放的搭建,带阻网络的搭建都有现成的电路,一个小时就能搞定,做FPGA滤波环节的人其实训练中期就曾经设计了思路比较新颖效果也还不错的多带通FIR滤波系统。因此我就秉持的比较放松的心态开始具体研究MOS管组成D类功放的原理。最开始的尝试是用单一的MOS管组成简单的放大电路,将PWM波放大后级加上简单的RC滤波就还原出了想要的正弦波形,但对于桥式的MOS管的控制,虽然仿真出来尚且有波形,但实际结果却差强人意。

大概用了近两天的时间,我终于明白了D类功放中桥式电路的控制原理,以及驱动器的使用必要性了。原因说出来就比较清晰了,两个相连对接的MOS管要想控制保证一个导通,一个闭合这样的状态不断转换,就必须要有两个独立的控制信号分别加载在他们GS端。

举例来说,如果我有两个信号源,产生两路方波分别加载到他们的GS上,就能独立的控制他们的开关了。但实际情况是,这两路方波一定是相位差为零,仅仅是逻辑相反而以,这样的信号源就做不到了(如何能让两个信号源分同步呢)。如果采用其他手段,比如让FPGA产生这样的逻辑相反的同步PWM波去分别控制两路GS,乍看起来好像也可以。但事实,由于两路PWM一定是共地的,这就使得桥的中点,也就是上方的MOS管的S级永远是地,因此当然输出的信号都是毛毛了。

因此驱动器的作用就产生了,他能产生两路不共地的PWM波。其实其内部在低频时就相当于光耦合,或变压线圈的作用。但意识到这个问题花了不少的时间,好在另一个研究IR2105的同学已经有了突破,终于搞明白了这个芯片的外围电路参数的确定办法。接下来我们就用这个放大电路进行了烧烤实验,功率确实够大的,8欧姆的负载加上时间不长就有烤肉味产生。但好在是成功放大了功率。这会儿我又花了点时间完成了前级放大电路的搭建,要说的NE5532效果确实很棒,一个简单的负反馈,不用太多的调节,出来就是完美的正弦波。时间到了接近第三天的晚上,本来我们很早就对系统的整体完成了设计。但发现功率在15V供电的情况下很难达到预期指标,不过通过占空比的调节终于让直流功率吧总功率顶上去了,与此同时我也完成了全系统的联调入箱的操作。可惜后期突然听说输出功率不包括直流功率,我当时无论如何也不能接受这个想法,但也没办法,人疲倦的时候就是经不住新思想,而这也使我们作出导致了几乎满盘皆输的决定—将半桥电路供电改为双电源,这意味着整个电路板上共地的许多点要打开改为-15V的点。这一改动过后,我们打开了电源,残酷的事实发生了,由于改动不全面,一处短路导致IR2105烧毁,正赶上12点多的时间,要芯片却没有老师,还好前一组留了块备用的,我们当时那叫一个感激啊。调整好后,我们做了类似西方人的饭前祷告,闭上眼的几秒钟差点没睡着~~再次上电终于将有了点波形,虽然没有了直流分量,全部是交流功率,但事实是交流功率小的可怜。还好我们都比较冷静,要不然恐怕就要跳楼了。原因恐怕很难找到,很可能是刚刚对于电路板的改动使得电路中各节点的焊接可能效果不理想等等,实在是不愿意多想了。面临的解决方案恐怕只能是改回去了,我是有点扛不住了,还好另一个还比较能扛,开始了交流返回直流的孤单征程。大概第四天早晨7点钟就完成了改造工作,输出是有了,效果比之前的差了很多,是啊,电路改来改去,效果不差才怪呢。原来好好的正弦波现在搞得跟三角波似的。

啥也别说了,时间不允许我们有更多的抱怨,赶紧装箱吧。

测试时间相比结束时又过了两天的时间,总体归纳整个测试环节,我们太缺少经验了。

这一次测试也彻底断送了我们整个比赛的延续,有客观原因,当然更要总结的还是主观原因。 测试前我们还是蛮有自信的,毕竟整个系统半调子的也算是做出来了。到了专家面开始了最后的准备,我们前面一组正好是北邮一组,做的题目和我们一样。我仔细的观察了他们的电路,以及整个测试过程。我想先说说他们的测试吧,因为印象还真是挺好的。从他们的整个系统看来,显然系统似乎比我们的复杂一些,电阻电容差不多比我们多了一倍,板子也多了几块。有一点确实很让我有感触,他们电路板之间的连线都是可插接的,输入输出线也都是可以选择性的插接的。最关键的是后级的功放用MOS管上面都有厚厚的散热片,负载电阻虽然和我们用的一样都是带有散热壳的大电流承载的电阻,但电路上,这个电阻却是悬空的,下面用两个散热片将之顶起,这样可以更大限度的降低电阻的温度。我们那个电阻工作起来起码140度啊,周边的电线皮都焦了,以上这两点细节我真是从来都没考虑过。测试时也很从容,让测哪一部分就接上哪一部分,保证效果一直良好。但他们的功放似乎仅仅采用了乙类推挽式放大,优点就是波形非常好,当然效率肯定最后没有达到指标。不过整体感觉测试的很轻松,把他们的电路都展现出来了。

轮到我们组了,这会儿我可没那么有自信了,就冲最后那个波形,我们那个和他们那个比起来,真是差很多(谁叫人家没用D类功放呢,牺牲了效率,换来了波形)。等老专家开始测试我们组,首先让我上电,让我接上它的信号源,然后他才根据那个毫伏表来调节信号源电压。就这点我就十分BS这个专家了,更BS他们的设备。信号源哪能不调好电压就接入我们的放大电路呢,电压太大烧了我的放大器怎么办呢。一个信号源连个显示输出电压的功能都没有,居然还用毫伏表测,还用个模拟的示波器,我滴神啊。当然我说的也未必全对,知识训练过程中,我一直使用数字示波器,而且信号源也使用示波器来测输出,那毫伏表在我看来无论如何都是老土的代表。

问题来了,接入我们的电路后,这老头说什么也不能把信号源调到有效值5mV,非说是我电路自激了。还好后来竞赛组组长前来解围,纠正了这个老专家,从原理上告诉了他信号源和毫伏表以及放大器输出电阻的关系,真不知道这专家究竟是学什么的。总算是解决的输入问题,接下来问题又来了,测量我的放大倍数,说不够,我就调了一下控制倍数的滑动变阻器,他又来事了,说我调电路参数。我跟他理论了半天,说我这个系统设计之初就设置了可以调节的功能,增加适应性,这老专家那叫一个不情愿啊(无知真可怕)。接下来带阻网络又来事了,说我们的改了它们给的电路参数,我解释说原图没办法达到-10db的衰减指标,我仅仅是将一个电阻改成了可调节的滑动变阻器,确保可衰减-10db。他连衰减网络频谱曲线测都没测就记了个‘滑动变阻器’,天知道他这么写的意思。接下来的均衡后的输入,我无论如何也想不到他居然吧扫频仪的输入接到了运放的输入端,那意味着400倍的放大倍数去放大扫频仪输出地100mv的电压,根本就是一个方波输出啊,哪有拿方波测量网络特性的(这点也是后来我才意识到,当时只是觉得怪怪的,我们都是直接让扫频仪接带阻输入的)。当然了,一个方波的输入和我们之前的设定的均衡系统肯定不匹配啊,均衡效果当然很糟,但还好我们的均衡采用的多带通技术是可以调节的,可是那老头又开始发牢骚了,说我们又要调电路参数,怎么跟他解释我们的数字滤波系统的优越可调适应性都不行。最后当然是滤波等于X了。

后级功放就更完,整个测试过程中,我最担心的就是这个,这老头巨磨叽,脱了老长时间,还不让断电,后级电阻都快成人造小太阳了。等到它测试功放输出,果然波形也跟人造小太阳一样四相散射。波形不好,他居然直接就说其他指标都不测了,当时我也却是理亏,谁叫咱波形不好呢,想想就只能灰溜溜的走人了。

以上的愤慨致辞如违反国家有关法律,请即刻销毁。因销毁不及时所产生的任何法律(包括宪法,加法、减法、乘法、除法、剑法、拳法、脚法、指法、民法,刑法,书法,公检法,基本法,劳动法,婚姻法,输入法,没办法,国际法,今日说法,吸星大法,与台湾关系法及文中涉及或可能涉及以及未涉及之法,各地治安管理条例)纠纷或责任本人概不负责。本人谢绝任何跨省、跨市,跨县、跨乡、跨村的追捕行为。确因不抓不足以平民愤,或不抓就领不到薪水养家户口的公职人员,建议携带工作证、身份(韩度)证、结婚证/离婚证、独生子女证、健康证、暂住证、毕业证、边防证、县以上government机关出具的介绍信温情操作。废话完了,以上声明内容部分来自网络修改而成,感谢广大网友的无私奉献精神。

客观地讲,我们的确存在准备上的不足。后级电路应该采用可插接方式连接,检查前级时,断开后级防止温度过高,同样也应该增加足够的散热装置。我们设计系统的想法看来和专家的想法有一定的偏差,谁知道出题人究竟是如何思考的呢。我们把重点放在了数字部分,要想进行数字部分的频谱可调,可不是每个组都能做到的啊,可惜我们根本没机会展示这个功能,同样未能展示的还包括了一个10带通滤波和DDS。带阻网络我们本来还很自豪居然调成了题目要求的-10db,可居然反而被专家认为不合格,他只看元件不看频谱曲线就已经奠定了这一点。最后的波形本来是可以很好的,知识改了来那个两次电路后,波形变差了,导致后级彻底废掉,这里经验就是要坚持自己的想法,哪怕有一点偏差,总比正确的却什么也没做出来好,盲目改变只能是一团糟。另外选题时一定要选人少的,而不是最熟的,因为你熟别人也熟,物以稀为贵啊。

比赛虽然没有获得很好的成绩,但对最终的结果我还是很欣然的接受了,从一开始也不是为了一个奖而参加的比赛。培训的过程中学到的东西真的是一生受用,现在随时想到一个电子系统,似乎自己马上就可以着手开始,到哪里买器件,哪里找资料,怎么制作,要注意的细节似乎都是理所当然。这期间我做过的那个万能遥控器,也真的是为生活增加了不少乐趣。当然最应该感谢的人一定是4个月来无私的培训我的老师们,没能获奖也许对他们的伤害更大哈~ 2009,我经历的不平凡的一年。

VC程序如何释放文件

很久以前写过一个在EXE的资源中释放出一个文件,然后加载运行做些事情的小程序,时间久了,忽然又有这个需求的时候,居然忘记是如何做的了,原来的程序代码早被删了,自己胡乱试验几次,结果弄出N个蓝屏出来,只好上网查了一下,但没有发现很理想的资料。只好吭哧吭哧费了九牛二虎才搞定,所以在此记录一下,以免以后忘记了。

需要:释放一个名为001.jpg文件到C盘根目录,并修改成名字002.jpg

在VC工程的的Resource View画面中,鼠标右键->add->add resource,出现添加资源画面->选”Import…”->找到001.jpg->确定,显示资源类型定义对话框,在资源类型定义中,自己定义一个不存在的类型名,这里叫TROJANHORSE,然后就把001.jpg添加进来了。这个时候,”Resource View”画面中会多出一个”TROJANHORSE”类型,下面资源名为:IDR_TROJANHORSE1,这个名字可以自由修改。

在代码中,写一个函数,(借助了网上资料,出处忘记了)

BOOL ReleaseMyFile(LPCTSTR lpszDestFilePath, LPCTSTR lpName, LPCTSTR lpType)  
{  
    HRSRC hRsrc = ::FindResource(NULL, lpName, lpType);  
    if (NULL == hRsrc)  
        return FALSE;  
  
    HGLOBAL hGlobal = ::LoadResource(NULL, hRsrc);  
    if (NULL == hGlobal)  
        return FALSE;  
  
    DWORD dwSize = ::SizeofResource(NULL, hRsrc);  
    LPVOID pBuffer = ::LockResource(hGlobal);  
  
    BOOL bRt = FALSE;  
  
    FILE* fp = _tfopen(lpszDestFilePath, _T("wb"));  
    if (fp != NULL)  
    {  
        if (dwSize == fwrite(pBuffer, sizeof(char), dwSize, fp))  
            bRt = TRUE;  
        fclose(fp);  
    }  
    return bRt;  
}

然后就可以在main中调这个函数释放资源文件了,具体代码如下:

BOOL bRt = ReleaseMyFile(TEXT("c:\002.jpg"), MAKEINTRESOURCE(IDR_TROJANHORSE1), TEXT("TROJANHORSE")); 

当然,可以把001.jpg换成exe或者sys文件,做该做的事情。

关于键盘驱动

关于键盘驱动

今天想在DOS下用C语言写一个带菜单的程序,一开始没有一点思路,主要是不知道怎样实现菜单的功能,于是上网搜索,得到启发:可以通过读取键盘的扫描码,从而实现菜单的功能。于是我开始研究怎样去获取键盘的输入信息,经过大半天的Google,现在我将关于键盘的知识记录下来。

我用的机器的平台是Intel Atom N270+945GSE+ICH-7M+EMC5035。

所谓的键盘控制器(KBC),也就是Intel 8042;它位于EC中,8042负责读取键盘扫描码并将其存在缓冲器中供程序读取;另外还有一个芯片ECE1077,它负责连接键盘和EC,将键盘动作转换成扫描码。CPU通过两个IO端口与8042通信,这两个IO端口就是0x60,0x64端口。下面介绍一下CPU怎样通过这两个IO端口与8042通信。

8042有四个8位的寄存器,它们是输入寄存器(RO)、输出寄存器(WO)、状态寄存器(RO)和命令寄存器(R/W)。

读输出寄存器:inportb(0x60);

写输入寄存器:outportb(0x60,data);

读状态寄存器:inportb(0x64);

读命令寄存器:先向0x64端口写命令0x20:outportb(0x64,0x20);再从0x60端口读数据:inportb(0x60);

写命令寄存器:先向0x64端口写命令0x60:outportb(0x64,0x60);再向0x69端口写数据:outportb(0x60,data);

状态寄存器和命令寄存器的每一位都是有特定意义的,如下:

状态寄存器:

Bit7: PARITY-EVEN(P_E): 从键盘获得的数据奇偶校验错误

Bit6: RCV-TMOUT(R_T): 接收超时,置1

Bit5: TRANS_TMOUT(T_T): 发送超时,置1

Bit4: KYBD_INH(K_I): 为1,键盘没有被禁止。为0,键盘被禁止。

Bit3: CMD_DATA(C_D): 为1,输入缓冲器中的内容为命令,为0,输入缓冲器中的内容为数据。

Bit2: SYS_FLAG(S_F): 系统标志,加电启动置0,自检通过后置1

Bit1: INPUT_BUF_FULL(I_B_F): 输入缓冲器满置1,i8042 取走后置0

Bit0: OUT_BUF_FULL(O_B_F): 输出缓冲器满置1,CPU读取后置0

命令寄存器:

Bit7: 保留,应该为0

Bit6: 将第二套扫描码翻译为第一套

Bit5: 置1,禁止鼠标

Bit4: 置1,禁止键盘

Bit3: 置1,忽略状态寄存器中的 Bit4

Bit2: 设置状态寄存器中的 Bit2

Bit1: 置1,enable 鼠标中断

Bit0: 置1,enable 键盘中断
有了以上知识,再对照键盘的ScanCode表,我们就可以编写程序读取并判断键盘输入的数据,并根据不同的按键执行不同的动作。


另外,发给8042的命令除了以上所讲的读/写命令寄存器以外,还有其他一些命令;这些命令可以分为两类:

一类是直接发给8042的命令,包括设置键盘密码,自检,开启和禁用键盘等;

还有一类是先发给8042,再通过8042间接发送给8048的命令。这里的8048类似上述的ECE1077,它将键盘动作转换成ScanCode供8042读取。这类操作命令有设置键盘LED灯,设置扫描码类型,设置键盘工作方式等。

这两类命令的详细信息如下:

① 通过写端口0x64,直接发送给8042的命令:

20h

准备读取8042芯片的Command Byte;其行为是将当前8042 Command Byte的内容放置于Output Register中,下一个从60H端口的读操作将会将其读取出来。

60h

准备写入8042芯片的Command Byte;下一个通过60h写入的字节将会被放入Command Byte。

A4h

测试一下键盘密码是否被设置;测试结果放置在Output Register,然后可以通过60h读取出来。测试结果可以有两种值:FAh=密码被设置;F1h=没有密码。

A5h

设置键盘密码。其结果被按照顺序通过60h端口一个一个被放置在Input Register中。密码的最后是一个空字节(内容为0)。

A6h

让密码生效。在发布这个命令之前,必须首先使用A5h命令设置密码。

AAh

自检。诊断结果放置在Output Register中,可以通过60h读取。55h=OK。

ADh

禁止键盘接口。Command Byte的bit-4被设置。当此命令被发布后,Keyboard将被禁止发送数据到Output Register。

AEh

打开键盘接口。Command Byte的bit-4被清除。当此命令被发布后,Keyboard将被允许发送数据到Output Register。

C0h

准备读取Input Port。Input Port的内容被放置于Output Register中,随后可以通过60h端口读取。

D0h

准备读取Output Port。结果被放在Output Register中,随后通过60h端口读取出来。

D1h

准备写Output Port。随后通过60h端口写入的字节,会被放置在Output Port中。

D2h

准备写数据到Output Register中。随后通过60h写入到Input Register的字节会被放入到Output Register中,此功能被用来模拟来自于Keyboard发送的数据。如果中断被允许,则会触发一个中断。

②通过写端口0x60,间接给8048发送命令:

EDh

设置LED。Keyboard收到此命令后,一个LED设置会话开始。Keyboard首先回复一个ACK(FAh),然后等待从60h端口写入的LED设置字节,如果等到一个,则再次回复一个ACK,然后根据此字节设置LED。然后接着等待。。。直到等到一个非LED设置字节(高位被设置),此时LED设置会话结束。

0xED命令后面跟的命令数据格式

EEh

诊断Echo。此命令纯粹为了检测Keyboard是否正常,如果正常,当Keyboard收到此命令后,将会回复一个EEh字节。

F0h

选择Scan code set。Keyboard系统共可能有3个Scan code set。当Keyboard收到此命令后,将回复一个ACK(FAh),然后等待一个来自于60h端口的Scan code set代码。系统必须在此命令之后发送给Keyboard一个Scan code set代码(01~03)。当Keyboard收到此代码后,将再次回复一个ACK,然后将Scan code set设置为收到的Scan code set代码所要求的。如果数据为0x00,则主机返回当前使用的键盘扫描码集的编号。

F2h

读取Keyboard ID。由于8042芯片后不仅仅能够接Keyboard。此命令是为了读取8042后所接的设备ID。设备ID为2个字节,Keyboard ID为83ABh。当键盘收到此命令后,会首先回复一个ACK(FAh),然后,将2字节的Keyboard ID一个一个回复回去。

F3h

设置Typematic Rate/Delay。当Keyboard收到此命令后,将回复一个ACK(FAh)。然后等待来自于60h的设置字节。一旦收到,将回复一个ACK,然后将Keyboard Rate/Delay设置为相应的值。

F4h

清理键盘的Output Buffer。一旦Keyboard收到此命令,将会将Output buffer清空,然后回复一个ACK(FAh)。然后继续接受Keyboard的击键。

F5h

设置默认状态(w/Disable)。一旦Keyboard收到此命令,将会将Keyboard完全初始化成默认状态。之前所有对它的设置都将失效——Output buffer被清空,Typematic Rate/Delay被设置成默认值。然后回复一个ACK(FAh),接着等待下一个命令。需要注意的是,这个命令被执行后,键盘的击键接受是禁止的。如果想让键盘接受击键输入,必须Enable Keyboard。

F6h

设置默认状态。和F5命令唯一不同的是,当此命令被执行之后,键盘的击键接收是允许的。

FEh

Resend。如果Keyboard收到此命令,则必须将刚才发送到8042 Output Register中的数据重新发送一遍。当系统检测到一个来自于Keyboard的错误之后,可以使用自命令让Keyboard重新发送刚才发送的字节。

FFh

Reset Keyboard。如果Keyboard收到此命令,则首先回复一个ACK(FAh),然后启动自身的Reset程序,并进行自身基本正确性检测(BAT-Basic Assurance Test)。等这一切结束之后,将返回给系统一个单字节的结束码(AAh=Success, FCh=Failed),并将键盘的Scan code set设置为2。

③从0x60读出的数据:

00h/FFh

当击键或释放键时检测到错误时,则在Output Bufer后放入此字节,如果Output Buffer已满,则会将Output Buffer的最后一个字节替代为此字节。使用Scan code set 1时使用00h,Scan code 2和Scan Code 3使用FFh。

AAh

BAT完成代码。如果键盘检测成功,则会将此字节发送到8042 Output Register中。

EEh

Echo响应。Keyboard使用EEh响应从60h发来的Echo请求。

F0h

在Scan code set 2和Scan code set 3中,被用作Break Code的前缀。

FAh

ACK。当Keyboard任何时候收到一个来自于60h端口的合法命令或合法数据之后,都回复一个FAh。

FCh

BAT失败代码。如果键盘检测失败,则会将此字节发送到8042 Output Register中。

FEh

Resend。当Keyboard任何时候收到一个来自于60h端口的非法命令或非法数据之后,或者数据的奇偶交验错误,都回复一个FEh,要求系统重新发送相关命令或数据。

83ABh

当键盘收到一个来自于60h的F2h命令之后,会依次回复83h,ABh。83AB是键盘的ID。

Scan code

除了上述那些特殊字节以外,剩下的都是Scan code。


关于ScanCode:

当键盘上有键被按下,松开,按住,键盘将产生扫描码( Scan Code ),这些扫描码将被 i8048 直接得到。扫描码有两种,Make Code 和 Break Code。当一个键被按下或按住时产生的是 Make Code ,当一个键被松开产生的是 Break Code。每个键被分配了唯一的 Make Code 和 Break Code ,这样主机通过扫描码就可以知道是哪一个键。简单的说就是按下键,产生一个 Make Code。松开键,产生一个 Break Code。

到目前为止一共有三套扫描码集( Scan Code Set ),ps/2 键盘默认使用第二套。不过可以设置 i8042,让 i8042 把得到的 Scan Code 翻译成 Scan Code Set 1 中的 Scan Code ,这样键盘驱动从 i8042 得到的所有 Scan Code 都是第一套中的 Scan Code(实际中驱动也是这么做的)。所以我们只讨论 Scan Code Set 1 。需要说明的是 Scan Code 和 ASCII码完全不相同。

在 Scan Code Set 1 中,大多数键的 Make Code,Break Code 都是一个字节。他们的 Make Code 的最高位都为0,也就是他们的 Make Code 都小于 0x7F。而他们的 Break Code 为其 Make Code 或运算 80h ,也就是把 Make Code 的低7位不变,最高位设置为1。

还有一些扩展按键,他们的 Scan Code 是双字节的。他们的第一个字节都是E0h,表明这是一个扩展键。第2个字节,和单字节 Scan Code 的情况相同。

还有一个特殊的键,Pause/Break 键,它的 Make Code 为 E1,1D,45 E1,9D,C5,注意是 E1h 开头。而且它没有 Break Code 。

Brother louie(经典的舞曲)

这是80年代的经典舞曲,Modern Talking的brother louie。

这首歌实在是太有名了,以至于被50多种语言翻唱,

原唱Modern Talking 是两人的德国dance-pop二人组合,在80年代中后期红遍世界

后来乐队解散,90年代后期重新组合,出了新的专辑,可惜已经远没有当年的悦耳了。

下面是歌词

Deep love is a burning fire stay,
cause then the flames grow higher Babe,
don ‘t let him steal your heart
It’s easy,easy
Girl,this game can’t last forever
Why, we cannot live together?
Try, don’t let him take your love from me
You’re no good, can’t you see
Brother louie, Louie, Louie
I’m in love – set you free
Oh, she’s only looking to me
Only love breaks her heart
Brother Louie, Louie, Louie
Only love’s paradise
Oh, she’s only looking to me
Brother Louie, Louie, Louie
Oh, she’s only looking to me
Oh, let it Louie
She is undercover
Brother Louie, Louie, Louie
Oh, doint what he’s doing
So, leave it Louie
‘Cause I’m her lover
Stay,’cause this boy wants to gamble
Stay, love is more than he can handle
Girl, oh, come on, stay by me forever, ever
Why does he go on pretending
That his love is never ending
Babe, don’t let him steal your love from me

下载地址:http://www.crossbayblvd.com/files/The_Stories_-_Brother_Louie.mp3

MV中的背景为《美国往事》,也是很经典的讲人生的电影。属于黑帮史诗型的~~

多线程的网络通信程序

起因是学校课要求写一个双机网络通信,并且可以发送文件的程序。

使用的是传统的socket (recv(),send() …..)等。而且是阻塞模式,使用图形界面MFC编写 (VC 6.0)。但为了能让程序不出现假死现象( recv,accept 这样的函数都会出现这样的事情),所以采用了多线程技术,其实也就是用了AfxBeginThread ,TerminateThread等等。这样对于阻塞函数都让他们在新建立的线程里运行就好了。

另外解决的一个大问题就是,创建的新线程无法对窗口进行操作,比如要自在编辑框显示一句话等等。如果直接取得窗口类的句柄操作,会出现wincore的错误,也就是跨线程错误。主要原因也就是——-MFC的线程被自己外部创建的线程调用就会有这个错误。解决的方法就是在线程里用SendMessage给窗口发送一个自定义的消息,比如我这里用的就是。

要实现这样的方法

在BEGIN_MESSAGE_MAP下面要添加

ON_MESSAGE(WM_UpdateDATA, OnMyMessage)
//绑定我自己的消息,这样外部的线程就可以通过SendMessage来调用窗体的函数OnMyMessage了,用来显示信息WM_UpdateDATA在stdafx.h中我自己定义
#define WM_UpdateDATA WM_USER+100
//定义一个自己的消息这样只要外部给窗口SendMessage WM_UpdateDATA 就会让窗口的onmymessage函数执行了,具体要显示的内容放在一个全局变量就好了。

这里写出一些关键的代码,具体程序可以到点击这里下载

我注释的相当详细了。
编译的话,debug版可以正常工作,但release版就无法正常工作了

serverdlg.cpp

//定义全局变量,方便各个工作线程和窗口线程的通信 SOCKET sockuse,sock; int flag; //主要是用来标志是否连接,用来控制一些循环和功能 HWND mydlg; //记录窗体的句柄 HWND stopbutton; //记录关闭连接按钮的句柄 char buff[200]; //主要的缓冲区,显示数据使用,也供线程间通信使用 CWinThread* mainthread; //记录线程的句柄 UINT FileTrans(LPVOID pParam) //发送文件的线程函数 { OPENFILENAMEA ofn; char szFile[260]; char path[260]; char filebuff[100]; int num; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = NULL; ofn.lpstrFile = szFile; ofn.lpstrFile[0] = ''; ofn.nMaxFile = sizeof(szFile); ofn.lpstrFilter = "所有文件*.*"; ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = 0; //以上的定义是为了建立一个文件打开对话框。步骤 //上来说都是固定的,这里只是借用一下 if (GetOpenFileNameA(&ofn)==FALSE) //判断文件路径取得是否正确 { //若失败则恢复建立MainControl线程,进行数据接收处理。 mainthread=AfxBeginThread(MainControl,NULL); flag=1; //设定flag保证MainControl可以正常进行循环 return 0; } memset(filebuff,0,100); //清空filebuff strcpy(path,ofn.lpstrFile); //将路径拷贝到path中 strcpy(filebuff,"@@sendstart"); send(sockuse,filebuff,strlen(filebuff),0); //发送请求信息 recv(sockuse,filebuff,100,0); //等待接收反馈信息 if(strcmp(filebuff,"@@sendagree")) //若接收到的信息不是@@sendagree { strcpy(buff,"对方接受错误"); SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); //发送给窗口消息,显示信息 mainthread=AfxBeginThread(MainControl,NULL); //恢复建立MainControl线程 flag=1; //设定flag保证MainControl循环正常 return 0; } SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); //发送给窗口消息,显示信息 while(!feof(fp)) { num=fread(filebuff,1,100,fp); //文件结束前每次读取100字节 send(sockuse,filebuff,num,0); //发送,最后一次不足100字节 //作为标志,可以让接受方知道文件结束 } strcpy(buff,"发送完毕"); SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); //发送给窗口消息,显示信息 memset(buff,0,100); fclose(fp); //关闭文件 flag=1; return 0; } UINT FileRecv() //接收文件函数 { char sendbuff[100]; //发送缓冲区 char recvbuff[100]; //接受缓冲区 int num; //记录每次接受的字节数 CString szGetName; //记录保存的文件路径 CFileDialog * lpszOpenFile; //定义一个CfileDialog对象 lpszOpenFile=new CFileDialog(false,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"文件类型(*.*)|*.*||");//生成一个对话框 if(lpszOpenFile->DoModal()==IDOK)//假如点击对话框确定按钮 { szGetName = lpszOpenFile->GetPathName(); //得到打开文件的路径 //SetWindowText(szGetName);     //在窗口标题上显示路径 } delete lpszOpenFile; //释放分配的对话框 memset(sendbuff,0,100); strcpy(sendbuff,"@@sendagree"); send(sockuse,sendbuff,strlen(sendbuff),0); //发送@@sendagree告知对方开始发送吧 SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); //发送给窗口消息,显//示信息 num=recv(sockuse,recvbuff,100,0); //接收数据 FILE *fp=fopen(szGetName,"wb"); //打开文件,路径为szGetName fwrite(recvbuff,num,1,fp); //写入之前的数据 { num=recv(sockuse,recvbuff,100,0); fwrite(recvbuff,num,1,fp); } fclose(fp); //结束后关闭文件。 strcpy(buff,"接收完毕"); SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); //发送给窗口消息,////显示信息 return 0; } int Addrlen=sizeof(sockaddr_in); //accept要用到的数值 sockaddr_in ClientAddr; sockuse=accept(sock,(struct sockaddr FAR *)&ClientAddr,&Addrlen); //上一句的accept函数调用后会进行阻塞,造成未返回时程序假死,使用了单独的线程 //就是为了防止这样的现象发生 flag=1; //返回成功后,设定flag保证MainControl循环正常 strcpy(buff,"已经连接!"); SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); //发送给窗口消//息,显示信息 mainthread=AfxBeginThread(MainControl,NULL); //建立MainControl线程 return 0; } { char recvbuff[100]; //接受缓冲区 memset(buff,0,100); while(flag) { memset(recvbuff,0,100); //每次接收前清空缓冲区 recv(sockuse,recvbuff,100,0); //进行阻塞接收数据,如果不是用单独的线程 //会造成程序假死,这也就是为什么我的程序使用单独的线程来处理 if(!strcmp(recvbuff,"@@end")) { SendMessage(stopbutton,BM_CLICK,NULL,NULL); //消息判断为@@end则调用 //窗口的OnButtonEnd函数来结束连接的清理工作。 return 0; } else if(!strcmp(recvbuff,"@@sendstart")) { //接受的消息判断为"@@sendstart"则调用FileRecv() FileRecv(); } else { strcpy(buff,"client:"); strcat(buff,recvbuff); SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); //发送给//窗口消息,显示信息 } } return 0; } { m_ctrlstop.EnableWindow(true); m_ctrlfile.EnableWindow(true); m_ctrlstart.EnableWindow(false); m_ctrlsend.EnableWindow(true); //以上使各个按钮进行使能 sockaddr_in ServerAddr; //开始建立socket WSADATA WSAData; if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0) { showmess("SOCKET 初始化错误rn"); return; } sock=socket(AF_INET,SOCK_STREAM,0); //采用流式套接字,ipv4 if(sock==SOCKET_ERROR) { showmess("SOCKET 创建错误!rn"); WSACleanup(); return; } ServerAddr.sin_family=AF_INET; ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY); //任意ip作为本机ip ServerAddr.sin_port=htons(2006); //使用2006端口 if(bind(sock,(struct sockaddr FAR*)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR) { //绑定socket和本地地址 showmess("绑定错误!n"); return; } //显示正在侦听 showmess("listening....."); listen(sock,1); flag=0; //未连接之前,flag=0 mydlg=this->GetSafeHwnd(); //取得窗口句柄供线程函数使用 stopbutton=::GetDlgItem(mydlg,IDC_BUTTON_STOP); //取得关闭连接按//钮的句柄供线程函数使用 AfxBeginThread(WaitForAccept,NULL); //启动WaitForAccept线程等待连接 return; } void CServerDlg::showmess(char *mess) //用来在信息窗口显示信息 { m_strmess+=mess; m_strmess+="rn"; //在每条信息后添加回车 UpdateData(false); //更新信息显示 } { flag=0; //将连接标志清零 strcpy(buff,"@@end"); send(sockuse,buff,strlen(buff),0); //给对方发送信息告知结束 TerminateThread(mainthread->m_hThread,0x01); //结束MainControl线程 closesocket(sock); //关闭套接字 closesocket(sockuse); WSACleanup(); //清理网络 m_ctrlstop.EnableWindow(false); //使能一些按钮 m_ctrlfile.EnableWindow(false); m_ctrlstart.EnableWindow(true); } void CServerDlg::OnMyMessage() { showmess(buff); //仅仅是为了线程函数调用内部的信息显示函数 } void CServerDlg::OnButtonFile() { flag=0; //设定 flag TerminateThread(mainthread->m_hThread,0x01); //中止MainControl AfxBeginThread(FileTrans,NULL); //启用FileTrans线程 } void CServerDlg::OnButtonSend() { char talkbuff[100]; memset(talkbuff,0,100); UpdateData(true); strcpy(talkbuff,m_strtalk); //取得对话框数据 send(sockuse,talkbuff,100,0); //发送给对方信息 }

clientDlg.cpp

#include "winsock.h" 
#include "stdio.h"
#include"string.h"
#pragma comment(lib,"wsock32.lib")    //这四句要加在本文件的开头部分。保证
//网络功能正常
在BEGIN_MESSAGE_MAP下面要添加
ON_MESSAGE(WM_UpdateDATA,   OnMyMessage)
 
 /*绑定我自己的消息,这样外部的线程就可以通过SendMessage来调用窗体的函数OnMyMessage了,用来显示信息 
WM_UpdateDATA在stdafx.h中我自己定义为
#define WM_UpdateDATA WM_USER+100    //定义一个自己的消息*/
 
 
//定义全局变量,方便各个工作线程和窗口线程的通信
SOCKET sock;
char buff[100];  //主要的缓冲区,显示数据使用,也供线程间通信使用
HWND mydlg;    //记录窗体的句柄
sockaddr_in ServerAddr;
int flag=0;      //主要是用来标志是否连接,用来控制一些循环和功能
CWinThread* mainthread;
HWND stopbutton;   //记录关闭连接按钮的句柄
 
 
 
UINT WaitForConnect(LPVOID pParam)  //等待connect 的线程 
{
       if(connect(sock,(struct sockaddr*)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR)
       {
       strcpy(buff,"connect failn");
       SendMessage(mydlg,WM_UpdateDATA,NULL,NULL);  //发送给窗口消//息,显示信息
       closesocket(sock);   //失败则关闭sock
       return 0;
       }
       strcpy(buff,"已经连接!");
       SendMessage(mydlg,WM_UpdateDATA,NULL,NULL);//发送给窗口消////息,显示信息
       flag=1;
       mainthread=AfxBeginThread(MainControl,NULL); //建立MainControl线程
       return 0;
}
 
{
char sendbuff[100];               //发送缓冲区
char recvbuff[100];                //接受缓冲区
int num;                          //记录每次接受的字节数
 
CString szGetName;
CFileDialog * lpszOpenFile;    //定义一个CfileDialog对象
lpszOpenFile = new CFileDialog(false,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"文件类型(*.*)|*.*||");//生成一个对话框
if(lpszOpenFile->DoModal()==IDOK)//假如点击对话框确定按钮
{
szGetName = lpszOpenFile->GetPathName();  //得到打开文件的路径
//SetWindowText(szGetName);            //在窗口标题上显示路径
}
delete lpszOpenFile; //释放分配的对话框
 
memset(sendbuff,0,100);
strcpy(sendbuff,"@@sendagree");    
send(sock,sendbuff,strlen(sendbuff),0);  //发送@@sendagree告知对方开始发送吧
SendMessage(mydlg,WM_UpdateDATA,NULL,NULL);   //发送给窗口消息,显示信息 
num=recv(sock,recvbuff,100,0);           //接收数据
FILE *fp=fopen(szGetName,"wb");      //打开文件,路径为szGetName
fwrite(recvbuff,num,1,fp);            //写入之前的数据 
 
while(num==100)         //根据接收是否为100字节判断文件是否结束 
{
num=recv(sock,recvbuff,100,0);
fwrite(recvbuff,num,1,fp);
} 
strcpy(buff,"接收完毕");
SendMessage(mydlg,WM_UpdateDATA,NULL,NULL);    //发送给窗口消息,显示信息
return 0;
}
 
char recvbuff[100];//接受缓冲区 
{ 
memset(buff,0,100);
 
while(flag) 
{
       memset(recvbuff,0,100); //每次接收前清空缓冲区
       recv(sock,recvbuff,100,0); //进行阻塞接收数据,如果不是用单独的线程
       //会造成程序假死,这也就是为什么我的程序使用单独的线程来处理
       if(!strcmp(recvbuff,"@@end"))  
       {//消息判断为@@end则调用
              //窗口的OnButtonEnd函数来结束连接的清理工作。
       SendMessage(stopbutton,BM_CLICK,NULL,NULL);
       return 0;
       }
       else if(!strcmp(recvbuff,"@@sendstart"))
       {
              //接受的消息判断为"@@sendstart"则调用FileRecv()
       FileRecv();
       memset(recvbuff,0,100);
       }
    else
       { 
              strcpy(buff,"server:");
              strcat(buff,recvbuff);
              SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); 
              //发送给窗口消息,显示信息
       }
}
return 0;
}
 
{
   
 OPENFILENAMEA ofn;      
 char szFile[260];      
 char path[260];
 char filebuff[100];
 int num;
 ZeroMemory(&ofn, sizeof(ofn));
 ofn.lStructSize = sizeof(ofn);
 ofn.hwndOwner = NULL;
 ofn.lpstrFile = szFile;
 ofn.lpstrFile[0] = '';
 ofn.nMaxFile = sizeof(szFile);
 ofn.lpstrFilter = "所有文件*.*";
 ofn.nFilterIndex = 1;
 ofn.lpstrFileTitle = NULL;
 ofn.nMaxFileTitle = 0;
 ofn.lpstrInitialDir = NULL;
 ofn.Flags = 0;
  //以上的定义是为了建立一个文件打开对话框。步骤
//上来说都是固定的,这里只是借用一下
 
 if (GetOpenFileNameA(&ofn)==FALSE)          //判断文件路径取得是否正确 
       {                   //若失败则恢复建立MainControl线程,进行数据接收处理。
        mainthread=AfxBeginThread(MainControl,NULL);
        flag=1;        //设定flag保证MainControl可以正常进行循环
       return 0;
       }
 memset(filebuff,0,100);      //清空filebuff
 strcpy(path,ofn.lpstrFile);   //将路径拷贝到path中
 strcpy(filebuff,"@@sendstart");
 send(sock,filebuff,strlen(filebuff),0);  //发送请求信息
 recv(sock,filebuff,100,0);      //等待接收反馈信息
 if(strcmp(filebuff,"@@sendagree"))        //若接收到的信息不是@@sendagree
 {
        strcpy(buff,"对方接受错误");            
     SendMessage(mydlg,WM_UpdateDATA,NULL,NULL);  //发送给窗口消息,显示信息
        mainthread=AfxBeginThread(MainControl,NULL);  //恢复建立MainControl线程
        flag=1;                               //设定flag保证MainControl循环正常
        return 0;
 
}
 
strcpy(buff,"对方已经同意,开始发送文件"); 
SendMessage(mydlg,WM_UpdateDATA,NULL,NULL); 
////发送给窗口消息,显示信息  
FILE *fp=fopen(path,"rb");           //打开文件
 
 
     while(!feof(fp)) 
        {
        num=fread(filebuff,1,100,fp);     //文件结束前每次读取100字节
        send(sock,filebuff,num,0);     //发送,最后一次不足100字节
                                     //作为标志,可以让接受方知道文件结束
        }
   
       strcpy(buff,"发送完毕");
       SendMessage(mydlg,WM_UpdateDATA,NULL,NULL);  //发送给窗口消息,显示信息
       memset(buff,0,100);
       fclose(fp);                     //关闭文件
    mainthread=AfxBeginThread(MainControl,NULL);   //恢复建立MainControl线程
    flag=1;
    return 0;
}
 
{
       m_ctrlstop.EnableWindow(true);
       m_ctrlfile.EnableWindow(true);
       m_ctrlconnect.EnableWindow(false);//以上使各个按钮进行使能
 
WSADATA WSAData;//开始建立socket
 
if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0)
{
       showmess("socket初始化错误");
       return;
} 
 
sock=socket(AF_INET,SOCK_STREAM,0);//采用流式套接字,ipv4 
if(sock==SOCKET_ERROR)
       {
              showmess("SOCK Create FAIL!");
              WSACleanup();
          return;
       }
ServerAddr.sin_family = AF_INET;       
ServerAddr.sin_port = htons(2006); //使用2006端口
UpdateData(true);  //读取ip 值
ServerAddr.sin_addr.s_addr = inet_addr(m_strip);
//使用编辑框中的ip地址,默认值127.0.0.1 
 
//取得窗口句柄供线程函数使用
flag=0;
stopbutton=::GetDlgItem(mydlg,IDC_BUTTON_STOP);
//取得关闭连接按钮的句柄供线程函数使用
AfxBeginThread(WaitForConnect,NULL);
//启动WaitForConnect线程进行连接
return; 
{
m_strmess+=mess;
m_strmess+="rn";  //在每条信息后添加回车
UpdateData(false);  //更新信息显示
}
 
void CClientDlg::OnMyMessage()   
{
showmess(buff);//仅仅是为了线程函数调用内部的信息显示函数
}
 
{ 
 
       TerminateThread(mainthread,0x01);
       //结束MainControl线程
       strcpy(buff,"@@end");
       send(sock,buff,strlen(buff),0);
       //给对方发送信息告知结束
       closesocket(sock);
       //关闭套接字
    WSACleanup();
       m_ctrlstop.EnableWindow(false);//使一些按钮
       m_ctrlfile.EnableWindow(false);
       m_ctrlconnect.EnableWindow(true);
}
 
 
{
       char talkbuff[100]; 
       memset(talkbuff,0,100);
       UpdateData(true);
       strcpy(talkbuff,m_strsendmess);  //取得对话框数据
       send(sock,talkbuff,100,0);   //发送给对方信息
      
}
 
void CClientDlg::OnButtonFile()  
{
flag=0;      //设定 flag
    TerminateThread(mainthread->m_hThread,0x01);  //中止MainControl
AfxBeginThread(FileTrans,NULL);   //启用FileTrans线程
}
 
 
 
 
 
void CClientDlg::OnButtonSend()
       flag=0;  //将连接标志清零
 
 
void CClientDlg::OnButtonStop() 
}
 
void CClientDlg::showmess(char *mess) //用来在信息窗口显示信息 
mydlg=this->GetSafeHwnd();   
 
void CClientDlg::OnButtonConnect()  
 
UINT FileTrans(LPVOID pParam)
 
UINT MainControl(LPVOID pParam)
 
fclose(fp);              //结束后关闭文件。 
strcpy(buff,"开始接收文件"); 
 
UINT FileRecv()  //接收文件函数
 
UINT MainControl(LPVOID pParam); //提前声明该线程函数
 

再次回到clientDlg.cpp中,接下来就是程序的主体部分了。

接下来是客户端的程序了,和server一样也要自定义消息

void CServerDlg::OnButtonStop()  
 
 
void CServerDlg::OnButtonStart() 
 
 
UINT MainControl(LPVOID pParam) 
{
 
UINT WaitForAccept(LPVOID pParam)    //等待accept 的线程
 
while(num==100)         //根据接收是否为100字节判断文件是否结束 
strcpy(buff,"开始接收文件"); 
       mainthread=AfxBeginThread(MainControl,NULL);   //恢复建立MainControl线程 
FILE *fp=fopen(path,"rb");           //打开文件
 
strcpy(buff,"对方已经同意,开始发送文件");       

iscc 2009

真的有点搞不下去了

基础关:

还真算是基础,但也学到了很多东西,http–reference算是最大的收获,本地提交也让我知道了,封包截取指示下下策。该死的循环干扰码,用regular expression两次提交都没有通过,估计是太草率了,没有考虑太多,就疯狂的替换了,现在倒是想明白了,可真是没脸再提交了。
最后的autoback,我发现了index.php存在index.php.bak但对于php环境不像asp,php.bak一样可以被解析,无法下载察看代码,虽然index.php.bak里action=basic_4.php不同于index.php,但也实在没找到这个页面,郁闷极了,憋了好几个下午都快吐血了。

脚本关:

前几关怎么过得都快忘干净了,前面会的,很快就通过了,后面德就死活搞不出来。比较欣慰的是数据库连接文件conn.asa总算是猜出来了。后面的倒数第三关好像过滤了space和%,总之就是提交失败。天杀的csrf xss我试了好久,终于绕过了字符过滤。诡异的就是明明提交了adduser的参数,为什么就是没能让管理员添加我,也尝试了cookie窃取,还特意在校内某服务器上搭建了asp环境来截获cookie,可除了自己的一无所获。今天以下午都在这耗着,我真的要放弃这几关了,平日积累真的是不太够,一直没太重视他们。

破解关:

这算是我最自豪的了,刚好最近做的那个创新项目就是研究shell,对于这种汇编代码的分析还比较得心应手,特别是各种anti一眼就看了出来,第五个shell也比较容易脱掉,我就直接带壳调试了,最终也还算运气比较好,跳过了一些环节后直接到了算法部分,其实只靠算法答案有6!种,但我比较幸运猜到了各位的关系。其中jmp eax是直接跳过了,真不知道正常情况下,哪个环节的跳转怎么从堆栈返回。不过这个方法倒是可以借鉴到我的shell编写中。

溢出关:

概念清晰很重要啊,没想到我的概念清晰到每个环节,第一次来真格的进行overflow竟然还真成功了,不过当然也是因为题目简单,思路其实很简单,就是覆盖返回的eip,heap seh等等我生疏的概念一个也用不到,比较头疼的就是最后一个overflow,shellcode因为都是自己写的,代码的选择费了好大的劲,还好不要求功能,要不就累死了。另外发现工具的使用也非常重要,一个得心应手的16进制编辑器是必需的,我的用得不太好,每次几百字节的shellcoded都是自己手动写的机器码,真想吐血。
内核关:虽然我挺喜欢编程序,但看来要搭建环境比较麻烦,把资料下载下来,留待假期研究吧
收获嘛,真的是太大了,感觉一下进步了不少,至少是增长了知识。

shot through the heart(大卫科波菲尔的表演)

前一段时间看了david copper field(大卫科波菲尔)以前的一段表演,不过真正吸引我的还是开始和结尾时的那段音乐,查了好久,就听清一句shot through the heart

去下载了这首歌,发现居然还不是。但作者算是找对了,jbon jovi 邦 乔维,是他的另一首歌You give love a bad name。确实很好听,希望大家喜欢

下载地址:http://www.liquidgeneration.com/ blogmedia/music/audio/yougiveloveabadname.mp3

下面是现场版的表演

英文歌词及翻译

Shot through the heart

透过心的注射

And you’re to blame

而且你应受谴责

You give love a bad name

你提供爱一个坏的名字

An angel’s smile is what you sell

天使的微笑是你所卖的

You promise me heaven, then put me through hell

你答应我天堂, 然后替我接通地狱

Chains of love got a hold on me

爱的链得到了在我上的把握

When passion’s a prison, you can’t break free

当强烈的感情一所监狱, 你自由地不能打破(wo.)

You’re a loaded gun(oh yeah)

你是一把上膛的枪 ( 表示惊讶是的?)

(wo.)

There’s nowhere to run

那里无处跑

No one can save me

没有人能解救我

The damage is done

损害被做

Shot through the heart

透过心的注射

And you’re to blame

而且你应受谴责

You give love a bad name

你提供爱一个坏的名字

I play my part and you play your game

我玩我的部份,而且你玩你的游戏

You give love a bad name

你提供爱一个坏的名字

You give love a bad name

你提供爱一个坏的名字

You paint your smile on your lips

你油漆在你的唇上你微笑

Blood red nails on your fingertips

在你的指尖上的鲜红色钉子

A school boy’s dream, you act so shy

一个学校男孩的梦, 你这么行动很胆怯

Your very first kiss was your first kiss goodbye

你的非常第一的吻是你的第一个吻再见

(wo.)

You’re a loaded gun

你是一把上膛的枪

(wo.)

There’s nowhere to run

那里无处跑

No one can save me

没有人能解救我

The damage is done

损害被做

Shot through the heart

透过心的注射

and you’re to blame

而且你应受谴责

You give love a bad name

你提供爱一个坏的名字

I play my part and you play your game

我玩我的部份,而且你玩你的游戏

You give love a bad name

你提供爱一个坏的名字

You give love.

你提供爱.

(solo)

(独奏)

Shot through the heart

透过心的注射

and you’re to blame

而且你应受谴责

You give love a bad name

你提供爱一个坏的名字

I play my part and you play your game

我玩我的部份,而且你玩你的游戏

You give love a bad name

你提供爱一个坏的名字

You give love.

你提供爱.

THE END

结束

by lune

藉着弓形

shape of my heart 很好听的歌曲

这首歌出自影片《这个杀手不太冷》,但第一次注意听还是在看别人表演时的配乐。

《shape of my heart》的演唱者是Sting,大名顶顶的“警察乐队”原主唱。影片《这个杀手不太冷》故事之精彩自不必说,让我最为难忘的是影片结尾,当莱昂为救小女孩而铤而走险,在混出重围后,眼看走向门口的光明时,却丧失了性命。曲终人散,这首《shape of my heart》在Sting他那独一无二的沙哑,但又不失细腻入微的嗓音的吟唱中,更显得自由不羁,如莱昂的灵魂,把莱昂侠义仁道、外冷内热的人格魅力演绎得淋漓尽致。

由于歌词中经常提到纸牌,因此纸牌魔术用这个配音真的不错

以下是两段我也比较喜欢的表演,用了这个配音

大魔竞刘世杰的表演

接下来这个是Shawn Farquhar 的表演,同样是这个音乐,而且和歌词搭配 ,他的个人简介后面会有。

下载地址:http://www.slaper.net/notes/ upload/2008/3/ShapeOfMyHeart.mp3

He deals the cards as a meditation 他出牌前沉思冥想

And those he plays never suspect 对出的每一张牌都很有把握

He doesn’t play for the money he wins 他不是为了赢钱而玩牌

He don’t play for respect 也不是为了获得尊重

He deals the cards to find the answer 他出牌是为了找寻答案

The sacred geometry of chance 找寻幸运的神圣机率

The hidden law of a probable outcome 在胜利后面隐藏着一种规则

The numbers lead a dance 那些数字在领舞

I know that the spades are the swords of a soldier 我知道黑桃是士兵的宝剑

I know that the clubs are weapons of war 我知道草花是战争的武器

I know that diamonds mean money for this art 我知道在这种游戏里方块就是钱

But that’s not the shape of my heart 但那不是我心的形状

He may play the jack of diamonds 他可以出方块J

He may lay the queen of spades 他可以出黑桃Q

He may conceal a king in his hand 他可以使小花招藏起K

While the memory of it fades 接着真的忘了自己有K

I know that the spades are the swords of a soldier 我知道黑桃是士兵的宝剑

I know that the clubs are weapons of war 我知道草花是战争的武器

I know that diamonds mean money for this art 我知道在这种游戏里方块就是钱

But that’s not the shape of my heart 但那不是我心的形状

And if I told you that I loved you 如果我告诉你我爱你

You’d maybe think there’s something wrong 你可能会觉得不妥

I’m not a man of too many faces 我不是多面派

The mask I wear is one 我只有一张面具

Well, those who speak know nothin’好吧,那些发言的人其实什么也不知道

And find out to their cost 他们最终会付出代价

Like those who curse their luck in too many places 就像有些人到处说自己不幸

And those who fear are lost还有那些退缩的人,他们都已迷失

I know that the spades are the swords of a soldier 我知道黑桃是士兵的宝剑

I know that the clubs are weapons of war 我知道草花是战争的武器

I know that diamonds mean money for this art 我知道在这种游戏里方块就是钱

But that’s not the shape of my heart 但那不是我心的形状

That’s not the shape, the shape of my heart 那不是我心的形状。。心的形状

That’s not the shape, the shape of my heart 那不是我心的形状。。心的形状

 

一副朴克牌,可以有多神奇呢?在Shawn Farquhar的手上,扑克牌变得不再是死板的一张张纸牌,而是会跟着音乐起舞,为你展现不同面貌的演员。而且,Shawn Farquhar也是魔术界少有的舞台近距离皆有成就的魔术师。他逗趣的表演,独特的个人风格,都是要每一个看过他魔术的观众,在不断的笑声与惊讶声中,永远都忘不了。

Shawn Farquhar是加拿大现在最红最有名的魔术师 他的技术是不用多说的 最重要的是他的人缘 他是一种奇迹的存在 和蔼就像一个大哥哥 有时候却很好笑 有时候却能很感人 亲切 这就可能是人们所说的具有观众缘吧

  • 2006年fism近距离部门第二名4
  • 2006年fism宴会部门第二名
  • 2003年fism近距离部门第二名
  • 2003年加拿大年度魔术师
  • 2001年IBM的近距离部门第一名
  • 2001年山姆近距离部门第一名
  • 2000年大平洋海岸魔术协会近距离部门总冠军
  • 1998年IBM的舞台部门第一名
  • 1992年太平洋海岸魔术协会舞台部门金奖