#include <reg51h>
#include <intrinsh>
#define uchar unsigned char
#define uint unsigned int
sbit IRIN = P3^2; //遥控输入脚
sbit BEEP = P3^7; //蜂鸣器
sbit RELAY= P3^6; //继电器
uchar IR_buf[4]={0x00,0x00,0x00,0x00};//IR_buf[0]、IR_buf[1]为用户码低位、用户码高位接收缓冲区
// IR_buf[2]、IR_buf[3]为键数据码和键数据码反码接收缓冲区
uchar disp_buf[2]={0x10,0x10}; //显示缓冲单元,初值为0x10(即16),指向显示码的第16个"-"
uchar code seg_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};
//0~F和"-"符的显示码(字形码)
/以下是014ms的x倍延时函数/
void delay(uchar x) //延时x014ms
{
uchar i;
while(x--)
for (i = 0; i<13; i++);
}
/以下是延时函数/
void Delay_ms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--) //i=xms即延时约xms毫秒
for(j=110;j>0;j--);
}
/以下是蜂鸣器响一声函数/
void beep()
{
BEEP=0; //蜂鸣器响
Delay_ms(100);
BEEP=1; //关闭蜂鸣器
Delay_ms(100);
}
/以下是显示函数/
void Display()
{
P0=(seg_data[disp_buf[0]]);
P2=0x7f;
Delay_ms(1);
P0=(seg_data[disp_buf[1]]);
P2=0xbf;
Delay_ms(1);
}
/以下是主函数/
main()
{
EA=1;EX0=1; //允许总中断中断,使能 INT0 外部中断
IT0 = 1; //触发方式为脉冲负边沿触发
IRIN=1; //遥控输入脚置1
BEEP=1; RELAY=1; //关闭蜂鸣器和继电器
P0=0xff; P2=0xff; //P0和P2口置1
Display(); //调显示函数
while(1)
{
if(IR_buf[2]==0x02) //02H键(键值码为02H)
RELAY=0; //继电器吸合
if(IR_buf[2]==0x01) // 01H键(键值码为01H)
RELAY=1; //继电器关闭
Display();
}
}
/以下是外中断0函数/
void IR_decode() interrupt 0
{
uchar j,k,count=0;
EX0 = 0; //暂时关闭外中断0中断请求
delay(20); //延时20014=28ms
if (IRIN==1) //等待 IRIN低电平出现
{
EX0 =1; //开外中断0
return; //中断返回
}
while (!IRIN) delay(1); //等待IRIN变为高电平,跳过9ms的低电平引导码
for (j=0;j<4;j++) //收集四组数据,即用户码低位、用户码高位、键值数据码和键值数码反码
{
for (k=0;k<8;k++) //每组数据有8位
{
while (IRIN) //等待IRIN变为低电平,跳过45ms的高电平引导码信号。
delay(1);
while (!IRIN) //等待IRIN变为高电平
delay(1);
while (IRIN) //对IRIN高电平时间进行计数
{
delay(1); //延时014ms
count++; //对014ms延时时间进行计数
if (count>=30)
{
EX0=1; //开外中断0
return; //014ms计数过长则返回
}
}
IR_buf[j]=IR_buf[j] >> 1; //若计数小于6,数据最高位补"0",说明收到的是"0"
if (count>=6) {IR_buf[j] = IR_buf[j] | 0x80;} //若计数大于等于6,数据最高位补"1",说明收到的是"1"
count=0; //计数器清0
}
}
if (IR_buf[2]!=~IR_buf[3]) //将键数据反码取反后与键数据码码比较,若不等,表示接收数据错误,放弃
{
EX0=1;
return;
}
disp_buf[0]=IR_buf[2] & 0x0f; //取键码的低四位送显示缓冲
disp_buf[1]=IR_buf[2] >> 4; //右移4次,高四位变为低四位送显示缓冲
Display(); //调显示函数
beep(); //蜂鸣器响一声
EX0 = 1; //开外中断0
}
gh0st远控软件采用驱动级RESSDT过主动,svchost参数启动,替换系统服务的方式工作的,工作方式较为先进,美中不足的部分是没有进行驱动级或用户级隐藏,当然这部分可以添加进去。编码利用了VC的编程环境。
一、环境配置
编译环境一定要配置好:DDK+SDK+VC6,DDK用来编译sys文件的,SDK+VC6是用来编译工程的,配置部分比较简单,网上有很多资料,这里不再详述,有兴趣的朋友也可以查看DDK和SDK的相关帮助。
二、特征码定位简述
杀毒软件查杀木马的原理基本是根据特征查杀的,被查杀的部分我们称之为特征码,所以我们可以利用特征码定位工具MyCLL定位出病毒的特征码位置,定位工具原理是将被扫描木马分块,利用分段填充的方式,匹配杀软的特征值,找到杀软查杀病毒的位置。
定位出特征码,如何反向找到源码中的对应位置呢?请看下面分析,
三、二进制文件与源码定位之map文件利用
map文件是二进制和源码之间对应的一个映射文件。
我们假设根据第三步我们定位出了病毒的特征码:
病毒名称 特征码位置 内存地址
svchostdll 000038AA_00000002 100044AA
svchostdll 00005F98_00000002
第一步设置VC编译环境生成Map文件。
在 VC 中,点击菜单“Project -> Settings”选项页(或按下 Alt+F7),选择 C/C++ 选项卡,并在最下面的 Project Options 里面输入:/Zd ,然后要点击 Link 选项卡,选中“Generate mapfile”复选框,并在最下面的 Project Options 里面输入:/mapinfo:lines,表示生成 MAP 文件时,加入行信息。设置完成。
第二步编译VC工程,设置活动工程编译即可,这个不用说明。这个步骤完成后,在release(或debug)目录,多了一个map文件(比如svchostmap)。
第三步打开map文件(用UE或文本编辑器打开都行),形式如下:
(begin)
Timestamp is 488fcef2 (Wed Jul 30 10:16:18 2008)
Preferred load address is 10000000
---------------------------------------------------------------------------1----(为方便说明,wrw添加)
Start Length Name Class
0001:00000000 00010a50H text CODE
0001:00010a50 00000485H text$x CODE
0002:00000000 000004c8H idata$5 DATA
0003:00000010 00000004H CRT$XIZ DATA
0003:00000020 00001a50H data DATA
0003:00001a70 00000688H bss DATA
0004:00000000 000000a8H rsrc$01 DATA
0004:000000b0 00000cf0H rsrc$02 DATA
----------------------------------------------------------------------------2---(为方便说明,wrw添加)
Address Publics by Value Rva+Base Lib:Object
0001:00000000 0CAudio@@QAE@XZ 10001000 f Audioobj
0001:000000d0 _GCAudio@@UAEPAXI@Z 100010d0 f i Audioobj
0001:000000d0 _ECAudio@@UAEPAXI@Z 100010d0 f i Audioobj
0001:000000f0 1CAudio@@UAE@XZ 100010f0 f Audioobj
0001:000001e0 getRecordBuffer@CAudio@@QAEPAEPAK@Z 100011e0 f Audioobj
0001:00000240 playBuffer@CAudio@@QAE_NPAEK@Z 10001240 f Audioobj
0001:000002c0 InitializeWaveIn@CAudio@@AAE_NXZ 100012c0 f Audioobj
0001:00003310 SendToken@CFileManager@@AAEHE@Z 10004310 f FileManagerobj
0001:00003320 UploadToRemote@CFileManager@@AAE_NPAE@Z 10004320 f FileManagerobj
0001:00003440 FixedUploadList@CFileManager@@AAE_NPBD@Z 10004440 f FileManagerobj
0001:00003670 StopTransfer@CFileManager@@AAEXXZ 10004670 f FileManagerobj
0001:00003730 CreateLocalRecvFile@CFileManager@@AAEXPAE@Z 10004730 f FileManagerobj
----------------------------------------------------------------------------3---(为方便说明,wrw添加)
Line numbers for \Release\FileManagerobj(E:\vtmp\gh0st3src\Server\svchost\common\FileManagercpp) segment text
17 0001:00002630 20 0001:0000267f 21 0001:00002698 24 0001:000026d0
25 0001:000026f8 26 0001:0000273c 29 0001:000027d0 33 0001:000027ee
77 0001:000027f8 36 0001:000027fb 37 0001:00002803 77 0001:0000280d
532 0001:0000340f 534 0001:00003414 537 0001:00003428 540 0001:00003440
546 0001:0000345d 547 0001:00003487 548 0001:00003490 549 0001:00003492
551 0001:0000349e 552 0001:000034b8 553 0001:000034cb 554 0001:000034d4
558 0001:000034de 560 0001:000034e9 563 0001:000034ee 564 0001:00003506
(end)
我们看下,定位svchostdll 的第一个特征码内存地址为:100044AA,在第2块中,我们可以找到RVA+BASE与之很接近的是
0001:00003440 FixedUploadList@CFileManager@@AAE_NPBD@Z 10004440 f FileManagerobj
这样我们可以定位到FileManagercpp中的FixedUploadList函数,是不是范围缩小了?
下面我们再缩小代码行
利用这个公式:特征码行偏移 = 特征码地址(Crash Address)- 基地址(ImageBase Address)- 0x1000
看起来好像很难,其实很简单,我们将100044AA去掉内存基址10000000,再减1000,因为PE很多从1000开始,可以得到代码偏移地址为34AA。到第3块中找对应的代码行。
偏移地址34AA在(551 0001:0000349e 552 0001:000034b8 )中间,也就是551行和552行中间,我们到源程序中查找第551行:
wsprintf(lpszFilter, "%s%s", lpPathName, lpszSlash);
这样就定位出源代码了,要怎么修改就怎么修改它就可以了。
四、实战免杀
A、卡巴免杀
首次编译后,先做卡巴的免杀。卡巴杀sys文件和dll,当然也就杀包装它们的installexe,最后卡巴还杀生成的sever,我这里说杀生成好的server不是和前面的特征码重叠的地方,而是杀配置信息。
第一步、sys免杀
sys重新编译后,增加了输入表的函数,同时系统不同,造成很多地方不同于原特征,顺利通过卡巴、金山、小红伞等杀软。
第二步、svchostdll免杀
特征码定位MultiByteToWideChar和"gh0st update"两个位置。这里是通过第3步map文件得出的。
卡巴怕加花指令, 这个函数MultiByteToWideChar的调用上,可以在这个函数前面随便加几句无效语句就可以通过卡巴杀软。
字符串调用"gh0st update" ,这个是用于更新用的 ,如果不要在线更新,直接把这个语句所在代码块删除;嘿嘿,其实搜索工程替换这个字符串为其他的字符串就可以了^_^,这个方法同时可以过金山杀软。
第三步、server免杀
卡巴定位在最后的配置信息,采取跳转显然是不行的,采用加花的办法,在写入AAAAAA配置信息之前,随便写些东西,就可以做server免杀。
卡巴免杀完成!
B、Avast免杀
最新的avast杀软再查杀1下,杀installexe和svchostdll(也就是杀生成的文件和其中的资源文件),接着做它的源码免杀。
定位在特征字符串%02d/%02d/%02d和“SYSTEM\CurrentControlSet\Services\%s”两个地方。
解决方案:
1、svchostdll的特征码定位在键盘记录KeyboardManagercpp文件中的SaveInfo(char lpBuffer)函数。特征字符串%02d/%02d/%02d,也就是我们看到键盘记录的日期,修改之,修改的方法很多,将其改为[%d/%d/%d %d:%d:%d] ,编译即可通过avast杀软。
2、install的特征码定位在“SYSTEM\CurrentControlSet\Services\%s”,对应文件是installcpp里的InstallService函数,修改大小写,编译即可通过免杀。
五、添加垃圾代码的小方法
垃圾代码要移动特征码所在的位置,不要跑到堆栈中了,这样的代码没有用。可以采取添加for循环,做计数,简单统计,采用局部变量,不改变后面的逻辑为宜。
添加输出表的方法:
有杀输出表的,可以在生成的svchostdll上添加空函数 ,但是每次编译都要修改1次资源 ,其实我们在源码上添加如下语句:
extern "C" __declspec(dllexport) bool JustTempFun();//声明
……
extern "C" __declspec(dllexport) bool JustTempFun() //实现
{
return false;
}
编译后,输出表就被改变了,有的杀软就可做到代码免杀。
六、gh0st自动生成6to4exdll的修改
看到好多站友提问自动生成6to4exdll的问题,有热心站友也提出了自己的见解 ,我感觉有些人提出的解决方案不完全正确,有可能造成刚入手人误解,我根据自己的理解说明1下。
gh0st服务端是通svchost -netsvcs启动的,所以程序要利用netsvcs 服务,服务端也就是根据netsvcs生成的,故不能说服务端生成是随机的,相对于大多数系统来讲,基本是固定的,下面看分析。
查看installcpp里面的InstallService()方法,首先遍历HKEY_LOCAL_MACHINE\SOFTWARE\ Microsoft\Windows NT\CurrentVersion\Svchost中的服务项,查找到一个服务后,程序采取替换服务的方法,将原服务删除,然后生成对应服务项+ exdll的文件替换原服务,6to4服务一般排在第一位,6to4服务是一种自动构造隧道的方式,作用在于只需要一个全球惟一的IPv4地址便可使得整个站点获得IPv6 的连接,这个服务对一般人来讲,基本闲置,所以我们的程序就把6to4服务给替换掉,同时在windows\system32\目录下生成 6to4exdll,以后启动就是6to4ex了,如果把这个服务跳过去,就依次向下生成Ias、Iprip等服务啦,如果netsvcs项没有可以替换的服务,则程序将自己添加1个服务,名称就是由 AddsvchostService()方法产生的netsvcs_0x%d。
这样说不知道关心服务名称的明白了不?
这个不能说是技术问题,但是小技巧问题可以从这里产生,我不知道其他人的360是怎么过的,但是我觉得可以提示1下的是,如果是360默认系统安全的服务,它肯定不会报不安全,替换闲置的系统安全的服务则通过360的效果要好的多
本文来自: 华夏黑客同盟论坛 本文详细地址:>
//TV类
public class Tv {
public void open(){
Systemoutprintln("打开电视机");
}
public void close(){
Systemoutprintln("关闭电视机");
}
public void search(int x){
Systemoutprintln("您搜索到的是"+x+"号频道");
}
public void ctrlVol(String s){
int vol=10;
if(sequals("+"))
vol++;
if(sequals("-"))
vol--;
Systemoutprintln("当前音量为"+vol);
}
public void changeChannel(int x){
if( x > 29 )
Systemoutprintln("没有该频道");
else
Systemoutprintln("当前"+x+"号频道");
}
public void changeChannel(String s){
int x=0;
if(sequals("+"))
x++;
if(sequals("-"))
x--;
Systemoutprintln("当前"+x+"号频道");
}
}
//Controller遥控器类
public class Controller{
public void openTv(Tv tv){
tvopen();
}
public void closeTv(Tv tv){
tvclose();
}
public void searchTv(Tv tv){
int x=(int)(Mathrandom()30);
tvsearch(x);
}
public void ctrlTvVol(Tv tv){
tvctrlVol("+");
}
public void changeTvChannel(Tv tv){
tvchangeChannel("+");
tvchangeChannel(23);
}
}
摆在我面前的问题就是选择什么语言进行编写咯,我首先考虑了JAVA,首先我从来没写过JAVA的程序,而且IDE装起来很麻烦,而且还是英文的,那更加完全不懂了。然后是C#,很多人都不知道C#可以写Android应用。其实是可以的,但是Android Studio我上次用着卡卡的,印象不是很好,不想用。那还剩下什么选择呢?还有一个:HTML5。
好了我去装了个Hbuilder:
中文的,很好用,问题在于我也从来没用过javascript,不过这是小问题啦。
打开Hbuilder,设置一些护眼什么的,然后点左上角[文件]-[新建]-[移动APP]。然后我选了个模板:
嗯,这就是这个程序在手机上执行的时候的样子。然后我模仿着加了一个列表项到indexhtml里面去:
<li id="plus/controllerhtml" onclick="clicked(thisid);">
<span class="item">Controller <div class="chs">小车遥控器</div>
</span></li>12345
好的,于是这个列表就加了一个选项了。:
继续,在plus文件夹里边添加一个controllerhtml,这就是我们的摇杆所存在的页面。在这个页面上,我们需要一个canvas标签和一个js脚本共同来绘制摇杆:
<!DOCTYPE html><html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=10, maximum-scale=10, user-scalable=no" />
<meta name="HandheldFriendly" content="true" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<!--<meta name="MobileOptimized" content="320" />-->
<title>小车遥控器</title>
<script type="text/javascript" src="/js/commonjs"></script>
</head>
<body>
<div class="leftjoystick">
<canvas id="joystick" width="120" height="120"></canvas>
<script src="/js/Joystickjs"></script>
</div>
</body></html>12345678910111213141516171819
好了,开始写代码绘制摇杆之前,我先做了两幅图,这样绘制摇杆时候就比较省力气了,效果也比较好。。
然后经过了一整天来熟悉javascript。我把控制摇杆的js代码捣鼓出来了。放代码咯:
var ji = new Image(); //内摇杆var jo = new Image(); //外摇杆var joystick = documentgetElementById('joystick'); //画板var josize = joystickheight; //外摇杆大小var jisize = josize 06; //内摇杆大小var centerX = josize / 2; //摇杆中心x坐标var centerY = josize / 2; //摇杆中心y坐标windowaddEventListener('load', load, false);var jc = joystickgetContext('2d'); //画布//摇杆头应当移动到的位置var jx = 0,
jy = 0;//加载完成时执行这俩函数jionload = function() {
jcdrawImage(ji, centerX - jisize / 2, centerY - jisize / 2, jisize, jisize); //首次绘制内摇杆}
joonload = function() {
jcdrawImage(jo, centerX - josize / 2, centerY - josize / 2, josize, josize);
}//绘图函数(绘制图形的时候就是用户观察到摇杆动了,所以取名是move)function move() {
jcclearRect(centerX - josize / 2, centerY - josize / 2, josize, josize);//清空画板
jcdrawImage(jo, centerX - josize / 2, centerY - josize / 2, josize, josize);//画底座
jcdrawImage(ji, centerX - jisize / 2 + jx, centerY - jisize / 2 + jy, jisize, jisize);//画摇杆头
requestAnimationFrame(move); //下一次绘图}
jisrc = '/img/joystickinpng';//加载josrc = '/img/joystickoutpng';//加载//页面加载时执行该函数function load() {
documentaddEventListener('touchstart', touch, false);
documentaddEventListener('touchmove', touch, false);
documentaddEventListener('touchend', touch, false); //加载的时候先把摇杆绘制出来再说
move(); //var effectiveFinger = 0; //当前有效手指
//触摸事件触发函数
function touch(event) {
var event = event || windowevent; var oInp = documentgetElementById("inp"); switch(eventtype) { case "touchstart": // //判断是否击中摇杆头
// if(Mathabs(eventtouches[eventidentifier]clientX - 100 - jx) <= 40 &&
// Mathabs(eventtouches[eventidentifier]clientY - 100 - jy) <= 40) {
// effectiveFinger = eventidentifier; //若是,则将此手指设为有效手指
// }//这个不知道为啥不能起作用,获取不到eventidentifier。
break; case "touchend"://手指离开的时候
//若手指离开,那就把内摇杆放中间
jx = 0;
jy = 0; break; case "touchmove"://手指移动的时候:
//是否触摸点在摇杆上
if(Mathsqrt(Mathpow(eventtouches[effectiveFinger]clientX - centerX, 2) + Mathpow(eventtouches[effectiveFinger]clientY - centerY, 2)) <=
josize / 2 - jisize / 2) {
jx = eventtouches[effectiveFinger]clientX - centerX;
jy = eventtouches[effectiveFinger]clientY - centerY;
} else
//否则计算摇杆最接近的位置
{ var x = eventtouches[effectiveFinger]clientX,
y = eventtouches[effectiveFinger]clientY,
r = josize / 2-jisize/2; var ans=GetPoint(centerX,centerY,r,centerX,centerY,x,y); //圆与直线有两个交点,计算出离手指最近的交点
if(Mathsqrt((ans[0]-x)(ans[0]-x)+(ans[1]-y)(ans[1]-y))<Mathsqrt((ans[2]-x)(ans[2]-x)+(ans[3]-y)(ans[3]-y)))
{
jx=ans[0]-centerX;jy=ans[1]-centerY;
} else
{
jx=ans[2]-centerX;jy=ans[3]-centerY;
}
} //move();
eventpreventDefault();//防止页面滑动,取消掉默认的事件
break;
}
}
requestAnimationFrame(move);//开始绘图}//计算圆于直线的交点(这一块好难啊)function GetPoint(cx, cy, r, stx, sty, edx, edy) {
//(x-cx)^2+(y-cy)^2=r^2
//y=kx+b
var k = (edy - sty) / (edx - stx); var b = edy - k edx; //(1 + k^2)x^2 - x(2cx -2k(b -cy) ) + cxcx + ( b - cy)(b - cy) - rr = 0
var x1, y1, x2, y2; var c = cx cx + (b - cy) (b - cy) - r r; var a = (1 + k k); var b1 = (2 cx - 2 k (b - cy)); var tmp = Mathsqrt(b1 b1 - 4 a c);
x1 = (b1 + tmp) / (2 a);
y1 = k x1 + b;
x2 = (b1 - tmp) / (2 a);
y2 = k x2 + b; return [x1,y1,x2,y2];
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
这个代码的思路就是,如果手指在底座上,那么就把摇杆头移动到手指下方,如果手指在底座外,那就把摇杆移动到底座离手指最近的部分。嗯,就是这样。
以上就是关于本人是单片机初学求C语言红外遥控解码程序并用数码管显示带注悉全部的内容,包括:本人是单片机初学求C语言红外遥控解码程序并用数码管显示带注悉、易语言怎么编写远程控制啊像灰鸽子的那种!最好有源代码!、急求一个java仿真程序 用面向对象程序设计语言编写“电视机-遥控器”仿真程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)