1.UMI3源码解析系列之构建原理
2.Console 模块解读及简单实现
3.「智能家居」自动化平台nodered的码解安装
4.HTB系列靶机Frolic的渗透测试详解
5.求一C++小游戏源代码 简单点的?!!码解谢谢
UMI3源码解析系列之构建原理
基于前面umi插件机制的码解原理可以了解到,umi是码解一个插件化的企业级前端框架,它配备了完善的码解插件体系,这也使得umi具有很好的码解ANDROID源码学习文案可扩展性。umi的码解全部功能都是由插件完成的,构建功能同样是码解以插件的形式完成的。下面将从以下两个方面来了解umi的码解构建原理。UMI命令注册想了解umi命令的码解注册流程,咱们就从umi生成的码解项目入手。
从umi初始化的码解项目package.json文件看,umi执行dev命令,码解实际执行的码解是start:dev,而start:dev最终执行的码解是umidev。
"scripts":{ "dev":"npmrunstart:dev","start:dev":"cross-envREACT_APP_ENV=devMOCK=noneUMI_ENV=devumidev"}根据这里的umi命令,我们找到node_modules里的umi文件夹,看下umi文件夹下的package.json文件:
"name":"umi","bin":{ "umi":"bin/umi.js"}可以看到,这里就是定义umi命令的地方,而umi命令执行的脚本就在bin/umi.js里。接下来咱们看看bin/umi.js都做了什么。
#!/usr/bin/envnoderequire('v8-compile-cache');constresolveCwd=require('@umijs/deps/compiled/resolve-cwd');const{ name,指标源码成本bin}=require('../package.json');constlocalCLI=resolveCwd.silent(`${ name}/${ bin['umi']}`);if(!process.env.USE_GLOBAL_UMI&&localCLI&&localCLI!==__filename){ constdebug=require('@umijs/utils').createDebug('umi:cli');debug('Usinglocalinstallofumi');require(localCLI);}else{ require('../lib/cli');}判断当前是否执行的是本地脚手架,若是,则引入本地脚手架文件,否则引入lib/cli。在这里,我们未开启本地脚手架指令,所以是引用的lib/cli。
//获取进程的版本号constv=process.version;//通过yParser工具对命令行参数进行处理,此处是将version和help进行了简写constargs=yParser(process.argv.slice(2),{ alias:{ version:['v'],help:['h'],},boolean:['version'],});//若参数中有version值,并且args._[0]为空,此时将version字段赋值给args._[0]if(args.version&&!args._[0]){ args._[0]='version';constlocal=existsSync(join(__dirname,'../.local'))?chalk.cyan('@local'):'';console.log(`umi@${ require('../package.json').version}${ local}`);//若参数中无version值,并且args._[0]为空,此时将help字段复制给args._[0]}elseif(!args._[0]){ args._[0]='help';}处理完version和help后,紧接着会执行一段自执行代码:
(async()=>{ try{ //读取args._中第一个参数值switch(args._[0]){ case'dev'://若当前运行环境是dev,则调用Node.js的核心模块child_process的fork方法衍生一个新的Node.js进程。scriptPath表示要在子进程中运行的模块,这里引用的是forkedDev.ts文件。constchild=fork({ scriptPath:require.resolve('./forkedDev'),});//ref:///api/process/signal_events.html///post/Console 模块解读及简单实现
Console模块解读及简单实现
Console模块提供了简单的调试功能,适用于测试调试场景,功能类似于浏览器中的console,但在Node.js中,关于其同步与异步特性有所疑问。智能分析源码
本文通过参考官方源码,实现了一个简化版的Console模块,旨在介绍基本使用方法和常见问题,以供学习参考。
作者:五月君,Nodejs开发者,后技术爱好者,公众号「Nodejs技术栈」,开源项目请见/article/...
来源:慕课网
本文首发于慕课网,转载时请注明出处,感谢合作。
「智能家居」自动化平台nodered的安装
Node-RED,一个由IBM研发的可视化物联网编排工具,现已纳入OpenJS Foundation。它使用NodeJS语言提供后端支持,具有Web页面功能,允许用户使用拖拽方式编写Flow,创建如最小可用服务。支持多种协议和连接设备,包含http、mqtt、通天星源码websocket、tcp和utp等,能连接主流的物联网设备与服务器,且是一个无限扩展平台,提供了超过,个可扩展模块。
在安装方面,Node-RED提供了源码、树莓派、Docker、安卓、AWS及IBM Cloud等方法。让我们关注HASSOS和Docker下的安装。
在HASSOS配置中,首先在supervisor的加载项商店找到并安装Node-RED,完成基本配置后启动服务。
在Docker环境中,通过注册表搜索并下载Node-RED镜像,设定启动参数,包括自启动选项。创建Node-RED文件夹,将其添加至Docker环境,antdform组件源码使用相同网络连接,配置环境变量以完成安装。
之后,通过浏览器输入群晖的IP:,即可访问Node-RED的Web界面。左侧展示了可用节点,每个节点配有特定配置选项,用户可双击编辑或通过节点管理搜索、下载新节点来扩展功能。
Node-RED是智能家居自动化领域的优选工具,支持广泛的连接与定制。无论是入门新手还是资深从业者,它都能满足需求,提供灵活的解决方案,推动智能家居与物联网领域的发展。
HTB系列靶机Frolic的渗透测试详解
Hack The Box 平台上提供了多种靶机,从简单到复杂,旨在提升渗透测试技能和黑盒测试能力。这些靶机模拟了真实世界场景,适合不同层次的挑战。今天,我们将详细介绍如何通过靶机 Frolic 的渗透测试。
首先,使用 nmap 扫描靶机开放的端口和服务。结果显示 SSH(端口 )、SMB(端口 和 )以及 HTTP(端口 )。
针对 SMB 服务,我们尝试使用 smbmap 查看共享文件。发现了两个共享目录,但没有访问权限。
接着,我们通过 nc 工具快速检测了端口 是否开放。结果显示该端口是开启的。随后,访问了该端口,发现了一个简单的欢迎页面,底部包含 “forlic.htb:” 的信息。
尝试登陆页面时,我们注意到需要账户密码。尽管使用常见默认账户和密码尝试登陆,但均失败。当使用 admin:password 登录时,页面陷入卡顿状态,且系统实施了等待时间限制,禁止暴力破解。
为了突破限制,我们使用 gobuster 爆破网站目录,成功发现了 /backup、/dev、/test 和 /admin 等目录。在 /backup 中,我们找到了 password.txt 和 user.txt 文件,分别包含了账号密码:admin: imnothuman。
尝试登陆刚刚发现的 Node-RED 页面时,发现无法登陆。我们转而访问 /admin 页面,发现提示剩余尝试次数。通过 Burp Suite 工具抓包发现,未接收到任何反馈信息。检查源代码的 JS 代码,发现了一种编码技巧。复制这段编码到谷歌搜索后,我们访问了作为提示的 URL,并通过解码找到一个 ZIP 文件。
解压 ZIP 文件后,需要密码,我们使用 zip2john 工具将其转换为密码 HASH,然后使用 john 工具破解,得到了密码:password。再次解压文件,内容疑似 进制格式。转换后,我们发现是一个需要解密的文本,通过谷歌搜索找到对应解码网站,解密后得到 idkwhatispass。
经过多次尝试,我们总共得到了两组密码。我们发现可能还有未被探索的网页,其密码可能属于未被发现的页面。基于此,我们继续使用 gobuster 工具进行进一步的扫描和爆破,最终找到了 /dev 下的 /backup 目录。
访问此目录并使用刚刚得到的密码尝试登陆。正确的账号密码是 admin: idkwhatispass。接着,我们尝试利用 playsms 的已知漏洞进行攻击。使用 1.4 版本的远程代码执行漏洞,通过 searchsploit-x Path 查找相应的漏洞说明并手动利用。也可以使用 Metasploit 框架中集成的工具进行攻击。
成功后,我们获得了 user flag。接下来是提权操作,我们使用 LinEnum 工具检查可利用的提升权限点。使用 Python 的 SimpleHTTPServer 模块将 LinEnum 上传到靶机执行,然后在 shell 中运行。我们注意到带有 SUID 权限的文件,可以通过输入特定内容触发溢出攻击,进而获得 root 权限。
我们使用 gdb 进行调试,通过插件 pEDA 安装,调试工具帮助我们定位错误位置和计算地址偏移量。通过一系列操作,我们最终获得了 /bin/sh 的地址,并整合系统调用函数 system() 和 exit() 的地址,构建了 payload,成功获取了 root 权限。
Ms 安全实验室专注于网络安全知识的普及和培训,已出版多本专业书籍,如《Web 安全攻防:渗透测试实战指南》、《内网安全攻防:渗透测试实战指南》等。团队定期在公众号分享技术干货,旨在提供实用的渗透测试实战指南。
求一C++小游戏源代码 简单点的?!!谢谢
#include<graphics.h>
#include<stdlib.h>
#include<dos.h>
#define LEFT 0x4b
#define RIGHT 0x4d
#define DOWN 0x
#define UP 0x
#define ESC 0xb
int i,key;
int score=0;
int gamespeed=;
struct Food /*食物的结构体*/
{
int x; /*食物的横坐标*/
int y; /*食物的纵坐标*/
int yes; /*食物是否出现的变量*/
}food;
struct Snack /*蛇的结构体*/
{
int x[N];
int y[N];
int node; /*蛇的节数*/
int direction; /*蛇的方向*/
int life; /*蛇的生命,0活着,1死亡*/
}snake;
void Init(void); /*图形驱动*/
void Close(void); /*关闭游戏函数*/
void DrawK(void); /*画图函数*/
void GameOver(void);/*输出失败函数*/
void GamePlay(); /*游戏控制函数 主要程序*/
void PrScore(void); /*分数输出函数*/
DELAY(char ch)/*调节游戏速度*/
{
if(ch=='3')
{
delay(gamespeed); /*delay是延迟函数*/
delay(gamespeed);
}
else if(ch=='2')
{
delay(gamespeed);
}
}
Menu()/*游戏开始菜单*/
{
char ch;
printf("Please choose the gamespeed:\n");
printf("1-Fast 2-Normal 3-Slow\n");
printf("\nPlease Press The numbers..\n");
do
{ ch=getch();}
while(ch!='1'&&ch!='2'&&ch!='3');
clrscr();
return(ch);
}
/*主函数*/
void main(void)
{
int ch;
ch=Menu();
Init();
DrawK();
GamePlay(ch);
Close();
}
void Init(void)
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"c:\\tc");
cleardevice();
}
void DrawK(void)
{
setcolor();
setlinestyle(SOLID_LINE,0,THICK_WIDTH);
for(i=;i<=;i+=)
{
rectangle(i,,i+,); /*画出上边框*/
rectangle(i,,i+,); /*画出下边框*/
}
for(i=;i<=;i+=)
{
rectangle(,i,,i+); /*画出左边框*/
rectangle(,i,,i+); /*画出右边框*/
}
}
void GamePlay(char ch)
{
randomize(); /*随机数发生器*/
food.yes=1; /*1代表要出现食物,0表示以存在食物*/
snake.life=0;
snake.direction=1;
snake.x[0]=;snake.y[0]=;
snake.x[1]=;snake.y[1]=;
snake.node=2;
PrScore();
while(1) /*可以重复游戏*/
{
while(!kbhit()) /*在没有按键的情况下蛇自己移动*/
{
if(food.yes==1) /*需要食物*/
{
food.x=rand()%+;
food.y=rand()%+; /*使用rand函数随机产生食物坐标*/
while(food.x%!=0)
food.x++;
while(food.y%!=0)
food.y++; /*判断食物是否出现在整格里*/
food.yes=0; /*现在有食物了*/
}
if(food.yes==0) /*有食物了就要显示出来*/
{
setcolor(GREEN);
rectangle(food.x,food.y,food.x+,food.y-);
}
for(i=snake.node-1;i>0;i--) /*贪吃蛇的移动算法*/
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1]; /*贪吃蛇的身体移动算法*/
}
switch(snake.direction) /*贪吃蛇的头部移动算法,以此来控制移动*/
{
case 1:snake.x[0]+=;break;
case 2:snake.x[0]-=;break;
case 3:snake.y[0]-=;break;
case 4:snake.y[0]+=;break;
}
for(i=3;i<snake.node;i++) /*判断是否头部与身体相撞*/
{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
{
GameOver();
snake.life=1;
break;
}
}
/*下面是判断是否撞到墙壁*/
if(snake.x[0]<||snake.x[0]>||snake.y[0]<||snake.y[0]>)
{
GameOver();
snake.life=1;
}
if(snake.life==1) /*如果死亡就退出循环*/
break;
if(snake.x[0]==food.x&&snake.y[0]==food.y) /*判断蛇是否吃到食物*/
{
setcolor(0);
rectangle(food.x,food.y,food.x+,food.y-); /*吃的食物后用黑色将食物擦去*/
snake.x[snake.node]=-;snake.y[snake.node]=-; /*现把增加的一节放到看不到的地方去*/
snake.node++;
food.yes=1;
score+=;
PrScore();
}
setcolor(4); /*每次移动后将后面的身体擦去*/
for(i=0;i<snake.node;i++)
rectangle(snake.x[i],snake.y[i],snake.x[i]+,snake.y[i]-);
delay(gamespeed);
DELAY(ch);
setcolor(0);
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],snake.x[snake.node-1]+,snake.y[snake.node-1]-);
}
if(snake.life==1)
break;
key=bioskey(0); /*接受按键*/
if(key==ESC)
break;
else
if(key==UP&&snake.direction!=4)/*判断是否改变方向*/
snake.direction=3;
else
if(key==RIGHT&&snake.direction!=2)
snake.direction=1;
else
if(key==LEFT&&snake.direction!=1)
snake.direction=2;
else
if(key==DOWN&&snake.direction!=3)
snake.direction=4;
}
}
void GameOver(void)
{
cleardevice();
setcolor(RED);
settextstyle(0,0,4);
outtextxy(,,"GAME OVER");
getch();
}
void PrScore(void)
{
char str[];
setfillstyle(SOLID_FILL,YELLOW);
bar(,,,);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,"scord:%d",score);
outtextxy(,,str);
}
void Close(void)
{
getch();
closegraph();
}
贪吃蛇